Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensound3d.c
Go to the documentation of this file.
00001 /* DirectSound 00002 * 00003 * Copyright 1998 Marcus Meissner 00004 * Copyright 1998 Rob Riggs 00005 * Copyright 2000-2001 TransGaming Technologies, Inc. 00006 * Copyright 2002-2003 Rok Mandeljc <rok.mandeljc@gimb.org> 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00021 */ 00022 /* 00023 * Most thread locking is complete. There may be a few race 00024 * conditions still lurking. 00025 * 00026 * Tested with a Soundblaster clone, a Gravis UltraSound Classic, 00027 * and a Turtle Beach Tropez+. 00028 * 00029 * TODO: 00030 * Implement SetCooperativeLevel properly (need to address focus issues) 00031 * Implement DirectSound3DBuffers (stubs in place) 00032 * Use hardware 3D support if available 00033 * Add critical section locking inside Release and AddRef methods 00034 * Handle static buffers - put those in hardware, non-static not in hardware 00035 * Hardware DuplicateSoundBuffer 00036 * Proper volume calculation, and setting volume in HEL primary buffer 00037 * Optimize WINMM and negotiate fragment size, decrease DS_HEL_MARGIN 00038 */ 00039 00040 #include <stdarg.h> 00041 #include <math.h> /* Insomnia - pow() function */ 00042 00043 #define NONAMELESSUNION 00044 #define NONAMELESSSTRUCT 00045 #include "windef.h" 00046 #include "winbase.h" 00047 #include "winuser.h" 00048 #include "mmsystem.h" 00049 #include "winternl.h" 00050 #include "mmddk.h" 00051 #include "wine/debug.h" 00052 #include "dsound.h" 00053 #include "dsdriver.h" 00054 #include "dsound_private.h" 00055 00056 /* default velocity of sound in the air */ 00057 #define DEFAULT_VELOCITY 340 00058 00059 WINE_DEFAULT_DEBUG_CHANNEL(dsound3d); 00060 00061 /******************************************************************************* 00062 * Auxiliary functions 00063 */ 00064 00065 /* scalar product (i believe it's called dot product in english) */ 00066 static inline D3DVALUE ScalarProduct (const D3DVECTOR *a, const D3DVECTOR *b) 00067 { 00068 D3DVALUE c; 00069 c = (a->x*b->x) + (a->y*b->y) + (a->z*b->z); 00070 TRACE("(%f,%f,%f) * (%f,%f,%f) = %f)\n", a->x, a->y, a->z, b->x, b->y, 00071 b->z, c); 00072 return c; 00073 } 00074 00075 /* vector product (i believe it's called cross product in english */ 00076 static inline D3DVECTOR VectorProduct (const D3DVECTOR *a, const D3DVECTOR *b) 00077 { 00078 D3DVECTOR c; 00079 c.x = (a->y*b->z) - (a->z*b->y); 00080 c.y = (a->z*b->x) - (a->x*b->z); 00081 c.z = (a->x*b->y) - (a->y*b->x); 00082 TRACE("(%f,%f,%f) x (%f,%f,%f) = (%f,%f,%f)\n", a->x, a->y, a->z, b->x, b->y, 00083 b->z, c.x, c.y, c.z); 00084 return c; 00085 } 00086 00087 /* magnitude (length) of vector */ 00088 static inline D3DVALUE VectorMagnitude (const D3DVECTOR *a) 00089 { 00090 D3DVALUE l; 00091 l = sqrt (ScalarProduct (a, a)); 00092 TRACE("|(%f,%f,%f)| = %f\n", a->x, a->y, a->z, l); 00093 return l; 00094 } 00095 00096 /* conversion between radians and degrees */ 00097 static inline D3DVALUE RadToDeg (D3DVALUE angle) 00098 { 00099 D3DVALUE newangle; 00100 newangle = angle * (360/(2*M_PI)); 00101 TRACE("%f rad = %f deg\n", angle, newangle); 00102 return newangle; 00103 } 00104 00105 /* angle between vectors - rad version */ 00106 static inline D3DVALUE AngleBetweenVectorsRad (const D3DVECTOR *a, const D3DVECTOR *b) 00107 { 00108 D3DVALUE la, lb, product, angle, cos; 00109 /* definition of scalar product: a*b = |a|*|b|*cos... therefore: */ 00110 product = ScalarProduct (a,b); 00111 la = VectorMagnitude (a); 00112 lb = VectorMagnitude (b); 00113 if (!la || !lb) 00114 return 0; 00115 00116 cos = product/(la*lb); 00117 angle = acos(cos); 00118 TRACE("angle between (%f,%f,%f) and (%f,%f,%f) = %f radians (%f degrees)\n", a->x, a->y, a->z, b->x, 00119 b->y, b->z, angle, RadToDeg(angle)); 00120 return angle; 00121 } 00122 00123 static inline D3DVALUE AngleBetweenVectorsDeg (const D3DVECTOR *a, const D3DVECTOR *b) 00124 { 00125 return RadToDeg(AngleBetweenVectorsRad(a, b)); 00126 } 00127 00128 /* calculates vector between two points */ 00129 static inline D3DVECTOR VectorBetweenTwoPoints (const D3DVECTOR *a, const D3DVECTOR *b) 00130 { 00131 D3DVECTOR c; 00132 c.x = b->x - a->x; 00133 c.y = b->y - a->y; 00134 c.z = b->z - a->z; 00135 TRACE("A (%f,%f,%f), B (%f,%f,%f), AB = (%f,%f,%f)\n", a->x, a->y, a->z, b->x, b->y, 00136 b->z, c.x, c.y, c.z); 00137 return c; 00138 } 00139 00140 /* calculates the length of vector's projection on another vector */ 00141 static inline D3DVALUE ProjectVector (const D3DVECTOR *a, const D3DVECTOR *p) 00142 { 00143 D3DVALUE prod, result; 00144 prod = ScalarProduct(a, p); 00145 result = prod/VectorMagnitude(p); 00146 TRACE("length projection of (%f,%f,%f) on (%f,%f,%f) = %f\n", a->x, a->y, a->z, p->x, 00147 p->y, p->z, result); 00148 return result; 00149 } 00150 00151 /******************************************************************************* 00152 * 3D Buffer and Listener mixing 00153 */ 00154 00155 void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb) 00156 { 00157 /* volume, at which the sound will be played after all calcs. */ 00158 D3DVALUE lVolume = 0; 00159 /* stuff for distance related stuff calc. */ 00160 D3DVECTOR vDistance; 00161 D3DVALUE flDistance = 0; 00162 /* panning related stuff */ 00163 D3DVALUE flAngle; 00164 D3DVECTOR vLeft; 00165 /* doppler shift related stuff */ 00166 #if 0 00167 D3DVALUE flFreq, flBufferVel, flListenerVel; 00168 #endif 00169 00170 TRACE("(%p)\n",dsb); 00171 00172 /* initial buffer volume */ 00173 lVolume = dsb->ds3db_lVolume; 00174 00175 switch (dsb->ds3db_ds3db.dwMode) 00176 { 00177 case DS3DMODE_DISABLE: 00178 TRACE("3D processing disabled\n"); 00179 /* this one is here only to eliminate annoying warning message */ 00180 DSOUND_RecalcVolPan (&dsb->volpan); 00181 break; 00182 case DS3DMODE_NORMAL: 00183 TRACE("Normal 3D processing mode\n"); 00184 /* we need to calculate distance between buffer and listener*/ 00185 vDistance = VectorBetweenTwoPoints(&dsb->ds3db_ds3db.vPosition, &dsb->device->ds3dl.vPosition); 00186 flDistance = VectorMagnitude (&vDistance); 00187 break; 00188 case DS3DMODE_HEADRELATIVE: 00189 TRACE("Head-relative 3D processing mode\n"); 00190 /* distance between buffer and listener is same as buffer's position */ 00191 flDistance = VectorMagnitude (&dsb->ds3db_ds3db.vPosition); 00192 break; 00193 } 00194 00195 if (flDistance > dsb->ds3db_ds3db.flMaxDistance) 00196 { 00197 /* some apps don't want you to hear too distant sounds... */ 00198 if (dsb->dsbd.dwFlags & DSBCAPS_MUTE3DATMAXDISTANCE) 00199 { 00200 dsb->volpan.lVolume = DSBVOLUME_MIN; 00201 DSOUND_RecalcVolPan (&dsb->volpan); 00202 /* i guess mixing here would be a waste of power */ 00203 return; 00204 } 00205 else 00206 flDistance = dsb->ds3db_ds3db.flMaxDistance; 00207 } 00208 00209 if (flDistance < dsb->ds3db_ds3db.flMinDistance) 00210 flDistance = dsb->ds3db_ds3db.flMinDistance; 00211 00212 /* attenuation proportional to the distance squared, converted to millibels as in lVolume*/ 00213 lVolume -= log10(flDistance/dsb->ds3db_ds3db.flMinDistance * flDistance/dsb->ds3db_ds3db.flMinDistance)*1000; 00214 TRACE("dist. att: Distance = %f, MinDistance = %f => adjusting volume %d to %f\n", flDistance, dsb->ds3db_ds3db.flMinDistance, dsb->ds3db_lVolume, lVolume); 00215 00216 /* conning */ 00217 /* sometimes it happens that vConeOrientation vector = (0,0,0); in this case angle is "nan" and it's useless*/ 00218 if (dsb->ds3db_ds3db.vConeOrientation.x == 0 && dsb->ds3db_ds3db.vConeOrientation.y == 0 && dsb->ds3db_ds3db.vConeOrientation.z == 0) 00219 { 00220 TRACE("conning: cones not set\n"); 00221 } 00222 else 00223 { 00224 /* calculate angle */ 00225 flAngle = AngleBetweenVectorsDeg(&dsb->ds3db_ds3db.vConeOrientation, &vDistance); 00226 /* if by any chance it happens that OutsideConeAngle = InsideConeAngle (that means that conning has no effect) */ 00227 if (dsb->ds3db_ds3db.dwInsideConeAngle != dsb->ds3db_ds3db.dwOutsideConeAngle) 00228 { 00229 /* my test show that for my way of calc., we need only half of angles */ 00230 DWORD dwInsideConeAngle = dsb->ds3db_ds3db.dwInsideConeAngle/2; 00231 DWORD dwOutsideConeAngle = dsb->ds3db_ds3db.dwOutsideConeAngle/2; 00232 if (dwOutsideConeAngle == dwInsideConeAngle) 00233 ++dwOutsideConeAngle; 00234 00235 /* full volume */ 00236 if (flAngle < dwInsideConeAngle) 00237 flAngle = dwInsideConeAngle; 00238 /* min (app defined) volume */ 00239 if (flAngle > dwOutsideConeAngle) 00240 flAngle = dwOutsideConeAngle; 00241 /* this probably isn't the right thing, but it's ok for the time being */ 00242 lVolume += ((dsb->ds3db_ds3db.lConeOutsideVolume)/((dwOutsideConeAngle) - (dwInsideConeAngle))) * flAngle; 00243 } 00244 TRACE("conning: Angle = %f deg; InsideConeAngle(/2) = %d deg; OutsideConeAngle(/2) = %d deg; ConeOutsideVolume = %d => adjusting volume to %f\n", 00245 flAngle, dsb->ds3db_ds3db.dwInsideConeAngle/2, dsb->ds3db_ds3db.dwOutsideConeAngle/2, dsb->ds3db_ds3db.lConeOutsideVolume, lVolume); 00246 } 00247 dsb->volpan.lVolume = lVolume; 00248 00249 /* panning */ 00250 if (dsb->device->ds3dl.vPosition.x == dsb->ds3db_ds3db.vPosition.x && 00251 dsb->device->ds3dl.vPosition.y == dsb->ds3db_ds3db.vPosition.y && 00252 dsb->device->ds3dl.vPosition.z == dsb->ds3db_ds3db.vPosition.z) { 00253 dsb->volpan.lPan = 0; 00254 flAngle = 0.0; 00255 } 00256 else 00257 { 00258 vDistance = VectorBetweenTwoPoints(&dsb->device->ds3dl.vPosition, &dsb->ds3db_ds3db.vPosition); 00259 vLeft = VectorProduct(&dsb->device->ds3dl.vOrientFront, &dsb->device->ds3dl.vOrientTop); 00260 flAngle = AngleBetweenVectorsRad(&vLeft, &vDistance); 00261 /* for now, we'll use "linear formula" (which is probably incorrect); if someone has it in book, correct it */ 00262 dsb->volpan.lPan = 10000*2*flAngle/M_PI - 10000; 00263 } 00264 TRACE("panning: Angle = %f rad, lPan = %d\n", flAngle, dsb->volpan.lPan); 00265 00266 /* FIXME: Doppler Effect disabled since i have no idea which frequency to change and how to do it */ 00267 #if 0 00268 /* doppler shift*/ 00269 if ((VectorMagnitude(&ds3db_ds3db.vVelocity) == 0) && (VectorMagnitude(&dsb->device->ds3dl.vVelocity) == 0)) 00270 { 00271 TRACE("doppler: Buffer and Listener don't have velocities\n"); 00272 } 00273 else if (ds3db_ds3db.vVelocity != dsb->device->ds3dl.vVelocity) 00274 { 00275 /* calculate length of ds3db_ds3db.vVelocity component which causes Doppler Effect 00276 NOTE: if buffer moves TOWARDS the listener, it's velocity component is NEGATIVE 00277 if buffer moves AWAY from listener, it's velocity component is POSITIVE */ 00278 flBufferVel = ProjectVector(&dsb->ds3db_ds3db.vVelocity, &vDistance); 00279 /* calculate length of ds3dl.vVelocity component which causes Doppler Effect 00280 NOTE: if listener moves TOWARDS the buffer, it's velocity component is POSITIVE 00281 if listener moves AWAY from buffer, it's velocity component is NEGATIVE */ 00282 flListenerVel = ProjectVector(&dsb->device->ds3dl.vVelocity, &vDistance); 00283 /* formula taken from Gianicoli D.: Physics, 4th edition: */ 00284 /* FIXME: replace dsb->freq with appropriate frequency ! */ 00285 flFreq = dsb->freq * ((DEFAULT_VELOCITY + flListenerVel)/(DEFAULT_VELOCITY + flBufferVel)); 00286 TRACE("doppler: Buffer velocity (component) = %lf, Listener velocity (component) = %lf => Doppler shift: %ld Hz -> %lf Hz\n", flBufferVel, flListenerVel, 00287 dsb->freq, flFreq); 00288 /* FIXME: replace following line with correct frequency setting ! */ 00289 dsb->freq = flFreq; 00290 DSOUND_RecalcFormat(dsb); 00291 DSOUND_MixToTemporary(dsb, 0, dsb->buflen); 00292 } 00293 #endif 00294 00295 /* time for remix */ 00296 DSOUND_RecalcVolPan(&dsb->volpan); 00297 } 00298 00299 static void DSOUND_Mix3DBuffer(IDirectSoundBufferImpl *dsb) 00300 { 00301 TRACE("(%p)\n",dsb); 00302 00303 DSOUND_Calc3DBuffer(dsb); 00304 } 00305 00306 static void DSOUND_ChangeListener(IDirectSound3DListenerImpl *ds3dl) 00307 { 00308 int i; 00309 TRACE("(%p)\n",ds3dl); 00310 for (i = 0; i < ds3dl->device->nrofbuffers; i++) 00311 { 00312 /* check if this buffer is waiting for recalculation */ 00313 if (ds3dl->device->buffers[i]->ds3db_need_recalc) 00314 { 00315 DSOUND_Mix3DBuffer(ds3dl->device->buffers[i]); 00316 } 00317 } 00318 } 00319 00320 /******************************************************************************* 00321 * IDirectSound3DBuffer 00322 */ 00323 00324 /* IUnknown methods */ 00325 static HRESULT WINAPI IDirectSound3DBufferImpl_QueryInterface( 00326 LPDIRECTSOUND3DBUFFER iface, REFIID riid, LPVOID *ppobj) 00327 { 00328 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00329 00330 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); 00331 return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb, riid, ppobj); 00332 } 00333 00334 static ULONG WINAPI IDirectSound3DBufferImpl_AddRef(LPDIRECTSOUND3DBUFFER iface) 00335 { 00336 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00337 ULONG ref = InterlockedIncrement(&(This->ref)); 00338 TRACE("(%p) ref was %d\n", This, ref - 1); 00339 return ref; 00340 } 00341 00342 static ULONG WINAPI IDirectSound3DBufferImpl_Release(LPDIRECTSOUND3DBUFFER iface) 00343 { 00344 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00345 ULONG ref = InterlockedDecrement(&(This->ref)); 00346 TRACE("(%p) ref was %d\n", This, ref + 1); 00347 00348 if (!ref) { 00349 This->dsb->ds3db = NULL; 00350 IDirectSoundBuffer_Release((LPDIRECTSOUNDBUFFER8)This->dsb); 00351 HeapFree(GetProcessHeap(), 0, This); 00352 TRACE("(%p) released\n", This); 00353 } 00354 return ref; 00355 } 00356 00357 /* IDirectSound3DBuffer methods */ 00358 static HRESULT WINAPI IDirectSound3DBufferImpl_GetAllParameters( 00359 LPDIRECTSOUND3DBUFFER iface, 00360 LPDS3DBUFFER lpDs3dBuffer) 00361 { 00362 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00363 TRACE("(%p,%p)\n",This,lpDs3dBuffer); 00364 00365 if (lpDs3dBuffer == NULL) { 00366 WARN("invalid parameter: lpDs3dBuffer == NULL\n"); 00367 return DSERR_INVALIDPARAM; 00368 } 00369 00370 if (lpDs3dBuffer->dwSize < sizeof(*lpDs3dBuffer)) { 00371 WARN("invalid parameter: lpDs3dBuffer->dwSize = %d\n",lpDs3dBuffer->dwSize); 00372 return DSERR_INVALIDPARAM; 00373 } 00374 00375 TRACE("returning: all parameters\n"); 00376 *lpDs3dBuffer = This->dsb->ds3db_ds3db; 00377 return DS_OK; 00378 } 00379 00380 static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeAngles( 00381 LPDIRECTSOUND3DBUFFER iface, 00382 LPDWORD lpdwInsideConeAngle, 00383 LPDWORD lpdwOutsideConeAngle) 00384 { 00385 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00386 TRACE("returning: Inside Cone Angle = %d degrees; Outside Cone Angle = %d degrees\n", 00387 This->dsb->ds3db_ds3db.dwInsideConeAngle, This->dsb->ds3db_ds3db.dwOutsideConeAngle); 00388 *lpdwInsideConeAngle = This->dsb->ds3db_ds3db.dwInsideConeAngle; 00389 *lpdwOutsideConeAngle = This->dsb->ds3db_ds3db.dwOutsideConeAngle; 00390 return DS_OK; 00391 } 00392 00393 static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeOrientation( 00394 LPDIRECTSOUND3DBUFFER iface, 00395 LPD3DVECTOR lpvConeOrientation) 00396 { 00397 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00398 TRACE("returning: Cone Orientation vector = (%f,%f,%f)\n", 00399 This->dsb->ds3db_ds3db.vConeOrientation.x, 00400 This->dsb->ds3db_ds3db.vConeOrientation.y, 00401 This->dsb->ds3db_ds3db.vConeOrientation.z); 00402 *lpvConeOrientation = This->dsb->ds3db_ds3db.vConeOrientation; 00403 return DS_OK; 00404 } 00405 00406 static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeOutsideVolume( 00407 LPDIRECTSOUND3DBUFFER iface, 00408 LPLONG lplConeOutsideVolume) 00409 { 00410 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00411 TRACE("returning: Cone Outside Volume = %d\n", This->dsb->ds3db_ds3db.lConeOutsideVolume); 00412 *lplConeOutsideVolume = This->dsb->ds3db_ds3db.lConeOutsideVolume; 00413 return DS_OK; 00414 } 00415 00416 static HRESULT WINAPI IDirectSound3DBufferImpl_GetMaxDistance( 00417 LPDIRECTSOUND3DBUFFER iface, 00418 LPD3DVALUE lpfMaxDistance) 00419 { 00420 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00421 TRACE("returning: Max Distance = %f\n", This->dsb->ds3db_ds3db.flMaxDistance); 00422 *lpfMaxDistance = This->dsb->ds3db_ds3db.flMaxDistance; 00423 return DS_OK; 00424 } 00425 00426 static HRESULT WINAPI IDirectSound3DBufferImpl_GetMinDistance( 00427 LPDIRECTSOUND3DBUFFER iface, 00428 LPD3DVALUE lpfMinDistance) 00429 { 00430 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00431 TRACE("returning: Min Distance = %f\n", This->dsb->ds3db_ds3db.flMinDistance); 00432 *lpfMinDistance = This->dsb->ds3db_ds3db.flMinDistance; 00433 return DS_OK; 00434 } 00435 00436 static HRESULT WINAPI IDirectSound3DBufferImpl_GetMode( 00437 LPDIRECTSOUND3DBUFFER iface, 00438 LPDWORD lpdwMode) 00439 { 00440 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00441 TRACE("returning: Mode = %d\n", This->dsb->ds3db_ds3db.dwMode); 00442 *lpdwMode = This->dsb->ds3db_ds3db.dwMode; 00443 return DS_OK; 00444 } 00445 00446 static HRESULT WINAPI IDirectSound3DBufferImpl_GetPosition( 00447 LPDIRECTSOUND3DBUFFER iface, 00448 LPD3DVECTOR lpvPosition) 00449 { 00450 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00451 TRACE("returning: Position vector = (%f,%f,%f)\n", 00452 This->dsb->ds3db_ds3db.vPosition.x, 00453 This->dsb->ds3db_ds3db.vPosition.y, 00454 This->dsb->ds3db_ds3db.vPosition.z); 00455 *lpvPosition = This->dsb->ds3db_ds3db.vPosition; 00456 return DS_OK; 00457 } 00458 00459 static HRESULT WINAPI IDirectSound3DBufferImpl_GetVelocity( 00460 LPDIRECTSOUND3DBUFFER iface, 00461 LPD3DVECTOR lpvVelocity) 00462 { 00463 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00464 TRACE("returning: Velocity vector = (%f,%f,%f)\n", 00465 This->dsb->ds3db_ds3db.vVelocity.x, 00466 This->dsb->ds3db_ds3db.vVelocity.y, 00467 This->dsb->ds3db_ds3db.vVelocity.z); 00468 *lpvVelocity = This->dsb->ds3db_ds3db.vVelocity; 00469 return DS_OK; 00470 } 00471 00472 static HRESULT WINAPI IDirectSound3DBufferImpl_SetAllParameters( 00473 LPDIRECTSOUND3DBUFFER iface, 00474 LPCDS3DBUFFER lpcDs3dBuffer, 00475 DWORD dwApply) 00476 { 00477 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00478 DWORD status = DSERR_INVALIDPARAM; 00479 TRACE("(%p,%p,%x)\n",iface,lpcDs3dBuffer,dwApply); 00480 00481 if (lpcDs3dBuffer == NULL) { 00482 WARN("invalid parameter: lpcDs3dBuffer == NULL\n"); 00483 return status; 00484 } 00485 00486 if (lpcDs3dBuffer->dwSize != sizeof(DS3DBUFFER)) { 00487 WARN("invalid parameter: lpcDs3dBuffer->dwSize = %d\n", lpcDs3dBuffer->dwSize); 00488 return status; 00489 } 00490 00491 TRACE("setting: all parameters; dwApply = %d\n", dwApply); 00492 This->dsb->ds3db_ds3db = *lpcDs3dBuffer; 00493 00494 if (dwApply == DS3D_IMMEDIATE) 00495 { 00496 DSOUND_Mix3DBuffer(This->dsb); 00497 } 00498 This->dsb->ds3db_need_recalc = TRUE; 00499 status = DS_OK; 00500 00501 return status; 00502 } 00503 00504 static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeAngles( 00505 LPDIRECTSOUND3DBUFFER iface, 00506 DWORD dwInsideConeAngle, 00507 DWORD dwOutsideConeAngle, 00508 DWORD dwApply) 00509 { 00510 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00511 TRACE("setting: Inside Cone Angle = %d; Outside Cone Angle = %d; dwApply = %d\n", 00512 dwInsideConeAngle, dwOutsideConeAngle, dwApply); 00513 This->dsb->ds3db_ds3db.dwInsideConeAngle = dwInsideConeAngle; 00514 This->dsb->ds3db_ds3db.dwOutsideConeAngle = dwOutsideConeAngle; 00515 if (dwApply == DS3D_IMMEDIATE) 00516 { 00517 DSOUND_Mix3DBuffer(This->dsb); 00518 } 00519 This->dsb->ds3db_need_recalc = TRUE; 00520 return DS_OK; 00521 } 00522 00523 static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOrientation( 00524 LPDIRECTSOUND3DBUFFER iface, 00525 D3DVALUE x, D3DVALUE y, D3DVALUE z, 00526 DWORD dwApply) 00527 { 00528 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00529 TRACE("setting: Cone Orientation vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply); 00530 This->dsb->ds3db_ds3db.vConeOrientation.x = x; 00531 This->dsb->ds3db_ds3db.vConeOrientation.y = y; 00532 This->dsb->ds3db_ds3db.vConeOrientation.z = z; 00533 if (dwApply == DS3D_IMMEDIATE) 00534 { 00535 This->dsb->ds3db_need_recalc = FALSE; 00536 DSOUND_Mix3DBuffer(This->dsb); 00537 } 00538 This->dsb->ds3db_need_recalc = TRUE; 00539 return DS_OK; 00540 } 00541 00542 static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOutsideVolume( 00543 LPDIRECTSOUND3DBUFFER iface, 00544 LONG lConeOutsideVolume, 00545 DWORD dwApply) 00546 { 00547 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00548 TRACE("setting: ConeOutsideVolume = %d; dwApply = %d\n", lConeOutsideVolume, dwApply); 00549 This->dsb->ds3db_ds3db.lConeOutsideVolume = lConeOutsideVolume; 00550 if (dwApply == DS3D_IMMEDIATE) 00551 { 00552 This->dsb->ds3db_need_recalc = FALSE; 00553 DSOUND_Mix3DBuffer(This->dsb); 00554 } 00555 This->dsb->ds3db_need_recalc = TRUE; 00556 return DS_OK; 00557 } 00558 00559 static HRESULT WINAPI IDirectSound3DBufferImpl_SetMaxDistance( 00560 LPDIRECTSOUND3DBUFFER iface, 00561 D3DVALUE fMaxDistance, 00562 DWORD dwApply) 00563 { 00564 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00565 TRACE("setting: MaxDistance = %f; dwApply = %d\n", fMaxDistance, dwApply); 00566 This->dsb->ds3db_ds3db.flMaxDistance = fMaxDistance; 00567 if (dwApply == DS3D_IMMEDIATE) 00568 { 00569 This->dsb->ds3db_need_recalc = FALSE; 00570 DSOUND_Mix3DBuffer(This->dsb); 00571 } 00572 This->dsb->ds3db_need_recalc = TRUE; 00573 return DS_OK; 00574 } 00575 00576 static HRESULT WINAPI IDirectSound3DBufferImpl_SetMinDistance( 00577 LPDIRECTSOUND3DBUFFER iface, 00578 D3DVALUE fMinDistance, 00579 DWORD dwApply) 00580 { 00581 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00582 TRACE("setting: MinDistance = %f; dwApply = %d\n", fMinDistance, dwApply); 00583 This->dsb->ds3db_ds3db.flMinDistance = fMinDistance; 00584 if (dwApply == DS3D_IMMEDIATE) 00585 { 00586 This->dsb->ds3db_need_recalc = FALSE; 00587 DSOUND_Mix3DBuffer(This->dsb); 00588 } 00589 This->dsb->ds3db_need_recalc = TRUE; 00590 return DS_OK; 00591 } 00592 00593 static HRESULT WINAPI IDirectSound3DBufferImpl_SetMode( 00594 LPDIRECTSOUND3DBUFFER iface, 00595 DWORD dwMode, 00596 DWORD dwApply) 00597 { 00598 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00599 TRACE("setting: Mode = %d; dwApply = %d\n", dwMode, dwApply); 00600 This->dsb->ds3db_ds3db.dwMode = dwMode; 00601 if (dwApply == DS3D_IMMEDIATE) 00602 { 00603 This->dsb->ds3db_need_recalc = FALSE; 00604 DSOUND_Mix3DBuffer(This->dsb); 00605 } 00606 This->dsb->ds3db_need_recalc = TRUE; 00607 return DS_OK; 00608 } 00609 00610 static HRESULT WINAPI IDirectSound3DBufferImpl_SetPosition( 00611 LPDIRECTSOUND3DBUFFER iface, 00612 D3DVALUE x, D3DVALUE y, D3DVALUE z, 00613 DWORD dwApply) 00614 { 00615 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00616 TRACE("setting: Position vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply); 00617 This->dsb->ds3db_ds3db.vPosition.x = x; 00618 This->dsb->ds3db_ds3db.vPosition.y = y; 00619 This->dsb->ds3db_ds3db.vPosition.z = z; 00620 if (dwApply == DS3D_IMMEDIATE) 00621 { 00622 This->dsb->ds3db_need_recalc = FALSE; 00623 DSOUND_Mix3DBuffer(This->dsb); 00624 } 00625 This->dsb->ds3db_need_recalc = TRUE; 00626 return DS_OK; 00627 } 00628 00629 static HRESULT WINAPI IDirectSound3DBufferImpl_SetVelocity( 00630 LPDIRECTSOUND3DBUFFER iface, 00631 D3DVALUE x, D3DVALUE y, D3DVALUE z, 00632 DWORD dwApply) 00633 { 00634 IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; 00635 TRACE("setting: Velocity vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply); 00636 This->dsb->ds3db_ds3db.vVelocity.x = x; 00637 This->dsb->ds3db_ds3db.vVelocity.y = y; 00638 This->dsb->ds3db_ds3db.vVelocity.z = z; 00639 if (dwApply == DS3D_IMMEDIATE) 00640 { 00641 This->dsb->ds3db_need_recalc = FALSE; 00642 DSOUND_Mix3DBuffer(This->dsb); 00643 } 00644 This->dsb->ds3db_need_recalc = TRUE; 00645 return DS_OK; 00646 } 00647 00648 static const IDirectSound3DBufferVtbl ds3dbvt = 00649 { 00650 /* IUnknown methods */ 00651 IDirectSound3DBufferImpl_QueryInterface, 00652 IDirectSound3DBufferImpl_AddRef, 00653 IDirectSound3DBufferImpl_Release, 00654 /* IDirectSound3DBuffer methods */ 00655 IDirectSound3DBufferImpl_GetAllParameters, 00656 IDirectSound3DBufferImpl_GetConeAngles, 00657 IDirectSound3DBufferImpl_GetConeOrientation, 00658 IDirectSound3DBufferImpl_GetConeOutsideVolume, 00659 IDirectSound3DBufferImpl_GetMaxDistance, 00660 IDirectSound3DBufferImpl_GetMinDistance, 00661 IDirectSound3DBufferImpl_GetMode, 00662 IDirectSound3DBufferImpl_GetPosition, 00663 IDirectSound3DBufferImpl_GetVelocity, 00664 IDirectSound3DBufferImpl_SetAllParameters, 00665 IDirectSound3DBufferImpl_SetConeAngles, 00666 IDirectSound3DBufferImpl_SetConeOrientation, 00667 IDirectSound3DBufferImpl_SetConeOutsideVolume, 00668 IDirectSound3DBufferImpl_SetMaxDistance, 00669 IDirectSound3DBufferImpl_SetMinDistance, 00670 IDirectSound3DBufferImpl_SetMode, 00671 IDirectSound3DBufferImpl_SetPosition, 00672 IDirectSound3DBufferImpl_SetVelocity, 00673 }; 00674 00675 HRESULT IDirectSound3DBufferImpl_Create( 00676 IDirectSoundBufferImpl *dsb, 00677 IDirectSound3DBufferImpl **pds3db) 00678 { 00679 IDirectSound3DBufferImpl *ds3db; 00680 TRACE("(%p,%p)\n",dsb,pds3db); 00681 00682 ds3db = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*ds3db)); 00683 00684 if (ds3db == NULL) { 00685 WARN("out of memory\n"); 00686 *pds3db = 0; 00687 return DSERR_OUTOFMEMORY; 00688 } 00689 00690 ds3db->ref = 0; 00691 ds3db->dsb = dsb; 00692 ds3db->lpVtbl = &ds3dbvt; 00693 00694 ds3db->dsb->ds3db_ds3db.dwSize = sizeof(DS3DBUFFER); 00695 ds3db->dsb->ds3db_ds3db.vPosition.x = 0.0; 00696 ds3db->dsb->ds3db_ds3db.vPosition.y = 0.0; 00697 ds3db->dsb->ds3db_ds3db.vPosition.z = 0.0; 00698 ds3db->dsb->ds3db_ds3db.vVelocity.x = 0.0; 00699 ds3db->dsb->ds3db_ds3db.vVelocity.y = 0.0; 00700 ds3db->dsb->ds3db_ds3db.vVelocity.z = 0.0; 00701 ds3db->dsb->ds3db_ds3db.dwInsideConeAngle = DS3D_DEFAULTCONEANGLE; 00702 ds3db->dsb->ds3db_ds3db.dwOutsideConeAngle = DS3D_DEFAULTCONEANGLE; 00703 ds3db->dsb->ds3db_ds3db.vConeOrientation.x = 0.0; 00704 ds3db->dsb->ds3db_ds3db.vConeOrientation.y = 0.0; 00705 ds3db->dsb->ds3db_ds3db.vConeOrientation.z = 0.0; 00706 ds3db->dsb->ds3db_ds3db.lConeOutsideVolume = DS3D_DEFAULTCONEOUTSIDEVOLUME; 00707 ds3db->dsb->ds3db_ds3db.flMinDistance = DS3D_DEFAULTMINDISTANCE; 00708 ds3db->dsb->ds3db_ds3db.flMaxDistance = DS3D_DEFAULTMAXDISTANCE; 00709 ds3db->dsb->ds3db_ds3db.dwMode = DS3DMODE_NORMAL; 00710 00711 ds3db->dsb->ds3db_need_recalc = TRUE; 00712 00713 IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)dsb); 00714 00715 *pds3db = ds3db; 00716 return S_OK; 00717 } 00718 00719 HRESULT IDirectSound3DBufferImpl_Destroy( 00720 IDirectSound3DBufferImpl *pds3db) 00721 { 00722 TRACE("(%p)\n",pds3db); 00723 00724 while (IDirectSound3DBufferImpl_Release((LPDIRECTSOUND3DBUFFER)pds3db) > 0); 00725 00726 return S_OK; 00727 } 00728 00729 /******************************************************************************* 00730 * IDirectSound3DListener 00731 */ 00732 00733 /* IUnknown methods */ 00734 static HRESULT WINAPI IDirectSound3DListenerImpl_QueryInterface( 00735 LPDIRECTSOUND3DLISTENER iface, REFIID riid, LPVOID *ppobj) 00736 { 00737 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00738 00739 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); 00740 00741 if (ppobj == NULL) { 00742 WARN("invalid parameter\n"); 00743 return E_INVALIDARG; 00744 } 00745 00746 *ppobj = NULL; /* assume failure */ 00747 00748 if ( IsEqualGUID(riid, &IID_IUnknown) || 00749 IsEqualGUID(riid, &IID_IDirectSound3DListener ) ) { 00750 IDirectSound3DListener_AddRef((LPDIRECTSOUND3DLISTENER)This); 00751 *ppobj = This; 00752 return S_OK; 00753 } 00754 00755 if ( IsEqualGUID(riid, &IID_IDirectSoundBuffer) ) { 00756 if (!This->device->primary) 00757 PrimaryBufferImpl_Create(This->device, &(This->device->primary), &(This->device->dsbd)); 00758 if (This->device->primary) { 00759 *ppobj = This->device->primary; 00760 IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)*ppobj); 00761 return S_OK; 00762 } 00763 } 00764 00765 FIXME( "Unknown IID %s\n", debugstr_guid( riid ) ); 00766 return E_NOINTERFACE; 00767 } 00768 00769 static ULONG WINAPI IDirectSound3DListenerImpl_AddRef(LPDIRECTSOUND3DLISTENER iface) 00770 { 00771 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00772 ULONG ref = InterlockedIncrement(&(This->ref)); 00773 TRACE("(%p) ref was %d\n", This, ref - 1); 00774 return ref; 00775 } 00776 00777 static ULONG WINAPI IDirectSound3DListenerImpl_Release(LPDIRECTSOUND3DLISTENER iface) 00778 { 00779 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00780 ULONG ref = InterlockedDecrement(&(This->ref)); 00781 TRACE("(%p) ref was %d\n", This, ref + 1); 00782 00783 if (!ref) { 00784 This->device->listener = 0; 00785 HeapFree(GetProcessHeap(), 0, This); 00786 TRACE("(%p) released\n", This); 00787 } 00788 return ref; 00789 } 00790 00791 /* IDirectSound3DListener methods */ 00792 static HRESULT WINAPI IDirectSound3DListenerImpl_GetAllParameter( 00793 LPDIRECTSOUND3DLISTENER iface, 00794 LPDS3DLISTENER lpDS3DL) 00795 { 00796 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00797 TRACE("(%p,%p)\n",This,lpDS3DL); 00798 00799 if (lpDS3DL == NULL) { 00800 WARN("invalid parameter: lpDS3DL == NULL\n"); 00801 return DSERR_INVALIDPARAM; 00802 } 00803 00804 if (lpDS3DL->dwSize < sizeof(*lpDS3DL)) { 00805 WARN("invalid parameter: lpDS3DL->dwSize = %d\n",lpDS3DL->dwSize); 00806 return DSERR_INVALIDPARAM; 00807 } 00808 00809 TRACE("returning: all parameters\n"); 00810 *lpDS3DL = This->device->ds3dl; 00811 return DS_OK; 00812 } 00813 00814 static HRESULT WINAPI IDirectSound3DListenerImpl_GetDistanceFactor( 00815 LPDIRECTSOUND3DLISTENER iface, 00816 LPD3DVALUE lpfDistanceFactor) 00817 { 00818 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00819 TRACE("returning: Distance Factor = %f\n", This->device->ds3dl.flDistanceFactor); 00820 *lpfDistanceFactor = This->device->ds3dl.flDistanceFactor; 00821 return DS_OK; 00822 } 00823 00824 static HRESULT WINAPI IDirectSound3DListenerImpl_GetDopplerFactor( 00825 LPDIRECTSOUND3DLISTENER iface, 00826 LPD3DVALUE lpfDopplerFactor) 00827 { 00828 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00829 TRACE("returning: Doppler Factor = %f\n", This->device->ds3dl.flDopplerFactor); 00830 *lpfDopplerFactor = This->device->ds3dl.flDopplerFactor; 00831 return DS_OK; 00832 } 00833 00834 static HRESULT WINAPI IDirectSound3DListenerImpl_GetOrientation( 00835 LPDIRECTSOUND3DLISTENER iface, 00836 LPD3DVECTOR lpvOrientFront, 00837 LPD3DVECTOR lpvOrientTop) 00838 { 00839 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00840 TRACE("returning: OrientFront vector = (%f,%f,%f); OrientTop vector = (%f,%f,%f)\n", This->device->ds3dl.vOrientFront.x, 00841 This->device->ds3dl.vOrientFront.y, This->device->ds3dl.vOrientFront.z, This->device->ds3dl.vOrientTop.x, This->device->ds3dl.vOrientTop.y, 00842 This->device->ds3dl.vOrientTop.z); 00843 *lpvOrientFront = This->device->ds3dl.vOrientFront; 00844 *lpvOrientTop = This->device->ds3dl.vOrientTop; 00845 return DS_OK; 00846 } 00847 00848 static HRESULT WINAPI IDirectSound3DListenerImpl_GetPosition( 00849 LPDIRECTSOUND3DLISTENER iface, 00850 LPD3DVECTOR lpvPosition) 00851 { 00852 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00853 TRACE("returning: Position vector = (%f,%f,%f)\n", This->device->ds3dl.vPosition.x, This->device->ds3dl.vPosition.y, This->device->ds3dl.vPosition.z); 00854 *lpvPosition = This->device->ds3dl.vPosition; 00855 return DS_OK; 00856 } 00857 00858 static HRESULT WINAPI IDirectSound3DListenerImpl_GetRolloffFactor( 00859 LPDIRECTSOUND3DLISTENER iface, 00860 LPD3DVALUE lpfRolloffFactor) 00861 { 00862 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00863 TRACE("returning: RolloffFactor = %f\n", This->device->ds3dl.flRolloffFactor); 00864 *lpfRolloffFactor = This->device->ds3dl.flRolloffFactor; 00865 return DS_OK; 00866 } 00867 00868 static HRESULT WINAPI IDirectSound3DListenerImpl_GetVelocity( 00869 LPDIRECTSOUND3DLISTENER iface, 00870 LPD3DVECTOR lpvVelocity) 00871 { 00872 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00873 TRACE("returning: Velocity vector = (%f,%f,%f)\n", This->device->ds3dl.vVelocity.x, This->device->ds3dl.vVelocity.y, This->device->ds3dl.vVelocity.z); 00874 *lpvVelocity = This->device->ds3dl.vVelocity; 00875 return DS_OK; 00876 } 00877 00878 static HRESULT WINAPI IDirectSound3DListenerImpl_SetAllParameters( 00879 LPDIRECTSOUND3DLISTENER iface, 00880 LPCDS3DLISTENER lpcDS3DL, 00881 DWORD dwApply) 00882 { 00883 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00884 TRACE("setting: all parameters; dwApply = %d\n", dwApply); 00885 This->device->ds3dl = *lpcDS3DL; 00886 if (dwApply == DS3D_IMMEDIATE) 00887 { 00888 This->device->ds3dl_need_recalc = FALSE; 00889 DSOUND_ChangeListener(This); 00890 } 00891 This->device->ds3dl_need_recalc = TRUE; 00892 return DS_OK; 00893 } 00894 00895 static HRESULT WINAPI IDirectSound3DListenerImpl_SetDistanceFactor( 00896 LPDIRECTSOUND3DLISTENER iface, 00897 D3DVALUE fDistanceFactor, 00898 DWORD dwApply) 00899 { 00900 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00901 TRACE("setting: Distance Factor = %f; dwApply = %d\n", fDistanceFactor, dwApply); 00902 This->device->ds3dl.flDistanceFactor = fDistanceFactor; 00903 if (dwApply == DS3D_IMMEDIATE) 00904 { 00905 This->device->ds3dl_need_recalc = FALSE; 00906 DSOUND_ChangeListener(This); 00907 } 00908 This->device->ds3dl_need_recalc = TRUE; 00909 return DS_OK; 00910 } 00911 00912 static HRESULT WINAPI IDirectSound3DListenerImpl_SetDopplerFactor( 00913 LPDIRECTSOUND3DLISTENER iface, 00914 D3DVALUE fDopplerFactor, 00915 DWORD dwApply) 00916 { 00917 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00918 TRACE("setting: Doppler Factor = %f; dwApply = %d\n", fDopplerFactor, dwApply); 00919 This->device->ds3dl.flDopplerFactor = fDopplerFactor; 00920 if (dwApply == DS3D_IMMEDIATE) 00921 { 00922 This->device->ds3dl_need_recalc = FALSE; 00923 DSOUND_ChangeListener(This); 00924 } 00925 This->device->ds3dl_need_recalc = TRUE; 00926 return DS_OK; 00927 } 00928 00929 static HRESULT WINAPI IDirectSound3DListenerImpl_SetOrientation( 00930 LPDIRECTSOUND3DLISTENER iface, 00931 D3DVALUE xFront, D3DVALUE yFront, D3DVALUE zFront, 00932 D3DVALUE xTop, D3DVALUE yTop, D3DVALUE zTop, 00933 DWORD dwApply) 00934 { 00935 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00936 TRACE("setting: Front vector = (%f,%f,%f); Top vector = (%f,%f,%f); dwApply = %d\n", 00937 xFront, yFront, zFront, xTop, yTop, zTop, dwApply); 00938 This->device->ds3dl.vOrientFront.x = xFront; 00939 This->device->ds3dl.vOrientFront.y = yFront; 00940 This->device->ds3dl.vOrientFront.z = zFront; 00941 This->device->ds3dl.vOrientTop.x = xTop; 00942 This->device->ds3dl.vOrientTop.y = yTop; 00943 This->device->ds3dl.vOrientTop.z = zTop; 00944 if (dwApply == DS3D_IMMEDIATE) 00945 { 00946 This->device->ds3dl_need_recalc = FALSE; 00947 DSOUND_ChangeListener(This); 00948 } 00949 This->device->ds3dl_need_recalc = TRUE; 00950 return DS_OK; 00951 } 00952 00953 static HRESULT WINAPI IDirectSound3DListenerImpl_SetPosition( 00954 LPDIRECTSOUND3DLISTENER iface, 00955 D3DVALUE x, D3DVALUE y, D3DVALUE z, 00956 DWORD dwApply) 00957 { 00958 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00959 TRACE("setting: Position vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply); 00960 This->device->ds3dl.vPosition.x = x; 00961 This->device->ds3dl.vPosition.y = y; 00962 This->device->ds3dl.vPosition.z = z; 00963 if (dwApply == DS3D_IMMEDIATE) 00964 { 00965 This->device->ds3dl_need_recalc = FALSE; 00966 DSOUND_ChangeListener(This); 00967 } 00968 This->device->ds3dl_need_recalc = TRUE; 00969 return DS_OK; 00970 } 00971 00972 static HRESULT WINAPI IDirectSound3DListenerImpl_SetRolloffFactor( 00973 LPDIRECTSOUND3DLISTENER iface, 00974 D3DVALUE fRolloffFactor, 00975 DWORD dwApply) 00976 { 00977 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00978 TRACE("setting: Rolloff Factor = %f; dwApply = %d\n", fRolloffFactor, dwApply); 00979 This->device->ds3dl.flRolloffFactor = fRolloffFactor; 00980 if (dwApply == DS3D_IMMEDIATE) 00981 { 00982 This->device->ds3dl_need_recalc = FALSE; 00983 DSOUND_ChangeListener(This); 00984 } 00985 This->device->ds3dl_need_recalc = TRUE; 00986 return DS_OK; 00987 } 00988 00989 static HRESULT WINAPI IDirectSound3DListenerImpl_SetVelocity( 00990 LPDIRECTSOUND3DLISTENER iface, 00991 D3DVALUE x, D3DVALUE y, D3DVALUE z, 00992 DWORD dwApply) 00993 { 00994 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 00995 TRACE("setting: Velocity vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply); 00996 This->device->ds3dl.vVelocity.x = x; 00997 This->device->ds3dl.vVelocity.y = y; 00998 This->device->ds3dl.vVelocity.z = z; 00999 if (dwApply == DS3D_IMMEDIATE) 01000 { 01001 This->device->ds3dl_need_recalc = FALSE; 01002 DSOUND_ChangeListener(This); 01003 } 01004 This->device->ds3dl_need_recalc = TRUE; 01005 return DS_OK; 01006 } 01007 01008 static HRESULT WINAPI IDirectSound3DListenerImpl_CommitDeferredSettings( 01009 LPDIRECTSOUND3DLISTENER iface) 01010 { 01011 IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; 01012 TRACE("\n"); 01013 DSOUND_ChangeListener(This); 01014 return DS_OK; 01015 } 01016 01017 static const IDirectSound3DListenerVtbl ds3dlvt = 01018 { 01019 /* IUnknown methods */ 01020 IDirectSound3DListenerImpl_QueryInterface, 01021 IDirectSound3DListenerImpl_AddRef, 01022 IDirectSound3DListenerImpl_Release, 01023 /* IDirectSound3DListener methods */ 01024 IDirectSound3DListenerImpl_GetAllParameter, 01025 IDirectSound3DListenerImpl_GetDistanceFactor, 01026 IDirectSound3DListenerImpl_GetDopplerFactor, 01027 IDirectSound3DListenerImpl_GetOrientation, 01028 IDirectSound3DListenerImpl_GetPosition, 01029 IDirectSound3DListenerImpl_GetRolloffFactor, 01030 IDirectSound3DListenerImpl_GetVelocity, 01031 IDirectSound3DListenerImpl_SetAllParameters, 01032 IDirectSound3DListenerImpl_SetDistanceFactor, 01033 IDirectSound3DListenerImpl_SetDopplerFactor, 01034 IDirectSound3DListenerImpl_SetOrientation, 01035 IDirectSound3DListenerImpl_SetPosition, 01036 IDirectSound3DListenerImpl_SetRolloffFactor, 01037 IDirectSound3DListenerImpl_SetVelocity, 01038 IDirectSound3DListenerImpl_CommitDeferredSettings, 01039 }; 01040 01041 HRESULT IDirectSound3DListenerImpl_Create( 01042 DirectSoundDevice * device, 01043 IDirectSound3DListenerImpl ** ppdsl) 01044 { 01045 IDirectSound3DListenerImpl *pdsl; 01046 TRACE("(%p,%p)\n",device,ppdsl); 01047 01048 pdsl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*pdsl)); 01049 01050 if (pdsl == NULL) { 01051 WARN("out of memory\n"); 01052 *ppdsl = 0; 01053 return DSERR_OUTOFMEMORY; 01054 } 01055 01056 pdsl->ref = 0; 01057 pdsl->lpVtbl = &ds3dlvt; 01058 01059 pdsl->device = device; 01060 01061 pdsl->device->ds3dl.dwSize = sizeof(DS3DLISTENER); 01062 pdsl->device->ds3dl.vPosition.x = 0.0; 01063 pdsl->device->ds3dl.vPosition.y = 0.0; 01064 pdsl->device->ds3dl.vPosition.z = 0.0; 01065 pdsl->device->ds3dl.vVelocity.x = 0.0; 01066 pdsl->device->ds3dl.vVelocity.y = 0.0; 01067 pdsl->device->ds3dl.vVelocity.z = 0.0; 01068 pdsl->device->ds3dl.vOrientFront.x = 0.0; 01069 pdsl->device->ds3dl.vOrientFront.y = 0.0; 01070 pdsl->device->ds3dl.vOrientFront.z = 1.0; 01071 pdsl->device->ds3dl.vOrientTop.x = 0.0; 01072 pdsl->device->ds3dl.vOrientTop.y = 1.0; 01073 pdsl->device->ds3dl.vOrientTop.z = 0.0; 01074 pdsl->device->ds3dl.flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR; 01075 pdsl->device->ds3dl.flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR; 01076 pdsl->device->ds3dl.flDopplerFactor = DS3D_DEFAULTDOPPLERFACTOR; 01077 01078 pdsl->device->ds3dl_need_recalc = TRUE; 01079 01080 *ppdsl = pdsl; 01081 return S_OK; 01082 } Generated on Sun May 27 2012 04:21:42 for ReactOS by
1.7.6.1
|