2 Star 1 Fork 1

刘煜/smartspeaker

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
play.c 2.92 KB
一键复制 编辑 原始数据 按行查看 历史
刘煜 提交于 2024-03-12 16:31 +08:00 . 消除播放结束时的杂音
#include <alsa/asoundlib.h> //ALSA头文件
int main(int argc, char** argv)
{
snd_pcm_t* dev;
//运行时需要指定音频文件
if (argc < 2)
{
fprintf(stderr, "too few argument\n");
return EXIT_FAILURE;
}
//打开放音设备,阻塞方式
int error = snd_pcm_open(&dev, "hw:0,0", SND_PCM_STREAM_PLAYBACK, 0);
if (error)
{
fprintf(stderr, "snd_pcm_open: %s\n", snd_strerror(error));
return EXIT_FAILURE;
}
//设置放音参数
snd_pcm_hw_params_t * record_param;
//在栈上分配参数内存并初始化
snd_pcm_hw_params_alloca(&record_param);
error += snd_pcm_hw_params_any(dev, record_param);
//设置采样格式(有符号16位整数,小端序)
error += snd_pcm_hw_params_set_format(dev, record_param, SND_PCM_FORMAT_S16_LE);
//设置访问方式(交错读写)
error += snd_pcm_hw_params_set_access(dev, record_param, SND_PCM_ACCESS_RW_INTERLEAVED);
//设置采样频率(16KHz)
error += snd_pcm_hw_params_set_rate(dev, record_param, 16000, 0);
//设置声道数量(单声道)
error += snd_pcm_hw_params_set_channels(dev, record_param, 1);
//根据硬件参数配置声卡
error = snd_pcm_hw_params(dev, record_param);
if (error)
{
fprintf(stderr, "snd_pcm_hw_params: %s\n", snd_strerror(error));
return EXIT_FAILURE;
}
//获取一个周期数据量,从声卡获取数据时,读写的最小单位是1个周期
snd_pcm_uframes_t nframe;
int dir = 0;
error = snd_pcm_hw_params_get_period_size(record_param, &nframe, &dir);
if (error)
{
fprintf(stderr, "snd_pcm_hw_params_get_period_size: %s\n", snd_strerror(error));
return EXIT_FAILURE;
}
printf("period = %lu frames\n", nframe);
//分配缓冲区,大小必须为周期的倍数
char* buf = malloc(snd_pcm_frames_to_bytes(dev, nframe));
//打开音频文件
FILE* fp = fopen(argv[1], "r+");
if (!fp)
{
perror("fopen");
free(buf);
return EXIT_FAILURE;
}
//开始播放
snd_pcm_prepare(dev);
while (1)
{
size_t rbytes;
//从文件中读取一个周期的音频数据
rbytes = fread(buf, 1, snd_pcm_frames_to_bytes(dev, nframe), fp);
if (rbytes == 0)
{
break;
}
//向最后一个周期的数据填充静音
if (rbytes < snd_pcm_frames_to_bytes(dev, nframe))
{
memset(buf + rbytes, 0, snd_pcm_frames_to_bytes(dev, nframe) - rbytes);
}
//将音频数据写入声卡
snd_pcm_sframes_t wframes = snd_pcm_writei(dev, buf, nframe);
if (wframes < 0)
{
fprintf(stderr, "snd_pcm_writei: %s\n", snd_strerror(wframes));
}
}
//停止并等待播放完成
snd_pcm_drain(dev);
fclose(fp);
free(buf);
//关闭设备
snd_pcm_close(dev);
return 0;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/tinytaro/smartspeaker.git
git@gitee.com:tinytaro/smartspeaker.git
tinytaro
smartspeaker
smartspeaker
main

搜索帮助