天天看點

alsa錄音demo

首先安裝相應的支援包:

sudo apt-get install libasound2-dev
           

編譯寫好的代碼

g++ -o 輸出目标檔案名 源代碼.cpp -lasound
           

執行結果檔案

./輸出目标檔案名
           

git stash 使用

/*
read from the default PCM device and writes to standard output for 5 seconds of data
修改聲音采集配置時候,除了修改聲音通道數量,還應該考慮申請的緩沖區時候足夠大 
*/

#define ALSA_PCM_NEW_HW_PARAMS_API

#include <alsa/asoundlib.h>

int main()
{
   long loops;		//一個長整型變量, 
   int rc;			//一個int變量 ,用來存放 snd_pcm_open(通路硬體)的傳回值 
   int size;		//一個int變量 
   snd_pcm_t * handle;		// 一個指向snd_pcm_t的指針 
   snd_pcm_hw_params_t * params;	// 一個指向 snd_pcm_hw_params_t的指針 
   unsigned int val;		// 無符号整型變量 ,用來存放錄音時候的采樣率 
   int dir;			// 整型變量 
   snd_pcm_uframes_t frames;		// snd_pcm_uframes_t 型變量 
   char * buffer;		// 一個字元型指針 
   FILE * out_fd;		// 一個指向檔案的指針 
   out_fd = fopen("out_pcm.raw","wb+");		/* 将流與檔案之間的關系建立起來,文
											   件名為 out_pcm.raw,w是以文本方式
											   打開檔案,wb是二進制方式打開檔案wb+ 
											   讀寫打開或建立一個二進制檔案,允許讀和寫。*/ 
   /* open PCM device for recording (capture). */
   // 通路硬體,并判斷硬體是否通路成功 
   rc = snd_pcm_open(&handle, "default",SND_PCM_STREAM_CAPTURE,0);
   if( rc < 0 )
   {
      fprintf(stderr,
              "unable to open pcm device: %s\n",
              snd_strerror(rc));
      exit(1);
   }
   /* allocate a hardware parameters object */
   // 配置設定一個硬體變量對象 
   snd_pcm_hw_params_alloca(¶ms);
   /* fill it with default values. */
   // 按照預設設定對硬體對象進行設定 
   snd_pcm_hw_params_any(handle,params);
   /* set the desired hardware parameters */
   /* interleaved mode 設定資料為交叉模式*/
   snd_pcm_hw_params_set_access(handle,params,
                                SND_PCM_ACCESS_RW_INTERLEAVED);
   /* signed 16-bit little-endian format */
   // 設定資料編碼格式為PCM、有符号、16bit、LE格式 
   snd_pcm_hw_params_set_format(handle,params,
                                SND_PCM_FORMAT_S16_LE);
   /* two channels(stereo) */
   // 設定雙聲道立體聲 
   snd_pcm_hw_params_set_channels(handle,params,6);
   /* sampling rate */
   // 設定采樣率 
   val = 44100;
   snd_pcm_hw_params_set_rate_near(handle,params,&val,&dir);
   /* set period size */
   // 周期長度(幀數) 
   frames = 32;
   snd_pcm_hw_params_set_period_size_near(handle,params,&frames,&dir);
   /* write 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);
   }
   /* use a buffer large enough to hold one period */
   // 配置一個緩沖區用來緩沖資料,緩沖區要足夠大,此處看意思應該是隻配置了
   // 夠兩個聲道用的緩沖記憶體 
   snd_pcm_hw_params_get_period_size(params,&frames,&dir);
   size = frames * 12; /* 2 bytes/sample, 2channels */
   buffer = ( char * ) malloc(size);
   /* loop for 5 seconds */
   // 記錄五秒長的聲音 
   snd_pcm_hw_params_get_period_time(params, &val, &dir);
   loops = 5000000 / val;
   while( loops > 0 )
   {
       loops--;
       rc = snd_pcm_readi(handle,buffer,frames);
       if ( rc == -EPIPE )
       {
          /* EPIPE means overrun */
          fprintf(stderr,"overrun occured\n");
          snd_pcm_prepare(handle);
       }
       else if ( rc < 0 )
       {
          fprintf(stderr,"error from read: %s\n",
                  snd_strerror(rc));
       }
       else if ( rc != (int)frames)
       {
          fprintf(stderr,"short read, read %d frames\n",rc);
       }
       // 将音頻資料寫入檔案 
       rc = fwrite(buffer, 1, size, out_fd);
       // rc = write(1, buffer, size);
       if ( rc != size )
       {
          fprintf(stderr,"short write: wrote %d bytes\n",rc);
       }
   }
   snd_pcm_drain(handle);
   snd_pcm_close(handle);
   free(buffer);
   fclose(out_fd);
}
           

錄音檔案導入audacity之後如下圖:

alsa錄音demo

1聲道是經過算法處理後的聲音信号;2345聲道是四路MIC的原始資料,6聲道是回放聲道,因為沒有開媒體播放,是以6聲道裡沒有聲音信号。

繼續閱讀