mirror of
https://gitee.com/Vancouver2017/luban-lite-t3e-pro.git
synced 2025-12-14 10:28:54 +00:00
129 lines
3.7 KiB
C
129 lines
3.7 KiB
C
/*
|
|
* Copyright (c) 2022-2023, ArtInChip Technology Co., Ltd
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
* Authors: dwj <weijie.ding@artinchip.com>
|
|
*/
|
|
#include <rtthread.h>
|
|
#include <rtdevice.h>
|
|
#include <dfs_posix.h>
|
|
|
|
#define RECORD_TIME_MS 5000
|
|
#define RECORD_SAMPLERATE 16000
|
|
#define RECORD_CHANNEL 2
|
|
#define RECORD_CHUNK_SZ ((RECORD_SAMPLERATE * RECORD_CHANNEL * 2) * 20\
|
|
/ 1000)
|
|
|
|
#define SOUND_DEVICE_NAME "dmic0"
|
|
static rt_device_t mic_dev;
|
|
|
|
struct wav_header
|
|
{
|
|
char riff_id[4]; /* "RIFF" */
|
|
int riff_datasize;
|
|
char riff_type[4]; /* "WAVE" */
|
|
char fmt_id[4]; /* "fmt " */
|
|
int fmt_datasize; /* fmt chunk data size,16 for pcm */
|
|
short fmt_compression_code; /* 1 for PCM */
|
|
short fmt_channels; /* 1(mono) or 2(stereo) */
|
|
int fmt_sample_rate; /* samples per second */
|
|
int fmt_avg_bytes_per_sec;
|
|
short fmt_block_align;
|
|
short fmt_bit_per_sample; /* bits of each sample(8,16,32). */
|
|
char data_id[4]; /* "data" */
|
|
int data_datasize; /* data chunk size,pcm_size - 44 */
|
|
};
|
|
|
|
static void wavheader_init(struct wav_header *header, int sample_rate,
|
|
int channels, int datasize)
|
|
{
|
|
memcpy(header->riff_id, "RIFF", 4);
|
|
header->riff_datasize = datasize + 44 - 8;
|
|
memcpy(header->riff_type, "WAVE", 4);
|
|
memcpy(header->fmt_id, "fmt ", 4);
|
|
header->fmt_datasize = 16;
|
|
header->fmt_compression_code = 1;
|
|
header->fmt_channels = channels;
|
|
header->fmt_sample_rate = sample_rate;
|
|
header->fmt_bit_per_sample = 16;
|
|
header->fmt_avg_bytes_per_sec = header->fmt_sample_rate *
|
|
header->fmt_channels *
|
|
header->fmt_bit_per_sample / 8;
|
|
header->fmt_block_align = header->fmt_bit_per_sample *
|
|
header->fmt_channels / 8;
|
|
memcpy(header->data_id, "data", 4);
|
|
header->data_datasize = datasize;
|
|
}
|
|
|
|
int test_wavrecord(int argc, char **argv)
|
|
{
|
|
int fd = -1;
|
|
uint8_t *buffer = NULL;
|
|
struct wav_header header;
|
|
struct rt_audio_caps caps = {0};
|
|
int length, total_length = 0;
|
|
|
|
if (argc != 2)
|
|
{
|
|
rt_kprintf("Usage:\n");
|
|
rt_kprintf("arecord file.wav\n");
|
|
return -1;
|
|
}
|
|
|
|
fd = open(argv[1], O_WRONLY | O_CREAT);
|
|
if (fd < 0)
|
|
{
|
|
rt_kprintf("open file for recording failed!\n");
|
|
return -1;
|
|
}
|
|
write(fd, &header, sizeof(struct wav_header));
|
|
|
|
buffer = rt_malloc(RECORD_CHUNK_SZ);
|
|
if (buffer == RT_NULL)
|
|
goto __exit;
|
|
|
|
mic_dev = rt_device_find(SOUND_DEVICE_NAME);
|
|
if (mic_dev == RT_NULL)
|
|
goto __exit;
|
|
|
|
rt_device_open(mic_dev, RT_DEVICE_OFLAG_RDONLY);
|
|
|
|
caps.main_type = AUDIO_TYPE_INPUT;
|
|
caps.sub_type = AUDIO_DSP_PARAM;
|
|
caps.udata.config.samplerate = RECORD_SAMPLERATE;
|
|
caps.udata.config.channels = RECORD_CHANNEL;
|
|
caps.udata.config.samplebits = 16;
|
|
rt_device_control(mic_dev, AUDIO_CTL_CONFIGURE, &caps);
|
|
|
|
while (1)
|
|
{
|
|
length = rt_device_read(mic_dev, 0, buffer, RECORD_CHUNK_SZ);
|
|
|
|
if (length)
|
|
{
|
|
write(fd, buffer, length);
|
|
total_length += length;
|
|
}
|
|
|
|
if ((total_length / RECORD_CHUNK_SZ) > (RECORD_TIME_MS / 20))
|
|
break;
|
|
}
|
|
|
|
wavheader_init(&header, RECORD_SAMPLERATE, RECORD_CHANNEL, total_length);
|
|
lseek(fd, 0, SEEK_SET);
|
|
write(fd, &header, sizeof(struct wav_header));
|
|
close(fd);
|
|
|
|
rt_device_close(mic_dev);
|
|
|
|
__exit:
|
|
if (fd >= 0)
|
|
close(fd);
|
|
|
|
if (buffer)
|
|
rt_free(buffer);
|
|
|
|
return 0;
|
|
}
|
|
MSH_CMD_EXPORT_ALIAS(test_wavrecord, arecord, record voice to a wav file);
|