第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > linux文件系统添加pcm 嵌入式linux中PCM音频编程实践

linux文件系统添加pcm 嵌入式linux中PCM音频编程实践

时间:2024-03-19 23:09:24

相关推荐

linux文件系统添加pcm 嵌入式linux中PCM音频编程实践

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

首先需要包含头文件:

#include

定义产量与结构体

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

");

}

}关闭设备:

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

");

}

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

");

snd_pcm_prepare(alsaplayhdl);

frames = snd_pcm_writei(alsaplayhdl, buf, length/2);

}

else if(frames < 0)

{

printf("snd_pcm_writei call failure:%s

", snd_strerror(ret));

frames = snd_pcm_recover(alsaplayhdl, frames, 0);

}

ret = frames*2;

err:

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;

err:

pthread_mutex_unlock(&alsa_cap_mutex);

return ret;

}

打开混音器

int open_mixer(void)

{

int ret;

unsigned charmixercount;

if(mixercount <= 0)

{

ret = snd_mixer_open(&mixerfd,0); // 打开混音器

if(ret < 0)

{

printf("alsa mixer open failture

");

return -1;

}

ret = snd_mixer_attach(mixerfd,"default"); // 先设定为默认

if(ret < 0)

{

printf("alsa mixer attach failture

");

return -2;

}

ret = snd_mixer_selem_register(mixerfd,NULL,NULL); // 注册混音器

if(ret < 0)

{

printf("alsa mixer register failture

");

return -3;

}

ret = snd_mixer_load(mixerfd);

if(ret < 0)

{

printf("alsa mixer load failture

");

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

");

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

");

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(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

");

snd_ctl_close(handle);

handle = NULL;

return -1;

}

}

snd_ctl_close(handle);

handle = NULL;

return 1;

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。