2009-09-20 63 views
4

我做在本土VC遊戲++(不是.NET)通過編程來制定和通過揚聲器C++

我正在尋找一種方式,通過發揮噪聲(也許8位或東西)播放聲音真正的揚聲器(不是內部)。我知道PlaySound,但我不想讓我的EXE變大。我想編程聲音。

是否有api的方式(有點像嗶聲()),但通過真正的揚聲器播放?

感謝

回答

10

你提到你知道的關於PlaySound。其中一個標誌(SND_MEMORY)將允許您播放已經加載到內存中的WAVE,即您自己創建的緩衝區。只要緩衝區具有適當的WAVE標頭,無論你放在哪裏,都應該通過揚聲器播放。

頭是一個44字節的塊是相當簡單的

struct WaveHeader 
{ 
    DWORD chunkID;  // 0x46464952 "RIFF" in little endian 
    DWORD chunkSize;  // 4 + (8 + subChunk1Size) + (8 + subChunk2Size) 
    DWORD format;  // 0x45564157 "WAVE" in little endian 

    DWORD subChunk1ID; // 0x20746d66 "fmt " in little endian 
    DWORD subChunk1Size; // 16 for PCM 
    WORD audioFormat; // 1 for PCM, 3 fot EEE floating point , 7 for μ-law 
    WORD numChannels; // 1 for mono, 2 for stereo 
    DWORD sampleRate; // 8000, 22050, 44100, etc... 
    DWORD byteRate;  // sampleRate * numChannels * bitsPerSample/8 
    WORD blockAlign; // numChannels * bitsPerSample/8 
    WORD bitsPerSample; // number of bits (8 for 8 bits, etc...) 

    DWORD subChunk2ID; // 0x61746164 "data" in little endian 
    DWORD subChunk2Size; // numSamples * numChannels * bitsPerSample/8 (this is the actual data size in bytes) 
}; 

你會設置你的緩衝區類似於:

char *myBuffer = new char[sizeof(WaveHeader) + myDataSize]; 

WaveHeader *header = (WaveHeader*)myBuffer; 
// fill out the header... 

char *data = myBuffer + sizeof(WaveHeader); //jumps to beginning of data 
// fill out waveform data... 

所以你使用它喜歡的東西:

PlaySound(myBuffer, NULL, SND_MEMORY | SND_ASYNC); 

我假設你將在你的應用程序的生命週期中使用你生成的聲音。如果不是,請小心該SND_ASYNC標誌。也就是說,在您調用PlaySound(當它仍在使用時)之後,請勿直接釋放緩衝區。

MSDN PlaySound Docs
A page with more detail on the WAV headerOLD - 現在不工作)

的DirectX還支持從內存緩衝區播放音頻,是一個更強大的API,但它或許矯枉過正,你需要做的:)

什麼
1

雖然對窗口有幾個可能性,最簡單的一個是sndPlaySound():

  • 包括mmsystem.h
  • 鏈接到winmm.lib
  • ::sndPlaySound("sound.wav", SND_ASYNC|SND_NODEFAULT);
  • 停止播放:::sndPlaySound(NULL, NULL);

當然還有其他的方法像MCI和直接的聲音可能滿足您的需求更好,如果你更清楚地看到你所需要的。

0

我的回答另一個問題可能是有益的,檢查出來here

我講一個易於使用具有類讀/寫WAV文件的開源API(The Synthesis Toolkit),和具有易於使用的包裝類,可以實時輸出到不同的驅動程序(wdm,asio,jack,...)

Imho它比winapi功能更容易使用