Skip to content

Commit aec9f04

Browse files
author
Gang He
committed
samples: drivers: audio: Add codec loopback sample.
Add audio loop back sample Signed-off-by: Gang He <[email protected]>
1 parent a829211 commit aec9f04

File tree

5 files changed

+174
-0
lines changed

5 files changed

+174
-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: audio 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: audio codec
5+
common:
6+
filter: dt_nodelabel_enabled(audcodec)
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: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
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, 0x55, 0x2C, 0xFE,
21+
0x17, 0x01, 0x00, 0x02, 0xE8, 0xAC, 0xD3, 0x15, 0xC6, 0x4F, 0xC1, 0x15, 0xC6, 0xAC, 0xD3,
22+
0x03, 0xE8, 0x00, 0x00, 0xFD, 0x17, 0x54, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEC, 0x39, 0x54,
23+
0x2C, 0xFE, 0x17, 0x00, 0x00, 0x02, 0xE8, 0xAB, 0xD3, 0x15, 0xC6, 0x4F, 0xC1, 0x15, 0xC6,
24+
0xAC, 0xD3, 0x02, 0xE8, 0x00, 0x00, 0xFD, 0x17, 0x54, 0x2C, 0xEC, 0x39, 0xB1, 0x3E, 0xEB,
25+
0x39, 0x55, 0x2C, 0xFE, 0x17, 0xFF, 0xFF, 0x03, 0xE8, 0xAB, 0xD3, 0x14, 0xC6, 0x4F, 0xC1,
26+
0x14, 0xC6, 0xAB, 0xD3, 0x02, 0xE8, 0x00, 0x00, 0xFE, 0x17, 0x55, 0x2C, 0xEC, 0x39, 0xB1,
27+
0x3E, 0xEC, 0x39, 0x54, 0x2C, 0xFD, 0x17, 0x01, 0x00, 0x02, 0xE8, 0xAC, 0xD3, 0x15, 0xC6,
28+
0x4F, 0xC1, 0x15, 0xC6, 0xAB, 0xD3, 0x02, 0xE8, 0x00, 0x00, 0xFE, 0x17, 0x55, 0x2C, 0xEB,
29+
0x39, 0xB1, 0x3E, 0xEB, 0x39, 0x54, 0x2C, 0xFD, 0x17, 0x00, 0x00, 0x02, 0xE8, 0xAC, 0xD3,
30+
0x14, 0xC6, 0x50, 0xC1, 0x14, 0xC6, 0xAC, 0xD3, 0x02, 0xE8, 0x01, 0x00, 0xFE, 0x17, 0x54,
31+
0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEB, 0x39, 0x54, 0x2C, 0xFE, 0x17, 0x00, 0x00, 0x03, 0xE8,
32+
0xAC, 0xD3, 0x14, 0xC6, 0x4F, 0xC1, 0x14, 0xC6, 0xAC, 0xD3, 0x02, 0xE8, 0x00, 0x00, 0xFD,
33+
0x17, 0x55, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEB, 0x39, 0x54, 0x2C, 0xFD, 0x17, 0x00, 0x00,
34+
0x02, 0xE8, 0xAC, 0xD3, 0x14, 0xC6, 0x4F, 0xC1, 0x15, 0xC6, 0xAB, 0xD3, 0x02, 0xE8, 0x01,
35+
0x00, 0xFD, 0x17, 0x55, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEB, 0x39, 0x54, 0x2C, 0xFD, 0x17,
36+
0x00, 0x00, 0x02, 0xE8, 0xAB, 0xD3, 0x14, 0xC6, 0x50, 0xC1, 0x15, 0xC6, 0xAB, 0xD3, 0x02,
37+
0xE8, 0x00, 0x00, 0xFD, 0x17, 0x55, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEC, 0x39, 0x54, 0x2C,
38+
0xFE, 0x17, 0x00, 0x00, 0x02, 0xE8, 0xAB, 0xD3, 0x15, 0xC6, 0x4F, 0xC1, 0x14, 0xC6, 0xAC,
39+
0xD3, 0x03, 0xE8, 0x00, 0x00, 0xFD, 0x17, 0x54, 0x2C, 0xEC, 0x39, 0xB2, 0x3E, 0xEB, 0x39,
40+
0x54, 0x2C, 0xFE, 0x17, 0x00, 0x00, 0x02, 0xE8, 0xAB, 0xD3, 0x15, 0xC6, 0x4F, 0xC1, 0x14,
41+
0xC6, 0xAB, 0xD3, 0x03, 0xE8,
42+
};
43+
44+
static void tx_done(const struct device *dev, void *user_data)
45+
{
46+
if (!loopback) {
47+
audio_codec_write(dev, audio_data_p, AUDIO_BLOCK_SIZE);
48+
audio_data_p += AUDIO_BLOCK_SIZE;
49+
if ((audio_data_p - pcm_16k) >= sizeof(pcm_16k)) {
50+
audio_data_p = pcm_16k;
51+
}
52+
}
53+
}
54+
void rx_done(const struct device *dev, uint8_t *buf, uint32_t len, void *user_data)
55+
{
56+
if (loopback) {
57+
audio_codec_write(dev, buf, 320);
58+
}
59+
}
60+
61+
int main(void)
62+
{
63+
static const struct device *dev;
64+
struct audio_codec_cfg cfg = {
65+
.dai_type = AUDIO_DAI_TYPE_PCM,
66+
.dai_cfg.pcm.dir = AUDIO_DAI_DIR_TX,
67+
.dai_cfg.pcm.pcm_width = AUDIO_PCM_WIDTH_16_BITS,
68+
.dai_cfg.pcm.channels = 1,
69+
.dai_cfg.pcm.block_size = AUDIO_BLOCK_SIZE,
70+
.dai_cfg.pcm.samplerate = AUDIO_PCM_RATE_16K,
71+
};
72+
73+
#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(audcodec))
74+
dev = DEVICE_DT_GET(DT_NODELABEL(audcodec));
75+
#else
76+
printk("No audio codec on this board. Skipping audio test.\n");
77+
return 0;
78+
#endif
79+
if (!device_is_ready(dev)) {
80+
printk("codec device is not ready\n");
81+
return -EBUSY;
82+
}
83+
printk("codec device is ready\n");
84+
k_sleep(K_MSEC(1000));
85+
printk("codec playback and capture example on %s\n", CONFIG_BOARD_TARGET);
86+
while (1) {
87+
audio_property_value_t val;
88+
89+
loopback = false;
90+
audio_data_p = pcm_16k;
91+
audio_codec_configure(dev, &cfg);
92+
audio_codec_register_done_callback(dev, tx_done, NULL, rx_done, NULL);
93+
printk("codec tansfer start\n");
94+
audio_codec_start(dev, AUDIO_DAI_DIR_TX);
95+
val.vol = SPEAKER_VOL;
96+
audio_codec_set_property(dev, AUDIO_PROPERTY_OUTPUT_VOLUME, 0, val);
97+
printk("codec tansfer started\n");
98+
k_sleep(K_MSEC(15000));
99+
audio_codec_stop(dev, AUDIO_DAI_DIR_TX);
100+
printk("codec tansfer stopped\n");
101+
102+
printk("codec loopback\n");
103+
loopback = true;
104+
audio_data_p = pcm_16k;
105+
cfg.dai_cfg.pcm.dir = AUDIO_DAI_DIR_TXRX;
106+
audio_codec_configure(dev, &cfg);
107+
audio_codec_start(dev, AUDIO_DAI_DIR_TXRX);
108+
audio_codec_set_property(dev, AUDIO_PROPERTY_OUTPUT_VOLUME, 0, val);
109+
k_sleep(K_MSEC(15000));
110+
audio_codec_stop(dev, AUDIO_DAI_DIR_TXRX);
111+
printk("example completed\n");
112+
}
113+
114+
return 0;
115+
}

0 commit comments

Comments
 (0)