Ejemplo n.º 1
0
//-----------------------------------------------------------------------------
// Name: CStreamingSound::HandleWaveStreamNotification()
// Desc: Handle the notification that tell us to put more wav data in the 
//       circular buffer
//-----------------------------------------------------------------------------
HRESULT CStreamingSound::HandleWaveStreamNotification()
{
    HRESULT hr;
    //DWORD   dwCurrentPlayPos;
    //DWORD   dwPlayDelta;
    //DWORD   dwBytesWrittenToBuffer;
    //VOID*   pDSLockedBuffer = NULL;
    //VOID*   pDSLockedBuffer2 = NULL;
    //DWORD   dwDSLockedBufferSize;
    //DWORD   dwDSLockedBufferSize2;

    if( m_pDSB == NULL )
        return CO_E_NOTINITIALIZED;

    // Restore the buffer if it was lost
    BOOL bRestored;
    if( FAILED( hr = RestoreBuffer( &bRestored ) ) )
        return DXTRACE_ERR( TEXT("RestoreBuffer"), hr );

    if( bRestored )
    	hr = FillBufferWithSound( TRUE );	//full it with data as it's restored
	else
		hr = FillBufferWithSound(FALSE);			// add one frame into it for play

    // The buffer was restored, so we need to fill it with new data
    if( FAILED( hr) )
        return DXTRACE_ERR( TEXT("FillBufferWithSound"), hr );

    return S_OK;
}
Ejemplo n.º 2
0
HRESULT DDuplexAudio::HandleRenderNotification(void)
{
	HRESULT hr;
	BOOL bRestored;

    if( FAILED( hr = RestoreBuffer( &bRestored ) ) )
		return hr;

	if( bRestored )
    	hr = FillBufferWithSound( TRUE );	//full it with data as it's restored
	else
		hr = FillBufferWithSound(FALSE);			// add one frame into it for play

	return hr;
}
Ejemplo n.º 3
0
//-----------------------------------------------------------------------------
// Name: CDSStreamingSound::Reset()
// Desc: Resets the sound so it will begin playing at the beginning
//-----------------------------------------------------------------------------
HRESULT CDSStreamingSound::Reset()
{
	HRESULT hr;

	if (!m_apDSBuffer[0] || !m_pWaveFile) return CO_E_NOTINITIALIZED;

	m_dwLastPlayPos     = 0;
	m_dwPlayProgress    = 0;
	m_dwNextWriteOffset = 0;
	m_dwTriggerWriteOffset = m_dwDSBufferSize - m_dwNotifySize;
	m_bFillNextNotificationWithSilence = FALSE;
	stopCount = 0;

	// Restore the buffer if it was lost
	BOOL bRestored;
	if (FAILED(hr = RestoreBuffer(m_apDSBuffer[0], &bRestored)))
		return DXTRACE_ERR(TEXT("RestoreBuffer"), hr);

	if (bRestored)
		if (FAILED(hr = FillBufferWithSound(m_apDSBuffer[0], FALSE)))
			return DXTRACE_ERR(TEXT("FillBufferWithSound"), hr);

	m_pWaveFile->Reset();
	return m_apDSBuffer[0]->SetCurrentPosition(0L);
}
Ejemplo n.º 4
0
/*
===============
idAudioBufferWIN32::Play
Desc: Plays the sound using voice management flags.  Pass in DSBPLAY_LOOPING
      in the dwFlags to loop the sound
===============
*/
int idAudioBufferWIN32::Play(dword dwPriority, dword dwFlags)
{
	int hr;
	bool    bRestored;

	if (m_apDSBuffer == NULL) {
		return -1;
	}

	// Restore the buffer if it was lost
	if (FAILED(hr = RestoreBuffer(m_apDSBuffer, &bRestored))) {
		common->Error(TEXT("RestoreBuffer"), hr);
	}

	if (bRestored) {
		// The buffer was restored, so we need to fill it with new data
		if (FAILED(hr = FillBufferWithSound(m_apDSBuffer, false))) {
			common->Error(TEXT("FillBufferWithSound"), hr);
		}

		// Make DirectSound do pre-processing on sound effects
		Reset();
	}

	m_apDSBuffer->Play(0, dwPriority, dwFlags);
	return 0;
}
Ejemplo n.º 5
0
//-----------------------------------------------------------------------------
// Name: CStreamingSound::Reset()
// Desc: Resets the sound so it will begin playing at the beginning
//-----------------------------------------------------------------------------
HRESULT CStreamingSound::Reset()
{
	HRESULT hr;

	if( m_apDSBuffer[0] == NULL || m_pWaveFile == NULL )
		return CO_E_NOTINITIALIZED;

	m_dwLastPlayPos     = 0;
	m_dwPlayProgress    = 0;
	m_dwNextWriteOffset = 0;
	m_bFillNextNotificationWithSilence = FALSE;

	// Restore the buffer if it was lost
	BOOL bRestored;
	if( FAILED( hr = RestoreBuffer( m_apDSBuffer[0], &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( m_apDSBuffer[0], FALSE ) ) )
			return DXTRACE_ERR( TEXT("FillBufferWithSound"), hr );
	}

	m_pWaveFile->ResetFile();

	return m_apDSBuffer[0]->SetCurrentPosition( 0L );
}
Ejemplo n.º 6
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 );
}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
0
bool CN3SndObj::Create(const std::string& szFN, e_SndType eType)
{
	if(NULL == s_lpDS) return false;
	if(SNDTYPE_2D != eType && SNDTYPE_3D != eType) return false;
	if(m_lpDSBuff) this->Init();

	CWaveFile	WaveFile;
	HRESULT hr = WaveFile.Open(szFN.c_str(), NULL, 1);	//#define WAVEFILE_READ   1
	if(FAILED(hr))
	{
#ifdef _N3GAME
		if(!szFN.empty()) CLogWriter::Write("CN3SndEng::LoadSource - WaveFile Open Failed.. (%s)", szFN.c_str());
#endif
		return false;
	}

	DSBUFFERDESC dsbd;
    ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
    dsbd.dwSize          = sizeof(DSBUFFERDESC);
	dsbd.dwBufferBytes   = WaveFile.GetSize();
	dsbd.lpwfxFormat     = WaveFile.m_pwfx;

	if(SNDTYPE_2D == eType) // 2D 음원
	{
		dsbd.dwFlags		 = DSBCAPS_CTRLVOLUME; // | DSBCAPS_STATIC;
	}
	else if(SNDTYPE_3D == eType)	//3D 음원..
	{
		dsbd.dwFlags         = DSBCAPS_CTRL3D | DSBCAPS_MUTE3DATMAXDISTANCE; // | DSBCAPS_STATIC;
		dsbd.guid3DAlgorithm = DS3DALG_HRTF_LIGHT;
	}

	hr = s_lpDS->CreateSoundBuffer( &dsbd, &m_lpDSBuff, NULL );
	if(FAILED(hr))
	{
#ifdef _N3GAME
		CLogWriter::Write("CN3SndObj::Create - CreateSoundBuffer Failed.. (%)", szFN.c_str());
#endif
		return false;
	}

    if(!FillBufferWithSound(&WaveFile))
	{
#ifdef _N3GAME
		CLogWriter::Write("CN3SndObj::Create - FillBufferWithSound Failed.. (%)", szFN.c_str());
#endif
		return false;
	}

	m_lpDSBuff->SetCurrentPosition(0);
	if(SNDTYPE_3D == eType)	//3D 음원..
		if(S_OK != m_lpDSBuff->QueryInterface(IID_IDirectSound3DBuffer, (VOID**)(&m_lpDS3DBuff)))
			return false;

	m_szFileName = szFN; // 파일 이름을 기록한다..

	s_bNeedDeferredTick = true;	// 3D Listener CommitDeferredSetting
	return true;
}
Ejemplo n.º 9
0
/*
===============
idAudioBufferWIN32::idAudioBuffer
===============
*/
idAudioBufferWIN32::idAudioBufferWIN32( LPDIRECTSOUNDBUFFER apDSBuffer, dword dwDSBufferSize, idWaveFile* pWaveFile ) {

    m_apDSBuffer = apDSBuffer;

    m_dwDSBufferSize = dwDSBufferSize;
    m_pWaveFile      = pWaveFile;

	if (pWaveFile) {
	    FillBufferWithSound( m_apDSBuffer, false );

		m_apDSBuffer->SetCurrentPosition(0);
	}
}
Ejemplo n.º 10
0
//-----------------------------------------------------------------------------
// Name: CDSSound::CDSSound()
// Desc: Constructs the class
//-----------------------------------------------------------------------------
CDSSound::CDSSound(LPDIRECTSOUNDBUFFER* apDSBuffer, DWORD DSBufferSize,
			   DWORD dwNumBuffers, Audio::CAudioFile* pWaveFile, DWORD dwCreationFlags)
{
	m_apDSBuffer = new LPDIRECTSOUNDBUFFER[dwNumBuffers];
	n_assert(m_apDSBuffer);
	for (DWORD i = 0; i < dwNumBuffers; ++i)
		m_apDSBuffer[i] = apDSBuffer[i];

	m_dwDSBufferSize = DSBufferSize;
	m_dwNumBuffers = dwNumBuffers;
	m_pWaveFile = pWaveFile;
	m_dwCreationFlags = dwCreationFlags;

	FillBufferWithSound(m_apDSBuffer[0], FALSE);
}
Ejemplo n.º 11
0
//-----------------------------------------------------------------------------
// 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;
}
Ejemplo n.º 12
0
//-----------------------------------------------------------------------------
// Name: CSound::CSound()
// Desc: Constructs the class
//-----------------------------------------------------------------------------
CSound::CSound( LPDIRECTSOUNDBUFFER* apDSBuffer, DWORD dwDSBufferSize, 
                DWORD dwNumBuffers, CPCMFile* CPCMFile )
{
    DWORD i;

    m_apDSBuffer = new LPDIRECTSOUNDBUFFER[dwNumBuffers];
    for( i=0; i<dwNumBuffers; i++ )
        m_apDSBuffer[i] = apDSBuffer[i];

    m_dwDSBufferSize = dwDSBufferSize;
    m_dwNumBuffers   = dwNumBuffers;
    m_pPCMFile       = CPCMFile;

    FillBufferWithSound( m_apDSBuffer[0], FALSE );

    // Make DirectSound do pre-processing on sound effects
    for( i=0; i<dwNumBuffers; i++ )
        m_apDSBuffer[i]->SetCurrentPosition(0);
}
Ejemplo n.º 13
0
//-----------------------------------------------------------------------------
// Name: CSound::CSound()
// Desc: Constructs the class
//-----------------------------------------------------------------------------
CSound::CSound( LPDIRECTSOUNDBUFFER* apDSBuffer, DWORD dwDSBufferSize, 
                DWORD dwNumBuffers, CWaveFile* pWaveFile, DWORD dwCreationFlags )
{
    DWORD i;

    m_apDSBuffer = new LPDIRECTSOUNDBUFFER[dwNumBuffers];
    if( NULL != m_apDSBuffer )
    {
        for( i=0; i<dwNumBuffers; i++ )
            m_apDSBuffer[i] = apDSBuffer[i];
    
        m_dwDSBufferSize = dwDSBufferSize;
        m_dwNumBuffers   = dwNumBuffers;
        m_pWaveFile      = pWaveFile;
        m_dwCreationFlags = dwCreationFlags;
        
        FillBufferWithSound( m_apDSBuffer[0], FALSE );
    }
}
Ejemplo n.º 14
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;
}
Ejemplo n.º 15
0
//-----------------------------------------------------------------------------
// Name: CSound::CSound()
// Desc: Constructs the class
//-----------------------------------------------------------------------------
CSound::CSound( IDirectSoundBuffer** apDSBuffer, DWORD dwDSBufferSize,
				DWORD dwNumBuffers, CWaveFile* pWaveFile, DWORD dwCreationFlags )
{
	DWORD i;

	if( dwNumBuffers <= 0 )
		return;

	m_apDSBuffer = new IDirectSoundBuffer*[dwNumBuffers];
	if( NULL != m_apDSBuffer )
	{
		for( i=0; i<dwNumBuffers; i++ )
			m_apDSBuffer[i] = apDSBuffer[i];

		m_dwDSBufferSize = dwDSBufferSize;
		m_dwNumBuffers   = dwNumBuffers;
		m_pWaveFile      = pWaveFile;
		m_dwCreationFlags = dwCreationFlags;

		FillBufferWithSound( m_apDSBuffer[0], FALSE );
	}
}
Ejemplo n.º 16
0
    // ////////////////////////////////////////////////////////////////////
    //
    // ////////////////////////////////////////////////////////////////////
    bool DirectSound8AudioBuffer::VOnRestore()
    {
        HRESULT hr;
        BOOL bRestored;

        // Restore the buffer if it was lost
        if(FAILED(hr = RestoreBuffer(&bRestored))) {
            GF_LOG_TRACE_ERR("DirectSound8AudioBuffer::VOnRestore()", "Failed to restore the buffer");
            return (false);
        }

        if(bRestored) {
            // The buffer was restored, so we need to fill it with new data
            if(FAILED(hr = FillBufferWithSound())) {
                GF_LOG_TRACE_ERR("DirectSound8AudioBuffer::VOnRestore()", "Failed to fill the buffer with sound");
                return (false);
            }
        } else {
            GF_LOG_TRACE_ERR("DirectSound8AudioBuffer::VOnRestore()", "Failed to restore the buffer so cannot fill it with sound");
        }

        return (true);
    }
