mirror of https://github.com/arendst/Tasmota.git
final i2s fix (#21770)
This commit is contained in:
parent
7e22861090
commit
3d34097275
|
@ -105,7 +105,7 @@ public:
|
|||
|
||||
void setSlotConfig(i2s_port_t i2s_port, uint8_t tx_slot_config,
|
||||
uint8_t tx_slot_mask, uint8_t rx_slot_mask) {
|
||||
_i2s_port = i2s_port;
|
||||
// _i2s_port = i2s_port;
|
||||
_tx_slot_config = tx_slot_config;
|
||||
}
|
||||
void setRxFreq(uint16_t freq) { _rx_freq = freq; }
|
||||
|
@ -323,14 +323,9 @@ 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);
|
||||
AddLog(LOG_LEVEL_DEBUG, "I2S: Tx i2s_channel_enable err=0x%04X", err);
|
||||
if (err != ERR_OK){
|
||||
return false;
|
||||
}
|
||||
|
@ -349,6 +344,11 @@ bool TasmotaI2S::stopTx() {
|
|||
dac_task_stop();
|
||||
err = dac_continuous_disable((dac_continuous_handle_t) _tx_handle);
|
||||
} else {
|
||||
uint8_t zero_buffer[240] = {0};
|
||||
size_t sz;
|
||||
for(int i = 0;i < 6;i++){
|
||||
i2s_channel_write(_tx_handle, zero_buffer, sizeof(zero_buffer), &sz, 0); // fill DMA buffer with silence
|
||||
}
|
||||
err = i2s_channel_disable(_tx_handle);
|
||||
}
|
||||
AddLog(LOG_LEVEL_DEBUG, "I2S: stopTx i2s_channel_disable err=0x%04X", err);
|
||||
|
@ -364,7 +364,7 @@ bool TasmotaI2S::stopTx() {
|
|||
AddLog(LOG_LEVEL_DEBUG, "I2S: stopTx i2s_del_channel err=0x%04X", err);
|
||||
_tx_handle = nullptr;
|
||||
}
|
||||
AddLog(LOG_LEVEL_INFO, "I2S: stop: I2S channel disabled");
|
||||
AddLog(LOG_LEVEL_DEBUG, "I2S: stop: I2S channel disabled");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -380,7 +380,7 @@ void TasmotaI2S::flush()
|
|||
delay(1);
|
||||
}
|
||||
}
|
||||
AddLog(LOG_LEVEL_INFO, "I2S: flush DMA TX buffer");
|
||||
AddLog(LOG_LEVEL_DEBUG, "I2S: flush DMA TX buffer");
|
||||
}
|
||||
|
||||
bool TasmotaI2S::delTxHandle(void) {
|
||||
|
|
|
@ -718,8 +718,8 @@ void I2sInit(void) {
|
|||
audio_i2s.Settings->tx.slot_mask, audio_i2s.Settings->rx.slot_mask);
|
||||
if (tx) {
|
||||
i2s->setTxMode(audio_i2s.Settings->tx.mode);
|
||||
i2s->setTxChannels(audio_i2s.Settings->tx.channels);
|
||||
i2s->setRate(audio_i2s.Settings->tx.sample_rate);
|
||||
// i2s->setTxChannels(audio_i2s.Settings->tx.channels);
|
||||
// i2s->setRate(audio_i2s.Settings->tx.sample_rate);
|
||||
}
|
||||
if (rx) {
|
||||
i2s->setRxMode(audio_i2s.Settings->rx.mode);
|
||||
|
@ -786,20 +786,7 @@ void I2sInit(void) {
|
|||
//
|
||||
// Returns `I2S_OK` if ok to send to output or error code
|
||||
int32_t I2SPrepareTx(void) {
|
||||
|
||||
if(audio_i2s_mp3.task_running){
|
||||
audio_i2s_mp3.task_running = false;
|
||||
while(!audio_i2s_mp3.task_has_ended){
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (audio_i2s_mp3.mic_task_handle) {
|
||||
audio_i2s_mp3.mic_stop = 1;
|
||||
while (audio_i2s_mp3.mic_stop) {
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
I2sStopPlaying();
|
||||
|
||||
AddLog(LOG_LEVEL_DEBUG, "I2S: I2SPrepareTx out=%p", audio_i2s.out);
|
||||
if (!audio_i2s.out) { return I2S_ERR_OUTPUT_NOT_CONFIGURED; }
|
||||
|
@ -835,13 +822,12 @@ void I2sMp3Task(void *arg) {
|
|||
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;
|
||||
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;
|
||||
|
@ -853,8 +839,7 @@ void I2sStatusCallback(void *cbData, int code, const char *string) {
|
|||
const char *ptr = reinterpret_cast<const char *>(cbData);
|
||||
(void) code;
|
||||
(void) ptr;
|
||||
//strncpy_P(status, string, sizeof(status)-1);
|
||||
//status[sizeof(status)-1] = 0;
|
||||
AddLog(LOG_LEVEL_DEBUG, "I2S: -> %s", string);
|
||||
}
|
||||
|
||||
#ifdef USE_I2S_MP3
|
||||
|
@ -870,7 +855,7 @@ void I2sMp3WrTask(void *arg){
|
|||
}
|
||||
}
|
||||
audio_i2s.out->flush();
|
||||
I2sStopPlaying();
|
||||
I2sWebRadioStopPlaying();
|
||||
audio_i2s_mp3.mp3_task_handle = nullptr;
|
||||
audio_i2s_mp3.task_has_ended = true;
|
||||
vTaskDelete(NULL);
|
||||
|
@ -879,11 +864,23 @@ void I2sMp3WrTask(void *arg){
|
|||
#endif // USE_I2S_MP3
|
||||
|
||||
void I2sStopPlaying() {
|
||||
|
||||
#ifdef USE_I2S_WEBRADIO
|
||||
I2sWebRadioStopPlaying();
|
||||
#endif
|
||||
I2SAudioPower(false);
|
||||
|
||||
if(audio_i2s_mp3.task_running){
|
||||
audio_i2s_mp3.task_running = false;
|
||||
while(audio_i2s_mp3.task_has_ended == false){
|
||||
delay(10);
|
||||
}
|
||||
while(audio_i2s_mp3.mp3){
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
if (audio_i2s_mp3.mic_task_handle) {
|
||||
audio_i2s_mp3.mic_stop = 1;
|
||||
while (audio_i2s_mp3.mic_stop) {
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_I2S_MP3
|
||||
|
@ -891,9 +888,9 @@ void I2sStopPlaying() {
|
|||
//
|
||||
// Returns I2S_error_t
|
||||
int32_t I2SPlayMp3(const char *path) {
|
||||
int32_t i2s_err = I2S_OK;
|
||||
if ((i2s_err = I2SPrepareTx()) != I2S_OK) { return i2s_err; }
|
||||
if (audio_i2s_mp3.decoder || audio_i2s_mp3.mp3) return I2S_ERR_DECODER_IN_USE;
|
||||
int32_t i2s_err = I2SPrepareTx();
|
||||
if ((i2s_err) != I2S_OK) { return i2s_err; }
|
||||
if (audio_i2s_mp3.mp3) return I2S_ERR_DECODER_IN_USE;
|
||||
|
||||
// check if the filename starts with '/', if not add it
|
||||
char fname[64];
|
||||
|
@ -926,13 +923,14 @@ void mp3_delete(void) {
|
|||
delete audio_i2s_mp3.file;
|
||||
delete audio_i2s_mp3.id3;
|
||||
delete audio_i2s_mp3.mp3;
|
||||
audio_i2s_mp3.mp3=nullptr;
|
||||
audio_i2s_mp3.mp3 = nullptr;
|
||||
|
||||
if (audio_i2s_mp3.decoder) {
|
||||
audio_i2s_mp3.decoder->stop();
|
||||
delete audio_i2s_mp3.decoder;
|
||||
audio_i2s_mp3.decoder = NULL;
|
||||
}
|
||||
// if (audio_i2s_mp3.decoder) {
|
||||
// audio_i2s_mp3.decoder->stop();
|
||||
// delete audio_i2s_mp3.decoder;
|
||||
// audio_i2s_mp3.decoder = nullptr;
|
||||
// AddLog(LOG_LEVEL_DEBUG, "I2S: audio_i2s_mp3.decoder = nullptr");
|
||||
// }
|
||||
}
|
||||
#endif // USE_I2S_MP3
|
||||
|
||||
|
@ -974,16 +972,12 @@ void CmndI2SStop(void) {
|
|||
ResponseCmndChar("I2S output not configured");
|
||||
return;
|
||||
}
|
||||
I2sStopPlaying();
|
||||
audio_i2s.out->setGain(0);
|
||||
ResponseCmndDone();
|
||||
}
|
||||
|
||||
#ifdef USE_I2S_MP3
|
||||
void CmndI2SPlay(void) {
|
||||
if (I2SPrepareTx()) {
|
||||
ResponseCmndChar("I2S output not configured");
|
||||
return;
|
||||
}
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
int32_t err = I2SPlayMp3(XdrvMailbox.data);
|
||||
// display return message
|
||||
|
|
|
@ -75,11 +75,18 @@ void Webradio(const char *url) {
|
|||
I2sWebRadioStopPlaying();
|
||||
return;
|
||||
}
|
||||
|
||||
AddLog(LOG_LEVEL_INFO, "I2S: did connect to %s",url);
|
||||
|
||||
I2SAudioPower(true);
|
||||
Audio_webradio.buff = new AudioFileSourceBuffer(Audio_webradio.ifile, Audio_webradio.preallocateBuffer, preallocateBufferSize);
|
||||
if(Audio_webradio.buff == nullptr){
|
||||
return;
|
||||
}
|
||||
Audio_webradio.buff->RegisterStatusCB(I2sStatusCallback, NULL);
|
||||
audio_i2s_mp3.decoder = new AudioGeneratorMP3(Audio_webradio.preallocateCodec, preallocateCodecSize);
|
||||
if(audio_i2s_mp3.decoder == nullptr){
|
||||
return;
|
||||
}
|
||||
audio_i2s_mp3.decoder->RegisterStatusCB(I2sStatusCallback, NULL);
|
||||
audio_i2s_mp3.decoder->begin(Audio_webradio.buff, audio_i2s.out);
|
||||
if (!audio_i2s_mp3.decoder->isRunning()) {
|
||||
|
|
Loading…
Reference in New Issue