/* * 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 #include #if defined(RT_USING_AUDIO) && defined(RT_AUDIO_ROCKCHIP) && defined(RT_USING_FINSH) #include #include #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 */