代码拉取完成,页面将自动刷新
#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;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。