9 static const char *
const TAG =
"rtttl";
11 static const uint32_t DOUBLE_NOTE_GAP_MS = 10;
14 static const uint16_t NOTES[] = {0, 262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494,
15 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988, 1047,
16 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976, 2093, 2217,
17 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951};
19 static const uint16_t I2S_SPEED = 1600;
22 static const double HALF_PI = 1.5707963267948966192313216916398;
25 static const double PI_ON_180 = 4.0 * atan(1.0) / 180.0;
26 return degrees * PI_ON_180;
32 this->
rtttl_ = std::move(rtttl);
46 ESP_LOGE(TAG,
"Missing ':' when looking for name.");
51 ESP_LOGD(TAG,
"Playing song %s",
name.c_str());
55 if (this->position_ == std::string::npos) {
56 ESP_LOGE(TAG,
"Missing 'd='");
65 this->position_ = this->
rtttl_.find(
"o=", this->position_);
66 if (this->position_ == std::string::npos) {
67 ESP_LOGE(TAG,
"Missing 'o=");
72 if (num >= 3 && num <= 7)
76 this->position_ = this->
rtttl_.find(
"b=", this->position_);
77 if (this->position_ == std::string::npos) {
78 ESP_LOGE(TAG,
"Missing b=");
86 this->position_ = this->
rtttl_.find(
':', this->position_);
87 if (this->position_ == std::string::npos) {
88 ESP_LOGE(TAG,
"Missing second ':'");
109 if (this->
output_ !=
nullptr) {
156 int send = this->
speaker_->
play((uint8_t *) (&sample), x * 4);
172 if (this->
output_ !=
nullptr) {
176 ESP_LOGD(TAG,
"Playback finished");
182 while (this->
rtttl_[this->position_] ==
',' || this->
rtttl_[this->position_] ==
' ')
197 switch (this->
rtttl_[this->position_]) {
226 if (this->
rtttl_[this->position_] ==
'#') {
232 if (this->
rtttl_[this->position_] ==
'.') {
241 bool need_note_gap =
false;
245 auto note_index = (scale - 4) * 12 + note;
246 if (note_index < 0 || note_index >= (
int)
sizeof(NOTES)) {
247 ESP_LOGE(TAG,
"Note out of valid range");
251 auto freq = NOTES[note_index];
257 ESP_LOGVV(TAG,
"playing note: %d for %dms", note, this->
note_duration_);
264 if (this->
output_ !=
nullptr) {
267 delay(DOUBLE_NOTE_GAP_MS);
virtual size_t play(const uint8_t *data, size_t length)=0
void play(std::string rtttl)
void dump_config() override
CallbackManager< void()> on_finished_playback_callback_
speaker::Speaker * speaker_
uint32_t IRAM_ATTR HOT millis()
void set_level(float state)
Set the level of this float output, this is called from the front-end.
double deg2rad(double degrees)
uint16_t default_duration_
output::FloatOutput * output_
Implementation of SPI Controller mode.
virtual void update_frequency(float frequency)
Set the frequency of the output for PWM outputs.
void IRAM_ATTR HOT delay(uint32_t ms)