//=========================================================================== // DS_Listenerv // Call SFXLP_UPDATE at the end of every channel update. //=========================================================================== void DS_Listenerv(int property, float *values) { if(!dsListener) return; switch(property) { case SFXLP_POSITION: dsListener->SetPosition(values[VX], values[VZ], values[VY], DS3D_DEFERRED); break; case SFXLP_VELOCITY: dsListener->SetVelocity(values[VX], values[VZ], values[VY], DS3D_DEFERRED); break; case SFXLP_ORIENTATION: ListenerOrientation(values[VX]/180*PI, values[VY]/180*PI); break; case SFXLP_REVERB: ListenerEnvironment(values); break; default: DS_Listener(property, 0); } }
// --------------------------------------------------------------------------------------- // ds3d_close_listener() // // void ds3d_close_listener() { if ( pDS3D_listener != NULL ) { pDS3D_listener->Release(); pDS3D_listener = NULL; } }
static void Release(void) { if (!g_lpDSDevice) return; if ( g_lpPrimaryBuffer!=NULL ) { ULONG status; ChannelFlushAll(0); g_lpPrimaryBuffer->GetStatus(&status); if ( (status&DSBSTATUS_PLAYING)==DSBSTATUS_PLAYING ) g_lpPrimaryBuffer->Stop(); if (g_lpDS3DListener) g_lpDS3DListener->Release(); g_lpPrimaryBuffer->Release(); g_lpPrimaryBuffer = NULL; } if (V3XA.p_driverList) { array_free(V3XA.p_driverList); V3XA.p_driverList = NULL; } }
static void RLXAPI Render(void) { HRESULT hr; if (g_lpDS3DListener) { hr = SYS_DXTRACE(g_lpDS3DListener->CommitDeferredSettings()); } }
static void DriverReleaseA(void) { if (g_lpDS3DListener) g_lpDS3DListener->Release(); if (g_lpPrimaryBuffer) g_lpPrimaryBuffer->Release(); }
// --------------------------------------------------------------------------------------- // ds3d_close_listener() // // void ds3d_close_listener() { #ifndef USE_OPENAL if (pDS3D_listener != NULL) { pDS3D_listener->Release(); pDS3D_listener = NULL; } #endif }
//=========================================================================== // DS_Listener // SFXLP_UNITS_PER_METER // SFXLP_DOPPLER // SFXLP_UPDATE //=========================================================================== void DS_Listener(int property, float value) { if(!dsListener) return; switch(property) { case SFXLP_UPDATE: // Commit any deferred settings. dsListener->CommitDeferredSettings(); EAXCommitDeferred(); break; case SFXLP_UNITS_PER_METER: dsListener->SetDistanceFactor(1/value, DS3D_IMMEDIATE); break; case SFXLP_DOPPLER: dsListener->SetDopplerFactor(value, DS3D_IMMEDIATE); break; } }
static void RLXAPI UserSetParms(V3XMATRIX *lpMAT, V3XVECTOR *lpVEL, float*lpDistanceF, float*lpDopplerF, float*lpRolloffF) { HRESULT hr; if (!g_lpDS3DListener) return; if (lpMAT) { V3XVECTOR *ps = &lpMAT->v.Pos; hr = g_lpDS3DListener->SetPosition(ps->x, ps->y, ps->z, DS3D_DEFMODE); g_lpDS3DListener->SetOrientation( lpMAT->v.K.x, lpMAT->v.K.y, lpMAT->v.K.z, // 3D engine use a other orientation (right hand) lpMAT->v.J.x, lpMAT->v.J.y, lpMAT->v.J.z, DS3D_DEFMODE); } if (lpVEL) g_lpDS3DListener->SetVelocity(lpVEL->x, lpVEL->y, lpVEL->z, DS3D_DEFMODE); if (lpDistanceF) g_lpDS3DListener->SetDistanceFactor(*lpDistanceF, DS3D_DEFMODE); if (lpDopplerF) g_lpDS3DListener->SetDopplerFactor( *lpDopplerF, DS3D_DEFMODE); if (lpRolloffF) g_lpDS3DListener->SetRolloffFactor( *lpRolloffF, DS3D_DEFMODE); }
//----------------------------------------------------------------------------- // Установка всех параметров слушателя // на входе : listener - указатель на интерфейс слушателя // data - указатель на структуру в которой содержатся // параметры слушателя // на выходе : успешность установки параметров слушателя //----------------------------------------------------------------------------- int ds_SetAllListenerParameters(LPDIRECTSOUND3DLISTENER listener, LPDS3DLISTENER data, DWORD def) { int ret = false; // проверка наличия слушателя if (!listener) return ret; // установка позиции ret = (listener->SetPosition(data->vPosition.x, data->vPosition.y, data->vPosition.z, def) == DS_OK) ? true : false; // установка скорости слушателя if (ret) ret = (listener->SetVelocity(data->vVelocity.x, data->vVelocity.y, data->vVelocity.z, def) == DS_OK) ? true : false; // установка ориентации if (ret) ret = (listener->SetOrientation(data->vOrientFront.x, data->vOrientFront.y, data->vOrientFront.z, data->vOrientTop.x, data->vOrientTop.y, data->vOrientTop.z, def) == DS_OK) ? true : false; // установка дистанции if (ret) ret = (listener->SetDistanceFactor(data->flDistanceFactor, def) == DS_OK) ? true : false; // установка фактора удаления if (ret) ret = (listener->SetRolloffFactor(data->flRolloffFactor, def) == DS_OK) ? true : false; // установка эффекта допплера if (ret) ret = (listener->SetDopplerFactor(data->flDopplerFactor, def) == DS_OK) ? true : false; return ret; }
//----------------------------------------------------------------------------- // Получение всех параметров слушателя // на входе : listener - указатель на интерфейс слушателя // data - указатель на структуру в которую нужно поместить // параметры слушателя // на выходе : успешность получения параметров слушателя //----------------------------------------------------------------------------- int ds_GetAllListenerParameters(LPDIRECTSOUND3DLISTENER listener, LPDS3DLISTENER data) { // проверка наличия слушателя if (!listener) return false; // пропишем размер структуры data->dwSize = sizeof(DS3DLISTENER); // получение параметров слушателя if (listener->GetAllParameters(data) == DS_OK) return true; return false; }
//=========================================================================== // DS_Shutdown //=========================================================================== void DS_Shutdown(void) { if(!initOk) return; if(eaxListener) eaxListener->Release(); if(dsListener) dsListener->Release(); if(primary) primary->Release(); if(dsound) dsound->Release(); eaxListener = NULL; dsListener = NULL; primary = NULL; dsound = NULL; initOk = false; }
//=========================================================================== // DS_DSoundListenerOrientation // Parameters are in radians. // Example front vectors: // Yaw 0:(0,0,1), pi/2:(-1,0,0) //=========================================================================== void ListenerOrientation(float yaw, float pitch) { float front[3], up[3]; if(!dsListener) return; front[VX] = cos(yaw) * cos(pitch); front[VZ] = sin(yaw) * cos(pitch); front[VY] = sin(pitch); up[VX] = -cos(yaw) * sin(pitch); up[VZ] = -sin(yaw) * sin(pitch); up[VY] = cos(pitch); dsListener->SetOrientation(front[VX], front[VY], front[VZ], up[VX], up[VY], up[VZ], DS3D_DEFERRED); }
static int Initialize(void *hwnd) { DSBUFFERDESC primaryDesc; if (!g_lpDSDevice) return TRUE; sysMemZero(&primaryDesc, sizeof(DSBUFFERDESC)); primaryDesc.dwSize = sizeof(DSBUFFERDESC); primaryDesc.dwFlags = DSBCAPS_PRIMARYBUFFER; if (RLX.Audio.Config & RLXAUDIO_Use3D) primaryDesc.dwFlags|= DSBCAPS_CTRL3D; if (SYS_DXTRACE(g_lpDSDevice->SetCooperativeLevel((HWND)hwnd, DSSCL_EXCLUSIVE)) != DS_OK) return -1; if (SYS_DXTRACE(g_lpDSDevice->CreateSoundBuffer(&primaryDesc, &g_lpPrimaryBuffer, NULL))!=DS_OK ) return 0; else { HRESULT hr; sysMemZero(&g_cDSPCMOutFormat, sizeof(WAVEFORMATEX)); g_cDSPCMOutFormat.wFormatTag = WAVE_FORMAT_PCM; g_cDSPCMOutFormat.wBitsPerSample = 16; g_cDSPCMOutFormat.nChannels = 2; g_cDSPCMOutFormat.nSamplesPerSec = 44100; g_cDSPCMOutFormat.nBlockAlign = (uint16_t)(g_cDSPCMOutFormat.nChannels * (g_cDSPCMOutFormat.wBitsPerSample>>3)); g_cDSPCMOutFormat.nAvgBytesPerSec = (uint32_t)g_cDSPCMOutFormat.nBlockAlign * (uint32_t)g_cDSPCMOutFormat.nSamplesPerSec; hr = g_lpPrimaryBuffer->SetFormat(&g_cDSPCMOutFormat); if ( hr != DS_OK ) FindAlternateSampleFormat(); if (RLX.Audio.Config & RLXAUDIO_Use3D) { hr = SYS_DXTRACE(g_lpPrimaryBuffer->QueryInterface(IID_IDirectSound3DListener, (void**)&g_lpDS3DListener)); if (hr== DS_OK) hr = g_lpDS3DListener->SetAllParameters(&Listener3dProps, DS3D_IMMEDIATE); } } return 0; // no problemo. }
// --------------------------------------------------------------------------------------- // ds3d_update_listener() // // returns: 0 => success // -1 => failure // int ds3d_update_listener(vector *pos, vector *vel, matrix *orient) { HRESULT hr; if (DS3D_inited == FALSE) return 0; if ( pDS3D_listener == NULL ) return -1; // set the listener position if ( pos != NULL ) { hr = pDS3D_listener->SetPosition(pos->x, pos->y, pos->z, DS3D_DEFERRED); } // set the listener veclocity if ( vel != NULL ) { hr = pDS3D_listener->SetVelocity(vel->x, vel->y, vel->z, DS3D_DEFERRED); } if ( orient != NULL ) { hr = pDS3D_listener->SetOrientation( orient->fvec.x, orient->fvec.y, orient->fvec.z, orient->uvec.x, orient->uvec.y, orient->uvec.z, DS3D_DEFERRED ); } float rolloff_factor = 1.0f; if (ds_using_a3d() == true) { rolloff_factor = 3.0f; // A3D rolloff } else { rolloff_factor = 3.0f; // EAX rolloff } hr = pDS3D_listener->SetRolloffFactor( rolloff_factor, DS3D_DEFERRED ); hr = pDS3D_listener->SetDopplerFactor( 1.0f, DS3D_DEFERRED ); hr = pDS3D_listener->CommitDeferredSettings(); if ( hr != DS_OK ) { nprintf(("SOUND","Error in pDS3D_listener->CommitDeferredSettings(): %s\n", get_DSERR_text(hr) )); return -1; } return 0; }
//----------------------------------------------------------------------------- // Name: Set3DParameters() // Desc: Set the 3D buffer parameters //----------------------------------------------------------------------------- VOID Set3DParameters( FLOAT fDopplerFactor, FLOAT fRolloffFactor, FLOAT fMinDistance, FLOAT fMaxDistance ) { // Every change to 3-D sound buffer and listener settings causes // DirectSound to remix, at the expense of CPU cycles. // To minimize the performance impact of changing 3-D settings, // use the DS3D_DEFERRED flag in the dwApply parameter of any of // the IDirectSound3DListener or IDirectSound3DBuffer methods that // change 3-D settings. Then call the IDirectSound3DListener::CommitDeferredSettings // method to execute all of the deferred commands at once. DWORD dwApplyFlag = ( g_bDeferSettings ) ? DS3D_DEFERRED : DS3D_IMMEDIATE; g_dsListenerParams.flDopplerFactor = fDopplerFactor; g_dsListenerParams.flRolloffFactor = fRolloffFactor; if( g_pDSListener ) g_pDSListener->SetAllParameters( &g_dsListenerParams, dwApplyFlag ); g_dsBufferParams.flMinDistance = fMinDistance; g_dsBufferParams.flMaxDistance = fMaxDistance; if( g_pDS3DBuffer ) g_pDS3DBuffer->SetAllParameters( &g_dsBufferParams, dwApplyFlag ); }
// --------------------------------------------------------------------------------------- // ds3d_update_listener() // // returns: 0 => success // -1 => failure // int ds3d_update_listener(vec3d* pos, vec3d* vel, matrix* orient) { if (DS3D_inited == FALSE) return 0; #ifdef USE_OPENAL // set the listener position if ( pos != NULL ) { OpenAL_ErrorPrint( alListener3f(AL_POSITION, pos->xyz.x, pos->xyz.y, pos->xyz.z) ); } // set the listener velocity if ( vel != NULL ) { OpenAL_ErrorPrint( alListener3f(AL_VELOCITY, vel->xyz.x, vel->xyz.y, vel->xyz.z) ); } // set the listener orientation if ( orient != NULL ) { // uvec is up/top vector, fvec is at/front vector ALfloat list_orien[] = { orient->vec.fvec.xyz.x, orient->vec.fvec.xyz.y, orient->vec.fvec.xyz.z, orient->vec.uvec.xyz.x, orient->vec.uvec.xyz.y, orient->vec.uvec.xyz.z }; OpenAL_ErrorPrint( alListenerfv(AL_ORIENTATION, list_orien) ); } #else HRESULT hr; if (pDS3D_listener == NULL) return -1; // set the listener position if (pos != NULL) { hr = pDS3D_listener->SetPosition(pos->xyz.x, pos->xyz.y, pos->xyz.z, DS3D_DEFERRED); } // set the listener veclocity if (vel != NULL) { hr = pDS3D_listener->SetVelocity(vel->xyz.x, vel->xyz.y, vel->xyz.z, DS3D_DEFERRED); } if (orient != NULL) { hr = pDS3D_listener->SetOrientation(orient->vec.fvec.xyz.x, orient->vec.fvec.xyz.y, orient->vec.fvec.xyz.z, orient->vec.uvec.xyz.x, orient->vec.uvec.xyz.y, orient->vec.uvec.xyz.z, DS3D_DEFERRED); } float rolloff_factor = 1.0f; if (ds_using_a3d() == true) { rolloff_factor = 3.0f; // A3D rolloff } else { rolloff_factor = 3.0f; // EAX rolloff } hr = pDS3D_listener->SetRolloffFactor(rolloff_factor, DS3D_DEFERRED); hr = pDS3D_listener->SetDopplerFactor(1.0f, DS3D_DEFERRED); hr = pDS3D_listener->CommitDeferredSettings(); if (hr != DS_OK) { nprintf(("SOUND", "Error in pDS3D_listener->CommitDeferredSettings(): %s\n", get_DSERR_text(hr))); return -1; } #endif return 0; }
//----------------------------------------------------------------------------- // Name: OnInitDialog() // Desc: Initializes the dialogs (sets up UI controls, etc.) //----------------------------------------------------------------------------- VOID OnInitDialog( HWND hDlg ) { HRESULT hr; // Load the icon #ifdef _WIN64 HINSTANCE hInst = (HINSTANCE) GetWindowLongPtr( hDlg, GWLP_HINSTANCE ); #else HINSTANCE hInst = (HINSTANCE) GetWindowLong( hDlg, GWL_HINSTANCE ); #endif HICON hIcon = LoadIcon( hInst, MAKEINTRESOURCE( IDR_MAINFRAME ) ); // Create a static IDirectSound in the CSound class. // Set coop level to DSSCL_PRIORITY, and set primary buffer // format to stereo, 22kHz and 16-bit output. g_pSoundManager = new CSoundManager(); hr = g_pSoundManager->Initialize( hDlg, DSSCL_PRIORITY, 2, 22050, 16 ); // Get the 3D listener, so we can control its params hr |= g_pSoundManager->Get3DListenerInterface( &g_pDSListener ); if( FAILED(hr) ) { DXTRACE_ERR( TEXT("Get3DListenerInterface"), hr ); MessageBox( hDlg, "Error initializing DirectSound. Sample will now exit.", "DirectSound Sample", MB_OK | MB_ICONERROR ); EndDialog( hDlg, IDABORT ); return; } // Get listener parameters g_dsListenerParams.dwSize = sizeof(DS3DLISTENER); g_pDSListener->GetAllParameters( &g_dsListenerParams ); // Set the icon for this dialog. PostMessage( hDlg, WM_SETICON, ICON_BIG, (LPARAM) hIcon ); // Set big icon PostMessage( hDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIcon ); // Set small icon // Create a timer to periodically move the 3D object around SetTimer( hDlg, IDT_MOVEMENT_TIMER, 0, NULL ); // Set the UI controls SetDlgItemText( hDlg, IDC_FILENAME, TEXT("") ); SetDlgItemText( hDlg, IDC_STATUS, TEXT("No file loaded.") ); // Get handles to dialog items HWND hDopplerSlider = GetDlgItem( hDlg, IDC_DOPPLER_SLIDER ); HWND hRolloffSlider = GetDlgItem( hDlg, IDC_ROLLOFF_SLIDER ); HWND hMinDistSlider = GetDlgItem( hDlg, IDC_MINDISTANCE_SLIDER ); HWND hMaxDistSlider = GetDlgItem( hDlg, IDC_MAXDISTANCE_SLIDER ); HWND hVertSlider = GetDlgItem( hDlg, IDC_VERTICAL_SLIDER ); HWND hHorzSlider = GetDlgItem( hDlg, IDC_HORIZONTAL_SLIDER ); // Set the range and position of the sliders PostMessage( hDopplerSlider, TBM_SETRANGEMAX, TRUE, 40L ); PostMessage( hDopplerSlider, TBM_SETRANGEMIN, TRUE, 0L ); PostMessage( hRolloffSlider, TBM_SETRANGEMAX, TRUE, 40L ); PostMessage( hRolloffSlider, TBM_SETRANGEMIN, TRUE, 0L ); PostMessage( hMinDistSlider, TBM_SETRANGEMAX, TRUE, 40L ); PostMessage( hMinDistSlider, TBM_SETRANGEMIN, TRUE, 1L ); PostMessage( hMaxDistSlider, TBM_SETRANGEMAX, TRUE, 40L ); PostMessage( hMaxDistSlider, TBM_SETRANGEMIN, TRUE, 1L ); PostMessage( hVertSlider, TBM_SETRANGEMAX, TRUE, 100L ); PostMessage( hVertSlider, TBM_SETRANGEMIN, TRUE, -100L ); PostMessage( hVertSlider, TBM_SETPOS, TRUE, 100L ); PostMessage( hHorzSlider, TBM_SETRANGEMAX, TRUE, 100L ); PostMessage( hHorzSlider, TBM_SETRANGEMIN, TRUE, -100L ); PostMessage( hHorzSlider, TBM_SETPOS, TRUE, 100L ); // Set the position of the sliders SetSlidersPos( hDlg, 0.0f, 0.0f, ORBIT_MAX_RADIUS, ORBIT_MAX_RADIUS*2.0f ); }
//----------------------------------------------------------------------------- // Освобождение интерфейса слушателя // на входе : listener - указатель на интерфейс слушателя // на выходе : * //----------------------------------------------------------------------------- void ds_ReleaseListener(LPDIRECTSOUND3DLISTENER listener) { if (listener) listener->Release(); }
//----------------------------------------------------------------------------- // Name: MainDlgProc() // Desc: Handles dialog messages //----------------------------------------------------------------------------- INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { HRESULT hr; switch( msg ) { case WM_INITDIALOG: OnInitDialog( hDlg ); break; case WM_COMMAND: switch( LOWORD(wParam) ) { case IDC_SOUNDFILE: OnOpenSoundFile( hDlg ); break; case IDCANCEL: EndDialog( hDlg, IDCANCEL ); break; case IDC_PLAY: if( FAILED( hr = OnPlaySound( hDlg ) ) ) { DXTRACE_ERR( TEXT("OnPlaySound"), hr ); MessageBox( hDlg, "Error playing DirectSound buffer." "Sample will now exit.", "DirectSound Sample", MB_OK | MB_ICONERROR ); EndDialog( hDlg, IDABORT ); } break; case IDC_STOP: if( g_pSound ) { g_pSound->Stop(); g_pSound->Reset(); } // Update the UI controls to show the sound as stopped EnablePlayUI( hDlg, TRUE ); SetDlgItemText( hDlg, IDC_STATUS, TEXT("Sound stopped.") ); break; case IDC_DEFER: g_bDeferSettings = !g_bDeferSettings; OnSliderChanged( hDlg ); break; case IDC_APPLY: // Call the IDirectSound3DListener::CommitDeferredSettings // method to execute all of the deferred commands at once. // This is many times more efficent than recomputing everything // for every call. if( g_pDSListener ) g_pDSListener->CommitDeferredSettings(); break; default: return FALSE; // Didn't handle message } break; case WM_TIMER: if( wParam == IDT_MOVEMENT_TIMER ) OnMovementTimer( hDlg ); break; case WM_NOTIFY: OnSliderChanged( hDlg ); break; case WM_DESTROY: // Cleanup everything KillTimer( hDlg, 1 ); SAFE_RELEASE( g_pDSListener ); SAFE_RELEASE( g_pDS3DBuffer ); SAFE_DELETE( g_pSound ); SAFE_DELETE( g_pSoundManager ); break; default: return FALSE; // Didn't handle message } return TRUE; // Handled message }
//=========================================================================== // DS_Init //=========================================================================== int DS_Init(void) { HWND hWnd; DSBUFFERDESC desc; LPDIRECTSOUNDBUFFER bufTemp; if(initOk) return true; // Are we in verbose mode? if((verbose = ArgExists("-verbose"))) Con_Message("DS_Init(Compat): Initializing sound driver...\n"); // Get Doomsday's window handle. hWnd = (HWND) DD_GetInteger(DD_WINDOW_HANDLE); hr = DS_OK; if(ArgExists("-noeax") || FAILED(hr = EAXDirectSoundCreate(NULL, &dsound, NULL))) { // EAX can't be initialized. Use normal DS, then. if(FAILED(hr)) Error("DS_Init", "EAX 2 couldn't be initialized."); if(FAILED(hr = DirectSoundCreate(NULL, &dsound, NULL))) { Error("DS_Init", "Failed to create dsound interface."); return false; } } // Set the cooperative level. if(FAILED(hr = dsound->SetCooperativeLevel(hWnd, DSSCL_PRIORITY))) { Error("DS_Init", "Couldn't set dSound coop level."); return false; } // Get the primary buffer and the listener. primary = NULL; memset(&desc, 0, sizeof(desc)); desc.dwSize = sizeof(desc); desc.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER; dsListener = NULL; if(SUCCEEDED(dsound->CreateSoundBuffer(&desc, &primary, NULL))) { // Query the listener interface. primary->QueryInterface(IID_IDirectSound3DListener, (void**) &dsListener); } else { // Failure; get a 2D primary buffer, then. desc.dwFlags = DSBCAPS_PRIMARYBUFFER; dsound->CreateSoundBuffer(&desc, &primary, NULL); } // Start playing the primary buffer. if(primary) { if(FAILED(hr = primary->Play(0, 0, DSBPLAY_LOOPING))) Error("DS_Init", "Can't play primary buffer."); } // Try to get the EAX listener property set. // Create a temporary secondary buffer for it. eaxListener = NULL; if(SUCCEEDED(CreateDSBuffer(DSBCAPS_STATIC | DSBCAPS_CTRL3D, DSBSIZE_MIN, 22050, 8, 1, &bufTemp))) { // Now try to get the property set. if(SUCCEEDED(hr = bufTemp->QueryInterface(IID_IKsPropertySet, (void**) &eaxListener))) { DWORD support = 0, revsize = 0; // Check for support. if(FAILED(hr = eaxListener->QuerySupport( DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ENVIRONMENT, &support)) || ((support & NEEDED_SUPPORT) != NEEDED_SUPPORT)) { Error("DS_Init", "Sufficient EAX2 support not present."); eaxListener->Release(); eaxListener = NULL; } else { // EAX is supported! if(verbose) Con_Message("DS_Init(Compat): EAX2 is available.\n"); } } // Release the temporary buffer interface. bufTemp->Release(); } // Get the caps. dsCaps.dwSize = sizeof(dsCaps); dsound->GetCaps(&dsCaps); if(verbose) Con_Message("DS_Init(Compat): Number of hardware 3D " "buffers: %i\n", dsCaps.dwMaxHw3DAllBuffers); // Configure the DS3D listener. if(dsListener) { dsListener->SetDistanceFactor(1/36.0f, DS3D_DEFERRED); dsListener->SetDopplerFactor(2, DS3D_DEFERRED); } // Success! initOk = true; return true; }