尝试了一下alsa录音播放的编程。
网上大部分文章比较老,最近这几年已经有新的接口了,一个snd_pcm_set_params函数搞定大部分参数设置
简单一点,例子说话
1。启动录音,第一打开第二设置
#define DEVICE "default"
int StartPCMRecording(AUDIO_RECORD *pAudioRecord) { int rc, size, dir; snd_pcm_t *handle; snd_pcm_hw_params_t *params; snd_pcm_uframes_t frames, ret; /* Open PCM device for record. */ rc = snd_pcm_open(&handle, DEVICE, SND_PCM_STREAM_CAPTURE, 0); if (rc!=0) printf("%d, return %d, %s \n",__LINE__,rc,snd_strerror(rc)); #if 0 /* Allocate a hardware parameters object. */ rc = snd_pcm_hw_params_malloc(¶ms); if (rc!=0) printf("%d, return %d, %s \n",__LINE__,rc,snd_strerror(rc)); /* Fill it in with default values. */ rc = snd_pcm_hw_params_any(handle, params); if (rc!=0) printf("%d, return %d, %s \n",__LINE__,rc,snd_strerror(rc)); /* Signed 16-bit little-endian format */ rc = snd_pcm_hw_params_set_format(handle, params, FORMAT); if (rc!=0) printf("%d, return %d, %s \n",__LINE__,rc,snd_strerror(rc)); /* One channels (stereo) */ rc = snd_pcm_hw_params_set_channels(handle, params, CHANNLE); if (rc!=0) printf("%d, return %d, %s \n",__LINE__,rc,snd_strerror(rc)); rc = snd_pcm_hw_params_set_access (handle, params,SND_PCM_ACCESS_RW_INTERLEAVED ); if (rc!=0) printf("%d, return %d, %s \n",__LINE__,rc,snd_strerror(rc)); /* 16000 sampling rate */ rc = snd_pcm_hw_params_set_rate(handle, params, SAMPLE_RATE, 0); if (rc!=0) printf("%d, return %d, %s \n",__LINE__,rc,snd_strerror(rc)); frames = FRAMES_SIZE; rc = snd_pcm_sw_params_set_avail_min(handle,params,frames); if (rc!=0) printf("%d, return %d, %s \n",__LINE__,rc,snd_strerror(rc)); /* Write the parameters to the driver */ rc = snd_pcm_hw_params(handle, params); if (rc!=0) printf("%d, return %d, %s \n",__LINE__,rc,snd_strerror(rc)); #endif //int snd_pcm_set_params(snd_pcm_t *pcm, // snd_pcm_format_t format, // snd_pcm_access_t access, // unsigned int channels, // unsigned int rate, // int soft_resample, // unsigned int latency); snd_pcm_set_params(handle,SND_PCM_FORMAT_S16_LE,SND_PCM_ACCESS_RW_INTERLEAVED,1,48000,0,500000);
从上面看到,以前设置pcm参数的一大堆函数调用已经简化成一个
snd_pcm_set_params()
2。录音代码
int read_from_pcm(void *pDevice, void *pData, int samples) { int ret; snd_pcm_t *handle = (snd_pcm_t *)pDevice; int nData=samples; //snd_pcm_wait(handle,20) ; ret = snd_pcm_readi(handle, pData, nData); return samples; }
3。结束代码
snd_pcm_drain(handle);
snd_pcm_close(handle);
4。播放也类似,总共5个函数,open/setting/write/close
void startPlaying(){ /* Open PCM device for playback. */ rc = snd_pcm_open(&handle,DEVICE, SND_PCM_STREAM_PLAYBACK, 0); printf("[StartPCMPlaying]:snd_pcm_open return value is %d\n",rc); //int snd_pcm_set_params(snd_pcm_t *pcm, // snd_pcm_format_t format, // snd_pcm_access_t access, // unsigned int channels, // unsigned int rate, // int soft_resample, // unsigned int latency); snd_pcm_set_params(handle,SND_PCM_FORMAT_S16_LE,SND_PCM_ACCESS_RW_INTERLEAVED,1,48000,1,500000); #if 0 /* Allocate a hardware parameters object. */ rc = snd_pcm_hw_params_malloc(¶ms); if (rc!=0) printf("%d, return %d, %s \n",__LINE__,rc,snd_strerror(rc)); /* Fill it in with default values. */ rc=snd_pcm_hw_params_any(handle, params); if (rc!=0) printf("%d, return %d, %s \n",__LINE__,rc,snd_strerror(rc)); /* Signed 16-bit little-endian format */ rc=snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); if (rc!=0) printf("%d, return %d, %s \n",__LINE__,rc,snd_strerror(rc)); /* Two channels (stereo) */ rc=snd_pcm_hw_params_set_channels(handle, params, 1); if (rc!=0) printf("%d, return %d, %s \n",__LINE__,rc,snd_strerror(rc)); /* 44100 bits/second sampling rate (CD quality) */ int val = 16000; rc=snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); if (rc!=0) printf("%d, return %d, %s \n",__LINE__,rc,snd_strerror(rc)); rc = snd_pcm_hw_params_set_access (handle, params,SND_PCM_ACCESS_RW_INTERLEAVED ); if (rc!=0) printf("%d, return %d, %s \n",__LINE__,rc,snd_strerror(rc)); rc = snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); if (rc!=0) printf("%d, return %d, %s \n",__LINE__,rc,snd_strerror(rc)); /* Write the parameters to the driver */ rc = snd_pcm_hw_params(handle, params); if (rc < 0) { fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc)); exit(1); } #endif } void write_to_pcm(void *pDevice, void *pData, int frames) { int nlen = frames ; int rc = snd_pcm_writei(pDevice, pData, nlen); } void int StopPlaying(void *pDevice) { snd_pcm_drain(pDevice; snd_pcm_close(pDevice); }
其中device可以用arecord -l 或aplay -l查看
通常用default是比较通用的选择,有耳麦用耳麦没耳麦用笔记本的