Skip to content

Commit fe05329

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 9f00766 commit fe05329

File tree

5 files changed

+175
-0
lines changed

5 files changed

+175
-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: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
sample:
2+
description: onchip audio codec example
3+
application
4+
name: audio codec sample
5+
tests:
6+
sample.drivers.audio.codec:
7+
filter: dt_nodelabel_enabled("audcodec")
8+
tags: codec
9+
integration_platforms:
10+
- sf32lb52_devkit_lcd
11+
harness: console
12+
harness_config:
13+
type: multi_line
14+
ordered: true
15+
regex:
16+
- "Audio codec sample"
17+
- "Exiting"
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
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+
#include <zephyr/logging/log.h>
13+
LOG_MODULE_REGISTER(codec_sample);
14+
15+
#define AUDIO_BLOCK_SIZE 320
16+
#define SPEAKER_VOL 15
17+
18+
static bool loopback;
19+
static uint8_t *audio_data_p;
20+
21+
static uint8_t __aligned(4) pcm_16k[] = {
22+
0x01, 0x00, 0xFE, 0x17, 0x55, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEC, 0x39, 0x55, 0x2C, 0xFE,
23+
0x17, 0x01, 0x00, 0x02, 0xE8, 0xAC, 0xD3, 0x15, 0xC6, 0x4F, 0xC1, 0x15, 0xC6, 0xAC, 0xD3,
24+
0x03, 0xE8, 0x00, 0x00, 0xFD, 0x17, 0x54, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEC, 0x39, 0x54,
25+
0x2C, 0xFE, 0x17, 0x00, 0x00, 0x02, 0xE8, 0xAB, 0xD3, 0x15, 0xC6, 0x4F, 0xC1, 0x15, 0xC6,
26+
0xAC, 0xD3, 0x02, 0xE8, 0x00, 0x00, 0xFD, 0x17, 0x54, 0x2C, 0xEC, 0x39, 0xB1, 0x3E, 0xEB,
27+
0x39, 0x55, 0x2C, 0xFE, 0x17, 0xFF, 0xFF, 0x03, 0xE8, 0xAB, 0xD3, 0x14, 0xC6, 0x4F, 0xC1,
28+
0x14, 0xC6, 0xAB, 0xD3, 0x02, 0xE8, 0x00, 0x00, 0xFE, 0x17, 0x55, 0x2C, 0xEC, 0x39, 0xB1,
29+
0x3E, 0xEC, 0x39, 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, 0x55, 0x2C, 0xEB,
31+
0x39, 0xB1, 0x3E, 0xEB, 0x39, 0x54, 0x2C, 0xFD, 0x17, 0x00, 0x00, 0x02, 0xE8, 0xAC, 0xD3,
32+
0x14, 0xC6, 0x50, 0xC1, 0x14, 0xC6, 0xAC, 0xD3, 0x02, 0xE8, 0x01, 0x00, 0xFE, 0x17, 0x54,
33+
0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEB, 0x39, 0x54, 0x2C, 0xFE, 0x17, 0x00, 0x00, 0x03, 0xE8,
34+
0xAC, 0xD3, 0x14, 0xC6, 0x4F, 0xC1, 0x14, 0xC6, 0xAC, 0xD3, 0x02, 0xE8, 0x00, 0x00, 0xFD,
35+
0x17, 0x55, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEB, 0x39, 0x54, 0x2C, 0xFD, 0x17, 0x00, 0x00,
36+
0x02, 0xE8, 0xAC, 0xD3, 0x14, 0xC6, 0x4F, 0xC1, 0x15, 0xC6, 0xAB, 0xD3, 0x02, 0xE8, 0x01,
37+
0x00, 0xFD, 0x17, 0x55, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEB, 0x39, 0x54, 0x2C, 0xFD, 0x17,
38+
0x00, 0x00, 0x02, 0xE8, 0xAB, 0xD3, 0x14, 0xC6, 0x50, 0xC1, 0x15, 0xC6, 0xAB, 0xD3, 0x02,
39+
0xE8, 0x00, 0x00, 0xFD, 0x17, 0x55, 0x2C, 0xEB, 0x39, 0xB1, 0x3E, 0xEC, 0x39, 0x54, 0x2C,
40+
0xFE, 0x17, 0x00, 0x00, 0x02, 0xE8, 0xAB, 0xD3, 0x15, 0xC6, 0x4F, 0xC1, 0x14, 0xC6, 0xAC,
41+
0xD3, 0x03, 0xE8, 0x00, 0x00, 0xFD, 0x17, 0x54, 0x2C, 0xEC, 0x39, 0xB2, 0x3E, 0xEB, 0x39,
42+
0x54, 0x2C, 0xFE, 0x17, 0x00, 0x00, 0x02, 0xE8, 0xAB, 0xD3, 0x15, 0xC6, 0x4F, 0xC1, 0x14,
43+
0xC6, 0xAB, 0xD3, 0x03, 0xE8,
44+
};
45+
46+
static void tx_done(const struct device *dev, void *user_data)
47+
{
48+
if (!loopback) {
49+
audio_codec_write(dev, audio_data_p, AUDIO_BLOCK_SIZE);
50+
audio_data_p += AUDIO_BLOCK_SIZE;
51+
if ((audio_data_p - pcm_16k) >= sizeof(pcm_16k)) {
52+
audio_data_p = pcm_16k;
53+
}
54+
}
55+
}
56+
void rx_done(const struct device *dev, uint8_t *buf, uint32_t len, void *user_data)
57+
{
58+
if (loopback) {
59+
audio_codec_write(dev, buf, 320);
60+
}
61+
}
62+
63+
int main(void)
64+
{
65+
static const struct device *dev;
66+
audio_property_value_t val;
67+
struct audio_codec_cfg cfg = {
68+
.dai_type = AUDIO_DAI_TYPE_PCM,
69+
.dai_cfg.pcm.dir = AUDIO_DAI_DIR_TX,
70+
.dai_cfg.pcm.pcm_width = AUDIO_PCM_WIDTH_16_BITS,
71+
.dai_cfg.pcm.channels = 1,
72+
.dai_cfg.pcm.block_size = AUDIO_BLOCK_SIZE,
73+
.dai_cfg.pcm.samplerate = AUDIO_PCM_RATE_16K,
74+
};
75+
76+
LOG_INF("Audio codec sample");
77+
#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(audcodec))
78+
dev = DEVICE_DT_GET(DT_NODELABEL(audcodec));
79+
#else
80+
LOG_ERR("No audio codec on this board. Skipping audio test.\n");
81+
return 0;
82+
#endif
83+
if (!device_is_ready(dev)) {
84+
LOG_ERR("codec device is not ready\n");
85+
return -EBUSY;
86+
}
87+
LOG_INF("codec device is ready");
88+
k_sleep(K_MSEC(1000));
89+
90+
LOG_INF("codec playback example");
91+
loopback = false;
92+
audio_data_p = pcm_16k;
93+
audio_codec_configure(dev, &cfg);
94+
audio_codec_register_done_callback(dev, tx_done, NULL, rx_done, NULL);
95+
LOG_INF("playback started");
96+
audio_codec_start(dev, AUDIO_DAI_DIR_TX);
97+
val.vol = SPEAKER_VOL;
98+
audio_codec_set_property(dev, AUDIO_PROPERTY_OUTPUT_VOLUME, 0, val);
99+
k_sleep(K_MSEC(15000));
100+
audio_codec_stop(dev, AUDIO_DAI_DIR_TX);
101+
LOG_INF("codec tansfer stopped");
102+
103+
LOG_INF("codec loopback example");
104+
loopback = true;
105+
audio_data_p = pcm_16k;
106+
cfg.dai_cfg.pcm.dir = AUDIO_DAI_DIR_TXRX;
107+
audio_codec_configure(dev, &cfg);
108+
LOG_INF("loopback started");
109+
audio_codec_start(dev, AUDIO_DAI_DIR_TXRX);
110+
audio_codec_set_property(dev, AUDIO_PROPERTY_OUTPUT_VOLUME, 0, val);
111+
k_sleep(K_MSEC(15000));
112+
audio_codec_stop(dev, AUDIO_DAI_DIR_TXRX);
113+
LOG_INF("loopback stopped");
114+
115+
LOG_INF("Exiting");
116+
return 0;
117+
}

0 commit comments

Comments
 (0)