Skip to content

Commit

Permalink
multiple fixes (arendst#21511)
Browse files Browse the repository at this point in the history
  • Loading branch information
Staars authored May 28, 2024
1 parent 7b478f7 commit a4dbc57
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 259 deletions.
8 changes: 6 additions & 2 deletions lib/lib_audio/ESP8266Audio/src/AudioGeneratorMP3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion lib/lib_audio/ESP8266Audio/src/AudioOutputMixer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
20 changes: 20 additions & 0 deletions tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_3_lib_idf51.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
104 changes: 61 additions & 43 deletions tasmota/tasmota_xdrv_driver/xdrv_42_0_i2s_audio_idf51.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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){
Expand Down Expand Up @@ -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;
}

Expand All @@ -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)

Expand All @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -959,7 +970,7 @@ void CmndI2SMic(void) {


void CmndI2SStop(void) {
if (!I2SPrepareTx()) {
if (I2SPrepareTx() != I2S_OK) {
ResponseCmndChar("I2S output not configured");
return;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand All @@ -1062,6 +1077,9 @@ void CmndI2SMicRec(void) {
}
ResponseCmndChar_P(PSTR("Stopped"));
}
else {
ResponseCmndChar_P(PSTR("No running recording"));
}
}
}
else{
Expand Down
Loading

0 comments on commit a4dbc57

Please sign in to comment.