参考:https://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_8c-example.html

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <alsa/asoundlib.h>
#include <unistd.h> typedef struct {
char *file_name;
char *device;
int ch;
int bit;
int rate;
snd_pcm_format_t format;
unsigned int buffer_time;
unsigned int period_time;
snd_pcm_uframes_t buffer;
snd_pcm_uframes_t period;
}CONFIG_T; typedef struct {
char id[];
int size;
}RIFF_HEADER_T; typedef struct {
char format[];
char sub_id_1[];
int sub_size_1;
short fmt;
short ch;
int sample_rate;
int byte_rate;
short block_align;
short bits_per_sample;
}WAVE_HEADER_T; typedef struct {
char sub_id_2[];
int sub_size_2;
}DATA_HEADER_T; RIFF_HEADER_T riff_header;
WAVE_HEADER_T wave_header;
DATA_HEADER_T data_header;
CONFIG_T config; static void help(void)
{
printf(
"Usage: pcm [OPTION]... [FILE]...\n"
"-h,--help help\n"
"-D,--device playback device\n"
"-i,--input_file only support wav file\n"
"\n");
} static void parse_cmd(int argc, char **argv)
{
struct option long_option[] =
{
{"help", , NULL, 'h'},
{"device", , NULL, 'D'},
{"input_file", , NULL, 'i'},
{NULL, , NULL, },
};
while () {
int c;
if ((c = getopt_long(argc, argv, "hD:i:", long_option, NULL)) < )
break;
switch (c) {
case 'h':
help();
break;
case 'D':
config.device = strdup(optarg);
break;
case 'i':
config.file_name = strdup(optarg);
break;
}
}
} static snd_pcm_format_t get_format(int bits_per_sample)
{
snd_pcm_format_t format = SND_PCM_FORMAT_S8;
switch(bits_per_sample) {
case :
format = SND_PCM_FORMAT_S8;
break;
case :
format = SND_PCM_FORMAT_S16_LE;
break;
case :
format = SND_PCM_FORMAT_S24_LE;
break;
case :
format = SND_PCM_FORMAT_S32_LE;
break;
}
return format;
} static int config_init(CONFIG_T *pConfig)
{
FILE *fp = NULL;
if (NULL == pConfig) {
return -;
}
fp = fopen(pConfig->file_name, "rb");
if (NULL == fp) {
return -;
} fread((void *)&riff_header, sizeof(RIFF_HEADER_T), , fp);
fread((void *)&wave_header, sizeof(WAVE_HEADER_T), , fp);
if (wave_header.sub_size_1 > sizeof (WAVE_HEADER_T) -)
fseek(fp, wave_header.sub_size_1 - (sizeof (WAVE_HEADER_T) - ), SEEK_CUR);
fread((void *)&data_header, sizeof(DATA_HEADER_T), , fp);
pConfig->ch = wave_header.ch;
pConfig->rate= wave_header.sample_rate;
pConfig->bit= wave_header.bits_per_sample;
pConfig->format = get_format(wave_header.bits_per_sample);
fclose(fp);
return ;
} static int set_hwparams(snd_pcm_t *handle)
{
snd_pcm_hw_params_t *params;
unsigned int rrate;
snd_pcm_uframes_t size;
int err, dir;
snd_pcm_hw_params_alloca(&params);
/* choose all parameters */
err = snd_pcm_hw_params_any(handle, params);
if (err < ) {
printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
return err;
}
/* set the interleaved read/write format */
err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
if (err < ) {
printf("Access type not available for playback: %s\n", snd_strerror(err));
return err;
}
/* set the sample format */
err = snd_pcm_hw_params_set_format(handle, params, config.format);
if (err < ) {
printf("Sample format not available for playback: %s\n", snd_strerror(err));
return err;
}
/* set the count of channels */
err = snd_pcm_hw_params_set_channels(handle, params, config.ch);
if (err < ) {
printf("Channels count (%u) not available for playbacks: %s\n", config.ch, snd_strerror(err));
return err;
}
/* set the stream rate */
rrate = config.rate;
err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, );
if (err < ) {
printf("Rate %uHz not available for playback: %s\n", config.rate, snd_strerror(err));
return err;
}
if (rrate != config.rate) {
printf("Rate doesn't match (requested %uHz, get %iHz)\n", config.rate, err);
return -EINVAL;
}
/* set the buffer time */
err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &config.buffer_time, &dir);
if (err < ) {
printf("Unable to set buffer time %u for playback: %s\n", config.buffer_time, snd_strerror(err));
return err;
}
err = snd_pcm_hw_params_get_buffer_size(params, &size);
if (err < ) {
printf("Unable to get buffer size for playback: %s\n", snd_strerror(err));
return err;
}
config.buffer = size;
/* set the period time */
err = snd_pcm_hw_params_set_period_time_near(handle, params, &config.period_time, &dir);
if (err < ) {
printf("Unable to set period time %u for playback: %s\n", config.period_time, snd_strerror(err));
return err;
}
err = snd_pcm_hw_params_get_period_size(params, &size, &dir);
if (err < ) {
printf("Unable to get period size for playback: %s\n", snd_strerror(err));
return err;
}
config.period = size;
/* write the parameters to device */
err = snd_pcm_hw_params(handle, params);
if (err < ) {
printf("Unable to set hw params for playback: %s\n", snd_strerror(err));
return err;
}
return ;
}
static int set_swparams(snd_pcm_t *handle)
{
int err;
snd_pcm_sw_params_t *swparams;
snd_pcm_sw_params_alloca(&swparams);
/* get the current swparams */
err = snd_pcm_sw_params_current(handle, swparams);
if (err < ) {
printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
return err;
}
/* start the transfer when the buffer is almost full: */
/* (buffer_size / avail_min) * avail_min */
err = snd_pcm_sw_params_set_start_threshold(handle, swparams, (config.buffer / config.period) * config.period);
if (err < ) {
printf("Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
return err;
} /* write the parameters to the playback device */
err = snd_pcm_sw_params(handle, swparams);
if (err < ) {
printf("Unable to set sw params for playback: %s\n", snd_strerror(err));
return err;
}
return ;
} /*
* Underrun and suspend recovery
*/ static int xrun_recovery(snd_pcm_t *handle, int err)
{
printf("stream recovery\n");
if (err == -EPIPE) { /* under-run */
err = snd_pcm_prepare(handle);
if (err < )
printf("Can't recovery from underrun, prepare failed: %s\n", snd_strerror(err));
return ;
} else if (err == -ESTRPIPE) {
while ((err = snd_pcm_resume(handle)) == -EAGAIN)
sleep(); /* wait until the suspend flag is released */
if (err < ) {
err = snd_pcm_prepare(handle);
if (err < )
printf("Can't recovery from suspend, prepare failed: %s\n", snd_strerror(err));
}
return ;
}
return err;
} static int write_loop(snd_pcm_t *handle)
{
int err;
size_t remain, read_size;
FILE *fp = NULL;
char *read_buffer = NULL, *offset = NULL;
int bytes_per_frame = config.ch * (config.bit >> );
read_size = config.period * bytes_per_frame;
fp = fopen(config.file_name, "rb");
if (NULL == fp) {
return -;
}
read_buffer = (char * )malloc(read_size);
fseek(fp, , SEEK_CUR); while () {
memset(read_buffer ,, read_size);
err = fread(read_buffer ,, read_size, fp);
if (err <= )
break;
offset = read_buffer;
remain = err / bytes_per_frame;
while (remain> ) {
err = snd_pcm_writei(handle, offset, remain);
if (err == -EAGAIN)
continue;
if (err < ) {
if (xrun_recovery(handle, err) < ) {
printf("Write error: %s\n", snd_strerror(err));
exit(EXIT_FAILURE);
}
continue;
}
offset += err * bytes_per_frame;
remain -= err;
}
}
free(read_buffer);
fclose(fp);
return ;
} int main(int argc, char **argv)
{
int err = ;
snd_pcm_t *handle;
memset (&config, , sizeof(CONFIG_T));
config.buffer_time = ;//us
config.period_time = ;
parse_cmd(argc, argv);
config_init(&config);
if ((err = snd_pcm_open(&handle, config.device, SND_PCM_STREAM_PLAYBACK, )) < ) {
printf("Playback open error: %s\n", snd_strerror(err));
return ;
} if ((err = set_hwparams(handle)) < ) {
printf("Setting of hwparams failed: %s\n", snd_strerror(err));
exit(EXIT_FAILURE);
}
if ((err = set_swparams(handle)) < ) {
printf("Setting of swparams failed: %s\n", snd_strerror(err));
exit(EXIT_FAILURE);
}
write_loop(handle);
snd_pcm_close(handle);
return 0;
}

Makefile:

ALSA_INC_PATH=/home/fellow/alsa-lib-1.2./output/usr/include
ALSA_LIB_PATH=/usr/lib/i386-linux-gnu
ALSA_PLUG_PATH=/usr/lib/i386-linux-gnu/alsa-lib export LD_LIBRARY_PATH=${ALSA_LIB_PATH}:${ALSA_PLUG_PATH}:$LD_LIBRARY_PATH
export CC=gcc
export CFLAGS=-I${ALSA_INC_PATH}
export LDFLAGS=-L{ALSA_LIB_PATH} -lasound
SOURCE=alsa_test.c
TARGET=alsa_test
all:
${CC} ${SOURCE} ${CFLAGS} ${LDFLAGS} -o ${TARGET}

./alsa_test -D default -i xx.wav

ALSA Lib-简单的播放例子的更多相关文章

  1. lib和dll的例子

    .dll和.lib的区别 lib是静态库,dll一般是动态链接库(也有可能是别的)比如要编译个exe,lib在编译的时候就会被编译到exe里,作为程序的一部分而dll是不被编译进去,是运行的时候才调入 ...

  2. 一个简单的cmake例子

    一个简单的cmake例子CMakeLists.txt,生成动态库文件,可以指定发布目录. 尚不支持: 1.交叉编译环境配置 2.添加依赖库   #在当前目录新建一个build目录,然后cd build ...

  3. ALSA lib基本概念

    1.channel 通道,即我们熟知的声道数.左/右声道,5.1channel等等 2.sample A sample is a single value that describes the amp ...

  4. Android开发6:Service的使用(简单音乐播放器的实现)

    前言 啦啦啦~各位好久不见啦~博主最近比较忙,而且最近一次实验也是刚刚结束~ 好了不废话了,直接进入我们这次的内容~ 在这篇博文里我们将学习Service(服务)的相关知识,学会使用 Service ...

  5. Android 实现简单音乐播放器(二)

    在Android 实现简单音乐播放器(一)中,我介绍了MusicPlayer的页面设计. 现在,我简单总结一些功能实现过程中的要点和有趣的细节,结合MainActivity.java代码进行说明(写出 ...

  6. Android 实现简单音乐播放器(一)

    今天掐指一算,学习Android长达近两个月了,今天开始,对过去一段时间的学习收获以及遇到的疑难杂症做一些总结. 简单音乐播放器是我自己完成的第一个功能较为完整的APP,可以说是我的Android学习 ...

  7. html5 简单音乐播放器

    html5 简单音乐播放器 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> < ...

  8. 一个简单的CORBA例子

    因为对CORBA分析的需要,这里写一个简单的CORBA例子.从JDK1.2开始,JDK中集成了ORB的实现,本例子使用了JDK1.7,对于JDK1.2+应该都没有问题.这个例子实现一个简单的加减乘除的 ...

  9. 菜鸟学习Hibernate——简单的一个例子

    一.Hibernate开发. 上篇博客已经为大家介绍了持久层框架的发展流程,持久层框架的种类. 为了能够使用Hibernate快速上手,我们先讲解一个简单的Hibernate应用实例hibernate ...

随机推荐

  1. 和内嵌的iframe进行通讯

    利用内置iframe进行通讯 1. 在当前网页设置iframe网页(监听iframe发来postmessage消息事件) a. 外部网页接收数据: 回调方法,其中e.data为传入数据: const ...

  2. REDTEAM 指南---第四章 外部侦察

    第四章 外部侦察 贡献者:Haythem Arfaoui 翻译BugMan 主动侦察 介绍 主动足迹涉及使用可以帮助您收集更多信息的工具和技术 有关目标的信息.与被动足迹不同的是,过程永远不会“触及” ...

  3. 小白学 Python 数据分析(8):Pandas (七)数据预处理

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  4. linux中find文件搜索命令

    find 解释 命令名称:find 命令所在路径:/bin/find 执行权限:所有用户 功能描述:文件搜索 语法 find [搜索范围] [匹配条件] 匹配条件: -name 文件名(区分大小写) ...

  5. 来简单说说var,let,const,function,import,class

    一.var和let var已经在JavaScript中存在很长一段时间了,但是它存在了一些不足的地方,接下来我们就来看看吧 首先var存在变量提升,这是怎么一回事呢,我们看下面代码 为什么是它呢,是因 ...

  6. AndroidStudio报错:Could not download gradle.jar:No cacahed version available for offline mode

    场景 在讲Android Studio 的.gradle目录从默认C盘修改为 别的目录后,新建app提示: Could not download gradle.jar:No cacahed versi ...

  7. 此Flash Player 与您的地区不相容,请重新安装Adobe Flash Player问题解决

    flash29老版本安装说明: 如果你是Google Chrome 54及以上版本,那么直接安装 install_flash_player_**_ppapi.exe 即可,Chrome 能识别加载,无 ...

  8. C#_Excel数据读取与写入_自定义解析封装类_支持设置标题行位置&使用excel表达式收集数据&单元格映射&标题映射&模板文件的参数数据替换

    本篇博客园是被任务所逼,而已有的使用nopi技术的文档技术经验又不支持我需要的应对各种复杂需求的苛刻要求,只能自己造轮子封装了,由于需要应对很多总类型的数据采集需求,因此有了本篇博客的代码封装,下面一 ...

  9. 转载整理:SublimeText3 Emmet失效问题以及win7 pyV8安装问题

    SublimeText3 Emmet安装问题网上已经很多帖子了,这个简单,主要对win7 64位我本人遇到的Emmet好多快捷功能无法用(比如ul>li*4  Tab无法生成)问题做了整理!搜了 ...

  10. 根据ip列表模拟输出redis cluster的主从对应关系

    需求:给点一批ip列表,一个数组或者一个文件,每行一个ip,模拟输出redis cluster的组从关系,前者是master_ip:master_port -> slave_ip:slave_p ...