Beispiel #1
0
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" );
	}
}
Beispiel #3
0
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 *)&currentPos_, 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);
	}
Beispiel #4
0
/// @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;
}
Beispiel #5
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;
}
Beispiel #7
0
		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" );
	}
}
Beispiel #10
0
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);*/
}
Beispiel #11
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;
}
Beispiel #14
0
//	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;
}
Beispiel #15
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;
}
Beispiel #16
0
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;
}
Beispiel #19
0
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;
}
Beispiel #20
0
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;
}
Beispiel #21
0
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;
}
Beispiel #22
0
  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;
  }
Beispiel #23
0
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);


}
Beispiel #24
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;
}
Beispiel #25
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;
}
Beispiel #26
0
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;
}
Beispiel #28
0
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;
}
Beispiel #29
0
// 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 );
}
Beispiel #30
0
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;
}