HRESULT CSBuffer::PlayExtended( DWORD dwFlags, int Pan, int Volume, DWORD freq ) { HRESULT rval; LPDIRECTSOUNDBUFFER Buffer = NULL; if( m_pDS==NULL ) return DSERR_UNINITIALIZED; if( m_pDS->GetSoundOn( ) ) return DS_OK; Buffer=GetFreeBuffer(); if(Buffer==NULL) return DSERR_ALLOCATED; rval=Buffer->SetPan(Pan); if(FAILED(rval)) return rval; rval=Buffer->SetVolume(Volume); if(FAILED(rval)) return rval; rval=Buffer->SetFrequency(freq); if(FAILED(rval)) return rval; if(m_Streamed) { m_sLoop=dwFlags; dwFlags=DSBPLAY_LOOPING; } m_dwLastUseTime = timeGetTime(); rval=Buffer->Play(0, 0, dwFlags); if(FAILED(rval)) return rval; return DS_OK; }
//----------------------------------------------------------------------------- // Name: CDSSound::Play() // Desc: Plays the sound using voice management flags. Pass in DSBPLAY_LOOPING // in the dwFlags to loop the sound //----------------------------------------------------------------------------- HRESULT CDSSound::Play(DWORD dwPriority, DWORD dwFlags, LONG lVolume, LONG lFrequency, LONG lPan, DWORD& outIndex) { HRESULT hr; BOOL bRestored; if (m_apDSBuffer == NULL) return CO_E_NOTINITIALIZED; LPDIRECTSOUNDBUFFER pDSB = GetFreeBuffer(outIndex); 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); pDSB->SetCurrentPosition(0); return pDSB->Play(0, dwPriority, dwFlags); }
//----------------------------------------------------------------------------- // 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 ) { HRESULT hr; BOOL bRestored; if( m_apDSBuffer == NULL ) return CO_E_NOTINITIALIZED; LPDIRECTSOUNDBUFFER 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 ); // Make DirectSound do pre-processing on sound effects Reset(); } return pDSB->Play( 0, dwPriority, dwFlags ); }
int32 FChunkCacheWorker::ProcessQueue() { SCOPE_CYCLE_COUNTER( STAT_FChunkCacheWorker_ProcessQueue ); // Add the queue to the active requests list { FScopeLock LockQueue(&QueueLock); ActiveRequests.Append(RequestQueue); RequestQueue.Empty(); } // Keep track how many request have been process this loop int32 ProcessedRequests = ActiveRequests.Num(); for (int32 RequestIndex = 0; RequestIndex < ActiveRequests.Num(); ++RequestIndex) { FChunkRequest& Request = *ActiveRequests[RequestIndex]; if (Request.RefCount.GetValue() == 0) { // ChunkRequest is no longer used by anything. Add it to the free requests lists // and release the associated buffer. ReleaseBuffer(Request.Index); ActiveRequests.RemoveAt(RequestIndex--); FreeChunkRequests.Push(&Request); } else if (Request.Buffer == NULL) { // See if the requested chunk is already cached. FChunkBuffer* CachedBuffer = GetCachedChunkBuffer(Request.Index); if (!CachedBuffer) { // This chunk is not cached. Get a free buffer if possible. CachedBuffer = GetFreeBuffer(); if (!!CachedBuffer) { // Load and verify. CachedBuffer->ChunkIndex = Request.Index; Request.Buffer = CachedBuffer; CheckSignature(Request); } } else { Request.Buffer = CachedBuffer; } if (!!CachedBuffer) { check(Request.Buffer == CachedBuffer); // Chunk is cached and trusted. We no longer need the request handle on this thread. // Let the other thread know the chunk is ready to read. Request.RefCount.Decrement(); Request.IsTrusted.Increment(); } } } return ProcessedRequests; }
bool CSingleBuffer::WriteBuffer(const char* Buffer, int nLen) { if( false==IsCanWrite(nLen) ) { return false; } char *p = GetFreeBuffer(); memcpy(p, Buffer, nLen); return true; }
//----------------------------------------------------------------------------- // 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; }
//----------------------------------------------------------------------------- // Name: CDSSound::Play3D() // Desc: Plays the sound using voice management flags. Pass in DSBPLAY_LOOPING // in the dwFlags to loop the sound //----------------------------------------------------------------------------- HRESULT CDSSound::Play3D(LPDS3DBUFFER p3DBuffer, DWORD dwPriority, DWORD dwFlags, LONG lVolume, LONG lFrequency, DWORD& outIndex) { HRESULT hr; BOOL bRestored; DWORD dwBaseFrequency; if (!m_apDSBuffer) return CO_E_NOTINITIALIZED; LPDIRECTSOUNDBUFFER pDSB = GetFreeBuffer(outIndex); if (!pDSB) 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) if (FAILED(hr = FillBufferWithSound(pDSB, FALSE))) return DXTRACE_ERR(TEXT("FillBufferWithSound"), hr); if (m_dwCreationFlags & DSBCAPS_CTRLFREQUENCY) { pDSB->GetFrequency(&dwBaseFrequency); pDSB->SetFrequency(dwBaseFrequency + lFrequency); } if (m_dwCreationFlags & DSBCAPS_CTRLVOLUME) pDSB->SetVolume(lVolume); // QI for the 3D buffer LPDIRECTSOUND3DBUFFER pDS3DBuffer; hr = pDSB->QueryInterface(IID_IDirectSound3DBuffer, (VOID**) &pDS3DBuffer); if (SUCCEEDED(hr)) { hr = pDS3DBuffer->SetAllParameters(p3DBuffer, DS3D_IMMEDIATE); if (SUCCEEDED(hr)) { hr = pDSB->SetCurrentPosition(0); hr = pDSB->Play(0, dwPriority, dwFlags); } pDS3DBuffer->Release(); } return hr; }
HRESULT CSBuffer::PlayExtended( float x, float y, float z, DWORD dwFlags ) { HRESULT rval; LPDIRECTSOUNDBUFFER Buffer = NULL; if(m_pDS==NULL) return DSERR_UNINITIALIZED; if(m_pDS->GetSoundOn()) return DS_OK; if(m_lp3dBuffer==NULL) return DSERR_UNINITIALIZED; Buffer=GetFreeBuffer(); if(Buffer==NULL) return DSERR_ALLOCATED; if(m_lp3dBuffer[m_Current]==NULL) return DSERR_UNINITIALIZED; rval=m_lp3dBuffer[m_Current]->SetPosition( x, y, z, DS3D_IMMEDIATE ); if(FAILED(rval)) return rval; m_dwLastUseTime = timeGetTime(); rval = Buffer->Play(0, 0, dwFlags); if(FAILED(rval)) return rval; return DS_OK; }
void CSH_XAudio2::Write(int16* buffer, unsigned int sampleCount, unsigned int sampleRate) { auto bufferInfo = GetFreeBuffer(); if(bufferInfo == nullptr) return; size_t bufferSize = sampleCount * sizeof(int16); if(bufferSize != bufferInfo->dataSize) { delete [] bufferInfo->data; bufferInfo->data = new uint8[bufferSize]; bufferInfo->dataSize = bufferSize; } memcpy(bufferInfo->data, buffer, bufferSize); bufferInfo->inUse = true; XAUDIO2_BUFFER buf = {}; buf.AudioBytes = bufferSize; buf.pAudioData = bufferInfo->data; buf.pContext = bufferInfo; HRESULT result = m_sourceVoice->SubmitSourceBuffer(&buf); assert(SUCCEEDED(result)); }
void CSingleBuffer::WriteBuffer(const char* Buffer, int nLen) { char *p = GetFreeBuffer(); memcpy(p, Buffer, nLen); }
void WinMIDIStreamer::Play(int looped) { UINT i; // Do we need to prepare the MIDI data? if(!registered) { // The song is already loaded in the song buffer. DeregisterSong(); // Prepare the buffers. if(song) { LPMIDIHDR mh = GetFreeBuffer(); MIDIEVENT mev; DWORD* ptr; // First add the tempo. ptr = (DWORD *) mh->lpData; *ptr++ = 0; *ptr++ = 0; *ptr++ = (MEVT_TEMPO << 24) | 1000000; // One second. mh->dwBytesRecorded = 3 * sizeof(DWORD); // Start reading the events. readPos = (byte *) song + ((musheader_t*)song)->scoreStart; readTime = 0; while(GetNextEvent(&mev)) { // Is the buffer getting full? if(mh->dwBufferLength - mh->dwBytesRecorded < 3 * sizeof(DWORD)) { // Try to get more buffer. if(!ResizeWorkBuffer(mh)) { // Not possible, buffer size has reached the limit. // We need to start working on another one. midiOutPrepareHeader((HMIDIOUT) midiStr, mh, sizeof(*mh)); mh = GetFreeBuffer(); if(!mh) return; // Oops. } } // Add the event. ptr = (DWORD *) (mh->lpData + mh->dwBytesRecorded); *ptr++ = mev.dwDeltaTime; *ptr++ = 0; *ptr++ = mev.dwEvent; mh->dwBytesRecorded += 3 * sizeof(DWORD); } // Prepare the last buffer, too. midiOutPrepareHeader((HMIDIOUT) midiStr, mh, sizeof(*mh)); } // Now there is a registered song. registered = TRUE; } playing = true; Reset(); // Stream out all buffers. for(i = 0; i < MAX_BUFFERS; ++i) { if(midiBuffers[i].dwUser) { loopBuffer = &midiBuffers[i]; midiStreamOut(midiStr, &midiBuffers[i], sizeof(midiBuffers[i])); } } // If we aren't looping, don't bother. if(!looped) loopBuffer = NULL; // Start playing. midiStreamRestart(midiStr); }
bool CSH_XAudio2::HasFreeBuffers() { return GetFreeBuffer() != nullptr; }