void DSound::SetPrimaryBufferMode() { #ifndef _XBOX DSBUFFERDESC format; memset( &format, 0, sizeof(format) ); format.dwSize = sizeof(format); format.dwFlags = DSBCAPS_PRIMARYBUFFER; format.dwBufferBytes = 0; format.lpwfxFormat = NULL; IDirectSoundBuffer *pBuffer; HRESULT hr = this->GetDS()->CreateSoundBuffer( &format, &pBuffer, NULL ); /* hr */ if( FAILED(hr) ) { LOG->Warn(hr_ssprintf(hr, "Couldn't create primary buffer")); return; } WAVEFORMATEX waveformat; memset( &waveformat, 0, sizeof(waveformat) ); waveformat.cbSize = 0; waveformat.wFormatTag = WAVE_FORMAT_PCM; waveformat.wBitsPerSample = 16; waveformat.nChannels = 2; waveformat.nSamplesPerSec = 44100; waveformat.nBlockAlign = 4; waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec * waveformat.nBlockAlign; // Set the primary buffer's format hr = IDirectSoundBuffer_SetFormat( pBuffer, &waveformat ); if( FAILED(hr) ) LOG->Warn( hr_ssprintf(hr, "SetFormat on primary buffer") ); DWORD got; hr = pBuffer->GetFormat( &waveformat, sizeof(waveformat), &got ); if( FAILED(hr) ) LOG->Warn( hr_ssprintf(hr, "GetFormat on primary buffer") ); else if( waveformat.nSamplesPerSec != 44100 ) LOG->Warn( "Primary buffer set to %i instead of 44100", waveformat.nSamplesPerSec ); /* MS docs: * * When there are no sounds playing, DirectSound stops the mixer engine and halts DMA * (direct memory access) activity. If your application has frequent short intervals of * silence, the overhead of starting and stopping the mixer each time a sound is played * may be worse than the DMA overhead if you kept the mixer active. Also, some sound * hardware or drivers may produce unwanted audible artifacts from frequent starting and * stopping of playback. If your application is playing audio almost continuously with only * short breaks of silence, you can force the mixer engine to remain active by calling the * IDirectSoundBuffer::Play method for the primary buffer. The mixer will continue to run * silently. * * However, I just added the above code and I don't want to change more until it's tested. */ // pBuffer->Play( 0, 0, DSBPLAY_LOOPING ); pBuffer->Release(); #endif }
void SoundLibrary3dDirectSound::SetChannelVolume( int _channel, float _volume ) { DirectSoundChannel *channel; if (_channel == m_musicChannelId) channel = m_musicChannel; else channel = &m_channels[_channel]; if (!NearlyEquals(_volume, channel->m_volume) || m_forceVolumeUpdate ) { AppDebugAssert(_volume >= 0.0f && _volume <= 10.0f); channel->m_volume = _volume; // long calculatedVolume = expf(10.0f - _volume); // calculatedVolume += m_masterVolume; // calculatedVolume *= -1.0f; float calculatedVolume = -(5.0f - _volume * 0.5f); calculatedVolume *= 1000.0f; calculatedVolume += m_masterVolume; if( calculatedVolume < -10000.0f ) calculatedVolume = -10000.0f; if( calculatedVolume > 0.0f ) calculatedVolume = 0.0f; IDirectSoundBuffer *buffer = channel->m_bufferInterface; int errCode = buffer->SetVolume( calculatedVolume ); if (errCode == DSERR_BUFFERLOST) buffer->Restore(); else SOUNDASSERT( errCode, "Direct sound couldn't set buffer volume" ); } }
int DSoundAudioBackend::RunThread() { if (FAILED(DirectSoundCreate8(0, &ds_, 0))) { ds_ = NULL; threadData_ = 2; return 1; } ds_->SetCooperativeLevel(window_, DSSCL_PRIORITY); if (!CreateBuffer()) { ds_->Release(); ds_ = NULL; threadData_ = 2; return 1; } soundSyncEvent_ = CreateEvent(0, false, false, 0); InitializeCriticalSection(&soundCriticalSection); DWORD num1; short *p1; dsBuffer_->Lock(0, bufferSize_, (void **)&p1, &num1, 0, 0, 0); memset(p1, 0, num1); dsBuffer_->Unlock(p1, num1, 0, 0); totalRenderedBytes_ = -bufferSize_; setCurrentThreadName("DSound"); currentPos_ = 0; lastPos_ = 0; dsBuffer_->Play(0,0,DSBPLAY_LOOPING); while (!threadData_) { EnterCriticalSection(&soundCriticalSection); dsBuffer_->GetCurrentPosition((DWORD *)¤tPos_, 0); int numBytesToRender = RoundDown128(ModBufferSize(currentPos_ - lastPos_)); if (numBytesToRender >= 256) { int numBytesRendered = 4 * (*callback_)(realtimeBuffer_, numBytesToRender >> 2, 16, 44100, 2); //We need to copy the full buffer, regardless of what the mixer claims to have filled //If we don't do this then the sound will loop if the sound stops and the mixer writes only zeroes numBytesRendered = numBytesToRender; WriteDataToBuffer(lastPos_, (char *) realtimeBuffer_, numBytesRendered); currentPos_ = ModBufferSize(lastPos_ + numBytesRendered); totalRenderedBytes_ += numBytesRendered; lastPos_ = currentPos_; } LeaveCriticalSection(&soundCriticalSection); WaitForSingleObject(soundSyncEvent_, MAXWAIT); }
/// @brief Open stream /// void DirectSoundPlayer::OpenStream() { // Get provider AudioProvider *provider = GetProvider(); // Initialize the DirectSound object HRESULT res; res = DirectSoundCreate8(&DSDEVID_DefaultPlayback,&directSound,NULL); // TODO: support selecting audio device if (FAILED(res)) throw _T("Failed initializing DirectSound"); // Set DirectSound parameters AegisubApp *app = (AegisubApp*) wxTheApp; directSound->SetCooperativeLevel((HWND)app->frame->GetHandle(),DSSCL_PRIORITY); // Create the wave format structure WAVEFORMATEX waveFormat; waveFormat.wFormatTag = WAVE_FORMAT_PCM; waveFormat.nSamplesPerSec = provider->GetSampleRate(); waveFormat.nChannels = provider->GetChannels(); waveFormat.wBitsPerSample = provider->GetBytesPerSample() * 8; waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8; waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; waveFormat.cbSize = sizeof(waveFormat); // Create the buffer initializer int aim = waveFormat.nAvgBytesPerSec * 15/100; // 150 ms buffer int min = DSBSIZE_MIN; int max = DSBSIZE_MAX; bufSize = std::min(std::max(min,aim),max); DSBUFFERDESC desc; desc.dwSize = sizeof(DSBUFFERDESC); desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS; desc.dwBufferBytes = bufSize; desc.dwReserved = 0; desc.lpwfxFormat = &waveFormat; desc.guid3DAlgorithm = GUID_NULL; // Create the buffer IDirectSoundBuffer *buf; res = directSound->CreateSoundBuffer(&desc,&buf,NULL); if (res != DS_OK) throw _T("Failed creating DirectSound buffer"); // Copy interface to buffer res = buf->QueryInterface(IID_IDirectSoundBuffer8,(LPVOID*) &buffer); if (res != S_OK) throw _T("Failed casting interface to IDirectSoundBuffer8"); // Set data offset = 0; }
bool DSoundAudioBackend::CreateBuffer() { PCMWAVEFORMAT pcmwf; DSBUFFERDESC dsbdesc; memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT)); memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); bufferSize_ = BUFSIZE; pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM; pcmwf.wf.nChannels = 2; pcmwf.wf.nSamplesPerSec = sampleRate_; pcmwf.wf.nBlockAlign = 4; pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign; pcmwf.wBitsPerSample = 16; dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS; // //DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; dsbdesc.dwBufferBytes = bufferSize_; //FIX32(pcmwf.wf.nAvgBytesPerSec); //change to set buffer size dsbdesc.lpwfxFormat = (WAVEFORMATEX *)&pcmwf; if (SUCCEEDED(ds_->CreateSoundBuffer(&dsbdesc, &dsBuffer_, NULL))) { dsBuffer_->SetCurrentPosition(0); return true; } else { dsBuffer_ = NULL; return false; } }
//----------------------------------------------------------------------------- // Name: CSound::Play3D() // Desc: Plays the sound using voice management flags. Pass in DSBPLAY_LOOPING // in the dwFlags to loop the sound //----------------------------------------------------------------------------- HRESULT CSound::Play3D( LPDS3DBUFFER p3DBuffer, DWORD dwPriority, DWORD dwFlags, LONG lFrequency ) { HRESULT hr; BOOL bRestored; DWORD dwBaseFrequency; if( m_apDSBuffer == NULL ) return CO_E_NOTINITIALIZED; IDirectSoundBuffer* pDSB = GetFreeBuffer(); if( pDSB == NULL ) return DXTRACE_ERR( TEXT("GetFreeBuffer"), E_FAIL ); // Restore the buffer if it was lost if( FAILED( hr = RestoreBuffer( pDSB, &bRestored ) ) ) return DXTRACE_ERR( TEXT("RestoreBuffer"), hr ); if( bRestored ) { // The buffer was restored, so we need to fill it with new data if( FAILED( hr = FillBufferWithSound( pDSB, FALSE ) ) ) return DXTRACE_ERR( TEXT("FillBufferWithSound"), hr ); } if( m_dwCreationFlags & DSBCAPS_CTRLFREQUENCY ) { pDSB->GetFrequency( &dwBaseFrequency ); pDSB->SetFrequency( dwBaseFrequency + lFrequency ); } // QI for the 3D buffer IDirectSound3DBuffer* pDS3DBuffer; hr = pDSB->QueryInterface( IID_IDirectSound3DBuffer, (VOID**) &pDS3DBuffer ); if( SUCCEEDED( hr ) ) { hr = pDS3DBuffer->SetAllParameters( p3DBuffer, DS3D_IMMEDIATE ); if( SUCCEEDED( hr ) ) { hr = pDSB->Play( 0, dwPriority, dwFlags ); } pDS3DBuffer->Release(); } return hr; }
HRESULT NatsumeSound::LoadSoundWave(TCHAR *_FileName) { // Waveファイルオープン WAVEFORMATEX wFmt; char *pWaveData = 0; DWORD WaveSize = 0; if(FAILED( OpenWave(_FileName,wFmt,&pWaveData,WaveSize) )) { Error("Waveファイルのロードに失敗しました。"); return E_FAIL; } DSBUFFERDESC DSBufferDesc; DSBufferDesc.dwSize = sizeof(DSBUFFERDESC); DSBufferDesc.dwFlags = 0; DSBufferDesc.dwBufferBytes = WaveSize; DSBufferDesc.dwReserved = 0; DSBufferDesc.lpwfxFormat = &wFmt; DSBufferDesc.guid3DAlgorithm = GUID_NULL; IDirectSoundBuffer *ptmpBuf = 0; LpDirectSound->CreateSoundBuffer( &DSBufferDesc, &ptmpBuf, NULL ); ptmpBuf->QueryInterface( IID_IDirectSoundBuffer8 ,(void**)&SoundDataBuffer[SoundDataBufferNextKey] ); ptmpBuf->Release(); if ( SoundDataBuffer[SoundDataBufferNextKey] == 0 ) { //pDS8->Release(); return E_FAIL; } // セカンダリバッファにWaveデータ書き込み LPVOID lpvWrite = 0; DWORD dwLength = 0; if ( DS_OK == SoundDataBuffer[SoundDataBufferNextKey]->Lock( 0, 0, &lpvWrite, &dwLength, NULL, NULL, DSBLOCK_ENTIREBUFFER ) ) { memcpy( lpvWrite, pWaveData, dwLength); SoundDataBuffer[SoundDataBufferNextKey]->Unlock( lpvWrite, dwLength, NULL, 0); } delete[] pWaveData; // 元音はもういらない return S_OK; }
void Window::CreateSoundBuffer(void) { //Fill in structures describing the sound buffer WAVEFORMATEX bufferFormat = {0}; bufferFormat.wFormatTag = WAVE_FORMAT_PCM; bufferFormat.nChannels = 2; bufferFormat.nSamplesPerSec = 44100; bufferFormat.wBitsPerSample = 16; bufferFormat.nBlockAlign = bufferFormat.nChannels * bufferFormat.wBitsPerSample / 8; bufferFormat.nAvgBytesPerSec= bufferFormat.nSamplesPerSec * bufferFormat.nBlockAlign; DSBUFFERDESC bufferDesc = {0}; bufferDesc.dwSize = sizeof(DSBUFFERDESC); bufferDesc.dwFlags = DSBCAPS_GLOBALFOCUS; bufferDesc.dwBufferBytes = bufferFormat.nAvgBytesPerSec; bufferDesc.lpwfxFormat = &bufferFormat; //Create an IDirectSoundBuffer IDirectSoundBuffer * tempSoundBuffer; if(FAILED(directSound->CreateSoundBuffer(&bufferDesc, &tempSoundBuffer, 0))) throw Ex("Window Error: directSound->CreateSoundBuffer failed"); //Promote to an IDirectSoundBuffer8 if(FAILED(tempSoundBuffer->QueryInterface( IID_IDirectSoundBuffer8, reinterpret_cast<LPVOID *>(&soundBuffer)))) { throw Ex("Window Error: tempSoundBuffer->QueryInterface failed"); } //Release the temporary sound buffer tempSoundBuffer->Release(); //Zero the contents of the sound buffer Dword numSoundBufferBytes; void * soundBufferDataPtr; if(FAILED(soundBuffer->Lock(0, 0, &soundBufferDataPtr, &numSoundBufferBytes, 0, 0, DSBLOCK_ENTIREBUFFER))) throw Ex("Window Error: soundBuffer->Lock failed"); ZeroMemory(soundBufferDataPtr, numSoundBufferBytes); if(FAILED(soundBuffer->Unlock(soundBufferDataPtr, numSoundBufferBytes, 0, 0))) throw Ex("Window Error: soundBuffer->Unlock failed"); }
void SoundLibrary3dDirectSound::SetChannelFrequency( int _channel, int _frequency ) { DirectSoundChannel *channel; if (_channel == m_musicChannelId) channel = m_musicChannel; else channel = &m_channels[_channel]; if (channel->m_freq != _frequency) { channel->m_freq = _frequency; IDirectSoundBuffer *buffer = channel->m_bufferInterface; int errCode = buffer->SetFrequency( _frequency ); if (errCode == DSERR_BUFFERLOST) buffer->Restore(); else SOUNDASSERT( errCode, "Direct sound couldn't set channel frequency" ); } }
void as_Sound::SetPitch(float pitch) { // set volume in hundredth of Decibel from 0 (full volume) to -9600 (silence) long volume; HRESULT hr; // Get the 3D buffer in the audio path. IDirectSoundBuffer *myBuffer = NULL; hr = this->pAudioPath->GetObjectInPath( 0, DMUS_PATH_BUFFER, 0, GUID_NULL, 0, IID_IDirectSoundBuffer, (LPVOID *)&myBuffer); if (FAILED(hr)) { AddLogMsg("Error: GetObjectInPath"); return; } //this->pDS3DBuffer->QueryInterface(IID_IDirectSoundBuffer,(LPVOID *)&myBuffer); if (myBuffer) { myBuffer->SetFrequency(pitch); } /* if (true == looping) { MUSIC_TIME mtLength; hr = pSegment->GetLength(&mtLength); hr = pSegment->SetLoopPoints(0, mtLength/44000*22000); if (S_OK != hr) { char msg[128]; sprintf(msg, "SetLoopPoints error 0x%08lX", hr); AddLogMsg(msg); } this->pSegment->SetRepeats(DMUS_SEG_REPEAT_INFINITE); } else this->pSegment->SetRepeats(0);*/ }
int CSound::Play(DWORD position_ms, bool isLoop) { if(!m_pSecondaryBuffer) return CS_E_NULL_SECONDARY; m_isLoop = isLoop; if(m_isStreamFile){ //OpenStreamThread(); //if(IsPlaying()){ //PostThreadMessage(m_dwThreadId, CSL_MSG_SEEK_AND_PLAY, (DWORD)(position_ms * ((double)m_wfx.nAvgBytesPerSec/1000.0)), 0); PostThreadMessage(m_dwThreadId, CSL_MSG_SEEK_AND_PLAY, position_ms, 0); WaitForSingleObject(m_hThreadMessageDispatchEvent, INFINITE); //this->SetStreamCurosr((DWORD)(position_ms * ((double)m_wfx.nAvgBytesPerSec/1000.0))); //} //m_pSecondaryBuffer->Play(0, 0, DSBPLAY_LOOPING); }else{ IDirectSoundBuffer* pBuffer = NULL; if(m_nDuplicateLimit > 0){ //セカンダリバッファのコピーを使う int id = GetInactiveBufferNo();//使用中でないバッファのインデックスを取得 if(id == -1) return CS_E_NOCANDO; pBuffer = m_ppDuplicatedBuffer[id]; }else{ if( !m_isAllowRapidAccess ){ DWORD dwStatus; m_pSecondaryBuffer->GetStatus( &dwStatus ); bool isSecondaryPlaying = (dwStatus & DSBSTATUS_PLAYING); if( isSecondaryPlaying ){ /* nop */ }else{ pBuffer = m_pSecondaryBuffer; } }else{ pBuffer = m_pSecondaryBuffer; } } if( !pBuffer ){ /* nop */ }else{ pBuffer->SetCurrentPosition( (DWORD)((double)position_ms * (double)(m_wfx.nAvgBytesPerSec/1000.0)) ); pBuffer->Play(0, 0, isLoop ? DSBPLAY_LOOPING : 0); //m_pSecondaryBuffer->Play(0, 0, m_isStreamFile ? DSBPLAY_LOOPING : isLoop ? DSBPLAY_LOOPING : 0); } } return CS_E_OK; }
//----------------------------------------------------------------------------- // Name: CSound::Play() // Desc: Plays the sound using voice management flags. Pass in DSBPLAY_LOOPING // in the dwFlags to loop the sound //----------------------------------------------------------------------------- HRESULT CSound::Play( DWORD dwPriority, DWORD dwFlags, LONG lVolume, LONG lFrequency, LONG lPan ) { HRESULT hr; BOOL bRestored; if( m_apDSBuffer == NULL ) return CO_E_NOTINITIALIZED; IDirectSoundBuffer* pDSB = GetFreeBuffer(); if( pDSB == NULL ) return DXTRACE_ERR( TEXT("GetFreeBuffer"), E_FAIL ); // Restore the buffer if it was lost if( FAILED( hr = RestoreBuffer( pDSB, &bRestored ) ) ) return DXTRACE_ERR( TEXT("RestoreBuffer"), hr ); if( bRestored ) { // The buffer was restored, so we need to fill it with new data if( FAILED( hr = FillBufferWithSound( pDSB, FALSE ) ) ) return DXTRACE_ERR( TEXT("FillBufferWithSound"), hr ); } if( m_dwCreationFlags & DSBCAPS_CTRLVOLUME ) { pDSB->SetVolume( lVolume ); } if( lFrequency != -1 && (m_dwCreationFlags & DSBCAPS_CTRLFREQUENCY) ) { pDSB->SetFrequency( lFrequency ); } if( m_dwCreationFlags & DSBCAPS_CTRLPAN ) { pDSB->SetPan( lPan ); } return pDSB->Play( 0, dwPriority, dwFlags ); }
int CSoundResource::play( int sndID, DWORD priority, DWORD flags, LONG volume, LONG freq, LONG pan ) { assert( mDSBuffers ); int bufferIdx = getFreeBufferIndex(); IDirectSoundBuffer* buffer = mDSBuffers[bufferIdx]; if( !restoreBufferAndFill( buffer, false ) ) return -1; if( mCreationFlags & DSBCAPS_CTRLVOLUME ) buffer->SetVolume( volume ); if( freq != -1 && (mCreationFlags & DSBCAPS_CTRLFREQUENCY) ) buffer->SetFrequency( freq ); if( mCreationFlags & DSBCAPS_CTRLPAN ) buffer->SetPan( pan ); mPlayingIDs[bufferIdx] = sndID; buffer->Play( 0, priority, flags ); return bufferIdx; }
// Initialise DirectSound and buffers void Loudspeaker::Init(HWND hwnd) { // Direct sound DirectSoundCreate8(NULL, &directSound, NULL); directSound->SetCooperativeLevel(hwnd, DSSCL_PRIORITY); // Primary (soundcard) buffer DSBUFFERDESC bufferDesc; bufferDesc.dwSize = sizeof(DSBUFFERDESC); bufferDesc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME; bufferDesc.dwBufferBytes = 0; bufferDesc.dwReserved = 0; bufferDesc.lpwfxFormat = NULL; bufferDesc.guid3DAlgorithm = GUID_NULL; directSound->CreateSoundBuffer(&bufferDesc, &primaryBuffer, NULL); WAVEFORMATEX waveFormat; waveFormat.wFormatTag = WAVE_FORMAT_PCM; waveFormat.nSamplesPerSec = 44100; waveFormat.wBitsPerSample = 16; waveFormat.nChannels = 1; waveFormat.nBlockAlign = (waveFormat.wBitsPerSample / 8) * waveFormat.nChannels; waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; waveFormat.cbSize = 0; primaryBuffer->SetFormat(&waveFormat); // Secondary (CPU) buffer bufferDesc.dwSize = sizeof(DSBUFFERDESC); bufferDesc.dwFlags = DSBCAPS_CTRLVOLUME; bufferDesc.dwBufferBytes = 1764; bufferDesc.dwReserved = 0; bufferDesc.lpwfxFormat = &waveFormat; bufferDesc.guid3DAlgorithm = GUID_NULL; IDirectSoundBuffer* temp; directSound->CreateSoundBuffer(&bufferDesc, &temp, NULL); temp->QueryInterface(IID_IDirectSoundBuffer8, (void**)&secondaryBuffer); temp->Release(); temp = 0; }
void DirectSoundStreamer::Stream( void const *pSamples ) { // Verify buffer availability DWORD play, write; if( FAILED( m_pDirectSoundBuffer->GetCurrentPosition( &play, &write ) ) ) return; if( write < play ) write += DWORD( m_physical ); std::size_t begin( m_begin ); if( begin < play ) begin += m_physical; if( begin < write ) begin = std::size_t( write ); std::size_t end( begin + m_stream ); if( play + m_virtual < end ) return; begin %= m_physical; // Copy samples to buffer void *ps[ 2 ]; DWORD sizes[ 2 ]; HRESULT hResult( m_pDirectSoundBuffer->Lock( DWORD( begin ), DWORD( m_stream ), &ps[ 0 ], &sizes[ 0 ], &ps[ 1 ], &sizes[ 1 ], 0 ) ); if( FAILED( hResult ) ) { if( hResult != DSERR_BUFFERLOST ) return; m_pDirectSoundBuffer->Restore(); if( FAILED( m_pDirectSoundBuffer->Lock( DWORD( begin ), DWORD( m_stream ), &ps[ 0 ], &sizes[ 0 ], &ps[ 1 ], &sizes[ 1 ], 0 ) ) ) return; } using std::memcpy; memcpy( ps[ 0 ], pSamples, std::size_t( sizes[ 0 ] ) ); if( ps[ 1 ] ) memcpy( ps[ 1 ], static_cast< char const * >( pSamples ) + sizes[ 0 ], std::size_t( sizes[ 1 ] ) ); m_pDirectSoundBuffer->Unlock( ps[ 0 ], sizes[ 0 ], ps[ 1 ], sizes[ 1 ] ); // Select next buffer m_begin = end % m_physical; }
bool DSoundAudioBackend::WriteDataToBuffer(DWORD offset, // Our own write cursor. char* soundData, // Start of our data. DWORD soundBytes) { // Size of block to copy. void *ptr1, *ptr2; DWORD numBytes1, numBytes2; // Obtain memory address of write block. This will be in two parts if the block wraps around. HRESULT hr = dsBuffer_->Lock(offset, soundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0); // If the buffer was lost, restore and retry lock. /* if (DSERR_BUFFERLOST == hr) { dsBuffer->Restore(); hr=dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0); } */ if (SUCCEEDED(hr)) { memcpy(ptr1, soundData, numBytes1); if (ptr2) memcpy(ptr2, soundData+numBytes1, numBytes2); // Release the data back to DirectSound. dsBuffer_->Unlock(ptr1, numBytes1, ptr2, numBytes2); return true; } return false; }
//----------------------------------------------------------------------------- // Name: CSoundManager::SetPrimaryBufferFormat() // Desc: Set primary buffer to a specified format // !WARNING! - Setting the primary buffer format and then using this // same DirectSound object for DirectMusic messes up // DirectMusic! // For example, to set the primary buffer format to 22kHz stereo, 16-bit // then: dwPrimaryChannels = 2 // dwPrimaryFreq = 22050, // dwPrimaryBitRate = 16 //----------------------------------------------------------------------------- HRESULT CSoundManager::SetPrimaryBufferFormat( DWORD dwPrimaryChannels, DWORD dwPrimaryFreq, DWORD dwPrimaryBitRate ) { HRESULT hr; IDirectSoundBuffer* pDSBPrimary = NULL; if( m_pDS == NULL ) return CO_E_NOTINITIALIZED; // Get the primary buffer DSBUFFERDESC dsbd; ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) ); dsbd.dwSize = sizeof(DSBUFFERDESC); dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER; dsbd.dwBufferBytes = 0; dsbd.lpwfxFormat = NULL; if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL ) ) ) return DXTRACE_ERR( TEXT("CreateSoundBuffer"), hr ); WAVEFORMATEX wfx; ZeroMemory( &wfx, sizeof(WAVEFORMATEX) ); wfx.wFormatTag = (WORD) WAVE_FORMAT_PCM; wfx.nChannels = (WORD) dwPrimaryChannels; wfx.nSamplesPerSec = (DWORD) dwPrimaryFreq; wfx.wBitsPerSample = (WORD) dwPrimaryBitRate; wfx.nBlockAlign = (WORD) (wfx.wBitsPerSample / 8 * wfx.nChannels); wfx.nAvgBytesPerSec = (DWORD) (wfx.nSamplesPerSec * wfx.nBlockAlign); if( FAILED( hr = pDSBPrimary->SetFormat(&wfx) ) ) return DXTRACE_ERR( TEXT("SetFormat"), hr ); SAFE_RELEASE( pDSBPrimary ); return S_OK; }
int CSoundResource::play3D( int sndID, const DS3DBUFFER& props3D, DWORD priority, DWORD flags, LONG volume, LONG freq ) { HRESULT hr; DWORD baseFreq; assert( mDSBuffers ); // cull the sound if too far const SVector3& earPos = G_AUDIOCTX->getListener().transform.getOrigin(); SVector3 toear( earPos.x - props3D.vPosition.x, earPos.y - props3D.vPosition.y, earPos.z - props3D.vPosition.z ); if( toear.lengthSq() >= props3D.flMaxDistance * props3D.flMaxDistance ) return 0; int bufferIdx = getFreeBufferIndex(); IDirectSoundBuffer* buffer = mDSBuffers[bufferIdx]; if( !restoreBufferAndFill( buffer, false ) ) return -1; if( mCreationFlags & DSBCAPS_CTRLVOLUME ) buffer->SetVolume( volume ); if( mCreationFlags & DSBCAPS_CTRLFREQUENCY ) { buffer->GetFrequency( &baseFreq ); buffer->SetFrequency( baseFreq + freq ); } IDirectSound3DBuffer* buf3D; hr = buffer->QueryInterface( IID_IDirectSound3DBuffer, (void**)&buf3D ); if( SUCCEEDED( hr ) ) { hr = buf3D->SetAllParameters( &props3D, DS3D_IMMEDIATE ); if( SUCCEEDED( hr ) ) { mPlayingIDs[bufferIdx] = sndID; hr = buffer->Play( 0, priority, flags ); } buf3D->Release(); } return bufferIdx; }
sBool sSetSoundHandler(sInt freq,sSoundHandler handler,sInt latency,sInt flags) { HRESULT hr; DSBUFFERDESC dsbd; IDirectSoundBuffer *buffer = 0; void *p1,*p2; DWORD c1,c2; WAVEFORMATEXTENSIBLE sformat = { { WAVE_FORMAT_PCM,2,freq,freq*4,4,16,0 }, {0}, {3}, {0} }; sClearSoundHandler(); if(!DXSThread) return 0; sLockSound(); DXSOSamples = latency; DXSORate = freq; DXSOChannels = 2; if (flags & sSOF_5POINT1) { DXSOChannels=6; sformat.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE; sformat.Format.cbSize=22; sformat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; } sformat.Format.nChannels=DXSOChannels; sformat.Format.nBlockAlign=2*DXSOChannels; sformat.Format.nAvgBytesPerSec=freq*sformat.Format.nBlockAlign; sformat.Samples.wValidBitsPerSample=16; sformat.dwChannelMask=(1<<DXSOChannels)-1; // very space opera // open device hr = DirectSoundCreate8(0,&DXSO,0); if(FAILED(hr)) goto error; hr = DXSO->SetCooperativeLevel(sHWND,DSSCL_PRIORITY); if(FAILED(hr)) goto error; // set primary buffer sample rate sSetMem(&dsbd,0,sizeof(dsbd)); dsbd.dwSize = sizeof(dsbd); dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER; dsbd.dwBufferBytes = 0; dsbd.lpwfxFormat = 0; hr = DXSO->CreateSoundBuffer(&dsbd,&DXSOPrimary,0); if(SUCCEEDED(hr)) DXSOPrimary->SetFormat(&sformat.Format); // create streaming buffer sSetMem(&dsbd,0,sizeof(dsbd)); dsbd.dwSize = sizeof(dsbd); dsbd.dwFlags = DSBCAPS_GETCURRENTPOSITION2; if(flags & sSOF_GLOBALFOCUS) dsbd.dwFlags |= DSBCAPS_GLOBALFOCUS; dsbd.dwBufferBytes = latency*DXSOChannels*2; dsbd.lpwfxFormat = &sformat.Format; hr = DXSO->CreateSoundBuffer(&dsbd,&buffer,0); if(FAILED(hr)) goto error; hr = buffer->QueryInterface(IID_IDirectSoundBuffer8,(void**)&DXSOBuffer); if(FAILED(hr)) goto error; buffer->Release(); buffer = 0; hr = DXSOBuffer->Lock(0,0,&p1,&c1,&p2,&c2,DSBLOCK_ENTIREBUFFER); if(!FAILED(hr)) { if (p1) sSetMem(p1,0,c1); if (p2) sSetMem(p2,0,c2); DXSOBuffer->Unlock(p1,c1,p2,c2); } DXSOHandler = handler; DXSOBuffer->Play(0,0,DSBPLAY_LOOPING); sUnlockSound(); sPingSound(); return sTRUE; error: sClearSoundHandler(); sUnlockSound(); return sFALSE; }
bool Sound::LoadWaveFile(const char* filename, IDirectSoundBuffer8** secondaryBuffer) { int error; FILE* filePtr; unsigned int count; WaveHeaderType waveFileHeader; WAVEFORMATEX waveFormat; DSBUFFERDESC bufferDesc; HRESULT result; IDirectSoundBuffer* tempBuffer; unsigned char* waveData; unsigned char* bufferPtr; unsigned long bufferSize; error = fopen_s(&filePtr, filename, "rb"); if(error != 0) { return false; } count = fread(&waveFileHeader, sizeof(waveFileHeader), 1, filePtr); if(count != 1) { return false; } //check through the header to make sure that it is a non-corrupted WAV file if((waveFileHeader.chunkId[0] != 'R') || (waveFileHeader.chunkId[1] != 'I') || (waveFileHeader.chunkId[2] != 'F') || (waveFileHeader.chunkId[3] != 'F')) { return false; } if((waveFileHeader.format[0] != 'W') || (waveFileHeader.format[1] != 'A') || (waveFileHeader.format[2] != 'V') || (waveFileHeader.format[3] != 'E')) { return false; } if((waveFileHeader.subChunkId[0] != 'f') || (waveFileHeader.subChunkId[1] != 'm') || (waveFileHeader.subChunkId[2] != 't') || (waveFileHeader.subChunkId[3] != ' ')) { return false; } if(waveFileHeader.audioFormat != WAVE_FORMAT_PCM) { return false; } if(waveFileHeader.numChannels != 2) { return false; } if(waveFileHeader.sampleRate != 44100) { return false; } if(waveFileHeader.bitsPerSample != 16) { return false; } if((waveFileHeader.dataChunkId[0] != 'd') || (waveFileHeader.dataChunkId[1] != 'a') || (waveFileHeader.dataChunkId[2] != 't') || (waveFileHeader.dataChunkId[3] != 'a')) { return false; } waveFormat.wFormatTag = WAVE_FORMAT_PCM; waveFormat.nSamplesPerSec = 44100; waveFormat.wBitsPerSample = 16; waveFormat.nChannels = 2; waveFormat.nBlockAlign = (waveFormat.wBitsPerSample / 8) * waveFormat.nChannels; waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; waveFormat.cbSize = 0; bufferDesc.dwSize = sizeof(DSBUFFERDESC); bufferDesc.dwFlags = DSBCAPS_CTRLVOLUME; bufferDesc.dwBufferBytes = waveFileHeader.dataSize; bufferDesc.dwReserved = 0; bufferDesc.lpwfxFormat = &waveFormat; bufferDesc.guid3DAlgorithm = GUID_NULL; result = m_DirectSound->CreateSoundBuffer(&bufferDesc, &tempBuffer, NULL); if(FAILED(result)) { return false; } result = tempBuffer->QueryInterface(IID_IDirectSoundBuffer8, (void**)&*secondaryBuffer); if(FAILED(result)) { return false; } tempBuffer->Release(); tempBuffer = 0; //move to the beginning of the wave data which starts at the end of the data chunk header. fseek(filePtr, sizeof(WaveHeaderType), SEEK_SET); //create a temporary buffer to hold the wave file data. waveData = new unsigned char[waveFileHeader.dataSize]; if(!waveData) { return false; } //read in the wave file data into the newly created buffer. count = fread(waveData, 1, waveFileHeader.dataSize, filePtr); if(count != waveFileHeader.dataSize) { return false; } error = fclose(filePtr); if(error != 0) { return false; } //lock the secondary buffer to write wave data into it. result = (*secondaryBuffer)->Lock(0, waveFileHeader.dataSize, (void**)&bufferPtr, (DWORD*)&bufferSize, NULL, 0, 0); if(FAILED(result)) { return false; } // Copy the wave data into the buffer. memcpy(bufferPtr, waveData, waveFileHeader.dataSize); // Unlock the secondary buffer after the data has been written to it. result = (*secondaryBuffer)->Unlock((void*)bufferPtr, bufferSize, NULL, 0); if(FAILED(result)) { return false; } delete [] waveData; waveData = 0; return true; }
HRESULT DirectSoundDevice::LoadWav(char* filename, SGE::Sound::Sound *sound){ //This method is based of an example featured on http://www.rastertek.com/dx11tut14.html struct WaveHeaderType { char chunkId[4]; unsigned long chunkSize; char format[4]; char subChunkId[4]; unsigned long subChunkSize; unsigned short audioFormat; unsigned short numChannels; unsigned long sampleRate; unsigned long bytesPerSecond; unsigned short blockAlign; unsigned short bitsPerSample; char dataChunkId[4]; unsigned long dataSize; }; sound->index = -1; int error; FILE* filePtr = NULL; unsigned int count; WaveHeaderType waveFileHeader; WAVEFORMATEX waveFormat; DSBUFFERDESC bufferDesc; HRESULT result; IDirectSoundBuffer* tempBuffer = NULL; unsigned char* waveData = NULL; unsigned char *bufferPtr = NULL; unsigned long bufferSize = NULL; if(fopen_s(&filePtr, filename, "rb") != 0) return E_FAIL; count = fread(&waveFileHeader, sizeof(waveFileHeader), 1, filePtr); if(count != 1) { return E_FAIL; } // Check that the chunk ID is the RIFF format. if((waveFileHeader.chunkId[0] != 'R') || (waveFileHeader.chunkId[1] != 'I') || (waveFileHeader.chunkId[2] != 'F') || (waveFileHeader.chunkId[3] != 'F')) { return E_FAIL; } // Check that the file format is the WAVE format. if((waveFileHeader.format[0] != 'W') || (waveFileHeader.format[1] != 'A') || (waveFileHeader.format[2] != 'V') || (waveFileHeader.format[3] != 'E')) { return E_FAIL; } // Check that the sub chunk ID is the fmt format. if((waveFileHeader.subChunkId[0] != 'f') || (waveFileHeader.subChunkId[1] != 'm') || (waveFileHeader.subChunkId[2] != 't') || (waveFileHeader.subChunkId[3] != ' ')) { return E_FAIL; } // Check for the data chunk header. if((waveFileHeader.dataChunkId[0] != 'd') || (waveFileHeader.dataChunkId[1] != 'a') || (waveFileHeader.dataChunkId[2] != 't') || (waveFileHeader.dataChunkId[3] != 'a')) { return E_FAIL; } // Set the wave format of secondary buffer that this wave file will be loaded onto. waveFormat.wFormatTag = waveFileHeader.audioFormat; waveFormat.nSamplesPerSec = waveFileHeader.sampleRate; waveFormat.wBitsPerSample = waveFileHeader.bitsPerSample; waveFormat.nChannels = waveFileHeader.numChannels; waveFormat.nBlockAlign = (waveFormat.wBitsPerSample / 8) * waveFormat.nChannels; waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; waveFormat.cbSize = 0; // Set the buffer description of the secondary sound buffer that the wave file will be loaded onto. bufferDesc.dwSize = sizeof(DSBUFFERDESC); bufferDesc.dwFlags = DSBCAPS_CTRLVOLUME; bufferDesc.dwBufferBytes = waveFileHeader.dataSize; bufferDesc.dwReserved = 0; bufferDesc.lpwfxFormat = &waveFormat; bufferDesc.guid3DAlgorithm = GUID_NULL; IDirectSoundBuffer8 * soundBuffer = NULL; result = lpds->CreateSoundBuffer(&bufferDesc, &tempBuffer, NULL); if(FAILED(result)) return result; result = tempBuffer->QueryInterface(IID_IDirectSoundBuffer8, (void**)&soundBuffer); if(FAILED(result)) return result; tempBuffer->Release(); tempBuffer = 0; fseek(filePtr, sizeof(WaveHeaderType), SEEK_SET); waveData = new unsigned char[waveFileHeader.dataSize]; count = fread(waveData, 1, waveFileHeader.dataSize, filePtr); error = fclose(filePtr); result = (soundBuffer)->Lock(0, waveFileHeader.dataSize, (void**)&bufferPtr, (DWORD*)&bufferSize, NULL, 0, 0); if(FAILED(result)) return result; memcpy(bufferPtr, waveData, waveFileHeader.dataSize); result = (soundBuffer)->Unlock((void*)bufferPtr, bufferSize, NULL, 0); if(FAILED(result)) return result; // Release the wave data since it was copied into the secondary buffer. delete [] waveData; waveData = 0; sounds.push_back(soundBuffer); sound->volume = 100; sound->index = sounds.size() - 1; return S_OK; }
OutputStream* DSAudioDevice::openBuffer( void* samples, int frame_count, int channel_count, int sample_rate, SampleFormat sample_format) { ADR_GUARD("DSAudioDevice::openBuffer"); const int frame_size = channel_count * GetSampleSize(sample_format); WAVEFORMATEX wfx; memset(&wfx, 0, sizeof(wfx)); wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = channel_count; wfx.nSamplesPerSec = sample_rate; wfx.nAvgBytesPerSec = sample_rate * frame_size; wfx.nBlockAlign = frame_size; wfx.wBitsPerSample = GetSampleSize(sample_format) * 8; wfx.cbSize = sizeof(wfx); DSBUFFERDESC dsbd; memset(&dsbd, 0, sizeof(dsbd)); dsbd.dwSize = sizeof(dsbd); dsbd.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY | DSBCAPS_STATIC | DSBCAPS_CTRLPOSITIONNOTIFY; if (m_global_focus) { dsbd.dwFlags |= DSBCAPS_GLOBALFOCUS; } const int buffer_frame_count = std::max(m_min_buffer_length, frame_count); const int buffer_size = buffer_frame_count * frame_size; dsbd.dwBufferBytes = buffer_size; dsbd.lpwfxFormat = &wfx; // create the DS buffer IDirectSoundBuffer* buffer; HRESULT result = m_direct_sound->CreateSoundBuffer( &dsbd, &buffer, NULL); if (FAILED(result) || !buffer) { return 0; } ADR_IF_DEBUG { DSBCAPS caps; caps.dwSize = sizeof(caps); result = buffer->GetCaps(&caps); if (FAILED(result)) { buffer->Release(); return 0; } else { std::ostringstream ss; ss << "actual buffer size: " << caps.dwBufferBytes << std::endl << "buffer_size: " << buffer_size; ADR_LOG(ss.str().c_str()); } } void* data; DWORD data_size; result = buffer->Lock(0, buffer_size, &data, &data_size, 0, 0, 0); if (FAILED(result)) { buffer->Release(); return 0; } ADR_IF_DEBUG { std::ostringstream ss; ss << "buffer size: " << buffer_size << std::endl << "data size: " << data_size << std::endl << "frame count: " << frame_count; ADR_LOG(ss.str().c_str()); } const int actual_size = frame_count * frame_size; memcpy(data, samples, actual_size); memset((u8*)data + actual_size, 0, buffer_size - actual_size); buffer->Unlock(data, data_size, 0, 0); DSOutputBuffer* b = new DSOutputBuffer( this, buffer, buffer_frame_count, frame_size); SYNCHRONIZED(this); m_open_buffers.push_back(b); return b; }
TDDSDGenWave::TDDSDGenWave( TDDSD* OWner, const wstring& fname, bool is3D, bool useFX ) { FIsStream = false; FOwner = OWner; FUseFX = useFX; //サウンドカードが無いなら、何もしない if( ! FOwner->Initialized() ) return; HMMIO hm = mmioOpen((LPWSTR)fname.c_str(), NULL, MMIO_READ | MMIO_ALLOCBUF); if( hm == 0 ) { //PutDebugMessage(fname + 'が、見つかりません'); return; } //WAVEに入る MMCKINFO mckP; //親チャンクの情報 mckP.fccType = MakeFourCC('W','A','V','E'); if( (mmioDescend(hm, &mckP, NULL, MMIO_FINDRIFF)) != 0 ) { mmioClose(hm, 0); //PutDebugMessage(fname + 'は、WAVEファイルではありません'); return; } //fmtチャンクに入る MMCKINFO mckC; //子チャンクの情報 mckC.ckid = MakeFourCC('f','m','t',' '); if( mmioDescend(hm, &mckC, &mckP, MMIO_FINDCHUNK) != 0 ) { mmioClose(hm, 0); //PutDebugMessage(fname + 'には、fmtチャンクが有りません'); return; } //fmtチャンクを読み取る u32 fmtSize = mckC.cksize; if( mmioRead(hm, (HPSTR)&FWaveFormat, fmtSize) != fmtSize ) { mmioClose(hm, 0); //PutDebugMessage(fname + 'のfmtチャンクが不正です'); return; } //fmtチャンクを抜け、dataチャンクに入る mmioAscend(hm, &mckC, 0); mckC.ckid = MakeFourCC('d','a','t','a'); if( mmioDescend(hm, &mckC, &mckP, MMIO_FINDCHUNK) != 0 ) { mmioClose(hm, 0); //PutDebugMessage(fname + 'には、dataチャンクが有りません'); return; } u32 dataSize = mckC.cksize; //二次バッファの作成 DSBUFFERDESC dsbd; ZeroMemory(&dsbd, sizeof(dsbd)); dsbd.dwSize = sizeof(dsbd); if( is3D ) dsbd.dwFlags = DSBCAPS_CTRLVOLUME + DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRL3D; else dsbd.dwFlags = DSBCAPS_CTRLPAN + DSBCAPS_CTRLVOLUME + DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN; if( FUseFX ) dsbd.dwFlags = DSBCAPS_CTRLPAN + DSBCAPS_CTRLVOLUME + DSBCAPS_CTRLFREQUENCY + DSBCAPS_CTRLFX; if( FOwner->FStickyFocus ) dsbd.dwFlags = dsbd.dwFlags | DSBCAPS_STICKYFOCUS; dsbd.dwBufferBytes = dataSize; dsbd.lpwfxFormat = &FWaveFormat; FLength = dataSize; IDirectSoundBuffer* dsb; FOwner->DSound()->CreateSoundBuffer(&dsbd, &dsb, NULL); dsb->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&FSoundBuffer); dsb->Release(); //二次バッファのロック LPVOID lpBuf1, lpBuf2; DWORD dwBuf1, dwBuf2; FSoundBuffer->Lock(0,dataSize, &lpBuf1, &dwBuf1, &lpBuf2, &dwBuf2, 0); //音データのロード(dataチャンクを読み取る) mmioRead(hm, (HPSTR)lpBuf1, dwBuf1); if( dwBuf2 != 0 ) { mmioRead(hm, (HPSTR)lpBuf2, dwBuf2); } FSoundBuffer->Unlock(lpBuf1,dwBuf1,lpBuf2,dwBuf2); FSoundBuffer->SetFrequency(FWaveFormat.nSamplesPerSec); mmioClose(hm, 0); }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW |CS_OWNDC; wc.lpfnWndProc = static_cast<WNDPROC>(WndProc); wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(PINGIEL_ICON)); wc.hCursor = nullptr; wc.hbrBackground = nullptr; wc.lpszMenuName = nullptr; wc.lpszClassName = "Monster"; if (!RegisterClass(&wc)) return false; int horizontal = GetSystemMetrics(16); int vertical = GetSystemMetrics(17); HWND hWnd = CreateWindow(wc.lpszClassName, "MonsterRace", WS_OVERLAPPED | WS_MAXIMIZE | WS_SYSMENU, 0, 0,horizontal, vertical, nullptr, nullptr, hInstance, nullptr); if (hWnd == nullptr) return false; static PIXELFORMATDESCRIPTOR pfd= //struktura formatu pixeli { sizeof(PIXELFORMATDESCRIPTOR), 1,//numerwersji PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 16,//tryb koloru 0,0,0,0,0,0,//ignorowane bity koloru 0,//brak kanalu alpha 0,//ignorowanie rpzesuniecia 0,//brak akumulatora 0,0,0,0,//ignorowane przesuniecie akumulatora 16,//16bitowy bufor glebokosci 0,//no stencil buffer 0,//no auxiliary buffer PFD_MAIN_PLANE,//glowna warstwa rysowania 0,//zarezerwowane 0,0,0//ignorowanie warstwy maski }; HGLRC hRC = nullptr;//kontekst renderowania GLuint PixelFormat;//styl pixeli if (!((hDC = GetDC(hWnd)))) return 0;//pobranie kontekstu if (!((PixelFormat = ChoosePixelFormat(hDC, &pfd))))return 0;//wyszukiwanie formatu pixeli if (!SetPixelFormat(hDC, PixelFormat, &pfd)) return 0;//ust. formatu pixeli if (!((hRC = wglCreateContext(hDC))))return 0;//pobvranie kontekstu renderowania if (!wglMakeCurrent(hDC, hRC))return 0; //uruchomienie kontekstu renderowania ShowWindow(hWnd, iCmdShow); SetForegroundWindow(hWnd); SetFocus(hWnd); ShowCursor(FALSE); //-------------------------DZWIEKI----------------------------------- //44.1khz 16bit stereo WAVEFORMATEX pcmWaveFormat; //df formatu dzwieku pcmWaveFormat.wFormatTag = WAVE_FORMAT_PCM; //format probek pcmWaveFormat.nChannels = 2; //liczba kanalow pcmWaveFormat.nSamplesPerSec = 44100L; //probkowanie pcmWaveFormat.wBitsPerSample = 16; //ilosc bitow na probke pcmWaveFormat.nAvgBytesPerSec = 176400L; //ilosc bajtow na sekunde pcmWaveFormat.nBlockAlign = 4; pcmWaveFormat.cbSize = 0; /* MMRESULT mmResult; HWAVEOUT hwo = nullptr; //uchwyt do interfejsu urzadzenia odtwarzania UINT devId; //ident. urzadzenia for (devId = 0; devId < waveOutGetNumDevs(); devId++) { mmResult = waveOutOpen(&hwo, devId, &pcmWaveFormat, 0, 0, CALLBACK_NULL); if (mmResult == MMSYSERR_NOERROR)break; } if (mmResult != MMSYSERR_NOERROR) { MessageBox(hWnd, TEXT("brak karty dzwiekowej o wymaganych parametrach"), TEXT("ERROR"), MB_OK); return mmResult; } */ IDirectSound8 *DS8; DirectSoundCreate8(nullptr, &DS8, nullptr); if (DS8 == nullptr) { MessageBox(nullptr, TEXT("nie mozna utworzyc direktsound"), TEXT("ERROR"), MB_OK); } if (DS8->SetCooperativeLevel(hWnd, DSSCL_NORMAL) != DS_OK) MessageBox(nullptr, TEXT("nie mozna ustawic wymaganego trybu pracy"), TEXT("ERROR"), MB_OK); //przygotowanie probek do odtworzenia WAVEHDR whdr; ZeroMemory(&whdr, sizeof(WAVEHDR)); whdr.lpData = new char[pcmWaveFormat.nAvgBytesPerSec * 10]; //ilosc bajtwo na sekunde whdr.dwBufferLength = pcmWaveFormat.nAvgBytesPerSec * 10; //razy ilosc sekund whdr.dwUser = 0; whdr.dwFlags = 0; whdr.dwLoops = 0; whdr.dwBytesRecorded = 0; whdr.lpNext = nullptr; //wypelnienei buffora probek probkami sygnalu ao czestoliwosci 880hz for (int i = 0; i < whdr.dwBufferLength; i++) { whdr.lpData[i] = 128 * sin(i*80.0 / static_cast<double>(pcmWaveFormat.nSamplesPerSec)) + 128; } /* waveOutSetVolume(hwo, 0xFFFFFFFF); mmResult = waveOutPrepareHeader(hwo, &whdr, sizeof(WAVEHDR)); //wyslanie naglowska if (mmResult != MMSYSERR_NOERROR) //przygotowanie urzadzenia { MessageBox(hWnd, TEXT("nie mozna zainisjowac karty"), TEXT("ERROR"), MB_OK); return mmResult; } mmResult = waveOutWrite(hwo, &whdr, sizeof(WAVEHDR)); //wyslanie probek do urzadzenia if (mmResult != MMSYSERR_NOERROR) { MessageBox(hWnd, TEXT("nie idzie zaladowac probek"), TEXT("error"), MB_OK); return mmResult; } while ((whdr.dwFlags&WHDR_DONE) != WHDR_DONE)Sleep(100);//czekanie na koniec //zamkniecie urzadzenia mmResult = waveOutUnprepareHeader(hwo, &whdr, sizeof(WAVEHDR)); mmResult = waveOutClose(hwo); */ IDirectSoundBuffer *DSB; DSBUFFERDESC DSBD; memset(&DSBD, 0, sizeof(DSBUFFERDESC)); DSBD.dwSize = sizeof(DSBD); DSBD.dwFlags = DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; DSBD.dwBufferBytes = whdr.dwBufferLength; DSBD.lpwfxFormat = &pcmWaveFormat; if (DS8->CreateSoundBuffer(&DSBD, &DSB, nullptr) != DS_OK) { MessageBox(nullptr, TEXT("nie mozna utworzy direktosoundbuffer"), TEXT("ERROR"), MB_OK); }; DSB->SetVolume(0xFFF0);//ustawienie glosnosci void *ptr1, *ptr2; DWORD l1, l2; DSB->Lock(0, whdr.dwBufferLength, &ptr1, &l1, &ptr2, &l2, DSBLOCK_ENTIREBUFFER); if (ptr1)memcpy(ptr1, whdr.lpData, l1); if (ptr2)memcpy(ptr2, whdr.lpData + l1, l2); DSB->Unlock(ptr1, l1, ptr2, l2); //DSB->Play(0, 0, 0); delete[]whdr.lpData;//usuniecie bufora z pamieci //--------------------------------------------------------------------------------------- if (!InitGL()) // Initialize Our Newly Created GL Window { // Reset The Display MessageBox(nullptr, "Initialization Failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return FALSE; // Return FALSE } BOOL done = false; SetTimer(hWnd, ID_TIMER_REDRAW, 16, nullptr); SetTimer(hWnd, ID_TIMER_REDRAW2, 8, nullptr); MSG msg; while (!done) { if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))//czy jest zdarzenie do obslugi? { if (msg.message == WM_QUIT) done = TRUE; else { TranslateMessage(&msg); DispatchMessage(&msg); } } } if (hRC) { wglMakeCurrent(nullptr, nullptr);//usuw. kontekstu rend. wglDeleteContext(hRC);//usuw. kontekstu rend. } if (hDC && !ReleaseDC(hWnd, hDC)) {}//wyzerowanie kontekstu if (hWnd&& !DestroyWindow(hWnd)){}//wyzerowanie uchwytu okienka return 0; }
bool OutputDirectSound::initialize(quint32 freq, ChannelMap map, Qmmp::AudioFormat format) { Q_UNUSED(format); DSBUFFERDESC bufferDesc; HRESULT result = DirectSoundCreate8(0, &m_ds, 0); if(result != DS_OK) { qWarning("OutputDirectSound: DirectSoundCreate8 failed, error code = 0x%lx", result); m_ds = 0; return false; } if((result = m_ds->SetCooperativeLevel(GetDesktopWindow(), DSSCL_PRIORITY)) != DS_OK) { qWarning("OutputDirectSound: SetCooperativeLevel failed, error code = 0x%lx", result); return false; } ZeroMemory(&bufferDesc, sizeof(DSBUFFERDESC)); bufferDesc.dwSize = sizeof(DSBUFFERDESC); bufferDesc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME; bufferDesc.dwBufferBytes = 0; bufferDesc.lpwfxFormat = NULL; if((result = m_ds->CreateSoundBuffer(&bufferDesc, &m_primaryBuffer, NULL)) != DS_OK) { m_primaryBuffer = 0; qWarning("OutputDirectSound: CreateSoundBuffer failed, error code = 0x%lx", result); return false; } WAVEFORMATEX wfex; ZeroMemory(&wfex, sizeof(WAVEFORMATEX)); wfex.wFormatTag = WAVE_FORMAT_PCM; wfex.nChannels = map.count(); wfex.nSamplesPerSec = freq; wfex.wBitsPerSample = 16; wfex.nBlockAlign = (wfex.wBitsPerSample / 8) * wfex.nChannels; wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign; if((result = m_primaryBuffer->SetFormat(&wfex)) != DS_OK) { qWarning("OutputDirectSound: SetFormat failed, error code = 0x%lx", result); return false; } if((result = m_primaryBuffer->Play(0, 0, DSBPLAY_LOOPING)) != DS_OK) { qWarning("OutputDirectSound: Play failed, error code = 0x%lx", result); return false; } ZeroMemory(&wfex, sizeof(WAVEFORMATEX)); wfex.wFormatTag = WAVE_FORMAT_PCM; wfex.nChannels = map.count(); wfex.nSamplesPerSec = freq; wfex.wBitsPerSample = 16; wfex.nBlockAlign = (wfex.wBitsPerSample / 8) * wfex.nChannels; wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign; ZeroMemory(&bufferDesc, sizeof(DSBUFFERDESC)); bufferDesc.dwSize = sizeof(DSBUFFERDESC); bufferDesc.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY; bufferDesc.lpwfxFormat = &wfex; bufferDesc.dwBufferBytes = DS_BUFSIZE; // buffer size IDirectSoundBuffer *pDSB; if((result = m_ds->CreateSoundBuffer(&bufferDesc, &pDSB, NULL)) != DS_OK) { qWarning("OutputDirectSound: CreateSoundBuffer failed, error code = 0x%lx", result); return false; } if((result = pDSB->QueryInterface(IID_IDirectSoundBuffer8, (void**)&m_dsBuffer)) != DS_OK) { m_dsBuffer = 0; qWarning("OutputDirectSound: QueryInterface failed, error code = 0x%lx", result); pDSB->Release(); return false; } m_dsBuffer->SetCurrentPosition(0); m_dsBuffer->Play(0,0,DSBPLAY_LOOPING); m_dsBufferAt = 0; configure(freq, map, Qmmp::PCM_S16LE); if(volumeControl) volumeControl->restore(); return true; }
bool cSound::loadWav(char* fileName, IDirectSoundBuffer8**secondaryBuffer) { int error; FILE *filePtr; unsigned int count=0; wavFileHeader waveFileHeader; //Stores the header of the wav file type WAVEFORMATEX waveFormat; //Stores the buffer wav format DSBUFFERDESC bufferDesc; //To sotre the details of the buffer IDirectSoundBuffer* tmpBuffer; unsigned char *waveData; //To load the wav file temporarily unsigned char *bufferPtr; unsigned long bufferSize; error = fopen_s(&filePtr, fileName, "rb"); if (error!=0) return false; if (filePtr) count = fread(&waveFileHeader, sizeof(wavFileHeader), 1, filePtr); if (count != 1) return false; if ((waveFileHeader.chunkId[0] != 'R') || (waveFileHeader.chunkId[1] != 'I') || (waveFileHeader.chunkId[2] != 'F') || (waveFileHeader.chunkId[3] != 'F')) { return false;// Check that the chunk ID is the RIFF format. } if ((waveFileHeader.format[0] != 'W') || (waveFileHeader.format[1] != 'A') || (waveFileHeader.format[2] != 'V') || (waveFileHeader.format[3] != 'E')) { return false;// Check that the file format is the WAVE format. } if ((waveFileHeader.subChunkId[0] != 'f') || (waveFileHeader.subChunkId[1] != 'm') || (waveFileHeader.subChunkId[2] != 't') || (waveFileHeader.subChunkId[3] != ' ')) { return false;// Check that the sub chunk ID is the fmt format. } if (waveFileHeader.audioFormat != WAVE_FORMAT_PCM) { return false;// Check that the audio format is WAVE_FORMAT_PCM. } int numChannels = waveFileHeader.numChannels; int sampleRate = waveFileHeader.sampleRate; int bitsPerSample = waveFileHeader.bitsPerSample; if ((waveFileHeader.dataChunkId[0] != 'd') || (waveFileHeader.dataChunkId[1] != 'a') || (waveFileHeader.dataChunkId[2] != 't') || (waveFileHeader.dataChunkId[3] != 'a')) return false;// Check for the data chunk header. waveFormat.wFormatTag = WAVE_FORMAT_PCM; waveFormat.nSamplesPerSec = sampleRate; waveFormat.nChannels = numChannels; waveFormat.wBitsPerSample = bitsPerSample; waveFormat.nBlockAlign = (waveFormat.wBitsPerSample / 8)*waveFormat.nChannels; waveFormat.nAvgBytesPerSec = waveFormat.nBlockAlign*waveFormat.nSamplesPerSec; waveFormat.cbSize = 0; bufferDesc.dwSize = sizeof(DSBUFFERDESC); bufferDesc.dwFlags = DSBCAPS_CTRLVOLUME; bufferDesc.dwBufferBytes = waveFileHeader.dataSize; bufferDesc.dwReserved = 0; bufferDesc.lpwfxFormat = &waveFormat; bufferDesc.guid3DAlgorithm = GUID_NULL; HRESULT result; result = intSound->CreateSoundBuffer(&bufferDesc, &tmpBuffer, NULL); if (FAILED(result))return false; result = tmpBuffer->QueryInterface(IID_IDirectSoundBuffer8, (void**)&*secondaryBuffer); if (FAILED(result))return false; tmpBuffer->Release(); tmpBuffer = NULL; //R E A D I N G T H E W A V F I L E S T A R T S H E R E fseek(filePtr, sizeof(waveFileHeader), SEEK_SET); waveData = new unsigned char[waveFileHeader.dataSize]; memset(waveData, 0, waveFileHeader.dataSize); if(!waveData) return false; while (count<waveFileHeader.dataSize) count = fread(waveData, 1, waveFileHeader.dataSize, filePtr); error = fclose(filePtr); if (error != 0)return false; result = (*secondaryBuffer)->Lock(0,waveFileHeader.dataSize,(void**)&bufferPtr,(DWORD*)&bufferSize,NULL,0,0); if (FAILED(result))return false; memcpy(bufferPtr, waveData, waveFileHeader.dataSize); result = (*secondaryBuffer)->Unlock((void**)bufferPtr, bufferSize, NULL, 0); if (FAILED(result))return false; delete[]waveData; return true; }
//----------------------------------------------------------------------------- // Name: CSoundManager::CreateStreaming() // Desc: //----------------------------------------------------------------------------- HRESULT CSoundManager::CreateStreaming( CStreamingSound** ppStreamingSound, LPTSTR strWaveFileName, DWORD dwCreationFlags, GUID guid3DAlgorithm, DWORD dwNotifyCount, DWORD dwNotifySize, HANDLE hNotifyEvent ) { HRESULT hr; if( m_pDS == NULL ) return CO_E_NOTINITIALIZED; if( strWaveFileName == NULL || ppStreamingSound == NULL || hNotifyEvent == NULL ) return E_INVALIDARG; IDirectSoundBuffer* pDSBuffer = NULL; DWORD dwDSBufferSize = NULL; CWaveFile* pWaveFile = NULL; DSBPOSITIONNOTIFY* aPosNotify = NULL; IDirectSoundNotify* pDSNotify = NULL; pWaveFile = new CWaveFile(); if( pWaveFile == NULL ) return E_OUTOFMEMORY; pWaveFile->Open( strWaveFileName, NULL, WAVEFILE_READ ); // Figure out how big the DirectSound buffer should be dwDSBufferSize = dwNotifySize * dwNotifyCount; // Set up the direct sound buffer. Request the NOTIFY flag, so // that we are notified as the sound buffer plays. Note, that using this flag // may limit the amount of hardware acceleration that can occur. DSBUFFERDESC dsbd; ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) ); dsbd.dwSize = sizeof(DSBUFFERDESC); dsbd.dwFlags = dwCreationFlags | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GETCURRENTPOSITION2; dsbd.dwBufferBytes = dwDSBufferSize; dsbd.guid3DAlgorithm = guid3DAlgorithm; dsbd.lpwfxFormat = pWaveFile->m_pwfx; if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &pDSBuffer, NULL ) ) ) { // If wave format isn't then it will return // either DSERR_BADFORMAT or E_INVALIDARG if( hr == DSERR_BADFORMAT || hr == E_INVALIDARG ) return DXTRACE_ERR( TEXT("CreateSoundBuffer"), hr ); return DXTRACE_ERR( TEXT("CreateSoundBuffer"), hr ); } // Create the notification events, so that we know when to fill // the buffer as the sound plays. if( FAILED( hr = pDSBuffer->QueryInterface( IID_IDirectSoundNotify, (VOID**)&pDSNotify ) ) ) { SAFE_DELETE_ARRAY( aPosNotify ); return DXTRACE_ERR( TEXT("QueryInterface"), hr ); } aPosNotify = new DSBPOSITIONNOTIFY[ dwNotifyCount ]; if( aPosNotify == NULL ) return E_OUTOFMEMORY; for( DWORD i = 0; i < dwNotifyCount; i++ ) { aPosNotify[i].dwOffset = (dwNotifySize * i) + dwNotifySize - 1; aPosNotify[i].hEventNotify = hNotifyEvent; } // Tell DirectSound when to notify us. The notification will come in the from // of signaled events that are handled in WinMain() if( FAILED( hr = pDSNotify->SetNotificationPositions( dwNotifyCount, aPosNotify ) ) ) { SAFE_RELEASE( pDSNotify ); SAFE_DELETE_ARRAY( aPosNotify ); return DXTRACE_ERR( TEXT("SetNotificationPositions"), hr ); } SAFE_RELEASE( pDSNotify ); SAFE_DELETE_ARRAY( aPosNotify ); // Create the sound *ppStreamingSound = new CStreamingSound( pDSBuffer, dwDSBufferSize, pWaveFile, dwNotifySize ); return S_OK; }
bool BufferCache::Acquire(const DSBUFFERDESC& desc, IDirectSoundBuffer8*& pBuffer, bool bUseCache) { // If buffer caching is enabled, try to find a // buffer with a matching description structure if(DXAudioMgr()->GetInit()->m_bCacheBuffers && bUseCache) { BufferInfoVector::iterator itr; for(itr = m_Free.begin(); itr != m_Free.end(); ++itr) { if((*itr)->m_Desc == desc) { pBuffer = (*itr)->m_pBuffer; pBuffer->SetCurrentPosition(0); pBuffer->AddRef(); m_Used.push_back(*itr); m_Free.erase(itr); return true; } } } // Create a buffer normally IDirectSoundBuffer* pDSBuffer; HRESULT hr = DXAudioMgr()->DirectSound()->CreateSoundBuffer(&desc, &pDSBuffer, NULL); if(FAILED(hr)) { DebugOut(3, "First attempt at sound buffer creation failed. Error = %s. Attempting again...", DXGetErrorString(hr)); if(desc.dwFlags & DSBCAPS_CTRL3D) { DXAudioMgr()->ResetSound3DLimit(); if(!DXAudioMgr()->RemoveSound3D(0)) return Error::Handle("Could not create sound buffer. Error = %s", DXGetErrorString(hr)); } else { DXAudioMgr()->ResetSoundLimit(); if(!DXAudioMgr()->RemoveSound(0)) return Error::Handle("Could not create sound buffer. Error = %s", DXGetErrorString(hr)); } hr = DXAudioMgr()->DirectSound()->CreateSoundBuffer(&desc, &pDSBuffer, NULL); if(FAILED(hr)) return Error::Handle("Could not create sound buffer. Error = %s", DXGetErrorString(hr)); } // Get the IDirectSoundBuffer8 interface hr = pDSBuffer->QueryInterface(IID_IDirectSoundBuffer8, (void**)&pBuffer); if(FAILED(hr)) return Error::Handle("Could not obtain DirectSoundBuffer8 interface. Error = %s", DXGetErrorString(hr)); // Release the temporary DirectSoundBuffer interface pDSBuffer->Release(); // If buffer caching is enabled, if(DXAudioMgr()->GetInit()->m_bCacheBuffers && bUseCache) { BufferInfo* pInfo = new BufferInfo; pInfo->m_pBuffer = pBuffer; pInfo->m_pBuffer->AddRef(); memcpy(&pInfo->m_Format, desc.lpwfxFormat, sizeof(WAVEFORMATEX)); memcpy(&pInfo->m_Desc, &desc, sizeof(DSBUFFERDESC)); pInfo->m_Desc.lpwfxFormat = &pInfo->m_Format; m_Used.push_back(pInfo); } return true; }
// must be 44.1k 16bit Stereo PCM Wave Sound DSound::CreateSound( char* wavFileName ) { int error; FILE* filePtr; unsigned int count; WaveHeaderType waveFileHeader; WAVEFORMATEX waveFormat; DSBUFFERDESC bufferDesc; HRESULT result; IDirectSoundBuffer* tempBuffer; IDirectSoundBuffer8* pSecondaryBuffer; unsigned char* waveData; unsigned char* bufferPtr; unsigned long bufferSize; // Open the wave file in binary. error = fopen_s( &filePtr,wavFileName,"rb" ); assert( error == 0 ); // Read in the wave file header. count = fread( &waveFileHeader,sizeof( waveFileHeader ),1,filePtr ); assert( count == 1 ); // Check that the chunk ID is the RIFF format. assert( (waveFileHeader.chunkId[0] == 'R') && (waveFileHeader.chunkId[1] == 'I') && (waveFileHeader.chunkId[2] == 'F') && (waveFileHeader.chunkId[3] == 'F') ); // Check that the file format is the WAVE format. assert( (waveFileHeader.format[0] == 'W') && (waveFileHeader.format[1] == 'A') && (waveFileHeader.format[2] == 'V') && (waveFileHeader.format[3] == 'E') ); // Check that the sub chunk ID is the fmt format. assert( (waveFileHeader.subChunkId[0] == 'f') && (waveFileHeader.subChunkId[1] == 'm') && (waveFileHeader.subChunkId[2] == 't') && (waveFileHeader.subChunkId[3] == ' ') ); // Check that the audio format is WAVE_FORMAT_PCM. assert( waveFileHeader.audioFormat == WAVE_FORMAT_PCM ); // Check that the wave file was recorded in stereo format. assert( waveFileHeader.numChannels == 2 ); // Check that the wave file was recorded at a sample rate of 44.1 KHz. assert( waveFileHeader.sampleRate == 44100 ); // Ensure that the wave file was recorded in 16 bit format. assert( waveFileHeader.bitsPerSample == 16 ); // Check for the data chunk header. assert( (waveFileHeader.dataChunkId[0] == 'd') && (waveFileHeader.dataChunkId[1] == 'a') && (waveFileHeader.dataChunkId[2] == 't') && (waveFileHeader.dataChunkId[3] == 'a') ); // Set the wave format of secondary buffer that this wave file will be loaded onto. waveFormat.wFormatTag = WAVE_FORMAT_PCM; waveFormat.nSamplesPerSec = 44100; waveFormat.wBitsPerSample = 16; waveFormat.nChannels = 2; waveFormat.nBlockAlign = (waveFormat.wBitsPerSample / 8) * waveFormat.nChannels; waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; waveFormat.cbSize = 0; // Set the buffer description of the secondary sound buffer that the wave file will be loaded onto. bufferDesc.dwSize = sizeof(DSBUFFERDESC); bufferDesc.dwFlags = DSBCAPS_CTRLVOLUME; bufferDesc.dwBufferBytes = waveFileHeader.dataSize; bufferDesc.dwReserved = 0; bufferDesc.lpwfxFormat = &waveFormat; bufferDesc.guid3DAlgorithm = GUID_NULL; // Create a temporary sound buffer with the specific buffer settings. result = pDirectSound->CreateSoundBuffer( &bufferDesc,&tempBuffer,NULL ); assert( !FAILED( result ) ); // Test the buffer format against the direct sound 8 interface and create the secondary buffer. result = tempBuffer->QueryInterface( IID_IDirectSoundBuffer8,(void**)&pSecondaryBuffer ); assert( !FAILED( result ) ); // Release the temporary buffer. tempBuffer->Release(); tempBuffer = 0; // Move to the beginning of the wave data which starts at the end of the data chunk header. fseek( filePtr,sizeof(WaveHeaderType),SEEK_SET ); // Create a temporary buffer to hold the wave file data. waveData = new unsigned char[ waveFileHeader.dataSize ]; assert( waveData ); // Read in the wave file data into the newly created buffer. count = fread( waveData,1,waveFileHeader.dataSize,filePtr ); assert( count == waveFileHeader.dataSize); // Close the file once done reading. error = fclose( filePtr ); assert( error == 0 ); // Lock the secondary buffer to write wave data into it. result = pSecondaryBuffer->Lock( 0,waveFileHeader.dataSize,(void**)&bufferPtr,(DWORD*)&bufferSize,NULL,0,0 ); assert( !FAILED( result ) ); // Copy the wave data into the buffer. memcpy( bufferPtr,waveData,waveFileHeader.dataSize ); // Unlock the secondary buffer after the data has been written to it. result = pSecondaryBuffer->Unlock( (void*)bufferPtr,bufferSize,NULL,0 ); assert( !FAILED( result ) ); // Release the wave data since it was copied into the secondary buffer. delete [] waveData; waveData = NULL; return Sound( pSecondaryBuffer ); }
bool SoundClass::LoadWaveFile(char* filename, IDirectSoundBuffer8** secondaryBuffer) { int error; FILE* filePtr; unsigned int count; WaveHeaderType waveFileHeader; WAVEFORMATEX waveFormat; DSBUFFERDESC bufferDesc; HRESULT result; IDirectSoundBuffer* tempBuffer; unsigned char* waveData; unsigned char* bufferPtr; unsigned long bufferSize; error = fopen_s(&filePtr, filename, "rb"); if (error != 0) { return false; } count = fread(&waveFileHeader, sizeof(waveFileHeader), 1, filePtr); if (count != 1) { return false; } if ((waveFileHeader.chunkId[0] != 'R') || (waveFileHeader.chunkId[1] != 'I') || (waveFileHeader.chunkId[2] != 'F') || (waveFileHeader.chunkId[3] != 'F')) { return false; } if ((waveFileHeader.format[0] != 'W') || (waveFileHeader.format[1] != 'A') || (waveFileHeader.format[2] != 'V') || (waveFileHeader.format[3] != 'E')) { return false; } if ((waveFileHeader.subChunkId[0] != 'f') || (waveFileHeader.subChunkId[1] != 'm') || (waveFileHeader.subChunkId[2] != 't') || (waveFileHeader.subChunkId[3] != ' ')) { return false; } if (waveFileHeader.audioFormat != WAVE_FORMAT_PCM) { return false; } if (waveFileHeader.numChannels != 2) { return false; } if (waveFileHeader.sampleRate != 44100) { return false; } if (waveFileHeader.bitsPerSample != 16) { return false; } if ((waveFileHeader.dataChunkId[0] != 'd') || (waveFileHeader.dataChunkId[1] != 'a') || (waveFileHeader.dataChunkId[2] != 't') || (waveFileHeader.dataChunkId[3] != 'a')) { return false; } waveFormat.wFormatTag = WAVE_FORMAT_PCM; waveFormat.nSamplesPerSec = 44100; waveFormat.wBitsPerSample = 16; waveFormat.nChannels = 2; waveFormat.nBlockAlign = (waveFormat.wBitsPerSample / 8) * waveFormat.nChannels; waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; waveFormat.cbSize = 0; bufferDesc.dwSize = sizeof(DSBUFFERDESC); bufferDesc.dwFlags = DSBCAPS_CTRLVOLUME; bufferDesc.dwBufferBytes = waveFileHeader.dataSize; bufferDesc.dwReserved = 0; bufferDesc.lpwfxFormat = &waveFormat; bufferDesc.guid3DAlgorithm = GUID_NULL; result = m_DirectSound->CreateSoundBuffer(&bufferDesc, &tempBuffer, NULL); if (FAILED(result)) { return false; } result = tempBuffer->QueryInterface(IID_IDirectSoundBuffer8, (void**)&*secondaryBuffer); if (FAILED(result)) { return false; } tempBuffer->Release(); tempBuffer = 0; fseek(filePtr, sizeof(WaveHeaderType), SEEK_SET); waveData = new unsigned char[waveFileHeader.dataSize]; if (!waveData) { return false; } count = fread(waveData, 1, waveFileHeader.dataSize, filePtr); if (count != waveFileHeader.dataSize) { return false; } error = fclose(filePtr); if (error != 0) { return false; } result = (*secondaryBuffer)->Lock(0, waveFileHeader.dataSize, (void**)&bufferPtr, (DWORD*)&bufferSize, NULL, 0, 0); if (FAILED(result)) { return false; } memcpy(bufferPtr, waveData, waveFileHeader.dataSize); result = (*secondaryBuffer)->Unlock((void*)bufferPtr, bufferSize, NULL, 0); if (FAILED(result)) { return false; } delete[] waveData; waveData = 0; return true; }