ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

sound3d.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.