Improved audio lib error handling and aborting playback
All checks were successful
Deploy Docs / build-and-deploy (push) Successful in 12s
All checks were successful
Deploy Docs / build-and-deploy (push) Successful in 12s
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <fs_mgmt.h>
|
||||
#include <audio.h>
|
||||
#include <hal/nrf_i2s.h>
|
||||
|
||||
LOG_MODULE_REGISTER(MMS, LOG_LEVEL_INF);
|
||||
|
||||
@@ -27,10 +28,16 @@ int main(void)
|
||||
|
||||
LOG_INF("Triggering first sound...");
|
||||
audio_play_sound("s1");
|
||||
audio_play_sound("dead");
|
||||
audio_play_sound("g1");
|
||||
k_sleep(K_MSEC(100));
|
||||
audio_stop();
|
||||
LOG_INF("Triggering second sound after abort...");
|
||||
audio_play_sound("s1");
|
||||
|
||||
k_sleep(K_MSEC(100));
|
||||
// Directly stop the I2S peripheral to simulate an abrupt stop that might occur with a DMA failure or similar issue. This will cause the next playback attempt to hit the slab timeout and trigger the I2S reset logic in the audio thread.
|
||||
NRF_I2S0->TASKS_STOP = 1;
|
||||
NRF_I2S0->ENABLE = 0;
|
||||
LOG_INF("Triggering third sound after failure simulation...");
|
||||
audio_play_sound("s1");
|
||||
audio_play_sound("dead");
|
||||
audio_play_sound("g1");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ if AUDIO
|
||||
config AUDIO_BLOCK_SIZE
|
||||
int "Audio Block Size (bytes)"
|
||||
default 1024
|
||||
range 256 4096
|
||||
range 256 8192
|
||||
help
|
||||
Set the size of each audio block in bytes. Larger blocks can reduce CPU overhead but increase latency. Default is 1024 bytes.
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@ void audio_thread_fn(void *p1, void *p2, void *p3)
|
||||
bool trigger_started = false;
|
||||
if (k_msgq_get(&audio_msgq, &file_path, K_FOREVER) == 0)
|
||||
{
|
||||
|
||||
abort_playback = false;
|
||||
|
||||
if (fs_open(&file, file_path, FS_O_READ) < 0)
|
||||
@@ -72,8 +71,19 @@ void audio_thread_fn(void *p1, void *p2, void *p3)
|
||||
while (!abort_playback)
|
||||
{
|
||||
void *mem_block;
|
||||
if (k_mem_slab_alloc(&audio_slab, &mem_block, K_MSEC(10)) < 0)
|
||||
continue;
|
||||
if (k_mem_slab_alloc(&audio_slab, &mem_block, K_MSEC(100)) < 0)
|
||||
{
|
||||
LOG_ERR("audio: slab timeout (I2S stall? DMA failure?) - skipping sound and resetting I2S...");
|
||||
i2s_trigger(i2s_dev, I2S_DIR_TX, I2S_TRIGGER_DROP);
|
||||
audio_init();
|
||||
break;
|
||||
}
|
||||
if (abort_playback)
|
||||
{
|
||||
LOG_DBG("thread: playback aborted while waiting for memory block.");
|
||||
k_mem_slab_free(&audio_slab, mem_block);
|
||||
break;
|
||||
}
|
||||
|
||||
int16_t *data_ptr = (int16_t *)mem_block;
|
||||
const uint32_t max_mono_samples = CONFIG_AUDIO_BLOCK_SIZE / 4;
|
||||
@@ -240,5 +250,6 @@ void audio_stop(void)
|
||||
{
|
||||
abort_playback = true;
|
||||
k_msgq_purge(&audio_msgq);
|
||||
i2s_trigger(i2s_dev, I2S_DIR_TX, I2S_TRIGGER_DROP);
|
||||
LOG_DBG("Playback stop requested, message queue purged");
|
||||
}
|
||||
Reference in New Issue
Block a user