Skip to content

Commit 0112374

Browse files
Gang Heljq-ctrl
authored andcommitted
samples: drivers: audio: Add codec loopback sample.
Add audio loop back sample Signed-off-by: ljq-ctrl <[email protected]>
1 parent 7ddd08e commit 0112374

File tree

5 files changed

+182
-0
lines changed

5 files changed

+182
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
5+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
6+
project(codec)
7+
8+
target_sources(app PRIVATE src/main.c)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
.. zephyr:code-sample:: codec
2+
:name: codec
3+
4+
mic to speaker loopback.
5+
6+
Overview
7+
********
8+
9+
A simple sample that to demo audio speaker play, and mic to speaker loopback functions.
10+
11+
Building and Running
12+
********************
13+
14+
This application can be built and executed on QEMU as follows:
15+
16+
.. zephyr-app-commands::
17+
:zephyr-app: samples/drivers/audio/codec
18+
:host-os: unix
19+
:board: sf32lb52_devkit_lcd
20+
:goals: run
21+
:compact:
22+
23+
To build for another board, change "sf32lb52_devkit_lcd" above to that board's name.
24+
25+
Sample Output
26+
=============
27+
28+
.. code-block:: console
29+
30+
mic to speaker loopback.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CONFIG_AUDIO=y
2+
CONFIG_LOG=y
3+
CONFIG_AUDIO_CODEC=y
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
sample:
2+
description: onchip audio codec example
3+
application
4+
name: codec
5+
common:
6+
filter: dt_nodelabel_enabled(aucodec)
7+
min_ram: 2
8+
min_flash: 16
9+
tags: audio
10+
integration_platforms:
11+
- sf32lb52_devkit_lcd
12+
harness: console
13+
harness_config:
14+
type: one_line
15+
regex:
16+
- "mic to speaker loopback"
17+
tests:
18+
sample.drivers.audio.codec:{}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Copyright 2025 SiFli Technologies(Nanjing) Co., Ltd
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdio.h>
8+
#include <zephyr/device.h>
9+
#include <zephyr/kernel.h>
10+
#include <zephyr/devicetree.h>
11+
#include <zephyr/audio/codec.h>
12+
13+
#define AUDIO_BLOCK_SIZE 320
14+
#define SPEAKER_VOL 15
15+
16+
static bool loopback;
17+
static uint8_t *audio_data_p;
18+
19+
static uint8_t __aligned(4) pcm_16k[] = {
20+
0x01, 0x00, 0xFE, 0x17, 0x55, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEC, 0x39,
21+
0x55, 0x2C, 0xFE, 0x17, 0x01, 0x00, 0x02, 0xE8, 0xAC, 0xD3, 0x15, 0xC6,
22+
0x4F, 0xC1, 0x15, 0xC6, 0xAC, 0xD3, 0x03, 0xE8, 0x00, 0x00, 0xFD, 0x17,
23+
0x54, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEC, 0x39, 0x54, 0x2C, 0xFE, 0x17,
24+
0x00, 0x00, 0x02, 0xE8, 0xAB, 0xD3, 0x15, 0xC6, 0x4F, 0xC1, 0x15, 0xC6,
25+
0xAC, 0xD3, 0x02, 0xE8, 0x00, 0x00, 0xFD, 0x17, 0x54, 0x2C, 0xEC, 0x39,
26+
0xB1, 0x3E, 0xEB, 0x39, 0x55, 0x2C, 0xFE, 0x17, 0xFF, 0xFF, 0x03, 0xE8,
27+
0xAB, 0xD3, 0x14, 0xC6, 0x4F, 0xC1, 0x14, 0xC6, 0xAB, 0xD3, 0x02, 0xE8,
28+
0x00, 0x00, 0xFE, 0x17, 0x55, 0x2C, 0xEC, 0x39, 0xB1, 0x3E, 0xEC, 0x39,
29+
0x54, 0x2C, 0xFD, 0x17, 0x01, 0x00, 0x02, 0xE8, 0xAC, 0xD3, 0x15, 0xC6,
30+
0x4F, 0xC1, 0x15, 0xC6, 0xAB, 0xD3, 0x02, 0xE8, 0x00, 0x00, 0xFE, 0x17,
31+
0x55, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEB, 0x39, 0x54, 0x2C, 0xFD, 0x17,
32+
0x00, 0x00, 0x02, 0xE8, 0xAC, 0xD3, 0x14, 0xC6, 0x50, 0xC1, 0x14, 0xC6,
33+
0xAC, 0xD3, 0x02, 0xE8, 0x01, 0x00, 0xFE, 0x17, 0x54, 0x2C, 0xEB, 0x39,
34+
0xB1, 0x3E, 0xEB, 0x39, 0x54, 0x2C, 0xFE, 0x17, 0x00, 0x00, 0x03, 0xE8,
35+
0xAC, 0xD3, 0x14, 0xC6, 0x4F, 0xC1, 0x14, 0xC6, 0xAC, 0xD3, 0x02, 0xE8,
36+
0x00, 0x00, 0xFD, 0x17, 0x55, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEB, 0x39,
37+
0x54, 0x2C, 0xFD, 0x17, 0x00, 0x00, 0x02, 0xE8, 0xAC, 0xD3, 0x14, 0xC6,
38+
0x4F, 0xC1, 0x15, 0xC6, 0xAB, 0xD3, 0x02, 0xE8, 0x01, 0x00, 0xFD, 0x17,
39+
0x55, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEB, 0x39, 0x54, 0x2C, 0xFD, 0x17,
40+
0x00, 0x00, 0x02, 0xE8, 0xAB, 0xD3, 0x14, 0xC6, 0x50, 0xC1, 0x15, 0xC6,
41+
0xAB, 0xD3, 0x02, 0xE8, 0x00, 0x00, 0xFD, 0x17, 0x55, 0x2C, 0xEB, 0x39,
42+
0xB1, 0x3E, 0xEC, 0x39, 0x54, 0x2C, 0xFE, 0x17, 0x00, 0x00, 0x02, 0xE8,
43+
0xAB, 0xD3, 0x15, 0xC6, 0x4F, 0xC1, 0x14, 0xC6, 0xAC, 0xD3, 0x03, 0xE8,
44+
0x00, 0x00, 0xFD, 0x17, 0x54, 0x2C, 0xEC, 0x39, 0xB2, 0x3E, 0xEB, 0x39,
45+
0x54, 0x2C, 0xFE, 0x17, 0x00, 0x00, 0x02, 0xE8, 0xAB, 0xD3, 0x15, 0xC6,
46+
0x4F, 0xC1, 0x14, 0xC6, 0xAB, 0xD3, 0x03, 0xE8,
47+
};
48+
49+
static void tx_done(const struct device *dev, void *user_data)
50+
{
51+
if (!loopback) {
52+
audio_codec_write(dev, audio_data_p, AUDIO_BLOCK_SIZE);
53+
audio_data_p += AUDIO_BLOCK_SIZE;
54+
if ((audio_data_p - pcm_16k) >= sizeof(pcm_16k)) {
55+
audio_data_p = pcm_16k;
56+
}
57+
}
58+
}
59+
void rx_done(const struct device *dev, uint8_t *buf, uint32_t len, void *user_data)
60+
{
61+
if (loopback) {
62+
audio_codec_write(dev, buf, 320);
63+
}
64+
}
65+
66+
int main(void)
67+
{
68+
static const struct device *dev;
69+
struct audio_codec_cfg cfg = {
70+
.dai_type = AUDIO_DAI_TYPE_PCM,
71+
.dai_cfg.pcm.dir = AUDIO_DAI_DIR_TX,
72+
.dai_cfg.pcm.pcm_width = AUDIO_PCM_WIDTH_16_BITS,
73+
.dai_cfg.pcm.channels = 1,
74+
.dai_cfg.pcm.block_size = AUDIO_BLOCK_SIZE,
75+
.dai_cfg.pcm.samplerate = AUDIO_PCM_RATE_16K,
76+
};
77+
78+
#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(audcodec))
79+
dev = DEVICE_DT_GET(DT_NODELABEL(audcodec));
80+
#else
81+
printk("No audio codec on this board. Skipping audio test.\n");
82+
return 0;
83+
#endif
84+
85+
printk("codec playback and capture example on %s\n", CONFIG_BOARD_TARGET);
86+
k_sleep(K_MSEC(1000));
87+
if (!device_is_ready(dev)) {
88+
printk("codec device is not ready\n");
89+
return -EBUSY;
90+
}
91+
printk("codec device is ready\n");
92+
while (1) {
93+
audio_property_value_t val;
94+
95+
loopback = false;
96+
audio_data_p = pcm_16k;
97+
audio_codec_configure(dev, &cfg);
98+
audio_codec_register_done_callback(dev, tx_done, NULL, rx_done, NULL);
99+
printk("codec tansfer start\n");
100+
audio_codec_start(dev, AUDIO_DAI_DIR_TX);
101+
val.vol = SPEAKER_VOL;
102+
audio_codec_set_property(dev, AUDIO_PROPERTY_OUTPUT_VOLUME, 0, val);
103+
printk("codec tansfer started\n");
104+
k_sleep(K_MSEC(15000));
105+
audio_codec_stop(dev, AUDIO_DAI_DIR_TX);
106+
printk("codec tansfer stopped\n");
107+
108+
printk("codec loopback\n");
109+
loopback = true;
110+
audio_data_p = pcm_16k;
111+
cfg.dai_cfg.pcm.dir = AUDIO_DAI_DIR_TXRX;
112+
audio_codec_configure(dev, &cfg);
113+
audio_codec_start(dev, AUDIO_DAI_DIR_TXRX);
114+
audio_codec_set_property(dev, AUDIO_PROPERTY_OUTPUT_VOLUME, 0, val);
115+
k_sleep(K_MSEC(15000));
116+
audio_codec_stop(dev, AUDIO_DAI_DIR_TXRX);
117+
printk("example completed\n");
118+
}
119+
120+
return 0;
121+
122+
}
123+

0 commit comments

Comments
 (0)