Ignore:
Timestamp:
Feb 22, 2010, 2:44:21 PM (16 years ago)
Author:
rlwalsh
Message:

add FlashWaveOut class to winmm - see Ticket #2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/winmm/waveoutdart.cpp

    r10525 r21358  
    1515 */
    1616
    17 
    18 /****************************************************************************
    19  * Includes                                                                 *
    20  ****************************************************************************/
    21 
    22 
     17/******************************************************************************/
     18// Includes
     19/******************************************************************************/
    2320
    2421#define  INCL_BASE
     
    4138#include "dbglocal.h"
    4239
     40/******************************************************************************/
     41
    4342#ifndef min
    4443#define min(a, b) ((a > b) ? b : a)
     
    5150LONG APIENTRY WaveOutHandler(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags);
    5251
    53 static BOOL fFixedWaveBufferSize = FALSE;
     52#define DART_BUFCNT     64
     53#define DART_BUFSIZE    4096
     54
     55/******************************************************************************/
    5456
    5557//#define DEBUG_DUMP_PCM
     
    6769#endif
    6870
    69 //******************************************************************************
     71/******************************************************************************/
     72
     73static BOOL fFixedWaveBufferSize = FALSE;
     74
     75/******************************************************************************/
    7076// ODIN_waveOutSetFixedBuffers
    7177//
     
    7682//       purpose solution.
    7783//
    78 //******************************************************************************
     84/******************************************************************************/
     85
    7986void WIN32API ODIN_waveOutSetFixedBuffers()
    8087{
    8188    fFixedWaveBufferSize = TRUE;
    8289}
    83 /******************************************************************************/
    84 /******************************************************************************/
     90
     91/******************************************************************************/
     92/******************************************************************************/
     93
    8594DartWaveOut::DartWaveOut(LPWAVEFORMATEX pwfx, ULONG fdwOpen, ULONG nCallback, ULONG dwInstance)
    8695                  : WaveOut(pwfx, fdwOpen, nCallback, dwInstance)
    8796{
    88     MCI_GENERIC_PARMS  GenericParms;
     97    DeviceId        = 0;
     98    fMixerSetup     = FALSE;
     99    fUnderrun       = FALSE;
     100    curFillBuf      = 0;
     101    curPlayBuf      = 0;
     102    curFillPos      = 0;
     103    curPlayPos      = 0;
     104    ulBufSize       = DART_BUFSIZE;
     105    ulBufCount      = DART_BUFCNT;
     106    bytesPlayed     = 0;
     107    bytesCopied     = 0;
     108    bytesReturned   = 0;
     109    ulUnderrunBase  = 0;
     110    mixHandle       = 0;
     111    curhdr          = NULL;
     112    pmixWriteProc   = 0;
     113    MixBuffer       = 0;
     114    BufferParms     = 0;
     115}
     116
     117/******************************************************************************/
     118/******************************************************************************/
     119
     120DartWaveOut::~DartWaveOut()
     121{
     122    MCI_GENERIC_PARMS GenericParms = {0};
     123
     124    State = STATE_STOPPED;
     125
     126#ifdef DEBUG_DUMP_PCM
     127    if (pcmfile) fclose(pcmfile);
     128#endif
     129
     130    if (DeviceId) {
     131        // Stop the playback.
     132        mymciSendCommand(DeviceId, MCI_STOP,
     133                         MCI_WAIT,
     134                         (PVOID)&GenericParms,0);
     135
     136        if (fMixerSetup)
     137            mymciSendCommand(DeviceId, MCI_BUFFER,
     138                             MCI_WAIT | MCI_DEALLOCATE_MEMORY,
     139                             (PVOID)&BufferParms, 0);
     140
     141        // Close the device
     142        mymciSendCommand(DeviceId, MCI_CLOSE,
     143                         MCI_WAIT,
     144                         (PVOID)&GenericParms, 0);
     145
     146        callback(WOM_CLOSE, 0, 0);
     147    }
     148
     149    if (MixBuffer)
     150        free(MixBuffer);
     151    if (BufferParms)
     152        free(BufferParms);
     153}
     154
     155/******************************************************************************/
     156/******************************************************************************/
     157
     158MMRESULT DartWaveOut::open()
     159{
    89160    MCI_AMP_OPEN_PARMS AmpOpenParms;
     161    MCI_GENERIC_PARMS  GenericParms = {0};
     162    MCI_MIXSETUP_PARMS MixSetupParms;
    90163    APIRET rc;
    91164
    92     curPlayBuf = curFillBuf = curFillPos = curPlayPos = 0;
    93     fMixerSetup   = FALSE;
    94     fUnderrun     = FALSE;
    95     ulUnderrunBase= 0;
    96 
    97     ulBufSize     = DART_BUFSIZE;
    98 
    99     MixBuffer     = (MCI_MIX_BUFFER *)malloc(PREFILLBUF_DART*sizeof(MCI_MIX_BUFFER));
    100     MixSetupParms = (MCI_MIXSETUP_PARMS *)malloc(sizeof(MCI_MIXSETUP_PARMS));
     165    MixBuffer     = (MCI_MIX_BUFFER *)malloc(ulBufCount*sizeof(MCI_MIX_BUFFER));
    101166    BufferParms   = (MCI_BUFFER_PARMS *)malloc(sizeof(MCI_BUFFER_PARMS));
    102     if(!MixBuffer || !MixSetupParms || !BufferParms) {
     167    if (!MixBuffer || !BufferParms) {
    103168        dprintf(("ERROR: malloc failed!!"));
    104         ulError = MMSYSERR_NOMEM;
    105         return;
    106     }
    107 
    108     // Setup the open structure, pass the playlist and tell MCI_OPEN to use it
    109     memset(&AmpOpenParms,0,sizeof(AmpOpenParms));
    110 
    111     AmpOpenParms.usDeviceID = ( USHORT ) 0;
    112     AmpOpenParms.pszDeviceType = ( PSZ ) MCI_DEVTYPE_AUDIO_AMPMIX;
    113 
    114     rc = mymciSendCommand(0, MCI_OPEN, MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE,
    115                        (PVOID) &AmpOpenParms, 0);
    116 
    117     DeviceId = AmpOpenParms.usDeviceID;
    118     if(rc) {
     169        return MMSYSERR_NOMEM;
     170    }
     171
     172    // Setup the open structure, then open the device
     173    memset(&AmpOpenParms, 0, sizeof(AmpOpenParms));
     174    AmpOpenParms.usDeviceID = 0;
     175    AmpOpenParms.pszDeviceType = (PSZ)MCI_DEVTYPE_AUDIO_AMPMIX;
     176
     177    rc = mymciSendCommand(0, MCI_OPEN,
     178                          MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE,
     179                          (PVOID)&AmpOpenParms, 0);
     180    if (LOUSHORT(rc) != MCIERR_SUCCESS) {
    119181        dprintf(("MCI_OPEN failed\n"));
    120182        mciError(rc);
    121         ulError = MMSYSERR_NODRIVER;
    122     }
    123     if(rc == 0) {
    124         //Grab exclusive rights to device instance (NOT entire device)
    125         GenericParms.hwndCallback = 0;  //Not needed, so set to 0
    126         rc = mymciSendCommand(DeviceId, MCI_ACQUIREDEVICE, MCI_EXCLUSIVE_INSTANCE,
    127                             (PVOID)&GenericParms, 0);
    128         if(rc) {
    129             dprintf(("MCI_ACQUIREDEVICE failed\n"));
    130             mciError(rc);
    131             ulError = MMSYSERR_NOTENABLED;
     183        return MMSYSERR_NODRIVER;
     184    }
     185    DeviceId = AmpOpenParms.usDeviceID;
     186
     187    // Grab exclusive rights to device instance (NOT entire device)
     188    rc = mymciSendCommand(DeviceId, MCI_ACQUIREDEVICE,
     189                          MCI_EXCLUSIVE_INSTANCE,
     190                          (PVOID)&GenericParms, 0);
     191    if (LOUSHORT(rc) != MCIERR_SUCCESS) {
     192        dprintf(("MCI_ACQUIREDEVICE failed\n"));
     193        mciError(rc);
     194        return MMSYSERR_NOTENABLED;
     195    }
     196    dprintf(("device acquired\n"));
     197    dprintf(("bps %d, sps %d chan %d\n", BitsPerSample, SampleRate, nChannels));
     198
     199    // Setup the mixer for playback of wave data
     200    memset(&MixSetupParms, 0, sizeof(MixSetupParms));
     201    MixSetupParms.ulBitsPerSample = BitsPerSample;
     202    MixSetupParms.ulSamplesPerSec = SampleRate;
     203    MixSetupParms.ulFormatTag     = MCI_WAVE_FORMAT_PCM;
     204    MixSetupParms.ulChannels      = nChannels;
     205    MixSetupParms.ulFormatMode    = MCI_PLAY;
     206    MixSetupParms.ulDeviceType    = MCI_DEVTYPE_WAVEFORM_AUDIO;
     207    MixSetupParms.pmixEvent       = WaveOutHandler;
     208
     209    rc = mymciSendCommand(DeviceId, MCI_MIXSETUP,
     210                          MCI_WAIT | MCI_MIXSETUP_INIT,
     211                          (PVOID)&MixSetupParms, 0);
     212
     213    if (LOUSHORT(rc) != MCIERR_SUCCESS) {
     214        mciError(rc);
     215        mymciSendCommand(DeviceId, MCI_RELEASEDEVICE,
     216                         MCI_WAIT,
     217                         (PVOID)&GenericParms, 0);
     218        return MMSYSERR_NOTSUPPORTED;
     219    }
     220
     221    // Save the mixer handle & the ptr to the write proc.
     222    mixHandle     = MixSetupParms.ulMixHandle;
     223    pmixWriteProc = MixSetupParms.pmixWrite;
     224
     225#ifdef DEBUG_DUMP_PCM
     226    REC_STRUCT recinfo;
     227
     228    pcmfile = fopen("dartpcm.dat", "wb");
     229    recinfo.bits = BitsPerSample;
     230    recinfo.rate = SampleRate;
     231    recinfo.format = MCI_WAVE_FORMAT_PCM;
     232    recinfo.numchan = nChannels;
     233    fwrite(&recinfo, sizeof(recinfo), 1, pcmfile);
     234#endif
     235
     236    setVolume(volume);
     237    callback(WOM_OPEN, 0, 0);
     238
     239    return MMSYSERR_NOERROR;
     240}
     241
     242/******************************************************************************/
     243/******************************************************************************/
     244
     245MMRESULT DartWaveOut::write(LPWAVEHDR pwh, UINT cbwh)
     246{
     247    APIRET rc;
     248
     249    queuedbuffers++;
     250    pwh->lpNext = NULL;
     251    pwh->reserved = 0;
     252
     253    // Set up the BufferParms data structure and allocate
     254    // device buffers from the Amp-Mixer
     255    if (fMixerSetup == FALSE)
     256    {
     257        ulBufSize = pwh->dwBufferLength;
     258        if (!ulBufSize || ulBufSize > 0x10000)
     259            return MMSYSERR_INVALPARAM;
     260
     261        rc = initBuffers();
     262        if (rc != MMSYSERR_NOERROR)
     263            return rc;
     264
     265        curhdr = pwh;
     266        fMixerSetup = TRUE;
     267    }
     268
     269    wmutex.enter();
     270
     271    if (wavehdr) {
     272        WAVEHDR *chdr = wavehdr;
     273        while (chdr->lpNext) {
     274#ifdef DEBUG
     275            if (chdr == pwh) dprintf(("adding already present buffer!!!!!"));
     276#endif
     277            chdr = chdr->lpNext;
    132278        }
    133     }
    134     setVolume(volume);
    135 
    136     if(!ulError)
    137         callback(WOM_OPEN, 0, 0);
    138 }
    139 /******************************************************************************/
    140 /******************************************************************************/
    141 DartWaveOut::~DartWaveOut()
    142 {
    143     MCI_GENERIC_PARMS GenericParms;
    144 
    145     State = STATE_STOPPED;
    146 
    147 #ifdef DEBUG_DUMP_PCM
    148     if(pcmfile) fclose(pcmfile);
    149 #endif
    150 
    151     if(!ulError) {
    152         // Generic parameters
    153         GenericParms.hwndCallback = 0;   //hwndFrame
    154 
    155         // Stop the playback.
    156         mymciSendCommand(DeviceId, MCI_STOP,MCI_WAIT, (PVOID)&GenericParms,0);
    157 
    158         mymciSendCommand(DeviceId, MCI_BUFFER,
    159                        MCI_WAIT | MCI_DEALLOCATE_MEMORY,
    160                        (PVOID)&BufferParms, 0);
    161 
    162         // Generic parameters
    163         GenericParms.hwndCallback = 0;   //hwndFrame
    164 
    165         // Close the device
    166         mymciSendCommand(DeviceId, MCI_CLOSE, MCI_WAIT, (PVOID)&GenericParms, 0);
    167     }
    168 
    169     if(!ulError)
     279        chdr->lpNext = pwh;
     280    }
     281    else wavehdr = pwh;
     282
     283    //don't start playback if paused
     284    if (!fUnderrun && State != STATE_STOPPED) {
     285        //write new data to the DART buffers (if there's any room left)
     286        if (State == STATE_PLAYING)
     287            writeBuffer();  //must be called before (re)starting playback
     288        wmutex.leave();
     289        return MMSYSERR_NOERROR;
     290    }
     291
     292    writeBuffer();  //must be called before (re)starting playback
     293    State     = STATE_PLAYING;
     294    fUnderrun = FALSE;
     295    wmutex.leave();
     296
     297    //write buffers to DART; starts playback
     298    dprintf(("WINMM: transfer all buffers to DART"));
     299
     300    USHORT selTIB = RestoreOS2FS(); // save current FS selector
     301    pmixWriteProc(mixHandle, MixBuffer, ulBufCount);
     302    SetFS(selTIB);           // switch back to the saved FS selector
     303
     304    dprintf(("Dart playing\n"));
     305
     306    return MMSYSERR_NOERROR;
     307}
     308
     309/******************************************************************************/
     310/******************************************************************************/
     311
     312MMRESULT DartWaveOut::initBuffers()
     313{
     314    APIRET rc;
     315    MCI_GENERIC_PARMS  GenericParms = {0};
     316    int orgbufsize = ulBufSize;  // on entry, ulBufSize == pwh->dwBufferLength
     317
     318#if 1
     319    //by default we need to select a small enough buffer
     320    //to be able to signal buffer completion in time
     321    if (fFixedWaveBufferSize == FALSE)
    170322    {
    171         callback(WOM_CLOSE, 0, 0);
    172     }
    173 
    174     if(MixBuffer)
    175         free(MixBuffer);
    176     if(MixSetupParms)
    177         free(MixSetupParms);
    178     if(BufferParms)
    179         free(BufferParms);
    180 }
    181 /******************************************************************************/
    182 /******************************************************************************/
    183 MMRESULT DartWaveOut::write(LPWAVEHDR pwh, UINT cbwh)
    184 {
    185     MCI_GENERIC_PARMS GenericParms = {0};
    186     APIRET rc;
    187     int i, buflength;
    188 
    189     queuedbuffers++;
    190     if(fMixerSetup == FALSE)
    191     {
    192         dprintf(("device acquired\n"));
    193         /* Set the MixSetupParms data structure to match the loaded file.
    194          * This is a global that is used to setup the mixer.
    195          */
    196         memset(MixSetupParms, 0, sizeof( MCI_MIXSETUP_PARMS ) );
    197 
    198         MixSetupParms->ulBitsPerSample = BitsPerSample;
    199         MixSetupParms->ulSamplesPerSec = SampleRate;
    200         MixSetupParms->ulFormatTag     = MCI_WAVE_FORMAT_PCM;
    201         MixSetupParms->ulChannels      = nChannels;
    202 
    203         dprintf(("bps %d, sps %d chan %d\n", BitsPerSample, SampleRate, nChannels));
    204 
    205 #ifdef DEBUG_DUMP_PCM
    206         REC_STRUCT recinfo;
    207 
    208         pcmfile = fopen("dartpcm.dat", "wb");
    209         recinfo.bits = BitsPerSample;
    210         recinfo.rate = SampleRate;
    211         recinfo.format = MCI_WAVE_FORMAT_PCM;
    212         recinfo.numchan = nChannels;
    213         fwrite(&recinfo, sizeof(recinfo), 1, pcmfile);
    214 #endif
    215         /* Setup the mixer for playback of wave data
    216          */
    217         MixSetupParms->ulFormatMode = MCI_PLAY;
    218         MixSetupParms->ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
    219         MixSetupParms->pmixEvent    = WaveOutHandler;
    220 
    221         rc = mymciSendCommand(DeviceId,
    222                             MCI_MIXSETUP,
    223                             MCI_WAIT | MCI_MIXSETUP_INIT,
    224                             (PVOID)MixSetupParms,
    225                             0);
    226 
    227         if ( rc != MCIERR_SUCCESS ) {
    228             mciError(rc);
    229             mymciSendCommand(DeviceId, MCI_RELEASEDEVICE, MCI_WAIT,
    230                            (PVOID)&GenericParms, 0);
    231             return(MMSYSERR_NOTSUPPORTED);
     323        int consumerate = getAvgBytesPerSecond();
     324        int minbufsize = consumerate/32;
     325
     326        ulBufSize /= 2;
     327        if (ulBufSize > minbufsize) {
     328            dprintf(("set buffer size to %d bytes (org size = %d)", minbufsize, orgbufsize));
     329            ulBufSize = minbufsize;
    232330        }
    233 
    234         /*
    235          * Set up the BufferParms data structure and allocate
    236          * device buffers from the Amp-Mixer
    237          */
    238         dprintf(("mix setup %d, %d\n", pwh->dwBufferLength, pwh->dwBufferLength));
    239 
    240 #if 1
    241         if(fFixedWaveBufferSize == FALSE)
    242         {//by default we need to select a small enough buffer to be able to
    243          //signal buffer completion in time
    244             int consumerate = getAvgBytesPerSecond();
    245             int minbufsize = consumerate/32;
    246 
    247             ulBufSize = pwh->dwBufferLength/2;
    248             if(ulBufSize > minbufsize) {
    249                 dprintf(("set buffer size to %d bytes (org size = %d)", minbufsize, pwh->dwBufferLength));
    250                 ulBufSize = minbufsize;
    251             }
    252         }
    253         else ulBufSize = pwh->dwBufferLength;
     331    }
    254332#else
    255         if(pwh->dwBufferLength >= 512 && pwh->dwBufferLength <= 1024)
    256                 ulBufSize = pwh->dwBufferLength;
    257         else    ulBufSize = 1024;
    258 #endif
    259         MixSetupParms->ulBufferSize = ulBufSize;
    260 
    261         BufferParms->ulNumBuffers = PREFILLBUF_DART;
    262         BufferParms->ulBufferSize = MixSetupParms->ulBufferSize;
    263         BufferParms->pBufList     = MixBuffer;
    264 
    265         for(i=0;i<PREFILLBUF_DART;i++) {
    266             MixBuffer[i].ulUserParm = (ULONG)this;
    267         }
    268 
    269         rc = mymciSendCommand(DeviceId,
    270                             MCI_BUFFER,
    271                             MCI_WAIT | MCI_ALLOCATE_MEMORY,
    272                             (PVOID)BufferParms,
    273                             0);
    274 
    275         if(ULONG_LOWD(rc) != MCIERR_SUCCESS) {
    276             mciError(rc);
    277             mymciSendCommand(DeviceId, MCI_RELEASEDEVICE, MCI_WAIT,
    278                           (PVOID)&GenericParms, 0);
    279             return(MMSYSERR_NOTSUPPORTED);
    280         }
    281 
    282         wmutex.enter();
    283         fMixerSetup = TRUE;
    284 
    285         curPlayBuf = curFillBuf = curFillPos = curPlayPos = 0;
    286         bytesPlayed = bytesCopied = bytesReturned = 0;
    287 
    288         for(i=0;i<PREFILLBUF_DART;i++) {
    289             memset(MixBuffer[i].pBuffer, 0, MixBuffer[i].ulBufferLength);
    290         }
    291         dprintf(("Dart opened, bufsize = %d\n", MixBuffer[0].ulBufferLength));
    292 
    293         wavehdr     = pwh;
    294         curhdr      = pwh;
    295         pwh->lpNext = NULL;
    296         pwh->reserved = 0;
    297 
    298         if(State != STATE_STOPPED) {//don't start playback if paused
    299             wmutex.leave();
    300             return(MMSYSERR_NOERROR);
    301         }
    302 
    303         writeBuffer();  //must be called before (re)starting playback
    304 
    305         dprintf(("MixSetupParms = %X\n", MixSetupParms));
    306         State     = STATE_PLAYING;
    307         fUnderrun = FALSE;
    308         wmutex.leave();
    309 
    310         //write buffers to DART; starts playback
    311         dprintf(("WINMM: transfer all buffers to DART"));
    312         USHORT selTIB = RestoreOS2FS(); // save current FS selector
    313 
    314         MixSetupParms->pmixWrite(MixSetupParms->ulMixHandle,
    315                                  MixBuffer,
    316                                  PREFILLBUF_DART);
    317         SetFS(selTIB);           // switch back to the saved FS selector
    318         dprintf(("Dart playing\n"));
    319     }
    320     else
    321     {
    322         pwh->lpNext   = NULL;
    323         pwh->reserved = 0;
    324         wmutex.enter();
    325         if(wavehdr) {
    326             WAVEHDR *chdr = wavehdr;
    327             while(chdr->lpNext) {
    328 #ifdef DEBUG
    329                 if(chdr == pwh) dprintf(("adding already present buffer!!!!!"));
    330 #endif
    331                 chdr = chdr->lpNext;
    332             }
    333             chdr->lpNext = pwh;
    334         }
    335         else wavehdr = pwh;
    336 
    337         if(!fUnderrun && State != STATE_STOPPED) {//don't start playback if paused
    338             //write new data to the DART buffers (if there's any room left)
    339             if(State == STATE_PLAYING) {
    340                 writeBuffer();  //must be called before (re)starting playback
    341             }
    342             wmutex.leave();
    343             return(MMSYSERR_NOERROR);
    344         }
    345         writeBuffer();  //must be called before (re)starting playback
    346         State     = STATE_PLAYING;
    347         fUnderrun = FALSE;
    348         wmutex.leave();
    349 
    350         //write buffers to DART; starts playback
    351         dprintf(("WINMM: transfer all buffers to DART"));
    352         USHORT selTIB = RestoreOS2FS(); // save current FS selector
    353 
    354         MixSetupParms->pmixWrite(MixSetupParms->ulMixHandle,
    355                                  MixBuffer,
    356                                  PREFILLBUF_DART);
    357         SetFS(selTIB);           // switch back to the saved FS selector
    358 
    359         dprintf(("Dart playing\n"));
    360     }
    361     return(MMSYSERR_NOERROR);
    362 }
    363 /******************************************************************************/
    364 /******************************************************************************/
     333    if (ulBufSize < 512 || ulBufSize > 1024)
     334        ulBufSize = 1024;
     335#endif
     336
     337    dprintf(("buffer setup - WAVE size = %d, DART size = %d\n",
     338             orgbufsize, ulBufSize));
     339
     340    BufferParms->ulNumBuffers = ulBufCount;
     341    BufferParms->ulBufferSize = ulBufSize;
     342    BufferParms->pBufList     = MixBuffer;
     343
     344    rc = mymciSendCommand(DeviceId, MCI_BUFFER,
     345                        MCI_WAIT | MCI_ALLOCATE_MEMORY,
     346                        (PVOID)BufferParms, 0);
     347
     348    if (LOUSHORT(rc) != MCIERR_SUCCESS) {
     349        mciError(rc);
     350        mymciSendCommand(DeviceId, MCI_RELEASEDEVICE,
     351                         MCI_WAIT,
     352                         (PVOID)&GenericParms, 0);
     353        return MMSYSERR_NOTSUPPORTED;
     354    }
     355
     356    // DART may not have allocated all the buffers requested.
     357    ulBufCount = BufferParms->ulNumBuffers;
     358
     359    for (int i = 0; i < ulBufCount; i++) {
     360        MixBuffer[i].ulUserParm = (ULONG)this;
     361        memset(MixBuffer[i].pBuffer, 0, MixBuffer[i].ulBufferLength);
     362    }
     363    dprintf(("Dart opened, bufsize = %d\n", MixBuffer[0].ulBufferLength));
     364
     365    return MMSYSERR_NOERROR;
     366}
     367
     368/******************************************************************************/
     369/******************************************************************************/
     370
    365371MMRESULT DartWaveOut::pause()
    366372{
    367     MCI_GENERIC_PARMS Params;
     373    MCI_GENERIC_PARMS  GenericParms = {0};
    368374
    369375    dprintf(("WINMM: DartWaveOut::pause"));
    370376
    371377    wmutex.enter();
    372     if(State != STATE_PLAYING) {
     378    if (State != STATE_PLAYING) {
    373379        State = STATE_PAUSED;
    374380        wmutex.leave();
    375         return(MMSYSERR_NOERROR);
     381        return MMSYSERR_NOERROR;
    376382    }
    377383
     
    379385    wmutex.leave();
    380386
    381     memset(&Params, 0, sizeof(Params));
    382 
    383387    // Pause playback.
    384     mymciSendCommand(DeviceId, MCI_PAUSE, MCI_WAIT, (PVOID)&Params, 0);
    385 
    386     return(MMSYSERR_NOERROR);
    387 }
    388 /******************************************************************************/
    389 /******************************************************************************/
     388    mymciSendCommand(DeviceId, MCI_PAUSE,
     389                     MCI_WAIT,
     390                     (PVOID)&GenericParms, 0);
     391
     392    return MMSYSERR_NOERROR;
     393}
     394
     395/******************************************************************************/
     396/******************************************************************************/
     397
    390398MMRESULT DartWaveOut::resume()
    391399{
    392     MCI_GENERIC_PARMS Params;
    393400    int i, curbuf;
    394401
     
    396403   
    397404    wmutex.enter();
    398     if(State != STATE_PAUSED) {
     405    if (State != STATE_PAUSED) {
    399406        wmutex.leave();
    400         return(MMSYSERR_NOERROR);
     407        return MMSYSERR_NOERROR;
    401408    }
    402409    State = STATE_PLAYING;
     
    405412    //Only write buffers to dart if mixer has been initialized; if not, then
    406413    //the first buffer write will do this for us.
    407     if(fMixerSetup == TRUE)
     414    if (fMixerSetup == TRUE)
    408415    {
    409416        wmutex.enter();
    410417        State     = STATE_PLAYING;
    411418        fUnderrun = FALSE;
    412         curbuf = curPlayBuf;
     419        curbuf    = curPlayBuf;
    413420        writeBuffer();  //must be called before (re)starting playback
    414421        wmutex.leave();
    415422
    416         // MCI_MIXSETUP_PARMS->pMixWrite does alter FS: selector!
    417423        USHORT selTIB = GetFS(); // save current FS selector
    418 
    419         for(i=0;i<PREFILLBUF_DART;i++)
     424        for (i = 0; i < ulBufCount; i++)
    420425        {
    421426            dprintf(("restart: write buffer at %x size %d", MixBuffer[curbuf].pBuffer, MixBuffer[curbuf].ulBufferLength));
    422             MixSetupParms->pmixWrite(MixSetupParms->ulMixHandle, &MixBuffer[curbuf], 1);
    423             if(++curbuf == PREFILLBUF_DART)
     427            pmixWriteProc(mixHandle, &MixBuffer[curbuf], 1);
     428            if (++curbuf == ulBufCount)
    424429                curbuf = 0;
    425430        }
    426431        SetFS(selTIB);           // switch back to the saved FS selector
    427432    }
    428     return(MMSYSERR_NOERROR);
    429 }
    430 /******************************************************************************/
    431 /******************************************************************************/
     433    return MMSYSERR_NOERROR;
     434}
     435
     436/******************************************************************************/
     437/******************************************************************************/
     438
    432439MMRESULT DartWaveOut::stop()
    433440{
    434     MCI_GENERIC_PARMS Params;
     441    MCI_GENERIC_PARMS  GenericParms = {0};
    435442
    436443    dprintf(("DartWaveOut::stop %s", (State == STATE_PLAYING) ? "playing" : "stopped"));
    437     if(State != STATE_PLAYING)
    438         return(MMSYSERR_HANDLEBUSY);
    439 
    440     memset(&Params, 0, sizeof(Params));
     444    if (State != STATE_PLAYING)
     445        return MMSYSERR_HANDLEBUSY;
    441446
    442447    // Stop the playback.
    443     mymciSendCommand(DeviceId, MCI_STOP, MCI_WAIT, (PVOID)&Params, 0);
     448    mymciSendCommand(DeviceId, MCI_STOP,
     449                     MCI_WAIT,
     450                     (PVOID)&GenericParms, 0);
    444451
    445452    State     = STATE_STOPPED;
     
    449456    bytesPlayed = bytesCopied = bytesReturned = 0;
    450457
    451     return(MMSYSERR_NOERROR);
    452 }
    453 /******************************************************************************/
    454 /******************************************************************************/
     458    return MMSYSERR_NOERROR;
     459}
     460
     461/******************************************************************************/
     462/******************************************************************************/
     463
    455464MMRESULT DartWaveOut::reset()
    456465{
    457     MCI_GENERIC_PARMS Params;
     466    MCI_GENERIC_PARMS  GenericParms = {0};
    458467    LPWAVEHDR tmpwavehdr;
    459468
    460469    dprintf(("DartWaveOut::reset %s", (State == STATE_PLAYING) ? "playing" : "stopped"));
    461     if(State != STATE_PLAYING)
    462         return(MMSYSERR_HANDLEBUSY);
    463 
    464     memset(&Params, 0, sizeof(Params));
     470    if (State != STATE_PLAYING)
     471        return MMSYSERR_HANDLEBUSY;
    465472
    466473    wmutex.enter();
     
    469476
    470477    // Stop the playback.
    471     mymciSendCommand(DeviceId, MCI_STOP, MCI_WAIT, (PVOID)&Params, 0);
     478    mymciSendCommand(DeviceId, MCI_STOP,
     479                     MCI_WAIT,
     480                     (PVOID)&GenericParms, 0);
    472481
    473482    wmutex.enter();
    474     while(wavehdr)
     483    while (wavehdr)
    475484    {
    476485        wavehdr->dwFlags  |= WHDR_DONE;
     
    494503
    495504    wmutex.leave();
    496     return(MMSYSERR_NOERROR);
    497 }
    498 /******************************************************************************/
    499 /******************************************************************************/
     505    return MMSYSERR_NOERROR;
     506}
     507
     508/******************************************************************************/
     509/******************************************************************************/
     510
    500511ULONG DartWaveOut::getPosition()
    501512{
    502  MCI_STATUS_PARMS mciStatus = {0};
    503  ULONG rc, nrbytes;
    504 
    505     if(State == STATE_STOPPED) {
     513    MCI_STATUS_PARMS StatusParms = {0};
     514    ULONG rc, nrbytes;
     515
     516    if (State == STATE_STOPPED) {
    506517        dprintf(("Not playing; return 0 position"));
    507518        return ulUnderrunBase;
    508519    }
    509520
    510     mciStatus.ulItem = MCI_STATUS_POSITION;
    511     rc = mymciSendCommand(DeviceId, MCI_STATUS, MCI_STATUS_ITEM|MCI_WAIT, (PVOID)&mciStatus, 0);
    512     if((rc & 0xFFFF) == MCIERR_SUCCESS) {
    513         nrbytes = (ULONG)(((double)mciStatus.ulReturn * (double)getAvgBytesPerSecond())/1000.0);
    514         return ulUnderrunBase+nrbytes;
    515     }
    516     mciError(rc);
    517     return 0xFFFFFFFF;
    518 }
    519 /******************************************************************************/
    520 /******************************************************************************/
    521 BOOL DartWaveOut::queryFormat(ULONG formatTag, ULONG nChannels,
    522                               ULONG nSamplesPerSec, ULONG wBitsPerSample)
    523 {
    524  MCI_WAVE_GETDEVCAPS_PARMS mciAudioCaps;
    525  MCI_GENERIC_PARMS    GenericParms;
    526  MCI_OPEN_PARMS       mciOpenParms;         /* open parms for MCI_OPEN             */
    527  int i, freqbits = 0;
    528  ULONG rc, DeviceId;
    529  BOOL winrc;
    530 
    531     dprintf(("DartWaveOut::queryFormat %x srate=%d, nchan=%d, bps=%d", formatTag, nSamplesPerSec, nChannels, wBitsPerSample));
    532 
    533     memset(&mciOpenParms,            /* Object to fill with zeros.       */
    534            0,                        /* Value to place into the object.  */
    535            sizeof( mciOpenParms ) ); /* How many zero's to use.          */
    536 
    537     mciOpenParms.pszDeviceType = (PSZ)MCI_DEVTYPE_WAVEFORM_AUDIO;
    538 
    539     rc = mymciSendCommand( (USHORT) 0,
    540                         MCI_OPEN,
    541                         MCI_WAIT | MCI_OPEN_TYPE_ID,
    542                         (PVOID) &mciOpenParms,
    543                         0);
    544     if((rc & 0xFFFF) != MCIERR_SUCCESS) {
     521    StatusParms.ulItem = MCI_STATUS_POSITION;
     522    rc = mymciSendCommand(DeviceId, MCI_STATUS,
     523                          MCI_STATUS_ITEM|MCI_WAIT,
     524                          (PVOID)&StatusParms, 0);
     525    if (LOUSHORT(rc) != MCIERR_SUCCESS) {
    545526        mciError(rc);
    546         return(FALSE);
    547     }
    548     DeviceId = mciOpenParms.usDeviceID;
    549 
    550     memset( &mciAudioCaps , 0, sizeof(MCI_WAVE_GETDEVCAPS_PARMS));
    551 
    552     mciAudioCaps.ulBitsPerSample = wBitsPerSample;
    553     mciAudioCaps.ulFormatTag     = DATATYPE_WAVEFORM;
    554     mciAudioCaps.ulSamplesPerSec = nSamplesPerSec;
    555     mciAudioCaps.ulChannels      = nChannels;
    556     mciAudioCaps.ulFormatMode    = MCI_PLAY;
    557     mciAudioCaps.ulItem          = MCI_GETDEVCAPS_WAVE_FORMAT;
    558 
    559     rc = mymciSendCommand(DeviceId,   /* Device ID    */
    560                         MCI_GETDEVCAPS,
    561                         MCI_WAIT | MCI_GETDEVCAPS_EXTENDED | MCI_GETDEVCAPS_ITEM,
    562                         (PVOID) &mciAudioCaps,
    563                         0);
    564     if((rc & 0xFFFF) != MCIERR_SUCCESS) {
     527        return 0xFFFFFFFF;
     528    }
     529
     530    nrbytes = (ULONG)(((double)StatusParms.ulReturn * (double)getAvgBytesPerSecond())/1000.0);
     531    return (ulUnderrunBase + nrbytes);
     532}
     533
     534/******************************************************************************/
     535/******************************************************************************/
     536
     537MMRESULT DartWaveOut::setVolume(ULONG ulVol)
     538{
     539    APIRET  rc;
     540    ULONG   ulVolR   = ((ulVol >> 16)    * 100) / 0xFFFF;
     541    ULONG   ulVolL   = ((ulVol & 0xffff) * 100) / 0xFFFF;
     542    MCI_SET_PARMS SetParms = {0};
     543
     544    dprintf(("DartWaveOut::setVolume %d %d", ulVolL, ulVolR));
     545    volume = ulVol;
     546
     547// Some drivers can't set left & right volumes independently
     548#ifdef GOOD_AUDIO_CARD_DRIVER
     549    SetParms.ulAudio = MCI_SET_AUDIO_LEFT;
     550    SetParms.ulLevel = ulVolL;
     551
     552    rc = mymciSendCommand(DeviceId, MCI_SET,
     553                          MCI_WAIT | MCI_SET_AUDIO | MCI_SET_VOLUME,
     554                          &SetParms, 0);
     555    if (LOUSHORT(rc) != MCIERR_SUCCESS)
    565556        mciError(rc);
    566         winrc = FALSE;
    567     }
    568     else  winrc = TRUE;
    569 
    570     // Close the device
    571     mymciSendCommand(DeviceId,MCI_CLOSE,MCI_WAIT,(PVOID)&GenericParms,0);
    572     return(winrc);
    573 }
    574 /******************************************************************************/
    575 /******************************************************************************/
    576 void DartWaveOut::mciError(ULONG ulError)
     557
     558    SetParms.ulAudio = MCI_SET_AUDIO_RIGHT;
     559    SetParms.ulLevel = ulVolR;
     560#else
     561    SetParms.ulAudio = MCI_SET_AUDIO_ALL;
     562    SetParms.ulLevel = (ulVolR + ulVolL) / 2;
     563#endif
     564
     565    rc = mymciSendCommand(DeviceId, MCI_SET,
     566                          MCI_WAIT | MCI_SET_AUDIO | MCI_SET_VOLUME,
     567                          &SetParms, 0);
     568    if (LOUSHORT(rc) != MCIERR_SUCCESS)
     569        mciError(rc);
     570
     571    return MMSYSERR_NOERROR;
     572}
     573
     574/******************************************************************************/
     575/******************************************************************************/
     576
     577void DartWaveOut::mciError(ULONG rc)
    577578{
    578579#ifdef DEBUG
    579580    char szError[256] = "";
    580581
    581     mymciGetErrorString(ulError, szError, sizeof(szError));
     582    mymciGetErrorString(rc, szError, sizeof(szError));
    582583    dprintf(("WINMM: DartWaveOut: %s\n", szError));
    583584#endif
    584585}
     586
    585587//******************************************************************************
    586588//******************************************************************************
     589
    587590void DartWaveOut::handler(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags)
    588591{
    589  ULONG    buflength;
    590  WAVEHDR *whdr, *prevhdr = NULL;
     592    ULONG    buflength;
     593    WAVEHDR *whdr, *prevhdr = NULL;
    591594
    592595    dprintf2(("WINMM: handler %d; buffers left %d", curPlayBuf, queuedbuffers));
    593     if(ulFlags == MIX_STREAM_ERROR) {
    594         if(ulStatus == ERROR_DEVICE_UNDERRUN) {
     596    if (ulFlags == MIX_STREAM_ERROR) {
     597        if (ulStatus == ERROR_DEVICE_UNDERRUN) {
    595598            dprintf(("WINMM: WaveOut handler UNDERRUN! state %s", (State == STATE_PLAYING) ? "playing" : "stopped"));
    596             if(State == STATE_PLAYING) {
     599            if (State == STATE_PLAYING) {
    597600                fUnderrun = TRUE;
    598601                //save current position for when we continue later
     
    605608        return;
    606609    }
    607     if(State != STATE_PLAYING) {
     610    if (State != STATE_PLAYING)
    608611        return;
    609     }
    610612
    611613    wmutex.enter();
     
    613615    bytesPlayed += MixBuffer[curPlayBuf].ulBufferLength;
    614616
    615     //update our buffer index
    616     if(curPlayBuf == PREFILLBUF_DART-1)
    617          curPlayBuf = 0;
    618     else curPlayBuf++;
     617    // update our buffer index
     618    if (++curPlayBuf >= ulBufCount)
     619        curPlayBuf = 0;
    619620
    620621    fUnderrun = FALSE;
    621622
    622623    whdr = wavehdr;
    623     while(whdr) {
    624         if(whdr->reserved == WHDR_DONE)
    625         {
    626             if(bytesPlayed < bytesReturned + whdr->dwBufferLength) {
    627                 dprintf2(("Buffer marked done, but not yet played completely (play %d/%d, cop %d, ret %d)", bytesPlayed, getPosition(), bytesCopied, bytesReturned));
    628                 break;  //not yet done
    629             }
    630 
    631             dprintf2(("WINMM: handler buf %X done (play %d/%d, cop %d, ret %d)", whdr, bytesPlayed, getPosition(), bytesCopied, bytesReturned));
    632             queuedbuffers--;
    633 
    634             whdr->dwFlags  &= ~WHDR_INQUEUE;
    635             whdr->dwFlags  |= WHDR_DONE;
    636             whdr->reserved  = 0;
    637 
    638             if(prevhdr == NULL)
    639                  wavehdr = whdr->lpNext;
    640             else prevhdr->lpNext = whdr->lpNext;
    641 
    642             whdr->lpNext = NULL;
    643 
    644             bytesReturned += whdr->dwBufferLength;
    645             wmutex.leave();
    646 
    647             callback(WOM_DONE, (ULONG)whdr, 0);
    648 
    649             wmutex.enter();
     624    while (whdr) {
     625        if (whdr->reserved != WHDR_DONE)
     626            break;
     627
     628        if (bytesPlayed < bytesReturned + whdr->dwBufferLength) {
     629            dprintf2(("Buffer marked done, but not yet played completely (play %d/%d, cop %d, ret %d)", bytesPlayed, getPosition(), bytesCopied, bytesReturned));
     630            break;  //not yet done
    650631        }
    651         else break;
     632
     633        dprintf2(("WINMM: handler buf %X done (play %d/%d, cop %d, ret %d)", whdr, bytesPlayed, getPosition(), bytesCopied, bytesReturned));
     634        queuedbuffers--;
     635
     636        whdr->dwFlags  &= ~WHDR_INQUEUE;
     637        whdr->dwFlags  |= WHDR_DONE;
     638        whdr->reserved  = 0;
     639
     640        if (prevhdr == NULL)
     641             wavehdr = whdr->lpNext;
     642        else prevhdr->lpNext = whdr->lpNext;
     643
     644        whdr->lpNext = NULL;
     645
     646        bytesReturned += whdr->dwBufferLength;
     647
     648        wmutex.leave();
     649        callback(WOM_DONE, (ULONG)whdr, 0);
     650        wmutex.enter();
    652651
    653652        prevhdr = whdr;
     
    655654    }
    656655
    657     if(wavehdr == NULL) {
    658         //last buffer played -> no new ones -> return now
     656    if (wavehdr == NULL) {
     657        // last buffer played -> no new ones -> return now
    659658        dprintf(("WINMM: WaveOut handler LAST BUFFER PLAYED! state %s (play %d (%d), cop %d, ret %d)", (State == STATE_PLAYING) ? "playing" : "stopped", bytesPlayed, getPosition(), bytesCopied, bytesReturned));
    660         if(getPosition() > bytesPlayed) {
     659        if (getPosition() > bytesPlayed) {
    661660            dprintf(("WINMM: WaveOut handler UNDERRUN! state %s", (State == STATE_PLAYING) ? "playing" : "stopped"));
    662661            //save current position for when we continue later
     
    671670    writeBuffer();
    672671
    673 sendbuffer:
    674672    wmutex.leave();
    675673
     
    677675    dprintf2(("WINMM: handler transfer buffer %d", pBuffer - MixBuffer));
    678676    USHORT selTIB = RestoreOS2FS(); // save current FS selector
    679     MixSetupParms->pmixWrite(MixSetupParms->ulMixHandle, pBuffer, 1);
     677    pmixWriteProc(mixHandle, pBuffer, 1);
    680678    SetFS(selTIB);           // switch back to the saved FS selector
    681679
    682680    dprintf2(("WINMM: handler DONE"));
    683681}
    684 /******************************************************************************/
    685 /******************************************************************************/
     682
     683/******************************************************************************/
     684/******************************************************************************/
     685
    686686void DartWaveOut::writeBuffer()
    687687{
    688688    ULONG buflength;
    689689
    690     if(!fUnderrun && State == STATE_PLAYING && wavehdr == NULL && curFillBuf == curPlayBuf) {
     690    if (!fUnderrun && State == STATE_PLAYING && wavehdr == NULL && curFillBuf == curPlayBuf) {
    691691        dprintf2(("writeBuffer: no more room for more audio data"));
    692692        return; //no room left
    693693    }
    694694
    695     if(curhdr == NULL)
     695    if (curhdr == NULL)
    696696        curhdr = wavehdr;
    697697
    698     while(curhdr && (curhdr->reserved == WHDR_DONE))  {
     698    while (curhdr && (curhdr->reserved == WHDR_DONE))  {
    699699        curhdr = curhdr->lpNext;
    700700    }
    701701
    702     if(curhdr == NULL) {
     702    if (curhdr == NULL)
    703703        return;     //no unprocessed buffers left
    704     }
    705 
    706     if(State == STATE_PLAYING && curFillBuf == curPlayBuf)
     704
     705    if (State == STATE_PLAYING && curFillBuf == curPlayBuf)
    707706    {
    708707        dprintf(("curFillBuf == curPlayBuf; no more room (%d,%d)", curFillBuf, curPlayBuf));
     
    712711    dprintf2(("WINMM: handler cur (%d,%d), fill (%d,%d)\n", curPlayBuf, curPlayPos, curFillBuf, curFillPos));
    713712
    714     while(curhdr) {
     713    while (curhdr) {
    715714        buflength = min((ULONG)MixBuffer[curFillBuf].ulBufferLength - curPlayPos,
    716715                        (ULONG)curhdr->dwBufferLength - curFillPos);
     
    727726        bytesCopied += buflength;
    728727
    729         if(curFillPos == curhdr->dwBufferLength) {
     728        if (curFillPos == curhdr->dwBufferLength) {
    730729            dprintf2(("Buffer %d done ptr %x size %d %x %x %x %x %x %x", curFillBuf, curhdr->lpData, curhdr->dwBufferLength, curhdr->dwBytesRecorded, curhdr->dwUser, curhdr->dwFlags, curhdr->dwLoops, curhdr->lpNext, curhdr->reserved));
    731730
     
    733732            curhdr->reserved = WHDR_DONE;
    734733            //search for next unprocessed buffer
    735             while(curhdr && (curhdr->reserved == WHDR_DONE))
     734            while (curhdr && (curhdr->reserved == WHDR_DONE))
    736735                curhdr = curhdr->lpNext;
    737736        }
    738         if(curPlayPos == MixBuffer[curFillBuf].ulBufferLength) {
     737        if (curPlayPos == MixBuffer[curFillBuf].ulBufferLength) {
    739738            curPlayPos = 0;
    740739
    741             if(++curFillBuf == PREFILLBUF_DART) {
     740            if (++curFillBuf >= ulBufCount)
    742741                curFillBuf = 0;
    743             }
    744             if(curFillBuf == curPlayBuf)
     742
     743            if (curFillBuf == curPlayBuf)
    745744                break;  //no more room left
    746745        }
    747746    }
    748747}
    749 /******************************************************************************/
    750 /******************************************************************************/
     748
     749/******************************************************************************/
     750/******************************************************************************/
     751
    751752LONG APIENTRY WaveOutHandler(ULONG ulStatus,
    752753                             PMCI_MIX_BUFFER pBuffer,
     
    759760
    760761    ptib2 = (PTIB2)_getTIBvalue(offsetof(TIB, tib_ptib2));
    761     if(ptib2 && HIBYTE(ptib2->tib2_ulpri) != PRTYC_TIMECRITICAL &&
     762    if (ptib2 && HIBYTE(ptib2->tib2_ulpri) != PRTYC_TIMECRITICAL &&
    762763       LOBYTE(ptib2->tib2_ulpri) != PRTYD_MAXIMUM)
    763764    {
     
    765766        DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM, 0);
    766767    }
    767     if(pBuffer && pBuffer->ulUserParm)
     768    if (pBuffer && pBuffer->ulUserParm)
    768769    {
    769770        dwave = (DartWaveOut *)pBuffer->ulUserParm;
    770771        dwave->handler(ulStatus, pBuffer, ulFlags);
    771772    }
    772     return(TRUE);
    773 }
    774 
    775 /******************************************************************************/
    776 /******************************************************************************/
    777 MMRESULT DartWaveOut::setVolume(ULONG ulVol)
    778 {
    779   ULONG ulVolR     = (((ulVol & 0xffff0000) >> 16 )*100)/0xFFFF; // Right Volume
    780   ULONG ulVolL      = ((ulVol& 0x0000ffff)*100)/0xFFFF;          // Left Volume
    781   MCI_SET_PARMS msp = {0};
    782 
    783   dprintf(("DartWaveOut::setVolume %d %d", ulVolL, ulVolR));
    784   volume = ulVol;
    785 
    786 // PD: My card (ESS 1868 PnP) driver can't change only
    787 //     one channel Left or Right :-(
    788 //
    789 #ifdef GOOD_AUDIO_CARD_DRIVER
    790 
    791   msp.ulAudio = MCI_SET_AUDIO_LEFT;
    792   msp.ulLevel = ulVolL;
    793 
    794   mymciSendCommand(DeviceId, MCI_SET,
    795                  MCI_WAIT | MCI_SET_AUDIO | MCI_SET_VOLUME,
    796                  &msp, 0);
    797 
    798   msp.ulAudio = MCI_SET_AUDIO_RIGHT;
    799   msp.ulLevel = ulVolR;
    800 
    801 #else
    802   msp.ulAudio = MCI_SET_AUDIO_ALL;
    803   msp.ulLevel = max(ulVolR,ulVolL);
    804 #endif
    805 
    806   mymciSendCommand(DeviceId, MCI_SET,
    807                  MCI_WAIT | MCI_SET_AUDIO | MCI_SET_VOLUME,
    808                  &msp, 0);
    809   return 0;
    810 }
    811 /******************************************************************************/
    812 /******************************************************************************/
    813 
     773    return TRUE;
     774}
     775
     776/******************************************************************************/
     777/******************************************************************************/
     778
Note: See TracChangeset for help on using the changeset viewer.