31    template<board::Timer NTIMER, board::PWMPin OUTPUT, 
typename TONEPLAY> 
class AbstractTonePlayer;
 
   44        static constexpr const Tone END = Tone::USER0;
 
   71        static constexpr const Tone TIE = Tone::USER3;
 
  135        return Duration(uint8_t(d) + uint8_t(d) / 2);
 
  143        return Duration(uint8_t(d) * 2 / 3);
 
  196        constexpr TonePlay(
Tone tone, uint8_t value = 0) : tone_{tone}, repeats_{value} {}
 
  205            return tone_ > Tone::SILENCE;
 
  207        bool is_pause()
 const 
  209            return tone_ == Tone::SILENCE;
 
  215        bool is_repeat_start()
 const 
  219        bool is_repeat_end()
 const 
  223        uint8_t repeat_count()
 const 
  231        uint8_t num_ties()
 const 
  236        template<board::Timer NTIMER, board::PWMPin OUTPUT>
 
  237        void generate_tone(ToneGenerator<NTIMER, OUTPUT>& generator)
 const 
  239            generator.start_tone(tone_);
 
  250        template<board::Timer, board::PWMPin, 
typename> 
friend class AbstractTonePlayer;
 
  268    template<board::Timer NTIMER, board::PWMPin OUTPUT> 
class QTonePlay 
  294            : flags_{flags(tone)}, prescaler_{prescaler(tone)}, counter_{counter(tone)}, duration_{duration} {}
 
  305            : flags_{flags(tone)}, prescaler_{prescaler(tone)}, counter_{counter(tone)}, repeats_{value} {}
 
  319            return flags_ == TONE;
 
  321        bool is_pause()
 const 
  323            return flags_ == NONE;
 
  327            return flags_ == END;
 
  329        bool is_repeat_start()
 const 
  331            return flags_ == REPEAT_START;
 
  333        bool is_repeat_end()
 const 
  335            return flags_ == REPEAT_END;
 
  337        uint8_t repeat_count()
 const 
  343            return flags_ == TIE;
 
  345        uint8_t num_ties()
 const 
  350        void generate_tone(ToneGenerator<NTIMER, OUTPUT>& generator)
 const 
  352            generator.start_tone(prescaler_, counter_);
 
  356        static constexpr uint8_t TONE = 0x00;
 
  357        static constexpr uint8_t NONE = 0x01;
 
  358        static constexpr uint8_t END = 0x02;
 
  359        static constexpr uint8_t REPEAT_START = 0x04;
 
  360        static constexpr uint8_t REPEAT_END = 0x08;
 
  361        static constexpr uint8_t TIE = 0x10;
 
  363        uint8_t flags_ = 
END;
 
  364        PRESCALER prescaler_;
 
  373        static constexpr uint32_t period(
Tone tone)
 
  375            return ONE_SECOND / 2 / uint16_t(tone);
 
  377        static constexpr PRESCALER prescaler(
Tone tone)
 
  379            return (tone > Tone::SILENCE ? 
CALC::CTC_prescaler(period(tone)) : PRESCALER::NO_PRESCALING);
 
  381        static constexpr COUNTER counter(
Tone tone)
 
  383            return (tone > Tone::SILENCE ? 
CALC::CTC_counter(prescaler(tone), period(tone)) : 0);
 
  385        static constexpr uint8_t flags(
Tone tone)
 
  387            if (tone == Tone::SILENCE) 
return NONE;
 
  408        explicit constexpr Beat(uint8_t bpm) : duration_{calculate_min_duration(bpm)} {}
 
  410        constexpr uint16_t duration()
 const 
  417        static constexpr uint16_t calculate_min_duration(uint8_t bpm)
 
  421            return (60U * 1000U / 8U) / bpm;
 
  463    template<board::Timer NTIMER, board::PWMPin OUTPUT, 
typename TONEPLAY = QTonePlay<NTIMER, OUTPUT>>
 
  492            t32_duration_ms_ = min_duration;
 
  501            return t32_duration_ms_;
 
  511            prepare_(melody, load_sram);
 
  521            prepare_(melody, load_eeprom);
 
  531            prepare_(melody, load_flash);
 
  546            return start_next_();
 
  560            return stop_current_();
 
  568            return (loader_ == 
nullptr);
 
  572        static constexpr const uint16_t INTERTONE_DELAY_MS = 20;
 
  576        void prepare_(
const TONE_PLAY* melody, LOAD_TONE load_tone)
 
  579            current_play_ = melody;
 
  580            repeat_play_ = 
nullptr;
 
  588            current_play_ = 
nullptr;
 
  589            repeat_play_ = 
