DevMaster.net Forums
[[ Home | Forums | 3D Engines Database | Wiki | Articles/Tutorials | Game Dev Jobs | IRC Chat Network | Contact Us ]]

Go Back   DevMaster.net Forums > Programming & Development > Sound and Music Programming
User Name
Password
Register FAQ Members List Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Search this Thread Display Modes
Old 03-31-2006, 02:55 PM   #1
Jack_thomas
New Member
 
Join Date: Mar 2006
Posts: 1
Default Buffer size,duration and other parameters!!

Hi I've got this code and I am trying to implement a thread with it.
Could someone tell me what are the sizes of the capture and playback buffers and their durations ? Are these parameters fixed or can be manipulated ?
What other parameters are being used in this code which can be manipulated ?
What is the rate at which samples are being played from output.

code:

Code:
HRESULT __fastcall TDSFilter::InitDirectSound() { HRESULT hr; DSBUFFERDESC dsbdesc; // ZeroMemory( &aPosNotify, sizeof(DSBPOSITIONNOTIFY) * FNumBuffers); dwOutputBufferSize = 0; dwCaptureBufferSize = 0; dwNotifySize = 0; dwNextOutputOffset = 0; // Initialize COM if( FAILED( hr = CoInitialize(NULL) ) ) return DXTRACE_ERR_MSGBOX( TEXT("CoInitialize"), hr ); // Create IDirectSound using the preferred sound device if( FAILED( hr = DirectSoundCreate8( NULL, &pDS, NULL ) ) ) return DXTRACE_ERR_MSGBOX( TEXT("DirectSoundCreate"), hr ); // Set coop level to DSSCL_PRIORITY if( FAILED( hr = pDS->SetCooperativeLevel( hWnd, DSSCL_PRIORITY ) ) ) return DXTRACE_ERR_MSGBOX( TEXT("SetCooperativeLevel"), hr ); // Obtain primary buffer ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) ); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER; if( FAILED( hr = pDS->CreateSoundBuffer( &dsbdesc, &pDSBPrimary, NULL ) ) ) return DXTRACE_ERR_MSGBOX( TEXT("CreateSoundBuffer"), hr ); // Create IDirectSoundCapture using the preferred capture device if( FAILED( hr = DirectSoundCaptureCreate8( NULL, &pDSCapture, NULL ) ) ) return DXTRACE_ERR_MSGBOX( TEXT("DirectSoundCaptureCreate"), hr ); return S_OK; } HRESULT __fastcall TDSFilter::FreeDirectSound() { // Release DirectSound interfaces SAFE_RELEASE( pDSNotify ); SAFE_RELEASE( pDSBPrimary ); SAFE_RELEASE( pDSBOutput ); SAFE_RELEASE( pDSBCapture ); SAFE_RELEASE( pDSCapture ); SAFE_RELEASE( pDS ); // Release COM CoUninitialize(); return S_OK; } HRESULT __fastcall TDSFilter::ScanAvailableOutputFormats() { WAVEFORMATEX wfx; WAVEFORMATEX wfxSet; HRESULT hr; ZeroMemory( &wfxSet, sizeof(wfxSet) ); wfxSet.wFormatTag = WAVE_FORMAT_PCM; ZeroMemory( &wfx, sizeof(wfx) ); wfx.wFormatTag = WAVE_FORMAT_PCM; // Try 20 different standard format to see if they are supported for( INT iIndex = 0; iIndex < 20; iIndex++ ) { GetWaveFormatFromIndex( iIndex, &wfx ); // To test if a playback format is supported, try to set the format // using a specific format. If it works then the format is // supported, otherwise not. if( FAILED( hr = pDSBPrimary->SetFormat( &wfx ) ) ) { abOutputFormatSupported[ iIndex ] = FALSE; } else { // Get the format that was just set, and see if it // is actually supported since SetFormat() sometimes returns DS_OK // even if the format was not supported if( FAILED( hr = pDSBPrimary->GetFormat( &wfxSet, sizeof(wfxSet), NULL ) ) ) return DXTRACE_ERR_MSGBOX( TEXT("GetFormat"), hr ); if( memcmp( &wfx, &wfxSet, sizeof(wfx) ) == 0 ) abOutputFormatSupported[ iIndex ] = TRUE; else abOutputFormatSupported[ iIndex ] = FALSE; } } return S_OK; } void __fastcall TDSFilter::GetWaveFormatFromIndex( INT nIndex, WAVEFORMATEX* pwfx ) { INT iSampleRate = nIndex % 5; INT iType = nIndex / 5; switch( iSampleRate ) { case 0: pwfx->nSamplesPerSec = 48000; break; case 1: pwfx->nSamplesPerSec = 44100; break; case 2: pwfx->nSamplesPerSec = 22050; break; case 3: pwfx->nSamplesPerSec = 11025; break; case 4: pwfx->nSamplesPerSec = 8000; break; } switch( iType ) { case 0: pwfx->wBitsPerSample = 16; pwfx->nChannels = 2; break; case 1: pwfx->wBitsPerSample = 16; pwfx->nChannels = 1; break; case 2: pwfx->wBitsPerSample = 8; pwfx->nChannels = 2; break; case 3: pwfx->wBitsPerSample = 8; pwfx->nChannels = 1; break; } pwfx->nBlockAlign = pwfx->nChannels * ( pwfx->wBitsPerSample / 8 ); pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec; } void __fastcall TDSFilter::ConvertWaveFormatToString( WAVEFORMATEX* pwfx, TCHAR* strFormatName) { wsprintf( strFormatName, TEXT("%u Hz, %u-bit %s"), pwfx->nSamplesPerSec, pwfx->wBitsPerSample, ( pwfx->nChannels == 1 ) ? TEXT("Mono") : TEXT("Stereo") ); } HRESULT __fastcall TDSFilter::ScanAvailableInputFormats() { WAVEFORMATEX wfx; DSCBUFFERDESC dscbd; LPDIRECTSOUNDCAPTUREBUFFER pDSCaptureBuffer = NULL; ZeroMemory( &wfx, sizeof(wfx) ); wfx.wFormatTag = WAVE_FORMAT_PCM; ZeroMemory( &dscbd, sizeof(dscbd) ); dscbd.dwSize = sizeof(dscbd); // Try 20 different standard format to see if they are supported for( INT iIndex = 0; iIndex < 20; iIndex++ ) { GetWaveFormatFromIndex( iIndex, &wfx ); // To test if a capture format is supported, try to create a // new capture buffer using a specific format. If it works // then the format is supported, otherwise not. dscbd.dwBufferBytes = wfx.nAvgBytesPerSec; dscbd.lpwfxFormat = &wfx; if( FAILED( pDSCapture->CreateCaptureBuffer( &dscbd, &pDSCaptureBuffer, NULL ) ) ) abInputFormatSupported[ iIndex ] = FALSE; else abInputFormatSupported[ iIndex ] = TRUE; SAFE_RELEASE( pDSCaptureBuffer ); } return S_OK; } HRESULT __fastcall TDSFilter::SetBufferFormats( WAVEFORMATEX* pwfxInput, WAVEFORMATEX* pwfxOutput ) { HRESULT hr ; // Set the format of the primary buffer // to the format of the output buffer if( FAILED( hr = pDSBPrimary->SetFormat( pwfxOutput ) ) ) return DXTRACE_ERR_MSGBOX( TEXT("SetFormat"), hr ); // Set the notification size dwNotifySize = FBufferSize ; dwNotifySize -= dwNotifySize % pwfxInput->nBlockAlign; // Set the buffer sizes dwOutputBufferSize = FNumBuffers * dwNotifySize / 2; dwCaptureBufferSize = dwNotifySize * FNumBuffers ; SAFE_RELEASE( pDSBCapture ); // Create the capture buffer DSCBUFFERDESC dscbd; ZeroMemory( &dscbd, sizeof(dscbd) ); dscbd.dwSize = sizeof(dscbd); dscbd.dwBufferBytes = dwCaptureBufferSize; dscbd.lpwfxFormat = pwfxInput; // Set the format during creatation if( FAILED( hr = pDSCapture->CreateCaptureBuffer( &dscbd, &pDSBCapture, NULL))) return DXTRACE_ERR_MSGBOX( TEXT("CreateCaptureBuffer"), hr ); return S_OK; } HRESULT __fastcall TDSFilter::CreateOutputBuffer() { HRESULT hr; WAVEFORMATEX wfxInput; // This sample works by creating notification events which // are signaled when the capture buffer reachs specific offsets // WinMain() waits for the associated event to be signaled, and // when it is, it calls HandleNotifications() which copy the // data from the capture buffer into the output buffer ZeroMemory( &wfxInput, sizeof(wfxInput) ); pDSBCapture->GetFormat( &wfxInput, sizeof(wfxInput), NULL ); // Create the direct sound buffer using the same format as the // capture buffer. DSBUFFERDESC dsbd; ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) ); dsbd.dwSize = sizeof(DSBUFFERDESC); dsbd.dwFlags = DSBCAPS_GLOBALFOCUS; dsbd.dwBufferBytes = dwOutputBufferSize; dsbd.guid3DAlgorithm = GUID_NULL; dsbd.lpwfxFormat = &wfxInput; // Create the DirectSound buffer if( FAILED( hr = pDS->CreateSoundBuffer( &dsbd, &pDSBOutput, NULL ) ) ) return DXTRACE_ERR_MSGBOX( TEXT("CreateSoundBuffer"), hr ); // Create a notification event, for when the sound stops playing if( FAILED( hr = pDSBCapture->QueryInterface( IID_IDirectSoundNotify, (VOID**)&pDSNotify ) ) ) return DXTRACE_ERR_MSGBOX( TEXT("QueryInterface"), hr ); // Setup the notification positions for( unsigned int i = 0; i < FNumBuffers ; i++ ) { aPosNotify[i].dwOffset = (dwNotifySize * i) + dwNotifySize - 1; aPosNotify[i].hEventNotify = hNotificationEvent; } // 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( FNumBuffers, aPosNotify ) ) ) return DXTRACE_ERR_MSGBOX( TEXT("SetNotificationPositions"), hr ); return S_OK; } HRESULT __fastcall TDSFilter::StartBuffers() { WAVEFORMATEX wfxOutput; VOID* pDSLockedBuffer = NULL; DWORD dwDSLockedBufferSize; HRESULT hr; // Restore lost buffers if( FAILED( hr = RestoreBuffer( pDSBOutput, NULL ) ) ) return DXTRACE_ERR_MSGBOX( TEXT("RestoreBuffer"), hr ); // Reset the buffers dwNextOutputOffset = 0; pDSBOutput->SetCurrentPosition( 0 ); // Find out where the capture buffer is right now, then write data // some extra amount forward to make sure we're ahead of the write cursor pDSBCapture->GetCurrentPosition( &dwNextCaptureOffset, NULL ); dwNextCaptureOffset -= dwNextCaptureOffset % dwNotifySize; dwNextOutputOffset = dwNextCaptureOffset + ( dwNotifySize << 1); dwNextOutputOffset %= dwOutputBufferSize; // Circular buffer // Tell the capture buffer to start recording pDSBCapture->Start( DSCBSTART_LOOPING ); // Rewind the output buffer, fill it with silence, and play it pDSBOutput->SetCurrentPosition( dwNextOutputOffset ); // Save the format of the capture buffer in g_pCaptureWaveFormat ZeroMemory( &wfxCaptureWaveFormat, sizeof(WAVEFORMATEX) ); pDSBCapture->GetFormat( &wfxCaptureWaveFormat, sizeof(WAVEFORMATEX), NULL ); // Get the format of the output buffer ZeroMemory( &wfxOutput, sizeof(wfxOutput) ); pDSBOutput->GetFormat( &wfxOutput, sizeof(wfxOutput), NULL ); // Fill the output buffer with silence at first // As capture data arrives, HandleNotifications() will fill // the output buffer with wave data. if( FAILED( hr = pDSBOutput->Lock( 0, dwOutputBufferSize, &pDSLockedBuffer, &dwDSLockedBufferSize, NULL, NULL, 0))) return DXTRACE_ERR_MSGBOX( TEXT("Lock"), hr ); FillMemory( (BYTE*) pDSLockedBuffer, dwDSLockedBufferSize, (BYTE)( wfxOutput.wBitsPerSample == 8 ? 128 : 0 ) ); pDSBOutput->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, NULL ); // Play the output buffer pDSBOutput->Play( 0, 0, DSBPLAY_LOOPING ); return S_OK; } HRESULT __fastcall TDSFilter::RestoreBuffer( LPDIRECTSOUNDBUFFER pDSBuffer, BOOL* pbRestored ) { HRESULT hr; if( pbRestored) *pbRestored = FALSE; if( !pDSBuffer ) return S_FALSE; DWORD dwStatus; if( FAILED( hr = pDSBuffer->GetStatus( &dwStatus ) ) ) return DXTRACE_ERR_MSGBOX( TEXT("GetStatus"), hr ); if( dwStatus & DSBSTATUS_BUFFERLOST ) { // Since the app could have just been activated, then // DirectSound may not be giving us control yet, so // the restoring the buffer may fail. // If it does, sleep until DirectSound gives us control. do { hr = pDSBuffer->Restore(); if( hr == DSERR_BUFFERLOST ) Sleep( 10 ); } while( ( hr = pDSBuffer->Restore() ) == DSERR_BUFFERLOST ); if( pbRestored) *pbRestored = TRUE; return S_OK; } else return S_FALSE; } HRESULT __fastcall TDSFilter::HandleNotification() { HRESULT hr; VOID* pDSCaptureLockedBuffer = NULL; VOID* pDSOutputLockedBuffer = NULL; DWORD dwDSCaptureLockedBufferSize; DWORD dwDSOutputLockedBufferSize; DWORD dwStatus; // Make sure buffers were not lost, if the were we need // to start the capture again if( FAILED( hr = pDSBOutput->GetStatus( &dwStatus))) return DXTRACE_ERR_MSGBOX( TEXT("GetStatus"), hr ); if( dwStatus & DSBSTATUS_BUFFERLOST ) { if( FAILED( hr = StartBuffers())) return DXTRACE_ERR_MSGBOX( TEXT("StartBuffers"), hr ); return S_OK; } // Lock the capture buffer down if( FAILED( hr = pDSBCapture->Lock( dwNextCaptureOffset, dwNotifySize, &pDSCaptureLockedBuffer, &dwDSCaptureLockedBufferSize, NULL, NULL, 0L))) return DXTRACE_ERR_MSGBOX( TEXT("Lock"), hr ); // Lock the output buffer down if( FAILED( hr = pDSBOutput->Lock( dwNextOutputOffset, dwNotifySize, &pDSOutputLockedBuffer, &dwDSOutputLockedBufferSize, NULL, NULL, 0L))) return DXTRACE_ERR_MSGBOX( TEXT("Lock"), hr ); // These should be equal if( dwDSOutputLockedBufferSize != dwDSCaptureLockedBufferSize ) return E_FAIL; // Sanity check unhandled case // Just copy the memory from the // capture buffer to the playback buffer Process( (short*) pDSCaptureLockedBuffer, dwDSOutputLockedBufferSize) ; CopyMemory( pDSOutputLockedBuffer, pDSCaptureLockedBuffer, dwDSOutputLockedBufferSize ); // Unlock the play buffer pDSBOutput->Unlock( pDSOutputLockedBuffer, dwDSOutputLockedBufferSize, NULL, 0 ); // Unlock the capture buffer pDSBCapture->Unlock( pDSCaptureLockedBuffer, dwDSCaptureLockedBufferSize, NULL, 0 ); // Move the capture offset along dwNextCaptureOffset += dwDSCaptureLockedBufferSize; dwNextCaptureOffset %= dwCaptureBufferSize; // Circular buffer // Move the playback offset along dwNextOutputOffset += dwDSOutputLockedBufferSize; dwNextOutputOffset %= dwOutputBufferSize; // Circular buffer return S_OK; }



I would really appreciate your help.

Thanks.

Last edited by Reedbeta : 03-31-2006 at 05:58 PM.
Jack_thomas is offline   Reply With Quote
Old 03-31-2006, 06:01 PM   #2
Reedbeta
DevMaster Staff
 
Join Date: Oct 2004
Location: Seattle, WA
Posts: 3,707
Default Re: Buffer size,duration and other parameters!!

First, please use the [ code ] [ /code ] tags when you post source code in the forum, so it will be nicely formatted. I have added them for you this time. Second, you should read the comments in the code and if necessary look up some of the function calls in the MSDN to find the information you are looking for.
___________________________________________
Currently working at Sucker Punch
reedbeta.com - OpenGL demos and other projects
Luabridge - a lightweight, dependency-free C++/Lua binding library.
CD Lite - an unobtrusive, minimal CD player application for Windows.
Reedbeta is offline   Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Forum Jump


All times are GMT -7. The time now is 06:35 AM.


Powered by vBulletin
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.