From a91beeb0cf79084e159890ac25044a00003ceb5a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 9 Feb 2021 15:47:20 +0100 Subject: [PATCH] Add support for transistor-based output without DAC Add support for transistor-based output without DAC (#10875) --- tasmota/tasmota_configurations_ESP32.h | 4 +- tasmota/xdrv_42_i2s_audio.ino | 134 +++++++++++++++---------- 2 files changed, 83 insertions(+), 55 deletions(-) diff --git a/tasmota/tasmota_configurations_ESP32.h b/tasmota/tasmota_configurations_ESP32.h index af6d0418f..f4dc57b82 100644 --- a/tasmota/tasmota_configurations_ESP32.h +++ b/tasmota/tasmota_configurations_ESP32.h @@ -79,8 +79,8 @@ #define FALLBACK_MODULE M5STACK_CORE2 // [Module2] Select default module on fast reboot where USER_MODULE is user template #define USE_M5STACK_CORE2 // Add support for M5Stack Core2 - #define SAY_TIME - #define USE_WEBRADIO + #define USE_I2S_SAY_TIME + #define USE_I2S_WEBRADIO #define USE_MPU6886 #define USE_UFILESYS #define USE_SDCARD diff --git a/tasmota/xdrv_42_i2s_audio.ino b/tasmota/xdrv_42_i2s_audio.ino index 359308cba..a63918206 100644 --- a/tasmota/xdrv_42_i2s_audio.ino +++ b/tasmota/xdrv_42_i2s_audio.ino @@ -1,5 +1,5 @@ /* - xdrv_42_i2s_audio.ino - audio dac support for Tasmota + xdrv_42_i2s_audio.ino - Audio dac support for Tasmota Copyright (C) 2021 Gerhard Mutz and Theo Arends @@ -17,16 +17,39 @@ along with this program. If not, see . */ -#if (defined(USE_I2S_AUDIO) || defined(USE_TTGO_WATCH) || defined(USE_M5STACK_CORE2)) +#if (defined(USE_I2S_AUDIO) || defined(USE_TTGO_WATCH) || defined(USE_M5STACK_CORE2)) +/*********************************************************************************************\ + * I2S support using an external DAC or a speaker connected to GPIO03 using a transistor + * + * Uses fixed GPIOs for ESP8266: + * I2S Out Data GPIO03 (Rx) + * I2S Out Bit Clock GPIO15 + * I2S Out Word Select GPIO02 + * I2S In Data GPIO12 + * I2S In Bit Clock GPIO13 + * I2S In Word Select GPIO14 +\*********************************************************************************************/ + +#define XDRV_42 42 + +#define USE_I2S_EXTERNAL_DAC 1 +//#define USE_I2S_NO_DAC // Add support for transistor-based output without DAC +//#define USE_I2S_WEBRADIO // Add support for web radio +//#define USE_I2S_SAY_TIME // Add support for english speaking clock + #include "AudioFileSourcePROGMEM.h" #include "AudioFileSourceID3.h" #include "AudioGeneratorMP3.h" -#include "AudioOutputI2S.h" +#ifdef USE_I2S_NO_DAC + #include "AudioOutputI2SNoDAC.h" // Transistor-driven lower quality connected to RX pin +#else + #include "AudioOutputI2S.h" // External I2S DAC IC +#endif // USE_I2S_NO_DAC #include #include "AudioFileSourceFS.h" -#ifdef SAY_TIME -#include "AudioGeneratorTalkie.h" -#endif +#ifdef USE_I2S_SAY_TIME + #include "AudioGeneratorTalkie.h" +#endif // USE_I2S_SAY_TIME #include "AudioFileSourceICYStream.h" #include "AudioFileSourceBuffer.h" #include "AudioGeneratorAAC.h" @@ -41,7 +64,7 @@ #undef AUDIO_PWR_OFF #define AUDIO_PWR_ON TTGO_audio_power(true); #define AUDIO_PWR_OFF TTGO_audio_power(false); -#endif // USE_TTGO_WATCH +#endif // USE_TTGO_WATCH #ifdef USE_M5STACK_CORE2 #undef AUDIO_PWR_ON @@ -54,21 +77,19 @@ #define DAC_IIS_BCK 12 #define DAC_IIS_WS 0 #define DAC_IIS_DOUT 2 -#endif // USE_M5STACK_CORE2 - - -#define EXTERNAL_DAC_PLAY 1 - -#define XDRV_42 42 +#endif // USE_M5STACK_CORE2 AudioGeneratorMP3 *mp3 = nullptr; AudioFileSourceFS *file; -AudioOutputI2S *out; +#ifdef USE_I2S_NO_DAC + AudioOutputI2SNoDAC *out; +#else + AudioOutputI2S *out; +#endif // USE_I2S_NO_DAC AudioFileSourceID3 *id3; AudioGeneratorMP3 *decoder = NULL; void *mp3ram = NULL; - extern FS *ufsp; #ifdef ESP8266 @@ -81,7 +102,7 @@ const int preallocateCodecSize = 29192; // MP3 codec max mem needed //const int preallocateCodecSize = 85332; // AAC+SBR codec max mem needed #endif // ESP32 -#ifdef USE_WEBRADIO +#ifdef USE_I2S_WEBRADIO AudioFileSourceICYStream *ifile = NULL; AudioFileSourceBuffer *buff = NULL; char wr_title[64]; @@ -90,11 +111,11 @@ char wr_title[64]; void *preallocateBuffer = NULL; void *preallocateCodec = NULL; uint32_t retryms = 0; -#endif // USE_WEBRADIO +#endif // USE_I2S_WEBRADIO -#ifdef SAY_TIME +#ifdef USE_I2S_SAY_TIME AudioGeneratorTalkie *talkie = nullptr; -#endif // SAY_TIME +#endif // USE_I2S_SAY_TIME //! MAX98357A + INMP441 DOUBLE I2S BOARD #ifdef ESP8266 @@ -111,26 +132,26 @@ AudioGeneratorTalkie *talkie = nullptr; #ifndef DAC_IIS_BCK #undef DAC_IIS_BCK #define DAC_IIS_BCK 26 -#endif // DAC_IIS_BCK +#endif // DAC_IIS_BCK #ifndef DAC_IIS_WS #undef DAC_IIS_WS #define DAC_IIS_WS 25 -#endif // DAC_IIS_WS +#endif // DAC_IIS_WS #ifndef DAC_IIS_DOUT #undef DAC_IIS_DOUT #define DAC_IIS_DOUT 33 -#endif // DAC_IIS_DOUT +#endif // DAC_IIS_DOUT #ifndef DAC_IIS_DIN #undef DAC_IIS_DIN -#define DAC_IIS_DIN 34 -#endif // DAC_IIS_DIN +#define DAC_IIS_DIN 34 +#endif // DAC_IIS_DIN #endif // ESP32 -#ifdef SAY_TIME +#ifdef USE_I2S_SAY_TIME long timezone = 2; byte daysavetime = 1; @@ -229,21 +250,29 @@ void sayTime(int hour, int minutes, AudioGeneratorTalkie *talkie) { out->stop(); AUDIO_PWR_OFF } -#endif // SAY_TIME +#endif // USE_I2S_SAY_TIME // should be in settings uint8_t is2_volume; void I2S_Init(void) { -#if EXTERNAL_DAC_PLAY - out = new AudioOutputI2S(); +#if USE_I2S_EXTERNAL_DAC + #ifdef USE_I2S_NO_DAC + out = new AudioOutputI2SNoDAC(); + #else + out = new AudioOutputI2S(); + #endif // USE_I2S_NO_DAC #ifdef ESP32 - out->SetPinout(DAC_IIS_BCK, DAC_IIS_WS, DAC_IIS_DOUT); + out->SetPinout(DAC_IIS_BCK, DAC_IIS_WS, DAC_IIS_DOUT); #endif // ESP32 #else - out = new AudioOutputI2S(0, 1); -#endif // EXTERNAL_DAC_PLAY + #ifdef USE_I2S_NO_DAC + out = new AudioOutputI2SNoDAC(); + #else + out = new AudioOutputI2S(0, 1); // Internal DAC port 0 + #endif // USE_I2S_NO_DAC +#endif // USE_I2S_EXTERNAL_DAC is2_volume=10; out->SetGain(((float)is2_volume/100.0)*4.0); @@ -255,7 +284,7 @@ void I2S_Init(void) { mp3ram = heap_caps_malloc(preallocateCodecSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); } -#ifdef USE_WEBRADIO +#ifdef USE_I2S_WEBRADIO if (psramFound()) { preallocateBuffer = heap_caps_malloc(preallocateBufferSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); preallocateCodec = heap_caps_malloc(preallocateCodecSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); @@ -266,12 +295,11 @@ void I2S_Init(void) { if (!preallocateBuffer || !preallocateCodec) { //Serial.printf_P(PSTR("FATAL ERROR: Unable to preallocate %d bytes for app\n"), preallocateBufferSize+preallocateCodecSize); } -#endif // USE_WEBRADIO -#endif // ESP32 +#endif // USE_I2S_WEBRADIO +#endif // ESP32 } - #ifdef ESP32 #define MODE_MIC 0 #define MODE_SPK 1 @@ -426,7 +454,7 @@ bool SaveWav(char *path, uint8_t *buff, uint32_t size) { return true; } -#endif // ESP32 +#endif // ESP32 #ifdef ESP32 TaskHandle_t mp3_task_h; @@ -447,9 +475,9 @@ void mp3_task(void *arg) { } } } -#endif // ESP32 +#endif // ESP32 -#ifdef USE_WEBRADIO +#ifdef USE_I2S_WEBRADIO void MDCallback(void *cbData, const char *type, bool isUnicode, const char *str) { const char *ptr = reinterpret_cast(cbData); (void) isUnicode; // Punt this ball for now @@ -557,7 +585,7 @@ void Cmd_MicRec(void) { ResponseCmndChar(XdrvMailbox.data); } } -#endif // USE_M5STACK_CORE2 +#endif // USE_M5STACK_CORE2 const char HTTP_WEBRADIO[] PROGMEM = "{s}" "I2S_WR-Title" "{m}%s{e}"; @@ -568,7 +596,7 @@ void I2S_WR_Show(void) { } } -#endif +#endif // USE_I2S_WEBRADIO #ifdef ESP32 void Play_mp3(const char *path) { @@ -610,7 +638,7 @@ void Play_mp3(const char *path) { mp3_delete(); } -#endif // USE_SCRIPT +#endif // USE_SCRIPT } void mp3_delete(void) { @@ -620,7 +648,7 @@ void mp3_delete(void) { mp3=nullptr; AUDIO_PWR_OFF } -#endif // ESP32 +#endif // ESP32 void Say(char *text) { @@ -642,22 +670,22 @@ const char kI2SAudio_Commands[] PROGMEM = "I2S|" "Say|Gain|Time" #ifdef ESP32 "|Play" -#ifdef USE_WEBRADIO +#ifdef USE_I2S_WEBRADIO "|WR" -#endif // USE_WEBRADIO +#endif // USE_I2S_WEBRADIO #ifdef USE_M5STACK_CORE2 "|REC" -#endif // USE_M5STACK_CORE2 -#endif // ESP32 +#endif // USE_M5STACK_CORE2 +#endif // ESP32 ; void (* const I2SAudio_Command[])(void) PROGMEM = { &Cmd_Say, &Cmd_Gain, &Cmd_Time #ifdef ESP32 ,&Cmd_Play -#ifdef USE_WEBRADIO +#ifdef USE_I2S_WEBRADIO ,&Cmd_WebRadio -#endif // USE_WEBRADIO +#endif // USE_I2S_WEBRADIO #ifdef USE_M5STACK_CORE2 ,&Cmd_MicRec #endif // USE_M5STACK_CORE2 @@ -691,9 +719,9 @@ void Cmd_Say(void) { } void Cmd_Time(void) { -#ifdef SAY_TIME +#ifdef USE_I2S_SAY_TIME sayTime(RtcTime.hour, RtcTime.minute, talkie); -#endif // SAY_TIME +#endif // USE_I2S_SAY_TIME ResponseCmndDone(); } @@ -712,12 +740,12 @@ bool Xdrv42(uint8_t function) { I2S_Init(); break; #ifdef USE_WEBSERVER -#ifdef USE_WEBRADIO +#ifdef USE_I2S_WEBRADIO case FUNC_WEB_SENSOR: I2S_WR_Show(); break; -#endif // USE_WEBRADIO -#endif // USE_WEBSERVER +#endif // USE_I2S_WEBRADIO +#endif // USE_WEBSERVER } return result; }