nullptr;
 
  594        uint16_t start_next_()
 
  596            if (loader_ == 
nullptr) 
return 0;
 
  599            const TONE_PLAY* current = loader_(current_play_, holder);
 
  600            if (current->is_end())
 
  607            if (current->is_repeat_start())
 
  609                repeat_play_ = current_play_;
 
  612            else if (current->is_repeat_end())
 
  616                    if (repeat_times_ == -1) repeat_times_ = current->repeat_count();
 
  618                        current_play_ = repeat_play_;
 
  620                        repeat_play_ = 
nullptr;
 
  623            else if (current->is_tie())
 
  625                tie_notes_ = current->num_ties();
 
  629                if (current->is_tone()) current->generate_tone(generator_);
 
  634                delay = duration(current->duration());
 
  640        uint16_t stop_current_()
 
  645            return INTERTONE_DELAY_MS;
 
  650            return uint8_t(d) * t32_duration_ms_;
 
  669        LOAD_TONE loader_ = 
nullptr;
 
  670        uint16_t t32_duration_ms_ = 0U;
 
  671        const TONE_PLAY* current_play_ = 
nullptr;
 
  673        int8_t repeat_times_ = 0;
 
  674        uint8_t tie_notes_ = 0;
 
  675        bool no_delay_ = 
false;
 
  711    template<board::Timer NTIMER, board::PWMPin OUTPUT, 
typename TONEPLAY = QTonePlay<NTIMER, OUTPUT>>
 
  818        volatile bool stop_ = 
true;
 
  855    template<board::Timer NTIMER, board::PWMPin OUTPUT, 
typename TONEPLAY = QTonePlay<NTIMER, OUTPUT>>
 
  905            status_ = Status::NOT_STARTED;
 
  909            status_ = Status::STARTED;
 
  928            status_ = Status::NOT_STARTED;
 
  932            status_ = Status::STARTED;
 
  951            status_ = Status::NOT_STARTED;
 
  955            status_ = Status::STARTED;
 
  964            status_ = Status::NOT_STARTED;
 
  973            return status_ != Status::NOT_STARTED;
 
  988            if ((status_ != Status::NOT_STARTED) && (rtt_millis >= next_time_))
 
  992                if (status_ == Status::PLAYING_NOTE)
 
  995                    next = Status::PLAYING_INTERNOTE;
 
 1000                    next = Status::PLAYING_NOTE;
 
 1004                    status_ = Status::NOT_STARTED;
 
 1007                    next_time_ = rtt_millis + delay;
 
 1014        enum class Status : uint8_t
 
 1022        Status status_ = Status::NOT_STARTED;
 
 1023        uint32_t next_time_ = 0UL;
 
