Improved audio lib and test app
All checks were successful
Deploy Docs / build-and-deploy (push) Successful in 12s

This commit is contained in:
2026-02-16 11:38:19 +01:00
parent 8305adf917
commit 0c3a8bfa39
6 changed files with 101 additions and 12 deletions

View File

@@ -21,7 +21,7 @@ if AUDIO
help
Set the audio sample rate in Hz. Common values are 8000, 16000, 44100, and 48000 Hz. Default is 16000 Hz.
config AUDIO_BIT_WIDTH
config AUDIO_WORD_WIDTH
int "Audio Bit Depth"
default 16
range 8 32
@@ -51,7 +51,7 @@ if AUDIO
config AUDIO_STACK_SIZE
int "Audio Thread Stack Size (bytes)"
default 2048
default 1200
range 256 8192
help
Set the stack size for the audio processing thread in bytes. Default is 2048 bytes.

View File

@@ -1,3 +1,21 @@
/**
* @file audio.h
* @brief Public API for the audio subsystem.
* This header defines the public interface for the audio subsystem, which
* provides functionality to play audio files and manage audio playback. It
* abstracts away the details of the underlying I2S peripheral and file
* system, allowing other parts of the application to easily trigger audio
* playback by specifying file paths or sound names.
*
* FLASH MEMORY USAGE:
* LOG LEVEL DEBUG: ~1.8 KB
* LOG LEVEL INFO: ~1.7 KB
* LOG LEVEL WARNING: ~1.2 KB
* LOG LEVEL ERROR: ~1.1 KB
*
* RAM USAGE (without stack and audio buffers):
* Any LOG LEVEL: ~0.47 KB
*/
#ifndef AUDIO_H
#define AUDIO_H

View File

@@ -7,6 +7,10 @@
LOG_MODULE_REGISTER(audio, CONFIG_AUDIO_LOG_LEVEL);
#define SAMPLES_PER_BLOCK (CONFIG_AUDIO_BLOCK_SIZE / (CONFIG_AUDIO_WORD_WIDTH / 8) / 2) // Divide by 2 for stereo
#define BLOCK_DURATION_MS ((SAMPLES_PER_BLOCK * 1000U) / CONFIG_AUDIO_SAMPLE_RATE) // Duration of audio in each block in milliseconds
#define MAX_WAIT_TIME_MS (3 * BLOCK_DURATION_MS) // Maximum time to wait for the I2S peripheral to request the next block before we consider it stalled and reset it
/* Get the I2S device from the devicetree */
#define I2S_NODE DT_NODELABEL(i2s0)
static const struct device *i2s_dev = DEVICE_DT_GET(I2S_NODE);
@@ -71,7 +75,7 @@ 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(100)) < 0)
if (k_mem_slab_alloc(&audio_slab, &mem_block, K_MSEC(MAX_WAIT_TIME_MS)) < 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);
@@ -185,7 +189,7 @@ int audio_init(void)
/* Initial configuration of the I2S peripheral */
struct i2s_config config = {
.word_size = CONFIG_AUDIO_BIT_WIDTH,
.word_size = CONFIG_AUDIO_WORD_WIDTH,
.channels = 2,
.format = I2S_FMT_DATA_FORMAT_I2S,
.options = I2S_OPT_BIT_CLK_MASTER | I2S_OPT_FRAME_CLK_MASTER,
@@ -202,7 +206,7 @@ int audio_init(void)
return ret;
}
LOG_DBG("I2S driver initialized and configured for %d Hz", CONFIG_AUDIO_SAMPLE_RATE);
LOG_DBG("Audio subsystem initialized successfully");
return 0;
}
@@ -217,7 +221,7 @@ int audio_play_file(const char *file)
size_t len = strnlen(file, CONFIG_AUDIO_MAX_PATH_LEN);
if (len >= CONFIG_AUDIO_MAX_PATH_LEN)
{
LOG_ERR("audio_play_file: file path too long");
LOG_ERR("audio_play_file: file path too long: %s", file);
return -ENAMETOOLONG;
}
@@ -236,6 +240,18 @@ int audio_play_file(const char *file)
int audio_play_sound(const char *file)
{
if (file == NULL)
{
LOG_ERR("audio_play_sound: file name is NULL");
return -EINVAL;
}
size_t len = strnlen(file, CONFIG_AUDIO_MAX_PATH_LEN) + strlen(CONFIG_FS_MGMT_MOUNT_POINT) + strlen(CONFIG_AUDIO_SAMPLE_FOLDER) + 2;
if (len >= CONFIG_AUDIO_MAX_PATH_LEN)
{
LOG_ERR("audio_play_sound: file path too long: %s/%s/%s", CONFIG_FS_MGMT_MOUNT_POINT, CONFIG_AUDIO_SAMPLE_FOLDER, file);
return -ENAMETOOLONG;
}
char path[CONFIG_AUDIO_MAX_PATH_LEN];
snprintf(path, sizeof(path), "%s/%s/%s",

View File

@@ -44,4 +44,33 @@ int lasertag_init_watchdog(void);
* @brief Feed the watchdog timer to prevent a system reset.
*/
void lasertag_feed_watchdog(void);
#endif /* LASERTAG_UTILS_H */
#endif /* LASERTAG_UTILS_H */
/**
* ANSI Defines for bold text formatting in logs.
*/
#define ANSI_RESET "\x1b[0m"
#define ANSI_BOLD "\x1b[1m"
#define ANSI_BRIGHT "\x1b[97m"
#define ANSI_GREEN "\x1b[32m"
#define ANSI_YELLOW "\x1b[33m"
#define ANSI_RED "\x1b[31m"
#define ANSI_BLUE "\x1b[34m"
#define FORMAT_BOLD(s) ANSI_BOLD s ANSI_RESET
#define FORMAT_BRIGHT(s) ANSI_BRIGHT s ANSI_RESET
#define FORMAT_BRIGHT_BOLD(s) ANSI_BRIGHT ANSI_BOLD s ANSI_RESET
#define FORMAT_GREEN(s) ANSI_GREEN s ANSI_RESET
#define FORMAT_GREEN_BOLD(s) ANSI_GREEN ANSI_BOLD s ANSI_RESET
#define FORMAT_YELLOW(s) ANSI_YELLOW s ANSI_RESET
#define FORMAT_YELLOW_BOLD(s) ANSI_YELLOW ANSI_BOLD s ANSI_RESET
#define FORMAT_RED(s) ANSI_RED s ANSI_RESET
#define FORMAT_RED_BOLD(s) ANSI_RED ANSI_BOLD s ANSI_RESET
#define FORMAT_BLUE(s) ANSI_BLUE s ANSI_RESET
#define FORMAT_BLUE_BOLD(s) ANSI_BLUE ANSI_BOLD s ANSI_RESET