ALSA record PCM

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <alsa/asoundlib.h>

#define PCM_FORMAT SND_PCM_FORMAT_S16_LE
#define CHANNEL 1
#define SAMPLE_RATE 16000

int main(int argc,char *argv[])
{
	/* Handle for the PCM device */ 
    	snd_pcm_t *handle;          
    	/* Playback stream */
    	snd_pcm_stream_t stream = SND_PCM_STREAM_CAPTURE;
    	snd_pcm_hw_params_t *hwparams;
    	char *pcm_name = "default";
    	int err;
	int dir = 0;
	snd_pcm_format_t format = PCM_FORMAT;
	unsigned int nChannels = CHANNEL;
	unsigned int rate = SAMPLE_RATE;
	snd_pcm_uframes_t psize_frames = 64;
	snd_pcm_uframes_t bsize_frames = 256;

	char *filename = "record.pcm";
	int fd;
	char *buffer = NULL;
	int count,loop;
	unsigned int period_time;


	fd = open(filename,O_RDWR | O_CREAT | O_TRUNC,666);
	if(fd < 0)
	{
		perror("open file failed!\n");
		return -1;
	}
	chmod(filename,0777);

	//open PCM
    	if (snd_pcm_open(&handle, pcm_name, stream, 0) < 0) 
    	{
      		printf(stderr, "Error opening PCM device %s\n", pcm_name);
      		return -1;
    	}

    	//Allocate the snd_pcm_hw_params_t structure on the stack. 
    	err = snd_pcm_hw_params_malloc(&hwparams);
	if(err < 0)
	{
		perror("malloc space for snd_pcm_hw_params_t structure failed !\n");
		return -1;
	}

	//initial hwparams
    	err = snd_pcm_hw_params_any(handle, hwparams);
    	if (err < 0) 
    	{
		printf("Broken configuration for this PCM\n");
		return err;
    	}

	//set access type
    	err = snd_pcm_hw_params_set_access(handle, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED);
	if (err < 0) 
	{
		printf("Access type not available\n");
		return err;
	}

	//set pcm format
	err = snd_pcm_hw_params_set_format(handle, hwparams, format);
	if (err < 0) 
	{
		printf("Sample format non available\n");
		return err;
	}

	//set pcm channels
	err = snd_pcm_hw_params_set_channels(handle, hwparams, 1);
	if (err < 0) 
	{
		printf("Channels count non available\n");
		return err;
	}

	//set pcm sample rate
	err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &rate, &dir);
	if (err < 0) 
	{
		printf("Set rate failed\n");
		return err;
	}

	//set buffer size
	err = snd_pcm_hw_params_set_buffer_size_near(handle,hwparams,&bsize_frames);
	if(err < 0)
	{
		printf("Set period size failed\n");
		return err;
	}

	//set period size
	err = snd_pcm_hw_params_set_period_size_near(handle,hwparams,&psize_frames,0);
	if(err < 0)
	{
		printf("Set buffer size failed\n");
		return err;
	}

	//set the hwparams to driver
	err = snd_pcm_hw_params(handle,hwparams);
	if(err<0)
	{
		printf("failed to set hardware parameters:%s\n",snd_strerror(err));
		return err;
	}


	err = snd_pcm_hw_params_get_period_size(hwparams, &psize_frames, &dir);
	if (err < 0) 
	{
		printf("get period size fail\n");
		return err;
	}
	else
	{
		printf("period size is %d frames.\n",psize_frames);
	}
	
	snd_pcm_hw_params_get_period_time(hwparams, &period_time, &dir);
	loop = 10000000/period_time;//录音10秒
	
	//play
	buffer = (char*)malloc(psize_frames*2);//1 channel,sizeof(frame) = 2*1 byte;
	while(loop--)
	{
		err = snd_pcm_readi(handle, buffer, psize_frames);  
          
        	if (err == -EAGAIN || (err >= 0 && (size_t)err < psize_frames)) 
		{  
            		snd_pcm_wait(handle, 1000);  
        	} 
		else if (err == -EPIPE) 
		{  
            		snd_pcm_prepare(handle);  
            		printf("<<<<<<<<<<<<<<< Buffer Underrun >>>>>>>>>>>>>>>/n");  
       		} 
		else if (err == -ESTRPIPE) 
		{ 
	    		snd_pcm_resume(handle);	
            		printf("<<<<<<<<<<<<<<< Need suspend >>>>>>>>>>>>>>>/n");  
        	} 
		else if (err < 0) 
		{  
            		printf("Error snd_pcm_writei: [%s]", snd_strerror(err));  
            		return -1; 
       	        } 

		// 将音频数据写入文件 
       		count = write(fd,buffer, psize_frames*2);
       		if ( count != psize_frames*2 )
      	 	{
          		printf("short write: wrote %d bytes\n",count);
       		}
          
	}

	snd_pcm_drain(handle);
  	snd_pcm_close(handle);
	free(buffer);
	close(fd);

	return 0;
}

代解决:通过读到的数据判断声音强度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值