multiple fixes (#21511)

This commit is contained in:
Christian Baars 2024-05-28 10:59:57 +02:00 committed by GitHub
parent 7b478f718c
commit a4dbc57448
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 269 additions and 220 deletions

View File

@ -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 we're here, we have one decoded frame and sent 0 or more samples out
if (samplePtr < synth->pcm.length) { if (samplePtr < synth->pcm.length) {
sample[AudioOutput::LEFTCHANNEL ] = synth->pcm.samples[0][samplePtr]; 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++; samplePtr++;
} else { } else {
samplePtr = 0; samplePtr = 0;
@ -200,7 +202,9 @@ bool AudioGeneratorMP3::GetOneSample(int16_t sample[2])
} }
// for IGNORE and CONTINUE, just play what we have now // for IGNORE and CONTINUE, just play what we have now
sample[AudioOutput::LEFTCHANNEL ] = synth->pcm.samples[0][samplePtr]; 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++; samplePtr++;
} }
return true; return true;

View File

@ -190,7 +190,7 @@ bool AudioOutputMixer::loop()
} }
} }
if (avail) { if (avail) {
int16_t s[2]; int16_t s[2] = {0};
if (leftAccum[readPtr] > 32767) { if (leftAccum[readPtr] > 32767) {
s[LEFTCHANNEL] = 32767; s[LEFTCHANNEL] = 32767;
} else if (leftAccum[readPtr] < -32767) { } else if (leftAccum[readPtr] < -32767) {

View File

@ -197,6 +197,7 @@ public:
// Tx // Tx
virtual bool begin(void) { return beginTx(); }; // the name `begin()`is inherited from superclass, prefer `beginTx()` which is more explicit 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 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 beginTx(void);
bool stopTx(void); bool stopTx(void);
bool ConsumeSample(int16_t sample[2]); bool ConsumeSample(int16_t sample[2]);
@ -322,6 +323,11 @@ bool TasmotaI2S::beginTx(void) {
} else } else
#endif // SOC_DAC_SUPPORTED #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); err = i2s_channel_enable(_tx_handle);
} }
AddLog(LOG_LEVEL_INFO, "I2S: Tx i2s_channel_enable err=0x%04X", err); AddLog(LOG_LEVEL_INFO, "I2S: Tx i2s_channel_enable err=0x%04X", err);
@ -363,6 +369,20 @@ bool TasmotaI2S::stopTx() {
return true; 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) { bool TasmotaI2S::delTxHandle(void) {
esp_err_t err = ESP_OK; esp_err_t err = ESP_OK;
AddLog(LOG_LEVEL_DEBUG, "I2S: calling delTxHandle() tx_running:%i tx_handle:%p", _tx_running, _tx_handle); AddLog(LOG_LEVEL_DEBUG, "I2S: calling delTxHandle() tx_running:%i tx_handle:%p", _tx_running, _tx_handle);

View File

@ -473,7 +473,7 @@ exit:
audio_i2s.in->stopRx(); audio_i2s.in->stopRx();
audio_i2s_mp3.mic_stop = 0; audio_i2s_mp3.mic_stop = 0;
audio_i2s_mp3.mic_error = error; 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.mic_task_handle = 0;
audio_i2s_mp3.recdur = 0; audio_i2s_mp3.recdur = 0;
audio_i2s_mp3.stream_active = 0; audio_i2s_mp3.stream_active = 0;
@ -484,6 +484,15 @@ exit:
int32_t I2sRecordShine(char *path) { int32_t I2sRecordShine(char *path) {
esp_err_t err = ESP_OK; 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 #ifdef USE_I2S_MP3
if (audio_i2s_mp3.decoder || audio_i2s_mp3.mp3) return 0; if (audio_i2s_mp3.decoder || audio_i2s_mp3.mp3) return 0;
#endif #endif
@ -735,8 +744,8 @@ void I2sInit(void) {
} }
if (init_tx_ok) { audio_i2s.out = i2s; } if (init_tx_ok) { audio_i2s.out = i2s; }
if (init_rx_ok) { audio_i2s.in = i2s; } if (init_rx_ok) { audio_i2s.in = i2s; }
audio_i2s.Settings->sys.tx = init_tx_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; audio_i2s.Settings->sys.rx |= init_rx_ok;
if (init_tx_ok && init_rx_ok) { audio_i2s.Settings->sys.duplex = true; } 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 // 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.out) { audio_i2s.out->setExclusive(exclusive); }
if (audio_i2s.in) { audio_i2s.in->setExclusive(exclusive); } if (audio_i2s.in) { audio_i2s.in->setExclusive(exclusive); }
if(audio_i2s.out != nullptr){ // if(audio_i2s.out != nullptr){
audio_i2s.out->SetGain(((float)audio_i2s.Settings->tx.gain / 100.0) * 4.0); // audio_i2s.out->SetGain(((float)(audio_i2s.Settings->tx.gain + 1)/ 100.0));
audio_i2s.out->beginTx(); // TODO - useful? // audio_i2s.out->beginTx(); // TODO - useful?
audio_i2s.out->stopTx(); // audio_i2s.out->stopTx();
} // }
#ifdef USE_I2S_MP3 #ifdef USE_I2S_MP3
audio_i2s_mp3.mp3ram = nullptr; audio_i2s_mp3.mp3ram = nullptr;
if (audio_i2s.Settings->sys.mp3_preallocate == 1){ if (audio_i2s.Settings->sys.mp3_preallocate == 1){
@ -784,11 +793,21 @@ int32_t I2SPrepareTx(void) {
delay(1); 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); 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) { return I2S_ERR_OUTPUT_NOT_CONFIGURED; }
if (!audio_i2s.out->beginTx()) { return I2S_ERR_TX_FAILED; } 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; return I2S_OK;
} }
@ -813,21 +832,20 @@ int32_t I2SPrepareRx(void) {
#if defined(USE_I2S_MP3) || defined(USE_I2S_WEBRADIO) #if defined(USE_I2S_MP3) || defined(USE_I2S_WEBRADIO)
void I2sMp3Task(void *arg) { void I2sMp3Task(void *arg) {
while (1) { audio_i2s_mp3.task_running = true;
while (audio_i2s_mp3.mp3->isRunning()) { while (audio_i2s_mp3.mp3->isRunning() && audio_i2s_mp3.task_running) {
if (!audio_i2s_mp3.mp3->loop()) { if (!audio_i2s_mp3.mp3->loop()) {
audio_i2s_mp3.mp3->stop(); audio_i2s_mp3.task_running == false;
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));
} }
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) #endif // defined(USE_I2S_MP3) || defined(USE_I2S_WEBRADIO)
@ -851,29 +869,17 @@ void I2sMp3WrTask(void *arg){
vTaskDelay(pdMS_TO_TICKS(1)); vTaskDelay(pdMS_TO_TICKS(1));
} }
} }
audio_i2s_mp3.decoder->stop(); audio_i2s.out->flush();
audio_i2s_mp3.task_has_ended = true;
I2sStopPlaying(); 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 #endif // USE_I2S_MP3
void I2sStopPlaying() { void I2sStopPlaying() {
#ifdef USE_I2S_MP3
I2SStopMP3Play();
#endif // USE_I2S_MP3
#ifdef USE_I2S_WEBRADIO #ifdef USE_I2S_WEBRADIO
I2sWebRadioStopPlaying(); I2sWebRadioStopPlaying();
#endif #endif
@ -921,7 +927,12 @@ void mp3_delete(void) {
delete audio_i2s_mp3.id3; delete audio_i2s_mp3.id3;
delete audio_i2s_mp3.mp3; delete audio_i2s_mp3.mp3;
audio_i2s_mp3.mp3=nullptr; 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 #endif // USE_I2S_MP3
@ -959,7 +970,7 @@ void CmndI2SMic(void) {
void CmndI2SStop(void) { void CmndI2SStop(void) {
if (!I2SPrepareTx()) { if (I2SPrepareTx() != I2S_OK) {
ResponseCmndChar("I2S output not configured"); ResponseCmndChar("I2S output not configured");
return; return;
} }
@ -1006,7 +1017,7 @@ void CmndI2SGain(void) {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) {
if (audio_i2s.out) { if (audio_i2s.out) {
audio_i2s.Settings->tx.gain = XdrvMailbox.payload; 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); ResponseCmndNumber(audio_i2s.Settings->tx.gain);
@ -1050,8 +1061,12 @@ void CmndI2SMicRec(void) {
if (!strncmp(XdrvMailbox.data, "-?", 2)) { if (!strncmp(XdrvMailbox.data, "-?", 2)) {
Response_P("{\"I2SREC-duration\":%d}", audio_i2s_mp3.recdur); Response_P("{\"I2SREC-duration\":%d}", audio_i2s_mp3.recdur);
} else { } else {
I2sRecordShine(XdrvMailbox.data); int err = I2sRecordShine(XdrvMailbox.data);
ResponseCmndChar(XdrvMailbox.data); if(err == pdPASS){
ResponseCmndChar(XdrvMailbox.data);
} else {
ResponseCmndChar_P(PSTR("Did not launch recording task"));
}
} }
} else { } else {
if (audio_i2s_mp3.mic_task_handle) { if (audio_i2s_mp3.mic_task_handle) {
@ -1062,6 +1077,9 @@ void CmndI2SMicRec(void) {
} }
ResponseCmndChar_P(PSTR("Stopped")); ResponseCmndChar_P(PSTR("Stopped"));
} }
else {
ResponseCmndChar_P(PSTR("No running recording"));
}
} }
} }
else{ else{

View File

@ -21,219 +21,219 @@
#if defined(ESP32) && ESP_IDF_VERSION_MAJOR >= 5 #if defined(ESP32) && ESP_IDF_VERSION_MAJOR >= 5
#ifdef USE_I2S_AUDIO #ifdef USE_I2S_AUDIO
uint32_t SpeakerMic(uint8_t spkr) { // uint32_t SpeakerMic(uint8_t spkr) {
esp_err_t err = ESP_OK; // esp_err_t err = ESP_OK;
// audio_i2s.mode = spkr; // // audio_i2s.mode = spkr;
return err; // return err;
} // }
#ifdef USE_SHINE // #ifdef USE_SHINE
#include <layer3.h> // #include <layer3.h>
#include <types.h> // #include <types.h>
// micro to mp3 file or stream // // micro to mp3 file or stream
void mic_task(void *arg){ // void mic_task(void *arg){
int8_t error = 0; // int8_t error = 0;
uint8_t *ucp; // uint8_t *ucp;
int written; // int written;
shine_config_t config; // shine_config_t config;
shine_t s = nullptr; // shine_t s = nullptr;
uint16_t samples_per_pass; // uint16_t samples_per_pass;
File mp3_out = (File)nullptr; // File mp3_out = (File)nullptr;
int16_t *buffer = nullptr; // int16_t *buffer = nullptr;
uint16_t bytesize; // uint16_t bytesize;
uint16_t bwritten; // uint16_t bwritten;
uint32_t ctime; // uint32_t ctime;
if (!audio_i2s_mp3.use_stream) { // if (!audio_i2s_mp3.use_stream) {
mp3_out = ufsp->open(audio_i2s_mp3.mic_path, "w"); // mp3_out = ufsp->open(audio_i2s_mp3.mic_path, "w");
if (!mp3_out) { // if (!mp3_out) {
error = 1; // error = 1;
goto exit; // goto exit;
} // }
} else { // } else {
if (!audio_i2s_mp3.stream_active) { // if (!audio_i2s_mp3.stream_active) {
error = 2; // error = 2;
audio_i2s_mp3.use_stream = 0; // audio_i2s_mp3.use_stream = 0;
goto exit; // goto exit;
} // }
audio_i2s_mp3.client.flush(); // audio_i2s_mp3.client.flush();
audio_i2s_mp3.client.setTimeout(3); // audio_i2s_mp3.client.setTimeout(3);
audio_i2s_mp3.client.print("HTTP/1.1 200 OK\r\n" // audio_i2s_mp3.client.print("HTTP/1.1 200 OK\r\n"
"Content-Type: audio/mpeg;\r\n\r\n"); // "Content-Type: audio/mpeg;\r\n\r\n");
// Webserver->send(200, "application/octet-stream", ""); // // Webserver->send(200, "application/octet-stream", "");
//"Content-Type: audio/mp3;\r\n\r\n"); // //"Content-Type: audio/mp3;\r\n\r\n");
} // }
shine_set_config_mpeg_defaults(&config.mpeg); // shine_set_config_mpeg_defaults(&config.mpeg);
if (audio_i2s.Settings->rx.channels == 1) { // if (audio_i2s.Settings->rx.channels == 1) {
config.mpeg.mode = MONO; // config.mpeg.mode = MONO;
} else { // } else {
config.mpeg.mode = STEREO; // config.mpeg.mode = STEREO;
} // }
config.mpeg.bitr = 128; // config.mpeg.bitr = 128;
config.wave.samplerate = audio_i2s.Settings->rx.sample_rate; // config.wave.samplerate = audio_i2s.Settings->rx.sample_rate;
config.wave.channels = (channels)audio_i2s.Settings->rx.channels; // config.wave.channels = (channels)audio_i2s.Settings->rx.channels;
if (shine_check_config(config.wave.samplerate, config.mpeg.bitr) < 0) { // if (shine_check_config(config.wave.samplerate, config.mpeg.bitr) < 0) {
error = 3; // error = 3;
goto exit; // goto exit;
} // }
s = shine_initialise(&config); // s = shine_initialise(&config);
if (!s) { // if (!s) {
error = 4; // error = 4;
goto exit; // goto exit;
} // }
samples_per_pass = shine_samples_per_pass(s); // samples_per_pass = shine_samples_per_pass(s);
bytesize = samples_per_pass * 2 * audio_i2s.Settings->rx.channels; // bytesize = samples_per_pass * 2 * audio_i2s.Settings->rx.channels;
buffer = (int16_t*)malloc(bytesize); // buffer = (int16_t*)malloc(bytesize);
if (!buffer) { // if (!buffer) {
error = 5; // error = 5;
goto exit; // goto exit;
} // }
ctime = TasmotaGlobal.uptime; // ctime = TasmotaGlobal.uptime;
while (!audio_i2s_mp3.mic_stop) { // while (!audio_i2s_mp3.mic_stop) {
uint32_t bytes_read; // 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*/); // 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)); // // i2s_read(audio_i2s.mic_port, (char *)buffer, bytesize, &bytes_read, (100 / portTICK_PERIOD_MS));
if (audio_i2s.Settings->rx.gain > 1) { // if (audio_i2s.Settings->rx.gain > 1) {
// set gain // // set gain
for (uint32_t cnt = 0; cnt < bytes_read / 2; cnt++) { // for (uint32_t cnt = 0; cnt < bytes_read / 2; cnt++) {
buffer[cnt] *= audio_i2s.Settings->rx.gain; // buffer[cnt] *= audio_i2s.Settings->rx.gain;
} // }
} // }
ucp = shine_encode_buffer_interleaved(s, buffer, &written); // ucp = shine_encode_buffer_interleaved(s, buffer, &written);
if (!audio_i2s.Settings->tx.stream_enable) { // if (!audio_i2s.Settings->tx.stream_enable) {
bwritten = mp3_out.write(ucp, written); // bwritten = mp3_out.write(ucp, written);
if (bwritten != written) { // if (bwritten != written) {
break; // break;
} // }
} else { // } else {
audio_i2s_mp3.client.write((const char*)ucp, written); // audio_i2s_mp3.client.write((const char*)ucp, written);
if (!audio_i2s_mp3.client.connected()) { // if (!audio_i2s_mp3.client.connected()) {
break; // break;
} // }
} // }
audio_i2s_mp3.recdur = TasmotaGlobal.uptime - ctime; // audio_i2s_mp3.recdur = TasmotaGlobal.uptime - ctime;
} // }
ucp = shine_flush(s, &written); // ucp = shine_flush(s, &written);
if (!audio_i2s_mp3.use_stream) { // if (!audio_i2s_mp3.use_stream) {
mp3_out.write(ucp, written); // mp3_out.write(ucp, written);
} else { // } else {
audio_i2s_mp3.client.write((const char*)ucp, written); // audio_i2s_mp3.client.write((const char*)ucp, written);
} // }
exit: // exit:
if (s) { // if (s) {
shine_close(s); // shine_close(s);
} // }
if (mp3_out) { // if (mp3_out) {
mp3_out.close(); // mp3_out.close();
} // }
if (buffer) { // if (buffer) {
free(buffer); // free(buffer);
} // }
if (audio_i2s_mp3.use_stream) { // if (audio_i2s_mp3.use_stream) {
audio_i2s_mp3.client.stop(); // audio_i2s_mp3.client.stop();
} // }
SpeakerMic(I2S_AUDIO_MODE_SPK); // SpeakerMic(I2S_AUDIO_MODE_SPK);
audio_i2s_mp3.mic_stop = 0; // audio_i2s_mp3.mic_stop = 0;
audio_i2s_mp3.mic_error = error; // audio_i2s_mp3.mic_error = error;
AddLog(LOG_LEVEL_INFO, PSTR("mp3task result code: %d"), error); // AddLog(LOG_LEVEL_INFO, PSTR("mp3task result code: %d"), error);
audio_i2s_mp3.mic_task_handle = 0; // audio_i2s_mp3.mic_task_handle = 0;
audio_i2s_mp3.recdur = 0; // audio_i2s_mp3.recdur = 0;
audio_i2s_mp3.stream_active = 0; // audio_i2s_mp3.stream_active = 0;
vTaskDelete(NULL); // vTaskDelete(NULL);
} // }
int32_t i2s_record_shine(char *path) { // int32_t i2s_record_shine(char *path) {
esp_err_t err = ESP_OK; // esp_err_t err = ESP_OK;
if (audio_i2s.in) { // if (audio_i2s.in) {
if (audio_i2s_mp3.decoder || audio_i2s_mp3.mp3) return 0; // if (audio_i2s_mp3.decoder || audio_i2s_mp3.mp3) return 0;
} // }
err = SpeakerMic(I2S_AUDIO_MODE_MIC); // err = SpeakerMic(I2S_AUDIO_MODE_MIC);
if (err) { // if (err) {
if (audio_i2s.in) { // if (audio_i2s.in) {
SpeakerMic(I2S_AUDIO_MODE_SPK); // SpeakerMic(I2S_AUDIO_MODE_SPK);
} // }
AddLog(LOG_LEVEL_INFO, PSTR("mic init error: %d"), err); // AddLog(LOG_LEVEL_INFO, PSTR("mic init error: %d"), err);
return err; // return err;
} // }
strlcpy(audio_i2s_mp3.mic_path, path, sizeof(audio_i2s_mp3.mic_path)); // strlcpy(audio_i2s_mp3.mic_path, path, sizeof(audio_i2s_mp3.mic_path));
audio_i2s_mp3.mic_stop = 0; // audio_i2s_mp3.mic_stop = 0;
uint32_t stack = 4096; // uint32_t stack = 4096;
audio_i2s_mp3.use_stream = !strcmp(audio_i2s_mp3.mic_path, "stream.mp3"); // audio_i2s_mp3.use_stream = !strcmp(audio_i2s_mp3.mic_path, "stream.mp3");
if (audio_i2s_mp3.use_stream) { // if (audio_i2s_mp3.use_stream) {
stack = 8000; // stack = 8000;
} // }
err = xTaskCreatePinnedToCore(mic_task, "MIC", stack, NULL, 3, &audio_i2s_mp3.mic_task_handle, 1); // err = xTaskCreatePinnedToCore(mic_task, "MIC", stack, NULL, 3, &audio_i2s_mp3.mic_task_handle, 1);
return err; // return err;
} // }
void Cmd_MicRec(void) { // void Cmd_MicRec(void) {
if (XdrvMailbox.data_len > 0) { // if (XdrvMailbox.data_len > 0) {
if (!strncmp(XdrvMailbox.data, "-?", 2)) { // if (!strncmp(XdrvMailbox.data, "-?", 2)) {
Response_P("{\"I2SREC-duration\":%d}", audio_i2s_mp3.recdur); // Response_P("{\"I2SREC-duration\":%d}", audio_i2s_mp3.recdur);
} else { // } else {
i2s_record_shine(XdrvMailbox.data); // i2s_record_shine(XdrvMailbox.data);
ResponseCmndChar(XdrvMailbox.data); // ResponseCmndChar(XdrvMailbox.data);
} // }
} else { // } else {
if (audio_i2s_mp3.mic_task_handle) { // if (audio_i2s_mp3.mic_task_handle) {
// stop task // // stop task
audio_i2s_mp3.mic_stop = 1; // audio_i2s_mp3.mic_stop = 1;
while (audio_i2s_mp3.mic_stop) { // while (audio_i2s_mp3.mic_stop) {
delay(1); // delay(1);
} // }
ResponseCmndChar_P(PSTR("Stopped")); // ResponseCmndChar_P(PSTR("Stopped"));
} // }
} // }
} // }
#endif // USE_SHINE // #endif // USE_SHINE
// mic gain in factor not percent // // mic gain in factor not percent
void Cmd_MicGain(void) { // void Cmd_MicGain(void) {
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 256)) { // if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 256)) {
if (audio_i2s.in) { // if (audio_i2s.in) {
audio_i2s.in->setRxGain(XdrvMailbox.payload); // audio_i2s.in->setRxGain(XdrvMailbox.payload);
} // }
if (audio_i2s.Settings) { // if (audio_i2s.Settings) {
audio_i2s.Settings->rx.gain = XdrvMailbox.payload * 16; // audio_i2s.Settings->rx.gain = XdrvMailbox.payload * 16;
} // }
I2SSettingsSave(AUDIO_CONFIG_FILENAME); // I2SSettingsSave(AUDIO_CONFIG_FILENAME);
} // }
ResponseCmndNumber(audio_i2s.Settings->rx.gain / 16); // ResponseCmndNumber(audio_i2s.Settings->rx.gain / 16);
} // }
#endif // USE_I2S_AUDIO #endif // USE_I2S_AUDIO
#endif // defined(ESP32) && ESP_IDF_VERSION_MAJOR >= 5 #endif // defined(ESP32) && ESP_IDF_VERSION_MAJOR >= 5

View File

@ -27,6 +27,7 @@
void Stream_mp3(void) { void Stream_mp3(void) {
if (audio_i2s_mp3.stream_active) { if (audio_i2s_mp3.stream_active) {
AddLog(LOG_LEVEL_INFO, PSTR("I2S: can not handle client - other MP3 task active"));
return; return;
} }
AddLog(LOG_LEVEL_INFO, PSTR("I2S: Handle mp3server")); AddLog(LOG_LEVEL_INFO, PSTR("I2S: Handle mp3server"));
@ -58,6 +59,7 @@ void I2sMp3Init(uint32_t on) {
delete audio_i2s_mp3.MP3Server; delete audio_i2s_mp3.MP3Server;
audio_i2s_mp3.MP3Server = nullptr; audio_i2s_mp3.MP3Server = nullptr;
audio_i2s_mp3.mic_stop = 1; audio_i2s_mp3.mic_stop = 1;
audio_i2s_mp3.stream_active = 0;
AddLog(LOG_LEVEL_INFO, PSTR("MP3: server deleted")); AddLog(LOG_LEVEL_INFO, PSTR("MP3: server deleted"));
} }
} }

View File

@ -118,6 +118,11 @@ void CmndI2SWebRadio(void) {
void I2sWebRadioStopPlaying() { 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) { if (Audio_webradio.buff) {
Audio_webradio.buff->close(); Audio_webradio.buff->close();
delete Audio_webradio.buff; delete Audio_webradio.buff;