提交 2f5c0ede 编写于 作者: xychen's avatar xychen 提交者: 叶康

apps: audio_service: Split AudioTrack and AudioRecord API sample

Signed-off-by: xychen's avatarxychen <xychen@listenai.com>
上级 c7ab6d35
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.20.0)
set(SDK_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../..)
set(BOARD_ROOT ${SDK_ROOT_PATH})
set(SNIPPET_ROOT ${SDK_ROOT_PATH}/boards)
list(APPEND ZEPHYR_EXTRA_MODULES ${SDK_ROOT_PATH}/components)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(record_play)
target_sources(app PRIVATE
src/main.c
)
target_link_libraries(app PRIVATE af)
add_subdirectory(resources)
/*
* Copyright (c) 2023 Anhui Listenai Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*/
/delete-node/ &storage_partition;
/delete-node/ &psram_ap;
/delete-node/ &psram_cp;
/delete-node/ &psram_share;
/delete-node/ &wifi_driver_storage;
/delete-node/ &wifi_nvs_storage;
/ {
chosen {
zephyr,code-partition = &ap_code_partition;
resource,cp = &cp_code_partition;
};
zephyr,user {
pa-enable-gpios = <&exgpiod 0 GPIO_ACTIVE_HIGH>;
};
};
&flash0 {
reg = <0x18000000 DT_SIZE_M(16)>;
write-block-size = <4>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
ap_code_partition: partition@0 {
label = "ap_code";
reg = <0x0 DT_SIZE_M(2)>;
};
cp_code_partition: partition@200000 {
label = "cp_code";
reg = <0x200000 DT_SIZE_M(1)>;
};
};
};
&psram0 {
compatible = "listenai,csk6-psram";
reg = <0x30000000 DT_SIZE_M(8)>;
#address-cells = <0x1>;
#size-cells = <0x1>;
psram_cp: psram_cp@30000000 {
compatible = "listenai,csk6-psram-partition";
reg = <0x30000000 0x510000>;
status = "okay";
};
psram_ap: psram_ap@30510000 {
compatible = "zephyr,memory-region",
"listenai,csk6-psram-partition";
reg = <0x30510000 0x2f0000>;
status = "okay";
zephyr,memory-region = "PSRAMAP";
};
};
......@@ -2,6 +2,7 @@
# SPDX-License-Identifier: Apache-2.0
CONFIG_LOG=y
CONFIG_LOG_MODE_IMMEDIATE=y
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
......
# Copyright (c) 2023 Anhui Listenai Co., Ltd.
# SPDX-License-Identifier: Apache-2.0
if(CONFIG_APLICATION_PACK_IMAGES)
set(gen_dir ${ZEPHYR_BINARY_DIR}/include/generated)
set(res_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../../resources)
generate_inc_file_for_target(
app
${res_dir}/venus_cp.bin
${gen_dir}/venus_cp.inc
)
zephyr_linker_sources(SECTIONS images.ld)
target_sources(app PRIVATE images.c)
endif() # CONFIG_APLICATION_PACK_IMAGES
# SPDX-License-Identifier: Apache-2.0
DT_CHOSEN_RES_CP := resource,cp
config FLASH_RES_CP_ADDR
def_hex $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_RES_CP))
config FLASH_RES_CP_SIZE
def_int $(dt_chosen_reg_size_int,$(DT_CHOSEN_RES_CP))
/*
* Copyright (c) 2023 Anhui Listenai Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*/
#include <listenai/app-res.h>
APP_RES_DECLARE(venus_cp) = {
#include "venus_cp.inc"
};
/*
* Copyright (c) 2023 Anhui Listenai Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*/
#include <listenai/linker/app-res.h>
APP_RES_SECTION(venus_cp, CONFIG_FLASH_RES_CP_ADDR)
sample:
name: AudioRecord Record & Play sample
tests:
apps.audio_service.audio_record.record_play:
build_only: true
platform_allow:
- csk6_duomotai_devkit
......@@ -10,8 +10,6 @@
#include <zephyr/input/input.h>
#include <zephyr/drivers/gpio.h>
#include <listenai/app-res.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG);
......@@ -26,9 +24,6 @@ LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG);
#define FLASH_CP_IMAGE_REGION_OFFSET DT_REG_ADDR(DT_NODE_BY_FIXED_PARTITION_LABEL(cp_code))
#define CP_BOOT_ADDRESS (CP_FLASH_BASE_ADDRESS + FLASH_CP_IMAGE_REGION_OFFSET)
#define DEMO_AUDIO_ADDR (CONFIG_FLASH_BASE_ADDRESS + APP_RES_DT_ADDR(demo_audio))
#define DEMO_AUDIO_SIZE (APP_RES_DT_SIZE(demo_audio))
static const struct gpio_dt_spec pa_enable =
GPIO_DT_SPEC_GET(DT_PATH(zephyr_user), pa_enable_gpios);
......@@ -37,12 +32,9 @@ static uint16_t last_key = 0;
static AudioTrack track;
static AudioRecord record;
static volatile bool busy = false;
Z_GENERIC_DOT_SECTION(psram_section)
static uint8_t record_buf[sizeof(int16_t) * 16000 * 5 * 1];
K_SEM_DEFINE(sem_play, 0, 1);
K_SEM_DEFINE(sem_record, 0, 1);
static void input_work_cb(struct k_work *work)
......@@ -51,18 +43,12 @@ static void input_work_cb(struct k_work *work)
switch (last_key) {
case INPUT_KEY_1:
LOG_DBG("Play start!");
k_sem_give(&sem_play);
LOG_DBG("Record start!");
k_sem_give(&sem_record);
break;
case INPUT_KEY_2:
LOG_DBG("Play stop!");
AudioTrack_stop(&track);
break;
case INPUT_KEY_3:
LOG_DBG("Record start!");
if (!busy) {
k_sem_give(&sem_record);
}
LOG_DBG("Record stop!");
AudioRecord_stop(&record);
break;
}
}
......@@ -79,45 +65,43 @@ static void input_cb(struct input_event *evt)
INPUT_LISTENER_CB_DEFINE(NULL, input_cb);
static void play_thread(void *p1, void *p2, void *p3)
int main(void)
{
uint32_t start_time, end_time;
ssize_t wrote;
ssize_t read;
int ret;
while (1) {
k_sem_take(&sem_play, K_FOREVER);
boot_cp((const void *)CP_BOOT_ADDRESS);
AudioTrack_start(&track);
gpio_pin_set_dt(&pa_enable, 1);
gpio_pin_configure_dt(&pa_enable, GPIO_OUTPUT_INACTIVE);
start_time = k_uptime_get_32();
wrote = AudioTrack_write(&track, (void *)DEMO_AUDIO_ADDR, DEMO_AUDIO_SIZE);
end_time = k_uptime_get_32();
lsf_init();
lsf_connect();
LOG_DBG("Wrote %d of %d bytes in %d ms", wrote, DEMO_AUDIO_SIZE,
end_time - start_time);
AudioSystem_initialize();
gpio_pin_set_dt(&pa_enable, 0);
AudioTrack_stop(&track);
String8 param;
String8_ctor_char(&param, "ADC_PDM_GAIN_A_LEFT=6;"
"ADC_PDM_GAIN_D_LEFT=20");
ret = AudioSystem_setParameters(0, &param);
String8_dtor(&param);
LOG_DBG("Play finished");
ret = AudioTrack_ctor(&track, 16000, PCM_16_BIT, CHANNEL_OUT_MONO, 0, NULL);
if (ret < 0) {
LOG_ERR("Failed to create AudioTrack: %d", ret);
return ret;
}
}
#define PLAY_THREAD_STACK_SIZE KB(8)
#define PLAY_THREAD_PRIORITY (5)
K_THREAD_DEFINE(play_thread_id, PLAY_THREAD_STACK_SIZE, play_thread, NULL, NULL, NULL,
PLAY_THREAD_PRIORITY, 0, 0);
ret = AudioRecord_ctor(&record, 0, 16000, PCM_16_BIT, CHANNEL_IN_MONO, 160, NULL);
if (ret < 0) {
LOG_ERR("Failed to create AudioRecord: %d", ret);
return ret;
}
static void record_thread(void *p1, void *p2, void *p3)
{
uint32_t start_time, end_time;
ssize_t read;
LOG_DBG("K1=RECORD, K2=STOP");
while (1) {
k_sem_take(&sem_record, K_FOREVER);
busy = true;
AudioRecord_start(&record);
......@@ -141,48 +125,7 @@ static void record_thread(void *p1, void *p2, void *p3)
AudioTrack_stop(&track);
LOG_DBG("Play finished");
busy = false;
}
}
#define RECORD_THREAD_STACK_SIZE KB(8)
#define RECORD_THREAD_PRIORITY (5)
K_THREAD_DEFINE(record_thread_id, RECORD_THREAD_STACK_SIZE, record_thread, NULL, NULL, NULL,
RECORD_THREAD_PRIORITY, 0, 0);
int main(void)
{
int ret;
boot_cp((const void *)CP_BOOT_ADDRESS);
gpio_pin_configure_dt(&pa_enable, GPIO_OUTPUT_INACTIVE);
lsf_init();
lsf_connect();
AudioSystem_initialize();
String8 param;
String8_ctor_char(&param, "ADC_PDM_GAIN_A_LEFT=6;"
"ADC_PDM_GAIN_D_LEFT=20");
ret = AudioSystem_setParameters(0, &param);
String8_dtor(&param);
ret = AudioTrack_ctor(&track, 16000, PCM_16_BIT, CHANNEL_OUT_MONO, 0, NULL);
if (ret < 0) {
LOG_ERR("Failed to create AudioTrack: %d", ret);
return ret;
}
ret = AudioRecord_ctor(&record, 0, 16000, PCM_16_BIT, CHANNEL_IN_MONO, 160, NULL);
if (ret < 0) {
LOG_ERR("Failed to create AudioRecord: %d", ret);
return ret;
}
LOG_DBG("K1=PLAY, K2=STOP, K3=RECORD");
return 0;
}
# SPDX-License-Identifier: Apache-2.0
#
# Note: The list of ForEachMacros can be obtained using:
#
# git grep -h '^#define [^[:space:]]*FOR_EACH[^[:space:]]*(' include/ \
# | sed "s,^#define \([^[:space:]]*FOR_EACH[^[:space:]]*\)(.*$, - '\1'," \
# | sort | uniq
#
# References:
# - https://clang.llvm.org/docs/ClangFormatStyleOptions.html
---
BasedOnStyle: LLVM
AlignConsecutiveMacros: AcrossComments
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AttributeMacros:
- __aligned
- __deprecated
- __packed
- __printf_like
- __syscall
- __syscall_always_inline
- __subsystem
BitFieldColonSpacing: After
BreakBeforeBraces: Linux
ColumnLimit: 100
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
ForEachMacros:
- 'FOR_EACH'
- 'FOR_EACH_FIXED_ARG'
- 'FOR_EACH_IDX'
- 'FOR_EACH_IDX_FIXED_ARG'
- 'FOR_EACH_NONEMPTY_TERM'
- 'RB_FOR_EACH'
- 'RB_FOR_EACH_CONTAINER'
- 'SYS_DLIST_FOR_EACH_CONTAINER'
- 'SYS_DLIST_FOR_EACH_CONTAINER_SAFE'
- 'SYS_DLIST_FOR_EACH_NODE'
- 'SYS_DLIST_FOR_EACH_NODE_SAFE'
- 'SYS_SFLIST_FOR_EACH_CONTAINER'
- 'SYS_SFLIST_FOR_EACH_CONTAINER_SAFE'
- 'SYS_SFLIST_FOR_EACH_NODE'
- 'SYS_SFLIST_FOR_EACH_NODE_SAFE'
- 'SYS_SLIST_FOR_EACH_CONTAINER'
- 'SYS_SLIST_FOR_EACH_CONTAINER_SAFE'
- 'SYS_SLIST_FOR_EACH_NODE'
- 'SYS_SLIST_FOR_EACH_NODE_SAFE'
- '_WAIT_Q_FOR_EACH'
- 'Z_FOR_EACH'
- 'Z_FOR_EACH_ENGINE'
- 'Z_FOR_EACH_EXEC'
- 'Z_FOR_EACH_FIXED_ARG'
- 'Z_FOR_EACH_FIXED_ARG_EXEC'
- 'Z_FOR_EACH_IDX'
- 'Z_FOR_EACH_IDX_EXEC'
- 'Z_FOR_EACH_IDX_FIXED_ARG'
- 'Z_FOR_EACH_IDX_FIXED_ARG_EXEC'
- 'Z_GENLIST_FOR_EACH_CONTAINER'
- 'Z_GENLIST_FOR_EACH_CONTAINER_SAFE'
- 'Z_GENLIST_FOR_EACH_NODE'
- 'Z_GENLIST_FOR_EACH_NODE_SAFE'
- 'STRUCT_SECTION_FOREACH'
- 'TYPE_SECTION_FOREACH'
IfMacros:
- 'CHECKIF'
# Disabled for now, see bug https://github.com/zephyrproject-rtos/zephyr/issues/48520
#IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^".*\.h"$'
Priority: 0
- Regex: '^<(assert|complex|ctype|errno|fenv|float|inttypes|limits|locale|math|setjmp|signal|stdarg|stdbool|stddef|stdint|stdio|stdlib|string|tgmath|time|wchar|wctype)\.h>$'
Priority: 1
- Regex: '^\<zephyr/.*\.h\>$'
Priority: 2
- Regex: '.*'
Priority: 3
IndentCaseLabels: false
IndentWidth: 8
InsertBraces: true
SpaceBeforeParens: ControlStatementsExceptControlMacros
SortIncludes: Never
UseTab: ForContinuationAndIndentation
WhitespaceSensitiveMacros:
- STRINGIFY
- Z_STRINGIFY
# EditorConfig: https://editorconfig.org/
# top-most EditorConfig file
root = true
# All (Defaults)
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
max_line_length = 100
# Assembly
[*.S]
indent_style = tab
indent_size = 8
# C
[*.{c,h}]
indent_style = tab
indent_size = 8
# C++
[*.{cpp,hpp}]
indent_style = tab
indent_size = 8
# Linker Script
[*.ld]
indent_style = tab
indent_size = 8
# Python
[*.py]
indent_style = space
indent_size = 4
# Perl
[*.pl]
indent_style = tab
indent_size = 8
# reStructuredText
[*.rst]
indent_style = space
indent_size = 3
# YAML
[*.{yml,yaml}]
indent_style = space
indent_size = 2
# Shell Script
[*.sh]
indent_style = space
indent_size = 4
# Windows Command Script
[*.cmd]
end_of_line = crlf
indent_style = tab
indent_size = 8
# Valgrind Suppression File
[*.supp]
indent_style = space
indent_size = 3
# CMake
[{CMakeLists.txt,*.cmake}]
indent_style = space
indent_size = 2
# Makefile
[Makefile]
indent_style = tab
indent_size = 8
# Device tree
[*.{dts,dtsi,overlay}]
indent_style = tab
indent_size = 8
# Git commit messages
[COMMIT_EDITMSG]
max_line_length = 75
# Kconfig
[Kconfig*]
indent_style = tab
indent_size = 8
......@@ -2,14 +2,14 @@
cmake_minimum_required(VERSION 3.20.0)
set(SDK_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..)
set(SDK_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../..)
set(BOARD_ROOT ${SDK_ROOT_PATH})
set(SNIPPET_ROOT ${SDK_ROOT_PATH}/boards)
list(APPEND ZEPHYR_EXTRA_MODULES ${SDK_ROOT_PATH}/components)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(hsd)
project(basic_api)
target_sources(app PRIVATE
src/main.c
......
# Copyright (c) 2023 Anhui Listenai Co., Ltd.
# SPDX-License-Identifier: Apache-2.0
rsource "resources/Kconfig"
source "Kconfig.zephyr"
# Copyright (c) 2023 Anhui Listenai Co., Ltd.
# SPDX-License-Identifier: Apache-2.0
CONFIG_LOG=y
CONFIG_LOG_MODE_IMMEDIATE=y
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
CONFIG_NEWLIB_LIBC_FLOAT_SCANF=y
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
CONFIG_HEAP_MEM_POOL_SIZE=81920
CONFIG_CSK_HEAP=y
CONFIG_CSK_HEAP_MEM_POOL_SIZE=307200
CONFIG_INPUT=y
CONFIG_INPUT_FT5336=n
CONFIG_GPIO=y
CONFIG_GPIO_CSK6_CH32V003=y
CONFIG_ADC=y
CONFIG_ADC_CSK6_CH32V003=y
CONFIG_DISK_MEMORY=n
CONFIG_LSF=y
CONFIG_LSF_CLIENT=y
CONFIG_LSF_OS_ZEPHYR=y
CONFIG_LSF_IC_MESSAGE_EP_ID=5
......@@ -3,16 +3,17 @@
if(CONFIG_APLICATION_PACK_IMAGES)
set(gen_dir ${ZEPHYR_BINARY_DIR}/include/generated)
set(res_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../../resources)
generate_inc_file_for_target(
app
${CMAKE_CURRENT_SOURCE_DIR}/images/venus_cp.bin
${res_dir}/venus_cp.bin
${gen_dir}/venus_cp.inc
)
generate_inc_file_for_target(
app
${CMAKE_CURRENT_SOURCE_DIR}/images/demo_audio/16k16b1ch10s.pcm
${res_dir}/demo_audio/16k16b1ch10s.pcm
${gen_dir}/demo_audio.inc
)
......
# Copyright (c) 2023 Anhui Listenai Co., Ltd.
# SPDX-License-Identifier: Apache-2.0
config APLICATION_PACK_IMAGES
bool "Package all algorithm resources, CP firmware and AP firmware into one image file"
default y
rsource "Kconfig.images"
sample:
name: audio_service
name: AudioTrack Basic API sample
tests:
apps.audio_service:
apps.audio_service.audio_track.basic_api:
build_only: true
platform_allow:
- csk6_duomotai_devkit
/*
* Copyright (c) 2023 Anhui Listenai Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/devicetree.h>
#include <zephyr/toolchain.h>
#include <zephyr/storage/flash_map.h>
#include <zephyr/input/input.h>
#include <zephyr/drivers/gpio.h>
#include <listenai/app-res.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG);
#include "boot_cp.h"
#include "lsf.h"
#include "AudioSystem.h"
#include "AudioTrack.h"
#define CP_FLASH_BASE_ADDRESS (0x68000000)
#define FLASH_CP_IMAGE_REGION_OFFSET DT_REG_ADDR(DT_NODE_BY_FIXED_PARTITION_LABEL(cp_code))
#define CP_BOOT_ADDRESS (CP_FLASH_BASE_ADDRESS + FLASH_CP_IMAGE_REGION_OFFSET)
#define DEMO_AUDIO_ADDR (CONFIG_FLASH_BASE_ADDRESS + APP_RES_DT_ADDR(demo_audio))
#define DEMO_AUDIO_SIZE (APP_RES_DT_SIZE(demo_audio))
static const struct gpio_dt_spec pa_enable =
GPIO_DT_SPEC_GET(DT_PATH(zephyr_user), pa_enable_gpios);
static uint16_t last_key = 0;
static AudioTrack track;
K_SEM_DEFINE(sem_play, 0, 1);
static void input_work_cb(struct k_work *work)
{
ARG_UNUSED(work);
switch (last_key) {
case INPUT_KEY_1:
LOG_DBG("Play start!");
k_sem_give(&sem_play);
break;
case INPUT_KEY_2:
LOG_DBG("Play stop!");
AudioTrack_stop(&track);
break;
}
}
K_WORK_DEFINE(input_work, input_work_cb);
static void input_cb(struct input_event *evt)
{
if (evt->type == INPUT_EV_KEY && evt->value) {
last_key = evt->code;
k_work_submit(&input_work);
}
}
INPUT_LISTENER_CB_DEFINE(NULL, input_cb);
int main(void)
{
uint32_t start_time, end_time;
ssize_t wrote;
int ret;
boot_cp((const void *)CP_BOOT_ADDRESS);
gpio_pin_configure_dt(&pa_enable, GPIO_OUTPUT_INACTIVE);
lsf_init();
lsf_connect();
AudioSystem_initialize();
ret = AudioTrack_ctor(&track, 16000, PCM_16_BIT, CHANNEL_OUT_MONO, 0, NULL);
if (ret < 0) {
LOG_ERR("Failed to create AudioTrack: %d", ret);
return ret;
}
LOG_DBG("K1=PLAY, K2=STOP");
while (1) {
k_sem_take(&sem_play, K_FOREVER);
AudioTrack_start(&track);
gpio_pin_set_dt(&pa_enable, 1);
start_time = k_uptime_get_32();
wrote = AudioTrack_write(&track, (void *)DEMO_AUDIO_ADDR, DEMO_AUDIO_SIZE);
end_time = k_uptime_get_32();
LOG_DBG("Wrote %d of %d bytes in %d ms", wrote, DEMO_AUDIO_SIZE,
end_time - start_time);
gpio_pin_set_dt(&pa_enable, 0);
AudioTrack_stop(&track);
LOG_DBG("Play finished");
}
return 0;
}
支持 Markdown
0% or
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册