3//shift array from position
4template<size_t maxParameters, size_t maxKeyFrames>
5void KeyFrameTrack<maxParameters, maxKeyFrames>::ShiftKeyFrameArray(int position){
6 for(uint8_t i = position; i < currentFrames; i++){
7 keyFrames[i + 1] = keyFrames[i];
11template<size_t maxParameters, size_t maxKeyFrames>
12KeyFrameTrack<maxParameters, maxKeyFrames>::KeyFrameTrack(float min, float max, InterpolationMethod interpMethod){
15 this->interpMethod = interpMethod;
18template<size_t maxParameters, size_t maxKeyFrames>
19float KeyFrameTrack<maxParameters, maxKeyFrames>::GetCurrentTime(){
20 currentTime = fmod(millis() / 1000.0f + timeOffset, stopFrameTime - startFrameTime) + startFrameTime;//normalize time and add offset
25template<size_t maxParameters, size_t maxKeyFrames>
26void KeyFrameTrack<maxParameters, maxKeyFrames>::SetCurrentTime(float setTime){
27 float currentSecs = millis() / 1000.0f;
29 //Test case: current time = 1.32s, set time = 1.09s, 1.59s
30 timeOffset = setTime - currentSecs;//1.59 - 1.32 = 0.27, 1.09 - 1.32 = -0.23
34template<size_t maxParameters, size_t maxKeyFrames>
35void KeyFrameTrack<maxParameters, maxKeyFrames>::Pause(){
39template<size_t maxParameters, size_t maxKeyFrames>
40void KeyFrameTrack<maxParameters, maxKeyFrames>::Play(){
44template<size_t maxParameters, size_t maxKeyFrames>
45void KeyFrameTrack<maxParameters, maxKeyFrames>::AddParameter(float* parameter){
46 if(currentParameters < maxParameters){
47 parameters[currentParameters] = parameter;
52template<size_t maxParameters, size_t maxKeyFrames>
53void KeyFrameTrack<maxParameters, maxKeyFrames>::AddKeyFrame(float time, float value){
54 if (currentFrames < maxKeyFrames){
55 value = Mathematics::Constrain(value, min, max);
57 if(currentFrames == 0){
58 keyFrames[0].Set(time, value);
60 else if (time > this->stopFrameTime){
61 keyFrames[currentFrames].Set(time, value);
64 for(int i = 0; i < currentFrames; i++){
65 if(time < keyFrames[i].Time){
66 ShiftKeyFrameArray(i);
67 keyFrames[i].Set(time, value);
75 this->startFrameTime = time < this->startFrameTime ? time : this->startFrameTime;//set new min time if lesser than current
76 this->stopFrameTime = time > this->stopFrameTime ? time : this->stopFrameTime;//Set new max time if greater than current
80template<size_t maxParameters, size_t maxKeyFrames>
81float KeyFrameTrack<maxParameters, maxKeyFrames>::GetParameterValue(){
82 return parameterValue;
85template<size_t maxParameters, size_t maxKeyFrames>
86void KeyFrameTrack<maxParameters, maxKeyFrames>::Reset(){
87 for(int i = 0; i < currentParameters; i++){
88 *(this->parameters[i]) = min;
92template<size_t maxParameters, size_t maxKeyFrames>
93float KeyFrameTrack<maxParameters, maxKeyFrames>::Update(){
97 byte previousFrame = 0, nextFrame = 0;
99 //find current time, find keyframe before and after
100 if(currentFrames > 0 && isActive){
101 for (uint8_t i = currentFrames - 1; i >= 0; i--){
102 if (currentTime >= keyFrames[i].Time){
110 float ratio = Mathematics::Map(currentTime, keyFrames[previousFrame].Time, keyFrames[nextFrame].Time, 0.0f, 1.0f);
111 float parameter = 0.0f;
113 switch(interpMethod){
115 parameter = Mathematics::CosineInterpolation(keyFrames[previousFrame].Value, keyFrames[nextFrame].Value, ratio);
118 parameter = keyFrames[previousFrame].Value;
121 parameter = Mathematics::Map(ratio, 0.0f, 1.0f, keyFrames[previousFrame].Value, keyFrames[nextFrame].Value);
126 parameterValue = parameter;
128 if (currentParameters > 0){//Update if not parameters are linked
129 for(uint8_t i = 0; i < currentParameters; i++){
130 *(this->parameters[i]) = parameter;
135 return parameterValue;