1818 #include  " WProgram.h" 
1919#endif 
2020
21+ #include < FixMath.h> 
22+ 
2123/* * For linear changes with a minimum of calculation at each step. For instance,
2224you can use Line to make an oscillator glide from one frequency to another, 
2325pre-calculating the required phase increments for each end and then letting your 
@@ -33,6 +35,9 @@ represent fractional numbers. Google "fixed point arithmetic" if this is new to
3335you. 
3436*/ 
3537
38+ 
39+ 
40+ 
3641template  <class  T >
3742class  Line 
3843{
@@ -315,6 +320,174 @@ class Line <unsigned long>
315320	}
316321};
317322
323+ 
324+ /*  UFix specialisation */ 
325+ template <int8_t  NI, int8_t  NF>
326+ class  Line <UFix<NI, NF>>
327+ {
328+ private: 
329+   typedef  UFix<NI, NF> internal_type;
330+   internal_type current_value;
331+   internal_type step_size;
332+ 
333+ public: 
334+   /* * Constructor. Use the template parameter to set the type of numbers you
335+       want to use. For example, Line \<int\> myline; makes a Line which uses ints. 
336+   */  
337+   Line  (){;}
338+ 
339+   /* * Increments one step along the line.
340+       @return the next value. 
341+   */  
342+   inline 
343+   internal_type next ()
344+   {
345+     current_value = current_value + step_size;
346+     return  current_value;
347+   }
348+ 
349+   /* * Set the current value of the line. 
350+       The Line will continue incrementing from this 
351+       value using any previously calculated step size. 
352+       @param value the number to set the Line's current_value to. 
353+   */  
354+   inline 
355+   void  set (internal_type value)
356+   {
357+     current_value=value;
358+   }
359+ 
360+   /* * Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
361+       @param targetvalue the value to move towards. 
362+       @param num_steps how many steps to take to reach the target as a UFix<_NI,0> 
363+   */  
364+   template <int8_t  _NI>
365+   void  set (internal_type targetvalue, UFix<_NI,0 > num_steps)
366+   {
367+     if (num_steps.asRaw ()) {
368+       internal_type numerator = targetvalue-current_value;
369+       step_size = numerator*num_steps.invAccurate ();
370+     } else  {
371+       step_size = 0 ;
372+       current_value = targetvalue;
373+     }
374+   }
375+ 
376+ 
377+   /* * Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
378+       @param targetvalue the value to move towards. 
379+       @param num_steps how many steps to take to reach the target. 
380+   */  
381+   template <typename  T>
382+   void  set (internal_type targetvalue, T num_steps)
383+   {
384+     if (num_steps) {
385+       internal_type numerator = targetvalue-current_value;
386+       step_size = internal_type (numerator.asRaw ()/num_steps,true );
387+     } else  {
388+       step_size = 0 ;
389+       current_value = targetvalue;
390+     }
391+   }
392+ 
393+   /* * Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
394+       @param startvalue the number to set the Line's current_value to. 
395+       @param targetvalue the value to move towards. 
396+       @param num_steps how many steps to take to reach the target. 
397+   */  
398+   template <typename  T>
399+   void  set (internal_type startvalue, internal_type targetvalue, T num_steps)
400+   {
401+     set (startvalue);
402+     set (targetvalue, num_steps);
403+   }  
404+ };
405+ 
406+ 
407+ /*  SFix specialisation (if someone has an idea to avoid duplication with UFix) */ 
408+ template <int8_t  NI, int8_t  NF>
409+ class  Line <SFix<NI, NF>>
410+ {
411+ private: 
412+   typedef  SFix<NI, NF> internal_type;
413+   internal_type current_value;
414+   internal_type step_size;
415+ 
416+ public: 
417+   /* * Constructor. Use the template parameter to set the type of numbers you
418+       want to use. For example, Line \<int\> myline; makes a Line which uses ints. 
419+   */  
420+   Line  (){;}
421+ 
422+   /* * Increments one step along the line.
423+       @return the next value. 
424+   */  
425+   inline 
426+   internal_type next ()
427+   {
428+     current_value = current_value + step_size;
429+     return  current_value;
430+   }
431+ 
432+   /* * Set the current value of the line. 
433+       The Line will continue incrementing from this 
434+       value using any previously calculated step size. 
435+       @param value the number to set the Line's current_value to. 
436+   */  
437+   inline 
438+   void  set (internal_type value)
439+   {
440+     current_value=value;
441+   }
442+ 
443+   /* * Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
444+       @param targetvalue the value to move towards. 
445+       @param num_steps how many steps to take to reach the target as a UFix<_NI,0> 
446+   */  
447+   template <int8_t  _NI>
448+   void  set (internal_type targetvalue, UFix<_NI,0 > num_steps)
449+   {
450+     if (num_steps.asRaw ()) {
451+       internal_type numerator = targetvalue-current_value;
452+       step_size = numerator*num_steps.invAccurate ();
453+     } else  {
454+       step_size = 0 ;
455+       current_value = targetvalue;
456+     }
457+   }
458+ 
459+ 
460+   /* * Given a target value and the number of steps to take on the way, this calculates the step size needed to get there from the current value.
461+       @param targetvalue the value to move towards. 
462+       @param num_steps how many steps to take to reach the target. 
463+   */  
464+   template <typename  T>
465+   void  set (internal_type targetvalue, T num_steps)
466+   {
467+     if (num_steps) {
468+       internal_type numerator = targetvalue-current_value;
469+       step_size = internal_type (numerator.asRaw ()/num_steps,true );
470+     } else  {
471+       step_size = 0 ;
472+       current_value = targetvalue;
473+     }
474+   }
475+ 
476+   /* * Given a new starting value, target value and the number of steps to take on the way, this sets the step size needed to get there.
477+       @param startvalue the number to set the Line's current_value to. 
478+       @param targetvalue the value to move towards. 
479+       @param num_steps how many steps to take to reach the target. 
480+   */  
481+   template <typename  T>
482+   void  set (internal_type startvalue, internal_type targetvalue, T num_steps)
483+   {
484+     set (startvalue);
485+     set (targetvalue, num_steps);
486+   }  
487+ };
488+ 
489+ 
490+ 
318491/* *
319492@example 02.Control/Control_Tremelo/Control_Tremelo.ino 
320493This example demonstrates the Line class. 
0 commit comments