Skip to content

Commit a4dbc57

Browse files
authored
multiple fixes (arendst#21511)
1 parent 7b478f7 commit a4dbc57

7 files changed

+308
-259
lines changed

lib/lib_audio/ESP8266Audio/src/AudioGeneratorMP3.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,9 @@ bool AudioGeneratorMP3::GetOneSample(int16_t sample[2])
186186
// If we're here, we have one decoded frame and sent 0 or more samples out
187187
if (samplePtr < synth->pcm.length) {
188188
sample[AudioOutput::LEFTCHANNEL ] = synth->pcm.samples[0][samplePtr];
189-
sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr];
189+
if(lastChannels == 2) {
190+
sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr];
191+
}
190192
samplePtr++;
191193
} else {
192194
samplePtr = 0;
@@ -200,7 +202,9 @@ bool AudioGeneratorMP3::GetOneSample(int16_t sample[2])
200202
}
201203
// for IGNORE and CONTINUE, just play what we have now
202204
sample[AudioOutput::LEFTCHANNEL ] = synth->pcm.samples[0][samplePtr];
203-
sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr];
205+
if(lastChannels == 2) {
206+
sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr];
207+
}
204208
samplePtr++;
205209
}
206210
return true;

lib/lib_audio/ESP8266Audio/src/AudioOutputMixer.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ bool AudioOutputMixer::loop()
190190
}
191191
}
192192
if (avail) {
193-
int16_t s[2];
193+
int16_t s[2] = {0};
194194
if (leftAccum[readPtr] > 32767) {
195195
s[LEFTCHANNEL] = 32767;
196196
} else if (leftAccum[readPtr] < -32767) {

tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_3_lib_idf51.ino

+20
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ public:
197197
// Tx
198198
virtual bool begin(void) { return beginTx(); }; // the name `begin()`is inherited from superclass, prefer `beginTx()` which is more explicit
199199
virtual bool stop(void) { return stopTx(); }; // the name `stop()`is inherited from superclass, prefer `stopTx()` which is more explicit
200+
virtual void flush(void); // makes sure that all stored DMA samples are consumed / played to prevent static noise after stop()
200201
bool beginTx(void);
201202
bool stopTx(void);
202203
bool ConsumeSample(int16_t sample[2]);
@@ -322,6 +323,11 @@ bool TasmotaI2S::beginTx(void) {
322323
} else
323324
#endif // SOC_DAC_SUPPORTED
324325
{
326+
uint8_t zero_buffer[240] = {0};
327+
size_t sz;
328+
for(int i = 0;i < 6;i++){
329+
i2s_channel_preload_data(_tx_handle, zero_buffer, sizeof(zero_buffer), &sz); // preload DMA buffer with silence
330+
}
325331
err = i2s_channel_enable(_tx_handle);
326332
}
327333
AddLog(LOG_LEVEL_INFO, "I2S: Tx i2s_channel_enable err=0x%04X", err);
@@ -363,6 +369,20 @@ bool TasmotaI2S::stopTx() {
363369
return true;
364370
}
365371

372+
void TasmotaI2S::flush()
373+
{
374+
int buffersize = 6 * 240;
375+
int16_t samples[2] = {0x0, 0x0};
376+
for (int i = 0; i < buffersize; i++)
377+
{
378+
while (!ConsumeSample(samples))
379+
{
380+
delay(1);
381+
}
382+
}
383+
AddLog(LOG_LEVEL_INFO, "I2S: flush DMA TX buffer");
384+
}
385+
366386
bool TasmotaI2S::delTxHandle(void) {
367387
esp_err_t err = ESP_OK;
368388
AddLog(LOG_LEVEL_DEBUG, "I2S: calling delTxHandle() tx_running:%i tx_handle:%p", _tx_running, _tx_handle);

tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_audio_idf51.ino

+61-43
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ exit:
473473
audio_i2s.in->stopRx();
474474
audio_i2s_mp3.mic_stop = 0;
475475
audio_i2s_mp3.mic_error = error;
476-
AddLog(LOG_LEVEL_INFO, PSTR("mp3task result code: %d"), error);
476+
AddLog(LOG_LEVEL_INFO, PSTR("I2S: mp3task result code: %d"), error);
477477
audio_i2s_mp3.mic_task_handle = 0;
478478
audio_i2s_mp3.recdur = 0;
479479
audio_i2s_mp3.stream_active = 0;
@@ -484,6 +484,15 @@ exit:
484484
int32_t I2sRecordShine(char *path) {
485485
esp_err_t err = ESP_OK;
486486

487+
switch(audio_i2s.Settings->rx.sample_rate){
488+
case 32000: case 48000: case 44100:
489+
break; // supported
490+
default:
491+
AddLog(LOG_LEVEL_INFO, PSTR("I2S: unsupported sample rate for MP3 encoding: %d"), audio_i2s.Settings->rx.sample_rate);
492+
return -1;
493+
}
494+
AddLog(LOG_LEVEL_INFO, PSTR("I2S: accepted sample rate for MP3 encoding: %d"), audio_i2s.Settings->rx.sample_rate);
495+
487496
#ifdef USE_I2S_MP3
488497
if (audio_i2s_mp3.decoder || audio_i2s_mp3.mp3) return 0;
489498
#endif
@@ -735,8 +744,8 @@ void I2sInit(void) {
735744
}
736745
if (init_tx_ok) { audio_i2s.out = i2s; }
737746
if (init_rx_ok) { audio_i2s.in = i2s; }
738-
audio_i2s.Settings->sys.tx = init_tx_ok;
739-
audio_i2s.Settings->sys.rx = init_rx_ok;
747+
audio_i2s.Settings->sys.tx |= init_tx_ok; // Do not set to zero id already configured on another channnel
748+
audio_i2s.Settings->sys.rx |= init_rx_ok;
740749
if (init_tx_ok && init_rx_ok) { audio_i2s.Settings->sys.duplex = true; }
741750

742751
// if intput and output are configured, don't proceed with other IS2 ports
@@ -750,11 +759,11 @@ void I2sInit(void) {
750759
if (audio_i2s.out) { audio_i2s.out->setExclusive(exclusive); }
751760
if (audio_i2s.in) { audio_i2s.in->setExclusive(exclusive); }
752761

753-
if(audio_i2s.out != nullptr){
754-
audio_i2s.out->SetGain(((float)audio_i2s.Settings->tx.gain / 100.0) * 4.0);
755-
audio_i2s.out->beginTx(); // TODO - useful?
756-
audio_i2s.out->stopTx();
757-
}
762+
// if(audio_i2s.out != nullptr){
763+
// audio_i2s.out->SetGain(((float)(audio_i2s.Settings->tx.gain + 1)/ 100.0));
764+
// audio_i2s.out->beginTx(); // TODO - useful?
765+
// audio_i2s.out->stopTx();
766+
// }
758767
#ifdef USE_I2S_MP3
759768
audio_i2s_mp3.mp3ram = nullptr;
760769
if (audio_i2s.Settings->sys.mp3_preallocate == 1){
@@ -784,11 +793,21 @@ int32_t I2SPrepareTx(void) {
784793
delay(1);
785794
}
786795
}
796+
797+
if (audio_i2s_mp3.mic_task_handle) {
798+
audio_i2s_mp3.mic_stop = 1;
799+
while (audio_i2s_mp3.mic_stop) {
800+
delay(1);
801+
}
802+
}
787803

788804
AddLog(LOG_LEVEL_DEBUG, "I2S: I2SPrepareTx out=%p", audio_i2s.out);
789805
if (!audio_i2s.out) { return I2S_ERR_OUTPUT_NOT_CONFIGURED; }
790806

791807
if (!audio_i2s.out->beginTx()) { return I2S_ERR_TX_FAILED; }
808+
809+
audio_i2s.out->SetGain(((float)(audio_i2s.Settings->tx.gain + 1)/ 100.0));
810+
792811
return I2S_OK;
793812
}
794813

@@ -813,21 +832,20 @@ int32_t I2SPrepareRx(void) {
813832

814833
#if defined(USE_I2S_MP3) || defined(USE_I2S_WEBRADIO)
815834
void I2sMp3Task(void *arg) {
816-
while (1) {
817-
while (audio_i2s_mp3.mp3->isRunning()) {
818-
if (!audio_i2s_mp3.mp3->loop()) {
819-
audio_i2s_mp3.mp3->stop();
820-
mp3_delete();
821-
audio_i2s.out->stop();
822-
if (audio_i2s_mp3.mp3_task_handle) {
823-
vTaskDelete(audio_i2s_mp3.mp3_task_handle);
824-
audio_i2s_mp3.mp3_task_handle = 0;
825-
}
826-
//mp3_task_handle=nullptr;
827-
}
828-
vTaskDelay(pdMS_TO_TICKS(1));
835+
audio_i2s_mp3.task_running = true;
836+
while (audio_i2s_mp3.mp3->isRunning() && audio_i2s_mp3.task_running) {
837+
if (!audio_i2s_mp3.mp3->loop()) {
838+
audio_i2s_mp3.task_running == false;
829839
}
840+
vTaskDelay(pdMS_TO_TICKS(1));
830841
}
842+
audio_i2s.out->flush();
843+
audio_i2s_mp3.mp3->stop();
844+
I2sStopPlaying();
845+
mp3_delete();
846+
audio_i2s_mp3.mp3_task_handle = nullptr;
847+
audio_i2s_mp3.task_has_ended = true;
848+
vTaskDelete(NULL);
831849
}
832850
#endif // defined(USE_I2S_MP3) || defined(USE_I2S_WEBRADIO)
833851

@@ -851,29 +869,17 @@ void I2sMp3WrTask(void *arg){
851869
vTaskDelay(pdMS_TO_TICKS(1));
852870
}
853871
}
854-
audio_i2s_mp3.decoder->stop();
855-
audio_i2s_mp3.task_has_ended = true;
872+
audio_i2s.out->flush();
856873
I2sStopPlaying();
874+
audio_i2s_mp3.mp3_task_handle = nullptr;
875+
audio_i2s_mp3.task_has_ended = true;
876+
vTaskDelete(NULL);
857877
}
858-
void I2SStopMP3Play(void) {
859878

860-
if (audio_i2s_mp3.decoder) {
861-
audio_i2s_mp3.decoder->stop();
862-
delete audio_i2s_mp3.decoder;
863-
audio_i2s_mp3.decoder = NULL;
864-
}
865-
866-
if (audio_i2s_mp3.mp3_task_handle) {
867-
vTaskDelete(audio_i2s_mp3.mp3_task_handle);
868-
audio_i2s_mp3.mp3_task_handle = nullptr;
869-
}
870-
}
871879
#endif // USE_I2S_MP3
872880

873881
void I2sStopPlaying() {
874-
#ifdef USE_I2S_MP3
875-
I2SStopMP3Play();
876-
#endif // USE_I2S_MP3
882+
877883
#ifdef USE_I2S_WEBRADIO
878884
I2sWebRadioStopPlaying();
879885
#endif
@@ -921,7 +927,12 @@ void mp3_delete(void) {
921927
delete audio_i2s_mp3.id3;
922928
delete audio_i2s_mp3.mp3;
923929
audio_i2s_mp3.mp3=nullptr;
924-
I2SAudioPower(false);
930+
931+
if (audio_i2s_mp3.decoder) {
932+
audio_i2s_mp3.decoder->stop();
933+
delete audio_i2s_mp3.decoder;
934+
audio_i2s_mp3.decoder = NULL;
935+
}
925936
}
926937
#endif // USE_I2S_MP3
927938

@@ -959,7 +970,7 @@ void CmndI2SMic(void) {
959970

960971

961972
void CmndI2SStop(void) {
962-
if (!I2SPrepareTx()) {
973+
if (I2SPrepareTx() != I2S_OK) {
963974
ResponseCmndChar("I2S output not configured");
964975
return;
965976
}
@@ -1006,7 +1017,7 @@ void CmndI2SGain(void) {
10061017
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) {
10071018
if (audio_i2s.out) {
10081019
audio_i2s.Settings->tx.gain = XdrvMailbox.payload;
1009-
audio_i2s.out->SetGain(((float)(audio_i2s.Settings->tx.gain-2)/100.0)*4.0);
1020+
audio_i2s.out->SetGain(((float)(audio_i2s.Settings->tx.gain+1)/100.0));
10101021
}
10111022
}
10121023
ResponseCmndNumber(audio_i2s.Settings->tx.gain);
@@ -1050,8 +1061,12 @@ void CmndI2SMicRec(void) {
10501061
if (!strncmp(XdrvMailbox.data, "-?", 2)) {
10511062
Response_P("{\"I2SREC-duration\":%d}", audio_i2s_mp3.recdur);
10521063
} else {
1053-
I2sRecordShine(XdrvMailbox.data);
1054-
ResponseCmndChar(XdrvMailbox.data);
1064+
int err = I2sRecordShine(XdrvMailbox.data);
1065+
if(err == pdPASS){
1066+
ResponseCmndChar(XdrvMailbox.data);
1067+
} else {
1068+
ResponseCmndChar_P(PSTR("Did not launch recording task"));
1069+
}
10551070
}
10561071
} else {
10571072
if (audio_i2s_mp3.mic_task_handle) {
@@ -1062,6 +1077,9 @@ void CmndI2SMicRec(void) {
10621077
}
10631078
ResponseCmndChar_P(PSTR("Stopped"));
10641079
}
1080+
else {
1081+
ResponseCmndChar_P(PSTR("No running recording"));
1082+
}
10651083
}
10661084
}
10671085
else{

0 commit comments

Comments
 (0)