2012-10-14 98 views
1

我正在讀C語言的.wav文件,然後嘗試使用某些QT函數播放音頻文件。這裏是我如何讀取文件:在C++和QT中播放wav音頻文件

FILE *fhandle=fopen("myAudioFile.wav","rb"); 
fread(ChunkID,1,4,fhandle); 
fread(&ChunkSize,4,1,fhandle); 
fread(Format,1,4,fhandle); 
fread(Subchunk1ID,1,4,fhandle); 
fread(&Subchunk1Size,4,1,fhandle); 
fread(&AudioFormat,2,1,fhandle); 
fread(&NumChannels,2,1,fhandle); 
fread(&SampleRate,4,1,fhandle); 
fread(&ByteRate,4,1,fhandle); 
fread(&BlockAlign,2,1,fhandle); 
fread(&BitsPerSample,2,1,fhandle); 
fread(&Subchunk2ID,1,4,fhandle); 
fread(&Subchunk2Size,4,1,fhandle); 
Data=new quint16 [Subchunk2Size/(BitsPerSample/8)]; 
fread(Data,BitsPerSample/8,Subchunk2Size/(BitsPerSample/8),fhandle); 
fclose(fhandle); 

所以我的音頻文件在Data裏面。 Data的每個元素都是無符號的16位整數。

要播放聲音,我將每個16位無符號整數分成兩個字符,然後每隔3毫秒(使用一個定時器),我發送256個字符到聲卡。 假設myData是256個字符的字符陣列I做到這一點(每3毫秒),以播放聲音:

m_output->write(myData, 256); 

另外m_output定義爲:

m_output = m_audioOutput->start(); 

m_audioOutput定義爲:

m_audioOutput = new QAudioOutput(m_Outputdevice, m_format, this); 

而音頻格式設置正確爲:

m_format.setFrequency(44100); 
m_format.setChannels(2); 
m_format.setSampleSize(16); 
m_format.setSampleType(QAudioFormat::UnSignedInt); 
m_format.setByteOrder(QAudioFormat::LittleEndian); 
m_format.setCodec("audio/pcm"); 

但是,當我嘗試運行代碼時,我聽到一些與真實音頻文件非常不同的噪音。 我有沒有做任何事情?

感謝, TJ

+0

你使用什麼樣的計時器? – Anthony

+0

有什麼特別的原因讓你以這種方式閱讀你的文件?否則,您可以使用簡單的方法:QSound :: play(「myAudioFile.wav」)或更好地使用QAudioOutput與QFile讀取,如文檔所示。 –

+0

@Anthony:這與我使用的計時器類型有關係嗎? – TJ1

回答

3

我認爲這個問題是您正在使用QTimer。 QTimer絕對不會允許您每隔三毫秒準確運行一次代碼,無論您使用的平臺如何。如果你只有一個樣本,你的音頻聽起來會很糟糕。根據QTimer docs

......他們不保證超時在指定的確切值。在很多情況下,它們可能會超時一段時間,而這一段時間取決於系統定時器的精度。

...在許多現實世界的情況下,定時器將不等於[1毫秒]的準確性。

就像我喜歡Qt一樣,我不會嘗試將它用於信號處理。我會使用另一個框架,如JUCE

+0

我想你是對的,最穩定的計時器是什麼? juce是否有精確的計時器? – TJ1

+0

我不認爲計時器是進行信號處理的方式。你不應該去那麼低的水平。無論如何,我會看看JUCE和[這裏](https://github.com/vinniefalco/DSPFilters)(一個使用JUCE的DSP類集合)。我也強烈推薦[PD](http://puredata.info/)。這是非常容易和非常強大的。 – Anthony