diff --git a/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMP3.cpp b/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMP3.cpp index d962c9e0be28..583c60317386 100644 --- a/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMP3.cpp +++ b/lib/lib_audio/ESP8266Audio/src/AudioGeneratorMP3.cpp @@ -186,7 +186,9 @@ bool AudioGeneratorMP3::GetOneSample(int16_t sample[2]) // If we're here, we have one decoded frame and sent 0 or more samples out if (samplePtr < synth->pcm.length) { sample[AudioOutput::LEFTCHANNEL ] = synth->pcm.samples[0][samplePtr]; - sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr]; + if(lastChannels == 2) { + sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr]; + } samplePtr++; } else { samplePtr = 0; @@ -200,7 +202,9 @@ bool AudioGeneratorMP3::GetOneSample(int16_t sample[2]) } // for IGNORE and CONTINUE, just play what we have now sample[AudioOutput::LEFTCHANNEL ] = synth->pcm.samples[0][samplePtr]; - sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr]; + if(lastChannels == 2) { + sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr]; + } samplePtr++; } return true; diff --git a/lib/lib_audio/ESP8266Audio/src/AudioOutputMixer.cpp b/lib/lib_audio/ESP8266Audio/src/AudioOutputMixer.cpp index 57a1c06a62f1..618bf99ea60c 100644 --- a/lib/lib_audio/ESP8266Audio/src/AudioOutputMixer.cpp +++ b/lib/lib_audio/ESP8266Audio/src/AudioOutputMixer.cpp @@ -190,7 +190,7 @@ bool AudioOutputMixer::loop() } } if (avail) { - int16_t s[2]; + int16_t s[2] = {0}; if (leftAccum[readPtr] > 32767) { s[LEFTCHANNEL] = 32767; } else if (leftAccum[readPtr] < -32767) { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_3_lib_idf51.ino b/tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_3_lib_idf51.ino index bce536903ffe..65466f7162be 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_3_lib_idf51.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_3_lib_idf51.ino @@ -197,6 +197,7 @@ public: // Tx virtual bool begin(void) { return beginTx(); }; // the name `begin()`is inherited from superclass, prefer `beginTx()` which is more explicit virtual bool stop(void) { return stopTx(); }; // the name `stop()`is inherited from superclass, prefer `stopTx()` which is more explicit + virtual void flush(void); // makes sure that all stored DMA samples are consumed / played to prevent static noise after stop() bool beginTx(void); bool stopTx(void); bool ConsumeSample(int16_t sample[2]); @@ -322,6 +323,11 @@ bool TasmotaI2S::beginTx(void) { } else #endif // SOC_DAC_SUPPORTED { + uint8_t zero_buffer[240] = {0}; + size_t sz; + for(int i = 0;i < 6;i++){ + i2s_channel_preload_data(_tx_handle, zero_buffer, sizeof(zero_buffer), &sz); // preload DMA buffer with silence + } err = i2s_channel_enable(_tx_handle); } AddLog(LOG_LEVEL_INFO, "I2S: Tx i2s_channel_enable err=0x%04X", err); @@ -363,6 +369,20 @@ bool TasmotaI2S::stopTx() { return true; } +void TasmotaI2S::flush() +{ + int buffersize = 6 * 240; + int16_t samples[2] = {0x0, 0x0}; + for (int i = 0; i < buffersize; i++) + { + while (!ConsumeSample(samples)) + { + delay(1); + } + } + AddLog(LOG_LEVEL_INFO, "I2S: flush DMA TX buffer"); +} + bool TasmotaI2S::delTxHandle(void) { esp_err_t err = ESP_OK; AddLog(LOG_LEVEL_DEBUG, "I2S: calling delTxHandle() tx_running:%i tx_handle:%p", _tx_running, _tx_handle); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_audio_idf51.ino b/tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_audio_idf51.ino index f4a840044629..20a5b459c9b2 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_audio_idf51.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_audio_idf51.ino @@ -473,7 +473,7 @@ exit: audio_i2s.in->stopRx(); audio_i2s_mp3.mic_stop = 0; audio_i2s_mp3.mic_error = error; - AddLog(LOG_LEVEL_INFO, PSTR("mp3task result code: %d"), error); + AddLog(LOG_LEVEL_INFO, PSTR("I2S: mp3task result code: %d"), error); audio_i2s_mp3.mic_task_handle = 0; audio_i2s_mp3.recdur = 0; audio_i2s_mp3.stream_active = 0; @@ -484,6 +484,15 @@ exit: int32_t I2sRecordShine(char *path) { esp_err_t err = ESP_OK; + switch(audio_i2s.Settings->rx.sample_rate){ + case 32000: case 48000: case 44100: + break; // supported + default: + AddLog(LOG_LEVEL_INFO, PSTR("I2S: unsupported sample rate for MP3 encoding: %d"), audio_i2s.Settings->rx.sample_rate); + return -1; + } + AddLog(LOG_LEVEL_INFO, PSTR("I2S: accepted sample rate for MP3 encoding: %d"), audio_i2s.Settings->rx.sample_rate); + #ifdef USE_I2S_MP3 if (audio_i2s_mp3.decoder || audio_i2s_mp3.mp3) return 0; #endif @@ -735,8 +744,8 @@ void I2sInit(void) { } if (init_tx_ok) { audio_i2s.out = i2s; } if (init_rx_ok) { audio_i2s.in = i2s; } - audio_i2s.Settings->sys.tx = init_tx_ok; - audio_i2s.Settings->sys.rx = init_rx_ok; + audio_i2s.Settings->sys.tx |= init_tx_ok; // Do not set to zero id already configured on another channnel + audio_i2s.Settings->sys.rx |= init_rx_ok; if (init_tx_ok && init_rx_ok) { audio_i2s.Settings->sys.duplex = true; } // if intput and output are configured, don't proceed with other IS2 ports @@ -750,11 +759,11 @@ void I2sInit(void) { if (audio_i2s.out) { audio_i2s.out->setExclusive(exclusive); } if (audio_i2s.in) { audio_i2s.in->setExclusive(exclusive); } - if(audio_i2s.out != nullptr){ - audio_i2s.out->SetGain(((float)audio_i2s.Settings->tx.gain / 100.0) * 4.0); - audio_i2s.out->beginTx(); // TODO - useful? - audio_i2s.out->stopTx(); - } + // if(audio_i2s.out != nullptr){ + // audio_i2s.out->SetGain(((float)(audio_i2s.Settings->tx.gain + 1)/ 100.0)); + // audio_i2s.out->beginTx(); // TODO - useful? + // audio_i2s.out->stopTx(); + // } #ifdef USE_I2S_MP3 audio_i2s_mp3.mp3ram = nullptr; if (audio_i2s.Settings->sys.mp3_preallocate == 1){ @@ -784,11 +793,21 @@ int32_t I2SPrepareTx(void) { delay(1); } } + + if (audio_i2s_mp3.mic_task_handle) { + audio_i2s_mp3.mic_stop = 1; + while (audio_i2s_mp3.mic_stop) { + delay(1); + } + } AddLog(LOG_LEVEL_DEBUG, "I2S: I2SPrepareTx out=%p", audio_i2s.out); if (!audio_i2s.out) { return I2S_ERR_OUTPUT_NOT_CONFIGURED; } if (!audio_i2s.out->beginTx()) { return I2S_ERR_TX_FAILED; } + + audio_i2s.out->SetGain(((float)(audio_i2s.Settings->tx.gain + 1)/ 100.0)); + return I2S_OK; } @@ -813,21 +832,20 @@ int32_t I2SPrepareRx(void) { #if defined(USE_I2S_MP3) || defined(USE_I2S_WEBRADIO) void I2sMp3Task(void *arg) { - while (1) { - while (audio_i2s_mp3.mp3->isRunning()) { - if (!audio_i2s_mp3.mp3->loop()) { - audio_i2s_mp3.mp3->stop(); - mp3_delete(); - audio_i2s.out->stop(); - if (audio_i2s_mp3.mp3_task_handle) { - vTaskDelete(audio_i2s_mp3.mp3_task_handle); - audio_i2s_mp3.mp3_task_handle = 0; - } - //mp3_task_handle=nullptr; - } - vTaskDelay(pdMS_TO_TICKS(1)); + audio_i2s_mp3.task_running = true; + while (audio_i2s_mp3.mp3->isRunning() && audio_i2s_mp3.task_running) { + if (!audio_i2s_mp3.mp3->loop()) { + audio_i2s_mp3.task_running == false; } + vTaskDelay(pdMS_TO_TICKS(1)); } + audio_i2s.out->flush(); + audio_i2s_mp3.mp3->stop(); + I2sStopPlaying(); + mp3_delete(); + audio_i2s_mp3.mp3_task_handle = nullptr; + audio_i2s_mp3.task_has_ended = true; + vTaskDelete(NULL); } #endif // defined(USE_I2S_MP3) || defined(USE_I2S_WEBRADIO) @@ -851,29 +869,17 @@ void I2sMp3WrTask(void *arg){ vTaskDelay(pdMS_TO_TICKS(1)); } } - audio_i2s_mp3.decoder->stop(); - audio_i2s_mp3.task_has_ended = true; + audio_i2s.out->flush(); I2sStopPlaying(); + audio_i2s_mp3.mp3_task_handle = nullptr; + audio_i2s_mp3.task_has_ended = true; + vTaskDelete(NULL); } -void I2SStopMP3Play(void) { - if (audio_i2s_mp3.decoder) { - audio_i2s_mp3.decoder->stop(); - delete audio_i2s_mp3.decoder; - audio_i2s_mp3.decoder = NULL; - } - - if (audio_i2s_mp3.mp3_task_handle) { - vTaskDelete(audio_i2s_mp3.mp3_task_handle); - audio_i2s_mp3.mp3_task_handle = nullptr; - } -} #endif // USE_I2S_MP3 void I2sStopPlaying() { -#ifdef USE_I2S_MP3 - I2SStopMP3Play(); -#endif // USE_I2S_MP3 + #ifdef USE_I2S_WEBRADIO I2sWebRadioStopPlaying(); #endif @@ -921,7 +927,12 @@ void mp3_delete(void) { delete audio_i2s_mp3.id3; delete audio_i2s_mp3.mp3; audio_i2s_mp3.mp3=nullptr; - I2SAudioPower(false); + + if (audio_i2s_mp3.decoder) { + audio_i2s_mp3.decoder->stop(); + delete audio_i2s_mp3.decoder; + audio_i2s_mp3.decoder = NULL; + } } #endif // USE_I2S_MP3 @@ -959,7 +970,7 @@ void CmndI2SMic(void) { void CmndI2SStop(void) { - if (!I2SPrepareTx()) { + if (I2SPrepareTx() != I2S_OK) { ResponseCmndChar("I2S output not configured"); return; } @@ -1006,7 +1017,7 @@ void CmndI2SGain(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) { if (audio_i2s.out) { audio_i2s.Settings->tx.gain = XdrvMailbox.payload; - audio_i2s.out->SetGain(((float)(audio_i2s.Settings->tx.gain-2)/100.0)*4.0); + audio_i2s.out->SetGain(((float)(audio_i2s.Settings->tx.gain+1)/100.0)); } } ResponseCmndNumber(audio_i2s.Settings->tx.gain); @@ -1050,8 +1061,12 @@ void CmndI2SMicRec(void) { if (!strncmp(XdrvMailbox.data, "-?", 2)) { Response_P("{\"I2SREC-duration\":%d}", audio_i2s_mp3.recdur); } else { - I2sRecordShine(XdrvMailbox.data); - ResponseCmndChar(XdrvMailbox.data); + int err = I2sRecordShine(XdrvMailbox.data); + if(err == pdPASS){ + ResponseCmndChar(XdrvMailbox.data); + } else { + ResponseCmndChar_P(PSTR("Did not launch recording task")); + } } } else { if (audio_i2s_mp3.mic_task_handle) { @@ -1062,6 +1077,9 @@ void CmndI2SMicRec(void) { } ResponseCmndChar_P(PSTR("Stopped")); } + else { + ResponseCmndChar_P(PSTR("No running recording")); + } } } else{ diff --git a/tasmota/tasmota_xdrv_driver/xdrv_42_1_i2s_mp3mic_idf51.ino b/tasmota/tasmota_xdrv_driver/xdrv_42_1_i2s_mp3mic_idf51.ino index e846d07b6127..3a9e82f6349a 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_42_1_i2s_mp3mic_idf51.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_42_1_i2s_mp3mic_idf51.ino @@ -21,219 +21,219 @@ #if defined(ESP32) && ESP_IDF_VERSION_MAJOR >= 5 #ifdef USE_I2S_AUDIO -uint32_t SpeakerMic(uint8_t spkr) { -esp_err_t err = ESP_OK; - -// audio_i2s.mode = spkr; - return err; -} - -#ifdef USE_SHINE - -#include -#include - -// micro to mp3 file or stream -void mic_task(void *arg){ - int8_t error = 0; - uint8_t *ucp; - int written; - shine_config_t config; - shine_t s = nullptr; - uint16_t samples_per_pass; - File mp3_out = (File)nullptr; - int16_t *buffer = nullptr; - uint16_t bytesize; - uint16_t bwritten; - uint32_t ctime; - - if (!audio_i2s_mp3.use_stream) { - mp3_out = ufsp->open(audio_i2s_mp3.mic_path, "w"); - if (!mp3_out) { - error = 1; - goto exit; - } - } else { - if (!audio_i2s_mp3.stream_active) { - error = 2; - audio_i2s_mp3.use_stream = 0; - goto exit; - } - audio_i2s_mp3.client.flush(); - audio_i2s_mp3.client.setTimeout(3); - audio_i2s_mp3.client.print("HTTP/1.1 200 OK\r\n" - "Content-Type: audio/mpeg;\r\n\r\n"); - - // Webserver->send(200, "application/octet-stream", ""); - //"Content-Type: audio/mp3;\r\n\r\n"); - } - - shine_set_config_mpeg_defaults(&config.mpeg); - - if (audio_i2s.Settings->rx.channels == 1) { - config.mpeg.mode = MONO; - } else { - config.mpeg.mode = STEREO; - } - config.mpeg.bitr = 128; - config.wave.samplerate = audio_i2s.Settings->rx.sample_rate; - config.wave.channels = (channels)audio_i2s.Settings->rx.channels; - - if (shine_check_config(config.wave.samplerate, config.mpeg.bitr) < 0) { - error = 3; - goto exit; - } - - s = shine_initialise(&config); - if (!s) { - error = 4; - goto exit; - } - - samples_per_pass = shine_samples_per_pass(s); - bytesize = samples_per_pass * 2 * audio_i2s.Settings->rx.channels; - - buffer = (int16_t*)malloc(bytesize); - if (!buffer) { - error = 5; - goto exit; - } - - ctime = TasmotaGlobal.uptime; - - while (!audio_i2s_mp3.mic_stop) { - uint32_t bytes_read; - bytes_read = audio_i2s.in->readMic((uint8_t*)buffer, bytesize, true /*dc_block*/, false /*apply_gain*/, true /*lowpass*/, nullptr /*peak_ptr*/); - // i2s_read(audio_i2s.mic_port, (char *)buffer, bytesize, &bytes_read, (100 / portTICK_PERIOD_MS)); - - if (audio_i2s.Settings->rx.gain > 1) { - // set gain - for (uint32_t cnt = 0; cnt < bytes_read / 2; cnt++) { - buffer[cnt] *= audio_i2s.Settings->rx.gain; - } - } - ucp = shine_encode_buffer_interleaved(s, buffer, &written); - - if (!audio_i2s.Settings->tx.stream_enable) { - bwritten = mp3_out.write(ucp, written); - if (bwritten != written) { - break; - } - } else { - audio_i2s_mp3.client.write((const char*)ucp, written); - - if (!audio_i2s_mp3.client.connected()) { - break; - } - } - audio_i2s_mp3.recdur = TasmotaGlobal.uptime - ctime; - } - - ucp = shine_flush(s, &written); - - if (!audio_i2s_mp3.use_stream) { - mp3_out.write(ucp, written); - } else { - audio_i2s_mp3.client.write((const char*)ucp, written); - } - - -exit: - if (s) { - shine_close(s); - } - if (mp3_out) { - mp3_out.close(); - } - if (buffer) { - free(buffer); - } - - if (audio_i2s_mp3.use_stream) { - audio_i2s_mp3.client.stop(); - } - - SpeakerMic(I2S_AUDIO_MODE_SPK); - audio_i2s_mp3.mic_stop = 0; - audio_i2s_mp3.mic_error = error; - AddLog(LOG_LEVEL_INFO, PSTR("mp3task result code: %d"), error); - audio_i2s_mp3.mic_task_handle = 0; - audio_i2s_mp3.recdur = 0; - audio_i2s_mp3.stream_active = 0; - vTaskDelete(NULL); - -} - -int32_t i2s_record_shine(char *path) { -esp_err_t err = ESP_OK; - - if (audio_i2s.in) { - if (audio_i2s_mp3.decoder || audio_i2s_mp3.mp3) return 0; - } - - err = SpeakerMic(I2S_AUDIO_MODE_MIC); - if (err) { - if (audio_i2s.in) { - SpeakerMic(I2S_AUDIO_MODE_SPK); - } - AddLog(LOG_LEVEL_INFO, PSTR("mic init error: %d"), err); - return err; - } - - strlcpy(audio_i2s_mp3.mic_path, path, sizeof(audio_i2s_mp3.mic_path)); - - audio_i2s_mp3.mic_stop = 0; - - uint32_t stack = 4096; - - audio_i2s_mp3.use_stream = !strcmp(audio_i2s_mp3.mic_path, "stream.mp3"); - - if (audio_i2s_mp3.use_stream) { - stack = 8000; - } - - err = xTaskCreatePinnedToCore(mic_task, "MIC", stack, NULL, 3, &audio_i2s_mp3.mic_task_handle, 1); - - return err; -} - -void Cmd_MicRec(void) { - - if (XdrvMailbox.data_len > 0) { - if (!strncmp(XdrvMailbox.data, "-?", 2)) { - Response_P("{\"I2SREC-duration\":%d}", audio_i2s_mp3.recdur); - } else { - i2s_record_shine(XdrvMailbox.data); - ResponseCmndChar(XdrvMailbox.data); - } - } else { - if (audio_i2s_mp3.mic_task_handle) { - // stop task - audio_i2s_mp3.mic_stop = 1; - while (audio_i2s_mp3.mic_stop) { - delay(1); - } - ResponseCmndChar_P(PSTR("Stopped")); - } - } - -} -#endif // USE_SHINE - - -// mic gain in factor not percent -void Cmd_MicGain(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 256)) { - if (audio_i2s.in) { - audio_i2s.in->setRxGain(XdrvMailbox.payload); - } - if (audio_i2s.Settings) { - audio_i2s.Settings->rx.gain = XdrvMailbox.payload * 16; - } - I2SSettingsSave(AUDIO_CONFIG_FILENAME); - } - ResponseCmndNumber(audio_i2s.Settings->rx.gain / 16); -} +// uint32_t SpeakerMic(uint8_t spkr) { +// esp_err_t err = ESP_OK; + +// // audio_i2s.mode = spkr; +// return err; +// } + +// #ifdef USE_SHINE + +// #include +// #include + +// // micro to mp3 file or stream +// void mic_task(void *arg){ +// int8_t error = 0; +// uint8_t *ucp; +// int written; +// shine_config_t config; +// shine_t s = nullptr; +// uint16_t samples_per_pass; +// File mp3_out = (File)nullptr; +// int16_t *buffer = nullptr; +// uint16_t bytesize; +// uint16_t bwritten; +// uint32_t ctime; + +// if (!audio_i2s_mp3.use_stream) { +// mp3_out = ufsp->open(audio_i2s_mp3.mic_path, "w"); +// if (!mp3_out) { +// error = 1; +// goto exit; +// } +// } else { +// if (!audio_i2s_mp3.stream_active) { +// error = 2; +// audio_i2s_mp3.use_stream = 0; +// goto exit; +// } +// audio_i2s_mp3.client.flush(); +// audio_i2s_mp3.client.setTimeout(3); +// audio_i2s_mp3.client.print("HTTP/1.1 200 OK\r\n" +// "Content-Type: audio/mpeg;\r\n\r\n"); + +// // Webserver->send(200, "application/octet-stream", ""); +// //"Content-Type: audio/mp3;\r\n\r\n"); +// } + +// shine_set_config_mpeg_defaults(&config.mpeg); + +// if (audio_i2s.Settings->rx.channels == 1) { +// config.mpeg.mode = MONO; +// } else { +// config.mpeg.mode = STEREO; +// } +// config.mpeg.bitr = 128; +// config.wave.samplerate = audio_i2s.Settings->rx.sample_rate; +// config.wave.channels = (channels)audio_i2s.Settings->rx.channels; + +// if (shine_check_config(config.wave.samplerate, config.mpeg.bitr) < 0) { +// error = 3; +// goto exit; +// } + +// s = shine_initialise(&config); +// if (!s) { +// error = 4; +// goto exit; +// } + +// samples_per_pass = shine_samples_per_pass(s); +// bytesize = samples_per_pass * 2 * audio_i2s.Settings->rx.channels; + +// buffer = (int16_t*)malloc(bytesize); +// if (!buffer) { +// error = 5; +// goto exit; +// } + +// ctime = TasmotaGlobal.uptime; + +// while (!audio_i2s_mp3.mic_stop) { +// uint32_t bytes_read; +// bytes_read = audio_i2s.in->readMic((uint8_t*)buffer, bytesize, true /*dc_block*/, false /*apply_gain*/, true /*lowpass*/, nullptr /*peak_ptr*/); +// // i2s_read(audio_i2s.mic_port, (char *)buffer, bytesize, &bytes_read, (100 / portTICK_PERIOD_MS)); + +// if (audio_i2s.Settings->rx.gain > 1) { +// // set gain +// for (uint32_t cnt = 0; cnt < bytes_read / 2; cnt++) { +// buffer[cnt] *= audio_i2s.Settings->rx.gain; +// } +// } +// ucp = shine_encode_buffer_interleaved(s, buffer, &written); + +// if (!audio_i2s.Settings->tx.stream_enable) { +// bwritten = mp3_out.write(ucp, written); +// if (bwritten != written) { +// break; +// } +// } else { +// audio_i2s_mp3.client.write((const char*)ucp, written); + +// if (!audio_i2s_mp3.client.connected()) { +// break; +// } +// } +// audio_i2s_mp3.recdur = TasmotaGlobal.uptime - ctime; +// } + +// ucp = shine_flush(s, &written); + +// if (!audio_i2s_mp3.use_stream) { +// mp3_out.write(ucp, written); +// } else { +// audio_i2s_mp3.client.write((const char*)ucp, written); +// } + + +// exit: +// if (s) { +// shine_close(s); +// } +// if (mp3_out) { +// mp3_out.close(); +// } +// if (buffer) { +// free(buffer); +// } + +// if (audio_i2s_mp3.use_stream) { +// audio_i2s_mp3.client.stop(); +// } + +// SpeakerMic(I2S_AUDIO_MODE_SPK); +// audio_i2s_mp3.mic_stop = 0; +// audio_i2s_mp3.mic_error = error; +// AddLog(LOG_LEVEL_INFO, PSTR("mp3task result code: %d"), error); +// audio_i2s_mp3.mic_task_handle = 0; +// audio_i2s_mp3.recdur = 0; +// audio_i2s_mp3.stream_active = 0; +// vTaskDelete(NULL); + +// } + +// int32_t i2s_record_shine(char *path) { +// esp_err_t err = ESP_OK; + +// if (audio_i2s.in) { +// if (audio_i2s_mp3.decoder || audio_i2s_mp3.mp3) return 0; +// } + +// err = SpeakerMic(I2S_AUDIO_MODE_MIC); +// if (err) { +// if (audio_i2s.in) { +// SpeakerMic(I2S_AUDIO_MODE_SPK); +// } +// AddLog(LOG_LEVEL_INFO, PSTR("mic init error: %d"), err); +// return err; +// } + +// strlcpy(audio_i2s_mp3.mic_path, path, sizeof(audio_i2s_mp3.mic_path)); + +// audio_i2s_mp3.mic_stop = 0; + +// uint32_t stack = 4096; + +// audio_i2s_mp3.use_stream = !strcmp(audio_i2s_mp3.mic_path, "stream.mp3"); + +// if (audio_i2s_mp3.use_stream) { +// stack = 8000; +// } + +// err = xTaskCreatePinnedToCore(mic_task, "MIC", stack, NULL, 3, &audio_i2s_mp3.mic_task_handle, 1); + +// return err; +// } + +// void Cmd_MicRec(void) { + +// if (XdrvMailbox.data_len > 0) { +// if (!strncmp(XdrvMailbox.data, "-?", 2)) { +// Response_P("{\"I2SREC-duration\":%d}", audio_i2s_mp3.recdur); +// } else { +// i2s_record_shine(XdrvMailbox.data); +// ResponseCmndChar(XdrvMailbox.data); +// } +// } else { +// if (audio_i2s_mp3.mic_task_handle) { +// // stop task +// audio_i2s_mp3.mic_stop = 1; +// while (audio_i2s_mp3.mic_stop) { +// delay(1); +// } +// ResponseCmndChar_P(PSTR("Stopped")); +// } +// } + +// } +// #endif // USE_SHINE + + +// // mic gain in factor not percent +// void Cmd_MicGain(void) { +// if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 256)) { +// if (audio_i2s.in) { +// audio_i2s.in->setRxGain(XdrvMailbox.payload); +// } +// if (audio_i2s.Settings) { +// audio_i2s.Settings->rx.gain = XdrvMailbox.payload * 16; +// } +// I2SSettingsSave(AUDIO_CONFIG_FILENAME); +// } +// ResponseCmndNumber(audio_i2s.Settings->rx.gain / 16); +// } #endif // USE_I2S_AUDIO #endif // defined(ESP32) && ESP_IDF_VERSION_MAJOR >= 5 diff --git a/tasmota/tasmota_xdrv_driver/xdrv_42_2_i2s_mp3stream_idf51.ino b/tasmota/tasmota_xdrv_driver/xdrv_42_2_i2s_mp3stream_idf51.ino index 0fff1b0e61cd..aca46360bd81 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_42_2_i2s_mp3stream_idf51.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_42_2_i2s_mp3stream_idf51.ino @@ -27,6 +27,7 @@ void Stream_mp3(void) { if (audio_i2s_mp3.stream_active) { + AddLog(LOG_LEVEL_INFO, PSTR("I2S: can not handle client - other MP3 task active")); return; } AddLog(LOG_LEVEL_INFO, PSTR("I2S: Handle mp3server")); @@ -58,6 +59,7 @@ void I2sMp3Init(uint32_t on) { delete audio_i2s_mp3.MP3Server; audio_i2s_mp3.MP3Server = nullptr; audio_i2s_mp3.mic_stop = 1; + audio_i2s_mp3.stream_active = 0; AddLog(LOG_LEVEL_INFO, PSTR("MP3: server deleted")); } } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_42_7_i2s_webradio_idf51.ino b/tasmota/tasmota_xdrv_driver/xdrv_42_7_i2s_webradio_idf51.ino index c023fb1975a0..1f0a8e7e4847 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_42_7_i2s_webradio_idf51.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_42_7_i2s_webradio_idf51.ino @@ -118,6 +118,11 @@ void CmndI2SWebRadio(void) { void I2sWebRadioStopPlaying() { + if(audio_i2s_mp3.decoder) { + audio_i2s_mp3.decoder->stop(); + delete audio_i2s_mp3.decoder; + audio_i2s_mp3.decoder = nullptr; + } if (Audio_webradio.buff) { Audio_webradio.buff->close(); delete Audio_webradio.buff;