Go Down

Topic: FastLED beatsin**() functions, BPM parameter. (Read 190 times) previous topic - next topic

SergeS

May 07, 2020, 04:54 pm Last Edit: May 07, 2020, 06:42 pm by SergeS
Looking in lib8tion.h:
Code: [Select]

/*
- Beat generators which return sine or sawtooth waves in a specified number of Beats Per Minute.
   Sine wave beat generators can specify a low and high range for the output.  Sawtooth wave beat
   generators always range 0-255 or 0-65535.
     beatsin8( BPM, low8, high8) = (sine(beatphase) * (high8-low8)) + low8
     beatsin16( BPM, low16, high16) = (sine(beatphase) * (high16-low16)) + low16
     beatsin88( BPM88, low16, high16) = (sine(beatphase) * (high16-low16)) + low16
   BPM is beats per minute in either simple form  e.g. 120, or Q8.8 fixed-point form.
   BPM88 is beats per minute in ONLY Q8.8 fixed-point form.
*/
...
//       beatsin8( BPM, uint8_t low, uint8_t high) returns an 8-bit value that
//                    rises and falls in a sine wave, 'BPM' times per minute,
//                    between the values of 'low' and 'high'.
//       beatsin16( BPM, uint16_t low, uint16_t high) returns a 16-bit value
//                    that rises and falls in a sine wave, 'BPM' times per
//                    minute, between the values of 'low' and 'high'.
//       beatsin88( BPM88, ...) is the same as beatsin16, except that the
//                    BPM88 argument MUST be in Q8.8 fixed point format,
//                    e.g. 120BPM must be specified as 120*256 = 30720.
...
//  BPM can be supplied two ways.  The simpler way of specifying BPM is as
//  a simple 8-bit integer from 1-255, (e.g., "120").
//  The more sophisticated way of specifying BPM allows for fractional
//  "Q8.8" fixed point number (an 'accum88') with an 8-bit integer part and
//  an 8-bit fractional part.  The easiest way to construct this is to multiply
//  a floating point BPM value (e.g. 120.3) by 256, (e.g. resulting in 30796
//  in this case), and pass that as the 16-bit BPM argument.
//  "BPM88" MUST always be specified in Q8.8 format.
...
/// beatsin88 generates a 16-bit sine wave at a given BPM,
///           that oscillates within a given range.
///           For this function, BPM MUST BE SPECIFIED as
///           a Q8.8 fixed-point value; e.g. 120BPM must be
///           specified as 120*256 = 30720.
///           If you just want to specify "120", use beatsin16 or beatsin8.
LIB8STATIC uint16_t beatsin88( accum88 beats_per_minute_88, uint16_t lowest = 0, uint16_t highest = 65535,
                              uint32_t timebase = 0, uint16_t phase_offset = 0)
...

/// beatsin16 generates a 16-bit sine wave at a given BPM,
///           that oscillates within a given range.
LIB8STATIC uint16_t beatsin16( accum88 beats_per_minute, uint16_t lowest = 0, uint16_t highest = 65535,
                               uint32_t timebase = 0, uint16_t phase_offset = 0)
...
/// beatsin8 generates an 8-bit sine wave at a given BPM,
///           that oscillates within a given range.
LIB8STATIC uint8_t beatsin8( accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255,
                            uint32_t timebase = 0, uint8_t phase_offset = 0)


My question - how to specify BPM parameter (not a BPM88!) in beatsin8() and beatsin16() less than 1 beat-per-minute (or other fractional value)? If it is not possible - what is the reason to use type accum88 there?
Can someone explain this sentence: "The more sophisticated way of specifying BPM allows for fractional  "Q8.8" fixed point number (an 'accum88') with an 8-bit integer part and an 8-bit fractional part.  The easiest way to construct this is to multiply a floating point BPM value (e.g. 120.3) by 256, (e.g. resulting in 30796 in this case), and pass that as the 16-bit BPM argument."

Grumpy_Mike

I think a Q8.8 number means a quasi floating point number consisting of an 8 bit integer in the top byte and the fractional part in the lower 8 bits. I haven't come across the term before but this is a well known fixed point notation.

So suppose you want to represent 4.7 then you would use the integer
4.7 * 256.

SergeS

I think a Q8.8 number means a quasi floating point number consisting of an 8 bit integer in the top byte and the fractional part in the lower 8 bits. I haven't come across the term before but this is a well known fixed point notation.

So suppose you want to represent 4.7 then you would use the integer
4.7 * 256.
Yes, this is correct.

I have misunderstood sentence "The more sophisticated way of specifying BPM allows ...<bla-bla-bla>" as ability to specify it in two different formats.

BPM88 MUST be specified as you have said, so 1 here means 1/256 beats per minute, 0xFFFF (max) means almost 256 beats per minute.

BPM is regular "human-readable" decimal format :-).

Go Up