28 #include "../../idlib/precompiled.h"
36 #include "../../sound/snd_local.h"
39 #include "../../openal/idal.cpp"
41 #define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
42 #define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
43 #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
52 bool Lock(
void **pDSLockedBuffer,
ulong *dwDSLockedBufferSize );
53 bool Unlock(
void *pDSLockedBuffer,
dword dwDSLockedBufferSize );
67 int RestoreBuffer( LPDIRECTSOUNDBUFFER pDSB,
bool* pbWasRestored );
85 bool Lock(
void **pDSLockedBuffer,
ulong *dwDSLockedBufferSize );
86 bool Unlock(
void *pDSLockedBuffer,
dword dwDSLockedBufferSize );
93 bool Flush(
void ) {
return true; }
148 if( FAILED( hr = DirectSoundCreate(
NULL, &
m_pDS,
NULL ) )) {
163 if ( dwSpeakers == 2 ) {
164 WAVEFORMATEXTENSIBLE wfx;
165 ZeroMemory( &wfx,
sizeof(WAVEFORMATEXTENSIBLE) );
166 wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
167 wfx.Format.nChannels = 2;
168 wfx.Format.nSamplesPerSec = dwPrimaryFreq;
169 wfx.Format.wBitsPerSample = dwPrimaryBitRate;
170 wfx.Format.nBlockAlign = wfx.Format.wBitsPerSample / 8 * wfx.Format.nChannels;
171 wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
172 wfx.Format.cbSize =
sizeof(WAVEFORMATEX);
178 WAVEFORMATEXTENSIBLE waveFormatPCMEx;
179 ZeroMemory( &waveFormatPCMEx,
sizeof(WAVEFORMATEXTENSIBLE) );
181 waveFormatPCMEx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
182 waveFormatPCMEx.Format.nChannels = 6;
183 waveFormatPCMEx.Format.nSamplesPerSec = dwPrimaryFreq;
184 waveFormatPCMEx.Format.wBitsPerSample = dwPrimaryBitRate;
185 waveFormatPCMEx.Format.nBlockAlign = waveFormatPCMEx.Format.wBitsPerSample / 8 * waveFormatPCMEx.Format.nChannels;
186 waveFormatPCMEx.Format.nAvgBytesPerSec = waveFormatPCMEx.Format.nSamplesPerSec * waveFormatPCMEx.Format.nBlockAlign;
187 waveFormatPCMEx.dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
191 waveFormatPCMEx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
192 waveFormatPCMEx.Format.cbSize =
sizeof(WAVEFORMATEXTENSIBLE);
193 waveFormatPCMEx.Samples.wValidBitsPerSample = 16;
227 m_pDS->GetSpeakerConfig( &cfgSpeakers );
230 dscaps.dwSize =
sizeof(DSCAPS);
231 m_pDS->GetCaps(&dscaps);
233 if (dscaps.dwFlags & DSCAPS_EMULDRIVER) {
239 ZeroMemory( &dsbd,
sizeof(DSBUFFERDESC) );
240 dsbd.dwSize =
sizeof(DSBUFFERDESC);
241 dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
242 dsbd.dwBufferBytes = 0;
243 dsbd.lpwfxFormat =
NULL;
246 if( FAILED( hr =
m_pDS->SetCooperativeLevel(
win32.
hWnd, DSSCL_PRIORITY ) ) ) {
247 DXTRACE_ERR( TEXT(
"SetPrimaryBufferFormat"), hr );
255 if ( dwSpeakers == 6 && (cfgSpeakers == DSSPEAKER_5POINT1 || cfgSpeakers == DSSPEAKER_SURROUND) ) {
256 WAVEFORMATEXTENSIBLE waveFormatPCMEx;
257 ZeroMemory( &waveFormatPCMEx,
sizeof(WAVEFORMATEXTENSIBLE) );
259 waveFormatPCMEx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
260 waveFormatPCMEx.Format.nChannels = 6;
261 waveFormatPCMEx.Format.nSamplesPerSec = dwPrimaryFreq;
262 waveFormatPCMEx.Format.wBitsPerSample = (WORD) dwPrimaryBitRate;
263 waveFormatPCMEx.Format.nBlockAlign = waveFormatPCMEx.Format.wBitsPerSample / 8 * waveFormatPCMEx.Format.nChannels;
264 waveFormatPCMEx.Format.nAvgBytesPerSec = waveFormatPCMEx.Format.nSamplesPerSec * waveFormatPCMEx.Format.nBlockAlign;
265 waveFormatPCMEx.dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
269 waveFormatPCMEx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
270 waveFormatPCMEx.Format.cbSize =
sizeof(WAVEFORMATEXTENSIBLE);
271 waveFormatPCMEx.Samples.wValidBitsPerSample = 16;
273 if( FAILED( hr =
pDSBPrimary->SetFormat((WAVEFORMATEX*)&waveFormatPCMEx) ) ) {
274 DXTRACE_ERR( TEXT(
"SetPrimaryBufferFormat"), hr );
278 blockAlign = waveFormatPCMEx.Format.nBlockAlign;
280 if (dwSpeakers == 6) {
281 common->
Printf(
"sound: hardware reported unable to use multisound, defaulted to stereo\n");
284 ZeroMemory( &wfx,
sizeof(WAVEFORMATEX) );
285 wfx.wFormatTag = WAVE_FORMAT_PCM;
287 wfx.nSamplesPerSec = dwPrimaryFreq;
288 wfx.wBitsPerSample = (WORD) dwPrimaryBitRate;
289 wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels;
290 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
291 wfx.cbSize =
sizeof(WAVEFORMATEX);
293 if( FAILED( hr =
pDSBPrimary->SetFormat(&wfx) ) ) {
314 const char* strWaveFileName,
315 dword dwCreationFlags ) {
317 LPDIRECTSOUNDBUFFER apDSBuffer =
NULL;
323 if( strWaveFileName ==
NULL || ppSound ==
NULL )
328 pWaveFile->
Open( strWaveFileName,
NULL );
343 memset( &dsbd, 0,
sizeof(DSBUFFERDESC) );
344 dsbd.dwSize =
sizeof(DSBUFFERDESC);
345 dsbd.dwFlags = dwCreationFlags;
346 dsbd.dwBufferBytes = dwDSBufferSize;
347 dsbd.guid3DAlgorithm = GUID_NULL;
348 dsbd.lpwfxFormat = (WAVEFORMATEX*)&pWaveFile->
mpwfx;
352 if( FAILED( hr =
m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer,
NULL ) ) )
375 LPDIRECTSOUNDBUFFER apDSBuffer =
NULL;
381 if( pWaveFile ==
NULL )
399 memset( &dsbd, 0,
sizeof(DSBUFFERDESC) );
400 dsbd.dwSize =
sizeof(DSBUFFERDESC);
402 dsbd.dwBufferBytes = dwDSBufferSize;
403 dsbd.guid3DAlgorithm = GUID_NULL;
404 dsbd.lpwfxFormat = (WAVEFORMATEX*)&pWaveFile->
mpwfx;
408 if( FAILED( hr =
m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer,
NULL ) ) )
430 dword dwCreationFlags ) {
432 LPDIRECTSOUNDBUFFER apDSBuffer =
NULL;
438 if( pbData ==
NULL || ppSound ==
NULL )
447 dwDSBufferSize = ulDataSize;
453 memset( &dsbd, 0,
sizeof(DSBUFFERDESC) );
454 dsbd.dwSize =
sizeof(DSBUFFERDESC);
455 dsbd.dwFlags = dwCreationFlags | DSBCAPS_GETCURRENTPOSITION2;
456 dsbd.dwBufferBytes = dwDSBufferSize;
457 dsbd.guid3DAlgorithm = GUID_NULL;
458 dsbd.lpwfxFormat = (WAVEFORMATEX *)pwfx;
460 if( FAILED( hr =
m_pDS->CreateSoundBuffer( &dsbd, &apDSBuffer,
NULL ) ) )
476 return speakers->
Lock( pDSLockedBuffer, dwDSLockedBufferSize );
505 static HMODULE hOpenAL =
NULL;
527 FreeLibrary( hOpenAL );
544 FreeLibrary( hOpenAL );
587 void* pDSLockedBuffer =
NULL;
588 ulong dwDSLockedBufferSize = 0;
589 int dwWavDataRead = 0;
602 DXTRACE_ERR( TEXT(
"RestoreBuffer"), hr );
608 DXTRACE_ERR( TEXT(
"Lock"), hr );
615 if( FAILED( hr =
m_pWaveFile->
Read( (
byte*) pDSLockedBuffer, dwDSLockedBufferSize, &dwWavDataRead ) ) ) {
616 return DXTRACE_ERR( TEXT(
"Read"), hr );
619 if( dwWavDataRead == 0 ) {
622 }
else if( dwWavDataRead < (
int)dwDSLockedBufferSize ) {
625 if( bRepeatWavIfBufferLarger ) {
627 int dwReadSoFar = dwWavDataRead;
628 while( dwReadSoFar < (
int)dwDSLockedBufferSize ) {
632 return DXTRACE_ERR( TEXT(
"ResetFile"), hr );
635 hr =
m_pWaveFile->
Read( (
byte*)pDSLockedBuffer + dwReadSoFar, dwDSLockedBufferSize - dwReadSoFar, &dwWavDataRead );
637 return DXTRACE_ERR( TEXT(
"Read"), hr );
640 dwReadSoFar += dwWavDataRead;
649 pDSB->Unlock( pDSLockedBuffer, dwDSLockedBufferSize,
NULL, 0 );
667 if( pbWasRestored ) {
668 *pbWasRestored =
false;
672 if( FAILED( hr = pDSB->GetStatus( &dwStatus ) ) ) {
673 return DXTRACE_ERR( TEXT(
"GetStatus"), hr );
676 if( dwStatus & DSBSTATUS_BUFFERLOST ) {
682 hr = pDSB->Restore();
683 if( hr == DSERR_BUFFERLOST ) {
686 hr = pDSB->Restore();
689 if( pbWasRestored !=
NULL ) {
690 *pbWasRestored =
true;
779 if ( dwStatus & DSBSTATUS_PLAYING ) {
828 DXTRACE_ERR( TEXT(
"RestoreBuffer"), hr );
832 if( FAILED( hr =
m_apDSBuffer->GetCurrentPosition(
NULL, pdwCurrentWriteCursor ) ) ) {
waveformatextensible_t mpwfx
bool Sys_LoadOpenAL(void)
bool Lock(void **pDSLockedBuffer, ulong *dwDSLockedBufferSize)
static idCVar s_numberOfSpeakers
const int MIXBUFFER_SAMPLES
void Sys_FreeOpenAL(void)
int FillBufferWithSound(LPDIRECTSOUNDBUFFER pDSB, bool bRepeatWavIfBufferLarger)
static idCVar s_libOpenAL
LPDIRECTSOUNDBUFFER pDSBPrimary
bool GetCurrentPosition(ulong *pdwCurrentWriteCursor)
void Sleep(const int time)
const char * InitializeIDAL(HMODULE h)
int Open(const char *strFileName, waveformatex_t *pwfx=NULL)
bool GetCurrentPosition(ulong *pdwCurrentWriteCursor)
const int ROOM_SLICES_IN_BUFFER
int Create(idWaveFile *pWaveFile, idAudioBuffer **ppiab)
int OpenFromMemory(short *pbData, int ulDataSize, waveformatextensible_t *pwfx)
int GetNumberOfSpeakers()
short * GetMixBuffer(void)
bool Unlock(void *pDSLockedBuffer, dword dwDSLockedBufferSize)
int Play(dword dwPriority=0, dword dwFlags=0)
int Read(byte *pBuffer, int dwSizeToRead, int *pdwSizeRead)
virtual void Printf(const char *fmt,...) id_attribute((format(printf
bool Lock(void **pDSLockedBuffer, ulong *dwDSLockedBufferSize)
bool IsSoundPlaying(void)
int CreateFromMemory(idAudioBufferWIN32 **ppSound, byte *pbData, ulong ulDataSize, waveformatextensible_t *pwfx, dword dwCreationFlags=0)
bool InitializeSpeakers(byte *buffer, int bufferSize, dword dwPrimaryFreq, dword dwPrimaryBitRate, dword dwSpeakers)
LPCSTR GetString(LPCSTR psPrompt)
idAudioBufferWIN32 * speakers
int RestoreBuffer(LPDIRECTSOUNDBUFFER pDSB, bool *pbWasRestored)
LPDIRECTSOUNDBUFFER m_apDSBuffer
void * Mem_Alloc(const int size)
void SetPrimaryBufferFormat(dword dwPrimaryFreq, dword dwPrimaryBitRate, dword dwSpeakers)
static idAudioHardware * Alloc()
virtual void Error(const char *fmt,...) id_attribute((format(printf
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
bool Unlock(void *pDSLockedBuffer, dword dwDSLockedBufferSize)
idAudioBufferWIN32(LPDIRECTSOUNDBUFFER apDSBuffer, dword dwDSBufferSize, idWaveFile *pWaveFile=NULL)
virtual ~idAudioHardware()
LPDIRECTSOUND IUnknown FAR *typedef HRESULT(FAR PASCAL *LPEAXDIRECTSOUNDCREATE)(GUID *