diff --git a/applications/nrf5340_audio/prj.conf b/applications/nrf5340_audio/prj.conf index 91d8461da51b..29ddc120d554 100644 --- a/applications/nrf5340_audio/prj.conf +++ b/applications/nrf5340_audio/prj.conf @@ -59,6 +59,5 @@ CONFIG_DEVICE_SHELL=n # assume card is in slot. Thus error message is always shown if card is not inserted CONFIG_SD_LOG_LEVEL_OFF=y CONFIG_LC3_DEC_CHAN_MAX=2 - CONFIG_MAIN_STACK_SIZE=1800 CONFIG_LC3_PLAYBACK=y diff --git a/applications/nrf5340_audio/src/audio/audio_datapath.c b/applications/nrf5340_audio/src/audio/audio_datapath.c index 253d100ca02e..b70d3d8423cb 100644 --- a/applications/nrf5340_audio/src/audio/audio_datapath.c +++ b/applications/nrf5340_audio/src/audio/audio_datapath.c @@ -556,7 +556,6 @@ static void alt_buffer_free_both(void) * the in.fifo message queue. */ -uint8_t sound_mix_buf[BLK_MONO_SIZE_OCTETS]; static void audio_datapath_i2s_blk_complete(uint32_t frame_start_ts, uint32_t *rx_buf_released, uint32_t const *tx_buf_released) { @@ -853,7 +852,7 @@ void audio_datapath_stream_out(const uint8_t *buf, size_t size, uint32_t sdu_ref int ret; size_t pcm_size; - ret = sw_codec_decode(buf, size, bad_frame, &ctrl_blk.decoded_data, &pcm_size, true); + ret = sw_codec_decode(buf, size, bad_frame, &ctrl_blk.decoded_data, &pcm_size); if (ret) { LOG_WRN("SW codec decode error: %d", ret); diff --git a/applications/nrf5340_audio/src/audio/audio_system.c b/applications/nrf5340_audio/src/audio/audio_system.c index b06d32349cdf..a757a5cdc920 100644 --- a/applications/nrf5340_audio/src/audio/audio_system.c +++ b/applications/nrf5340_audio/src/audio/audio_system.c @@ -22,7 +22,6 @@ #include "audio_usb.h" #include "streamctrl.h" #include "pcm_mix.h" -#include #include LOG_MODULE_REGISTER(audio_system, CONFIG_AUDIO_SYSTEM_LOG_LEVEL); @@ -242,7 +241,7 @@ int audio_decode(void const *const encoded_data, size_t encoded_data_size, bool } ret = sw_codec_decode(encoded_data, encoded_data_size, bad_frame, &pcm_raw_data, - &pcm_block_size, true); + &pcm_block_size); if (ret) { LOG_ERR("Failed to decode"); return ret; diff --git a/applications/nrf5340_audio/src/audio/sw_codec_select.c b/applications/nrf5340_audio/src/audio/sw_codec_select.c index 1eeef9bfd8ac..fc366125dfc5 100644 --- a/applications/nrf5340_audio/src/audio/sw_codec_select.c +++ b/applications/nrf5340_audio/src/audio/sw_codec_select.c @@ -107,7 +107,7 @@ int sw_codec_encode(void *pcm_data, size_t pcm_size, uint8_t **encoded_data, siz } int sw_codec_decode(uint8_t const *const encoded_data, size_t encoded_size, bool bad_frame, - void **decoded_data, size_t *decoded_size, bool lc3_playback_is_active) + void **decoded_data, size_t *decoded_size) { if (!m_config.decoder.enabled) { LOG_ERR("Decoder has not been initialized"); @@ -126,8 +126,8 @@ int sw_codec_decode(uint8_t const *const encoded_data, size_t encoded_size, bool #if (CONFIG_SW_CODEC_LC3) /* Typically used for right channel if stereo signal */ char pcm_data_mono_right[PCM_NUM_BYTES_MONO] = {0}; - - if (m_config.decoder.num_ch == SW_CODEC_MONO) { + /* NB! For now, playing stereo files from SD card is unsupported */ + if (IS_ENABLED(CONFIG_LC3_PLAYBACK)) { if (bad_frame && IS_ENABLED(CONFIG_SW_CODEC_OVERRIDE_PLC)) { memset(pcm_data_mono, 0, PCM_NUM_BYTES_MONO); pcm_size_session = PCM_NUM_BYTES_MONO; @@ -150,64 +150,76 @@ int sw_codec_decode(uint8_t const *const encoded_data, size_t encoded_size, bool if (ret) { return ret; } - } else if (m_config.decoder.num_ch == SW_CODEC_STEREO && !lc3_playback_is_active) { - if (bad_frame && IS_ENABLED(CONFIG_SW_CODEC_OVERRIDE_PLC)) { - memset(pcm_data_mono, 0, PCM_NUM_BYTES_MONO); - memset(pcm_data_mono_right, 0, PCM_NUM_BYTES_MONO); - pcm_size_session = PCM_NUM_BYTES_MONO; - } else { - /* Decode left channel */ - ret = sw_codec_lc3_dec_run( - encoded_data, encoded_size / 2, LC3_PCM_NUM_BYTES_MONO, - AUDIO_CH_L, pcm_data_mono, (uint16_t *)&pcm_size_session, - bad_frame); - if (ret) { - return ret; + } else { + switch (m_config.decoder.num_ch) { + case SW_CODEC_MONO: { + if (bad_frame && IS_ENABLED(CONFIG_SW_CODEC_OVERRIDE_PLC)) { + memset(pcm_data_mono, 0, PCM_NUM_BYTES_MONO); + pcm_size_session = PCM_NUM_BYTES_MONO; + } else { + ret = sw_codec_lc3_dec_run( + encoded_data, encoded_size, LC3_PCM_NUM_BYTES_MONO, + 0, pcm_data_mono, (uint16_t *)&pcm_size_session, + bad_frame); + if (ret) { + return ret; + } } - /* Decode right channel */ - ret = sw_codec_lc3_dec_run( - (encoded_data + (encoded_size / 2)), encoded_size / 2, - LC3_PCM_NUM_BYTES_MONO, AUDIO_CH_R, pcm_data_mono_right, - (uint16_t *)&pcm_size_session, bad_frame); + + /* For now, i2s is only stereo, so in order to send + * just one channel, we need to insert 0 for the + * other channel + */ + ret = pscm_zero_pad(pcm_data_mono, pcm_size_session, + m_config.decoder.audio_ch, + CONFIG_AUDIO_BIT_DEPTH_BITS, pcm_data_stereo, + &pcm_size_stereo); if (ret) { return ret; } + break; } - ret = pscm_combine(pcm_data_mono, pcm_data_mono_right, pcm_size_session, - CONFIG_AUDIO_BIT_DEPTH_BITS, pcm_data_stereo, - &pcm_size_stereo); - if (ret) { - return ret; - } - } else if (m_config.decoder.num_ch == SW_CODEC_STEREO && lc3_playback_is_active) { - if (bad_frame && IS_ENABLED(CONFIG_SW_CODEC_OVERRIDE_PLC)) { - memset(pcm_data_mono, 0, PCM_NUM_BYTES_MONO); - pcm_size_session = PCM_NUM_BYTES_MONO; - } else { - ret = sw_codec_lc3_dec_run( - encoded_data, encoded_size, LC3_PCM_NUM_BYTES_MONO, 0, - pcm_data_mono, (uint16_t *)&pcm_size_session, bad_frame); + case SW_CODEC_STEREO: { + if (bad_frame && IS_ENABLED(CONFIG_SW_CODEC_OVERRIDE_PLC)) { + memset(pcm_data_mono, 0, PCM_NUM_BYTES_MONO); + memset(pcm_data_mono_right, 0, PCM_NUM_BYTES_MONO); + pcm_size_session = PCM_NUM_BYTES_MONO; + } else { + /* Decode left channel */ + ret = sw_codec_lc3_dec_run( + encoded_data, encoded_size / 2, + LC3_PCM_NUM_BYTES_MONO, AUDIO_CH_L, pcm_data_mono, + (uint16_t *)&pcm_size_session, bad_frame); + if (ret) { + return ret; + } + /* Decode right channel */ + ret = sw_codec_lc3_dec_run( + (encoded_data + (encoded_size / 2)), + encoded_size / 2, LC3_PCM_NUM_BYTES_MONO, + AUDIO_CH_R, pcm_data_mono_right, + (uint16_t *)&pcm_size_session, bad_frame); + if (ret) { + return ret; + } + } + ret = pscm_combine(pcm_data_mono, pcm_data_mono_right, + pcm_size_session, CONFIG_AUDIO_BIT_DEPTH_BITS, + pcm_data_stereo, &pcm_size_stereo); if (ret) { return ret; } + break; } - - /* For now, i2s is only stereo, so in order to send - * just one channel, we need to insert 0 for the - * other channel - */ - ret = pscm_zero_pad(pcm_data_mono, pcm_size_session, - m_config.decoder.audio_ch, CONFIG_AUDIO_BIT_DEPTH_BITS, - pcm_data_stereo, &pcm_size_stereo); - if (ret) { - return ret; + default: + LOG_ERR("Unsupported number of channels: %d", + m_config.encoder.num_ch); + return -ENODEV; } - } else { - LOG_ERR("Unsupported number of channels: %d", m_config.encoder.num_ch); - return -ENODEV; } *decoded_size = pcm_size_stereo; *decoded_data = pcm_data_stereo; + #endif /* (CONFIG_SW_CODEC_LC3) */ break; } diff --git a/applications/nrf5340_audio/src/audio/sw_codec_select.h b/applications/nrf5340_audio/src/audio/sw_codec_select.h index e76fc8f923a2..908fc441f6eb 100644 --- a/applications/nrf5340_audio/src/audio/sw_codec_select.h +++ b/applications/nrf5340_audio/src/audio/sw_codec_select.h @@ -95,7 +95,7 @@ int sw_codec_encode(void *pcm_data, size_t pcm_size, uint8_t **encoded_data, siz * @return 0 if success, error codes depends on sw_codec selected */ int sw_codec_decode(uint8_t const *const encoded_data, size_t encoded_size, bool bad_frame, - void **decoded_data, size_t *decoded_size, bool lc3_playback_is_active); + void **decoded_data, size_t *decoded_size); /**@brief Uninitialize sw_codec and free allocated space * diff --git a/applications/nrf5340_audio/src/modules/Kconfig b/applications/nrf5340_audio/src/modules/Kconfig index 5816ed1c6c17..066a1a82f4e4 100644 --- a/applications/nrf5340_audio/src/modules/Kconfig +++ b/applications/nrf5340_audio/src/modules/Kconfig @@ -84,6 +84,10 @@ module = MODULE_SD_CARD module-str = module-sd-card source "subsys/logging/Kconfig.template.log_config" +module = MODULE_LC3_PLAYBACK +module-str = module-lc3-playback +source "subsys/logging/Kconfig.template.log_config" + endmenu # Log levels #----------------------------------------------------------------------------# diff --git a/applications/nrf5340_audio/src/modules/lc3_playback.c b/applications/nrf5340_audio/src/modules/lc3_playback.c index a8a35acaa9f7..3850b3c2b369 100644 --- a/applications/nrf5340_audio/src/modules/lc3_playback.c +++ b/applications/nrf5340_audio/src/modules/lc3_playback.c @@ -11,40 +11,35 @@ #include "sw_codec_lc3.h" #include -LOG_MODULE_REGISTER(lc3_playback, 4); /* For draft PR feedback: going to change this line */ +LOG_MODULE_REGISTER(lc3_playback, CONFIG_MODULE_LC3_PLAYBACK_LOG_LEVEL); -#define RING_BUF_SIZE 960 /* This can be modified */ -#define lc3_playback_STACK_SIZE 4096 +#define RING_BUF_SIZE_1920_BYTES 1920 +#define LC3_PLAYBACK_STACK_SIZE 4096 /*File structure of the LC3 encoded files*/ -struct lc3BinaryHdr_t { - uint16_t fileId; /* Constant value, 0xCC1C */ - uint16_t hdrSize; /* Header size, 0x0012 */ - uint16_t sampleRate_divided100; /* Sample frequency / 100 */ - uint16_t bitRate_divided100; /* Bit rate / 100 (total for all channels) */ - uint16_t channels; /* Number of channels */ - uint16_t frameMs_times100; /* Frame duration in ms * 100 */ - uint16_t rfu; /* RFU value */ - uint16_t signalLen; /* Number of samples in signal, 16 LSB */ - uint16_t signalLenRed; /* Number of samples in signal, 16 MSB (>> 16) */ +struct lc3_binary_hdr_t { + uint16_t file_id; /* Constant value, 0xCC1C */ + uint16_t hdr_size; /* Header size, 0x0012 */ + uint16_t sample_rate; /* Sample frequency / 100 */ + uint16_t bit_rate; /* Bit rate / 100 (total for all channels) */ + uint16_t channels; /* Number of channels */ + uint16_t frame_ms; /* Frame duration in ms * 100 */ + uint16_t rfu; /* RFU value */ + uint16_t signal_len_lsb; /* Number of samples in signal, 16 LSB */ + uint16_t signal_len_msb; /* Number of samples in signal, 16 MSB (>> 16) */ }; -static struct lc3BinaryHdr_t header; -static size_t header_size = sizeof(header); -static uint16_t lc3_frame_length; -static uint16_t lc3_frames_num; -static uint16_t pcm_mono_frame_size; -static bool lc3_playback_active; - -RING_BUF_DECLARE(m_ringbuf_sound_data_lc3, RING_BUF_SIZE); +RING_BUF_DECLARE(m_ringbuf_sound_data_lc3, RING_BUF_SIZE_1920_BYTES); K_SEM_DEFINE(m_sem_load_from_buf_lc3, 1, 1); K_MUTEX_DEFINE(mtx_ringbuf); +K_THREAD_STACK_DEFINE(lc3_playback_thread_stack, LC3_PLAYBACK_STACK_SIZE); +static struct lc3_binary_hdr_t lc3_file_header; +static uint16_t pcm_frame_size; +static bool lc3_playback_active; static struct k_thread lc3_playback_thread_data; static k_tid_t lc3_playback_thread_id; -K_THREAD_STACK_DEFINE(lc3_playback_thread_stack, lc3_playback_STACK_SIZE); - bool lc3_playback_is_active(void) { return lc3_playback_active; @@ -52,12 +47,10 @@ bool lc3_playback_is_active(void) int lc3_playback_buffer_set(uint8_t *buf, size_t size) { - uint16_t size_gotten; - k_mutex_lock(&mtx_ringbuf, K_FOREVER); - size_gotten = ring_buf_get(&m_ringbuf_sound_data_lc3, buf, size); + ring_buf_get(&m_ringbuf_sound_data_lc3, buf, size); k_mutex_unlock(&mtx_ringbuf); - if (ring_buf_space_get(&m_ringbuf_sound_data_lc3) >= pcm_mono_frame_size) { + if (ring_buf_space_get(&m_ringbuf_sound_data_lc3) >= pcm_frame_size) { k_sem_give(&m_sem_load_from_buf_lc3); } return 0; @@ -66,20 +59,19 @@ int lc3_playback_buffer_set(uint8_t *buf, size_t size) int lc3_playback_mix_with_stream(void *const pcm_a, size_t pcm_a_size) { int ret; - uint8_t pcm_b[pcm_mono_frame_size]; + uint8_t pcm_b[pcm_frame_size]; - ret = lc3_playback_buffer_set(pcm_b, pcm_mono_frame_size); + ret = lc3_playback_buffer_set(pcm_b, pcm_frame_size); if (ret < 0) { LOG_ERR("Error when loading pcm data into buffer. Ret: %d", ret); return ret; } - pcm_mix(pcm_a, pcm_a_size, pcm_b, pcm_mono_frame_size, B_MONO_INTO_A_STEREO_L); + pcm_mix(pcm_a, pcm_a_size, pcm_b, pcm_frame_size, B_MONO_INTO_A_STEREO_L); return 0; } static int lc3_playback_buffer_to_ringbuffer(uint8_t *buffer, size_t numbytes) { - /* Burde kanskje ha en sjekk her for å sjekke at numbytes gir mening */ static uint8_t *buf_ptr; k_mutex_lock(&mtx_ringbuf, K_FOREVER); @@ -95,49 +87,33 @@ static int lc3_playback_buffer_to_ringbuffer(uint8_t *buffer, size_t numbytes) static int lc3_playback_header_read(const char *filename, const char *path_to_file) { - LOG_DBG("In header read"); int ret; - size_t lc3_frame_length_size = sizeof(lc3_frame_length); - uint32_t num_samples; + size_t lc3_file_header_size = sizeof(lc3_file_header); - ret = sd_card_segment_open(filename, path_to_file); + ret = sd_card_open(filename, path_to_file); if (ret < 0) { LOG_ERR("Error when trying to open file on SD card. Return value: %d", ret); return ret; } /* Read the header */ - ret = sd_card_segment_read((char *)&header, &header_size); + ret = sd_card_read((char *)&lc3_file_header, &lc3_file_header_size); if (ret < 0) { LOG_ERR("Error when trying to peek at file segment on SD card. Return value: %d", ret); return ret; } - pcm_mono_frame_size = 2 * header.sampleRate_divided100 * header.frameMs_times100 / 1000; - num_samples = (header.signalLenRed << 16) + header.signalLen; - lc3_frames_num = 2 * num_samples / pcm_mono_frame_size; - - /* Read the frame length */ - ret = sd_card_segment_peek((char *)&lc3_frame_length, &lc3_frame_length_size); - if (ret < 0) { - LOG_ERR("Error when trying to peek at file segment on SD card. Return value: %d", - ret); - return ret; - } - - ret = sd_card_segment_close(); - if (ret < 0) { - LOG_ERR("Error when trying to close file on SD card. Return value: %d", ret); - return ret; - } - return 0; } static int lc3_playback_play(const char *filename, const char *path_to_file) { int ret; + uint16_t lc3_frames_num; + uint16_t lc3_frame_length; + size_t lc3_frame_length_size = 2; + uint16_t pcm_mono_write_size; ret = lc3_playback_header_read(filename, path_to_file); if (ret < 0) { @@ -145,57 +121,83 @@ static int lc3_playback_play(const char *filename, const char *path_to_file) return ret; } - uint16_t pcm_mono_frame[pcm_mono_frame_size / 2]; - uint16_t pcm_mono_write_size; - uint16_t lc3_frame[lc3_frame_length]; - size_t lc3_fr_len = lc3_frame_length; /* Converting to size_t */ - size_t lc3_fr_len_size = sizeof(lc3_frame_length); - - /* First, open file on SD card */ - ret = sd_card_segment_open(filename, path_to_file); - if (ret < 0) { - LOG_ERR("Error when trying to open file on SD card. Return value: %d", ret); - return ret; - } + pcm_frame_size = 2 * lc3_file_header.sample_rate * lc3_file_header.frame_ms / 1000; + uint8_t pcm_mono_frame[pcm_frame_size]; + lc3_frames_num = 2 * + ((lc3_file_header.signal_len_msb << 16) + lc3_file_header.signal_len_lsb) / + pcm_frame_size; - /* Then, skip the header */ - ret = sd_card_segment_skip(&header_size); - if (ret < 0) { - LOG_ERR("Error when trying to open file on SD card. Return value: %d", ret); - return ret; - } lc3_playback_active = true; for (uint32_t i = 0; i < lc3_frames_num; i++) { - /* Skip the frame length info to get to the audio data */ - ret = sd_card_segment_skip(&lc3_fr_len_size); + ret = sd_card_read((char *)&lc3_frame_length, &lc3_frame_length_size); if (ret < 0) { LOG_ERR("Error when trying to skip file on SD card. Return value: %d", ret); return ret; } - + uint8_t lc3_frame[lc3_frame_length]; + size_t lc3_fr_len = lc3_frame_length; /* Read the audio data frame to be encoded */ - ret = sd_card_segment_read((char *)lc3_frame, &lc3_fr_len); + ret = sd_card_read((char *)lc3_frame, &lc3_fr_len); if (ret < 0) { LOG_ERR("Something went wrong when reading from SD card. Return value: %d", ret); return ret; } - /* Decode audio data frame*/ - - ret = sw_codec_lc3_dec_run((char *)lc3_frame, lc3_frame_length, pcm_mono_frame_size, - 1, pcm_mono_frame, &pcm_mono_write_size, false); + ret = sw_codec_lc3_dec_run((char *)lc3_frame, lc3_frame_length, pcm_frame_size, 1, + pcm_mono_frame, &pcm_mono_write_size, false); if (ret < 0) { LOG_ERR("Error when running decoder. Return value: %d\n", ret); return ret; } - /* Wait until there is enough space in the ringbuffer */ k_sem_take(&m_sem_load_from_buf_lc3, K_FOREVER); lc3_playback_buffer_to_ringbuffer((char *)pcm_mono_frame, pcm_mono_write_size); } - ret = sd_card_segment_close(); + ret = sd_card_close(); + if (ret < 0) { + LOG_ERR("Error when closing file. Return value: %d", ret); + return ret; + } + lc3_playback_active = false; + return 0; +} + +static int lc3_playback_play_wav(const char *filename, const char *path_to_file, + uint32_t frame_duration_ms, uint8_t bit_depth, + enum Sample_rates sample_rate, enum Audio_channels audio_ch) +{ + int ret; + + size_t pcm_wav_mono_frame_size = frame_duration_ms * sample_rate * bit_depth / 8; + pcm_frame_size = pcm_wav_mono_frame_size; + uint8_t pcm_wav_mono_frame[pcm_wav_mono_frame_size]; + ret = sd_card_open(filename, path_to_file); + if (ret < 0) { + LOG_ERR("Error when trying to open file on SD card. Return value: %d", ret); + return ret; + } + + lc3_playback_active = true; + while (lc3_playback_active) { + + ret = sd_card_read(pcm_wav_mono_frame, &pcm_wav_mono_frame_size); + if (ret < 0) { + LOG_ERR("Error when trying to read file on SD card. Return value: %d", ret); + return ret; + } + if (pcm_wav_mono_frame_size < pcm_frame_size) { + lc3_playback_active = false; + } + /* Wait until there is enough space in the ringbuffer */ + if (lc3_playback_active) { + k_sem_take(&m_sem_load_from_buf_lc3, K_FOREVER); + lc3_playback_buffer_to_ringbuffer(pcm_wav_mono_frame, + pcm_wav_mono_frame_size); + } + } + ret = sd_card_close(); if (ret < 0) { LOG_ERR("Error when closing file. Return value: %d", ret); return ret; @@ -209,7 +211,7 @@ static void lc3_playback_thread(void *arg1, void *arg2, void *arg3) while (!sw_codec_is_initialized()) { k_msleep(100); } - lc3_playback_play("enc_21.bin", ""); + lc3_playback_play_wav("whitney_48k_mono.wav", "", 10, 16, SAMPLE_RATE_48K, AUDIO_CH_MONO); } int lc3_playback_init(void) @@ -218,8 +220,8 @@ int lc3_playback_init(void) lc3_playback_thread_id = k_thread_create(&lc3_playback_thread_data, lc3_playback_thread_stack, - lc3_playback_STACK_SIZE, (k_thread_entry_t)lc3_playback_thread, - NULL, NULL, NULL, K_PRIO_PREEMPT(5), 0, K_NO_WAIT); + LC3_PLAYBACK_STACK_SIZE, (k_thread_entry_t)lc3_playback_thread, + NULL, NULL, NULL, K_PRIO_PREEMPT(4), 0, K_NO_WAIT); ret = k_thread_name_set(lc3_playback_thread_id, "lc3_playback"); if (ret < 0) { LOG_ERR("Failed"); diff --git a/applications/nrf5340_audio/src/modules/lc3_playback.h b/applications/nrf5340_audio/src/modules/lc3_playback.h index be0d4b534251..cf4eba3fa2f2 100644 --- a/applications/nrf5340_audio/src/modules/lc3_playback.h +++ b/applications/nrf5340_audio/src/modules/lc3_playback.h @@ -9,8 +9,18 @@ #include +enum Audio_channels { + AUDIO_CH_NONE, + AUDIO_CH_MONO, + AUDIO_CH_STEREO +}; + +enum Sample_rates { + SAMPLE_RATE_48K = 48 +}; + /**@brief Figure out whether or not the lc3_playback module is active - * @retval true, if active. false, otherwise + * @retval true, if active. false, if not active */ bool lc3_playback_is_active(void); diff --git a/applications/nrf5340_audio/src/modules/sd_card.c b/applications/nrf5340_audio/src/modules/sd_card.c index 690269505a63..cd785a60cdb2 100644 --- a/applications/nrf5340_audio/src/modules/sd_card.c +++ b/applications/nrf5340_audio/src/modules/sd_card.c @@ -24,7 +24,7 @@ LOG_MODULE_REGISTER(sd_card, CONFIG_MODULE_SD_CARD_LOG_LEVEL); static const char *sd_root_path = "/SD:"; static FATFS fat_fs; static bool sd_init_success; -static volatile bool seg_read_started; +static bool seg_read_started; static struct fs_file_t f_seg_read_entry; static struct fs_mount_t mnt_pt = { @@ -32,12 +32,17 @@ static struct fs_mount_t mnt_pt = { .fs_data = &fat_fs, }; -int sd_card_list_files(char *path, char *buf, size_t buf_size) +int sd_card_list_files(const char *path, char *buf, size_t *buf_size) { int ret; struct fs_dir_t dirp; static struct fs_dirent entry; char abs_path_name[PATH_MAX_LEN + 1] = SD_ROOT_PATH; + size_t used_buf_size = 0; + + if (seg_read_started) { + return -EPERM; + } if (!sd_init_success) { return -ENODEV; @@ -65,7 +70,6 @@ int sd_card_list_files(char *path, char *buf, size_t buf_size) } } - size_t used_buf_size = 0; while (true) { ret = fs_readdir(&dirp, &entry); if (ret) { @@ -76,7 +80,7 @@ int sd_card_list_files(char *path, char *buf, size_t buf_size) break; } if (buf != NULL) { - size_t remaining_buf_size = buf_size - used_buf_size; + size_t remaining_buf_size = *buf_size - used_buf_size; ssize_t len = snprintk( &buf[used_buf_size], remaining_buf_size, "[%s]\t%s\n", entry.type == FS_DIR_ENTRY_DIR ? "DIR " : "FILE", entry.name); @@ -96,10 +100,11 @@ int sd_card_list_files(char *path, char *buf, size_t buf_size) return ret; } + *buf_size = used_buf_size; return 0; } -int sd_card_write(char const *const filename, char const *const data, size_t *size) +int sd_card_open_write_close(char const *const filename, char const *const data, size_t *size) { int ret; struct fs_file_t f_entry; @@ -147,7 +152,7 @@ int sd_card_write(char const *const filename, char const *const data, size_t *si return 0; } -int sd_card_read(char const *const filename, char *const data, size_t *size) +int sd_card_open_read_close(char const *const filename, char *const data, size_t *size) { int ret; struct fs_file_t f_entry; @@ -191,28 +196,29 @@ int sd_card_read(char const *const filename, char *const data, size_t *size) return 0; } -int sd_card_segment_open(char const *const filename, char const *const path_to_file) +int sd_card_open(char const *const filename, char const *const path_to_file) { int ret; char abs_path_name[PATH_MAX_LEN + 1] = SD_ROOT_PATH; + if (!sd_init_success) { + return -ENODEV; + } + if (seg_read_started) { LOG_ERR("Segment read has already started"); - /* Which value should I return here? */ - return -1; + return -EPERM; } - if (strlen(path_to_file) + strlen(abs_path_name) > PATH_MAX_LEN) { + if ((strlen(path_to_file) + strlen(abs_path_name)) > PATH_MAX_LEN) { LOG_ERR("Filepath is too long"); return -EINVAL; } - strcat(abs_path_name, path_to_file); - LOG_INF("abs path name:\t%s", abs_path_name); + size_t avilable_path_space = PATH_MAX_LEN - strlen(SD_ROOT_PATH); - if (!sd_init_success) { - return -ENODEV; - } + strncat(abs_path_name, path_to_file, avilable_path_space); + LOG_INF("abs path name:\t%s", abs_path_name); if (strlen(filename) > CONFIG_FS_FATFS_MAX_LFN) { LOG_ERR("Filename is too long"); @@ -233,75 +239,26 @@ int sd_card_segment_open(char const *const filename, char const *const path_to_f return 0; } -int sd_card_segment_read(char *const data, size_t *size) -{ - int ret; - - if (!seg_read_started) { - return -EBUSY; - } - - ret = fs_read(&f_seg_read_entry, data, *size); - if (ret < 0) { - LOG_ERR("Read file failed"); - return ret; - } - - *size = ret; - - return 0; -} - -int sd_card_segment_peek(char *const data, size_t *size) +int sd_card_read(char *const data, size_t *size) { int ret; - off_t offset; if (!seg_read_started) { return -EBUSY; } - offset = fs_tell(&f_seg_read_entry); - if (offset < 0) { - LOG_ERR("Fs tell failed"); - return offset; - } - ret = fs_read(&f_seg_read_entry, data, *size); if (ret < 0) { LOG_ERR("Read file failed"); return ret; } - ret = fs_seek(&f_seg_read_entry, offset, 0); - if (ret < 0) { - LOG_ERR("Fs seek failed"); - return ret; - } - *size = ret; return 0; } -int sd_card_segment_skip(const size_t *size) -{ - int ret; - - if (!seg_read_started) { - return -EBUSY; - } - - ret = fs_seek(&f_seg_read_entry, *size, FS_SEEK_CUR); - if (ret < 0) { - LOG_ERR("Fs seek failed. Return value: %d", ret); - return ret; - } - - return 0; -} - -int sd_card_segment_close(void) +int sd_card_close(void) { int ret; diff --git a/applications/nrf5340_audio/src/modules/sd_card.h b/applications/nrf5340_audio/src/modules/sd_card.h index 032824d2dcb2..1376f5be9a88 100644 --- a/applications/nrf5340_audio/src/modules/sd_card.h +++ b/applications/nrf5340_audio/src/modules/sd_card.h @@ -11,93 +11,79 @@ /**@brief Print out the contents under SD card root path and write the content to buffer. * - * @param path Path of the folder which going to list - * If assigned path is null, then listing the contents under root - * If assigned path doesn't exist, an error will be returned - * @param buf Buffer where data is written. If set to NULL, it will be ignored. - * @param buf_size Buffer size + * @param[in] path Path of the folder which going to list + * If assigned path is null, then listing the contents under root + * If assigned path doesn't exist, an error will be returned + * @param[out] buf Buffer where data is written. If set to NULL, it will be ignored. + * @param[in, out] buf_size Buffer size * @return 0 on success. + * -EPERM SD card read is ongoing somewhere else * -ENODEV SD init failed. SD card likely not inserted * -EINVAL Failed to append to buffer + * -FR_INVALID_NAME Path is too long * Otherwise, error from underlying drivers */ -int sd_card_list_files(char *path, char *buf, size_t buf_size); +int sd_card_list_files(const char *path, char *buf, size_t *buf_size); /**@brief Write data from buffer into the file * * @note If the file already exists, data will be appended to the end of the file. * - * @param filename Name of the target file for writing, the default location is the - * root directoy of SD card, accept absolute path under root of SD card - * @param data Data which going to be written into the file - * @param size Pointer to the number of bytes which is going to be written - * The actual written size will be returned - * + * @param[in] filename Name of the target file for writing, the default location is + *the root directoy of SD card, accept absolute path under root of SD card + * @param data[in] Data which going to be written into the file + * @param size[in, out] Pointer to the number of bytes which is going to be written + * The actual written size will be returned * @return 0 on success. * -ENODEV SD init failed. SD card likely not inserted * Otherwise, error from underlying drivers */ -int sd_card_write(char const *const filename, char const *const data, size_t *size); +int sd_card_open_write_close(char const *const filename, char const *const data, size_t *size); /**@brief Read data from file into the buffer * - * @param filename Name of the target file for reading, the default location is the - * root directoy of SD card, accept absolute path under root of SD card - * @param data The buffer which will be filled by read file contents - * @param size Pointer to the number of bytes which wait to be read from the file - * The actual read size will be returned - * If the actual read size is 0, there will be a warning message which - * indicates the file is empty + * @param[in] filename Name of the target file for reading, the default location is + *the root directoy of SD card, accept absolute path under root of SD card + * @param data[out] The buffer which will be filled by read file contents + * @param size[in, out] Pointer to the number of bytes which wait to be read from the file + * The actual read size will be returned + * If the actual read size is 0, there will be a warning message + *which indicates the file is empty * @return 0 on success. * -ENODEV SD init failed. SD card likely not inserted * Otherwise, error from underlying drivers */ -int sd_card_read(char const *const filename, char *const data, size_t *size); +int sd_card_open_read_close(char const *const filename, char *const data, size_t *size); /**@brief Open file on SD card - * param filename Name of file to open - * param path_to_file Path to file + * param[in] filename Name of file to open + * param[in] path_to_file Path to file * @retval 0 on success * -ENODEV SD init failed. SD likely not inserted + * -EPERM SD card read is ongoing somewhere else + * Otherwise, error from underlying drivers */ -int sd_card_segment_open(char const *const filename, char const *const path_to_file); +int sd_card_open(char const *const filename, char const *const path_to_file); /**@brief Read segment on the open file on the SD card - * param data Where the read data is stored - * @param size Number of bytes to be read from file - * The actual read size will be returned - * If the actual read size is 0, there will be a warning message which - * indicates that the file is empty + * param data[out] Where the read data is stored + * @param size[in, out] Number of bytes to be read from file + * The actual read size will be returned + * If the actual read size is 0, there will be a warning message + *which indicates that the file is empty * @retval 0 on success * -ENODEV SD init failed. SD likely not inserted * Otherwise, error from underlying drivers */ -int sd_card_segment_read(char *const data, size_t *size); +int sd_card_read(char *const data, size_t *size); /**@brief Close the file opened by the sd_card_segment_read_open function * @retval 0 on success * -EBUSY Segment read operation has not started * Otherwise, error from underlying drivers */ -int sd_card_segment_close(void); - -/**@brief Peek at data ahead of current file position without changing file position - * param data Location to where the read data should be stored - * param size Size of data to be read - * @retval 0 on success - * -EBUSY Segment read operation has not started - * Otherwise, error from underlying drivers - */ -int sd_card_segment_peek(char *const data, size_t *size); - -/**@brief Skip segment from current file position - * param size Size of segment to skip - * @retval 0 on success - * -EBUSY Segment read operation has not started - * Otherwise, error from underlying drivers - */ -int sd_card_segment_skip(const size_t *size); +int sd_card_close(void); /**@brief Initialize the SD card interface and print out SD card details. * diff --git a/applications/nrf5340_audio/tools/buildprog/nrf5340_audio_dk_devices.json b/applications/nrf5340_audio/tools/buildprog/nrf5340_audio_dk_devices.json index 0acda4753625..0a42fe365d5b 100644 --- a/applications/nrf5340_audio/tools/buildprog/nrf5340_audio_dk_devices.json +++ b/applications/nrf5340_audio/tools/buildprog/nrf5340_audio_dk_devices.json @@ -1,11 +1,11 @@ [ { - "nrf5340_audio_dk_snr": 1050183438, + "nrf5340_audio_dk_snr": 1000, "nrf5340_audio_dk_dev": "headset", "channel": "left" }, { - "nrf5340_audio_dk_snr": 1050139103, + "nrf5340_audio_dk_snr": 1000, "nrf5340_audio_dk_dev": "gateway", "channel": "NA" },