QT中有一個強大的音頻處理的庫,可以設置採集的參數,指定採集的設備等,這個強大的類就是QAudioInput,下面介紹如何通過這個類實現音頻的設置,採集和保存
- QAudioInput屬於multimedia模塊,故我們在pro文件需要 QT += multimedia
- 採集音頻的參數設置通過QAudioFormat 來設置,告訴計算機應該以什麼樣的方式進行數據採集,如採樣率、聲道數量、編碼方式等;
QAudioFormat formatAudio;
formatAudio.setSampleRate(8000);//採樣頻率。8kHz(電話)、44.1kHz(CD)、48kHz(DVD)。
formatAudio.setChannelCount(1);//通道個數。常見的音頻有立體聲(stereo)和單聲道(mono)兩種類型,立體聲包含左聲道和右聲道。另外還有環繞立體聲等其它不太常用的類型。
formatAudio.setSampleSize(16);//量化位數。通常該值爲16-bit。
formatAudio.setCodec("audio/pcm");
formatAudio.setByteOrder(QAudioFormat::LittleEndian);
formatAudio.setSampleType(QAudioFormat::UnSignedInt);
- QAudioInput的主要寫入接口爲
void start(QIODevice *device);
QIODevice* start();
前者可以通過傳入QIODevice的指針,例如QFile或者QIODevice的子類,變可以獲取採集到的音頻數據。本例子通過繼承QIODevice,然後通過writeData()接口來獲取到音頻數據,後者則獲取到採集音頻的句柄,此時可以通過定時器或者按鈕信號,在必要的時候將數據進行處理。
使用QAudioInput調用如下
QAudioDeviceInfo inputDevices = QAudioDeviceInfo::defaultInputDevice();
m_audioInput.reset(new QAudioInput(inputDevices, formatAudio));
m_audioInput->start(this);
其中inputDevices是獲取錄音設備,這裏使用系統默認指定設備,如果有多個錄音設備的話,可以通過__QList availableDevices(QAudio::Mode mode) (QAudio::Mode mode)__獲取錄音設備。
qint64 DataSource::writeData(const char * data, qint64 maxSize)
{
m_audioData.append(data, maxSize);
return maxSize;
}
- 另外,如果我們在錄製音頻時想將音頻保存爲一個音頻文件,則需要將數據保存爲音頻文件,此時獲取的數據是音頻裸數據,也即PCM數據,所以這個時候我們把數據保存爲wav文件即可,也就是在這個PCM數據最前面給他寫入wav頭,關於wav文件的數據頭定義如下,一般爲44個字節。
struct WavFileHead
{
char RIFFNAME[4];
unsigned int nRIFFLength;
char WAVNAME[4];
char FMTNAME[4];
unsigned int nFMTLength;
unsigned short nAudioFormat;
unsigned short nChannleNumber;
unsigned int nSampleRate;
unsigned int nBytesPerSecond;
unsigned short nBytesPerSample;
unsigned short nBitsPerSample;
char DATANAME[4];
unsigned int nDataLength;
};
將採集參數填寫到wav數據頭
m_wavFileHead.nRIFFLength = 36;
m_wavFileHead.nFMTLength = sampleSize;
m_wavFileHead.nAudioFormat = 0x01;
m_wavFileHead.nChannleNumber = channels;//通道
m_wavFileHead.nSampleRate = sampleRate;//採樣頻率
m_wavFileHead.nBytesPerSecond = (sampleSize / 8) * channels * sampleRate;//播放頻率
m_wavFileHead.nBytesPerSample = (sampleSize / 8) * channels;
m_wavFileHead.nBitsPerSample = sampleSize;//量化位寬
m_wavFileHead.nDataLength = 0;//實際數據長度
最後寫入文件
QFile f("test.wav");
bool bisOk = f.open(QIODevice::WriteOnly);
if(bisOk == true)
{
m_wavFileHead.nDataLength = m_audioData.size();
f.write((char *)&m_wavFileHead, sizeof(WavFileHead));
f.write(m_audioData.data(), m_audioData.size());
f.close();
}else{
}
示例運行截圖
- 注: