1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
/*
* Copyright (c) 2006-2026, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2026-07-22 GuEe-GUI first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#if defined(RT_USING_AUDIO) && defined(RT_AUDIO_ROCKCHIP) && defined(RT_USING_FINSH)
#include <finsh.h>
#include <stdlib.h>
#define AUDIO_TEST_DEVICE "rockchip-hdmi0"
#define AUDIO_TEST_RATE 48000U
#define AUDIO_TEST_CHANNELS 2U
#define AUDIO_TEST_BITS 16U
#define AUDIO_TEST_BUFFER_SIZE 4096U
#define AUDIO_TEST_DEFAULT_SECONDS 2U
#define AUDIO_TEST_MAX_SECONDS 30U
/* One period at 48 kHz produces a 1 kHz sine wave. */
static const rt_int16_t audio_test_sine[] =
{
0, 2139, 4240, 6269, 8192, 9974, 11585, 12998,
14189, 15136, 15825, 16244, 16384, 16244, 15825, 15136,
14189, 12998, 11585, 9974, 8192, 6269, 4240, 2139,
0, -2139, -4240, -6269, -8192, -9974,-11585,-12998,
-14189,-15136,-15825,-16244,-16384,-16244,-15825,-15136,
-14189,-12998,-11585, -9974, -8192, -6269, -4240, -2139,
};
static int audio_test(int argc, char **argv)
{
int ret = -RT_ERROR;
char *end;
unsigned long value;
rt_uint32_t phase = 0;
rt_uint32_t seconds = AUDIO_TEST_DEFAULT_SECONDS;
rt_size_t remaining;
rt_device_t device;
rt_int16_t *buffer;
const char *name = AUDIO_TEST_DEVICE;
struct rt_audio_caps caps = { 0 };
if (argc > 3)
{
rt_kprintf("usage: audio_test [device] [seconds]\n");
return -RT_EINVAL;
}
if (argc > 1)
{
name = argv[1];
}
if (argc > 2)
{
value = strtoul(argv[2], &end, 0);
if (*end || !value || value > AUDIO_TEST_MAX_SECONDS)
{
rt_kprintf("seconds must be 1..%u\n", AUDIO_TEST_MAX_SECONDS);
return -RT_EINVAL;
}
seconds = value;
}
device = rt_device_find(name);
if (!device)
{
rt_kprintf("audio device %s not found\n", name);
return -RT_ENOSYS;
}
buffer = rt_malloc(AUDIO_TEST_BUFFER_SIZE);
if (!buffer)
{
return -RT_ENOMEM;
}
ret = rt_device_open(device, RT_DEVICE_OFLAG_WRONLY);
if (ret)
{
rt_kprintf("open %s failed: %s\n", name, rt_strerror(ret));
goto _free;
}
caps.main_type = AUDIO_TYPE_OUTPUT;
caps.sub_type = AUDIO_DSP_PARAM;
caps.udata.config.samplerate = AUDIO_TEST_RATE;
caps.udata.config.channels = AUDIO_TEST_CHANNELS;
caps.udata.config.samplebits = AUDIO_TEST_BITS;
ret = rt_device_control(device, AUDIO_CTL_CONFIGURE, &caps);
if (ret)
{
rt_kprintf("configure %s failed: %s\n", name, rt_strerror(ret));
goto _close;
}
remaining = (rt_size_t)seconds * AUDIO_TEST_RATE *
AUDIO_TEST_CHANNELS * sizeof(*buffer);
rt_kprintf("playing 1 kHz stereo tone on %s for %u second(s)\n",
name, seconds);
while (remaining)
{
rt_size_t size = rt_min_t(rt_size_t, remaining, AUDIO_TEST_BUFFER_SIZE);
rt_size_t samples = size / sizeof(*buffer);
/* Interleaved stereo: send the same sample to left and right. */
for (rt_size_t i = 0; i < samples; i += AUDIO_TEST_CHANNELS)
{
rt_int16_t sample = audio_test_sine[phase];
buffer[i] = sample;
buffer[i + 1] = sample;
phase = (phase + 1) % RT_ARRAY_SIZE(audio_test_sine);
}
if (rt_device_write(device, 0, buffer, size) != size)
{
rt_kprintf("write %s failed\n", name);
ret = -RT_EIO;
goto _close;
}
remaining -= size;
}
ret = RT_EOK;
_close:
rt_device_close(device);
_free:
rt_free(buffer);
return ret;
}
MSH_CMD_EXPORT(audio_test, play a 1 kHz tone: audio_test [device] [seconds]);
#endif /* RT_USING_AUDIO && RT_AUDIO_ROCKCHIP && RT_USING_FINSH */
|