依賴庫
要完成該功能依賴libasound、libsndfile庫,該命令在linux下可以通過命令行安裝安裝,安裝命令如下:
sudo apt-get install libasound2-dev
sudo apt-get install libsndfile1-dev
代碼實現
本文的目的是在linux下利用libasound和libsndfile庫基于C++實現讀取麥克風數據,并保存為wav文件。具體實現代碼如下所示:
#include <iostream>
#include <vector>
#include <complex>
#include <fftw3.h>
#include <alsa/asoundlib.h>
#include "math.h"
#include "stdio.h"
#include <vector>
#include <QDateTime>
#include <QDebug>
#include <fstream>
#include "sndfile.h"using namespace std;
const int FRAME_SIZE = 1024;// 定義采樣率、通道數、采樣格式等參數
#define SAMPLE_RATE 16000
#define CHANNELS 1
#define FORMAT SND_PCM_FORMAT_S16_LE // 16位,小端int main() {// 初始化 ALSA 音頻采集snd_pcm_t* capture_handle;int rc;rc = snd_pcm_open(&capture_handle, "default", SND_PCM_STREAM_CAPTURE, 0);if (rc < 0){std::cerr << "無法打開默認音頻設備: " << snd_strerror(rc) << std::endl;return 1;}// 設置音頻采集參數// 配置PCM參數snd_pcm_hw_params_t *params;snd_pcm_hw_params_alloca(¶ms);snd_pcm_hw_params_any(capture_handle, params);snd_pcm_hw_params_set_access(capture_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); //設置該參數的目的是決定多通道時是否采用一塊內存來存儲音頻數據,設置SND_PCM_ACCESS_RW_INTERLEAVED參數就是將多通道情況下的數據存儲到一塊內存中snd_pcm_hw_params_set_format(capture_handle, params, FORMAT);snd_pcm_hw_params_set_channels(capture_handle, params, CHANNELS);unsigned int sampleRate = SAMPLE_RATE;snd_pcm_hw_params_set_rate_near(capture_handle, params, &sampleRate, 0);int err = snd_pcm_hw_params(capture_handle, params);if(err < 0){fprintf(stderr, "無法打開 PCM 設備: %s\n", snd_strerror(err));return 1;}SNDFILE* sndfile;SF_INFO sfinfo;sfinfo.samplerate = 16000;sfinfo.channels = 1;sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;sfinfo.frames = 0;sndfile = sf_open("output1.wav", SFM_WRITE, &sfinfo);if(!sndfile){qDebug()<<"無法創建wav文件";snd_pcm_close(capture_handle);return 1;}int index = 0;short* audioFrame = (short*)malloc(FRAME_SIZE*sizeof(short));while (true){rc = snd_pcm_readi(capture_handle, audioFrame, FRAME_SIZE);//vector<int16_t> vData(audioFrame, audioFrame+FRAME_SIZE);qDebug()<<"time :"<<QDateTime::currentMSecsSinceEpoch();if (rc == FRAME_SIZE){sf_count_t ret = sf_write_short(sndfile, audioFrame, FRAME_SIZE);qDebug()<<"sf_write_short ret : "<<ret;index++;if(index == 50)break;}else if (rc < 0){std::cerr << "讀取音頻數據時出錯: " << snd_strerror(rc) << std::endl;break;}}sf_close(sndfile);snd_pcm_close(capture_handle);return 0;
}
該程序編譯通過后,運行該程序,可以實現錄音。