相关文章推荐
眼睛小的匕首  ·  Learn JavaScript ...·  1 年前    · 
卖萌的煎鸡蛋  ·  【Python面试】 ...·  1 年前    · 

嵌入式设备中经常需要用的音频,音频设备最原始的数据格式就是PCM,也就是大家常见的WAV,在linux中,音频编程使用最多的就是alsa框架,下面就来看一下pcm音频的编程实例吧。

首先需要包含头文件:

#include <alsa/asoundlib.h> 

定义产量与结构体
snd_pcm_t 			*alsaplayhdl;
snd_pcm_t 			*alsacapturehdl;
snd_mixer_t 		*mixerfd;
snd_mixer_elem_t 	*elem;
pthread_mutex_t alsa_play_mutex;
pthread_mutex_t alsa_cap_mutex;
snd_pcm_hw_params_t *dispalsa_hwparams;
snd_pcm_sw_params_t *dispalsa_swparams;
snd_pcm_hw_params_t *capturehwparams;
snd_pcm_sw_params_t *captureswparams;

定义设备号:
#define ALSADEVNAME "default"

打开设备:
void open_dev(void)
	int ret = -1;
	ret = snd_pcm_open(&alsaplayhdl,ALSADEVNAME,SND_PCM_STREAM_PLAYBACK,0);
	if(ret < 0)
		printf("open alsa display failture\n");
}
关闭设备:
void close_dev(void)
    int ret = -1;
    pthread_t tid;
    if(alsaplayhdl != NULL)
        snd_pcm_drop(alsaplayhdl);
        ret = snd_pcm_close(alsaplayhdl);
        if(ret < 0)
            printf("alsa close dev failture\n");
        alsaplayhdl = NULL;

写入音频数据
int alsa_write(char* buf, int length)
    int frames;
    int ret=0;
    int write = 0,size;
	long int audiodisplay[2];
    audiodisplay[0]++;                                           //正常情况下,alsa_write_audiobuf()调用一次,sysglobaldata_status.audiodisplay[0]的值增加1。如果该值长久没有变化时表明声音播放异常
    frames = snd_pcm_writei(alsaplayhdl, buf, length/2);
    if(frames ==  -EPIPE)
        printf("apps write buff too Slow!-EPIPE\n");
        snd_pcm_prepare(alsaplayhdl);
        frames = snd_pcm_writei(alsaplayhdl, buf, length/2);
    else if(frames < 0)
        printf("snd_pcm_writei call failure:%s\n", snd_strerror(ret));
        frames = snd_pcm_recover(alsaplayhdl, frames, 0);
    ret = frames*2;
    return ret;

读取设备音频数据
int alsa_read(char* buf, int length)
	int frames;
	int ret = -1;
	int read;
	pthread_mutex_lock(&alsa_cap_mutex);
	frames = snd_pcm_avail(alsacapturehdl);
	if(frames <= 0)
		goto err;
	read = frames *2 > length ? length : frames * 2;
	frames = snd_pcm_readi(alsacapturehdl, buf, read/2);
	if(frames < 0)
		goto err;
	ret = frames * 2;
	pthread_mutex_unlock(&alsa_cap_mutex);
	return ret;

打开混音器

int open_mixer(void)
	int ret;
	unsigned char		mixercount;
	if(mixercount <= 0)
		ret = snd_mixer_open(&mixerfd,0);                       // 打开混音器
		if(ret < 0)
			printf("alsa mixer open failture\n");
			return -1;
		ret = snd_mixer_attach(mixerfd,"default"); 				// 先设定为默认
		if(ret < 0)
			printf("alsa mixer attach failture\n");
			return -2;
		ret = snd_mixer_selem_register(mixerfd,NULL,NULL);    		 // 注册混音器
		if(ret < 0)
			printf("alsa mixer register failture\n");
			return -3;
		ret = snd_mixer_load(mixerfd);
		if(ret < 0)
			printf("alsa mixer load failture\n");
			return -4;
		mixercount = 0;
	mixercount ++;
	return mixercount;