Ejemplo n.º 17
0
    // ////////////////////////////////////////////////////////////////////
    //
    // ////////////////////////////////////////////////////////////////////
    DirectSound8AudioBuffer::DirectSound8AudioBuffer(LPDIRECTSOUNDBUFFER sample, shared_ptr<SoundResHandle> resource)\
:
    AudioBuffer(resource), m_Sample(sample)
    {
        FillBufferWithSound();
    }
Ejemplo n.º 18
0
//-----------------------------------------------------------------------------
// Name: CDSStreamingSound::HandleWaveStreamNotification()
// Desc: Handle the notification that tells us to put more wav data in the
//       circular buffer
//-----------------------------------------------------------------------------
HRESULT CDSStreamingSound::HandleWaveStreamNotification(BOOL bLoopedPlay)
{
	if (!m_apDSBuffer || !m_pWaveFile) return CO_E_NOTINITIALIZED;

	HRESULT hr;
	DWORD   dwCurrentPlayPos;
	DWORD   dwPlayDelta;
	DWORD   dwBytesWrittenToBuffer;
	VOID*   pDSLockedBuffer = NULL;
	VOID*   pDSLockedBuffer2 = NULL;
	DWORD   dwDSLockedBufferSize;
	DWORD   dwDSLockedBufferSize2;

    // Restore the buffer if it was lost
    BOOL bRestored;
    if (FAILED(hr = RestoreBuffer(m_apDSBuffer[0], &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(m_apDSBuffer[0], FALSE)))
            return DXTRACE_ERR(TEXT("FillBufferWithSound"), hr);
        return S_OK;
    }

    // Lock the DirectSound buffer
    if (FAILED(hr = m_apDSBuffer[0]->Lock(m_dwNextWriteOffset, m_dwNotifySize,
                                          &pDSLockedBuffer, &dwDSLockedBufferSize,
                                          &pDSLockedBuffer2, &dwDSLockedBufferSize2, 0L)))
        return DXTRACE_ERR(TEXT("Lock"), hr);

    // m_dwDSBufferSize and m_dwNextWriteOffset are both multiples of m_dwNotifySize,
    // it should the second buffer, so it should never be valid
    if (pDSLockedBuffer2) return E_UNEXPECTED;

	WORD BitsPerSample = m_pWaveFile->GetFormat()->wBitsPerSample;
    if (!m_bFillNextNotificationWithSilence)
    {
        dwBytesWrittenToBuffer = m_pWaveFile->Read((char*) pDSLockedBuffer, dwDSLockedBufferSize);
    }
    else
    {
        // Fill the DirectSound buffer with silence
        this->stopCount++;
        FillMemory(pDSLockedBuffer, dwDSLockedBufferSize,
                   (BYTE)(BitsPerSample == 8 ? 128 : 0));
        dwBytesWrittenToBuffer = dwDSLockedBufferSize;
    }

    // If the number of bytes written is less than the
    // amount we requested, we have a short file.
    if (dwBytesWrittenToBuffer < dwDSLockedBufferSize)
    {
        if (!bLoopedPlay)
        {
            // Fill in silence for the rest of the buffer.
            FillMemory((BYTE*) pDSLockedBuffer + dwBytesWrittenToBuffer,
                       dwDSLockedBufferSize - dwBytesWrittenToBuffer,
                       (BYTE)(BitsPerSample == 8 ? 128 : 0));

            // Any future notifications should just fill the buffer with silence
            m_bFillNextNotificationWithSilence = TRUE;
        }
        else
        {
            // We are looping, so reset the file and fill the buffer with wav data
            DWORD dwReadSoFar = dwBytesWrittenToBuffer;    // From previous call above.
            while (dwReadSoFar < dwDSLockedBufferSize)
            {
                // This will keep reading in until the buffer is full (for very short files).
                m_pWaveFile->Reset();
                dwBytesWrittenToBuffer = m_pWaveFile->Read((char*)pDSLockedBuffer + dwReadSoFar,
                                                           dwDSLockedBufferSize - dwReadSoFar);
                n_assert(dwBytesWrittenToBuffer > 0);
                dwReadSoFar += dwBytesWrittenToBuffer;
            }
        }
    }

    // Unlock the DirectSound buffer
    m_apDSBuffer[0]->Unlock(pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0);

    // Figure out how much data has been played so far.  When we have played
    // past the end of the file, we will either need to start filling the
    // buffer with silence or starting reading from the beginning of the file,
    // depending if the user wants to loop the sound
    if (FAILED(hr = m_apDSBuffer[0]->GetCurrentPosition(&dwCurrentPlayPos, NULL)))
        return DXTRACE_ERR(TEXT("GetCurrentPosition"), hr);

    // Check to see if the position counter looped
    if (dwCurrentPlayPos < m_dwLastPlayPos)
        dwPlayDelta = (m_dwDSBufferSize - m_dwLastPlayPos) + dwCurrentPlayPos;
    else
        dwPlayDelta = dwCurrentPlayPos - m_dwLastPlayPos;

    m_dwPlayProgress += dwPlayDelta;
    m_dwLastPlayPos = dwCurrentPlayPos;

    // If we are now filling the buffer with silence, then we have found the end so
    // check to see if the entire sound has played, if it has then stop the buffer.
    if (m_bFillNextNotificationWithSilence)
    {
        // We don't want to cut off the sound before it's done playing.
        if (m_dwPlayProgress >= (DWORD)m_pWaveFile->GetSize())
            m_apDSBuffer[0]->Stop();
    }

    // Update where the buffer will lock (for next time)
    m_dwNextWriteOffset += dwDSLockedBufferSize;
    m_dwTriggerWriteOffset = m_dwNextWriteOffset - m_dwNotifySize;
    m_dwNextWriteOffset %= m_dwDSBufferSize; // Circular buffer
    m_dwTriggerWriteOffset %= m_dwDSBufferSize;

    return S_OK;
}
Ejemplo n.º 19
0
void DDuplexAudio::Execute(Thread::Arg arg)
{
	DWORD dwResult;
	HRESULT hr;

	LOGINFO("DDuplexAudio Starting up ...");

	ResetCapture();
	ResetPlay();
	FillBufferWithSound(TRUE);	//full it first with silence first.

	if (FAILED(hr = StartCapture()) || FAILED(hr = StartPlay()))
	{
		LOGWARNING("DDuplexAudio::Execute:Failed to start Capturing or Playing,shutting down...");
		Shutdown();
	}

	while (!_is_shutdown_requested)
	{
		dwResult = MsgWaitForMultipleObjects( 2, &_events[0], 
                                              FALSE, INFINITE, QS_ALLEVENTS );

		switch( dwResult )
        {
            case WAIT_OBJECT_0 + 0:
                // rendering notification is signaled
                // This means that DirectSound just finished playing 
                // a piece of the buffer, so we need to fill the circular 
                // buffer with new sound from the wav file

                if( FAILED( hr = HandleRenderNotification() ) )
                {
                    //DXTRACE_ERR( TEXT("RecordCapturedData"), hr );
                    //MessageBox( NULL, TEXT("Error handling DirectSound notifications. Sample will now exit."), TEXT("DirectSound Sample"), 
                    //           MB_OK | MB_ICONERROR );
					LOGDEBUG("DDuplexAudio::Execute:Failed to HandleRenderNotification,shutting down...");
                    _is_shutdown_requested = TRUE;
                }
                break;

			case WAIT_OBJECT_0 + 1:
				// capturing notification is signaled
                // This means that DirectSound just finished capturing 
                // a piece of the buffer, so we can copy the captured data from the recorder buffer.

                if( FAILED( hr = HandleCaptureNotification() ) )
                {
                    //DXTRACE_ERR( TEXT("RecordCapturedData"), hr );
                    //MessageBox( NULL, TEXT("Error handling DirectSound notifications. Sample will now exit."), TEXT("DirectSound Sample"), 
                    //           MB_OK | MB_ICONERROR );
					LOGDEBUG("DDuplexAudio::Execute:Failed to HandleCaptureNotification,shutting down...");
                    _is_shutdown_requested = TRUE;
                }
                break;

            case WAIT_OBJECT_0 + 2:
                //// Windows messages are available
                //while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) 
                //{ 
                //    if( !IsDialogMessage( hDlg, &msg ) )  
                //    {
                //        TranslateMessage( &msg ); 
                //        DispatchMessage( &msg ); 
                //    }

                //    if( msg.message == WM_QUIT )
                //        bDone = TRUE;
			default :
				break;
		}
	}

	StopCapture();
	StopPlay();

	LOGINFO("DDuplexAudio shutdowned.");
}