xref: /reactos/dll/directx/wine/dsound/sound3d.c (revision c2c66aff)
1*c2c66affSColin Finck /*  			DirectSound
2*c2c66affSColin Finck  *
3*c2c66affSColin Finck  * Copyright 1998 Marcus Meissner
4*c2c66affSColin Finck  * Copyright 1998 Rob Riggs
5*c2c66affSColin Finck  * Copyright 2000-2001 TransGaming Technologies, Inc.
6*c2c66affSColin Finck  * Copyright 2002-2003 Rok Mandeljc <rok.mandeljc@gimb.org>
7*c2c66affSColin Finck  *
8*c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
9*c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
10*c2c66affSColin Finck  * License as published by the Free Software Foundation; either
11*c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
12*c2c66affSColin Finck  *
13*c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
14*c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16*c2c66affSColin Finck  * Lesser General Public License for more details.
17*c2c66affSColin Finck  *
18*c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
19*c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
20*c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21*c2c66affSColin Finck  */
22*c2c66affSColin Finck /*
23*c2c66affSColin Finck  * Most thread locking is complete. There may be a few race
24*c2c66affSColin Finck  * conditions still lurking.
25*c2c66affSColin Finck  *
26*c2c66affSColin Finck  * Tested with a Soundblaster clone, a Gravis UltraSound Classic,
27*c2c66affSColin Finck  * and a Turtle Beach Tropez+.
28*c2c66affSColin Finck  *
29*c2c66affSColin Finck  * TODO:
30*c2c66affSColin Finck  *	Implement SetCooperativeLevel properly (need to address focus issues)
31*c2c66affSColin Finck  *	Implement DirectSound3DBuffers (stubs in place)
32*c2c66affSColin Finck  *	Use hardware 3D support if available
33*c2c66affSColin Finck  *      Add critical section locking inside Release and AddRef methods
34*c2c66affSColin Finck  *      Handle static buffers - put those in hardware, non-static not in hardware
35*c2c66affSColin Finck  *      Hardware DuplicateSoundBuffer
36*c2c66affSColin Finck  *      Proper volume calculation, and setting volume in HEL primary buffer
37*c2c66affSColin Finck  *      Optimize WINMM and negotiate fragment size, decrease DS_HEL_MARGIN
38*c2c66affSColin Finck  */
39*c2c66affSColin Finck 
40*c2c66affSColin Finck #include "dsound_private.h"
41*c2c66affSColin Finck 
42*c2c66affSColin Finck /* default velocity of sound in the air */
43*c2c66affSColin Finck #define DEFAULT_VELOCITY 340
44*c2c66affSColin Finck 
45*c2c66affSColin Finck /*******************************************************************************
46*c2c66affSColin Finck  *              Auxiliary functions
47*c2c66affSColin Finck  */
48*c2c66affSColin Finck 
49*c2c66affSColin Finck /* scalar product (I believe it's called dot product in English) */
ScalarProduct(const D3DVECTOR * a,const D3DVECTOR * b)50*c2c66affSColin Finck static inline D3DVALUE ScalarProduct (const D3DVECTOR *a, const D3DVECTOR *b)
51*c2c66affSColin Finck {
52*c2c66affSColin Finck 	D3DVALUE c;
53*c2c66affSColin Finck 	c = (a->x*b->x) + (a->y*b->y) + (a->z*b->z);
54*c2c66affSColin Finck 	TRACE("(%f,%f,%f) * (%f,%f,%f) = %f)\n", a->x, a->y, a->z, b->x, b->y,
55*c2c66affSColin Finck 	      b->z, c);
56*c2c66affSColin Finck 	return c;
57*c2c66affSColin Finck }
58*c2c66affSColin Finck 
59*c2c66affSColin Finck /* vector product (I believe it's called cross product in English */
VectorProduct(const D3DVECTOR * a,const D3DVECTOR * b)60*c2c66affSColin Finck static inline D3DVECTOR VectorProduct (const D3DVECTOR *a, const D3DVECTOR *b)
61*c2c66affSColin Finck {
62*c2c66affSColin Finck 	D3DVECTOR c;
63*c2c66affSColin Finck 	c.x = (a->y*b->z) - (a->z*b->y);
64*c2c66affSColin Finck 	c.y = (a->z*b->x) - (a->x*b->z);
65*c2c66affSColin Finck 	c.z = (a->x*b->y) - (a->y*b->x);
66*c2c66affSColin Finck 	TRACE("(%f,%f,%f) x (%f,%f,%f) = (%f,%f,%f)\n", a->x, a->y, a->z, b->x, b->y,
67*c2c66affSColin Finck 	      b->z, c.x, c.y, c.z);
68*c2c66affSColin Finck 	return c;
69*c2c66affSColin Finck }
70*c2c66affSColin Finck 
71*c2c66affSColin Finck /* magnitude (length) of vector */
VectorMagnitude(const D3DVECTOR * a)72*c2c66affSColin Finck static inline D3DVALUE VectorMagnitude (const D3DVECTOR *a)
73*c2c66affSColin Finck {
74*c2c66affSColin Finck 	D3DVALUE l;
75*c2c66affSColin Finck 	l = sqrt (ScalarProduct (a, a));
76*c2c66affSColin Finck 	TRACE("|(%f,%f,%f)| = %f\n", a->x, a->y, a->z, l);
77*c2c66affSColin Finck 	return l;
78*c2c66affSColin Finck }
79*c2c66affSColin Finck 
80*c2c66affSColin Finck /* conversion between radians and degrees */
RadToDeg(D3DVALUE angle)81*c2c66affSColin Finck static inline D3DVALUE RadToDeg (D3DVALUE angle)
82*c2c66affSColin Finck {
83*c2c66affSColin Finck 	D3DVALUE newangle;
84*c2c66affSColin Finck 	newangle = angle * (360/(2*M_PI));
85*c2c66affSColin Finck 	TRACE("%f rad = %f deg\n", angle, newangle);
86*c2c66affSColin Finck 	return newangle;
87*c2c66affSColin Finck }
88*c2c66affSColin Finck 
89*c2c66affSColin Finck /* angle between vectors - rad version */
AngleBetweenVectorsRad(const D3DVECTOR * a,const D3DVECTOR * b)90*c2c66affSColin Finck static inline D3DVALUE AngleBetweenVectorsRad (const D3DVECTOR *a, const D3DVECTOR *b)
91*c2c66affSColin Finck {
92*c2c66affSColin Finck 	D3DVALUE la, lb, product, angle, cos;
93*c2c66affSColin Finck 	/* definition of scalar product: a*b = |a|*|b|*cos... therefore: */
94*c2c66affSColin Finck 	product = ScalarProduct (a,b);
95*c2c66affSColin Finck 	la = VectorMagnitude (a);
96*c2c66affSColin Finck 	lb = VectorMagnitude (b);
97*c2c66affSColin Finck 	if (!la || !lb)
98*c2c66affSColin Finck 		return 0;
99*c2c66affSColin Finck 
100*c2c66affSColin Finck 	cos = product/(la*lb);
101*c2c66affSColin Finck 	angle = acos(cos);
102*c2c66affSColin Finck 	TRACE("angle between (%f,%f,%f) and (%f,%f,%f) = %f radians (%f degrees)\n",  a->x, a->y, a->z, b->x,
103*c2c66affSColin Finck 	      b->y, b->z, angle, RadToDeg(angle));
104*c2c66affSColin Finck 	return angle;
105*c2c66affSColin Finck }
106*c2c66affSColin Finck 
AngleBetweenVectorsDeg(const D3DVECTOR * a,const D3DVECTOR * b)107*c2c66affSColin Finck static inline D3DVALUE AngleBetweenVectorsDeg (const D3DVECTOR *a, const D3DVECTOR *b)
108*c2c66affSColin Finck {
109*c2c66affSColin Finck 	return RadToDeg(AngleBetweenVectorsRad(a, b));
110*c2c66affSColin Finck }
111*c2c66affSColin Finck 
112*c2c66affSColin Finck /* calculates vector between two points */
VectorBetweenTwoPoints(const D3DVECTOR * a,const D3DVECTOR * b)113*c2c66affSColin Finck static inline D3DVECTOR VectorBetweenTwoPoints (const D3DVECTOR *a, const D3DVECTOR *b)
114*c2c66affSColin Finck {
115*c2c66affSColin Finck 	D3DVECTOR c;
116*c2c66affSColin Finck 	c.x = b->x - a->x;
117*c2c66affSColin Finck 	c.y = b->y - a->y;
118*c2c66affSColin Finck 	c.z = b->z - a->z;
119*c2c66affSColin Finck 	TRACE("A (%f,%f,%f), B (%f,%f,%f), AB = (%f,%f,%f)\n", a->x, a->y, a->z, b->x, b->y,
120*c2c66affSColin Finck 	      b->z, c.x, c.y, c.z);
121*c2c66affSColin Finck 	return c;
122*c2c66affSColin Finck }
123*c2c66affSColin Finck 
124*c2c66affSColin Finck #ifndef __REACTOS__
125*c2c66affSColin Finck /* calculates the length of vector's projection on another vector */
ProjectVector(const D3DVECTOR * a,const D3DVECTOR * p)126*c2c66affSColin Finck static inline D3DVALUE ProjectVector (const D3DVECTOR *a, const D3DVECTOR *p)
127*c2c66affSColin Finck {
128*c2c66affSColin Finck 	D3DVALUE prod, result;
129*c2c66affSColin Finck 	prod = ScalarProduct(a, p);
130*c2c66affSColin Finck 	result = prod/VectorMagnitude(p);
131*c2c66affSColin Finck 	TRACE("length projection of (%f,%f,%f) on (%f,%f,%f) = %f\n", a->x, a->y, a->z, p->x,
132*c2c66affSColin Finck               p->y, p->z, result);
133*c2c66affSColin Finck 	return result;
134*c2c66affSColin Finck }
135*c2c66affSColin Finck #endif
136*c2c66affSColin Finck 
137*c2c66affSColin Finck /*******************************************************************************
138*c2c66affSColin Finck  *              3D Buffer and Listener mixing
139*c2c66affSColin Finck  */
140*c2c66affSColin Finck 
DSOUND_Calc3DBuffer(IDirectSoundBufferImpl * dsb)141*c2c66affSColin Finck void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb)
142*c2c66affSColin Finck {
143*c2c66affSColin Finck 	/* volume, at which the sound will be played after all calcs. */
144*c2c66affSColin Finck 	D3DVALUE lVolume = 0;
145*c2c66affSColin Finck 	/* stuff for distance related stuff calc. */
146*c2c66affSColin Finck 	D3DVECTOR vDistance;
147*c2c66affSColin Finck 	D3DVALUE flDistance = 0;
148*c2c66affSColin Finck 	/* panning related stuff */
149*c2c66affSColin Finck 	D3DVALUE flAngle;
150*c2c66affSColin Finck 	D3DVECTOR vLeft;
151*c2c66affSColin Finck 	/* doppler shift related stuff */
152*c2c66affSColin Finck #if 0
153*c2c66affSColin Finck 	D3DVALUE flFreq, flBufferVel, flListenerVel;
154*c2c66affSColin Finck #endif
155*c2c66affSColin Finck 
156*c2c66affSColin Finck 	TRACE("(%p)\n",dsb);
157*c2c66affSColin Finck 
158*c2c66affSColin Finck 	/* initial buffer volume */
159*c2c66affSColin Finck 	lVolume = dsb->ds3db_lVolume;
160*c2c66affSColin Finck 
161*c2c66affSColin Finck 	switch (dsb->ds3db_ds3db.dwMode)
162*c2c66affSColin Finck 	{
163*c2c66affSColin Finck 		case DS3DMODE_DISABLE:
164*c2c66affSColin Finck 			TRACE("3D processing disabled\n");
165*c2c66affSColin Finck 			/* this one is here only to eliminate annoying warning message */
166*c2c66affSColin Finck 			DSOUND_RecalcVolPan (&dsb->volpan);
167*c2c66affSColin Finck 			break;
168*c2c66affSColin Finck 		case DS3DMODE_NORMAL:
169*c2c66affSColin Finck 			TRACE("Normal 3D processing mode\n");
170*c2c66affSColin Finck 			/* we need to calculate distance between buffer and listener*/
171*c2c66affSColin Finck 			vDistance = VectorBetweenTwoPoints(&dsb->ds3db_ds3db.vPosition, &dsb->device->ds3dl.vPosition);
172*c2c66affSColin Finck 			flDistance = VectorMagnitude (&vDistance);
173*c2c66affSColin Finck 			break;
174*c2c66affSColin Finck 		case DS3DMODE_HEADRELATIVE:
175*c2c66affSColin Finck 			TRACE("Head-relative 3D processing mode\n");
176*c2c66affSColin Finck 			/* distance between buffer and listener is same as buffer's position */
177*c2c66affSColin Finck 			flDistance = VectorMagnitude (&dsb->ds3db_ds3db.vPosition);
178*c2c66affSColin Finck 			break;
179*c2c66affSColin Finck 	}
180*c2c66affSColin Finck 
181*c2c66affSColin Finck 	if (flDistance > dsb->ds3db_ds3db.flMaxDistance)
182*c2c66affSColin Finck 	{
183*c2c66affSColin Finck 		/* some apps don't want you to hear too distant sounds... */
184*c2c66affSColin Finck 		if (dsb->dsbd.dwFlags & DSBCAPS_MUTE3DATMAXDISTANCE)
185*c2c66affSColin Finck 		{
186*c2c66affSColin Finck 			dsb->volpan.lVolume = DSBVOLUME_MIN;
187*c2c66affSColin Finck 			DSOUND_RecalcVolPan (&dsb->volpan);
188*c2c66affSColin Finck 			/* i guess mixing here would be a waste of power */
189*c2c66affSColin Finck 			return;
190*c2c66affSColin Finck 		}
191*c2c66affSColin Finck 		else
192*c2c66affSColin Finck 			flDistance = dsb->ds3db_ds3db.flMaxDistance;
193*c2c66affSColin Finck 	}
194*c2c66affSColin Finck 
195*c2c66affSColin Finck 	if (flDistance < dsb->ds3db_ds3db.flMinDistance)
196*c2c66affSColin Finck 		flDistance = dsb->ds3db_ds3db.flMinDistance;
197*c2c66affSColin Finck 
198*c2c66affSColin Finck 	/* attenuation proportional to the distance squared, converted to millibels as in lVolume*/
199*c2c66affSColin Finck 	lVolume -= log10(flDistance/dsb->ds3db_ds3db.flMinDistance * flDistance/dsb->ds3db_ds3db.flMinDistance)*1000;
200*c2c66affSColin Finck 	TRACE("dist. att: Distance = %f, MinDistance = %f => adjusting volume %d to %f\n", flDistance, dsb->ds3db_ds3db.flMinDistance, dsb->ds3db_lVolume, lVolume);
201*c2c66affSColin Finck 
202*c2c66affSColin Finck 	/* conning */
203*c2c66affSColin Finck 	/* sometimes it happens that vConeOrientation vector = (0,0,0); in this case angle is "nan" and it's useless*/
204*c2c66affSColin Finck 	if (dsb->ds3db_ds3db.vConeOrientation.x == 0 && dsb->ds3db_ds3db.vConeOrientation.y == 0 && dsb->ds3db_ds3db.vConeOrientation.z == 0)
205*c2c66affSColin Finck 	{
206*c2c66affSColin Finck 		TRACE("conning: cones not set\n");
207*c2c66affSColin Finck 	}
208*c2c66affSColin Finck 	else
209*c2c66affSColin Finck 	{
210*c2c66affSColin Finck 		/* calculate angle */
211*c2c66affSColin Finck 		flAngle = AngleBetweenVectorsDeg(&dsb->ds3db_ds3db.vConeOrientation, &vDistance);
212*c2c66affSColin Finck 		/* if by any chance it happens that OutsideConeAngle = InsideConeAngle (that means that conning has no effect) */
213*c2c66affSColin Finck 		if (dsb->ds3db_ds3db.dwInsideConeAngle != dsb->ds3db_ds3db.dwOutsideConeAngle)
214*c2c66affSColin Finck 		{
215*c2c66affSColin Finck 			/* my test show that for my way of calc., we need only half of angles */
216*c2c66affSColin Finck 			DWORD dwInsideConeAngle = dsb->ds3db_ds3db.dwInsideConeAngle/2;
217*c2c66affSColin Finck 			DWORD dwOutsideConeAngle = dsb->ds3db_ds3db.dwOutsideConeAngle/2;
218*c2c66affSColin Finck 			if (dwOutsideConeAngle == dwInsideConeAngle)
219*c2c66affSColin Finck 				++dwOutsideConeAngle;
220*c2c66affSColin Finck 
221*c2c66affSColin Finck 			/* full volume */
222*c2c66affSColin Finck 			if (flAngle < dwInsideConeAngle)
223*c2c66affSColin Finck 				flAngle = dwInsideConeAngle;
224*c2c66affSColin Finck 			/* min (app defined) volume */
225*c2c66affSColin Finck 			if (flAngle > dwOutsideConeAngle)
226*c2c66affSColin Finck 				flAngle = dwOutsideConeAngle;
227*c2c66affSColin Finck 			/* this probably isn't the right thing, but it's ok for the time being */
228*c2c66affSColin Finck 			lVolume += ((dsb->ds3db_ds3db.lConeOutsideVolume)/((dwOutsideConeAngle) - (dwInsideConeAngle))) * flAngle;
229*c2c66affSColin Finck 		}
230*c2c66affSColin Finck 		TRACE("conning: Angle = %f deg; InsideConeAngle(/2) = %d deg; OutsideConeAngle(/2) = %d deg; ConeOutsideVolume = %d => adjusting volume to %f\n",
231*c2c66affSColin Finck 		       flAngle, dsb->ds3db_ds3db.dwInsideConeAngle/2, dsb->ds3db_ds3db.dwOutsideConeAngle/2, dsb->ds3db_ds3db.lConeOutsideVolume, lVolume);
232*c2c66affSColin Finck 	}
233*c2c66affSColin Finck 	dsb->volpan.lVolume = lVolume;
234*c2c66affSColin Finck 
235*c2c66affSColin Finck 	/* panning */
236*c2c66affSColin Finck 	if (dsb->device->ds3dl.vPosition.x == dsb->ds3db_ds3db.vPosition.x &&
237*c2c66affSColin Finck 	    dsb->device->ds3dl.vPosition.y == dsb->ds3db_ds3db.vPosition.y &&
238*c2c66affSColin Finck 	    dsb->device->ds3dl.vPosition.z == dsb->ds3db_ds3db.vPosition.z) {
239*c2c66affSColin Finck 		dsb->volpan.lPan = 0;
240*c2c66affSColin Finck 		flAngle = 0.0;
241*c2c66affSColin Finck 	}
242*c2c66affSColin Finck 	else
243*c2c66affSColin Finck 	{
244*c2c66affSColin Finck 		vDistance = VectorBetweenTwoPoints(&dsb->device->ds3dl.vPosition, &dsb->ds3db_ds3db.vPosition);
245*c2c66affSColin Finck 		vLeft = VectorProduct(&dsb->device->ds3dl.vOrientFront, &dsb->device->ds3dl.vOrientTop);
246*c2c66affSColin Finck 		flAngle = AngleBetweenVectorsRad(&vLeft, &vDistance);
247*c2c66affSColin Finck 		/* for now, we'll use "linear formula" (which is probably incorrect); if someone has it in book, correct it */
248*c2c66affSColin Finck 		dsb->volpan.lPan = 10000*2*flAngle/M_PI - 10000;
249*c2c66affSColin Finck 	}
250*c2c66affSColin Finck 	TRACE("panning: Angle = %f rad, lPan = %d\n", flAngle, dsb->volpan.lPan);
251*c2c66affSColin Finck 
252*c2c66affSColin Finck 	/* FIXME: Doppler Effect disabled since i have no idea which frequency to change and how to do it */
253*c2c66affSColin Finck #if 0
254*c2c66affSColin Finck 	/* doppler shift*/
255*c2c66affSColin Finck 	if ((VectorMagnitude(&ds3db_ds3db.vVelocity) == 0) && (VectorMagnitude(&dsb->device->ds3dl.vVelocity) == 0))
256*c2c66affSColin Finck 	{
257*c2c66affSColin Finck 		TRACE("doppler: Buffer and Listener don't have velocities\n");
258*c2c66affSColin Finck 	}
259*c2c66affSColin Finck 	else if (ds3db_ds3db.vVelocity != dsb->device->ds3dl.vVelocity)
260*c2c66affSColin Finck 	{
261*c2c66affSColin Finck 		/* calculate length of ds3db_ds3db.vVelocity component which causes Doppler Effect
262*c2c66affSColin Finck 		   NOTE: if buffer moves TOWARDS the listener, it's velocity component is NEGATIVE
263*c2c66affSColin Finck 		         if buffer moves AWAY from listener, it's velocity component is POSITIVE */
264*c2c66affSColin Finck 		flBufferVel = ProjectVector(&dsb->ds3db_ds3db.vVelocity, &vDistance);
265*c2c66affSColin Finck 		/* calculate length of ds3dl.vVelocity component which causes Doppler Effect
266*c2c66affSColin Finck 		   NOTE: if listener moves TOWARDS the buffer, it's velocity component is POSITIVE
267*c2c66affSColin Finck 		         if listener moves AWAY from buffer, it's velocity component is NEGATIVE */
268*c2c66affSColin Finck 		flListenerVel = ProjectVector(&dsb->device->ds3dl.vVelocity, &vDistance);
269*c2c66affSColin Finck 		/* formula taken from Gianicoli D.: Physics, 4th edition: */
270*c2c66affSColin Finck 		/* FIXME: replace dsb->freq with appropriate frequency ! */
271*c2c66affSColin Finck 		flFreq = dsb->freq * ((DEFAULT_VELOCITY + flListenerVel)/(DEFAULT_VELOCITY + flBufferVel));
272*c2c66affSColin Finck 		TRACE("doppler: Buffer velocity (component) = %lf, Listener velocity (component) = %lf => Doppler shift: %ld Hz -> %lf Hz\n", flBufferVel, flListenerVel,
273*c2c66affSColin Finck 		      dsb->freq, flFreq);
274*c2c66affSColin Finck 		/* FIXME: replace following line with correct frequency setting ! */
275*c2c66affSColin Finck 		dsb->freq = flFreq;
276*c2c66affSColin Finck 		DSOUND_RecalcFormat(dsb);
277*c2c66affSColin Finck 		DSOUND_MixToTemporary(dsb, 0, dsb->buflen);
278*c2c66affSColin Finck 	}
279*c2c66affSColin Finck #endif
280*c2c66affSColin Finck 
281*c2c66affSColin Finck 	/* time for remix */
282*c2c66affSColin Finck 	DSOUND_RecalcVolPan(&dsb->volpan);
283*c2c66affSColin Finck }
284*c2c66affSColin Finck 
DSOUND_Mix3DBuffer(IDirectSoundBufferImpl * dsb)285*c2c66affSColin Finck static void DSOUND_Mix3DBuffer(IDirectSoundBufferImpl *dsb)
286*c2c66affSColin Finck {
287*c2c66affSColin Finck 	TRACE("(%p)\n",dsb);
288*c2c66affSColin Finck 
289*c2c66affSColin Finck 	DSOUND_Calc3DBuffer(dsb);
290*c2c66affSColin Finck }
291*c2c66affSColin Finck 
DSOUND_ChangeListener(IDirectSound3DListenerImpl * ds3dl)292*c2c66affSColin Finck static void DSOUND_ChangeListener(IDirectSound3DListenerImpl *ds3dl)
293*c2c66affSColin Finck {
294*c2c66affSColin Finck 	int i;
295*c2c66affSColin Finck 	TRACE("(%p)\n",ds3dl);
296*c2c66affSColin Finck 	for (i = 0; i < ds3dl->device->nrofbuffers; i++)
297*c2c66affSColin Finck 	{
298*c2c66affSColin Finck 		/* check if this buffer is waiting for recalculation */
299*c2c66affSColin Finck 		if (ds3dl->device->buffers[i]->ds3db_need_recalc)
300*c2c66affSColin Finck 		{
301*c2c66affSColin Finck 			DSOUND_Mix3DBuffer(ds3dl->device->buffers[i]);
302*c2c66affSColin Finck 		}
303*c2c66affSColin Finck 	}
304*c2c66affSColin Finck }
305*c2c66affSColin Finck 
306*c2c66affSColin Finck /*******************************************************************************
307*c2c66affSColin Finck  *              IDirectSound3DBuffer
308*c2c66affSColin Finck  */
309*c2c66affSColin Finck 
310*c2c66affSColin Finck /* IUnknown methods */
IDirectSound3DBufferImpl_QueryInterface(LPDIRECTSOUND3DBUFFER iface,REFIID riid,LPVOID * ppobj)311*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_QueryInterface(
312*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface, REFIID riid, LPVOID *ppobj)
313*c2c66affSColin Finck {
314*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
315*c2c66affSColin Finck 
316*c2c66affSColin Finck 	TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
317*c2c66affSColin Finck 	return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb, riid, ppobj);
318*c2c66affSColin Finck }
319*c2c66affSColin Finck 
IDirectSound3DBufferImpl_AddRef(LPDIRECTSOUND3DBUFFER iface)320*c2c66affSColin Finck static ULONG WINAPI IDirectSound3DBufferImpl_AddRef(LPDIRECTSOUND3DBUFFER iface)
321*c2c66affSColin Finck {
322*c2c66affSColin Finck     IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
323*c2c66affSColin Finck     ULONG ref = InterlockedIncrement(&(This->ref));
324*c2c66affSColin Finck 
325*c2c66affSColin Finck     TRACE("(%p) ref was %d\n", This, ref - 1);
326*c2c66affSColin Finck 
327*c2c66affSColin Finck     if(ref == 1)
328*c2c66affSColin Finck         InterlockedIncrement(&This->dsb->numIfaces);
329*c2c66affSColin Finck 
330*c2c66affSColin Finck     return ref;
331*c2c66affSColin Finck }
332*c2c66affSColin Finck 
IDirectSound3DBufferImpl_Release(LPDIRECTSOUND3DBUFFER iface)333*c2c66affSColin Finck static ULONG WINAPI IDirectSound3DBufferImpl_Release(LPDIRECTSOUND3DBUFFER iface)
334*c2c66affSColin Finck {
335*c2c66affSColin Finck     IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
336*c2c66affSColin Finck     ULONG ref = InterlockedDecrement(&(This->ref));
337*c2c66affSColin Finck     TRACE("(%p) ref was %d\n", This, ref + 1);
338*c2c66affSColin Finck 
339*c2c66affSColin Finck     if (!ref) {
340*c2c66affSColin Finck         This->dsb->ds3db = NULL;
341*c2c66affSColin Finck         if (!InterlockedDecrement(&This->dsb->numIfaces))
342*c2c66affSColin Finck             secondarybuffer_destroy(This->dsb);
343*c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, This);
344*c2c66affSColin Finck         TRACE("(%p) released\n", This);
345*c2c66affSColin Finck     }
346*c2c66affSColin Finck     return ref;
347*c2c66affSColin Finck }
348*c2c66affSColin Finck 
349*c2c66affSColin Finck /* IDirectSound3DBuffer methods */
IDirectSound3DBufferImpl_GetAllParameters(LPDIRECTSOUND3DBUFFER iface,LPDS3DBUFFER lpDs3dBuffer)350*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_GetAllParameters(
351*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
352*c2c66affSColin Finck 	LPDS3DBUFFER lpDs3dBuffer)
353*c2c66affSColin Finck {
354*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
355*c2c66affSColin Finck 	TRACE("(%p,%p)\n",This,lpDs3dBuffer);
356*c2c66affSColin Finck 
357*c2c66affSColin Finck 	if (lpDs3dBuffer == NULL) {
358*c2c66affSColin Finck 		WARN("invalid parameter: lpDs3dBuffer == NULL\n");
359*c2c66affSColin Finck 		return DSERR_INVALIDPARAM;
360*c2c66affSColin Finck 	}
361*c2c66affSColin Finck 
362*c2c66affSColin Finck 	if (lpDs3dBuffer->dwSize < sizeof(*lpDs3dBuffer)) {
363*c2c66affSColin Finck 		WARN("invalid parameter: lpDs3dBuffer->dwSize = %d\n",lpDs3dBuffer->dwSize);
364*c2c66affSColin Finck 		return DSERR_INVALIDPARAM;
365*c2c66affSColin Finck 	}
366*c2c66affSColin Finck 
367*c2c66affSColin Finck 	TRACE("returning: all parameters\n");
368*c2c66affSColin Finck 	*lpDs3dBuffer = This->dsb->ds3db_ds3db;
369*c2c66affSColin Finck 	return DS_OK;
370*c2c66affSColin Finck }
371*c2c66affSColin Finck 
IDirectSound3DBufferImpl_GetConeAngles(LPDIRECTSOUND3DBUFFER iface,LPDWORD lpdwInsideConeAngle,LPDWORD lpdwOutsideConeAngle)372*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeAngles(
373*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
374*c2c66affSColin Finck 	LPDWORD lpdwInsideConeAngle,
375*c2c66affSColin Finck 	LPDWORD lpdwOutsideConeAngle)
376*c2c66affSColin Finck {
377*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
378*c2c66affSColin Finck 	TRACE("returning: Inside Cone Angle = %d degrees; Outside Cone Angle = %d degrees\n",
379*c2c66affSColin Finck 		This->dsb->ds3db_ds3db.dwInsideConeAngle, This->dsb->ds3db_ds3db.dwOutsideConeAngle);
380*c2c66affSColin Finck 	*lpdwInsideConeAngle = This->dsb->ds3db_ds3db.dwInsideConeAngle;
381*c2c66affSColin Finck 	*lpdwOutsideConeAngle = This->dsb->ds3db_ds3db.dwOutsideConeAngle;
382*c2c66affSColin Finck 	return DS_OK;
383*c2c66affSColin Finck }
384*c2c66affSColin Finck 
IDirectSound3DBufferImpl_GetConeOrientation(LPDIRECTSOUND3DBUFFER iface,LPD3DVECTOR lpvConeOrientation)385*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeOrientation(
386*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
387*c2c66affSColin Finck 	LPD3DVECTOR lpvConeOrientation)
388*c2c66affSColin Finck {
389*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
390*c2c66affSColin Finck 	TRACE("returning: Cone Orientation vector = (%f,%f,%f)\n",
391*c2c66affSColin Finck 		This->dsb->ds3db_ds3db.vConeOrientation.x,
392*c2c66affSColin Finck 		This->dsb->ds3db_ds3db.vConeOrientation.y,
393*c2c66affSColin Finck 		This->dsb->ds3db_ds3db.vConeOrientation.z);
394*c2c66affSColin Finck 	*lpvConeOrientation = This->dsb->ds3db_ds3db.vConeOrientation;
395*c2c66affSColin Finck 	return DS_OK;
396*c2c66affSColin Finck }
397*c2c66affSColin Finck 
IDirectSound3DBufferImpl_GetConeOutsideVolume(LPDIRECTSOUND3DBUFFER iface,LPLONG lplConeOutsideVolume)398*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeOutsideVolume(
399*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
400*c2c66affSColin Finck 	LPLONG lplConeOutsideVolume)
401*c2c66affSColin Finck {
402*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
403*c2c66affSColin Finck 	TRACE("returning: Cone Outside Volume = %d\n", This->dsb->ds3db_ds3db.lConeOutsideVolume);
404*c2c66affSColin Finck 	*lplConeOutsideVolume = This->dsb->ds3db_ds3db.lConeOutsideVolume;
405*c2c66affSColin Finck 	return DS_OK;
406*c2c66affSColin Finck }
407*c2c66affSColin Finck 
IDirectSound3DBufferImpl_GetMaxDistance(LPDIRECTSOUND3DBUFFER iface,LPD3DVALUE lpfMaxDistance)408*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_GetMaxDistance(
409*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
410*c2c66affSColin Finck 	LPD3DVALUE lpfMaxDistance)
411*c2c66affSColin Finck {
412*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
413*c2c66affSColin Finck 	TRACE("returning: Max Distance = %f\n", This->dsb->ds3db_ds3db.flMaxDistance);
414*c2c66affSColin Finck 	*lpfMaxDistance = This->dsb->ds3db_ds3db.flMaxDistance;
415*c2c66affSColin Finck 	return DS_OK;
416*c2c66affSColin Finck }
417*c2c66affSColin Finck 
IDirectSound3DBufferImpl_GetMinDistance(LPDIRECTSOUND3DBUFFER iface,LPD3DVALUE lpfMinDistance)418*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_GetMinDistance(
419*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
420*c2c66affSColin Finck 	LPD3DVALUE lpfMinDistance)
421*c2c66affSColin Finck {
422*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
423*c2c66affSColin Finck 	TRACE("returning: Min Distance = %f\n", This->dsb->ds3db_ds3db.flMinDistance);
424*c2c66affSColin Finck 	*lpfMinDistance = This->dsb->ds3db_ds3db.flMinDistance;
425*c2c66affSColin Finck 	return DS_OK;
426*c2c66affSColin Finck }
427*c2c66affSColin Finck 
IDirectSound3DBufferImpl_GetMode(LPDIRECTSOUND3DBUFFER iface,LPDWORD lpdwMode)428*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_GetMode(
429*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
430*c2c66affSColin Finck 	LPDWORD lpdwMode)
431*c2c66affSColin Finck {
432*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
433*c2c66affSColin Finck 	TRACE("returning: Mode = %d\n", This->dsb->ds3db_ds3db.dwMode);
434*c2c66affSColin Finck 	*lpdwMode = This->dsb->ds3db_ds3db.dwMode;
435*c2c66affSColin Finck 	return DS_OK;
436*c2c66affSColin Finck }
437*c2c66affSColin Finck 
IDirectSound3DBufferImpl_GetPosition(LPDIRECTSOUND3DBUFFER iface,LPD3DVECTOR lpvPosition)438*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_GetPosition(
439*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
440*c2c66affSColin Finck 	LPD3DVECTOR lpvPosition)
441*c2c66affSColin Finck {
442*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
443*c2c66affSColin Finck 	TRACE("returning: Position vector = (%f,%f,%f)\n",
444*c2c66affSColin Finck 		This->dsb->ds3db_ds3db.vPosition.x,
445*c2c66affSColin Finck 		This->dsb->ds3db_ds3db.vPosition.y,
446*c2c66affSColin Finck 		This->dsb->ds3db_ds3db.vPosition.z);
447*c2c66affSColin Finck 	*lpvPosition = This->dsb->ds3db_ds3db.vPosition;
448*c2c66affSColin Finck 	return DS_OK;
449*c2c66affSColin Finck }
450*c2c66affSColin Finck 
IDirectSound3DBufferImpl_GetVelocity(LPDIRECTSOUND3DBUFFER iface,LPD3DVECTOR lpvVelocity)451*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_GetVelocity(
452*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
453*c2c66affSColin Finck 	LPD3DVECTOR lpvVelocity)
454*c2c66affSColin Finck {
455*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
456*c2c66affSColin Finck 	TRACE("returning: Velocity vector = (%f,%f,%f)\n",
457*c2c66affSColin Finck 		This->dsb->ds3db_ds3db.vVelocity.x,
458*c2c66affSColin Finck 		This->dsb->ds3db_ds3db.vVelocity.y,
459*c2c66affSColin Finck 		This->dsb->ds3db_ds3db.vVelocity.z);
460*c2c66affSColin Finck 	*lpvVelocity = This->dsb->ds3db_ds3db.vVelocity;
461*c2c66affSColin Finck 	return DS_OK;
462*c2c66affSColin Finck }
463*c2c66affSColin Finck 
IDirectSound3DBufferImpl_SetAllParameters(LPDIRECTSOUND3DBUFFER iface,LPCDS3DBUFFER lpcDs3dBuffer,DWORD dwApply)464*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_SetAllParameters(
465*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
466*c2c66affSColin Finck 	LPCDS3DBUFFER lpcDs3dBuffer,
467*c2c66affSColin Finck 	DWORD dwApply)
468*c2c66affSColin Finck {
469*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
470*c2c66affSColin Finck 	DWORD status = DSERR_INVALIDPARAM;
471*c2c66affSColin Finck 	TRACE("(%p,%p,%x)\n",iface,lpcDs3dBuffer,dwApply);
472*c2c66affSColin Finck 
473*c2c66affSColin Finck 	if (lpcDs3dBuffer == NULL) {
474*c2c66affSColin Finck 		WARN("invalid parameter: lpcDs3dBuffer == NULL\n");
475*c2c66affSColin Finck 		return status;
476*c2c66affSColin Finck 	}
477*c2c66affSColin Finck 
478*c2c66affSColin Finck 	if (lpcDs3dBuffer->dwSize != sizeof(DS3DBUFFER)) {
479*c2c66affSColin Finck 		WARN("invalid parameter: lpcDs3dBuffer->dwSize = %d\n", lpcDs3dBuffer->dwSize);
480*c2c66affSColin Finck 		return status;
481*c2c66affSColin Finck 	}
482*c2c66affSColin Finck 
483*c2c66affSColin Finck 	TRACE("setting: all parameters; dwApply = %d\n", dwApply);
484*c2c66affSColin Finck 	This->dsb->ds3db_ds3db = *lpcDs3dBuffer;
485*c2c66affSColin Finck 
486*c2c66affSColin Finck 	if (dwApply == DS3D_IMMEDIATE)
487*c2c66affSColin Finck 	{
488*c2c66affSColin Finck 		DSOUND_Mix3DBuffer(This->dsb);
489*c2c66affSColin Finck 	}
490*c2c66affSColin Finck 	This->dsb->ds3db_need_recalc = TRUE;
491*c2c66affSColin Finck 	status = DS_OK;
492*c2c66affSColin Finck 
493*c2c66affSColin Finck 	return status;
494*c2c66affSColin Finck }
495*c2c66affSColin Finck 
IDirectSound3DBufferImpl_SetConeAngles(LPDIRECTSOUND3DBUFFER iface,DWORD dwInsideConeAngle,DWORD dwOutsideConeAngle,DWORD dwApply)496*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeAngles(
497*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
498*c2c66affSColin Finck 	DWORD dwInsideConeAngle,
499*c2c66affSColin Finck 	DWORD dwOutsideConeAngle,
500*c2c66affSColin Finck 	DWORD dwApply)
501*c2c66affSColin Finck {
502*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
503*c2c66affSColin Finck 	TRACE("setting: Inside Cone Angle = %d; Outside Cone Angle = %d; dwApply = %d\n",
504*c2c66affSColin Finck 		dwInsideConeAngle, dwOutsideConeAngle, dwApply);
505*c2c66affSColin Finck 	This->dsb->ds3db_ds3db.dwInsideConeAngle = dwInsideConeAngle;
506*c2c66affSColin Finck 	This->dsb->ds3db_ds3db.dwOutsideConeAngle = dwOutsideConeAngle;
507*c2c66affSColin Finck 	if (dwApply == DS3D_IMMEDIATE)
508*c2c66affSColin Finck 	{
509*c2c66affSColin Finck 		DSOUND_Mix3DBuffer(This->dsb);
510*c2c66affSColin Finck 	}
511*c2c66affSColin Finck 	This->dsb->ds3db_need_recalc = TRUE;
512*c2c66affSColin Finck 	return DS_OK;
513*c2c66affSColin Finck }
514*c2c66affSColin Finck 
IDirectSound3DBufferImpl_SetConeOrientation(LPDIRECTSOUND3DBUFFER iface,D3DVALUE x,D3DVALUE y,D3DVALUE z,DWORD dwApply)515*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOrientation(
516*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
517*c2c66affSColin Finck 	D3DVALUE x, D3DVALUE y, D3DVALUE z,
518*c2c66affSColin Finck 	DWORD dwApply)
519*c2c66affSColin Finck {
520*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
521*c2c66affSColin Finck 	TRACE("setting: Cone Orientation vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply);
522*c2c66affSColin Finck 	This->dsb->ds3db_ds3db.vConeOrientation.x = x;
523*c2c66affSColin Finck 	This->dsb->ds3db_ds3db.vConeOrientation.y = y;
524*c2c66affSColin Finck 	This->dsb->ds3db_ds3db.vConeOrientation.z = z;
525*c2c66affSColin Finck 	if (dwApply == DS3D_IMMEDIATE)
526*c2c66affSColin Finck 	{
527*c2c66affSColin Finck 		This->dsb->ds3db_need_recalc = FALSE;
528*c2c66affSColin Finck 		DSOUND_Mix3DBuffer(This->dsb);
529*c2c66affSColin Finck 	}
530*c2c66affSColin Finck 	This->dsb->ds3db_need_recalc = TRUE;
531*c2c66affSColin Finck 	return DS_OK;
532*c2c66affSColin Finck }
533*c2c66affSColin Finck 
IDirectSound3DBufferImpl_SetConeOutsideVolume(LPDIRECTSOUND3DBUFFER iface,LONG lConeOutsideVolume,DWORD dwApply)534*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOutsideVolume(
535*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
536*c2c66affSColin Finck 	LONG lConeOutsideVolume,
537*c2c66affSColin Finck 	DWORD dwApply)
538*c2c66affSColin Finck {
539*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
540*c2c66affSColin Finck 	TRACE("setting: ConeOutsideVolume = %d; dwApply = %d\n", lConeOutsideVolume, dwApply);
541*c2c66affSColin Finck 	This->dsb->ds3db_ds3db.lConeOutsideVolume = lConeOutsideVolume;
542*c2c66affSColin Finck 	if (dwApply == DS3D_IMMEDIATE)
543*c2c66affSColin Finck 	{
544*c2c66affSColin Finck 		This->dsb->ds3db_need_recalc = FALSE;
545*c2c66affSColin Finck 		DSOUND_Mix3DBuffer(This->dsb);
546*c2c66affSColin Finck 	}
547*c2c66affSColin Finck 	This->dsb->ds3db_need_recalc = TRUE;
548*c2c66affSColin Finck 	return DS_OK;
549*c2c66affSColin Finck }
550*c2c66affSColin Finck 
IDirectSound3DBufferImpl_SetMaxDistance(LPDIRECTSOUND3DBUFFER iface,D3DVALUE fMaxDistance,DWORD dwApply)551*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_SetMaxDistance(
552*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
553*c2c66affSColin Finck 	D3DVALUE fMaxDistance,
554*c2c66affSColin Finck 	DWORD dwApply)
555*c2c66affSColin Finck {
556*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
557*c2c66affSColin Finck 	TRACE("setting: MaxDistance = %f; dwApply = %d\n", fMaxDistance, dwApply);
558*c2c66affSColin Finck 	This->dsb->ds3db_ds3db.flMaxDistance = fMaxDistance;
559*c2c66affSColin Finck 	if (dwApply == DS3D_IMMEDIATE)
560*c2c66affSColin Finck 	{
561*c2c66affSColin Finck 		This->dsb->ds3db_need_recalc = FALSE;
562*c2c66affSColin Finck 		DSOUND_Mix3DBuffer(This->dsb);
563*c2c66affSColin Finck 	}
564*c2c66affSColin Finck 	This->dsb->ds3db_need_recalc = TRUE;
565*c2c66affSColin Finck 	return DS_OK;
566*c2c66affSColin Finck }
567*c2c66affSColin Finck 
IDirectSound3DBufferImpl_SetMinDistance(LPDIRECTSOUND3DBUFFER iface,D3DVALUE fMinDistance,DWORD dwApply)568*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_SetMinDistance(
569*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
570*c2c66affSColin Finck 	D3DVALUE fMinDistance,
571*c2c66affSColin Finck 	DWORD dwApply)
572*c2c66affSColin Finck {
573*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
574*c2c66affSColin Finck 	TRACE("setting: MinDistance = %f; dwApply = %d\n", fMinDistance, dwApply);
575*c2c66affSColin Finck 	This->dsb->ds3db_ds3db.flMinDistance = fMinDistance;
576*c2c66affSColin Finck 	if (dwApply == DS3D_IMMEDIATE)
577*c2c66affSColin Finck 	{
578*c2c66affSColin Finck 		This->dsb->ds3db_need_recalc = FALSE;
579*c2c66affSColin Finck 		DSOUND_Mix3DBuffer(This->dsb);
580*c2c66affSColin Finck 	}
581*c2c66affSColin Finck 	This->dsb->ds3db_need_recalc = TRUE;
582*c2c66affSColin Finck 	return DS_OK;
583*c2c66affSColin Finck }
584*c2c66affSColin Finck 
IDirectSound3DBufferImpl_SetMode(LPDIRECTSOUND3DBUFFER iface,DWORD dwMode,DWORD dwApply)585*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_SetMode(
586*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
587*c2c66affSColin Finck 	DWORD dwMode,
588*c2c66affSColin Finck 	DWORD dwApply)
589*c2c66affSColin Finck {
590*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
591*c2c66affSColin Finck 	TRACE("setting: Mode = %d; dwApply = %d\n", dwMode, dwApply);
592*c2c66affSColin Finck 	This->dsb->ds3db_ds3db.dwMode = dwMode;
593*c2c66affSColin Finck 	if (dwApply == DS3D_IMMEDIATE)
594*c2c66affSColin Finck 	{
595*c2c66affSColin Finck 		This->dsb->ds3db_need_recalc = FALSE;
596*c2c66affSColin Finck 		DSOUND_Mix3DBuffer(This->dsb);
597*c2c66affSColin Finck 	}
598*c2c66affSColin Finck 	This->dsb->ds3db_need_recalc = TRUE;
599*c2c66affSColin Finck 	return DS_OK;
600*c2c66affSColin Finck }
601*c2c66affSColin Finck 
IDirectSound3DBufferImpl_SetPosition(LPDIRECTSOUND3DBUFFER iface,D3DVALUE x,D3DVALUE y,D3DVALUE z,DWORD dwApply)602*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_SetPosition(
603*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
604*c2c66affSColin Finck 	D3DVALUE x, D3DVALUE y, D3DVALUE z,
605*c2c66affSColin Finck 	DWORD dwApply)
606*c2c66affSColin Finck {
607*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
608*c2c66affSColin Finck 	TRACE("setting: Position vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply);
609*c2c66affSColin Finck 	This->dsb->ds3db_ds3db.vPosition.x = x;
610*c2c66affSColin Finck 	This->dsb->ds3db_ds3db.vPosition.y = y;
611*c2c66affSColin Finck 	This->dsb->ds3db_ds3db.vPosition.z = z;
612*c2c66affSColin Finck 	if (dwApply == DS3D_IMMEDIATE)
613*c2c66affSColin Finck 	{
614*c2c66affSColin Finck 		This->dsb->ds3db_need_recalc = FALSE;
615*c2c66affSColin Finck 		DSOUND_Mix3DBuffer(This->dsb);
616*c2c66affSColin Finck 	}
617*c2c66affSColin Finck 	This->dsb->ds3db_need_recalc = TRUE;
618*c2c66affSColin Finck 	return DS_OK;
619*c2c66affSColin Finck }
620*c2c66affSColin Finck 
IDirectSound3DBufferImpl_SetVelocity(LPDIRECTSOUND3DBUFFER iface,D3DVALUE x,D3DVALUE y,D3DVALUE z,DWORD dwApply)621*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DBufferImpl_SetVelocity(
622*c2c66affSColin Finck 	LPDIRECTSOUND3DBUFFER iface,
623*c2c66affSColin Finck 	D3DVALUE x, D3DVALUE y, D3DVALUE z,
624*c2c66affSColin Finck 	DWORD dwApply)
625*c2c66affSColin Finck {
626*c2c66affSColin Finck 	IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
627*c2c66affSColin Finck 	TRACE("setting: Velocity vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply);
628*c2c66affSColin Finck 	This->dsb->ds3db_ds3db.vVelocity.x = x;
629*c2c66affSColin Finck 	This->dsb->ds3db_ds3db.vVelocity.y = y;
630*c2c66affSColin Finck 	This->dsb->ds3db_ds3db.vVelocity.z = z;
631*c2c66affSColin Finck 	if (dwApply == DS3D_IMMEDIATE)
632*c2c66affSColin Finck 	{
633*c2c66affSColin Finck 		This->dsb->ds3db_need_recalc = FALSE;
634*c2c66affSColin Finck 		DSOUND_Mix3DBuffer(This->dsb);
635*c2c66affSColin Finck 	}
636*c2c66affSColin Finck 	This->dsb->ds3db_need_recalc = TRUE;
637*c2c66affSColin Finck 	return DS_OK;
638*c2c66affSColin Finck }
639*c2c66affSColin Finck 
640*c2c66affSColin Finck static const IDirectSound3DBufferVtbl ds3dbvt =
641*c2c66affSColin Finck {
642*c2c66affSColin Finck 	/* IUnknown methods */
643*c2c66affSColin Finck 	IDirectSound3DBufferImpl_QueryInterface,
644*c2c66affSColin Finck 	IDirectSound3DBufferImpl_AddRef,
645*c2c66affSColin Finck 	IDirectSound3DBufferImpl_Release,
646*c2c66affSColin Finck 	/* IDirectSound3DBuffer methods */
647*c2c66affSColin Finck 	IDirectSound3DBufferImpl_GetAllParameters,
648*c2c66affSColin Finck 	IDirectSound3DBufferImpl_GetConeAngles,
649*c2c66affSColin Finck 	IDirectSound3DBufferImpl_GetConeOrientation,
650*c2c66affSColin Finck 	IDirectSound3DBufferImpl_GetConeOutsideVolume,
651*c2c66affSColin Finck 	IDirectSound3DBufferImpl_GetMaxDistance,
652*c2c66affSColin Finck 	IDirectSound3DBufferImpl_GetMinDistance,
653*c2c66affSColin Finck 	IDirectSound3DBufferImpl_GetMode,
654*c2c66affSColin Finck 	IDirectSound3DBufferImpl_GetPosition,
655*c2c66affSColin Finck 	IDirectSound3DBufferImpl_GetVelocity,
656*c2c66affSColin Finck 	IDirectSound3DBufferImpl_SetAllParameters,
657*c2c66affSColin Finck 	IDirectSound3DBufferImpl_SetConeAngles,
658*c2c66affSColin Finck 	IDirectSound3DBufferImpl_SetConeOrientation,
659*c2c66affSColin Finck 	IDirectSound3DBufferImpl_SetConeOutsideVolume,
660*c2c66affSColin Finck 	IDirectSound3DBufferImpl_SetMaxDistance,
661*c2c66affSColin Finck 	IDirectSound3DBufferImpl_SetMinDistance,
662*c2c66affSColin Finck 	IDirectSound3DBufferImpl_SetMode,
663*c2c66affSColin Finck 	IDirectSound3DBufferImpl_SetPosition,
664*c2c66affSColin Finck 	IDirectSound3DBufferImpl_SetVelocity,
665*c2c66affSColin Finck };
666*c2c66affSColin Finck 
IDirectSound3DBufferImpl_Create(IDirectSoundBufferImpl * dsb,IDirectSound3DBufferImpl ** pds3db)667*c2c66affSColin Finck HRESULT IDirectSound3DBufferImpl_Create(
668*c2c66affSColin Finck 	IDirectSoundBufferImpl *dsb,
669*c2c66affSColin Finck 	IDirectSound3DBufferImpl **pds3db)
670*c2c66affSColin Finck {
671*c2c66affSColin Finck 	IDirectSound3DBufferImpl *ds3db;
672*c2c66affSColin Finck 	TRACE("(%p,%p)\n",dsb,pds3db);
673*c2c66affSColin Finck 
674*c2c66affSColin Finck 	ds3db = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*ds3db));
675*c2c66affSColin Finck 
676*c2c66affSColin Finck 	if (ds3db == NULL) {
677*c2c66affSColin Finck 		WARN("out of memory\n");
678*c2c66affSColin Finck 		*pds3db = 0;
679*c2c66affSColin Finck 		return DSERR_OUTOFMEMORY;
680*c2c66affSColin Finck 	}
681*c2c66affSColin Finck 
682*c2c66affSColin Finck 	ds3db->ref = 0;
683*c2c66affSColin Finck 	ds3db->dsb = dsb;
684*c2c66affSColin Finck 	ds3db->lpVtbl = &ds3dbvt;
685*c2c66affSColin Finck 
686*c2c66affSColin Finck 	ds3db->dsb->ds3db_ds3db.dwSize = sizeof(DS3DBUFFER);
687*c2c66affSColin Finck 	ds3db->dsb->ds3db_ds3db.vPosition.x = 0.0;
688*c2c66affSColin Finck 	ds3db->dsb->ds3db_ds3db.vPosition.y = 0.0;
689*c2c66affSColin Finck 	ds3db->dsb->ds3db_ds3db.vPosition.z = 0.0;
690*c2c66affSColin Finck 	ds3db->dsb->ds3db_ds3db.vVelocity.x = 0.0;
691*c2c66affSColin Finck 	ds3db->dsb->ds3db_ds3db.vVelocity.y = 0.0;
692*c2c66affSColin Finck 	ds3db->dsb->ds3db_ds3db.vVelocity.z = 0.0;
693*c2c66affSColin Finck 	ds3db->dsb->ds3db_ds3db.dwInsideConeAngle = DS3D_DEFAULTCONEANGLE;
694*c2c66affSColin Finck 	ds3db->dsb->ds3db_ds3db.dwOutsideConeAngle = DS3D_DEFAULTCONEANGLE;
695*c2c66affSColin Finck 	ds3db->dsb->ds3db_ds3db.vConeOrientation.x = 0.0;
696*c2c66affSColin Finck 	ds3db->dsb->ds3db_ds3db.vConeOrientation.y = 0.0;
697*c2c66affSColin Finck 	ds3db->dsb->ds3db_ds3db.vConeOrientation.z = 0.0;
698*c2c66affSColin Finck 	ds3db->dsb->ds3db_ds3db.lConeOutsideVolume = DS3D_DEFAULTCONEOUTSIDEVOLUME;
699*c2c66affSColin Finck 	ds3db->dsb->ds3db_ds3db.flMinDistance = DS3D_DEFAULTMINDISTANCE;
700*c2c66affSColin Finck 	ds3db->dsb->ds3db_ds3db.flMaxDistance = DS3D_DEFAULTMAXDISTANCE;
701*c2c66affSColin Finck 	ds3db->dsb->ds3db_ds3db.dwMode = DS3DMODE_NORMAL;
702*c2c66affSColin Finck 
703*c2c66affSColin Finck 	ds3db->dsb->ds3db_need_recalc = TRUE;
704*c2c66affSColin Finck 
705*c2c66affSColin Finck 	*pds3db = ds3db;
706*c2c66affSColin Finck 	return S_OK;
707*c2c66affSColin Finck }
708*c2c66affSColin Finck 
IDirectSound3DBufferImpl_Destroy(IDirectSound3DBufferImpl * pds3db)709*c2c66affSColin Finck HRESULT IDirectSound3DBufferImpl_Destroy(
710*c2c66affSColin Finck     IDirectSound3DBufferImpl *pds3db)
711*c2c66affSColin Finck {
712*c2c66affSColin Finck     TRACE("(%p)\n",pds3db);
713*c2c66affSColin Finck 
714*c2c66affSColin Finck     while (IDirectSound3DBufferImpl_Release((LPDIRECTSOUND3DBUFFER)pds3db) > 0);
715*c2c66affSColin Finck 
716*c2c66affSColin Finck     return S_OK;
717*c2c66affSColin Finck }
718*c2c66affSColin Finck 
719*c2c66affSColin Finck /*******************************************************************************
720*c2c66affSColin Finck  *	      IDirectSound3DListener
721*c2c66affSColin Finck  */
722*c2c66affSColin Finck 
723*c2c66affSColin Finck /* IUnknown methods */
IDirectSound3DListenerImpl_QueryInterface(LPDIRECTSOUND3DLISTENER iface,REFIID riid,LPVOID * ppobj)724*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DListenerImpl_QueryInterface(
725*c2c66affSColin Finck 	LPDIRECTSOUND3DLISTENER iface, REFIID riid, LPVOID *ppobj)
726*c2c66affSColin Finck {
727*c2c66affSColin Finck 	IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
728*c2c66affSColin Finck 
729*c2c66affSColin Finck 	TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
730*c2c66affSColin Finck 
731*c2c66affSColin Finck 	if (ppobj == NULL) {
732*c2c66affSColin Finck 		WARN("invalid parameter\n");
733*c2c66affSColin Finck 		return E_INVALIDARG;
734*c2c66affSColin Finck 	}
735*c2c66affSColin Finck 
736*c2c66affSColin Finck 	*ppobj = NULL;  /* assume failure */
737*c2c66affSColin Finck 
738*c2c66affSColin Finck 	if ( IsEqualGUID(riid, &IID_IUnknown) ||
739*c2c66affSColin Finck 	     IsEqualGUID(riid, &IID_IDirectSound3DListener ) ) {
740*c2c66affSColin Finck                 IDirectSound3DListener_AddRef((LPDIRECTSOUND3DLISTENER)This);
741*c2c66affSColin Finck 		*ppobj = This;
742*c2c66affSColin Finck 		return S_OK;
743*c2c66affSColin Finck 	}
744*c2c66affSColin Finck 
745*c2c66affSColin Finck 	if ( IsEqualGUID(riid, &IID_IDirectSoundBuffer) ) {
746*c2c66affSColin Finck                 *ppobj = &This->device->primary->IDirectSoundBuffer8_iface;
747*c2c66affSColin Finck                 IDirectSoundBuffer8_AddRef(&This->device->primary->IDirectSoundBuffer8_iface);
748*c2c66affSColin Finck                 return S_OK;
749*c2c66affSColin Finck 	}
750*c2c66affSColin Finck 
751*c2c66affSColin Finck         FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
752*c2c66affSColin Finck 	return E_NOINTERFACE;
753*c2c66affSColin Finck }
754*c2c66affSColin Finck 
IDirectSound3DListenerImpl_AddRef(LPDIRECTSOUND3DLISTENER iface)755*c2c66affSColin Finck static ULONG WINAPI IDirectSound3DListenerImpl_AddRef(LPDIRECTSOUND3DLISTENER iface)
756*c2c66affSColin Finck {
757*c2c66affSColin Finck     IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
758*c2c66affSColin Finck     ULONG ref = InterlockedIncrement(&(This->ref));
759*c2c66affSColin Finck 
760*c2c66affSColin Finck     TRACE("(%p) ref was %d\n", This, ref - 1);
761*c2c66affSColin Finck 
762*c2c66affSColin Finck     if(ref == 1)
763*c2c66affSColin Finck         InterlockedIncrement(&This->device->primary->numIfaces);
764*c2c66affSColin Finck 
765*c2c66affSColin Finck     return ref;
766*c2c66affSColin Finck }
767*c2c66affSColin Finck 
IDirectSound3DListenerImpl_Release(LPDIRECTSOUND3DLISTENER iface)768*c2c66affSColin Finck static ULONG WINAPI IDirectSound3DListenerImpl_Release(LPDIRECTSOUND3DLISTENER iface)
769*c2c66affSColin Finck {
770*c2c66affSColin Finck     IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
771*c2c66affSColin Finck     ULONG ref = InterlockedDecrement(&(This->ref));
772*c2c66affSColin Finck     TRACE("(%p) ref was %d\n", This, ref + 1);
773*c2c66affSColin Finck 
774*c2c66affSColin Finck     if (!ref) {
775*c2c66affSColin Finck         This->device->listener = 0;
776*c2c66affSColin Finck         if (!InterlockedDecrement(&This->device->primary->numIfaces))
777*c2c66affSColin Finck             primarybuffer_destroy(This->device->primary);
778*c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, This);
779*c2c66affSColin Finck         TRACE("(%p) released\n", This);
780*c2c66affSColin Finck     }
781*c2c66affSColin Finck     return ref;
782*c2c66affSColin Finck }
783*c2c66affSColin Finck 
784*c2c66affSColin Finck /* IDirectSound3DListener methods */
IDirectSound3DListenerImpl_GetAllParameter(LPDIRECTSOUND3DLISTENER iface,LPDS3DLISTENER lpDS3DL)785*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DListenerImpl_GetAllParameter(
786*c2c66affSColin Finck 	LPDIRECTSOUND3DLISTENER iface,
787*c2c66affSColin Finck 	LPDS3DLISTENER lpDS3DL)
788*c2c66affSColin Finck {
789*c2c66affSColin Finck 	IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
790*c2c66affSColin Finck 	TRACE("(%p,%p)\n",This,lpDS3DL);
791*c2c66affSColin Finck 
792*c2c66affSColin Finck 	if (lpDS3DL == NULL) {
793*c2c66affSColin Finck 		WARN("invalid parameter: lpDS3DL == NULL\n");
794*c2c66affSColin Finck 		return DSERR_INVALIDPARAM;
795*c2c66affSColin Finck 	}
796*c2c66affSColin Finck 
797*c2c66affSColin Finck 	if (lpDS3DL->dwSize < sizeof(*lpDS3DL)) {
798*c2c66affSColin Finck 		WARN("invalid parameter: lpDS3DL->dwSize = %d\n",lpDS3DL->dwSize);
799*c2c66affSColin Finck 		return DSERR_INVALIDPARAM;
800*c2c66affSColin Finck 	}
801*c2c66affSColin Finck 
802*c2c66affSColin Finck 	TRACE("returning: all parameters\n");
803*c2c66affSColin Finck 	*lpDS3DL = This->device->ds3dl;
804*c2c66affSColin Finck 	return DS_OK;
805*c2c66affSColin Finck }
806*c2c66affSColin Finck 
IDirectSound3DListenerImpl_GetDistanceFactor(LPDIRECTSOUND3DLISTENER iface,LPD3DVALUE lpfDistanceFactor)807*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DListenerImpl_GetDistanceFactor(
808*c2c66affSColin Finck 	LPDIRECTSOUND3DLISTENER iface,
809*c2c66affSColin Finck 	LPD3DVALUE lpfDistanceFactor)
810*c2c66affSColin Finck {
811*c2c66affSColin Finck 	IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
812*c2c66affSColin Finck 	TRACE("returning: Distance Factor = %f\n", This->device->ds3dl.flDistanceFactor);
813*c2c66affSColin Finck 	*lpfDistanceFactor = This->device->ds3dl.flDistanceFactor;
814*c2c66affSColin Finck 	return DS_OK;
815*c2c66affSColin Finck }
816*c2c66affSColin Finck 
IDirectSound3DListenerImpl_GetDopplerFactor(LPDIRECTSOUND3DLISTENER iface,LPD3DVALUE lpfDopplerFactor)817*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DListenerImpl_GetDopplerFactor(
818*c2c66affSColin Finck 	LPDIRECTSOUND3DLISTENER iface,
819*c2c66affSColin Finck 	LPD3DVALUE lpfDopplerFactor)
820*c2c66affSColin Finck {
821*c2c66affSColin Finck 	IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
822*c2c66affSColin Finck 	TRACE("returning: Doppler Factor = %f\n", This->device->ds3dl.flDopplerFactor);
823*c2c66affSColin Finck 	*lpfDopplerFactor = This->device->ds3dl.flDopplerFactor;
824*c2c66affSColin Finck 	return DS_OK;
825*c2c66affSColin Finck }
826*c2c66affSColin Finck 
IDirectSound3DListenerImpl_GetOrientation(LPDIRECTSOUND3DLISTENER iface,LPD3DVECTOR lpvOrientFront,LPD3DVECTOR lpvOrientTop)827*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DListenerImpl_GetOrientation(
828*c2c66affSColin Finck 	LPDIRECTSOUND3DLISTENER iface,
829*c2c66affSColin Finck 	LPD3DVECTOR lpvOrientFront,
830*c2c66affSColin Finck 	LPD3DVECTOR lpvOrientTop)
831*c2c66affSColin Finck {
832*c2c66affSColin Finck 	IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
833*c2c66affSColin Finck 	TRACE("returning: OrientFront vector = (%f,%f,%f); OrientTop vector = (%f,%f,%f)\n", This->device->ds3dl.vOrientFront.x,
834*c2c66affSColin Finck 	This->device->ds3dl.vOrientFront.y, This->device->ds3dl.vOrientFront.z, This->device->ds3dl.vOrientTop.x, This->device->ds3dl.vOrientTop.y,
835*c2c66affSColin Finck 	This->device->ds3dl.vOrientTop.z);
836*c2c66affSColin Finck 	*lpvOrientFront = This->device->ds3dl.vOrientFront;
837*c2c66affSColin Finck 	*lpvOrientTop = This->device->ds3dl.vOrientTop;
838*c2c66affSColin Finck 	return DS_OK;
839*c2c66affSColin Finck }
840*c2c66affSColin Finck 
IDirectSound3DListenerImpl_GetPosition(LPDIRECTSOUND3DLISTENER iface,LPD3DVECTOR lpvPosition)841*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DListenerImpl_GetPosition(
842*c2c66affSColin Finck 	LPDIRECTSOUND3DLISTENER iface,
843*c2c66affSColin Finck 	LPD3DVECTOR lpvPosition)
844*c2c66affSColin Finck {
845*c2c66affSColin Finck 	IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
846*c2c66affSColin Finck 	TRACE("returning: Position vector = (%f,%f,%f)\n", This->device->ds3dl.vPosition.x, This->device->ds3dl.vPosition.y, This->device->ds3dl.vPosition.z);
847*c2c66affSColin Finck 	*lpvPosition = This->device->ds3dl.vPosition;
848*c2c66affSColin Finck 	return DS_OK;
849*c2c66affSColin Finck }
850*c2c66affSColin Finck 
IDirectSound3DListenerImpl_GetRolloffFactor(LPDIRECTSOUND3DLISTENER iface,LPD3DVALUE lpfRolloffFactor)851*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DListenerImpl_GetRolloffFactor(
852*c2c66affSColin Finck 	LPDIRECTSOUND3DLISTENER iface,
853*c2c66affSColin Finck 	LPD3DVALUE lpfRolloffFactor)
854*c2c66affSColin Finck {
855*c2c66affSColin Finck 	IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
856*c2c66affSColin Finck 	TRACE("returning: RolloffFactor = %f\n", This->device->ds3dl.flRolloffFactor);
857*c2c66affSColin Finck 	*lpfRolloffFactor = This->device->ds3dl.flRolloffFactor;
858*c2c66affSColin Finck 	return DS_OK;
859*c2c66affSColin Finck }
860*c2c66affSColin Finck 
IDirectSound3DListenerImpl_GetVelocity(LPDIRECTSOUND3DLISTENER iface,LPD3DVECTOR lpvVelocity)861*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DListenerImpl_GetVelocity(
862*c2c66affSColin Finck 	LPDIRECTSOUND3DLISTENER iface,
863*c2c66affSColin Finck 	LPD3DVECTOR lpvVelocity)
864*c2c66affSColin Finck {
865*c2c66affSColin Finck 	IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
866*c2c66affSColin Finck 	TRACE("returning: Velocity vector = (%f,%f,%f)\n", This->device->ds3dl.vVelocity.x, This->device->ds3dl.vVelocity.y, This->device->ds3dl.vVelocity.z);
867*c2c66affSColin Finck 	*lpvVelocity = This->device->ds3dl.vVelocity;
868*c2c66affSColin Finck 	return DS_OK;
869*c2c66affSColin Finck }
870*c2c66affSColin Finck 
IDirectSound3DListenerImpl_SetAllParameters(LPDIRECTSOUND3DLISTENER iface,LPCDS3DLISTENER lpcDS3DL,DWORD dwApply)871*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DListenerImpl_SetAllParameters(
872*c2c66affSColin Finck 	LPDIRECTSOUND3DLISTENER iface,
873*c2c66affSColin Finck 	LPCDS3DLISTENER lpcDS3DL,
874*c2c66affSColin Finck 	DWORD dwApply)
875*c2c66affSColin Finck {
876*c2c66affSColin Finck 	IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
877*c2c66affSColin Finck 	TRACE("setting: all parameters; dwApply = %d\n", dwApply);
878*c2c66affSColin Finck 	This->device->ds3dl = *lpcDS3DL;
879*c2c66affSColin Finck 	if (dwApply == DS3D_IMMEDIATE)
880*c2c66affSColin Finck 	{
881*c2c66affSColin Finck 		This->device->ds3dl_need_recalc = FALSE;
882*c2c66affSColin Finck 		DSOUND_ChangeListener(This);
883*c2c66affSColin Finck 	}
884*c2c66affSColin Finck 	This->device->ds3dl_need_recalc = TRUE;
885*c2c66affSColin Finck 	return DS_OK;
886*c2c66affSColin Finck }
887*c2c66affSColin Finck 
IDirectSound3DListenerImpl_SetDistanceFactor(LPDIRECTSOUND3DLISTENER iface,D3DVALUE fDistanceFactor,DWORD dwApply)888*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DListenerImpl_SetDistanceFactor(
889*c2c66affSColin Finck 	LPDIRECTSOUND3DLISTENER iface,
890*c2c66affSColin Finck 	D3DVALUE fDistanceFactor,
891*c2c66affSColin Finck 	DWORD dwApply)
892*c2c66affSColin Finck {
893*c2c66affSColin Finck 	IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
894*c2c66affSColin Finck 	TRACE("setting: Distance Factor = %f; dwApply = %d\n", fDistanceFactor, dwApply);
895*c2c66affSColin Finck 	This->device->ds3dl.flDistanceFactor = fDistanceFactor;
896*c2c66affSColin Finck 	if (dwApply == DS3D_IMMEDIATE)
897*c2c66affSColin Finck 	{
898*c2c66affSColin Finck 		This->device->ds3dl_need_recalc = FALSE;
899*c2c66affSColin Finck 		DSOUND_ChangeListener(This);
900*c2c66affSColin Finck 	}
901*c2c66affSColin Finck 	This->device->ds3dl_need_recalc = TRUE;
902*c2c66affSColin Finck 	return DS_OK;
903*c2c66affSColin Finck }
904*c2c66affSColin Finck 
IDirectSound3DListenerImpl_SetDopplerFactor(LPDIRECTSOUND3DLISTENER iface,D3DVALUE fDopplerFactor,DWORD dwApply)905*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DListenerImpl_SetDopplerFactor(
906*c2c66affSColin Finck 	LPDIRECTSOUND3DLISTENER iface,
907*c2c66affSColin Finck 	D3DVALUE fDopplerFactor,
908*c2c66affSColin Finck 	DWORD dwApply)
909*c2c66affSColin Finck {
910*c2c66affSColin Finck 	IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
911*c2c66affSColin Finck 	TRACE("setting: Doppler Factor = %f; dwApply = %d\n", fDopplerFactor, dwApply);
912*c2c66affSColin Finck 	This->device->ds3dl.flDopplerFactor = fDopplerFactor;
913*c2c66affSColin Finck 	if (dwApply == DS3D_IMMEDIATE)
914*c2c66affSColin Finck 	{
915*c2c66affSColin Finck 		This->device->ds3dl_need_recalc = FALSE;
916*c2c66affSColin Finck 		DSOUND_ChangeListener(This);
917*c2c66affSColin Finck 	}
918*c2c66affSColin Finck 	This->device->ds3dl_need_recalc = TRUE;
919*c2c66affSColin Finck 	return DS_OK;
920*c2c66affSColin Finck }
921*c2c66affSColin Finck 
IDirectSound3DListenerImpl_SetOrientation(LPDIRECTSOUND3DLISTENER iface,D3DVALUE xFront,D3DVALUE yFront,D3DVALUE zFront,D3DVALUE xTop,D3DVALUE yTop,D3DVALUE zTop,DWORD dwApply)922*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DListenerImpl_SetOrientation(
923*c2c66affSColin Finck 	LPDIRECTSOUND3DLISTENER iface,
924*c2c66affSColin Finck 	D3DVALUE xFront, D3DVALUE yFront, D3DVALUE zFront,
925*c2c66affSColin Finck 	D3DVALUE xTop, D3DVALUE yTop, D3DVALUE zTop,
926*c2c66affSColin Finck 	DWORD dwApply)
927*c2c66affSColin Finck {
928*c2c66affSColin Finck 	IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
929*c2c66affSColin Finck 	TRACE("setting: Front vector = (%f,%f,%f); Top vector = (%f,%f,%f); dwApply = %d\n",
930*c2c66affSColin Finck 	xFront, yFront, zFront, xTop, yTop, zTop, dwApply);
931*c2c66affSColin Finck 	This->device->ds3dl.vOrientFront.x = xFront;
932*c2c66affSColin Finck 	This->device->ds3dl.vOrientFront.y = yFront;
933*c2c66affSColin Finck 	This->device->ds3dl.vOrientFront.z = zFront;
934*c2c66affSColin Finck 	This->device->ds3dl.vOrientTop.x = xTop;
935*c2c66affSColin Finck 	This->device->ds3dl.vOrientTop.y = yTop;
936*c2c66affSColin Finck 	This->device->ds3dl.vOrientTop.z = zTop;
937*c2c66affSColin Finck 	if (dwApply == DS3D_IMMEDIATE)
938*c2c66affSColin Finck 	{
939*c2c66affSColin Finck 		This->device->ds3dl_need_recalc = FALSE;
940*c2c66affSColin Finck 		DSOUND_ChangeListener(This);
941*c2c66affSColin Finck 	}
942*c2c66affSColin Finck 	This->device->ds3dl_need_recalc = TRUE;
943*c2c66affSColin Finck 	return DS_OK;
944*c2c66affSColin Finck }
945*c2c66affSColin Finck 
IDirectSound3DListenerImpl_SetPosition(LPDIRECTSOUND3DLISTENER iface,D3DVALUE x,D3DVALUE y,D3DVALUE z,DWORD dwApply)946*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DListenerImpl_SetPosition(
947*c2c66affSColin Finck 	LPDIRECTSOUND3DLISTENER iface,
948*c2c66affSColin Finck 	D3DVALUE x, D3DVALUE y, D3DVALUE z,
949*c2c66affSColin Finck 	DWORD dwApply)
950*c2c66affSColin Finck {
951*c2c66affSColin Finck 	IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
952*c2c66affSColin Finck 	TRACE("setting: Position vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply);
953*c2c66affSColin Finck 	This->device->ds3dl.vPosition.x = x;
954*c2c66affSColin Finck 	This->device->ds3dl.vPosition.y = y;
955*c2c66affSColin Finck 	This->device->ds3dl.vPosition.z = z;
956*c2c66affSColin Finck 	if (dwApply == DS3D_IMMEDIATE)
957*c2c66affSColin Finck 	{
958*c2c66affSColin Finck 		This->device->ds3dl_need_recalc = FALSE;
959*c2c66affSColin Finck 		DSOUND_ChangeListener(This);
960*c2c66affSColin Finck 	}
961*c2c66affSColin Finck 	This->device->ds3dl_need_recalc = TRUE;
962*c2c66affSColin Finck 	return DS_OK;
963*c2c66affSColin Finck }
964*c2c66affSColin Finck 
IDirectSound3DListenerImpl_SetRolloffFactor(LPDIRECTSOUND3DLISTENER iface,D3DVALUE fRolloffFactor,DWORD dwApply)965*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DListenerImpl_SetRolloffFactor(
966*c2c66affSColin Finck 	LPDIRECTSOUND3DLISTENER iface,
967*c2c66affSColin Finck 	D3DVALUE fRolloffFactor,
968*c2c66affSColin Finck 	DWORD dwApply)
969*c2c66affSColin Finck {
970*c2c66affSColin Finck 	IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
971*c2c66affSColin Finck 	TRACE("setting: Rolloff Factor = %f; dwApply = %d\n", fRolloffFactor, dwApply);
972*c2c66affSColin Finck 	This->device->ds3dl.flRolloffFactor = fRolloffFactor;
973*c2c66affSColin Finck 	if (dwApply == DS3D_IMMEDIATE)
974*c2c66affSColin Finck 	{
975*c2c66affSColin Finck 		This->device->ds3dl_need_recalc = FALSE;
976*c2c66affSColin Finck 		DSOUND_ChangeListener(This);
977*c2c66affSColin Finck 	}
978*c2c66affSColin Finck 	This->device->ds3dl_need_recalc = TRUE;
979*c2c66affSColin Finck 	return DS_OK;
980*c2c66affSColin Finck }
981*c2c66affSColin Finck 
IDirectSound3DListenerImpl_SetVelocity(LPDIRECTSOUND3DLISTENER iface,D3DVALUE x,D3DVALUE y,D3DVALUE z,DWORD dwApply)982*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DListenerImpl_SetVelocity(
983*c2c66affSColin Finck 	LPDIRECTSOUND3DLISTENER iface,
984*c2c66affSColin Finck 	D3DVALUE x, D3DVALUE y, D3DVALUE z,
985*c2c66affSColin Finck 	DWORD dwApply)
986*c2c66affSColin Finck {
987*c2c66affSColin Finck 	IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
988*c2c66affSColin Finck 	TRACE("setting: Velocity vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply);
989*c2c66affSColin Finck 	This->device->ds3dl.vVelocity.x = x;
990*c2c66affSColin Finck 	This->device->ds3dl.vVelocity.y = y;
991*c2c66affSColin Finck 	This->device->ds3dl.vVelocity.z = z;
992*c2c66affSColin Finck 	if (dwApply == DS3D_IMMEDIATE)
993*c2c66affSColin Finck 	{
994*c2c66affSColin Finck 		This->device->ds3dl_need_recalc = FALSE;
995*c2c66affSColin Finck 		DSOUND_ChangeListener(This);
996*c2c66affSColin Finck 	}
997*c2c66affSColin Finck 	This->device->ds3dl_need_recalc = TRUE;
998*c2c66affSColin Finck 	return DS_OK;
999*c2c66affSColin Finck }
1000*c2c66affSColin Finck 
IDirectSound3DListenerImpl_CommitDeferredSettings(LPDIRECTSOUND3DLISTENER iface)1001*c2c66affSColin Finck static HRESULT WINAPI IDirectSound3DListenerImpl_CommitDeferredSettings(
1002*c2c66affSColin Finck 	LPDIRECTSOUND3DLISTENER iface)
1003*c2c66affSColin Finck {
1004*c2c66affSColin Finck 	IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
1005*c2c66affSColin Finck 	TRACE("\n");
1006*c2c66affSColin Finck 	DSOUND_ChangeListener(This);
1007*c2c66affSColin Finck 	return DS_OK;
1008*c2c66affSColin Finck }
1009*c2c66affSColin Finck 
1010*c2c66affSColin Finck static const IDirectSound3DListenerVtbl ds3dlvt =
1011*c2c66affSColin Finck {
1012*c2c66affSColin Finck 	/* IUnknown methods */
1013*c2c66affSColin Finck 	IDirectSound3DListenerImpl_QueryInterface,
1014*c2c66affSColin Finck 	IDirectSound3DListenerImpl_AddRef,
1015*c2c66affSColin Finck 	IDirectSound3DListenerImpl_Release,
1016*c2c66affSColin Finck 	/* IDirectSound3DListener methods */
1017*c2c66affSColin Finck 	IDirectSound3DListenerImpl_GetAllParameter,
1018*c2c66affSColin Finck 	IDirectSound3DListenerImpl_GetDistanceFactor,
1019*c2c66affSColin Finck 	IDirectSound3DListenerImpl_GetDopplerFactor,
1020*c2c66affSColin Finck 	IDirectSound3DListenerImpl_GetOrientation,
1021*c2c66affSColin Finck 	IDirectSound3DListenerImpl_GetPosition,
1022*c2c66affSColin Finck 	IDirectSound3DListenerImpl_GetRolloffFactor,
1023*c2c66affSColin Finck 	IDirectSound3DListenerImpl_GetVelocity,
1024*c2c66affSColin Finck 	IDirectSound3DListenerImpl_SetAllParameters,
1025*c2c66affSColin Finck 	IDirectSound3DListenerImpl_SetDistanceFactor,
1026*c2c66affSColin Finck 	IDirectSound3DListenerImpl_SetDopplerFactor,
1027*c2c66affSColin Finck 	IDirectSound3DListenerImpl_SetOrientation,
1028*c2c66affSColin Finck 	IDirectSound3DListenerImpl_SetPosition,
1029*c2c66affSColin Finck 	IDirectSound3DListenerImpl_SetRolloffFactor,
1030*c2c66affSColin Finck 	IDirectSound3DListenerImpl_SetVelocity,
1031*c2c66affSColin Finck 	IDirectSound3DListenerImpl_CommitDeferredSettings,
1032*c2c66affSColin Finck };
1033*c2c66affSColin Finck 
IDirectSound3DListenerImpl_Create(DirectSoundDevice * device,IDirectSound3DListenerImpl ** ppdsl)1034*c2c66affSColin Finck HRESULT IDirectSound3DListenerImpl_Create(
1035*c2c66affSColin Finck 	DirectSoundDevice * device,
1036*c2c66affSColin Finck 	IDirectSound3DListenerImpl ** ppdsl)
1037*c2c66affSColin Finck {
1038*c2c66affSColin Finck 	IDirectSound3DListenerImpl *pdsl;
1039*c2c66affSColin Finck 	TRACE("(%p,%p)\n",device,ppdsl);
1040*c2c66affSColin Finck 
1041*c2c66affSColin Finck 	pdsl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*pdsl));
1042*c2c66affSColin Finck 
1043*c2c66affSColin Finck 	if (pdsl == NULL) {
1044*c2c66affSColin Finck 		WARN("out of memory\n");
1045*c2c66affSColin Finck 		*ppdsl = 0;
1046*c2c66affSColin Finck 		return DSERR_OUTOFMEMORY;
1047*c2c66affSColin Finck 	}
1048*c2c66affSColin Finck 
1049*c2c66affSColin Finck 	pdsl->ref = 0;
1050*c2c66affSColin Finck 	pdsl->lpVtbl = &ds3dlvt;
1051*c2c66affSColin Finck 
1052*c2c66affSColin Finck 	pdsl->device = device;
1053*c2c66affSColin Finck 
1054*c2c66affSColin Finck 	pdsl->device->ds3dl.dwSize = sizeof(DS3DLISTENER);
1055*c2c66affSColin Finck 	pdsl->device->ds3dl.vPosition.x = 0.0;
1056*c2c66affSColin Finck 	pdsl->device->ds3dl.vPosition.y = 0.0;
1057*c2c66affSColin Finck 	pdsl->device->ds3dl.vPosition.z = 0.0;
1058*c2c66affSColin Finck 	pdsl->device->ds3dl.vVelocity.x = 0.0;
1059*c2c66affSColin Finck 	pdsl->device->ds3dl.vVelocity.y = 0.0;
1060*c2c66affSColin Finck 	pdsl->device->ds3dl.vVelocity.z = 0.0;
1061*c2c66affSColin Finck 	pdsl->device->ds3dl.vOrientFront.x = 0.0;
1062*c2c66affSColin Finck 	pdsl->device->ds3dl.vOrientFront.y = 0.0;
1063*c2c66affSColin Finck 	pdsl->device->ds3dl.vOrientFront.z = 1.0;
1064*c2c66affSColin Finck 	pdsl->device->ds3dl.vOrientTop.x = 0.0;
1065*c2c66affSColin Finck 	pdsl->device->ds3dl.vOrientTop.y = 1.0;
1066*c2c66affSColin Finck 	pdsl->device->ds3dl.vOrientTop.z = 0.0;
1067*c2c66affSColin Finck 	pdsl->device->ds3dl.flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR;
1068*c2c66affSColin Finck 	pdsl->device->ds3dl.flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR;
1069*c2c66affSColin Finck 	pdsl->device->ds3dl.flDopplerFactor = DS3D_DEFAULTDOPPLERFACTOR;
1070*c2c66affSColin Finck 
1071*c2c66affSColin Finck 	pdsl->device->ds3dl_need_recalc = TRUE;
1072*c2c66affSColin Finck 
1073*c2c66affSColin Finck 	*ppdsl = pdsl;
1074*c2c66affSColin Finck 	return S_OK;
1075*c2c66affSColin Finck }
1076