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;
}

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"alsa lib pcm.c:8512"是一个错误信息,它是ALSA(Advanced Linux Sound Architecture)库中的一个错误代码。 ALSA是用于在Linux操作系统上处理音频和声音的软件框架。pcm.c是该库中与PCM(Pulse-code Modulation)音频数据处理相关的文件。当出现"alsa lib pcm.c:8512"错误时,表示在执行PCM音频数据读取或写入操作时发生了错误,具体是在pcm.c文件的第8512行。 要解决这个错误,可以考虑以下几个步骤: 1. 检查设备配置:确保使用正确的音频设备进行读取或写入操作。可以使用命令"aplay -l"和"arecord -l"来列出系统中可用的音频设备。 2. 检查权限:确保当前用户有足够的权限来访问音频设备。可以使用命令"ls -l /dev/snd/"来查看设备文件的权限。 3. 检查设置参数:检查PCM音频处理的设置参数是否正确。可以参考ALSA文档和相应的程序代码来确认参数设置的正确性。 4. 检查驱动和库版本:确保ALSA库和音频驱动程序的版本是兼容的。更新驱动程序或升级ALSA库可能有助于解决一些已知的问题。 5. 查找其他错误信息:在"alsa lib pcm.c:8512"错误之前或之后的错误信息中,可能会提供更多有关问题原因的线索。对这些错误信息进行分析,可能会帮助定位和解决问题。 6. 检查其他系统资源:确保系统上的其他资源,如内存、磁盘空间等,充足且没有其他问题。 如果以上步骤都无法解决问题,建议查看ALSA论坛或咨询相关的技术支持团队,寻求更详细的帮助和指导。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值