Beispiel #1
0
static HRESULT WINAPI PrimaryBufferImpl_SetPan(IDirectSoundBuffer *iface, LONG pan)
{
	IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
	DirectSoundDevice *device = This->device;
	float fvol;
	HRESULT hr;
	int i;

	TRACE("(%p,%d)\n", iface, pan);

	if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
		WARN("control unavailable\n");
		return DSERR_CONTROLUNAVAIL;
	}

	if ((pan > DSBPAN_RIGHT) || (pan < DSBPAN_LEFT)) {
		WARN("invalid parameter: pan = %d\n", pan);
		return DSERR_INVALIDPARAM;
	}

	/* **** */
	EnterCriticalSection(&device->mixlock);

	for (i = 0; i < DS_MAX_CHANNELS; i++) {
		if (device->pwfx->nChannels > i){
			hr = IAudioStreamVolume_GetChannelVolume(device->volume, i, &fvol);
			if (FAILED(hr)){
				LeaveCriticalSection(&device->mixlock);
				WARN("GetChannelVolume failed: %08x\n", hr);
				return hr;
			}
		} else
			fvol = 1;

		device->volpan.dwTotalAmpFactor[i] = ((UINT16)(fvol * (DWORD)0xFFFF));
	}

	DSOUND_AmpFactorToVolPan(&device->volpan);
	if (pan != device->volpan.lPan) {
		device->volpan.lPan=pan;
		DSOUND_RecalcVolPan(&device->volpan);

		for (i = 0; i < DS_MAX_CHANNELS; i++) {
			if (device->pwfx->nChannels > i) {
				fvol = (float)((DWORD)(device->volpan.dwTotalAmpFactor[i] & 0xFFFF) / (float)0xFFFF);
				hr = IAudioStreamVolume_SetChannelVolume(device->volume, i, fvol);
				if (FAILED(hr)){
					LeaveCriticalSection(&device->mixlock);
					WARN("SetChannelVolume failed: %08x\n", hr);
					return hr;
				}
			}
		}
	}

	LeaveCriticalSection(&device->mixlock);
	/* **** */

	return DS_OK;
}
Beispiel #2
0
static HRESULT WINAPI PrimaryBufferImpl_SetVolume(
	LPDIRECTSOUNDBUFFER iface,LONG vol
) {
	DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
	DWORD ampfactors;
        HRESULT hres = DS_OK;
	TRACE("(%p,%d)\n", iface, vol);

	if (!(device->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
		WARN("control unavailable\n");
		return DSERR_CONTROLUNAVAIL;
	}

	if ((vol > DSBVOLUME_MAX) || (vol < DSBVOLUME_MIN)) {
		WARN("invalid parameter: vol = %d\n", vol);
		return DSERR_INVALIDPARAM;
	}

	/* **** */
	EnterCriticalSection(&(device->mixlock));

        waveOutGetVolume(device->hwo, &ampfactors);
        device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
        device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
        DSOUND_AmpFactorToVolPan(&device->volpan);
        if (vol != device->volpan.lVolume) {
            device->volpan.lVolume=vol;
            DSOUND_RecalcVolPan(&device->volpan);
            if (device->hwbuf) {
                hres = IDsDriverBuffer_SetVolumePan(device->hwbuf, &device->volpan);
                if (hres != DS_OK)
                    WARN("IDsDriverBuffer_SetVolumePan failed\n");
            } else {
                ampfactors = (device->volpan.dwTotalLeftAmpFactor & 0xffff) | (device->volpan.dwTotalRightAmpFactor << 16);
                waveOutSetVolume(device->hwo, ampfactors);
            }
        }

	LeaveCriticalSection(&(device->mixlock));
	/* **** */

	return hres;
}
Beispiel #3
0
static HRESULT WINAPI PrimaryBufferImpl_SetPan(
    LPDIRECTSOUNDBUFFER iface,LONG pan
) {
    IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
    DirectSoundDevice *device = This->device;
    DWORD ampfactors;
    HRESULT hres = DS_OK;
    TRACE("(%p,%d)\n", iface, pan);

    if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
        WARN("control unavailable\n");
        return DSERR_CONTROLUNAVAIL;
    }

    if ((pan > DSBPAN_RIGHT) || (pan < DSBPAN_LEFT)) {
        WARN("invalid parameter: pan = %d\n", pan);
        return DSERR_INVALIDPARAM;
    }

    /* **** */
    EnterCriticalSection(&(device->mixlock));

    waveOutGetVolume(device->hwo, &ampfactors);
    device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
    device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
    DSOUND_AmpFactorToVolPan(&device->volpan);
    if (pan != device->volpan.lPan) {
        device->volpan.lPan=pan;
        DSOUND_RecalcVolPan(&device->volpan);
        ampfactors = (device->volpan.dwTotalLeftAmpFactor & 0xffff) | (device->volpan.dwTotalRightAmpFactor << 16);
        waveOutSetVolume(device->hwo, ampfactors);
    }

    LeaveCriticalSection(&(device->mixlock));
    /* **** */

    return hres;
}
Beispiel #4
0
static HRESULT WINAPI PrimaryBufferImpl_SetPan(
	LPDIRECTSOUNDBUFFER iface,LONG pan
) {
	IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
	DirectSoundDevice *device = This->device;
	float lvol, rvol;
	HRESULT hr;
	TRACE("(%p,%d)\n", iface, pan);

	if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
		WARN("control unavailable\n");
		return DSERR_CONTROLUNAVAIL;
	}

	if ((pan > DSBPAN_RIGHT) || (pan < DSBPAN_LEFT)) {
		WARN("invalid parameter: pan = %d\n", pan);
		return DSERR_INVALIDPARAM;
	}

	/* **** */
	EnterCriticalSection(&device->mixlock);

	hr = IAudioStreamVolume_GetChannelVolume(device->volume, 0, &lvol);
	if(FAILED(hr)){
		LeaveCriticalSection(&device->mixlock);
		WARN("GetChannelVolume failed: %08x\n", hr);
		return hr;
	}

	if(device->pwfx->nChannels > 1){
		hr = IAudioStreamVolume_GetChannelVolume(device->volume, 1, &rvol);
		if(FAILED(hr)){
			LeaveCriticalSection(&device->mixlock);
			WARN("GetChannelVolume failed: %08x\n", hr);
			return hr;
		}
	}else
		rvol = 1;

	device->volpan.dwTotalLeftAmpFactor = ((UINT16)(lvol * (DWORD)0xFFFF));
	device->volpan.dwTotalRightAmpFactor = ((UINT16)(rvol * (DWORD)0xFFFF));

	DSOUND_AmpFactorToVolPan(&device->volpan);
	if (pan != device->volpan.lPan) {
		device->volpan.lPan=pan;
		DSOUND_RecalcVolPan(&device->volpan);

		lvol = (float)((DWORD)(device->volpan.dwTotalLeftAmpFactor & 0xFFFF) / (float)0xFFFF);
		hr = IAudioStreamVolume_SetChannelVolume(device->volume, 0, lvol);
		if(FAILED(hr)){
			LeaveCriticalSection(&device->mixlock);
			WARN("SetChannelVolume failed: %08x\n", hr);
			return hr;
		}

		if(device->pwfx->nChannels > 1){
			rvol = (float)((DWORD)(device->volpan.dwTotalRightAmpFactor & 0xFFFF) / (float)0xFFFF);
			hr = IAudioStreamVolume_SetChannelVolume(device->volume, 1, rvol);
			if(FAILED(hr)){
				LeaveCriticalSection(&device->mixlock);
				WARN("SetChannelVolume failed: %08x\n", hr);
				return hr;
			}
		}
	}

	LeaveCriticalSection(&device->mixlock);
	/* **** */

	return DS_OK;
}
Beispiel #5
0
void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb)
{
	/* volume, at which the sound will be played after all calcs. */
	D3DVALUE lVolume = 0;
	/* stuff for distance related stuff calc. */
	D3DVECTOR vDistance;
	D3DVALUE flDistance = 0;
	/* panning related stuff */
	D3DVALUE flAngle, flAngle2;
	D3DVECTOR vLeft;
	int i, num_main_speakers;
	float a, ingain;
	/* doppler shift related stuff */

	TRACE("(%p)\n",dsb);

	/* initial buffer volume */
	lVolume = dsb->ds3db_lVolume;
	
	switch (dsb->ds3db_ds3db.dwMode)
	{
		case DS3DMODE_DISABLE:
			TRACE("3D processing disabled\n");
			/* this one is here only to eliminate annoying warning message */
			DSOUND_RecalcVolPan (&dsb->volpan);
			return;
		case DS3DMODE_NORMAL:
			TRACE("Normal 3D processing mode\n");
			/* we need to calculate distance between buffer and listener*/
			vDistance = VectorBetweenTwoPoints(&dsb->device->ds3dl.vPosition, &dsb->ds3db_ds3db.vPosition);
			flDistance = VectorMagnitude (&vDistance);
			break;
		case DS3DMODE_HEADRELATIVE:
			TRACE("Head-relative 3D processing mode\n");
			/* distance between buffer and listener is same as buffer's position */
			vDistance = dsb->ds3db_ds3db.vPosition;
			flDistance = VectorMagnitude (&vDistance);
			break;
	}
	
	if (flDistance > dsb->ds3db_ds3db.flMaxDistance)
	{
		/* some apps don't want you to hear too distant sounds... */
		if (dsb->dsbd.dwFlags & DSBCAPS_MUTE3DATMAXDISTANCE)
		{
			dsb->volpan.lVolume = DSBVOLUME_MIN;
			DSOUND_RecalcVolPan (&dsb->volpan);		
			/* i guess mixing here would be a waste of power */
			return;
		}
		else
			flDistance = dsb->ds3db_ds3db.flMaxDistance;
	}		

	if (flDistance < dsb->ds3db_ds3db.flMinDistance)
		flDistance = dsb->ds3db_ds3db.flMinDistance;
	
	/* attenuation proportional to the distance squared, converted to millibels as in lVolume*/
	lVolume -= log10(flDistance/dsb->ds3db_ds3db.flMinDistance * flDistance/dsb->ds3db_ds3db.flMinDistance)*1000 * dsb->device->ds3dl.flRolloffFactor;
	TRACE("dist. att: Distance = %f, MinDistance = %f => adjusting volume %d to %f\n", flDistance, dsb->ds3db_ds3db.flMinDistance, dsb->ds3db_lVolume, lVolume);

	/* conning */
	/* sometimes it happens that vConeOrientation vector = (0,0,0); in this case angle is "nan" and it's useless*/
	if (dsb->ds3db_ds3db.vConeOrientation.x == 0 && dsb->ds3db_ds3db.vConeOrientation.y == 0 && dsb->ds3db_ds3db.vConeOrientation.z == 0)
	{
		TRACE("conning: cones not set\n");
	}
	else
	{
		D3DVECTOR vDistanceInv;

		vDistanceInv.x = -vDistance.x;
		vDistanceInv.y = -vDistance.y;
		vDistanceInv.z = -vDistance.z;

		/* calculate angle */
		flAngle = AngleBetweenVectorsDeg(&dsb->ds3db_ds3db.vConeOrientation, &vDistanceInv);
		/* if by any chance it happens that OutsideConeAngle = InsideConeAngle (that means that conning has no effect) */
		if (dsb->ds3db_ds3db.dwInsideConeAngle != dsb->ds3db_ds3db.dwOutsideConeAngle)
		{
			/* my test show that for my way of calc., we need only half of angles */
			DWORD dwInsideConeAngle = dsb->ds3db_ds3db.dwInsideConeAngle/2;
			DWORD dwOutsideConeAngle = dsb->ds3db_ds3db.dwOutsideConeAngle/2;
			if (dwOutsideConeAngle == dwInsideConeAngle)
				++dwOutsideConeAngle;

			/* full volume */
			if (flAngle < dwInsideConeAngle)
				flAngle = dwInsideConeAngle;
			/* min (app defined) volume */
			if (flAngle > dwOutsideConeAngle)
				flAngle = dwOutsideConeAngle;
			/* this probably isn't the right thing, but it's ok for the time being */
			lVolume += ((flAngle - dwInsideConeAngle)/(dwOutsideConeAngle - dwInsideConeAngle)) * dsb->ds3db_ds3db.lConeOutsideVolume;
		}
		TRACE("conning: Angle = %f deg; InsideConeAngle(/2) = %d deg; OutsideConeAngle(/2) = %d deg; ConeOutsideVolume = %d => adjusting volume to %f\n",
		       flAngle, dsb->ds3db_ds3db.dwInsideConeAngle/2, dsb->ds3db_ds3db.dwOutsideConeAngle/2, dsb->ds3db_ds3db.lConeOutsideVolume, lVolume);
	}
	dsb->volpan.lVolume = lVolume;

	ingain = pow(2.0, dsb->volpan.lVolume / 600.0) * 0xffff;

	if (dsb->device->pwfx->nChannels == 1)
	{
		dsb->volpan.dwTotalAmpFactor[0] = ingain;
		return;
	}
	
	/* panning */
	if (vDistance.x == 0.0f && vDistance.y == 0.0f && vDistance.z == 0.0f)
		flAngle = 0.0;
	else
	{
		vLeft = VectorProduct(&dsb->device->ds3dl.vOrientFront, &dsb->device->ds3dl.vOrientTop);
		/* To calculate angle to sound source we need to:
		 * 1) Get angle between vDistance and a plane on which angle to sound source should be 0.
		 *    Such a plane is given by vectors vOrientFront and vOrientTop, and angle between vector
		 *    and a plane equals to M_PI_2 - angle between vector and normal to this plane (vLeft in this case).
		 * 2) Determine if the source is behind or in front of us by calculating angle between vDistance
		 *    and vOrientFront.
		 */
		flAngle = AngleBetweenVectorsRad(&vLeft, &vDistance);
		flAngle2 = AngleBetweenVectorsRad(&dsb->device->ds3dl.vOrientFront, &vDistance);
		if (flAngle2 > M_PI_2)
			flAngle = -flAngle;
		flAngle -= M_PI_2;
		if (flAngle < -M_PI)
			flAngle += 2*M_PI;
	}
	TRACE("panning: Angle = %f rad, lPan = %d\n", flAngle, dsb->volpan.lPan);

	/* FIXME: Doppler Effect disabled since i have no idea which frequency to change and how to do it */
if(0)
{
	D3DVALUE flFreq, flBufferVel, flListenerVel;
	/* doppler shift*/
	if (!VectorMagnitude(&dsb->ds3db_ds3db.vVelocity) && !VectorMagnitude(&dsb->device->ds3dl.vVelocity))
	{
		TRACE("doppler: Buffer and Listener don't have velocities\n");
	}
	else if (!(dsb->ds3db_ds3db.vVelocity.x == dsb->device->ds3dl.vVelocity.x &&
	           dsb->ds3db_ds3db.vVelocity.y == dsb->device->ds3dl.vVelocity.y &&
	           dsb->ds3db_ds3db.vVelocity.z == dsb->device->ds3dl.vVelocity.z))
	{
		/* calculate length of ds3db_ds3db.vVelocity component which causes Doppler Effect
		   NOTE: if buffer moves TOWARDS the listener, it's velocity component is NEGATIVE
		         if buffer moves AWAY from listener, it's velocity component is POSITIVE */
		flBufferVel = ProjectVector(&dsb->ds3db_ds3db.vVelocity, &vDistance);
		/* calculate length of ds3dl.vVelocity component which causes Doppler Effect
		   NOTE: if listener moves TOWARDS the buffer, it's velocity component is POSITIVE
		         if listener moves AWAY from buffer, it's velocity component is NEGATIVE */
		flListenerVel = ProjectVector(&dsb->device->ds3dl.vVelocity, &vDistance);
		/* formula taken from Gianicoli D.: Physics, 4th edition: */
		/* FIXME: replace dsb->freq with appropriate frequency ! */
		flFreq = dsb->freq * ((DEFAULT_VELOCITY + flListenerVel)/(DEFAULT_VELOCITY + flBufferVel));
		TRACE("doppler: Buffer velocity (component) = %f, Listener velocity (component) = %f => Doppler shift: %d Hz -> %f Hz\n",
		      flBufferVel, flListenerVel, dsb->freq, flFreq);
		/* FIXME: replace following line with correct frequency setting ! */
		dsb->freq = flFreq;
		DSOUND_RecalcFormat(dsb);
	}
}

	for (i = 0; i < dsb->device->pwfx->nChannels; i++)
		dsb->volpan.dwTotalAmpFactor[i] = 0;

	num_main_speakers = dsb->device->pwfx->nChannels;

	if (dsb->device->lfe_channel != -1) {
		dsb->volpan.dwTotalAmpFactor[dsb->device->lfe_channel] = ingain;
		num_main_speakers--;
	}

	/* adapted from OpenAL's Alc/panning.c */
	for (i = 0; i < num_main_speakers - 1; i++)
	{
		if(flAngle >= dsb->device->speaker_angles[i] && flAngle < dsb->device->speaker_angles[i+1])
		{
			/* Sound is between speakers i and i+1 */
			a = (flAngle-dsb->device->speaker_angles[i]) / (dsb->device->speaker_angles[i+1]-dsb->device->speaker_angles[i]);
			dsb->volpan.dwTotalAmpFactor[dsb->device->speaker_num[i]] = sqrtf(1.0f-a) * ingain;
			dsb->volpan.dwTotalAmpFactor[dsb->device->speaker_num[i+1]] = sqrtf(a) * ingain;
			return;
		}
	}

	/* Sound is between last and first speakers */
	if (flAngle < dsb->device->speaker_angles[0]) { flAngle += M_PI*2.0f; }
	a = (flAngle-dsb->device->speaker_angles[i]) / (M_PI*2.0f + dsb->device->speaker_angles[0]-dsb->device->speaker_angles[i]);
	dsb->volpan.dwTotalAmpFactor[dsb->device->speaker_num[i]] = sqrtf(1.0f-a) * ingain;
	dsb->volpan.dwTotalAmpFactor[dsb->device->speaker_num[0]] = sqrtf(a) * ingain;
}
Beispiel #6
0
void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb)
{
	/* volume, at which the sound will be played after all calcs. */
	D3DVALUE lVolume = 0;
	/* stuff for distance related stuff calc. */
	D3DVECTOR vDistance;
	D3DVALUE flDistance = 0;
	/* panning related stuff */
	D3DVALUE flAngle;
	D3DVECTOR vLeft;
	/* doppler shift related stuff */
#if 0
	D3DVALUE flFreq, flBufferVel, flListenerVel;
#endif

	TRACE("(%p)\n",dsb);

	/* initial buffer volume */
	lVolume = dsb->ds3db_lVolume;
	
	switch (dsb->ds3db_ds3db.dwMode)
	{
		case DS3DMODE_DISABLE:
			TRACE("3D processing disabled\n");
			/* this one is here only to eliminate annoying warning message */
			DSOUND_RecalcVolPan (&dsb->volpan);
			break;
		case DS3DMODE_NORMAL:
			TRACE("Normal 3D processing mode\n");
			/* we need to calculate distance between buffer and listener*/
			vDistance = VectorBetweenTwoPoints(&dsb->ds3db_ds3db.vPosition, &dsb->device->ds3dl.vPosition);
			flDistance = VectorMagnitude (&vDistance);
			break;
		case DS3DMODE_HEADRELATIVE:
			TRACE("Head-relative 3D processing mode\n");
			/* distance between buffer and listener is same as buffer's position */
			flDistance = VectorMagnitude (&dsb->ds3db_ds3db.vPosition);
			break;
	}
	
	if (flDistance > dsb->ds3db_ds3db.flMaxDistance)
	{
		/* some apps don't want you to hear too distant sounds... */
		if (dsb->dsbd.dwFlags & DSBCAPS_MUTE3DATMAXDISTANCE)
		{
			dsb->volpan.lVolume = DSBVOLUME_MIN;
			DSOUND_RecalcVolPan (&dsb->volpan);		
			/* i guess mixing here would be a waste of power */
			return;
		}
		else
			flDistance = dsb->ds3db_ds3db.flMaxDistance;
	}		

	if (flDistance < dsb->ds3db_ds3db.flMinDistance)
		flDistance = dsb->ds3db_ds3db.flMinDistance;
	
	/* attenuation proportional to the distance squared, converted to millibels as in lVolume*/
	lVolume -= log10(flDistance/dsb->ds3db_ds3db.flMinDistance * flDistance/dsb->ds3db_ds3db.flMinDistance)*1000;
	TRACE("dist. att: Distance = %f, MinDistance = %f => adjusting volume %d to %f\n", flDistance, dsb->ds3db_ds3db.flMinDistance, dsb->ds3db_lVolume, lVolume);

	/* conning */
	/* sometimes it happens that vConeOrientation vector = (0,0,0); in this case angle is "nan" and it's useless*/
	if (dsb->ds3db_ds3db.vConeOrientation.x == 0 && dsb->ds3db_ds3db.vConeOrientation.y == 0 && dsb->ds3db_ds3db.vConeOrientation.z == 0)
	{
		TRACE("conning: cones not set\n");
	}
	else
	{
		/* calculate angle */
		flAngle = AngleBetweenVectorsDeg(&dsb->ds3db_ds3db.vConeOrientation, &vDistance);
		/* if by any chance it happens that OutsideConeAngle = InsideConeAngle (that means that conning has no effect) */
		if (dsb->ds3db_ds3db.dwInsideConeAngle != dsb->ds3db_ds3db.dwOutsideConeAngle)
		{
			/* my test show that for my way of calc., we need only half of angles */
			DWORD dwInsideConeAngle = dsb->ds3db_ds3db.dwInsideConeAngle/2;
			DWORD dwOutsideConeAngle = dsb->ds3db_ds3db.dwOutsideConeAngle/2;
			if (dwOutsideConeAngle == dwInsideConeAngle)
				++dwOutsideConeAngle;

			/* full volume */
			if (flAngle < dwInsideConeAngle)
				flAngle = dwInsideConeAngle;
			/* min (app defined) volume */
			if (flAngle > dwOutsideConeAngle)
				flAngle = dwOutsideConeAngle;
			/* this probably isn't the right thing, but it's ok for the time being */
			lVolume += ((dsb->ds3db_ds3db.lConeOutsideVolume)/((dwOutsideConeAngle) - (dwInsideConeAngle))) * flAngle;
		}
		TRACE("conning: Angle = %f deg; InsideConeAngle(/2) = %d deg; OutsideConeAngle(/2) = %d deg; ConeOutsideVolume = %d => adjusting volume to %f\n",
		       flAngle, dsb->ds3db_ds3db.dwInsideConeAngle/2, dsb->ds3db_ds3db.dwOutsideConeAngle/2, dsb->ds3db_ds3db.lConeOutsideVolume, lVolume);
	}
	dsb->volpan.lVolume = lVolume;
	
	/* panning */
	if (dsb->device->ds3dl.vPosition.x == dsb->ds3db_ds3db.vPosition.x &&
	    dsb->device->ds3dl.vPosition.y == dsb->ds3db_ds3db.vPosition.y &&
	    dsb->device->ds3dl.vPosition.z == dsb->ds3db_ds3db.vPosition.z) {
		dsb->volpan.lPan = 0;
		flAngle = 0.0;
	}
	else
	{
		vDistance = VectorBetweenTwoPoints(&dsb->device->ds3dl.vPosition, &dsb->ds3db_ds3db.vPosition);
		vLeft = VectorProduct(&dsb->device->ds3dl.vOrientFront, &dsb->device->ds3dl.vOrientTop);
		flAngle = AngleBetweenVectorsRad(&vLeft, &vDistance);
		/* for now, we'll use "linear formula" (which is probably incorrect); if someone has it in book, correct it */
		dsb->volpan.lPan = 10000*2*flAngle/M_PI - 10000;
	}
	TRACE("panning: Angle = %f rad, lPan = %d\n", flAngle, dsb->volpan.lPan);

	/* FIXME: Doppler Effect disabled since i have no idea which frequency to change and how to do it */
#if 0	
	/* doppler shift*/
	if ((VectorMagnitude(&ds3db_ds3db.vVelocity) == 0) && (VectorMagnitude(&dsb->device->ds3dl.vVelocity) == 0))
	{
		TRACE("doppler: Buffer and Listener don't have velocities\n");
	}
	else if (ds3db_ds3db.vVelocity != dsb->device->ds3dl.vVelocity)
	{
		/* calculate length of ds3db_ds3db.vVelocity component which causes Doppler Effect
		   NOTE: if buffer moves TOWARDS the listener, it's velocity component is NEGATIVE
		         if buffer moves AWAY from listener, it's velocity component is POSITIVE */
		flBufferVel = ProjectVector(&dsb->ds3db_ds3db.vVelocity, &vDistance);
		/* calculate length of ds3dl.vVelocity component which causes Doppler Effect
		   NOTE: if listener moves TOWARDS the buffer, it's velocity component is POSITIVE
		         if listener moves AWAY from buffer, it's velocity component is NEGATIVE */
		flListenerVel = ProjectVector(&dsb->device->ds3dl.vVelocity, &vDistance);
		/* formula taken from Gianicoli D.: Physics, 4th edition: */
		/* FIXME: replace dsb->freq with appropriate frequency ! */
		flFreq = dsb->freq * ((DEFAULT_VELOCITY + flListenerVel)/(DEFAULT_VELOCITY + flBufferVel));
		TRACE("doppler: Buffer velocity (component) = %lf, Listener velocity (component) = %lf => Doppler shift: %ld Hz -> %lf Hz\n", flBufferVel, flListenerVel,
		      dsb->freq, flFreq);
		/* FIXME: replace following line with correct frequency setting ! */
		dsb->freq = flFreq;
		DSOUND_RecalcFormat(dsb);
		DSOUND_MixToTemporary(dsb, 0, dsb->buflen);
	}
#endif	
	
	/* time for remix */
	DSOUND_RecalcVolPan(&dsb->volpan);
}