设置设备音量
int set_volume(int volume) 
    int err;  
    int orig_volume = 0;  
    static snd_ctl_t *handle = NULL;  
    snd_ctl_elem_info_t *info;  
    snd_ctl_elem_id_t *id;  
    snd_ctl_elem_value_t *control;  
    unsigned int count;  
    snd_ctl_elem_type_t type;  
    snd_ctl_elem_info_alloca(&info);  
    snd_ctl_elem_id_alloca(&id);  
    snd_ctl_elem_value_alloca(&control);      
    snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
    snd_ctl_elem_id_set_name(id, "Mic Capture Volume");  
    if ((err = snd_ctl_open(&handle, "default", 0)) < 0) {  
        printf("open ctl device failed\n");       
        return -1;  
    snd_ctl_elem_info_set_id(info, id);  
    if ((err = snd_ctl_elem_info(handle, info)) < 0) {  
        printf("snd_ctl_elem_info failed\n");
        snd_ctl_close(handle);  
        handle = NULL;  
        return -1;  
    type = snd_ctl_elem_info_get_type(info);  
    count = snd_ctl_elem_info_get_count(info);  
    snd_ctl_elem_value_set_id(control, id);  
    if (!snd_ctl_elem_read(handle, control)) {  
        orig_volume = snd_ctl_elem_value_get_integer(control, 0);  
    if(volume != orig_volume) {  
        //snd_ctl_elem_value_set_integer(control, 0, static_cast<long>(volume));  
        snd_ctl_elem_value_set_integer(control, 0,volume);  
        snd_ctl_elem_value_set_integer(control, 1,volume);  
        if ((err = snd_ctl_elem_write(handle, control)) < 0) 
            printf("snd_ctl_elem_write failed\n");
            snd_ctl_close(handle);  
            handle = NULL;  
            return -1;  
    snd_ctl_close(handle);  
    handle = NULL;  
    return 1;  
                    嵌入式设备中经常需要用的音频,音频设备最原始的数据格式就是PCM,也就是大家常见的WAV,在linux中,音频编程使用最多的就是alsa框架,下面就来看一下pcm音频的编程实例吧。    首先需要包含头文件:#include  定义产量与结构体snd_pcm_t 			*alsaplayhdl;snd_pcm_t 			*alsacapturehdl;snd_mixer_t
				
    pcm播放的时候,接口snd_pcm_writei 返回 -EPIPE,为underrun     录制音频的时候, 接口snd_pcm_readi 返回 -EPIPE, 为overrun     使用ALSA架构的驱动程序,在实际开发使用过程,比较常见的错误有-EPIPE,也就是-32?为什么会出现呢?肯定是系统内部不和谐了!EPIPE的错误在播放时出现就是因为驱动buffer没有...
在看音频数据是怎么写的时候,在MixerThread的threadloop函数,有以下代码完成了往硬件写数据: int bytesWritten = (int)mOutput-&gt;write(mMixBuffer, mixBufferSize); mOutput来历: 函数AudioFlinger::openOutput创建了一个MixerThread对象,并将前面调用mAudioH...
[Loong]:之前写过基于ALSA的WAV播放录音程序,见http://blog.csdn.net/sepnic/archive/2011/01/14/6140824.aspx。现在本想好好整理一下ALSA编程思想,但Google了一下,发现已经有同道做了类似的工作,故将其转载过来,并添加一些本人的疑问以及补充(将会继续补充,原文很多重要的ALSA参数没有提到)。 原文:http://blo
由于历史的原因,在 Linux 环境下有多种API系统可用于声音编程。但没有合适的指引就难以找到合乎自己需要的体系。这里是一个指引,是由Lennart Poettering 所写(参见:Homepage of Lennart),目的就是带你走出这个密林。 最简单的指引莫过于问自己
alsa音频输出过程 alsa播放音频的原理通过snd_pcm_writei()等函数将音频数据写到alsa的bufferalsa启动播放以后,alsa驱动会产生断,每次断从buffer取走period个音频数据帧输出到codec。 音频最后的数据不足一个period alsa驱动从buffer是按照一个完整的period个数据帧取走数据的,如果取走的一个period数据,并不都是音频数据,可能有其他脏数据,那就可能在最后一帧产生噪音。 首先关于buffer和frame的概念还不知道
#include &lt;alsa/asoundlib.h&gt; 3.定义变量 snd_pcm_t *handle;  //调用snd_pcm_open打开PCM设备返回的文件句柄,后续的操作都使用是、这个句柄操作这个PCM设备 snd_pcm_hw_para...
http://old.sebug.net/paper/books/scipydoc/wave_pyaudio.html 在虚拟机下不知道为什么就是报错,所以换成的windows下运行,安装教程http://blog.csdn.net/qq_30706581/article/details/56666522 ALSA lib setup.c:548:(add_elem) Cannot o
1.  什么是pcmpcm(Pulse-code modulation)脉冲编码调制,是将模拟信号转化为数字信号的一种方法。声音的转化的过程为,先对连续的模拟信号按照固定频率周期性采样,将采样到的数据按照一定的精度进行量化,量化后的信号和采样后的信号差值叫做量化误差,将量化后的数据进行最后的编码存储,最终模拟信号变化为数字信号。 2. pcm的两个重要属性