QtQuick音頻採集

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

示例運行截圖
QtQuick音頻採集

  • 注:
  1. 如果我們需要保存10s鐘的音頻即可,我們可以通過計算需要保存的數據長度,也即
    nDataLength = sampleRate(採樣頻率) * 10 * sampleSize(量化位寬)/ 8(char的大小),具體可參考PCM音頻數據,然後再writeData()接口判斷m_audioData的數據是否大於nDataLength,停止採集即可。

  2. 本例子使用QByteArray來保存數據,所以需要保存多長的數據,從QByteArray截取即可,此時也可以做網絡傳輸,也可以使用QAudioOutput進行數據播放。
    例子工程下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章