This low-level API defines an abstract player of melodies (defined as a sequence of tones and duratio...
uint16_t get_min_duration() const
Get the duration, in milliseconds, of a 32nd note.
void set_min_duration(uint16_t min_duration)
Set the duration, in milliseconds, of a 32nd note.
void prepare_eeprom(const TONE_PLAY *melody)
Prepare playing of melody, which should be stored in EEPROM.
ToneGenerator< NTIMER, OUTPUT > GENERATOR
The type of ToneGenerator to use as constructor's argument.
uint16_t stop_current_note()
Ask this player to stop playing the current note of the melody.
uint16_t start_next_note()
Ask this player to start playing the next note of the melody.
TONEPLAY TONE_PLAY
The type that holds unit of information of a melody.
void prepare_sram(const TONE_PLAY *melody)
Prepare playing of melody, which should be stored in SRAM.
AbstractTonePlayer(GENERATOR &tone_generator)
Create a new tone player, based on an existing ToneGenerator.
bool is_finished() const
Indicate if the currently played melody is finished.
void prepare_flash(const TONE_PLAY *melody)
Prepare playing of melody, which should be stored in Flash.
This API defines a player of melodies, defined as a sequence of tones and durations.
typename BASE::GENERATOR GENERATOR
The type of ToneGenerator to use as constructor's argument.
void update(uint32_t rtt_millis)
Ask this player to update current play if needed, based on current time (as returned by an timer::RTT...
uint16_t get_min_duration() const
Get the duration, in milliseconds, of a 32nd note.
void play_eeprom(const TONE_PLAY *melody, const Beat &beat)
Start playing a melody, defined by a sequence of TONE_PLAYs, stored in EEPROM.
void play_sram(const TONE_PLAY *melody, const Beat &beat)
Start playing a melody, defined by a sequence of TONE_PLAYs, stored in SRAM.
typename BASE::TONE_PLAY TONE_PLAY
The type that holds unit of information of a melody.
bool is_playing() const
Tell if a melody is currently playing.
void stop()
Stop playing current melody (if any).
AsyncTonePlayer(GENERATOR &tone_generator)
Create a new asynchronous tone player, based on an existing ToneGenerator.
void play_flash(const TONE_PLAY *melody, const Beat &beat)
Start playing a melody, defined by a sequence of TONE_PLAYs, stored in Flash.
This embeds minimum duration (duration of a 32nd note), in milliseconds, for a given tempo (beats per...
An optimized surrogate to TonePlay structure.
constexpr QTonePlay(Tone tone, uint8_t value=0)
Construct a "special" optimized tone play with the provided value.
constexpr QTonePlay(Tone tone, Duration duration)
Construct an optimized tone play for the provided tone and duration.
QTonePlay()=default
Default constructor, used only to declare an uninitialized QTonePlay variable.
API class for tone generation to a buzzer (or better an amplifier) connected to pin OUTPUT.
void stop_tone()
Stop the tone being currently generated to the connected buzzer.
This struct is the unit data manipulated by TonePlayer: it describes one Tone along with its duration...
TonePlay()=default
Default constructor, used only to declare an uninitialized TonePlay variable.
constexpr TonePlay(Tone tone, Duration duration)
Construct a tone play with the provided tone and duration.
constexpr TonePlay(Tone tone, uint8_t value=0)
Construct a "special" tone play with the provided value.
This API defines a player of melodies, defined as a sequence of tones and durations.
typename BASE::TONE_PLAY TONE_PLAY
The type that holds unit of information of a melody.
void play_flash(const TONE_PLAY *melody, const Beat &beat)
Play a melody, defined by a sequence of TONE_PLAYs, stored in Flash.
void stop()
Stop playing current melody (if any).
TonePlayer(GENERATOR &tone_generator)
Create a new synchronous tone player, based on an existing ToneGenerator.
bool is_playing() const
Tell if a melody is currently playing.
void play_sram(const TONE_PLAY *melody, const Beat &beat)
Play a melody, defined by a sequence of TONE_PLAYs, stored in SRAM.
void play_eeprom(const TONE_PLAY *melody, const Beat &beat)
Play a melody, defined by a sequence of TONE_PLAYs, stored in EEPROM.
typename BASE::GENERATOR GENERATOR
The type of ToneGenerator to use as constructor's argument.
static bool read(const T *address, T &value)
Read value of type T stored in EEPROM at address.
General API to handle an AVR timer.
typename TRAIT::TYPE TYPE
The type of this timer's counter (either uint8_t or uint16_t).
typename PRESCALERS_TRAIT::TYPE PRESCALER
The enum type listing all available precaler values for this timer.
#define UNUSED
Specific GCC attribute to declare an argument or variable unused, so that the compiler does not emit ...
@ NONE
No interrupt will be generated by the Anolog Comparator.
static constexpr const Tone SLUR
This special tone marks the following notes to be slurred together, ie no intertone delay shall occur...
static constexpr const Tone REPEAT_END
This special tone marks the end of a repeating sequence (started with REPEAT_START).
static constexpr const Tone END
This special tone marks the end of a melody (as a sequence of Tones).
static constexpr const Tone REPEAT_START
This special tone marks the beginning of sequence that shall be repeated later.
static constexpr const Tone TIE
This special tone marks the following notes to be tied together, ie their durations are added with no...
Defines API for audio tones (square waves) generation and simple melodies playing.
static constexpr Duration dotted(Duration d)
Transforms a note duration to its dotted value (1.5 times the given duration).
static constexpr Duration triplet(Duration d)
Transforms a note duration to allow it to use in a triplet.
Duration
Possible duration of a note, following music theory.
@ QUARTER
Duration of a quarter note; this is actually the duration of one beat.
@ SEMI_QUAVER
Other common name for a sixteenth note.
@ SIXTEENTH
Duration of a sixteenth note; a quarter the duration of a quarter!
@ CROTCHET
Other common name for a quarter note.
@ HALF
Duration of a half note; 2 times the duration of a quarter.
@ SEMI_BREVE
Other common name for a whole note.
@ WHOLE
Duration of a whole note; 4 times the duration of a quarter.
@ EIGHTH
Duration of an eighth note; half the duration of a quarter.
@ QUAVER
Other common name for an eighth note.
@ MINIM
Other common name for a half note.
Tone
This enum defines all possible audio tones that can be generated.
T * read_flash(uint16_t address, T *buffer, uint8_t size)
Read flash memory content at given address into buffer.
@ OUTPUT
Notification is dispatched whenever the Future output buffer gets filled, even partly.
void delay_ms(uint16_t ms) INLINE
Delay program execution for the given amount of milliseconds.
DELAY_PTR delay
Delay program execution for the given amount of milliseconds.
Defines a set of calculation methods for the given NTIMER_ The behavior of these methods is specific ...
static constexpr TYPE CTC_counter(PRESCALER prescaler, uint32_t us)
Computes the value of counter to use for this timer, in TimerMode::CTC mode, with prescaler,...
static constexpr PRESCALER CTC_prescaler(uint32_t us)
Computes the ideal prescaler value to use for this timer, in TimerMode::CTC mode, in order to be able...
API to handle tones (simple square waves) generation to a buzzer.