Ignore:
Timestamp:
Mar 13, 2000, 1:47:54 PM (25 years ago)
Author:
sandervl
Message:

replaced dsound by new version

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/dsound/OS2SNDBUFFER.CPP

    r2637 r3099  
    1 /* $Id: OS2SNDBUFFER.CPP,v 1.6 2000-02-04 19:29:16 hugh Exp $ */
     1/* $Id: OS2SNDBUFFER.CPP,v 1.7 2000-03-13 12:47:48 sandervl Exp $ */
    22
    33/*
     
    55 *
    66 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
     7 * Copyright 2000 Michal Necasek
    78 *
    89 * Project Odin Software License can be found in LICENSE.TXT
     
    1617#define INCL_DOSMISC
    1718#include <os2win.h>
     19
    1820#include <stdlib.h>
    1921#include <string.h>
     
    2224#include <dsound.h>
    2325
    24 #include "os2dsound.h"
    25 #include "os2sndbuffer.h"
     26#include "OS2DSound.h"
     27#include "OS2SndBuffer.h"
     28#include "OS2PrimBuff.h"
     29#include "OS23DListener.h"
     30#include "OS23DBuffer.h"
     31#include "OS2Notify.h"
    2632#include <misc.h>
    2733
    28 
    29 extern DWORD GetTickCountOS2();
     34#include "DSVolume.h"
    3035
    3136WAVEFORMATEX wfxDefaultPrimaryBuf = { WAVE_FORMAT_PCM,
     
    3742                                      0};
    3843
    39 //******************************************************************************
    40 //******************************************************************************
    41 OS2IDirectSoundBuffer::OS2IDirectSoundBuffer(const DSBUFFERDESC *lpDSBufferDesc) //KSO Apr 13 1999: const, SDK changes
     44OS2IDirectSoundBuffer *OS2IDirectSoundBuffer::dsbroot = NULL;
     45OS2IDirectSoundBuffer *OS2IDirectSoundBuffer::primary = NULL;
     46
     47//******************************************************************************
     48//******************************************************************************
     49OS2IDirectSoundBuffer::OS2IDirectSoundBuffer(OS2IDirectSound *DSound, const DSBUFFERDESC *lpDSBufferDesc)
    4250        : Referenced(0), lastError(DS_OK)
    4351{
    44   lpVtbl = &Vtbl;
    45   Vtbl.AddRef               = SoundBufAddRef;
    46   Vtbl.Release              = SoundBufRelease;
    47   Vtbl.QueryInterface       = SoundBufQueryInterface;
    48   Vtbl.GetCaps              = SoundBufGetCaps;
    49   Vtbl.GetFormat            = SoundBufGetFormat;
    50   Vtbl.GetVolume            = SoundBufGetVolume;
    51   Vtbl.GetStatus            = SoundBufGetStatus;
    52   Vtbl.GetCurrentPosition   = SoundBufGetCurrentPosition;
    53   Vtbl.GetPan               = SoundBufGetPan;
    54   Vtbl.Initialize           = SoundBufInitialize;
    55   Vtbl.Restore              = SoundBufRestore;
    56   Vtbl.SetFormat            = SoundBufSetFormat;
    57   Vtbl.SetVolume            = SoundBufSetVolume;
    58   Vtbl.SetCurrentPosition   = SoundBufSetCurrentPosition;
    59   Vtbl.SetPan               = SoundBufSetPan;
    60   Vtbl.Lock                 = SoundBufLock;
    61   Vtbl.Unlock               = SoundBufUnlock;
    62   Vtbl.Stop                 = SoundBufStop;
    63   Vtbl.Play                 = SoundBufPlay;
    64 
    65   pan       = 0;
    66   writepos  = 0;
    67   playpos   = 0;
    68   frequency = 22050;
    69   status    = 0;;
    70   fLocked   = FALSE;
    71   volume    = 0;
    72   lpfxFormat= NULL;
    73   lpBuffer  = NULL;
    74   fPlaying  = FALSE;
    75   fLoop     = FALSE;
    76   newWritePos = 0;
    77   LastTickCnt = 0;
    78   memcpy(&bufferdesc, lpDSBufferDesc, sizeof(DSBUFFERDESC));
    79 
    80   if(bufferdesc.dwFlags & DSBCAPS_PRIMARYBUFFER)
    81   {
    82     // Primary Buffer
    83     // Fake this for now and setup the default values for it
    84     //todo: Do the primary buffer right
    85     bufferdesc.dwBufferBytes = 4096;
    86     bufferdesc.lpwfxFormat = &wfxDefaultPrimaryBuf;
    87 
    88   }
    89 
    90   if(bufferdesc.lpwfxFormat == NULL || bufferdesc.dwBufferBytes == 0)
    91   {
     52   lpVtbl = &Vtbl;
     53   Vtbl.AddRef               = SoundBufAddRef;
     54   Vtbl.Release              = SoundBufRelease;
     55   Vtbl.QueryInterface       = SoundBufQueryInterface;
     56   Vtbl.GetCaps              = SoundBufGetCaps;
     57   Vtbl.GetFormat            = SoundBufGetFormat;
     58   Vtbl.GetVolume            = SoundBufGetVolume;
     59   Vtbl.GetStatus            = SoundBufGetStatus;
     60   Vtbl.GetCurrentPosition   = SoundBufGetCurrentPosition;
     61   Vtbl.GetPan               = SoundBufGetPan;
     62   Vtbl.GetFrequency         = SoundBufGetFrequency;
     63   Vtbl.Initialize           = SoundBufInitialize;
     64   Vtbl.Restore              = SoundBufRestore;
     65   Vtbl.SetFormat            = SoundBufSetFormat;
     66   Vtbl.SetVolume            = SoundBufSetVolume;
     67   Vtbl.SetCurrentPosition   = SoundBufSetCurrentPosition;
     68   Vtbl.SetPan               = SoundBufSetPan;
     69   Vtbl.SetFrequency         = SoundBufSetFrequency;
     70   Vtbl.Lock                 = SoundBufLock;
     71   Vtbl.Unlock               = SoundBufUnlock;
     72   Vtbl.Stop                 = SoundBufStop;
     73   Vtbl.Play                 = SoundBufPlay;
     74
     75   dprintf(("DSOUND-OS2IDirectSoundBuffer::OS2IDirectSoundBuffer (buf=%X)", this));
     76
     77   // If the primary SoundBuffer doesn't exist by now, we have to create it!
     78   if (primary == NULL) {
     79      OS2PrimBuff *primbuff;
     80      primbuff = new OS2PrimBuff(DSound, lpDSBufferDesc);
     81
     82      if (primary == NULL) {
     83         lastError = DSERR_OUTOFMEMORY;
     84         return;
     85      }
     86   }
     87   // Add a reference to the primary buffer for _every_ secondary buffer; this makes
     88   // sure that as long as a secondary buffer exists the primary buffer won't get
     89   // destroyed; moreover if the user didn't create  a primary buffer himself/herself,
     90   // it will automatically get created and destroyed with the last secondary buffer
     91   primary->Vtbl.AddRef(primary);
     92
     93   // Start playing the primary buffer
     94   // TODO: only start playing the primary buffer when necessary!
     95   OS2IDirectSoundBuffer::primary->Vtbl.Play(OS2IDirectSoundBuffer::primary, 0, 0, DSBPLAY_LOOPING);
     96
     97   parentDS  = DSound;
     98   writepos  = 0;
     99   playpos   = 0;
     100   status    = 0;
     101   fLocked   = FALSE;
     102   fPrimary  = FALSE;
     103   volume    = 255;
     104   DSvolume  = 0;
     105   pan       = 0;
     106   DSpan     = 0;
     107   lpfxFormat= NULL;
     108   lpBuffer  = NULL;
     109   fPlaying  = FALSE;
     110   fLoop     = FALSE;
     111   notify    = NULL;
     112   memcpy(&bufferdesc, lpDSBufferDesc, sizeof(DSBUFFERDESC));
     113
     114   // Note: this cannot be a primary buffer - those take a different route
     115
     116   // frequency has to be set according to the bufer format
     117   frequency = bufferdesc.lpwfxFormat->nSamplesPerSec;
     118
     119   if (bufferdesc.lpwfxFormat == NULL || bufferdesc.dwBufferBytes == 0) {
    92120      dprintf(("bufferdesc not valid!"));
    93121      lastError = DSERR_INVALIDPARAM;
    94122      return;
    95   }
    96 
    97   lpfxFormat = (WAVEFORMATEX *)malloc(bufferdesc.lpwfxFormat->cbSize + sizeof(WAVEFORMATEX));
    98   memcpy( lpfxFormat,
     123   }
     124
     125   // Some apps pass trash in cbSize, can't rely on that!
     126   lpfxFormat = (WAVEFORMATEX *)malloc(/*bufferdesc.lpwfxFormat->cbSize +*/ sizeof(WAVEFORMATEX));
     127   memcpy(lpfxFormat,
    99128          bufferdesc.lpwfxFormat,
    100           bufferdesc.lpwfxFormat->cbSize + sizeof(WAVEFORMATEX));
    101 
    102   bufferdesc.lpwfxFormat = lpfxFormat;
    103 
    104   lpBuffer = (LPSTR)VirtualAlloc( 0, bufferdesc.dwBufferBytes, MEM_COMMIT, PAGE_READWRITE);
    105   if(lpBuffer == NULL)
    106   {
     129          /*bufferdesc.lpwfxFormat->cbSize + */sizeof(WAVEFORMATEX));
     130
     131   dprintf((" Buffer format: %dHz, %dbit, %d channels", lpfxFormat->nSamplesPerSec, lpfxFormat->wBitsPerSample, lpfxFormat->nChannels));
     132
     133   lpBuffer = (LPSTR)VirtualAlloc(0, bufferdesc.dwBufferBytes, MEM_COMMIT, PAGE_READWRITE);
     134   if (lpBuffer == NULL) {
    107135      dprintf(("VirtualAlloc failed"));
    108136      lpBuffer  = NULL;
    109137      lastError = DSERR_OUTOFMEMORY;
    110138      return;
    111   }
    112 
    113 }
     139   }
     140
     141   next = dsbroot;
     142   dsbroot = this;
     143}
     144
    114145//******************************************************************************
    115146//******************************************************************************
    116147OS2IDirectSoundBuffer::~OS2IDirectSoundBuffer()
    117148{
    118   if(lpBuffer)
    119     VirtualFree(lpBuffer, 0, MEM_RELEASE);
    120   if(lpfxFormat)
    121     free(lpfxFormat);
    122 
    123 }
     149   /* We must not run this destructor on the primary buffer! */
     150   if (fPrimary)
     151      return;
     152
     153   dprintf(("DSOUND-OS2IDirectSoundBuffer::~OS2IDirectSoundBuffer (buf=%X)", this));
     154
     155   // free allocted memory
     156   if (lpBuffer)
     157      VirtualFree(lpBuffer, 0, MEM_RELEASE);
     158
     159   if (lpfxFormat)
     160      free(lpfxFormat);
     161
     162   // remove ourselves from the linked list
     163   OS2IDirectSoundBuffer *cur  = dsbroot;
     164   OS2IDirectSoundBuffer *prev = NULL;
     165
     166   // release the primary buffer too
     167   primary->Vtbl.Release(primary);
     168
     169   if (this == dsbroot)  // is this the first SoundBuffer?
     170      dsbroot = next;
     171   else {                // walk the chain
     172      while (cur->next != this)
     173         cur  = cur->next;
     174
     175      cur->next = next;
     176   }
     177
     178}
     179
     180//******************************************************************************
     181//******************************************************************************
     182void OS2IDirectSoundBuffer::DestroyAllBuffers()
     183{
     184   dprintf(("DSOUND-OS2IDirectSoundBuffer::DestroyAllBuffers"));
     185
     186   // if any SoundBuffers still exist when the OS2IDirectSound object is
     187   // being closed, just kill them all
     188   OS2IDirectSoundBuffer *cur  = dsbroot;
     189   OS2IDirectSoundBuffer *tmp;
     190
     191   if (primary != NULL)
     192      primary->Vtbl.Stop(primary);
     193
     194   while (cur != NULL) {
     195      tmp = cur->next;
     196      delete cur;
     197      cur = tmp;
     198   }
     199   dprintf(("DSOUND-OS2IDirectSoundBuffer::DestroyAllBuffers - %X", primary));
     200   if (primary != NULL)
     201      primary->Vtbl.Release(primary);
     202}
     203
    124204//******************************************************************************
    125205//******************************************************************************
    126206HRESULT WIN32API SoundBufQueryInterface(THIS, REFIID riid, LPVOID * ppvObj)
    127207{
    128   dprintf(("OS2IDirectSoundBuffer::QueryInterface\n"));
    129   if(This == NULL)
    130   {
    131     return DSERR_INVALIDPARAM;
    132   }
    133   *ppvObj = NULL;
    134 
    135   if(!IsEqualGUID(riid, IID_IDirectSoundBuffer))
    136     return E_NOINTERFACE;
    137 
    138   *ppvObj = This;
    139 
    140   SoundBufAddRef(This);
    141   return(DS_OK);
     208   dprintf(("DSOUND-OS2IDirectSoundBuffer::QueryInterface"));
     209   if (This == NULL) {
     210      return DSERR_INVALIDPARAM;
     211   }
     212   *ppvObj = NULL;
     213
     214   if (IsEqualGUID(riid, IID_IDirectSoundBuffer)) {
     215      *ppvObj = This;
     216
     217      SoundBufAddRef(This);
     218      return DS_OK;
     219   }
     220
     221   if (IsEqualGUID(riid, IID_IDirectSoundNotify)) {
     222      OS2IDirectSoundBuffer  *me     = (OS2IDirectSoundBuffer *)This;
     223      OS2IDirectSoundNotify  *notify;
     224
     225      notify     = new OS2IDirectSoundNotify(me);
     226      *ppvObj    = notify;
     227      notify->Vtbl.AddRef(notify);
     228      return DS_OK;
     229   }
     230
     231   if (IsEqualGUID(riid, IID_IDirectSound3DBuffer)) {
     232      OS2IDirectSoundBuffer   *me     = (OS2IDirectSoundBuffer *)This;
     233      OS2IDirectSound3DBuffer *buffer3D;
     234
     235      buffer3D   = new OS2IDirectSound3DBuffer(me);
     236      *ppvObj    = buffer3D;
     237      buffer3D->Vtbl.AddRef((IDirectSound3DBuffer *)buffer3D);
     238      return DS_OK;
     239   }
     240
     241   return E_NOINTERFACE;
    142242}
    143243//******************************************************************************
     
    145245ULONG WIN32API SoundBufAddRef(THIS)
    146246{
    147  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    148 
    149   dprintf(("OS2IDirectSoundBuffer::AddRef %d\n", me->Referenced+1));
    150   if(me == NULL)
    151   {
    152     return 0;
    153   }
    154   return ++me->Referenced;
     247   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     248
     249   dprintf(("DSOUND-OS2IDirectSoundBuffer::AddRef (buf=%X) %d", me, me->Referenced+1));
     250   if (me == NULL) {
     251      return 0;
     252   }
     253   return ++me->Referenced;
    155254}
    156255//******************************************************************************
     
    158257ULONG WIN32API SoundBufRelease(THIS)
    159258{
    160  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    161 
    162   dprintf(("OS2IDirectSoundBuffer::Release %d\n", me->Referenced-1));
    163   if(me == NULL)
    164   {
    165     return 0;
    166   }
    167   if(me->Referenced)
    168   {
    169     me->Referenced--;
    170     if(me->Referenced == 0)
    171     {
    172       delete me;
    173       return(0);
    174     }
    175     else
    176       return me->Referenced;
    177   }
    178   else
    179     return(0);
     259   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     260
     261   dprintf(("DSOUND-OS2IDirectSoundBuffer::Release (buf=%X) %d", me, me->Referenced-1));
     262   if (me == NULL) {
     263      return 0;
     264   }
     265   if (me->Referenced) {
     266      me->Referenced--;
     267      if (me->Referenced == 0) {
     268         delete me;
     269         return 0;
     270      }
     271      else
     272         return me->Referenced;
     273   }
     274   else
     275      return 0;
    180276}
    181277//******************************************************************************
     
    183279HRESULT __stdcall SoundBufGetCaps(THIS_ LPDSBCAPS lpDSCaps)
    184280{
    185  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    186 
    187   dprintf(("OS2IDirectSoundBuffer::SoundBufGetCaps"));
    188   if(me == NULL || lpDSCaps == NULL)
    189   {
    190     return DSERR_INVALIDPARAM;
    191   }
    192   return DS_OK;
     281   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     282
     283   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetCaps (buf=%X)", me));
     284   if (me == NULL || lpDSCaps == NULL) {
     285      return DSERR_INVALIDPARAM;
     286   }
     287   /* FIXME: fill with more realistic values */
     288   lpDSCaps->dwSize               = sizeof(DSBCAPS);
     289   lpDSCaps->dwFlags              = me->bufferdesc.dwFlags | DSBCAPS_LOCSOFTWARE;
     290   lpDSCaps->dwBufferBytes        = me->bufferdesc.dwBufferBytes;
     291   lpDSCaps->dwUnlockTransferRate = 0;     /* in KB/sec - 0 == no transfer needed */
     292   lpDSCaps->dwPlayCpuOverhead    = 0;     /* % CPU time - let's lie */
     293
     294   return DS_OK;
    193295}
    194296//******************************************************************************
     
    197299                         LPDWORD lpdwCurrentWriteCursor)
    198300{
    199  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    200 
    201   dprintf(("OS2IDirectSoundBuffer::SoundBufGetCurrentPosition"));
    202   if( me == NULL || lpdwCurrentPlayCursor == NULL || lpdwCurrentWriteCursor == NULL)
    203   {
    204     dprintf(("  Invalid parameters %d %d %d",me,lpdwCurrentPlayCursor,lpdwCurrentWriteCursor));
    205     return DSERR_INVALIDPARAM;
    206   }
    207 
    208   // Simply advance the bufferpointer according to time;
    209   if(me->fPlaying)
    210   {
    211     ULONG CurrentTicks, Ticks, NewPos;
    212     CurrentTicks = GetTickCountOS2();
    213     Ticks = CurrentTicks-me->LastTickCnt;
    214     dprintf(("  Is Playing, Ticks: Last %d Current %d Difference %d",me->LastTickCnt, CurrentTicks,Ticks));
    215     dprintf(("  Frequency: %d Bits per Sample %d",me->frequency,me->lpfxFormat->wBitsPerSample));
    216 
    217     NewPos = ((me->frequency*Ticks)/1000)*(me->lpfxFormat->wBitsPerSample/8);
    218     dprintf(("  advance pos by %d bytes",NewPos));
    219 
    220     if(NewPos)
    221       me->LastTickCnt = CurrentTicks;
    222 
    223     if(me->playpos+NewPos >= me->bufferdesc.dwBufferBytes)
    224     {
    225       if(me->fLoop)
    226       {
    227         me->playpos = (me->playpos+NewPos) % me->bufferdesc.dwBufferBytes;
    228       }
    229       else
    230       {
    231         me->playpos  = me->bufferdesc.dwBufferBytes;
    232         me->fPlaying = FALSE;
    233       }
    234 
    235     }
    236     else
    237     {
    238       me->playpos += NewPos;
    239     }
    240     me->writepos = me->playpos + 2048;
    241     if(me->writepos >= me->bufferdesc.dwBufferBytes)
    242       me->writepos = me->writepos % me->bufferdesc.dwBufferBytes;
    243     dprintf(("  new Pos Write: %d   Play: %d",me->writepos,me->playpos));
    244   }
    245   else
    246   {
    247     dprintf(("  Buffer Not playing"));
    248   }
    249   dprintf(("  Buffer %d: PlayPos %d, WritePos %d\n",me, me->playpos,me->writepos));
    250   *lpdwCurrentPlayCursor  = me->playpos;
    251   *lpdwCurrentWriteCursor = me->writepos;
    252   return DS_OK;
     301   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     302
     303   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetCurrentPosition (buf=%X)", me));
     304   if ( me == NULL || lpdwCurrentPlayCursor == NULL || lpdwCurrentWriteCursor == NULL) {
     305     dprintf(("  Invalid parameters %d %d %d",me,lpdwCurrentPlayCursor,lpdwCurrentWriteCursor));
     306     return DSERR_INVALIDPARAM;
     307   }
     308
     309   dprintf(("  PlayPos %d, WritePos %d", me->playpos, me->writepos));
     310   *lpdwCurrentPlayCursor  = me->playpos;
     311   *lpdwCurrentWriteCursor = me->writepos;
     312   return DS_OK;
    253313}
    254314//******************************************************************************
     
    257317                    DWORD ddwSizeAllocated, LPDWORD lpdwSizeWritten)
    258318{
    259  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    260  int copysize;
    261 
    262   dprintf(("OS2IDirectSoundBuffer::SoundBufGetFormat"));
    263   if( me == NULL || lpwfxFormat == NULL || ddwSizeAllocated == 0)
    264   {
    265     return DSERR_INVALIDPARAM;
    266   }
    267   copysize = min(ddwSizeAllocated, (me->lpfxFormat->cbSize + sizeof(WAVEFORMATEX)));
    268   memcpy(lpwfxFormat, me->lpfxFormat, copysize);
    269 
    270   if(lpdwSizeWritten)
    271   {
    272     *lpdwSizeWritten = copysize;
    273   }
    274   return DS_OK;
     319   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     320   int copysize;
     321
     322   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetFormat (buf=%X)", me));
     323   if (me == NULL || lpwfxFormat == NULL || ddwSizeAllocated == 0) {
     324      return DSERR_INVALIDPARAM;
     325   }
     326   copysize = min(ddwSizeAllocated, (me->lpfxFormat->cbSize + sizeof(WAVEFORMATEX)));
     327   memcpy(lpwfxFormat, me->lpfxFormat, copysize);
     328
     329   if (lpdwSizeWritten) {
     330      *lpdwSizeWritten = copysize;
     331   }
     332   return DS_OK;
    275333}
    276334//******************************************************************************
     
    278336HRESULT __stdcall SoundBufGetVolume(THIS_ LPLONG lplVolume)
    279337{
    280  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    281 
    282   dprintf(("OS2IDirectSoundBuffer::SoundBufGetVolume"));
    283   if(me == NULL || lplVolume == NULL)
    284   {
    285     return DSERR_INVALIDPARAM;
    286   }
    287   *lplVolume = me->volume;
    288   return DS_OK;
     338   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     339
     340   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetVolume (buf=%X)", me));
     341   if (me == NULL || lplVolume == NULL) {
     342      return DSERR_INVALIDPARAM;
     343   }
     344   *lplVolume = me->DSvolume;
     345   return DS_OK;
    289346}
    290347//******************************************************************************
     
    292349HRESULT __stdcall SoundBufGetPan(THIS_ LPLONG lplPan)
    293350{
    294  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    295 
    296   dprintf(("OS2IDirectSoundBuffer::SoundBufGetPan"));
    297   if(me == NULL || lplPan == NULL)
    298   {
    299     return DSERR_INVALIDPARAM;
    300   }
    301   *lplPan = me->pan;
    302   return DS_OK;
     351   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     352
     353   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetPan (buf=%X)", me));
     354   if (me == NULL || lplPan == NULL) {
     355      return DSERR_INVALIDPARAM;
     356   }
     357   *lplPan = me->DSpan;
     358   return DS_OK;
    303359}
    304360//******************************************************************************
     
    306362HRESULT __stdcall SoundBufGetFrequency(THIS_ LPDWORD lpdwFrequency)
    307363{
    308  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    309 
    310   dprintf(("OS2IDirectSoundBuffer::SoundBufGetFrequency"));
    311   if(me == NULL || lpdwFrequency == NULL)
    312   {
    313     return DSERR_INVALIDPARAM;
    314   }
    315   *lpdwFrequency = me->frequency;
    316   return DS_OK;
     364   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     365
     366   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetFrequency (buf=%X)", me));
     367   if (me == NULL || lpdwFrequency == NULL) {
     368      return DSERR_INVALIDPARAM;
     369   }
     370   *lpdwFrequency = me->frequency;
     371   return DS_OK;
    317372}
    318373//******************************************************************************
     
    320375HRESULT __stdcall SoundBufGetStatus(THIS_ LPDWORD lpdwStatus)
    321376{
    322  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    323 
    324   dprintf(("OS2IDirectSoundBuffer::SoundBufGetStatus"));
    325   if(me == NULL || lpdwStatus == NULL)
    326   {
    327     return DSERR_INVALIDPARAM;
    328   }
    329   *lpdwStatus = me->status;
    330   return DS_OK;
     377   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     378
     379   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufGetStatus (buf=%X)", me));
     380   if (me == NULL || lpdwStatus == NULL) {
     381      return DSERR_INVALIDPARAM;
     382   }
     383
     384   if (me->fPlaying)
     385      if (me->fLoop)
     386         me->status |= DSBSTATUS_PLAYING | DSBSTATUS_LOOPING;
     387      else
     388         me->status |= DSBSTATUS_PLAYING;
     389   else
     390      me->status  &= ~(DSBSTATUS_PLAYING | DSBSTATUS_LOOPING);
     391
     392   *lpdwStatus = me->status;
     393   return DS_OK;
    331394}
    332395//******************************************************************************
     
    334397HRESULT __stdcall SoundBufInitialize(THIS_ LPDIRECTSOUND, LPDSBUFFERDESC )
    335398{
    336  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    337 
    338   dprintf(("SoundBufInitialize"));
    339   if(me == NULL)
    340   {
    341     return DSERR_INVALIDPARAM;
    342   }
    343   return DSERR_ALREADYINITIALIZED;  //todo: for future extensions (dx5/6 ??)
     399   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     400
     401   dprintf(("DSOUND-SoundBufInitialize (buf=%X)", me));
     402   if (me == NULL) {
     403      return DSERR_INVALIDPARAM;
     404   }
     405   return DSERR_ALREADYINITIALIZED;  //todo: for future extensions (dx5/6 ??)
    344406}
    345407//******************************************************************************
     
    350412                   DWORD dwFlags)
    351413{
    352  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    353 
    354   dprintf(("OS2IDirectSoundBuffer::SoundBufLock"));
    355   if(me == NULL || !lplpvAudioPtr1 || !lpdwAudioBytes1)
    356   {
    357     return(DSERR_INVALIDPARAM);
    358   }
    359   //not sure if this is an error, but it's certainly a smart thing to do (cond. == true)
    360   if(dwWriteBytes > me->bufferdesc.dwBufferBytes)
    361   {
    362     dprintf(("SoundBufLock: dwWriteBytes > me->bufferdesc.dwBufferBytes"));
    363     return(DSERR_INVALIDPARAM);
    364   }
    365   if(dwFlags & DSBLOCK_FROMWRITECURSOR)
    366   {
    367     dwWriteCursor = me->writepos;
    368   }
    369   dprintf(("  Buffer at 0x%08X Size %d",me->lpBuffer,me->bufferdesc.dwBufferBytes));
    370   if(dwWriteCursor + dwWriteBytes > me->bufferdesc.dwBufferBytes )
    371   {
    372     *(DWORD *)lplpvAudioPtr1  = (DWORD)(me->lpBuffer + dwWriteCursor);
    373     *lpdwAudioBytes1          = me->bufferdesc.dwBufferBytes - dwWriteCursor;
    374     dprintf(("  Lock1 at 0x%08X Size %d",*(DWORD *)lplpvAudioPtr1,*lpdwAudioBytes1));
    375     if(lplpvAudioPtr2 && lpdwAudioBytes2)
    376     {
    377       *(DWORD *)lplpvAudioPtr2   = (DWORD)me->lpBuffer;
    378       *lpdwAudioBytes2           = dwWriteBytes - *lpdwAudioBytes1;
    379       dprintf(("  Lock2 at 0x%08X Size %d",*(DWORD *)lplpvAudioPtr2,*lpdwAudioBytes2));
    380     }
    381   }
    382   else
    383   {
    384     *(DWORD *)lplpvAudioPtr1  = (DWORD)(me->lpBuffer + dwWriteCursor);
    385     *lpdwAudioBytes1          = dwWriteBytes;
    386     dprintf(("  Lock1 at 0x%08X Size %d",*(DWORD *)lplpvAudioPtr1,*lpdwAudioBytes1));
    387     if(lplpvAudioPtr2 && lpdwAudioBytes2)
    388     {
    389       *(DWORD *)lplpvAudioPtr2   = 0;
    390       *lpdwAudioBytes2           = 0;
    391       dprintf(("  Lock2 at 0x%08X Size %d",*(DWORD *)lplpvAudioPtr2,*lpdwAudioBytes2));
    392     }
    393   }
    394   me->fLocked = TRUE;
    395   return DS_OK;
    396 }
    397 //******************************************************************************
    398 //******************************************************************************
    399 HRESULT __stdcall SoundBufPlay(THIS_ DWORD dwRes1,DWORD dwRes2,DWORD dwFlags)
    400 {
    401  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    402 
    403   dprintf(("OS2IDirectSoundBuffer::SoundBufPlay"));
    404   if(me == NULL)
    405   {
    406     dprintf(("  Invalid parms me is NULL\n"));
    407     return DSERR_INVALIDPARAM;
    408   }
    409   me->fPlaying = TRUE;
    410   me->fLoop = dwFlags == DSBPLAY_LOOPING;
    411   me->LastTickCnt = GetTickCountOS2();
    412   dprintf(("  Buffer %d: Start at Tick %d Loop %s",me,me->LastTickCnt,me->fLoop?"YES":"NO"));
    413   return DS_OK;
    414 }
     414   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     415
     416   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufLock (buf=%X, %d bytes of %d)", me, dwWriteBytes, me->bufferdesc.dwBufferBytes));
     417   if (me == NULL || !lplpvAudioPtr1 || !lpdwAudioBytes1)
     418      return DSERR_INVALIDPARAM;
     419
     420   //not sure if this is an error, but it's certainly a smart thing to do (cond. == true)
     421   if(dwWriteBytes > me->bufferdesc.dwBufferBytes) {
     422      dprintf(("SoundBufLock: dwWriteBytes > me->bufferdesc.dwBufferBytes"));
     423      return DSERR_INVALIDPARAM;
     424   }
     425   if (dwFlags & DSBLOCK_FROMWRITECURSOR) {
     426      dwWriteCursor = me->writepos;
     427   }
     428   if (dwWriteCursor + dwWriteBytes > me->bufferdesc.dwBufferBytes) {
     429      *(DWORD *)lplpvAudioPtr1  = (DWORD)(me->lpBuffer + dwWriteCursor);
     430      *lpdwAudioBytes1          = me->bufferdesc.dwBufferBytes - dwWriteCursor;
     431      if (lplpvAudioPtr2 && lpdwAudioBytes2) {
     432         *(DWORD *)lplpvAudioPtr2   = (DWORD)me->lpBuffer;
     433         *lpdwAudioBytes2           = dwWriteBytes - *lpdwAudioBytes1;
     434      }
     435   }
     436   else {
     437      *(DWORD *)lplpvAudioPtr1  = (DWORD)(me->lpBuffer + dwWriteCursor);
     438      *lpdwAudioBytes1          = dwWriteBytes;
     439      if (lplpvAudioPtr2 && lpdwAudioBytes2) {
     440         *(DWORD *)lplpvAudioPtr2   = 0;
     441         *lpdwAudioBytes2           = 0;
     442      }
     443   }
     444
     445   me->fLocked = TRUE;
     446
     447   return DS_OK;
     448}
     449
     450//******************************************************************************
     451//******************************************************************************
     452HRESULT __stdcall SoundBufPlay(THIS_ DWORD dwRes1, DWORD dwRes2, DWORD dwFlags)
     453{
     454   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     455
     456   ULONG ulBytesToPlay;
     457
     458   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufPlay (buf=%X)", me));
     459   if (me == NULL) {
     460      dprintf(("  Invalid parms - me is NULL"));
     461      return DSERR_INVALIDPARAM;
     462   }
     463
     464   if (!me->fPlaying) {
     465      me->frac     = 0;
     466      me->fPlaying = TRUE;
     467      me->status   = DSBSTATUS_PLAYING;
     468      me->fLoop = dwFlags == DSBPLAY_LOOPING;
     469      if (me->fLoop)
     470         me->status |= DSBSTATUS_LOOPING;
     471
     472      dprintf(("  Buffer %X: start at pos %d, loop %s",me, me->playpos, me->fLoop?"YES":"NO"));
     473   }
     474   else {
     475      me->fLoop = dwFlags == DSBPLAY_LOOPING;
     476      if (me->fLoop)
     477         me->status |= DSBSTATUS_LOOPING;
     478
     479      dprintf(("  Buffer %X: already playing, loop %s",me, me->fLoop?"YES":"NO"));
     480   }
     481
     482   return DS_OK;
     483}
     484
    415485//******************************************************************************
    416486//******************************************************************************
    417487HRESULT __stdcall SoundBufSetCurrentPosition(THIS_ DWORD dwNewPosition)
    418488{
    419  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    420 
    421   dprintf(("OS2IDirectSoundBuffer::SoundBufSetCurrentPosition"));
    422   if(me == NULL)
    423   {
    424     return DSERR_INVALIDPARAM;
    425   }
    426   //todo: check for primary buffer (can't do it with those)
    427   me->playpos   = dwNewPosition;
    428   me->writepos  = dwNewPosition;
    429   return DS_OK;
    430 }
    431 //******************************************************************************
    432 //******************************************************************************
    433 HRESULT __stdcall SoundBufSetFormat(THIS_ LPWAVEFORMATEX )
    434 {
    435  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    436 
    437   dprintf(("OS2IDirectSoundBuffer::SoundBufSetFormat"));
    438   if(me == NULL)
    439   {
    440     return DSERR_INVALIDPARAM;
    441   }
    442   return DS_OK;
    443 }
     489   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     490
     491   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufSetCurrentPosition (buf=%X) to %d", me, dwNewPosition));
     492   if (me == NULL) {
     493      return DSERR_INVALIDPARAM;
     494   }
     495   me->playpos   = dwNewPosition;
     496
     497   return DS_OK;
     498}
     499
     500//******************************************************************************
     501//******************************************************************************
     502HRESULT __stdcall SoundBufSetFormat(THIS_ LPWAVEFORMATEX lpWaveFormatEx)
     503{
     504   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     505
     506   // Note: this sets the format of the _primary_ buffer;
     507   // since this class only handles secondary buffers, we just return error
     508   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufSetFormat (buf=%X)", me));
     509
     510   return DSERR_UNSUPPORTED;
     511}
     512
    444513//******************************************************************************
    445514//******************************************************************************
    446515HRESULT __stdcall SoundBufSetVolume(THIS_ LONG lVolume)
    447516{
    448  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    449 
    450   dprintf(("OS2IDirectSoundBuffer::SoundBufSetVolume"));
    451   if(me == NULL)
    452   {
    453     return DSERR_INVALIDPARAM;
    454   }
    455   me->volume = lVolume;
    456   return DS_OK;
     517   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     518
     519   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufSetVolume (%d, buf=%X)", lVolume, me));
     520   if (me == NULL || lVolume < -10000) {
     521      return DSERR_INVALIDPARAM;
     522   }
     523   // some apps pass positive values in lVolume, that's wrong right?!?
     524   me->DSvolume = (lVolume > 0) ? 0 : lVolume;
     525
     526   /* = (10 ^ (1/10)) = 1dB - but the formula below gives results _very_ similar */
     527   /* to 'real' DirectSound, indistinguishable for all practical purposes        */
     528   //me->volume = 255.0 * pow(4, me->DSvolume / 1000.0);
     529
     530   /* Note: for some strange reason the above code sometimes gives erroneous     */
     531   /* results, hence we now use a simple conversion table (in steps of 4/100 dB) */
     532
     533   if (me->DSvolume < -4000)
     534      me->volume = 0;
     535   else
     536      me->volume = VolTable[-me->DSvolume / 4];
     537
     538   dprintf(("  New volume: %d", me->volume));
     539
     540   return DS_OK;
    457541}
    458542//******************************************************************************
     
    460544HRESULT __stdcall SoundBufSetPan(THIS_ LONG lPan)
    461545{
    462  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    463 
    464   dprintf(("OS2IDirectSoundBuffer::SoundBufSetPan"));
    465   if(me == NULL)
    466   {
    467     return DSERR_INVALIDPARAM;
    468   }
    469   me->pan = lPan;
    470   return DS_OK;
    471 }
     546   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     547
     548   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufSetPan (%d, buf=%X)", lPan, me));
     549   if (me == NULL || lPan < -10000 || lPan > 10000) {
     550      return DSERR_INVALIDPARAM;
     551   }
     552   me->DSpan = lPan;
     553   if (lPan == 0) {
     554      me->pan = 0;
     555      return DS_OK;
     556   }
     557
     558   /* Note: we use very similar code as for volume above   */
     559   if (lPan < 0)
     560      if (lPan < -4000)
     561         me->pan = -255;
     562      else
     563         me->pan = VolTable[-lPan / 4] - 255;
     564   else
     565      if (lPan > 4000)
     566         me->pan = 255;
     567      else
     568         me->pan = 255 - VolTable[lPan / 4];
     569
     570   dprintf(("  New pan: %d", me->pan));
     571
     572   return DS_OK;
     573}
     574
    472575//******************************************************************************
    473576//******************************************************************************
    474577HRESULT __stdcall SoundBufSetFrequency(THIS_ DWORD dwFrequency)
    475578{
    476  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    477 
    478   dprintf(("OS2IDirectSoundBuffer::SoundBufSetFrequency"));
    479   if(me == NULL)
    480   {
    481     return DSERR_INVALIDPARAM;
    482   }
    483   me->frequency = dwFrequency;
    484   return DS_OK;
    485 }
     579   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     580
     581   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufSetFrequency (buf=%X)", me));
     582   if (me == NULL) {
     583     return DSERR_INVALIDPARAM;
     584   }
     585
     586   // zero means default (buffer format) frequency
     587   if (dwFrequency)
     588      me->frequency = dwFrequency;
     589   else
     590     me->frequency = me->lpfxFormat->nSamplesPerSec;
     591
     592   return DS_OK;
     593}
     594
    486595//******************************************************************************
    487596//******************************************************************************
    488597HRESULT __stdcall SoundBufStop(THIS  )
    489598{
    490  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    491 
    492   dprintf(("OS2IDirectSoundBuffer::SoundBufStop"));
    493   if(me == NULL)
    494   {
    495     return DSERR_INVALIDPARAM;
    496   }
    497   // Simply advance the bufferpointer according to time;
    498   if(me->fPlaying)
    499   {
    500     ULONG CurrentTicks, Ticks, NewPos;
    501     CurrentTicks = GetTickCountOS2();
    502 
    503     Ticks = CurrentTicks - me->LastTickCnt;
    504     me->LastTickCnt = CurrentTicks;
    505 
    506     NewPos = ((me->frequency*Ticks)/1000)*(me->lpfxFormat->wBitsPerSample>>8);
    507     if(me->playpos+NewPos >= me->bufferdesc.dwBufferBytes)
    508     {
    509       if(me->fLoop)
    510       {
    511         me->playpos = (me->playpos+NewPos % me->bufferdesc.dwBufferBytes);
    512       }
    513       else
    514       {
    515         me->playpos  = me->bufferdesc.dwBufferBytes;
    516         me->fPlaying = FALSE;
    517       }
    518 
    519     }
    520     else
    521     {
    522       me->playpos += NewPos;
    523     }
    524     me->writepos = me->playpos + 2048;
    525     if(me->writepos >= me->bufferdesc.dwBufferBytes)
    526       me->writepos = me->writepos % me->bufferdesc.dwBufferBytes;
    527 
    528     me->fPlaying = FALSE;
    529 
    530   }
    531   return DS_OK;
    532 }
    533 //******************************************************************************
    534 //******************************************************************************
    535 HRESULT __stdcall SoundBufUnlock(THIS_ LPVOID,DWORD,LPVOID,DWORD )
    536 {
    537  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    538 
    539   dprintf(("OS2IDirectSoundBuffer::SoundBufUnlock"));
    540   if(me == NULL)
    541   {
    542     return DSERR_INVALIDPARAM;
    543   }
    544 
    545   return DS_OK;
    546 }
     599   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     600
     601   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufStop (buf=%X)", me));
     602   if (me == NULL) {
     603      return DSERR_INVALIDPARAM;
     604   }
     605
     606   me->fPlaying = FALSE;
     607   me->status  &= ~(DSBSTATUS_PLAYING | DSBSTATUS_LOOPING);
     608
     609   if (me->notify != NULL)
     610      me->notify->CheckStop();
     611
     612   return DS_OK;
     613}
     614
     615//******************************************************************************
     616//******************************************************************************
     617HRESULT __stdcall SoundBufUnlock(THIS_
     618                                 LPVOID lpvAudioPtr1, DWORD dwAudioBytes1,
     619                                 LPVOID lpvAudioPtr2, DWORD dwAudioBytes2)
     620{
     621   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     622
     623   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufUnlock (buf=%X)", me));
     624   if (me == NULL) {
     625      return DSERR_INVALIDPARAM;
     626   }
     627
     628   me->fLocked = TRUE;
     629
     630   return DS_OK;
     631}
     632
    547633//******************************************************************************
    548634//******************************************************************************
    549635HRESULT __stdcall SoundBufRestore(THIS  )
    550636{
    551  OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
    552 
    553   dprintf(("OS2IDirectSoundBuffer::SoundBufRestore"));
    554   if(me == NULL)
    555   {
    556     return DSERR_INVALIDPARAM;
    557   }
    558   return DS_OK;
    559 }
    560 //******************************************************************************
    561 //******************************************************************************
     637   OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
     638
     639   dprintf(("DSOUND-OS2IDirectSoundBuffer::SoundBufRestore (buf=%X)", me));
     640   if (me == NULL) {
     641      return DSERR_INVALIDPARAM;
     642   }
     643   return DS_OK;
     644}
     645//******************************************************************************
     646//******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.