上一篇文章講到了音頻採集,既然有了採集,也就需要將音頻數據進行播放,當然也可以讀取音頻文件或接收網絡音頻數據進行播放,這個時候就要用到QAudioInput的平行類QAudioOutput,QAudioOuput的使用和QAudioInput差不多,同樣需要設置音頻的參數,指定播放的設備(QAudioDeviceInfo),指定播放的數據緩衝(QIODevice)
下面說一下一些使用的差別
- 設置音頻的參數需要和錄音時設定的參數一樣,也即在錄音時設置什麼參數,在播放時就必須設置一樣的參數
- 獲取播放設備還是通過QAudioDeviceInfo,具體請看接口__QAudioDeviceInfo::defaultOutputDevice()或__QList availableDevices(QAudio::Mode mode)
以上兩點如下
void DataSource::startPlay()
{
QAudioFormat format;
format.setSampleRate(16000);
format.setChannelCount(2);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt);
auto device = QAudioDeviceInfo::defaultOutputDevice();
m_audioOutput.reset(new QAudioOutput(device, format));
m_audioOutput->start(this);
}
- 與錄音時在QIODevice接口writeData()接收數據相反,需要在readData()提供數據給播放數據:
qint64 DataSource::readData(char * data, qint64 maxSize)
{
qint64 total = 0;
auto chunk = qMin(((qint64)m_audioData.size() - m_readPos), maxSize);
memcpy(data + total, m_audioData.data() + m_readPos, chunk);
m_readPos = m_readPos + chunk;
total += chunk;
return total;
}
maxSize是說一次最多隻能讀取多少數據到播音設備的緩存中,這個時候用m_readPos記錄每一次讀取了多少數據,再用memcpy將需要播放的數據複製到data中,最後返回實際讀取的數據
- 本文的例程是在上篇文章的基礎上做的,例程效果圖
注:
- QAudioOutput其他接口的時候和一般的音視頻播放差不多,比如提供了暫停,停止,設置音量等接口,此外,還有一些通知的接口__setNotifyInterval(int ms)__,具體參考Qt文檔。
- 執行過程爲開始錄音——停止錄音——開始播放——停止播放。
- 如將wav文件進行播放,則可以通過讀取wav的文件頭到header裏,後面的數據即爲PCM數據,將讀取到header結構體設置到QAudioFormat即可
Edited:
使用QAudioOutput播放音頻,如果不需要定製需求,我們也可以使用QBuffer,同樣繼承自QIODevice,但是就不需要重寫readData()接口。