SNDOBJ *SndObjCreate(IDirectSound *pDS, LPCTSTR lpName, int iConcurrent) { SNDOBJ *pSO = NULL; LPWAVEFORMATEX pWaveHeader; BOOL fFound = FALSE; BYTE *pbData; DWORD cbData; void *pvBase; if (DSGetWaveResource(NULL, lpName, &pWaveHeader, &pbData, &cbData)) fFound = TRUE; if (DSGetWaveFile(NULL, lpName, &pWaveHeader, &pbData, &cbData, &pvBase)) { fFound = TRUE; UnmapViewOfFile( pvBase ); } if( fFound ) { if (iConcurrent < 1) iConcurrent = 1; if ((pSO = (SNDOBJ *)LocalAlloc(LPTR, sizeof(SNDOBJ) + (iConcurrent-1) * sizeof(IDirectSoundBuffer *))) != NULL) { int i; pSO->iAlloc = iConcurrent; pSO->pbWaveData = pbData; pSO->cbWaveSize = cbData; pSO->Buffers[0] = DSLoadSoundBuffer(pDS, lpName); for (i=1; i<pSO->iAlloc; i++) { if (FAILED(IDirectSound_DuplicateSoundBuffer(pDS, pSO->Buffers[0], &pSO->Buffers[i]))) { pSO->Buffers[i] = DSLoadSoundBuffer(pDS, lpName); if (!pSO->Buffers[i]) { SndObjDestroy(pSO); pSO = NULL; break; } } } } } return pSO; }
SNDOBJ *SndObjCreate(IDirectSound *pDS, char *lpName, int sfx_flags , DWORD buf_flags, int sfx) { SNDOBJ *pSO = NULL; void * Buffer = NULL; int i; HRESULT hres; DSBCAPS dsbcaps; #if 0 // needed for locking sound buffer LPVOID lpvAudioPtr1; DWORD dwAudioBytes1; LPVOID lpvAudioPtr2; DWORD dwAudioBytes2; DWORD dwFlags = DSBLOCK_ENTIREBUFFER; #endif pSO = (SNDOBJ *)malloc(sizeof(SNDOBJ)); if ( !FreeHWBuffers ) buf_flags |= DSBCAPS_LOCSOFTWARE; if (pSO != NULL) { memset( pSO, 0, sizeof(SNDOBJ) ); pSO->Dup_Buffer[0] = NULL; pSO->CompoundBuffer = FALSE; pSO->looping_sfx_index[0] = -1; // if sound is already loaded into HW... if ( ( IS_COMPOUND( sfx_flags ) ) && CompoundSfxAllocated[sfx] ) { pSO->CompoundBuffer = TRUE; for (i = 0; i < MAX_DUP_BUFFERS; i++) pSO->CompoundBufferLookup[i] = -1; }else { if ( A3DCapable ) { pSO->Dup_Buffer[0] = DSLoad3DSoundBuffer(pDS, lpName, &pSO->Dup_3DBuffer[0], buf_flags ); }else { // create buffer. Will create in hw if available, since only 16 channels have been used for compound sfx if( buf_flags & DSBCAPS_CTRL3D ) { pSO->Dup_Buffer[0] = DSLoad3DSoundBuffer(pDS, lpName, &pSO->Dup_3DBuffer[0], buf_flags ); }else{ pSO->Dup_Buffer[0] = DSLoadSoundBuffer(pDS, lpName, buf_flags ); } } if( !pSO->Dup_Buffer[ 0 ] ) { Msg("Unable to create sound buffer for %s\n", lpName ); InvalidateBuffers( pSO ); return pSO; } // get caps of buffer memset( &dsbcaps, 0, sizeof( DSBCAPS ) ); dsbcaps.dwSize = sizeof( DSBCAPS ); IDirectSoundBuffer_GetCaps( pSO->Dup_Buffer[ 0 ], &dsbcaps ); if ( dsbcaps.dwFlags & DSBCAPS_LOCHARDWARE ) { //DebugPrintf("creating %s in hardware\n", lpName ); }else { //DebugPrintf("creating %s in software\n", lpName ); #if 0 // lock buffer IDirectSoundBuffer_Lock( pSO->Dup_Buffer[ 0 ], 0, 0, &lpvAudioPtr1, &dwAudioBytes1, &lpvAudioPtr2, &dwAudioBytes2, dwFlags ); // make non-volatile MakeRegionPresent( ( BYTE * )lpvAudioPtr1, (UINT)dwAudioBytes1 ); // unlock buffer IDirectSoundBuffer_Unlock( pSO->Dup_Buffer[ 0 ], lpvAudioPtr1, 0, lpvAudioPtr2, 0 ); #endif } // if buffer in hw, should check free channels here, but Ensoniq driver always reports back 256 // so we will just have to try duplicating until failure for (i = 1; i < MAX_DUP_BUFFERS; i++) { pSO->looping_sfx_index[i] = -1; // duplicate 2D buffer... if ( !SoundBufferDuplicate( pDS, pSO->Dup_Buffer[0], &pSO->Dup_Buffer[i]) ) { DebugPrintf("unable to duplicate sound buffer\n"); // invalidate buffer & all duplicates InvalidateBuffers( pSO ); // was original buffer hw? if so, try to recreate in sw if ( dsbcaps.dwFlags & DSBCAPS_LOCHARDWARE ) { DebugPrintf("trying to recreate in sw\n"); FreeHWBuffers = FALSE; // recreate all buffers up to & including this one in software if( buf_flags & DSBCAPS_CTRL3D ) { pSO->Dup_Buffer[ 0 ] = DSLoad3DSoundBuffer(pDS, lpName, &pSO->Dup_3DBuffer[ 0 ], buf_flags | DSBCAPS_LOCSOFTWARE ); }else{ pSO->Dup_Buffer[ 0 ] = DSLoadSoundBuffer(pDS, lpName, buf_flags | DSBCAPS_LOCSOFTWARE ); } if( !pSO->Dup_Buffer[ 0 ] ) { Msg("Unable to create sound buffer for %s\n", lpName ); InvalidateBuffers( pSO ); return pSO; } i = 0; continue; }else { // couldn't duplicate buffer in sw - just break out with buffer info still marked as invalid Msg("unable to duplicate buffers in sw\n"); break; } } // query for 3D interface if we are using 3D... if ( pSO->Dup_3DBuffer[0] ) { hres = IDirectSoundBuffer_QueryInterface(pSO->Dup_Buffer[i], &IID_IDirectSound3DBuffer, &pSO->Dup_3DBuffer[i]); } } } } return pSO; }