FastArduino
v1.8
C++ library to build fast but small Arduino/AVR projects
|
Go to the documentation of this file.
21 #ifndef TONE_PLAYER_HH
22 #define TONE_PLAYER_HH
24 #include "../eeprom.h"
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);
194 constexpr
TonePlay(
Tone tone, uint8_t value = 0) : tone_{tone}, repeats_{value} {}
203 return tone_ > Tone::SILENCE;
205 bool is_pause()
const
207 return tone_ == Tone::SILENCE;
213 bool is_repeat_start()
const
217 bool is_repeat_end()
const
221 uint8_t repeat_count()
const
229 uint8_t num_ties()
const
234 template<board::Timer NTIMER, board::PWMPin OUTPUT>
235 void generate_tone(ToneGenerator<NTIMER, OUTPUT>& generator)
const
237 generator.start_tone(tone_);
248 template<board::Timer, board::PWMPin,
typename>
friend class AbstractTonePlayer;
266 template<board::Timer NTIMER, board::PWMPin OUTPUT>
class QTonePlay
290 : flags_{flags(tone)}, prescaler_{prescaler(tone)}, counter_{counter(tone)}, duration_{duration} {}
301 : flags_{flags(tone)}, prescaler_{prescaler(tone)}, counter_{counter(tone)}, repeats_{value} {}
315 return flags_ == TONE;
317 bool is_pause()
const
319 return flags_ == NONE;
323 return flags_ == END;
325 bool is_repeat_start()
const
327 return flags_ == REPEAT_START;
329 bool is_repeat_end()
const
331 return flags_ == REPEAT_END;
333 uint8_t repeat_count()
const
339 return flags_ == TIE;
341 uint8_t num_ties()
const
346 void generate_tone(ToneGenerator<NTIMER, OUTPUT>& generator)
const
348 generator.start_tone(prescaler_, counter_);
352 static constexpr uint8_t TONE = 0x00;
353 static constexpr uint8_t NONE = 0x01;
354 static constexpr uint8_t END = 0x02;
355 static constexpr uint8_t REPEAT_START = 0x04;
356 static constexpr uint8_t REPEAT_END = 0x08;
357 static constexpr uint8_t TIE = 0x10;
360 PRESCALER prescaler_;
369 static constexpr uint32_t period(
Tone tone)
371 return ONE_SECOND / 2 / uint16_t(tone);
373 static constexpr PRESCALER prescaler(
Tone tone)
375 return (tone > Tone::SILENCE ?
CALC::CTC_prescaler(period(tone)) : PRESCALER::NO_PRESCALING);
377 static constexpr COUNTER counter(
Tone tone)
379 return (tone > Tone::SILENCE ?
CALC::CTC_counter(prescaler(tone), period(tone)) : 0);
381 static constexpr uint8_t flags(
Tone tone)
383 if (tone == Tone::SILENCE)
return NONE;
430 template<board::Timer NTIMER, board::PWMPin OUTPUT,
typename TONEPLAY = QTonePlay<NTIMER, OUTPUT>>
461 return (60U * 1000U / 8U) / bpm;
472 t32_duration_ms_ = min_duration;
481 return t32_duration_ms_;
491 prepare_(melody, load_sram);
501 prepare_(melody, load_eeprom);
511 prepare_(melody, load_flash);
526 return start_next_();
540 return stop_current_();
548 return (loader_ ==
nullptr);
552 static constexpr
const uint16_t INTERTONE_DELAY_MS = 20;
556 void prepare_(
const TONE_PLAY* melody, LOAD_TONE load_tone)
559 current_play_ = melody;
560 repeat_play_ =
nullptr;
568 current_play_ =
nullptr;
569 repeat_play_ =
nullptr;
574 uint16_t start_next_()
576 if (loader_ ==
nullptr)
return 0;
579 const TONE_PLAY* current = loader_(current_play_, holder);
580 if (current->is_end())
587 if (current->is_repeat_start())
589 repeat_play_ = current_play_;
592 else if (current->is_repeat_end())
596 if (repeat_times_ == -1) repeat_times_ = current->repeat_count();
598 current_play_ = repeat_play_;
600 repeat_play_ =
nullptr;
603 else if (current->is_tie())
605 tie_notes_ = current->num_ties();
609 if (current->is_tone()) current->generate_tone(generator_);
614 delay = duration(current->duration());
620 uint16_t stop_current_()
625 return INTERTONE_DELAY_MS;
630 return uint8_t(d) * t32_duration_ms_;
649 LOAD_TONE loader_ =
nullptr;
650 uint16_t t32_duration_ms_ = 0U;
651 const TONE_PLAY* current_play_ =
nullptr;
653 int8_t repeat_times_ = 0;
654 uint8_t tie_notes_ = 0;
655 bool no_delay_ =
false;
691 template<board::Timer NTIMER, board::PWMPin OUTPUT,
typename TONEPLAY = QTonePlay<NTIMER, OUTPUT>>
798 volatile bool stop_ =
true;
835 template<board::Timer NTIMER, board::PWMPin OUTPUT,
typename TONEPLAY = QTonePlay<NTIMER, OUTPUT>>
885 status_ = Status::NOT_STARTED;
889 status_ = Status::STARTED;
908 status_ = Status::NOT_STARTED;
912 status_ = Status::STARTED;
931 status_ = Status::NOT_STARTED;
935 status_ = Status::STARTED;
944 status_ = Status::NOT_STARTED;
953 return status_ != Status::NOT_STARTED;
968 if ((status_ != Status::NOT_STARTED) && (rtt_millis >= next_time_))
972 if (status_ == Status::PLAYING_NOTE)
975 next = Status::PLAYING_INTERNOTE;
980 next = Status::PLAYING_NOTE;
984 status_ = Status::NOT_STARTED;
987 next_time_ = rtt_millis +
delay;
994 enum class Status : uint8_t
1002 Status status_ = Status::NOT_STARTED;
1003 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 stop_current_note()
Ask this player to stop playing the current note of the melody.
TonePlay()=default
Default constructor, used only to declare an uninitialized TonePlay variable.
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,...
void set_min_duration(uint16_t min_duration)
Set the duration, in milliseconds, of a 32nd note.
@ WHOLE
Duration of a whole note; 4 times the duration of a quarter.
API to handle tones (simple square waves) generation to a buzzer.
void play_sram(const TONE_PLAY *melody, uint8_t bpm)
Start playing a melody, defined by a sequence of TONE_PLAYs, stored in SRAM.
Tone
This enum defines all possible audio tones that can be generated.
static constexpr Duration dotted(Duration d)
Transforms a note duration to its dotted value (1.5 times the given duration).
constexpr QTonePlay(Tone tone, Duration duration)
Construct an optimized tone play for the provided tone and duration.
DELAY_PTR delay
Delay program execution for the given amount of milliseconds.
typename BASE::GENERATOR GENERATOR
The type of ToneGenerator to use as constructor's argument.
This struct is the unit data manipulated by TonePlayer: it describes one Tone along with its duration...
This API defines a player of melodies, defined as a sequence of tones and durations.
uint16_t start_next_note()
Ask this player to start playing the next note of the melody.
typename PRESCALERS_TRAIT::TYPE PRESCALER
The enum type listing all available precaler values for this timer.
void stop_tone()
Stop the tone being currently generated to the connected buzzer.
static constexpr const Tone SLUR
This special tone marks the following notes to be slurred together, ie no intertone delay shall occur...
static constexpr Duration triplet(Duration d)
Transforms a note duration to allow it to use in a triplet.
AbstractTonePlayer(GENERATOR &tone_generator)
Create a new tone player, based on an existing ToneGenerator.
void stop()
Stop playing current melody (if any).
void stop()
Stop playing current melody (if any).
typename BASE::TONE_PLAY TONE_PLAY
The type that holds unit of information of a melody.
static constexpr const Tone END
This special tone marks the end of a melody (as a sequence of Tones).
AsyncTonePlayer(GENERATOR &tone_generator)
Create a new asynchronous tone player, based on an existing ToneGenerator.
bool is_playing() const
Tell if a melody is currently playing.
void play_flash(const TONE_PLAY *melody, uint8_t bpm)
Play a melody, defined by a sequence of TONE_PLAYs, stored in Flash.
Status
Transmission status codes.
API class for tone generation to a buzzer (or better an amplifier) connected to pin OUTPUT.
constexpr QTonePlay(Tone tone, uint8_t value=0)
Construct a "special" optimized tone play with the provided value.
This API defines a player of melodies, defined as a sequence of tones and durations.
void prepare_flash(const TONE_PLAY *melody)
Prepare playing of melody, which should be stored in Flash.
bool is_finished() const
Indicate if the currently played melody is finished.
#define UNUSED
Specific GCC attribute to declare an argument or variable unused, so that the compiler does not emit ...
typename TRAIT::TYPE TYPE
The type of this timer's counter (either uint8_t or uint16_t).
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...
QTonePlay()=default
Default constructor, used only to declare an uninitialized QTonePlay variable.
@ INPUT
Digital pin is configured as high-impedance (open drain) input.
constexpr TonePlay(Tone tone, uint8_t value=0)
Construct a "special" tone play with the provided value.
static constexpr const Tone REPEAT_END
This special tone marks the end of a repeating sequence (started with REPEAT_START).
void play_eeprom(const TONE_PLAY *melody, uint8_t bpm)
Play a melody, defined by a sequence of TONE_PLAYs, stored in EEPROM.
ToneGenerator< NTIMER, OUTPUT > GENERATOR
The type of ToneGenerator to use as constructor's argument.
void prepare_sram(const TONE_PLAY *melody)
Prepare playing of melody, which should be stored in SRAM.
Defines a set of calculation methods for the given NTIMER_ The behavior of these methods is specific ...
void play_eeprom(const TONE_PLAY *melody, uint8_t bpm)
Start playing a melody, defined by a sequence of TONE_PLAYs, stored in EEPROM.
typename BASE::TONE_PLAY TONE_PLAY
The type that holds unit of information of a melody.
uint16_t get_min_duration() const
Get the duration, in milliseconds, of a 32nd note.
Duration
Possible duration of a note, following music theory.
TONEPLAY TONE_PLAY
The type that holds unit of information of a melody.
T * read_flash(uint16_t address, T *buffer, uint8_t size)
Read flash memory content at given address into buffer.
uint16_t get_min_duration() const
Get the duration, in milliseconds, of a 32nd note.
Defines API for audio tones (square waves) generation and simple melodies playing.
static constexpr const Tone TIE
This special tone marks the following notes to be tied together, ie their durations are added with no...
static bool read(const T *address, T &value)
Read value of type T stored in EEPROM at address.
static constexpr const Tone REPEAT_START
This special tone marks the beginning of sequence that shall be repeated later.
TonePlayer(GENERATOR &tone_generator)
Create a new synchronous tone player, based on an existing ToneGenerator.
void prepare_eeprom(const TONE_PLAY *melody)
Prepare playing of melody, which should be stored in EEPROM.
void delay_ms(uint16_t ms) INLINE
Delay program execution for the given amount of milliseconds.
bool is_playing() const
Tell if a melody is currently playing.
static constexpr uint16_t calculate_min_duration(uint8_t bpm)
Calculate the minimum duration (duration of a 32nd note), in milliseconds, for the given tempo (beats...
void play_sram(const TONE_PLAY *melody, uint8_t bpm)
Play a melody, defined by a sequence of TONE_PLAYs, stored in SRAM.
void play_flash(const TONE_PLAY *melody, uint8_t bpm)
Start playing a melody, defined by a sequence of TONE_PLAYs, stored in Flash.
constexpr TonePlay(Tone tone, Duration duration)
Construct a tone play with the provided tone and duration.
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...
typename BASE::GENERATOR GENERATOR
The type of ToneGenerator to use as constructor's argument.
An optimized surrogate to TonePlay structure.