Example #1
0
//===========================================================================
// 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);
	}
}
Example #2
0
// ---------------------------------------------------------------------------------------
// ds3d_close_listener()
//
//
void ds3d_close_listener()
{
	if ( pDS3D_listener != NULL ) {
		pDS3D_listener->Release();
		pDS3D_listener = NULL;
	}
}
Example #3
0
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;
	}
}
Example #4
0
static void RLXAPI Render(void)
{
	HRESULT  hr;
    if (g_lpDS3DListener)
    {
        hr = SYS_DXTRACE(g_lpDS3DListener->CommitDeferredSettings());
    }
}
Example #5
0
static void DriverReleaseA(void)
{
	if (g_lpDS3DListener)
		g_lpDS3DListener->Release();

	if (g_lpPrimaryBuffer)
		g_lpPrimaryBuffer->Release();

}
Example #6
0
// ---------------------------------------------------------------------------------------
// ds3d_close_listener()
//
//
void ds3d_close_listener()
{
#ifndef USE_OPENAL
	if (pDS3D_listener != NULL)
	{
		pDS3D_listener->Release();
		pDS3D_listener = NULL;
	}
#endif
}
Example #7
0
//===========================================================================
// 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;
	}
}
Example #8
0
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);
}
Example #9
0
//-----------------------------------------------------------------------------
//	Установка всех параметров слушателя
// на входе    :  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;
}
Example #10
0
//-----------------------------------------------------------------------------
//	Получение всех параметров слушателя
// на входе    :  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;
}
Example #11
0
//===========================================================================
// 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;
}
Example #12
0
//===========================================================================
// 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);
}
Example #13
0
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.
}
Example #14
0
// ---------------------------------------------------------------------------------------
// 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;
}
Example #15
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 );
}
Example #16
0
// ---------------------------------------------------------------------------------------
// 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;
}
Example #17
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 );
}
Example #18
0
//-----------------------------------------------------------------------------
//	Освобождение интерфейса слушателя
// на входе    :  listener  - указатель на интерфейс слушателя
// на выходе   :	*
//-----------------------------------------------------------------------------
void ds_ReleaseListener(LPDIRECTSOUND3DLISTENER listener)
{
	if (listener)
		listener->Release();
}
Example #19
0
//-----------------------------------------------------------------------------
// 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
}
Example #20
0
//===========================================================================
// 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;
}