earlephilhower / ESP8266Audio

Arduino library to play MOD, WAV, FLAC, MIDI, RTTTL, MP3, and AAC files on I2S DACs or with a software emulated delta-sigma DAC on the ESP8266 and ESP32
GNU General Public License v3.0
1.98k stars 432 forks source link

feature request: simple I2S tone() generator #643

Open aIecxs opened 11 months ago

aIecxs commented 11 months ago

I need a tone() function that can redirect audio to the DAC. ChatGPT is hallucinating and recommended <AudioGeneratorTone.h>, which, of course, does not exist.

MP3 works fine, but I want to use tone() on the same speaker without additional wiring. I have seen Arduino SimpleTone <I2S.h>, but I don't know how to change the default pinout for ESP32. I2S.setBCLK(bclkPin), I2S.setDOUT(doutPin), or I2S.setLRCLK(wclkPin)? are unknown on Arduino 1.8.19. That's why I prefer ESP8266Audio.

I had a look into AudioGeneratorRTTTL.cpp, but I don't understand how the tones are generated. I decided to play RTTTL notes instead, but I feel this is overloading with unnecessary code and memory waste. Furthermore, the notes sound different, and the mapping is inaccurate.

Click to expand ``` #include #include #include #define WCLK_PIN 25 #define BCLK_PIN 26 #define DOUT_PIN 27 AudioFileSourcePROGMEM *file; AudioGeneratorRTTTL *rtttl; AudioOutputI2S *out; void beep(int freq, unsigned int duration) { out = new AudioOutputI2S(); out->SetPinout(BCLK_PIN, WCLK_PIN, DOUT_PIN); out->SetGain(1.0); unsigned long tempo = 240000 / duration; char rtttlString[26]; String note; if (freq <= 262) note = "c4"; else if (262 < freq && freq <= 277) note = abs(freq - 262) < abs(277 - freq) ? "c4" : "c#4"; else if (277 < freq && freq <= 294) note = abs(freq - 277) < abs(294 - freq) ? "c#4" : "d4"; else if (294 < freq && freq <= 311) note = abs(freq - 294) < abs(311 - freq) ? "d4" : "d#4"; else if (311 < freq && freq <= 330) note = abs(freq - 311) < abs(330 - freq) ? "d#4" : "e4"; else if (330 < freq && freq <= 349) note = abs(freq - 330) < abs(349 - freq) ? "e4" : "f4"; else if (349 < freq && freq <= 370) note = abs(freq - 349) < abs(370 - freq) ? "f4" : "f#4"; else if (370 < freq && freq <= 392) note = abs(freq - 370) < abs(392 - freq) ? "f#4" : "g4"; else if (392 < freq && freq <= 415) note = abs(freq - 392) < abs(415 - freq) ? "g4" : "g#4"; else if (415 < freq && freq <= 440) note = abs(freq - 415) < abs(440 - freq) ? "g#4" : "a4"; else if (440 < freq && freq <= 466) note = abs(freq - 440) < abs(466 - freq) ? "a4" : "a#4"; else if (466 < freq && freq <= 494) note = abs(freq - 466) < abs(494 - freq) ? "a#4" : "b4"; else if (494 < freq && freq <= 523) note = abs(freq - 494) < abs(523 - freq) ? "b4" : "c5"; else if (523 < freq && freq <= 554) note = abs(freq - 523) < abs(554 - freq) ? "c5" : "c#5"; else if (554 < freq && freq <= 587) note = abs(freq - 554) < abs(587 - freq) ? "c#5" : "d5"; else if (587 < freq && freq <= 622) note = abs(freq - 587) < abs(622 - freq) ? "d5" : "d#5"; else if (622 < freq && freq <= 659) note = abs(freq - 622) < abs(659 - freq) ? "d#5" : "e5"; else if (659 < freq && freq <= 698) note = abs(freq - 659) < abs(698 - freq) ? "e5" : "f5"; else if (698 < freq && freq <= 740) note = abs(freq - 698) < abs(740 - freq) ? "f5" : "f#5"; else if (740 < freq && freq <= 784) note = abs(freq - 740) < abs(784 - freq) ? "f#5" : "g5"; else if (784 < freq && freq <= 831) note = abs(freq - 784) < abs(831 - freq) ? "g5" : "g#5"; else if (831 < freq && freq <= 880) note = abs(freq - 831) < abs(880 - freq) ? "g#5" : "a5"; else if (880 < freq && freq <= 932) note = abs(freq - 880) < abs(932 - freq) ? "a5" : "a#5"; else if (932 < freq && freq <= 988) note = abs(freq - 932) < abs(988 - freq) ? "a#5" : "b5"; else if (988 < freq && freq <= 1047) note = abs(freq - 988) < abs(1047 - freq) ? "b5" : "c6"; else if (1047 < freq && freq <= 1109) note = abs(freq - 1047) < abs(1109 - freq) ? "c6" : "c#6"; else if (1109 < freq && freq <= 1175) note = abs(freq - 1109) < abs(1175 - freq) ? "c#6" : "d6"; else if (1175 < freq && freq <= 1245) note = abs(freq - 1175) < abs(1245 - freq) ? "d6" : "d#6"; else if (1245 < freq && freq <= 1319) note = abs(freq - 1245) < abs(1319 - freq) ? "d#6" : "e6"; else if (1319 < freq && freq <= 1397) note = abs(freq - 1319) < abs(1397 - freq) ? "e6" : "f6"; else if (1397 < freq && freq <= 1480) note = abs(freq - 1397) < abs(1480 - freq) ? "f6" : "f#6"; else if (1480 < freq && freq <= 1568) note = abs(freq - 1480) < abs(1568 - freq) ? "f#6" : "g6"; else if (1568 < freq && freq <= 1661) note = abs(freq - 1568) < abs(1661 - freq) ? "g6" : "g#6"; else if (1661 < freq && freq <= 1760) note = abs(freq - 1661) < abs(1760 - freq) ? "g#6" : "a6"; else if (1760 < freq && freq <= 1865) note = abs(freq - 1760) < abs(1865 - freq) ? "a6" : "a#6"; else if (1865 < freq && freq <= 1976) note = abs(freq - 1865) < abs(1976 - freq) ? "a#6" : "b6"; else if (1976 < freq && freq <= 2093) note = abs(freq - 1976) < abs(2093 - freq) ? "b6" : "c7"; else if (2093 < freq && freq <= 2217) note = abs(freq - 2093) < abs(2217 - freq) ? "c7" : "c#7"; else if (2217 < freq && freq <= 2349) note = abs(freq - 2217) < abs(2349 - freq) ? "c#7" : "d7"; else if (2349 < freq && freq <= 2489) note = abs(freq - 2349) < abs(2489 - freq) ? "d7" : "d#7"; else if (2489 < freq && freq <= 2637) note = abs(freq - 2489) < abs(2637 - freq) ? "d#7" : "e7"; else if (2637 < freq && freq <= 2794) note = abs(freq - 2637) < abs(2794 - freq) ? "e7" : "f7"; else if (2794 < freq && freq <= 2960) note = abs(freq - 2794) < abs(2960 - freq) ? "f7" : "f#7"; else if (2960 < freq && freq <= 3136) note = abs(freq - 2960) < abs(3136 - freq) ? "f#7" : "g7"; else if (3136 < freq && freq <= 3322) note = abs(freq - 3136) < abs(3322 - freq) ? "g7" : "g#7"; else if (3322 < freq && freq <= 3520) note = abs(freq - 3322) < abs(3520 - freq) ? "g#7" : "a7"; else if (3520 < freq && freq <= 3729) note = abs(freq - 3520) < abs(3729 - freq) ? "a7" : "a#7"; else if (3729 < freq && freq <= 3951) note = abs(freq - 3729) < abs(3951 - freq) ? "a#7" : "b7"; else if (freq > 3951) note = "b7"; snprintf(rtttlString, sizeof(rtttlString), "note:d=1,o=5,b=%d:%s", tempo, note); file = new AudioFileSourcePROGMEM(rtttlString, strlen_P(rtttlString)); rtttl = new AudioGeneratorRTTTL(); rtttl->begin(file, out); while (rtttl->isRunning()) { if (!rtttl->loop()) { rtttl->stop(); break; } } delete rtttl; delete file; delete out; } void setup() { beep(300, 100); beep(400, 100); beep(500, 100); } void loop() { // Code here if needed } ```

I would be happy to see beep() with the same usage as tone() in the next release.

hlcm0 commented 11 months ago

I think maybe this example, https://github.com/earlephilhower/ESP8266Audio/blob/master/examples/PlayWAVFromFunction/PlayWAVFromFunction.ino, can meet your requirement. It generates sine waves as AudioSources.