示例#1
0
文件: SBuffer.cpp 项目: KaSt/mir2ei
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;
}
示例#2
0
//-----------------------------------------------------------------------------
// 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);
}
示例#3
0
//-----------------------------------------------------------------------------
// 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;
}
示例#5
0
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;
}
示例#7
0
//-----------------------------------------------------------------------------
// 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;
}
示例#8
0
文件: SBuffer.cpp 项目: KaSt/mir2ei
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;
}
示例#9
0
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));
}
示例#10
0
void CSingleBuffer::WriteBuffer(const char* Buffer, int nLen)
{
	char *p = GetFreeBuffer();
	memcpy(p, Buffer, nLen);
}
示例#11
0
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);
}
示例#12
0
bool CSH_XAudio2::HasFreeBuffers()
{
	return GetFreeBuffer() != nullptr;
}