FastArduino  v1.7
C++ library to build fast but small Arduino/AVR projects
tone_player.h
Go to the documentation of this file.
1 // Copyright 2016-2021 Jean-Francois Poilpret
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
16 
21 #ifndef TONE_PLAYER_HH
22 #define TONE_PLAYER_HH
23 
24 #include "../eeprom.h"
25 #include "../flash.h"
26 #include "tones.h"
27 
28 namespace devices::audio
29 {
30  // Forward declaration
31  template<board::Timer NTIMER, board::PWMPin OUTPUT, typename TONEPLAY> class AbstractTonePlayer;
32 
39  namespace SpecialTone
40  {
44  static constexpr const Tone END = Tone::USER0;
45 
51  static constexpr const Tone REPEAT_START = Tone::USER1;
52 
59  static constexpr const Tone REPEAT_END = Tone::USER2;
60 
71  static constexpr const Tone TIE = Tone::USER3;
72 
85  static constexpr const Tone SLUR = TIE;
86  }
87 
103  enum class Duration : uint8_t
104  {
105  // Common names for notes durations
107  WHOLE = 32,
109  HALF = 16,
111  QUARTER = 8,
113  EIGHTH = 4,
115  SIXTEENTH = 2,
116 
117  // Synonyms for some notes durations
119  SEMI_BREVE = WHOLE,
121  MINIM = HALF,
123  CROTCHET = QUARTER,
125  QUAVER = EIGHTH,
127  SEMI_QUAVER = SIXTEENTH,
128  };
129 
133  static constexpr Duration dotted(Duration d)
134  {
135  return Duration(uint8_t(d) + uint8_t(d) / 2);
136  }
137 
141  static constexpr Duration triplet(Duration d)
142  {
143  return Duration(uint8_t(d) * 2 / 3);
144  }
145 
161  class TonePlay
162  {
163  public:
164  TonePlay(const TonePlay&) = default;
165  TonePlay& operator=(const TonePlay&) = default;
166 
174  TonePlay() = default;
175 
184  constexpr TonePlay(Tone tone, Duration duration) : tone_{tone}, duration_{duration} {}
185 
194  constexpr TonePlay(Tone tone, uint8_t value = 0) : tone_{tone}, repeats_{value} {}
195 
196  private:
197  Duration duration() const
198  {
199  return duration_;
200  }
201  bool is_tone() const
202  {
203  return tone_ > Tone::SILENCE;
204  }
205  bool is_pause() const
206  {
207  return tone_ == Tone::SILENCE;
208  }
209  bool is_end() const
210  {
211  return tone_ == SpecialTone::END;
212  }
213  bool is_repeat_start() const
214  {
215  return tone_ == SpecialTone::REPEAT_START;
216  }
217  bool is_repeat_end() const
218  {
219  return tone_ == SpecialTone::REPEAT_END;
220  }
221  uint8_t repeat_count() const
222  {
223  return repeats_;
224  }
225  bool is_tie() const
226  {
227  return tone_ == SpecialTone::TIE;
228  }
229  uint8_t num_ties() const
230  {
231  return ties_;
232  }
233 
234  template<board::Timer NTIMER, board::PWMPin OUTPUT>
235  void generate_tone(ToneGenerator<NTIMER, OUTPUT>& generator) const
236  {
237  generator.start_tone(tone_);
238  }
239 
240  Tone tone_;
241  union
242  {
243  Duration duration_;
244  uint8_t repeats_;
245  uint8_t ties_;
246  };
247 
248  template<board::Timer, board::PWMPin, typename> friend class AbstractTonePlayer;
249  };
250 
266  template<board::Timer NTIMER, board::PWMPin OUTPUT> class QTonePlay
267  {
268  public:
269  QTonePlay(const QTonePlay<NTIMER, OUTPUT>&) = default;
270  QTonePlay<NTIMER, OUTPUT>& operator=(const QTonePlay<NTIMER, OUTPUT>&) = default;
271 
279  QTonePlay() = default;
280 
289  constexpr QTonePlay(Tone tone, Duration duration)
290  : flags_{flags(tone)}, prescaler_{prescaler(tone)}, counter_{counter(tone)}, duration_{duration} {}
291 
300  constexpr QTonePlay(Tone tone, uint8_t value = 0)
301  : flags_{flags(tone)}, prescaler_{prescaler(tone)}, counter_{counter(tone)}, repeats_{value} {}
302 
303  private:
304  using CALC = timer::Calculator<NTIMER>;
305  using TIMER = timer::Timer<NTIMER>;
306  using PRESCALER = typename TIMER::PRESCALER;
307  using COUNTER = typename TIMER::TYPE;
308 
309  Duration duration() const
310  {
311  return duration_;
312  }
313  bool is_tone() const
314  {
315  return flags_ == TONE;
316  }
317  bool is_pause() const
318  {
319  return flags_ == NONE;
320  }
321  bool is_end() const
322  {
323  return flags_ == END;
324  }
325  bool is_repeat_start() const
326  {
327  return flags_ == REPEAT_START;
328  }
329  bool is_repeat_end() const
330  {
331  return flags_ == REPEAT_END;
332  }
333  uint8_t repeat_count() const
334  {
335  return repeats_;
336  }
337  bool is_tie() const
338  {
339  return flags_ == TIE;
340  }
341  uint8_t num_ties() const
342  {
343  return ties_;
344  }
345 
346  void generate_tone(ToneGenerator<NTIMER, OUTPUT>& generator) const
347  {
348  generator.start_tone(prescaler_, counter_);
349  }
350 
351  // Flags meaning
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;
358 
359  uint8_t flags_;
360  PRESCALER prescaler_;
361  COUNTER counter_;
362  union
363  {
364  Duration duration_;
365  uint8_t repeats_;
366  uint8_t ties_;
367  };
368 
369  static constexpr uint32_t period(Tone tone)
370  {
371  return ONE_SECOND / 2 / uint16_t(tone);
372  }
373  static constexpr PRESCALER prescaler(Tone tone)
374  {
375  return (tone > Tone::SILENCE ? CALC::CTC_prescaler(period(tone)) : PRESCALER::NO_PRESCALING);
376  }
377  static constexpr COUNTER counter(Tone tone)
378  {
379  return (tone > Tone::SILENCE ? CALC::CTC_counter(prescaler(tone), period(tone)) : 0);
380  }
381  static constexpr uint8_t flags(Tone tone)
382  {
383  if (tone == Tone::SILENCE) return NONE;
384  if (tone == SpecialTone::END) return END;
385  if (tone == SpecialTone::REPEAT_START) return REPEAT_START;
386  if (tone == SpecialTone::REPEAT_END) return REPEAT_END;
387  if (tone == SpecialTone::TIE) return TIE;
388  return TONE;
389  }
390 
391  friend class AbstractTonePlayer<NTIMER, OUTPUT, QTonePlay<NTIMER, OUTPUT>>;
392  };
393 
430  template<board::Timer NTIMER, board::PWMPin OUTPUT, typename TONEPLAY = QTonePlay<NTIMER, OUTPUT>>
432  {
433  protected:
437 
439  using TONE_PLAY = TONEPLAY;
442 
448  explicit AbstractTonePlayer(GENERATOR& tone_generator) : generator_{tone_generator} {}
449 
457  static constexpr uint16_t calculate_min_duration(uint8_t bpm)
458  {
459  // bpm defines the duration of a quarter note (in 4/4 mode)
460  // We want the minimum duration allowed (for a 32nd note, since we allow dotted sixteenth)
461  return (60U * 1000U / 8U) / bpm;
462  }
463 
470  void set_min_duration(uint16_t min_duration)
471  {
472  t32_duration_ms_ = min_duration;
473  }
474 
479  uint16_t get_min_duration() const
480  {
481  return t32_duration_ms_;
482  }
483 
489  void prepare_sram(const TONE_PLAY* melody)
490  {
491  prepare_(melody, load_sram);
492  }
493 
499  void prepare_eeprom(const TONE_PLAY* melody)
500  {
501  prepare_(melody, load_eeprom);
502  }
503 
509  void prepare_flash(const TONE_PLAY* melody)
510  {
511  prepare_(melody, load_flash);
512  }
513 
524  uint16_t start_next_note()
525  {
526  return start_next_();
527  }
528 
538  uint16_t stop_current_note()
539  {
540  return stop_current_();
541  }
542 
546  bool is_finished() const
547  {
548  return (loader_ == nullptr);
549  }
550 
551  private:
552  static constexpr const uint16_t INTERTONE_DELAY_MS = 20;
553 
554  using LOAD_TONE = const TONE_PLAY* (*) (const TONE_PLAY* address, TONE_PLAY& holder);
555 
556  void prepare_(const TONE_PLAY* melody, LOAD_TONE load_tone)
557  {
558  loader_ = load_tone;
559  current_play_ = melody;
560  repeat_play_ = nullptr;
561  repeat_times_ = 0;
562  tie_notes_ = 0;
563  }
564 
565  void reset_()
566  {
567  loader_ = nullptr;
568  current_play_ = nullptr;
569  repeat_play_ = nullptr;
570  repeat_times_ = 0;
571  tie_notes_ = 0;
572  }
573 
574  uint16_t start_next_()
575  {
576  if (loader_ == nullptr) return 0;
577 
578  TONE_PLAY holder;
579  const TONE_PLAY* current = loader_(current_play_, holder);
580  if (current->is_end())
581  {
582  reset_();
583  return 0;
584  }
585  uint16_t delay = 0;
586  no_delay_ = true;
587  if (current->is_repeat_start())
588  {
589  repeat_play_ = current_play_;
590  repeat_times_ = -1;
591  }
592  else if (current->is_repeat_end())
593  {
594  if (repeat_play_)
595  {
596  if (repeat_times_ == -1) repeat_times_ = current->repeat_count();
597  if (repeat_times_--)
598  current_play_ = repeat_play_;
599  else
600  repeat_play_ = nullptr;
601  }
602  }
603  else if (current->is_tie())
604  {
605  tie_notes_ = current->num_ties();
606  }
607  else
608  {
609  if (current->is_tone()) current->generate_tone(generator_);
610  if (tie_notes_)
611  --tie_notes_;
612  else
613  no_delay_ = false;
614  delay = duration(current->duration());
615  }
616  ++current_play_;
617  return delay;
618  }
619 
620  uint16_t stop_current_()
621  {
622  if (no_delay_)
623  return 0;
624  generator_.stop_tone();
625  return INTERTONE_DELAY_MS;
626  }
627 
628  uint16_t duration(Duration d) const
629  {
630  return uint8_t(d) * t32_duration_ms_;
631  }
632 
633  static const TONE_PLAY* load_sram(const TONE_PLAY* address, TONE_PLAY& holder UNUSED)
634  {
635  return address;
636  }
637  static const TONE_PLAY* load_eeprom(const TONE_PLAY* address, TONE_PLAY& holder)
638  {
639  eeprom::EEPROM::read(address, holder);
640  return &holder;
641  }
642  static const TONE_PLAY* load_flash(const TONE_PLAY* address, TONE_PLAY& holder)
643  {
644  flash::read_flash(address, holder);
645  return &holder;
646  }
647 
648  GENERATOR& generator_;
649  LOAD_TONE loader_ = nullptr;
650  uint16_t t32_duration_ms_ = 0U;
651  const TONE_PLAY* current_play_ = nullptr;
652  const TONE_PLAY* repeat_play_ = nullptr;
653  int8_t repeat_times_ = 0;
654  uint8_t tie_notes_ = 0;
655  bool no_delay_ = false;
656  };
657 
691  template<board::Timer NTIMER, board::PWMPin OUTPUT, typename TONEPLAY = QTonePlay<NTIMER, OUTPUT>>
692  class TonePlayer : public AbstractTonePlayer<NTIMER, OUTPUT, TONEPLAY>
693  {
695 
696  public:
698  using GENERATOR = typename BASE::GENERATOR;
700  using TONE_PLAY = typename BASE::TONE_PLAY;
701 
707  explicit TonePlayer(GENERATOR& tone_generator) : BASE{tone_generator} {}
708 
721  void play_sram(const TONE_PLAY* melody, uint8_t bpm)
722  {
724  this->prepare_sram(melody);
725  play_();
726  }
727 
740  void play_eeprom(const TONE_PLAY* melody, uint8_t bpm)
741  {
743  this->prepare_eeprom(melody);
744  play_();
745  }
746 
759  void play_flash(const TONE_PLAY* melody, uint8_t bpm)
760  {
762  this->prepare_flash(melody);
763  play_();
764  }
765 
770  void stop()
771  {
772  stop_ = true;
773  }
774 
778  bool is_playing() const
779  {
780  return !stop_;
781  }
782 
783  private:
784  void play_()
785  {
786  stop_ = false;
787  while (!stop_)
788  {
789  uint16_t delay = this->start_next_note();
790  if (delay) time::delay_ms(delay);
791  delay = this->stop_current_note();
792  if (delay) time::delay_ms(delay);
793  if (this->is_finished())
794  stop_ = true;
795  }
796  }
797 
798  volatile bool stop_ = true;
799  };
800 
835  template<board::Timer NTIMER, board::PWMPin OUTPUT, typename TONEPLAY = QTonePlay<NTIMER, OUTPUT>>
836  class AsyncTonePlayer : public AbstractTonePlayer<NTIMER, OUTPUT, TONEPLAY>
837  {
840 
841  public:
843  using GENERATOR = typename BASE::GENERATOR;
845  using TONE_PLAY = typename BASE::TONE_PLAY;
846 
852  explicit AsyncTonePlayer(GENERATOR& tone_generator) : BASE{tone_generator} {}
853 
864  uint16_t get_min_duration() const
865  {
866  return BASE::get_min_duration();
867  }
868 
883  void play_sram(const TONE_PLAY* melody, uint8_t bpm)
884  {
885  status_ = Status::NOT_STARTED;
887  this->prepare_sram(melody);
888  next_time_ = 0;
889  status_ = Status::STARTED;
890  }
891 
906  void play_eeprom(const TONE_PLAY* melody, uint8_t bpm)
907  {
908  status_ = Status::NOT_STARTED;
910  this->prepare_eeprom(melody);
911  next_time_ = 0;
912  status_ = Status::STARTED;
913  }
914 
929  void play_flash(const TONE_PLAY* melody, uint8_t bpm)
930  {
931  status_ = Status::NOT_STARTED;
933  this->prepare_flash(melody);
934  next_time_ = 0;
935  status_ = Status::STARTED;
936  }
937 
942  void stop()
943  {
944  status_ = Status::NOT_STARTED;
945  this->stop_current_note();
946  }
947 
951  bool is_playing() const
952  {
953  return status_ != Status::NOT_STARTED;
954  }
955 
966  void update(uint32_t rtt_millis)
967  {
968  if ((status_ != Status::NOT_STARTED) && (rtt_millis >= next_time_))
969  {
970  uint16_t delay;
971  Status next;
972  if (status_ == Status::PLAYING_NOTE)
973  {
974  delay = this->stop_current_note();
975  next = Status::PLAYING_INTERNOTE;
976  }
977  else
978  {
979  delay = this->start_next_note();
980  next = Status::PLAYING_NOTE;
981  }
982 
983  if (this->is_finished())
984  status_ = Status::NOT_STARTED;
985  else
986  {
987  next_time_ = rtt_millis + delay;
988  status_ = next;
989  }
990  }
991  }
992 
993  private:
994  enum class Status : uint8_t
995  {
996  NOT_STARTED = 0,
997  STARTED,
998  PLAYING_NOTE,
999  PLAYING_INTERNOTE
1000  };
1001 
1002  Status status_ = Status::NOT_STARTED;
1003  uint32_t next_time_ = 0UL;
1004  };
1005 }
1006 
1007 #endif /* TONE_PLAYER_HH */
1008 
devices::audio::AbstractTonePlayer
This low-level API defines an abstract player of melodies (defined as a sequence of tones and duratio...
Definition: tone_player.h:432
devices::audio::AbstractTonePlayer::stop_current_note
uint16_t stop_current_note()
Ask this player to stop playing the current note of the melody.
Definition: tone_player.h:538
devices::audio::TonePlay::TonePlay
TonePlay()=default
Default constructor, used only to declare an uninitialized TonePlay variable.
timer::Calculator::CTC_counter
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,...
Definition: timer.h:423
devices::audio::AbstractTonePlayer::set_min_duration
void set_min_duration(uint16_t min_duration)
Set the duration, in milliseconds, of a 32nd note.
Definition: tone_player.h:470
devices::audio::Duration::WHOLE
@ WHOLE
Duration of a whole note; 4 times the duration of a quarter.
tones.h
API to handle tones (simple square waves) generation to a buzzer.
devices::audio::AsyncTonePlayer::play_sram
void play_sram(const TONE_PLAY *melody, uint8_t bpm)
Start playing a melody, defined by a sequence of TONE_PLAYs, stored in SRAM.
Definition: tone_player.h:883
devices::audio::Tone
Tone
This enum defines all possible audio tones that can be generated.
Definition: tones.h:57
devices::audio::dotted
static constexpr Duration dotted(Duration d)
Transforms a note duration to its dotted value (1.5 times the given duration).
Definition: tone_player.h:133
devices::audio::QTonePlay::QTonePlay
constexpr QTonePlay(Tone tone, Duration duration)
Construct an optimized tone play for the provided tone and duration.
Definition: tone_player.h:289
time::delay
DELAY_PTR delay
Delay program execution for the given amount of milliseconds.
Definition: time.cpp:19
devices::audio::AsyncTonePlayer::GENERATOR
typename BASE::GENERATOR GENERATOR
The type of ToneGenerator to use as constructor's argument.
Definition: tone_player.h:843
devices::audio::TonePlay
This struct is the unit data manipulated by TonePlayer: it describes one Tone along with its duration...
Definition: tone_player.h:162
devices::audio::AsyncTonePlayer
This API defines a player of melodies, defined as a sequence of tones and durations.
Definition: tone_player.h:837
devices::audio::AbstractTonePlayer::start_next_note
uint16_t start_next_note()
Ask this player to start playing the next note of the melody.
Definition: tone_player.h:524
timer::Timer< NTIMER >::PRESCALER
typename PRESCALERS_TRAIT::TYPE PRESCALER
The enum type listing all available precaler values for this timer.
Definition: timer.h:733
devices::audio::ToneGenerator::stop_tone
void stop_tone()
Stop the tone being currently generated to the connected buzzer.
Definition: tones.h:240
devices::audio::SpecialTone::SLUR
static constexpr const Tone SLUR
This special tone marks the following notes to be slurred together, ie no intertone delay shall occur...
Definition: tone_player.h:85
devices::audio::triplet
static constexpr Duration triplet(Duration d)
Transforms a note duration to allow it to use in a triplet.
Definition: tone_player.h:141
devices::audio::AbstractTonePlayer::AbstractTonePlayer
AbstractTonePlayer(GENERATOR &tone_generator)
Create a new tone player, based on an existing ToneGenerator.
Definition: tone_player.h:448
devices::audio::TonePlayer::stop
void stop()
Stop playing current melody (if any).
Definition: tone_player.h:770
devices::audio::AsyncTonePlayer::stop
void stop()
Stop playing current melody (if any).
Definition: tone_player.h:942
devices::audio::AsyncTonePlayer::TONE_PLAY
typename BASE::TONE_PLAY TONE_PLAY
The type that holds unit of information of a melody.
Definition: tone_player.h:845
flash::read_flash
T & read_flash(uint16_t address, T &item)
Read flash memory content at given address into item.
Definition: flash.h:47
devices::audio::SpecialTone::END
static constexpr const Tone END
This special tone marks the end of a melody (as a sequence of Tones).
Definition: tone_player.h:44
devices::audio::AsyncTonePlayer::AsyncTonePlayer
AsyncTonePlayer(GENERATOR &tone_generator)
Create a new asynchronous tone player, based on an existing ToneGenerator.
Definition: tone_player.h:852
devices::audio::AsyncTonePlayer::is_playing
bool is_playing() const
Tell if a melody is currently playing.
Definition: tone_player.h:951
devices::audio::TonePlayer::play_flash
void play_flash(const TONE_PLAY *melody, uint8_t bpm)
Play a melody, defined by a sequence of TONE_PLAYs, stored in Flash.
Definition: tone_player.h:759
i2c::Status
Status
Transmission status codes.
Definition: i2c.h:66
devices::audio::ToneGenerator
API class for tone generation to a buzzer (or better an amplifier) connected to pin OUTPUT.
Definition: tones.h:183
board::Port::PORT_A
@ PORT_A
Port A (8 IO)
devices::audio::QTonePlay::QTonePlay
constexpr QTonePlay(Tone tone, uint8_t value=0)
Construct a "special" optimized tone play with the provided value.
Definition: tone_player.h:300
devices::audio::TonePlayer
This API defines a player of melodies, defined as a sequence of tones and durations.
Definition: tone_player.h:693
timer::Timer< NTIMER >
devices::audio::AbstractTonePlayer::prepare_flash
void prepare_flash(const TONE_PLAY *melody)
Prepare playing of melody, which should be stored in Flash.
Definition: tone_player.h:509
devices::audio::AbstractTonePlayer::is_finished
bool is_finished() const
Indicate if the currently played melody is finished.
Definition: tone_player.h:546
UNUSED
#define UNUSED
Specific GCC attribute to declare an argument or variable unused, so that the compiler does not emit ...
Definition: defines.h:45
timer::Timer< NTIMER >::TYPE
typename TRAIT::TYPE TYPE
The type of this timer's counter (either uint8_t or uint16_t).
Definition: timer.h:723
devices::audio::AsyncTonePlayer::update
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...
Definition: tone_player.h:966
devices::audio::QTonePlay::QTonePlay
QTonePlay()=default
Default constructor, used only to declare an uninitialized QTonePlay variable.
gpio::PinMode::INPUT
@ INPUT
Digital pin is configured as high-impedance (open drain) input.
devices::audio::TonePlay::TonePlay
constexpr TonePlay(Tone tone, uint8_t value=0)
Construct a "special" tone play with the provided value.
Definition: tone_player.h:194
devices::audio::SpecialTone::REPEAT_END
static constexpr const Tone REPEAT_END
This special tone marks the end of a repeating sequence (started with REPEAT_START).
Definition: tone_player.h:59
devices::audio::TonePlayer::play_eeprom
void play_eeprom(const TONE_PLAY *melody, uint8_t bpm)
Play a melody, defined by a sequence of TONE_PLAYs, stored in EEPROM.
Definition: tone_player.h:740
devices::audio::AbstractTonePlayer::GENERATOR
ToneGenerator< NTIMER, OUTPUT > GENERATOR
The type of ToneGenerator to use as constructor's argument.
Definition: tone_player.h:441
devices::audio::AbstractTonePlayer::prepare_sram
void prepare_sram(const TONE_PLAY *melody)
Prepare playing of melody, which should be stored in SRAM.
Definition: tone_player.h:489
timer::Calculator
Defines a set of calculation methods for the given NTIMER_ The behavior of these methods is specific ...
Definition: timer.h:302
devices::audio::AsyncTonePlayer::play_eeprom
void play_eeprom(const TONE_PLAY *melody, uint8_t bpm)
Start playing a melody, defined by a sequence of TONE_PLAYs, stored in EEPROM.
Definition: tone_player.h:906
devices::audio::TonePlayer::TONE_PLAY
typename BASE::TONE_PLAY TONE_PLAY
The type that holds unit of information of a melody.
Definition: tone_player.h:700
devices::audio::AbstractTonePlayer::get_min_duration
uint16_t get_min_duration() const
Get the duration, in milliseconds, of a 32nd note.
Definition: tone_player.h:479
devices::audio::Duration
Duration
Possible duration of a note, following music theory.
Definition: tone_player.h:104
devices::audio::AbstractTonePlayer::TONE_PLAY
TONEPLAY TONE_PLAY
The type that holds unit of information of a melody.
Definition: tone_player.h:439
devices::audio::AsyncTonePlayer::get_min_duration
uint16_t get_min_duration() const
Get the duration, in milliseconds, of a 32nd note.
Definition: tone_player.h:864
devices::audio
Defines API for audio tones (square waves) generation and simple melodies playing.
Definition: tone_player.h:29
devices::audio::SpecialTone::TIE
static constexpr const Tone TIE
This special tone marks the following notes to be tied together, ie their durations are added with no...
Definition: tone_player.h:71
eeprom::EEPROM::read
static bool read(const T *address, T &value)
Read value of type T stored in EEPROM at address.
Definition: eeprom.h:149
devices::audio::SpecialTone::REPEAT_START
static constexpr const Tone REPEAT_START
This special tone marks the beginning of sequence that shall be repeated later.
Definition: tone_player.h:51
devices::audio::TonePlayer::TonePlayer
TonePlayer(GENERATOR &tone_generator)
Create a new synchronous tone player, based on an existing ToneGenerator.
Definition: tone_player.h:707
devices::audio::AbstractTonePlayer::prepare_eeprom
void prepare_eeprom(const TONE_PLAY *melody)
Prepare playing of melody, which should be stored in EEPROM.
Definition: tone_player.h:499
time::delay_ms
void delay_ms(uint16_t ms) INLINE
Delay program execution for the given amount of milliseconds.
Definition: time.h:346
devices::audio::TonePlayer::is_playing
bool is_playing() const
Tell if a melody is currently playing.
Definition: tone_player.h:778
devices::audio::AbstractTonePlayer::calculate_min_duration
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...
Definition: tone_player.h:457
devices::audio::TonePlayer::play_sram
void play_sram(const TONE_PLAY *melody, uint8_t bpm)
Play a melody, defined by a sequence of TONE_PLAYs, stored in SRAM.
Definition: tone_player.h:721
devices::audio::AsyncTonePlayer::play_flash
void play_flash(const TONE_PLAY *melody, uint8_t bpm)
Start playing a melody, defined by a sequence of TONE_PLAYs, stored in Flash.
Definition: tone_player.h:929
devices::audio::TonePlay::TonePlay
constexpr TonePlay(Tone tone, Duration duration)
Construct a tone play with the provided tone and duration.
Definition: tone_player.h:184
timer::Calculator::CTC_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...
Definition: timer.h:390
devices::audio::TonePlayer::GENERATOR
typename BASE::GENERATOR GENERATOR
The type of ToneGenerator to use as constructor's argument.
Definition: tone_player.h:698
devices::audio::QTonePlay
An optimized surrogate to TonePlay structure.
Definition: tone_player.h:267