From cda5ba1580b007bd9a12fa5172ca7acc5e7f3f63 Mon Sep 17 00:00:00 2001 From: eadmaster <925171+eadmaster@users.noreply.github.com> Date: Tue, 6 Aug 2024 08:50:22 +0200 Subject: [PATCH] added playTone and beep cmds (#113) --- src/core/globals.cpp | 7 ---- src/core/globals.h | 2 +- src/core/serialcmds.cpp | 15 +++++++ src/modules/others/audio.cpp | 76 +++++++++++++++++++++++++++++++++++- src/modules/others/audio.h | 6 ++- 5 files changed, 96 insertions(+), 10 deletions(-) diff --git a/src/core/globals.cpp b/src/core/globals.cpp index f649d943..f85ded4e 100644 --- a/src/core/globals.cpp +++ b/src/core/globals.cpp @@ -71,10 +71,3 @@ void updateTimeStr(struct tm timeInfo) { snprintf(timeStr, sizeof(timeStr), "%02d:%02d", timeInfo.tm_hour, timeInfo.tm_min); } -void _tone(unsigned int frequency, unsigned long duration = 0UL) { -#if defined(BUZZ_PIN) - tone(BUZZ_PIN, frequency, duration); -//#elif defined(HAS_NS4168_SPKR) -//TODO: alt. implementation using the speaker -#endif -} diff --git a/src/core/globals.h b/src/core/globals.h index aded9606..d977c99f 100644 --- a/src/core/globals.h +++ b/src/core/globals.h @@ -112,4 +112,4 @@ extern String wui_pwd; extern int tmz; void setup_gpio(); -void _tone(unsigned int frequency, unsigned long duration); + diff --git a/src/core/serialcmds.cpp b/src/core/serialcmds.cpp index 7e09386d..f12488f6 100644 --- a/src/core/serialcmds.cpp +++ b/src/core/serialcmds.cpp @@ -291,6 +291,21 @@ bool processSerialCommand(String cmd_str) { } #endif + #if defined(HAS_NS4168_SPKR) || defined(BUZZ_PIN) + if(cmd_str.startsWith("tone" ) || cmd_str.startsWith("beep" )) { + const char* args = cmd_str.c_str() + 4; + unsigned long frequency = 500UL; + unsigned long duration = 500UL; // default to 2 sec + if(strlen(args)>1) sscanf(args, " %lu %lu", &frequency, &duration); // try to read the args, keep the defaults if missing + //Serial.print((int) frequency); + //Serial.print((int) duration); + _tone(frequency, duration); + //delay(1000); + //playTone(frequency, duration, 1); // sine + return true; + } + #endif + #if defined(HAS_NS4168_SPKR) //M5StickCs doesn't have speakers.. they have buzzers on pin 02 that only beeps in different frequencies if(cmd_str.startsWith("music_player " ) ) { // || cmd_str.startsWith("play " ) String song = cmd_str.substring(13, cmd_str.length()); diff --git a/src/modules/others/audio.cpp b/src/modules/others/audio.cpp index 934eb180..716b061d 100644 --- a/src/modules/others/audio.cpp +++ b/src/modules/others/audio.cpp @@ -1,6 +1,9 @@ #include "audio.h" #include -#include +#include "AudioGeneratorMIDI.h" +#include "AudioFileSourceFunction.h" +#include "AudioGeneratorWAV.h" +#include "AudioOutputI2SNoDAC.h" #include #include "core/mykeyboard.h" @@ -117,4 +120,75 @@ bool isAudioFile(String filepath) { return filepath.endsWith(".opus") || filepath.endsWith(".rtttl") || filepath.endsWith(".wav") || filepath.endsWith(".mod") || filepath.endsWith(".mp3") ; } + + +void playTone(unsigned int frequency, unsigned long duration, short waveType) +{ + // derived from https://github.com/earlephilhower/ESP8266Audio/blob/master/examples/PlayWAVFromFunction/PlayWAVFromFunction.ino + + if(frequency==0 || duration==0) return; + + float hz = frequency; + + AudioGeneratorWAV* wav; + AudioFileSourceFunction* file; + AudioOutputI2S* out = new AudioOutputI2S(); + out->SetPinout(BCLK, WCLK, DOUT); + + file = new AudioFileSourceFunction( duration/1000.0); // , 1, 44100 + // + // you can set (sec, channels, hz, bit/sample) but you should care about + // the trade-off between performance and the audio quality + // + // file = new AudioFileSourceFunction(sec, channels, hz, bit/sample); + // channels : default = 1 + // hz : default = 8000 (8000, 11025, 22050, 44100, 48000, etc.) + // bit/sample : default = 16 (8, 16, 32) + + // ===== set your sound function ===== + + if(waveType==0) { // square + file->addAudioGenerators([&](const float time) { + float v = ( sin(hz * time) >= 0 ) ? 1.0f : -1.0f;; // generate square wave + v *= 0.1; // scale + return v; + }); + } + else if(waveType==1) { // sine + file->addAudioGenerators([&](const float time) { + float v = sin(TWO_PI * hz * time); // generate sine wave + v *= fmod(time, 1.f); // change linear + v *= 0.1; // scale + return v; + }); + } + // TODO: more wave types: triangle, sawtooth + // + // sound function should have one argument(float) and one return(float) + // param : float (current time [sec] of the song) + // return : float (the amplitude of sound which varies from -1.f to +1.f) + + wav = new AudioGeneratorWAV(); + wav->begin(file, out); + + while (wav->isRunning()) { + if (!wav->loop() || checkAnyKeyPress()) wav->stop(); + } + + delete file; + delete wav; + delete out; +} + #endif + + +void _tone(unsigned int frequency, unsigned long duration) { +#if defined(BUZZ_PIN) + tone(BUZZ_PIN, frequency, duration); +#elif defined(HAS_NS4168_SPKR) + // alt. implementation using the speaker + playTone(frequency, duration, 0); +#endif +} + diff --git a/src/modules/others/audio.h b/src/modules/others/audio.h index 272dfb5e..50489dad 100644 --- a/src/modules/others/audio.h +++ b/src/modules/others/audio.h @@ -9,4 +9,8 @@ bool playAudioRTTTLString(String song); bool tts(String text); -bool isAudioFile(String filePath); \ No newline at end of file +bool isAudioFile(String filePath); + +void playTone(unsigned int frequency, unsigned long duration = 0UL, short waveType=0); + +void _tone(unsigned int frequency, unsigned long duration = 0UL); \ No newline at end of file