Ignore:
Timestamp:
Apr 30, 2001, 11:06:56 PM (24 years ago)
Author:
sandervl
Message:

DirectAudio interface updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/dsound/DAudioBuffer.cpp

    r5608 r5643  
    1 /* $Id: DAudioBuffer.cpp,v 1.1 2001-04-27 17:39:48 sandervl Exp $ */
     1/* $Id: DAudioBuffer.cpp,v 1.2 2001-04-30 21:06:37 sandervl Exp $ */
    22
    33/*
     
    4040        : Referenced(0), lastError(DS_OK), daudio(NULL), lpSndBuffer(NULL)
    4141{
    42     //This is the "normal" constructor
     42    initVtbl();
     43
     44    dprintf(("DSOUND-IDirectAudioBuffer::IDirectAudioBuffer (buf=%X)", this));
     45
     46    parentDS  = DSound;
     47    writepos  = 0;
     48    playpos   = 0;
     49    status    = 0;
     50    fLocked   = FALSE;
     51    volume    = 255;
     52    DSvolume  = 0;
     53    pan       = 0;
     54    DSpan     = 0;
     55    lpfxFormat= NULL;
     56    fPlaying  = FALSE;
     57    fLoop     = FALSE;
     58    notify    = NULL;
     59    memcpy(&bufferdesc, lpDSBufferDesc, sizeof(DSBUFFERDESC));
     60
     61    // frequency has to be set according to the bufer format
     62    frequency = bufferdesc.lpwfxFormat->nSamplesPerSec;
     63
     64    if (bufferdesc.lpwfxFormat == NULL || bufferdesc.dwBufferBytes == 0) {
     65        dprintf(("bufferdesc not valid!"));
     66        lastError = DSERR_INVALIDPARAM;
     67        return;
     68    }
     69
     70    // Some apps pass trash in cbSize, can't rely on that!
     71    lpfxFormat = (WAVEFORMATEX *)malloc(/*bufferdesc.lpwfxFormat->cbSize +*/ sizeof(WAVEFORMATEX));
     72    memcpy(lpfxFormat, bufferdesc.lpwfxFormat,  /*bufferdesc.lpwfxFormat->cbSize + */sizeof(WAVEFORMATEX));
     73
     74    dprintf((" Buffer format: %dHz, %dbit, %d channels", lpfxFormat->nSamplesPerSec, lpfxFormat->wBitsPerSample, lpfxFormat->nChannels));
     75
     76    lpSndBuffer = (SOUNDBUF *)VirtualAlloc(0, bufferdesc.dwBufferBytes + sizeof(DWORD), MEM_COMMIT, PAGE_READWRITE);
     77    if (lpSndBuffer == NULL) {
     78        dprintf(("VirtualAlloc failed"));
     79        lpSndBuffer  = NULL;
     80        lastError = DSERR_OUTOFMEMORY;
     81        return;
     82    }
     83    lpBuffer = &(lpSndBuffer->pData[0]);
     84    lpSndBuffer->dwReferences = 1;
     85
     86    daudio = new DAudioWaveOut(lpfxFormat);
     87    if(daudio == NULL || daudio->getError()) {
     88        dprintf(("DAudioWaveOut ctor failed"));
     89        lastError = DSERR_OUTOFMEMORY;
     90        return;
     91    }
     92
     93    wmutex.enter(VMUTEX_WAIT_FOREVER);
     94    next = dsbroot;
     95    dsbroot = this;
     96    wmutex.leave();
     97}
     98
     99//******************************************************************************
     100//******************************************************************************
     101IDirectAudioBuffer::IDirectAudioBuffer(OS2IDirectSound *DSound, IDirectAudioBuffer *srcBuf)
     102        : Referenced(0), lastError(DS_OK), daudio(NULL), lpSndBuffer(NULL)
     103{
     104    initVtbl();
     105
     106    dprintf(("DSOUND-IDirectAudioBuffer::OS2IDirectAudioBuffer/Duplicate (buf=%X)", this));
     107
     108    parentDS  = DSound;
     109    writepos  = 0;
     110    playpos   = 0;
     111    status    = 0;
     112    fLocked   = FALSE;
     113    volume    = srcBuf->volume;
     114    DSvolume  = srcBuf->DSvolume;
     115    pan       = srcBuf->pan;
     116    DSpan     = srcBuf->DSpan;
     117    lpBuffer  = srcBuf->lpBuffer;
     118    fPlaying  = FALSE;
     119    fLoop     = srcBuf->fLoop;
     120    notify    = NULL;
     121    memcpy(&bufferdesc, &(srcBuf->bufferdesc), sizeof(DSBUFFERDESC));
     122
     123    // frequency has to be set according to the bufer format
     124    frequency = srcBuf->frequency;
     125
     126    lpfxFormat = (WAVEFORMATEX *)malloc(sizeof(WAVEFORMATEX));
     127    memcpy(lpfxFormat,srcBuf->lpfxFormat, sizeof(WAVEFORMATEX));
     128
     129    dprintf((" Buffer format: %dHz, %dbit, %d channels", lpfxFormat->nSamplesPerSec, lpfxFormat->wBitsPerSample, lpfxFormat->nChannels));
     130
     131    // Increment reference count for the buffer memory
     132    lpSndBuffer  = srcBuf->lpSndBuffer;
     133    lpSndBuffer->dwReferences++;
     134
     135    daudio = new DAudioWaveOut(lpfxFormat);
     136    if(daudio == NULL || daudio->getError()) {
     137        dprintf(("DAudioWaveOut ctor failed"));
     138        lastError = DSERR_OUTOFMEMORY;
     139        return;
     140    }
     141
     142    wmutex.enter(VMUTEX_WAIT_FOREVER);
     143    next = dsbroot;
     144    dsbroot = this;
     145    wmutex.leave();
     146}
     147//******************************************************************************
     148//******************************************************************************
     149IDirectAudioBuffer::~IDirectAudioBuffer()
     150{
     151    dprintf(("DSOUND-IDirectAudioBuffer::~OS2IDirectAudioBuffer (buf=%X)", this));
     152
     153    // free allocted memory - unless it's shared by a duplicated buffer
     154    if (lpSndBuffer) {
     155        lpSndBuffer->dwReferences--;
     156        if (lpSndBuffer->dwReferences == 0)
     157            VirtualFree(lpSndBuffer, 0, MEM_RELEASE);
     158    }
     159
     160    if (lpfxFormat)
     161        free(lpfxFormat);
     162
     163    if(daudio) {
     164        delete daudio;
     165        daudio = 0;
     166    }
     167
     168    // remove ourselves from the linked list
     169    IDirectAudioBuffer *cur  = dsbroot;
     170    IDirectAudioBuffer *prev = NULL;
     171
     172    wmutex.enter(VMUTEX_WAIT_FOREVER);
     173    if (this == dsbroot)  // is this the first DAudioBuffer?
     174        dsbroot = next;
     175    else {                // walk the chain
     176        while (cur->next != this)
     177            cur  = cur->next;
     178
     179        cur->next = next;
     180    }
     181    wmutex.leave();
     182}
     183//******************************************************************************
     184//******************************************************************************
     185void IDirectAudioBuffer::initVtbl()
     186{
    43187    lpVtbl = &Vtbl;
    44188    Vtbl.AddRef               = DAudioBufAddRef;
     
    63207    Vtbl.Stop                 = DAudioBufStop;
    64208    Vtbl.Play                 = DAudioBufPlay;
    65 
    66     dprintf(("DSOUND-IDirectAudioBuffer::IDirectAudioBuffer (buf=%X)", this));
    67 
    68     parentDS  = DSound;
    69     writepos  = 0;
    70     playpos   = 0;
    71     status    = 0;
    72     fLocked   = FALSE;
    73     volume    = 255;
    74     DSvolume  = 0;
    75     pan       = 0;
    76     DSpan     = 0;
    77     lpfxFormat= NULL;
    78     fPlaying  = FALSE;
    79     fLoop     = FALSE;
    80     notify    = NULL;
    81     memcpy(&bufferdesc, lpDSBufferDesc, sizeof(DSBUFFERDESC));
    82 
    83     // frequency has to be set according to the bufer format
    84     frequency = bufferdesc.lpwfxFormat->nSamplesPerSec;
    85 
    86     if (bufferdesc.lpwfxFormat == NULL || bufferdesc.dwBufferBytes == 0) {
    87         dprintf(("bufferdesc not valid!"));
    88         lastError = DSERR_INVALIDPARAM;
    89         return;
    90     }
    91 
    92     // Some apps pass trash in cbSize, can't rely on that!
    93     lpfxFormat = (WAVEFORMATEX *)malloc(/*bufferdesc.lpwfxFormat->cbSize +*/ sizeof(WAVEFORMATEX));
    94     memcpy(lpfxFormat, bufferdesc.lpwfxFormat,  /*bufferdesc.lpwfxFormat->cbSize + */sizeof(WAVEFORMATEX));
    95 
    96     dprintf((" Buffer format: %dHz, %dbit, %d channels", lpfxFormat->nSamplesPerSec, lpfxFormat->wBitsPerSample, lpfxFormat->nChannels));
    97 
    98     lpSndBuffer = (SOUNDBUF *)VirtualAlloc(0, bufferdesc.dwBufferBytes + sizeof(DWORD), MEM_COMMIT, PAGE_READWRITE);
    99     if (lpSndBuffer == NULL) {
    100         dprintf(("VirtualAlloc failed"));
    101         lpSndBuffer  = NULL;
    102         lastError = DSERR_OUTOFMEMORY;
    103         return;
    104     }
    105     lpBuffer = &(lpSndBuffer->pData[0]);
    106     lpSndBuffer->dwReferences = 1;
    107 
    108     daudio = new DAudioWaveOut(lpfxFormat);
    109     if(daudio == NULL || daudio->getError()) {
    110         dprintf(("DAudioWaveOut ctor failed"));
    111         lastError = DSERR_OUTOFMEMORY;
    112         return;
    113     }
    114 
    115     wmutex.enter(VMUTEX_WAIT_FOREVER);
    116     next = dsbroot;
    117     dsbroot = this;
    118     wmutex.leave();
    119 }
    120 
    121 //******************************************************************************
    122 //******************************************************************************
    123 IDirectAudioBuffer::IDirectAudioBuffer(OS2IDirectSound *DSound, IDirectAudioBuffer *srcBuf)
    124         : Referenced(0), lastError(DS_OK), daudio(NULL), lpSndBuffer(NULL)
    125 {
    126     //This is the constructor used for duplicating sound buffers
    127     lpVtbl = &Vtbl;
    128     Vtbl.AddRef               = DAudioBufAddRef;
    129     Vtbl.Release              = DAudioBufRelease;
    130     Vtbl.QueryInterface       = DAudioBufQueryInterface;
    131     Vtbl.GetCaps              = DAudioBufGetCaps;
    132     Vtbl.GetFormat            = DAudioBufGetFormat;
    133     Vtbl.GetVolume            = DAudioBufGetVolume;
    134     Vtbl.GetStatus            = DAudioBufGetStatus;
    135     Vtbl.GetCurrentPosition   = DAudioBufGetCurrentPosition;
    136     Vtbl.GetPan               = DAudioBufGetPan;
    137     Vtbl.GetFrequency         = DAudioBufGetFrequency;
    138     Vtbl.Initialize           = DAudioBufInitialize;
    139     Vtbl.Restore              = DAudioBufRestore;
    140     Vtbl.SetFormat            = DAudioBufSetFormat;
    141     Vtbl.SetVolume            = DAudioBufSetVolume;
    142     Vtbl.SetCurrentPosition   = DAudioBufSetCurrentPosition;
    143     Vtbl.SetPan               = DAudioBufSetPan;
    144     Vtbl.SetFrequency         = DAudioBufSetFrequency;
    145     Vtbl.Lock                 = DAudioBufLock;
    146     Vtbl.Unlock               = DAudioBufUnlock;
    147     Vtbl.Stop                 = DAudioBufStop;
    148     Vtbl.Play                 = DAudioBufPlay;
    149 
    150     dprintf(("DSOUND-IDirectAudioBuffer::OS2IDirectAudioBuffer/Duplicate (buf=%X)", this));
    151 
    152     parentDS  = DSound;
    153     writepos  = 0;
    154     playpos   = 0;
    155     status    = 0;
    156     fLocked   = FALSE;
    157     volume    = srcBuf->volume;
    158     DSvolume  = srcBuf->DSvolume;
    159     pan       = srcBuf->pan;
    160     DSpan     = srcBuf->DSpan;
    161     lpBuffer  = srcBuf->lpBuffer;
    162     fPlaying  = FALSE;
    163     fLoop     = srcBuf->fLoop;
    164     notify    = NULL;
    165     memcpy(&bufferdesc, &(srcBuf->bufferdesc), sizeof(DSBUFFERDESC));
    166 
    167     // frequency has to be set according to the bufer format
    168     frequency = srcBuf->frequency;
    169 
    170     lpfxFormat = (WAVEFORMATEX *)malloc(sizeof(WAVEFORMATEX));
    171     memcpy(lpfxFormat,srcBuf->lpfxFormat, sizeof(WAVEFORMATEX));
    172 
    173     dprintf((" Buffer format: %dHz, %dbit, %d channels", lpfxFormat->nSamplesPerSec, lpfxFormat->wBitsPerSample, lpfxFormat->nChannels));
    174 
    175     // Increment reference count for the buffer memory
    176     lpSndBuffer  = srcBuf->lpSndBuffer;
    177     lpSndBuffer->dwReferences++;
    178 
    179     if(daudio) {
    180         delete daudio;
    181         daudio = 0;
    182     }
    183     wmutex.enter(VMUTEX_WAIT_FOREVER);
    184     next = dsbroot;
    185     dsbroot = this;
    186     wmutex.leave();
    187 }
    188 
    189 //******************************************************************************
    190 //******************************************************************************
    191 IDirectAudioBuffer::~IDirectAudioBuffer()
    192 {
    193     dprintf(("DSOUND-IDirectAudioBuffer::~OS2IDirectAudioBuffer (buf=%X)", this));
    194 
    195     // free allocted memory - unless it's shared by a duplicated buffer
    196     if (lpSndBuffer) {
    197         lpSndBuffer->dwReferences--;
    198         if (lpSndBuffer->dwReferences == 0)
    199             VirtualFree(lpSndBuffer, 0, MEM_RELEASE);
    200     }
    201 
    202     if (lpfxFormat)
    203         free(lpfxFormat);
    204 
    205     // remove ourselves from the linked list
    206     IDirectAudioBuffer *cur  = dsbroot;
    207     IDirectAudioBuffer *prev = NULL;
    208 
    209     wmutex.enter(VMUTEX_WAIT_FOREVER);
    210     if (this == dsbroot)  // is this the first DAudioBuffer?
    211         dsbroot = next;
    212     else {                // walk the chain
    213         while (cur->next != this)
    214             cur  = cur->next;
    215 
    216         cur->next = next;
    217     }
    218     wmutex.leave();
    219 }
    220 
     209}
    221210//******************************************************************************
    222211//******************************************************************************
     
    325314    }
    326315
    327     dprintf(("  PlayPos %d, WritePos %d", playpos, writepos));
    328     *lpdwCurrentPlayCursor  = playpos;
    329     *lpdwCurrentWriteCursor = writepos;
     316    *lpdwCurrentPlayCursor  = daudio->getPosition(lpdwCurrentWriteCursor);
     317    dprintf(("  PlayPos %d, WritePos %d", *lpdwCurrentPlayCursor, *lpdwCurrentWriteCursor));
    330318    return DS_OK;
    331319}
     
    337325    playpos   = dwNewPosition;
    338326
     327    //TODO:
    339328    return DS_OK;
    340329}
     
    462451HRESULT IDirectAudioBuffer::SetFrequency(DWORD dwFrequency)
    463452{
    464     dprintf(("DSOUND-IDirectAudioBuffer::DAudioBufSetFrequency %x %x", this, dwFrequency));
     453 DWORD oldfrequency = frequency;
     454
     455    dprintf(("DSOUND-IDirectAudioBuffer::DAudioBufSetFrequency %x %d (old %d)", this, dwFrequency, oldfrequency));
    465456
    466457    // zero means default (buffer format) frequency
     
    470461        frequency = lpfxFormat->nSamplesPerSec;
    471462
     463    if(frequency != oldfrequency) {
     464        daudio->setProperty(PROPERTY_FREQUENCY, frequency);
     465    }
    472466    return DS_OK;
    473467}
     
    559553        status   = DSBSTATUS_PLAYING;
    560554        fLoop    = dwFlags == DSBPLAY_LOOPING;
    561         if (fLoop)
     555        if (fLoop) {
    562556            status |= DSBSTATUS_LOOPING;
    563 
    564         dprintf(("  Buffer %X: start at pos %d, loop %s",this, playpos, fLoop?"YES":"NO"));
     557            daudio->setProperty(PROPERTY_LOOPING, TRUE);
     558        }
     559        dprintf(("Buffer %X: start at pos %d, loop %s",this, playpos, fLoop?"YES":"NO"));
    565560    }
    566561    else {
     
    569564            status |= DSBSTATUS_LOOPING;
    570565
     566        daudio->setProperty(PROPERTY_LOOPING, fLoop);
    571567        dprintf(("  Buffer %X: already playing, loop %s",this, fLoop?"YES":"NO"));
    572568    }
     
    582578    status  &= ~(DSBSTATUS_PLAYING | DSBSTATUS_LOOPING);
    583579
     580    daudio->stop();
     581
    584582    if (notify != NULL)
    585583        notify->CheckStop();
Note: See TracChangeset for help on using the changeset viewer.