Ignore:
Timestamp:
Jul 22, 2010, 9:33:17 PM (15 years ago)
Author:
David Azarewicz
Message:

Reintegrate branch into trunk

File:
1 edited

Legend:

Unmodified
Added
Removed
  • OCO/trunk/drv16/wavestrm.cpp

    r486 r526  
    11/* SCCSID = %W% %E% */
    22/****************************************************************************
    3  *                                                                          *
    4  * Copyright (c) IBM Corporation 1994 - 1997.                               *
    5  *                                                                          *
    6  * The following IBM OS/2 source code is provided to you solely for the     *
     3 *                                                                                                                                                      *
     4 * Copyright (c) IBM Corporation 1994 - 1997.                                                           *
     5 *                                                                                                                                                      *
     6 * The following IBM OS/2 source code is provided to you solely for the         *
    77 * the purpose of assisting you in your development of OS/2 device drivers. *
    8  * You may use this code in accordance with the IBM License Agreement       *
    9  * provided in the IBM Device Driver Source Kit for OS/2.                   *
    10  *                                                                          *
     8 * You may use this code in accordance with the IBM License Agreement           *
     9 * provided in the IBM Device Driver Source Kit for OS/2.                                       *
     10 *                                                                                                                                                      *
    1111 ****************************************************************************/
    1212/**@internal %W%
     
    1414 * @version %I%
    1515 * @context Unless otherwise noted, all interfaces are Ring-0, 16-bit,
    16  *  <stack context>.
     16 *      <stack context>.
    1717 * @history
    1818 *
    1919 */
    2020#define INCL_NOPMAPI
    21 #define INCL_DOSERRORS            // for ERROR_INVALID_FUNCTION
     21#define INCL_DOSERRORS                    // for ERROR_INVALID_FUNCTION
    2222#include <os2.h>
    2323#include <os2me.h>
    24 #include <audio.h>                // for #define MIDI
     24#include <audio.h>                                // for #define MIDI
    2525#include <string.h>
    2626#include <include.h>
     
    4242extern "C" ULONG  __cdecl __saveregs OSSIDC_EntryPoint(ULONG cmd, ULONG param1, ULONG param2);
    4343
    44 
    45 //******************************************************************************
    46 //  _vRealignBuffer
    47 //  called just after a wave stream pause on a playback.
    48 //  Gets the end position of the stream when paused and a pointer to a
    49 //  STREAMBUFFER. Basicly this function looks at the streambuffer and if
     44#define SNDRV_PCM_STATE_XRUN 4 /* stream reached an xrun */
     45
     46//******************************************************************************
     47//      _vRealignBuffer
     48//      called just after a wave stream pause on a playback.
     49//      Gets the end position of the stream when paused and a pointer to a
     50//      STREAMBUFFER. Basicly this function looks at the streambuffer and if
    5051// there is any unplayed data in it it adjusts the bufpos counter.
    5152// the donepos counter is ALWAYS set to zero. It will return 0 if all
    5253// the data has been played and 1 if there is still some data left.
    5354//******************************************************************************
    54 USHORT  WAVESTREAM::_vRealignBuffer(ULONG ulEndPos, PSTREAMBUFFER pBuffer)
     55USHORT  WAVESTREAM::_vRealignBuffer(ULONG ulEndPos, PSTREAMBUFFER pBuffer)
    5556{
    5657        if (ulEndPos >= pBuffer->ulDonepos) { /* all of the data has been consumed */
     
    115116                }
    116117
    117                 // if there are buffere on the done queue, pop them off the head and
     118                // if there are buffers on the done queue, pop them off the head and
    118119                // push them on the head of qhTempHead.  This will reorder them so
    119120                // that the more recently used ones will be in the front of the queue.
     
    122123                // be returned) so put it on the Tail of the done queue.
    123124                // If the rc is 1 then put it on the head of the InProcess queue.
    124 
    125125                while (qhDone.IsElements()) {
    126126                        pTempHead->PushOnHead(qhDone.PopHead());
     
    130130                {
    131131                        usRC = _vRealignBuffer(ulEndPos, (PSTREAMBUFFER)pTempHead->Head());
    132                         if (usRC)
     132                        if (usRC) {
    133133                                qhInProcess.PushOnHead(pTempHead->PopHead());
    134                         else
    135                                 qhDone.PushOnTail(pTempHead->PopHead());
     134                        } else {
     135                                qhDone.PushOnHead(pTempHead->PopHead());
     136                        }
    136137                }
    137138                while (qhDone.IsElements()) {
     
    142143                break;
    143144        } /* endswitch */
     145        delete pTempHead; // free the memory
     146}
     147
     148void WAVESTREAM::_vUnderrunStop(PCHAR pchStr)
     149{
     150        if (ulStreamState == STREAM_STOPPED) return;
     151        rprintf(("%s: Underrun-stop", pchStr));
     152        //pahw->SetVolume(StreamId, getMixerStreamId(), 0);
     153        pahw->Stop(StreamId);
     154        ulStreamState = STREAM_STOPPED;
     155        fUnderrun = TRUE;
     156        _ulBytesProcessed = 0;
     157        _ulBytesWritten = 0;
     158}
     159
     160ULONG WAVESTREAM::_vUnderrunStart(void)
     161{
     162        if (ulStreamState == STREAM_STREAMING) return 0;
     163        rprintf(("Underrun-start"));
     164        PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
     165//      if(pahw->ConfigDev(StreamId, &_configinfo, (pTemp) ? pTemp->ulBuffsz : 0) == FALSE) {
     166//              rprintf(("WS::Write: ConfigDev failed"));
     167//              return ERROR_INSUFF_BUFFER;
     168//      }
     169        _configinfo.ulSRatePosition = 0;
     170        // prepare wave device for playback/recording
     171        if(pahw->Prepare(StreamId) == FALSE) {
     172                rprintf(("WS::UR Start: Prepare failed"));
     173                return ERROR_START_STREAM;
     174        }
     175
     176        _ulBytesProcessed = 0;
     177        _ulBytesWritten = 0;
     178        ulStreamState = STREAM_STREAMING;
     179        fUnderrun = FALSE;
     180        //if (ulStreamType == STREAM_WAVE_PLAY) pahw->SetVolume(StreamId, getMixerStreamId(), volume);
     181        return 0;
    144182}
    145183
     
    150188// if this is a write stream call _vFillAudioBuf
    151189//******************************************************************************
     190static short sAddBuffersInProcess = 0;
     191static short sDbgSave;
    152192#pragma off (unreferenced)
    153 void WAVESTREAM::AddBuffers(BOOL fFirst)
     193void WAVESTREAM::AddBuffers(SHORT sFirst)
    154194#pragma on (unreferenced)
    155195{
    156     ULONG ulSpace, ulBytesWritten;
     196        ULONG ulSpace, ulBytesWritten;
    157197        ULONG ulDAZ;
    158 
    159         //dgprintf(("WS:AddBuffers First=%d, SampleSize=%lx", fFirst, _configinfo.ulSampleSize));
    160 
    161     ulBytesWritten = 0;
    162     if (ulStreamType & STREAM_WRITE)
    163     {
    164         // get the space available in the hardware buffer
    165         // only call GetSpace once because the amount of free space in
    166         // the hardware buffer is a moving target and calling it more than once
    167         // could keep us in this loop writing 4 or 8 bytes at a time.
    168         // In extream cases we will stay stuck in this loop long enough to casue a trap rjj
    169                 if (pahw->GetSpace(StreamId, &_configinfo, &ulSpace) == FALSE)
    170         {
    171                         dgprintf(("WAVESTREAM::AddBuffers GetSpace failed"));
    172             return;
    173         }
    174         ulSpace &= (~(_configinfo.ulSampleSize - 1));
     198        ULONG ulStatus;
     199
     200        //dprintf(("WS:AddBuffers First=%d, SampleSize=%lx", sFirst, _configinfo.ulSampleSize));
     201
     202        if (sAddBuffersInProcess) {
     203                // This routine cannot be reentered
     204                // Some systems generate an extra interrupt causing this routine to be reentered
     205                // so we ignore the call that causes us to be reentered
     206                rprintf(("WS::ABS InProcess Now=%x Save=%x", sFirst, sDbgSave));
     207                return;
     208        }
     209        sAddBuffersInProcess++;
     210        sDbgSave = sFirst;
     211
     212        ulBytesWritten = 0;
     213        if (ulStreamType & STREAM_WRITE)
     214        {
     215                // get the space available in the hardware buffer
     216                // only call GetSpace once because the amount of free space in
     217                // the hardware buffer is a moving target and calling it more than once
     218                // could keep us in this loop writing 4 or 8 bytes at a time.
     219                // In extream cases we will stay stuck in this loop long enough to casue a trap rjj
     220                if (pahw->GetSpace(StreamId, &_configinfo, &ulSpace) == FALSE) {
     221                        rprintf(("WS::ABS GetSpace failed"));
     222                        return;
     223                }
     224                ulSpace &= (~(_configinfo.ulSampleSize - 1));
     225#if 1
     226                /* DAZ testing -- underrun detection */
     227                if (ulSpace == 0) {
     228                        OSS16_WaveGetStatus(StreamId, &ulStatus);
     229                        rprintf(("WS::ABS ulSpace=0 state=%lx u32status=%lx", ulStreamState, ulStatus));
     230
     231                        _vUnderrunStop("WS:ABS");
     232                        _vUnderrunStart();
     233
     234                        if (pahw->GetSpace(StreamId, &_configinfo, &ulSpace) == FALSE) {
     235                                rprintf(("WS::ABS GetSpace failed"));
     236                                return;
     237                        }
     238                        ulSpace &= (~(_configinfo.ulSampleSize - 1));
     239                        if (ulSpace ==0) rprintf(("WS::ABS still no space"));
     240                }
     241#endif
    175242                ulDAZ = 0;
    176         while (ulSpace && qhInProcess.IsElements())
    177         {
     243                while (ulSpace && qhInProcess.IsElements())
     244                {
    178245                        if (ulDAZ++ > 20) {
    179                                 dgprintf(("WAVESTREAM::AddBuffers DAZ break")); // Temporary hack to prevent lockups when uniaud32 stops (underrun)
     246                                rprintf(("WS::ABS DAZ break")); // Temporary hack to prevent lockups when uniaud32 stops (underrun)
     247                                int3(); /* should never happen */
    180248                                break;
    181249                        }
    182                 // First time is in task time. For I7 need to give time for interrupt time
    183                 if (fFirst == TRUE)  //PS+++
    184             {
    185                                 //cli();
    186                     DevHelp_ProcBlock (0x5541, 20, 0); // ok since the first call is at task time
    187                 ulBytesWritten = AddBuffer(ulSpace);
    188                                 return;
     250                        ulBytesWritten = AddBuffer(ulSpace);
     251                        if (ulBytesWritten == (ULONG)-1) {
     252                                OSS16_WaveGetStatus(StreamId, &ulStatus);
     253                                rprintf(("WS::ABS AddBuffer returns -1 u32Status=%lx", ulStatus));
     254                                break;
    189255                        }
    190             ulBytesWritten = AddBuffer(ulSpace);
    191             if (ulBytesWritten == (ULONG)-1) break;
    192             ulSpace -= ulBytesWritten;
    193             ulSpace &= ( ~(_configinfo.ulSampleSize - 1));
    194         }
    195 
    196     }
    197 }
    198 
    199 //******************************************************************************
    200 // write one buffer to the audio buffer                                           1
    201 // the caller of this function MUST make sure it ok to write the audio buffer..
    202 // _AudioBufWrite will not check if there is room in the audio buffer of if
    203 // there are buffers on pHead... BEWARE
     256                        ulSpace -= ulBytesWritten;
     257                        ulSpace &= ( ~(_configinfo.ulSampleSize - 1));
     258                }
     259//              if (ulSpace) {
     260//                      dprintf(("WAVESTREAM::AddBuffers done. ulSpace=%lx", ulSpace));
     261//              }
     262        }
     263        sAddBuffersInProcess--;
     264}
     265
     266//******************************************************************************
     267// write one buffer to the audio buffer in uniaud32
    204268//******************************************************************************
    205269ULONG WAVESTREAM::AddBuffer(ULONG ulSpace)
    206270{
    207     PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
    208     ULONG pDataBuf;
    209     ULONG ulBuffLeft;
     271        PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
     272        ULONG pDataBuf;
     273        ULONG ulBuffLeft;
    210274        ULONG ulBytesWritten;
    211 //DAZ   ULONG ulStartPos;
    212 
    213     /* make sure we have a buffer to copy from */
    214     if (!pTemp)
    215     {
    216         return (ULONG)-1;
    217     }
     275
     276        /* make sure we have a buffer to copy from */
     277        if (!pTemp) return (ULONG)-1;
    218278
    219279        /* make sure there is space in the output buffer */
    220     if (!ulSpace)
    221     {
    222         return (ULONG)-1;
    223     }
     280        if (!ulSpace) return (ULONG)-1;
    224281
    225282        /* PS+++ if input buffer is ZERO do nothing and ask for give new buffer, See REMARK in mmpm2.inf */
    226     if (!pTemp->ulBuffsz)
    227     {
    228         qhDone.PushOnTail(qhInProcess.PopHead());
    229         return (ULONG)-1;
    230     }
    231 
    232 /* DAZ */
    233 #if 0
    234     // get the starting position. Call WaveGetHwPtr. if we get a bad rc then we bail out.
    235     if(pahw->GetHwPtr(StreamId, &_configinfo, &ulStartPos) == FALSE)
    236     {
    237         dgprintf(("WAVESTREAM::AddBuffer Err in GetHwPtr"));
    238         DebugInt3();
    239         return (ULONG)-1;
    240     }
    241 #endif
    242 
    243     // get the buffer pointer and amount of data remaining
    244     pDataBuf  = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos; /* points to the beginning of data in src buffer */
    245     ulBuffLeft = pTemp->ulBuffsz - pTemp->ulBuffpos; /* amount of src data left to transfer */
    246     //dgprintf(("WS::AddBuffer buf=%lx remain=%lx, space=%lx bp=%lx dp=%lx size=%lx", pTemp->pBuffptr, ulBuffLeft, ulSpace, pTemp->ulBuffpos, pTemp->ulDonepos, pTemp->ulBuffsz));
    247     ulBuffLeft = min(ulBuffLeft, ulSpace); /* the smaller of src data left or dst space available */
    248 
    249     if (pahw->Transfer(StreamId, &_configinfo, pDataBuf, ulBuffLeft, &ulBytesWritten) == FALSE)
    250     {
     283        if (!pTemp->ulBuffsz) {
     284                qhDone.PushOnTail(qhInProcess.PopHead());
     285                return 0;
     286        }
     287        if (pTemp->ulBuffsz < (_configinfo.ulBytesPerIRQ*2)) {
     288                rprintf(("WS::AB: BufferMode=1"));
     289                usBufferMode = 1;
     290        }
     291
     292        // get the buffer pointer and amount of data remaining
     293        pDataBuf  = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos; /* points to the beginning of data in src buffer */
     294        ulBuffLeft = pTemp->ulBuffsz - pTemp->ulBuffpos; /* amount of src data left to transfer */
     295        //dprintf(("WS::AddBuffer buf=%lx remain=%lx, space=%lx bp=%lx dp=%lx size=%lx", pTemp->pBuffptr, ulBuffLeft, ulSpace, pTemp->ulBuffpos, pTemp->ulDonepos, pTemp->ulBuffsz));
     296        ulBuffLeft = min(ulBuffLeft, ulSpace); /* the smaller of src data left or dst space available */
     297
     298        if (!ulBuffLeft) {
     299                qhDone.PushOnTail(qhInProcess.PopHead());
     300                return 0;
     301        }
     302
     303        if (pahw->Transfer(StreamId, &_configinfo, pDataBuf, ulBuffLeft, &ulBytesWritten) == FALSE) {
    251304                // This could mean that the hardware has underrun TODO: implement underrun logic
    252         dgprintf(("WS::AddBuffer: pahw->Transfer failed"));
    253         return (ULONG)-1;
    254     }
    255     if (ulBytesWritten == 0)
    256     {
     305                rprintf(("WS::AB: pahw->Transfer failed"));
     306                return (ULONG)-1;
     307        }
     308        //dprintf(("WS::AB: %lx of %lx bytes written", ulBytesWritten, ulBuffLeft));
     309        if (ulBytesWritten == 0) {
    257310                // This could mean that the hardware has underrun TODO: implement underrun logic
    258         dgprintf(("WS::AddBuffer: 0 of %lx bytes written by transfer", ulBuffLeft));
    259                 return (ULONG)-1; /* DAZ check into returning zero, returning 0 may cause lockup */
    260     }
    261         //dgprintf(("WS::AddBuffer added %lx from %lx BuffPos=%lx sz=%lx bw=%lx dp=%lx", ulBytesWritten, pTemp->pBuffptr, pTemp->ulBuffpos, pTemp->ulBuffsz, _ulBytesWritten, pTemp->ulDonepos));
     311                //rprintf(("WS::AddBuffer: 0 of %lx bytes written by transfer", ulBuffLeft));
     312                return (ULONG)-1;
     313        }
     314        //dprintf(("WS::AddBuffer added %lx from %lx BuffPos=%lx sz=%lx bw=%lx dp=%lx", ulBytesWritten, pTemp->pBuffptr, pTemp->ulBuffpos, pTemp->ulBuffsz, _ulBytesWritten, pTemp->ulDonepos));
    262315
    263316        _ulBytesWritten += ulBytesWritten; /* update the running counter */
    264     pTemp->ulBuffpos += ulBytesWritten; /* update the buffer pos counter */
    265     pTemp->ulDonepos = _ulBytesWritten; /* update the done Position for returning the buffer */
    266 
    267     // check to see if the whole buffer has been copied and needs to be put on the done queue
    268     if (pTemp->ulBuffpos >= (pTemp->ulBuffsz /* & 0xFFFFFFFC*/)) /* DAZ */
    269     {
    270                 //dgprintf(("WS::AddBuffer done with buffer %lx dp=%lx", pTemp->pBuffptr, pTemp->ulDonepos));
    271         qhDone.PushOnTail(qhInProcess.PopHead());
    272     }
    273     return ulBytesWritten;
     317        pTemp->ulBuffpos += ulBytesWritten; /* update the buffer pos counter */
     318        pTemp->ulDonepos = _ulBytesWritten; /* update the done Position for returning the buffer */
     319
     320        // check to see if the whole buffer has been copied and needs to be put on the done queue
     321        if (pTemp->ulBuffpos >= (pTemp->ulBuffsz /* & 0xFFFFFFFC*/)) /* DAZ */
     322        {
     323                //dprintf(("WS::AddBuffer done with buffer %lx dp=%lx", pTemp->pBuffptr, pTemp->ulDonepos));
     324                qhDone.PushOnTail(qhInProcess.PopHead());
     325        }
     326        return ulBytesWritten;
    274327}
    275328//******************************************************************************
     
    279332BOOL WAVESTREAM::_vReadAudioBuf(void)
    280333{
    281     PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
    282     ULONG pDataBuf;
    283     ULONG ulBuffLeft, ulBytesRead;
    284 
    285     if(!pTemp) return FALSE;
    286 
    287     // get the buffer pointer and amount of data remaining
    288     pDataBuf  = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos;
    289     ulBuffLeft = pTemp->ulBuffsz - pTemp->ulBuffpos;
    290 
    291     // read wave data
    292     if(pahw->Transfer(StreamId, &_configinfo, pDataBuf, ulBuffLeft, &ulBytesRead) == FALSE)
    293     {
    294        return FALSE; /* No more data */
    295     }
    296     if(ulBytesRead == 0) {
    297        return FALSE; /* No more data */
    298     }
     334        PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
     335        ULONG pDataBuf;
     336        ULONG ulBuffLeft, ulBytesRead;
     337
     338        if(!pTemp) return FALSE;
     339
     340        // get the buffer pointer and amount of data remaining
     341        pDataBuf  = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos;
     342        ulBuffLeft = pTemp->ulBuffsz - pTemp->ulBuffpos;
     343
     344        // read wave data
     345        if(pahw->Transfer(StreamId, &_configinfo, pDataBuf, ulBuffLeft, &ulBytesRead) == FALSE)
     346        {
     347           return FALSE; /* No more data */
     348        }
     349        if(ulBytesRead == 0) {
     350           return FALSE; /* No more data */
     351        }
    299352        if (ulBytesRead > ulBuffLeft) {
    300        return FALSE; /* Internal error */
    301         }
    302 
    303     // update the buffer pos counter
    304     pTemp->ulBuffpos  += ulBytesRead;
    305     _ulBytesProcessed += ulBytesRead;
     353           return FALSE; /* Internal error */
     354        }
     355
     356        // update the buffer pos counter
     357        pTemp->ulBuffpos  += ulBytesRead;
     358        _ulBytesProcessed += ulBytesRead;
    306359
    307360        //dprintf(("_vReadAudioBuf %lx Requested=%lx Read=%lx Remain=%lx Processed=%lx", pDataBuf, ulBuffLeft, ulBytesRead, pTemp->ulBuffsz-pTemp->ulBuffpos, _ulBytesProcessed));
    308361
    309     if(pTemp->ulBuffpos == pTemp->ulBuffsz) {
    310         qhDone.PushOnTail(qhInProcess.PopHead());
    311             ReturnBuffer();
    312     }
    313 
    314     return TRUE;
     362        if(pTemp->ulBuffpos == pTemp->ulBuffsz) {
     363                qhDone.PushOnTail(qhInProcess.PopHead());
     364                ReturnBuffer();
     365        }
     366
     367        return TRUE;
    315368}
    316369//******************************************************************************
     
    327380        ULONG ulDAZ;
    328381
    329         //ddprintf(("WAVESTREAM::Process Start"));
    330 
    331     // get the stream position. if we get a bad rc or the position is 0
    332     // then we bail out. Hopefully this will be better next time.
    333     // GetPostiion returns the adjusted hw pointer from the ALSA status ioctl
    334     // This is really a running total of bytes consumed by the hardware.
     382        //dprintf(("WAVESTREAM::Process Start"));
     383
     384        // get the stream position. if we get a bad rc or the position is 0
     385        // then we bail out. Hopefully this will be better next time.
     386        // GetPostiion returns the adjusted hw pointer from the ALSA status ioctl
     387        // This is really a running total of bytes consumed by the hardware.
    335388        // DAZ - Note that this is a 32 bit counter and will wrap at sometime. ALSA
    336389        // attempts to wrap this counter intelligently. I haven't determined what
    337390        // effect, if any, the wrapping of this counter will have playing a stream.
    338     if(pahw->GetPosition(StreamId, &_configinfo, &ulBytes) == FALSE)
    339     {
    340         ddprintf(("Error No bytes processed"));
    341         DebugInt3();
    342         return;
    343     }
    344     _ulBytesProcessed = ulBytes;
    345 
    346     switch (ulStreamType & STREAM_WRITE)
    347     {
    348         case STREAM_WRITE:
    349             if (qhInProcess.IsElements())
    350             {
    351                                 AddBuffers(FALSE);
    352             }
    353                 // Return any buffers that have been completely written to uniaud32
     391        if(pahw->GetPosition(StreamId, &_configinfo, &ulBytes) == FALSE)
     392        {
     393                //dprintf(("Error No bytes processed"));
     394                DebugInt3();
     395                return;
     396        }
     397        _ulBytesProcessed = ulBytes;
     398
     399        switch (ulStreamType & STREAM_WRITE)
     400        {
     401                case STREAM_WRITE:
     402                        if(!qhInProcess.IsElements() && !qhDone.IsElements()) {
     403                                _vUnderrunStop("WS:Process");
     404                                break;
     405                        }
     406                        if (qhInProcess.IsElements()) AddBuffers(1);
     407                        // Return any buffers that have been completely written to uniaud32
     408                        //dprintf(("WS::Process usBufferMode=%x", usBufferMode));
    354409                        while (qhDone.IsElements()) {
    355                 pTemp = (PSTREAMBUFFER)qhDone.Head(); /* get a pointer to the first completed buffer */
     410                                pTemp = (PSTREAMBUFFER)qhDone.Head(); /* get a pointer to the first completed buffer */
    356411                                // Hang on to the last buffer until the hardware is done writing the data
    357412                                // We do this because MMPM uses the return of the last buffer to determine when we are
    358413                                // done playing the stream
    359                                 if ((qhDone.Head() == qhDone.Tail()) && !qhInProcess.IsElements() && (_ulBytesProcessed < pTemp->ulDonepos)) break; /* only one buffer left */
     414                                if ((qhDone.Head() == qhDone.Tail()) && !qhInProcess.IsElements()) {  /* only one buffer left */
     415                                        if (_ulBytesProcessed < pTemp->ulDonepos) break;
     416                                } else { /* not the last buffer */
     417                                        /* if the buffer is bigger than BytesPerIRQ and it's not finished yet, hang on to it */
     418                                        if (!usBufferMode && (_ulBytesProcessed < pTemp->ulDonepos)) break;
     419                                        //if ((_ulBytesProcessed + _configinfo.ulBytesPerIRQ) < pTemp->ulDonepos) break;
     420                                }
    360421                                ReturnBuffer();
    361422                        }
    362                 break;
    363         case STREAM_READ:
     423                        break;
     424                case STREAM_READ:
    364425                        ulDAZ = 0;
    365                     while(_vReadAudioBuf()) {
     426                        while(_vReadAudioBuf()) {
    366427                                if (ulDAZ++ > 20) { /* temporary hack to prevent hangs when uniaud32 stops (overruns) */
    367                                 ddprintf(("WAVESTREAM::Process Read DAZ Break"));
     428                                        rprintf(("WS::Process Read DAZ Break"));
    368429                                        break;
    369430                                }
    370431                        }
    371                     break;
    372         default:
    373             break;
    374     } /* endswitch */
    375 
    376     ProcessEvents();
    377     //ddprintf(("WAVESTREAM::Process End"));
     432                        break;
     433                default:
     434                        break;
     435        } /* endswitch */
     436
     437        ProcessEvents();
     438        //dprintf(("WAVESTREAM::Process End"));
    378439}
    379440//******************************************************************************
     
    383444#pragma on (unreferenced)
    384445{
    385     PSTREAMBUFFER pStreamBuf = new STREAMBUFFER(uLength, pbuf);
    386 
    387     return Write(pStreamBuf);
     446        PSTREAMBUFFER pStreamBuf = new STREAMBUFFER(uLength, pbuf);
     447
     448        return Write(pStreamBuf);
    388449}
    389450//******************************************************************************
     
    391452ULONG WAVESTREAM::Write(PSTREAMBUFFER pStreamBuf)
    392453{
    393     qhInProcess.PushOnTail((PQUEUEELEMENT)pStreamBuf);
    394     //    dprintf2(("WAVESTREAM::Write: Push on tail %lx %ld", ((PSTREAMBUFFER)qhInProcess.Tail())->pBuffptr, ((PSTREAMBUFFER)qhInProcess.Tail())->ulBuffsz));
    395     return 0;
     454
     455#if 1
     456        ULONG ulStatus;
     457
     458        ulStatus = 0;
     459        if (OSS16_WaveGetStatus(StreamId, &ulStatus) != OSSERR_SUCCESS) ulStatus = SNDRV_PCM_STATE_XRUN;
     460        //dprintf(("WS::Write: status=%lx", ulStatus));
     461        if (ulStatus == SNDRV_PCM_STATE_XRUN) {
     462                rprintf(("WS::Write: Xrun detect"));
     463                _vUnderrunStop("WS:Write");
     464                fUnderrun = TRUE;
     465        }
     466#endif
     467        qhInProcess.PushOnTail((PQUEUEELEMENT)pStreamBuf);
     468        if (fUnderrun) {
     469                _vUnderrunStart();
     470                AddBuffers(2);
     471        }
     472        return 0;
    396473}
    397474//******************************************************************************
     
    399476ULONG WAVESTREAM::Read(PSTREAMBUF pbuf, unsigned uLength)
    400477{
    401     qhInProcess.PushOnTail((PQUEUEELEMENT)new STREAMBUFFER(uLength, pbuf));
    402     //dprintf2(("WAVESTREAM::Read: Push on tail %lx %lx", pbuf, uLength));
    403     return 0;
     478        qhInProcess.PushOnTail((PQUEUEELEMENT)new STREAMBUFFER(uLength, pbuf));
     479        //dprintf2(("WAVESTREAM::Read: Push on tail %lx %lx", pbuf, uLength));
     480        return 0;
    404481}
    405482//******************************************************************************
     
    419496ULONG WAVESTREAM::GetCurrentTime()
    420497{
    421     ULONG Seconds, MilliSeconds, Overflow, Processed;
    422 
    423         //PS++ optimize code
    424     Processed = _ulBytesProcessed;
    425     if (ulStreamState == STREAM_STREAMING)  // if the stream is active
    426     {
    427        if (ulStreamType & STREAM_WRITE)
    428        {
    429            if (pahw->GetPosition(StreamId, &_configinfo, &Processed) == FALSE)
    430            {
    431                                 //DebugInt3();
    432                 Processed = _ulBytesProcessed; //last known position
    433            }
    434         }
    435     }
    436 
    437     // if we haven't processed anything then just return _ulTimeBase
    438     if(Processed == 0)
    439         return(_ulTimeBase);
    440 
    441     Seconds  = Processed / _configinfo.ulPCMConsumeRate;
    442     Overflow = Processed - (Seconds * _configinfo.ulPCMConsumeRate);
    443     MilliSeconds = (Overflow * 1000) / _configinfo.ulPCMConsumeRate;
    444     MilliSeconds += (Seconds * 1000);
    445     return (MilliSeconds + _ulTimeBase);
    446 }
    447 //******************************************************************************
    448 //******************************************************************************
    449 ULONG WAVESTREAM::GetCurrentPos(void)
    450 {
    451         ULONG Processed;
     498        ULONG Seconds, MilliSeconds, Overflow, Processed;
    452499
    453500        //PS++ optimize code
    454501        Processed = _ulBytesProcessed;
    455         if (ulStreamState == STREAM_STREAMING)  // if the stream is active
     502        if (ulStreamState == STREAM_STREAMING)  // if the stream is active
     503        {
     504           if (ulStreamType & STREAM_WRITE)
     505           {
     506                   if (pahw->GetPosition(StreamId, &_configinfo, &Processed) == FALSE)
     507                   {
     508                                //DebugInt3();
     509                                Processed = _ulBytesProcessed; //last known position
     510                   }
     511                }
     512        }
     513
     514        // if we haven't processed anything then just return _ulTimeBase
     515        if(Processed == 0)
     516                return(_ulTimeBase);
     517
     518        Seconds  = Processed / _configinfo.ulPCMConsumeRate;
     519        Overflow = Processed - (Seconds * _configinfo.ulPCMConsumeRate);
     520        MilliSeconds = (Overflow * 1000) / _configinfo.ulPCMConsumeRate;
     521        MilliSeconds += (Seconds * 1000);
     522        return (MilliSeconds + _ulTimeBase);
     523}
     524//******************************************************************************
     525//******************************************************************************
     526ULONG WAVESTREAM::GetCurrentPos(void)
     527{
     528        ULONG Processed;
     529
     530        //PS++ optimize code
     531        Processed = _ulBytesProcessed;
     532        if (ulStreamState == STREAM_STREAMING)  // if the stream is active
    456533        {
    457534                if (ulStreamType & STREAM_WRITE)
     
    478555   if(!pTemp)
    479556   {
    480        pTemp = (PSTREAMBUFFER)qhInProcess.Head();
     557           pTemp = (PSTREAMBUFFER)qhInProcess.Head();
    481558   }
    482559   if(pTemp)
    483560   {
    484        writepos = pTemp->ulBuffpos;
     561           writepos = pTemp->ulBuffpos;
    485562   }
    486563   sti();
     
    495572void  WAVESTREAM::SetCurrentTime(ULONG time)
    496573{
    497         //ddprintf(("SetCurrentTime: %lx", time));
    498     _ulTimeBase = time;
     574        //dprintf(("SetCurrentTime: %lx", time));
     575        _ulTimeBase = time;
    499576}
    500577//******************************************************************************
     
    502579ULONG WAVESTREAM::StartStream()
    503580{
    504     PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
    505 
    506     if(ulStreamState == STREAM_STREAMING)
    507     {
    508         ddprintf(("StartStream: already playing!!"));
    509         return NO_ERROR;
    510     }
    511 
    512     // configure the wave device
    513     // (NOTE: Must call this function; sample rate position is reset there)
    514     if(pahw->ConfigDev(StreamId, &_configinfo, (pTemp) ? pTemp->ulBuffsz : 0) == FALSE)
    515     {
    516         ddprintf(("StartStream: ConfigDev failed!!"));
    517         return ERROR_INSUFF_BUFFER;
     581        PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
     582
     583        if(ulStreamState == STREAM_STREAMING)
     584        {
     585                //dprintf(("StartStream: already playing!!"));
     586                return NO_ERROR;
     587        }
     588
     589        // configure the wave device
     590        // (NOTE: Must call this function; sample rate position is reset there)
     591        if(pahw->ConfigDev(StreamId, &_configinfo, (pTemp) ? pTemp->ulBuffsz : 0) == FALSE)
     592        {
     593                rprintf(("StartStream: ConfigDev failed!!"));
     594                return ERROR_INSUFF_BUFFER;
    518595                //goto fail;
    519     }
    520     // prepare wave device for playback/recording
    521     if(pahw->Prepare(StreamId) == FALSE)
    522     {
    523         ddprintf(("StartStream: Prepare failed!!"));
    524         goto fail;
    525     }
    526 
    527     _ulBytesProcessed = 0;
     596        }
     597        // prepare wave device for playback/recording
     598        if(pahw->Prepare(StreamId) == FALSE)
     599        {
     600                rprintf(("StartStream: Prepare failed!!"));
     601                goto fail;
     602        }
     603
     604        _ulBytesProcessed = 0;
    528605        _ulBytesWritten = 0;
    529 
    530     ulStreamState = STREAM_STREAMING;
    531     //Adding the first buffer also starts playback
    532     if (ulStreamType == STREAM_WAVE_PLAY)
    533     {
    534                 pahw->SetVolume(StreamId, getMixerStreamId(), volume);    //PS
    535                 AddBuffers(TRUE);
    536         //Must set volume after adding buffers (voices inside sblive driver might not
    537         //be allocated otherwise (first start) )
    538 //        dprintf(("SetVolume %lx",volume));
    539 // PS, removing to high
    540 //      pahw->SetVolume(StreamId, getMixerStreamId(), volume);
    541     }
    542     else
    543     {
    544         //dprintf(("Starting Rec Stream"));
    545         ulSavedInputGain = pahw->QueryVolume(StreamId, getMixerStreamId());
    546         pahw->SetInputSrc(StreamId, getMixerStreamId(), inputsrc);
    547         pahw->SetVolume(StreamId, getMixerStreamId(), inputgain);
     606        fUnderrun = FALSE;
     607        usBufferMode = 0;
     608
     609        ulStreamState = STREAM_STREAMING;
     610        //Adding the first buffer also starts playback
     611        if (ulStreamType == STREAM_WAVE_PLAY)
     612        {
     613                //DAZ moved from AddBuffers, for I7, might not be needed
     614                //DevHelp_ProcBlock (0x5541, 20, 0);
     615                pahw->SetVolume(StreamId, getMixerStreamId(), volume);    //PS
     616                AddBuffers(3);
     617        }
     618        else
     619        {
     620                //dprintf(("Starting Rec Stream"));
     621                ulSavedInputGain = pahw->QueryVolume(StreamId, getMixerStreamId());
     622                pahw->SetInputSrc(StreamId, getMixerStreamId(), inputsrc);
     623                pahw->SetVolume(StreamId, getMixerStreamId(), inputgain);
    548624
    549625                if(pahw->Start(StreamId) != TRUE)
    550626                {
    551             dprintf(("pahw->Start failed!!"));
    552             goto fail;
    553         }
    554     }
    555     return NO_ERROR;
     627                        rprintf(("pahw->Start failed!!"));
     628                        goto fail;
     629                }
     630        }
     631        return NO_ERROR;
    556632
    557633fail:
    558     DebugInt3();
    559     return ERROR_START_STREAM;
     634        DebugInt3();
     635        return ERROR_START_STREAM;
    560636}
    561637//******************************************************************************
     
    563639ULONG WAVESTREAM::StopStream(PCONTROL_PARM pControl)
    564640{
    565     if(ulStreamState == STREAM_STOPPED) {
    566         dprintf(("WAVESTREAM::StopStream %lx (already stopped)", StreamId));
    567             pControl->ulTime = GetCurrentTime();
    568             return NO_ERROR;
    569     }
    570     //silence wave stream before stopping it (removes clicks)
    571     if(ulStreamType == STREAM_WAVE_PLAY) {
    572         pahw->SetVolume(StreamId, getMixerStreamId(), 0);
    573     }
    574     else {
    575         pahw->SetVolume(StreamId, getMixerStreamId(), ulSavedInputGain);
    576     }
    577     pahw->Stop(StreamId);
    578 
    579     ulStreamState = STREAM_STOPPED;
    580         //ddprintf(("WAVESTREAM::StopStream %lx", StreamId));
    581 
    582     ReturnBuffers();
    583     pControl->ulTime = GetCurrentTime();
    584 
    585     // We need to set _ulBytesProcessed to 0 here. if we do not
    586     // and MMPM restarts the stream by sending a DDCMD_SETUP followed By
    587     // DDCMD_ENABLE_EVENT the event time will get screwed up. rjj
    588     _ulBytesProcessed = 0;
     641        if(ulStreamState == STREAM_STOPPED) {
     642                //dprintf(("WS::StopStream %lx (already stopped)", StreamId));
     643                fUnderrun = FALSE;
     644                pControl->ulTime = GetCurrentTime();
     645                return NO_ERROR;
     646        }
     647        //silence wave stream before stopping it (removes clicks)
     648        if(ulStreamType == STREAM_WAVE_PLAY) {
     649                pahw->SetVolume(StreamId, getMixerStreamId(), 0);
     650        }
     651        else {
     652                pahw->SetVolume(StreamId, getMixerStreamId(), ulSavedInputGain);
     653        }
     654        pahw->Stop(StreamId);
     655
     656        ulStreamState = STREAM_STOPPED;
     657        fUnderrun = FALSE;
     658        //dprintf(("WAVESTREAM::StopStream %lx", StreamId));
     659
     660        ReturnBuffers();
     661        pControl->ulTime = GetCurrentTime();
     662
     663        // We need to set _ulBytesProcessed to 0 here. if we do not
     664        // and MMPM restarts the stream by sending a DDCMD_SETUP followed By
     665        // DDCMD_ENABLE_EVENT the event time will get screwed up. rjj
     666        _ulBytesProcessed = 0;
    589667        _ulBytesWritten = 0;
    590     return NO_ERROR;
     668        return NO_ERROR;
    591669}
    592670//******************************************************************************
     
    594672ULONG  WAVESTREAM::PauseStream(PCONTROL_PARM pControl)
    595673{
    596     ULONG ulEndPos, ulEndPos2;
    597 
    598     if(ulStreamState == STREAM_PAUSED) {
    599         dprintf(("WAVESTREAM::PauseStream %lx (already paused)", StreamId));
    600             pControl->ulTime = GetCurrentTime();
    601             return NO_ERROR;
    602     }
    603 
    604     pahw->GetPosition(StreamId, &_configinfo, &ulEndPos);
    605     //silence wave stream before stopping it (removes clicks)
    606     pahw->SetVolume(StreamId, getMixerStreamId(), 0);
    607     pahw->Stop(StreamId);
    608 
     674        ULONG ulEndPos;
     675
     676        if(ulStreamState == STREAM_PAUSED) {
     677                dprintf(("WS::PauseStream %lx (already paused)", StreamId));
     678                fUnderrun = FALSE;
     679                pControl->ulTime = GetCurrentTime();
     680                return NO_ERROR;
     681        }
     682
     683        pahw->GetPosition(StreamId, &_configinfo, &ulEndPos);
     684        //silence wave stream before stopping it (removes clicks)
     685        pahw->SetVolume(StreamId, getMixerStreamId(), 0);
     686        pahw->Stop(StreamId);
     687
     688#if 0
    609689        /* DAZ test code begin */
    610     if (pahw->GetPosition(StreamId, &_configinfo, &ulEndPos2) == FALSE) ulEndPos2 = 0;
     690        if (pahw->GetPosition(StreamId, &_configinfo, &ulEndPos2) == FALSE) ulEndPos2 = 0;
    611691        if (ulEndPos2 != ulEndPos) {
    612             ddprintf(("WAVESTREAM::PauseStream %lx!=%lx", ulEndPos, ulEndPos2));
     692                dprintf(("WS::PauseStream %lx!=%lx", ulEndPos, ulEndPos2));
    613693                if (ulEndPos2) ulEndPos = ulEndPos2;
    614694        }
    615695        /* DAZ test code end */
    616 
    617     ulStreamState = STREAM_PAUSED;
    618 
    619     ddprintf(("WAVESTREAM::PauseStream %lx", StreamId));
    620 
    621     _ulBytesProcessed = ulEndPos;
    622 
    623     _vRealignPausedBuffers(ulEndPos);
    624 
    625     pControl->ulTime = GetCurrentTime();
    626 
    627     _ulBytesProcessed = 0;
     696#endif
     697
     698        ulStreamState = STREAM_PAUSED;
     699
     700        dprintf(("WS::PauseStream %lx", StreamId));
     701
     702        _ulBytesProcessed = ulEndPos;
     703
     704        _vRealignPausedBuffers(ulEndPos);
     705
     706        pControl->ulTime = GetCurrentTime();
     707
     708        _ulBytesProcessed = 0;
    628709        _ulBytesWritten = 0;
    629 
    630     return NO_ERROR;
     710        fUnderrun = FALSE;
     711
     712        return NO_ERROR;
    631713}
    632714//******************************************************************************
     
    634716ULONG  WAVESTREAM::ResumeStream(void)
    635717{
    636 #ifdef DEBUG
    637     //dprintf(("WAVESTREAM::ResumeStream %lx", StreamId));
    638 #endif
    639     return StartStream();
     718        //dprintf(("WAVESTREAM::ResumeStream %lx", StreamId));
     719        return StartStream();
    640720}
    641721//******************************************************************************
     
    643723BOOL WAVESTREAM::SetProperty(int type, ULONG value, ULONG reserved)
    644724{
    645     switch(type) {
    646     case PROPERTY_VOLUME:
    647         volume = value;
    648         dprintf(("WAVESTREAM::SetProperty() Vol: %0lx",value));
    649         if(ulStreamState == STREAM_STREAMING && ulStreamType == STREAM_WAVE_PLAY) {
    650             MixerSetWaveVolume(getMixerStreamId(), StreamId, volume);
    651         }
    652         break;
    653 
    654     case PROPERTY_INPUTSRC:
    655         inputsrc = value;
    656         break;
    657 
    658     case PROPERTY_INPUTGAIN:
    659         inputgain = value;
    660         break;
    661 
    662     default:
    663         return STREAM::SetProperty(type, value, reserved);
    664     }
    665     return TRUE;
     725        switch(type) {
     726        case PROPERTY_VOLUME:
     727                volume = value;
     728                dprintf(("WS::SetProperty() Vol: %0lx",value));
     729                if(ulStreamState == STREAM_STREAMING && ulStreamType == STREAM_WAVE_PLAY) {
     730                        MixerSetWaveVolume(getMixerStreamId(), StreamId, volume);
     731                }
     732                break;
     733
     734        case PROPERTY_INPUTSRC:
     735                inputsrc = value;
     736                break;
     737
     738        case PROPERTY_INPUTGAIN:
     739                inputgain = value;
     740                break;
     741
     742        default:
     743                return STREAM::SetProperty(type, value, reserved);
     744        }
     745        return TRUE;
    666746}
    667747//******************************************************************************
     
    669749ULONG WAVESTREAM::GetProperty(int type)
    670750{
    671     switch(type) {
    672     case PROPERTY_FREQUENCY:
    673        return _configinfo.ulSampleRate;
    674 
    675     case PROPERTY_INPUTSRC:
    676        return inputsrc;
    677 
    678     case PROPERTY_INPUTGAIN:
    679        return inputgain;
    680 
    681     default:
    682        return STREAM::GetProperty(type);
    683     }
     751        switch(type) {
     752        case PROPERTY_FREQUENCY:
     753           return _configinfo.ulSampleRate;
     754
     755        case PROPERTY_INPUTSRC:
     756           return inputsrc;
     757
     758        case PROPERTY_INPUTGAIN:
     759           return inputgain;
     760
     761        default:
     762           return STREAM::GetProperty(type);
     763        }
    684764}
    685765//******************************************************************************
     
    688768   STREAM(streamtype, filesysnum, mixerStreamId)
    689769{
    690     // get the pointer to the hardware object
    691     pahw = (WAVEAUDIO*)GetHardwareDevice(streamtype);
    692 
    693     _fmemset(&_configinfo, 0, sizeof(_configinfo));
    694     _configinfo.ulSampleRate    = pinit->lSRate;
    695     _configinfo.ulBitsPerSample = pinit->lBitsPerSRate;
    696     _configinfo.ulNumChannels   = pinit->sChannels;
    697     _configinfo.ulDataType      = pinit->sMode;
    698     _ulBytesWritten             = 0;
    699     _ulBytesProcessed           = 0;
    700     _ulTimeBase                 = 0;
    701     ulSavedInputGain            = 0;
    702 
    703     _configinfo.pConversionBuffer  = 0;
    704     pahw->SetupConversion(&_configinfo, pinit->ulOperation, pinit->sMode, pinit->sChannels, pinit->lBitsPerSRate);
    705 
    706     if(_configinfo.usConversion != CONVERT_NONE)
    707     {//allocate conversion buffer
    708         PVOID pSelOff;
    709         LIN   linAddr;
    710 
    711         if(DevHelp_VMAlloc((VMDHA_FIXED | VMDHA_CONTIG), CONVERSION_BUFFER_SIZE, (ULONG)-1L, &linAddr, &pSelOff) != 0)
    712         {
    713              dgprintf(("Error in DevHelp_VMAlloc Conversion Buffer"));
    714              DebugInt3(); //should never happen!!
    715              _configinfo.usConversion = CONVERT_NONE;
    716         }
    717         else _configinfo.pConversionBuffer = linAddr;
    718     }
    719     if(_configinfo.fSampleRateConversion == TRUE)
    720     {//allocate buffer for sample rate conversion
    721         PVOID pSelOff;
    722         LIN   linAddr;
    723 
    724         if (DevHelp_VMAlloc((VMDHA_FIXED | VMDHA_CONTIG), CONVERSION_BUFFER_SIZE, (ULONG)-1L, &linAddr, &pSelOff) != 0)
    725         {
    726             dgprintf(("Error in DevHelp_VMAlloc SR Conversion Buffer"));
    727             DebugInt3(); //should never happen!!
    728         }
    729         else _configinfo.pSRateConvBuffer = linAddr;
    730     }
    731 
    732     pinit->ulFlags |= pahw->QueryDataFlags(pinit->ulOperation, pinit->sMode, pinit->lBitsPerSRate);
    733 
    734     StreamId    = 0;
    735 
    736     if(pahw->Open(current_device, ulStreamType, ulSysFileNum, &StreamId) != TRUE)
    737     {
    738         dprintf(("pahw->Open failed!!"));
    739         DebugInt3();
    740     }
     770        // get the pointer to the hardware object
     771        pahw = (WAVEAUDIO*)GetHardwareDevice(streamtype);
     772
     773        _fmemset(&_configinfo, 0, sizeof(_configinfo));
     774        _configinfo.ulSampleRate        = pinit->lSRate;
     775        _configinfo.ulBitsPerSample = pinit->lBitsPerSRate;
     776        _configinfo.ulNumChannels       = pinit->sChannels;
     777        _configinfo.ulDataType          = pinit->sMode;
     778        _ulBytesWritten                         = 0;
     779        _ulBytesProcessed                       = 0;
     780        _ulTimeBase                             = 0;
     781        ulSavedInputGain                        = 0;
     782        fUnderrun = FALSE;
     783        usBufferMode = 0;
     784
     785        _configinfo.pConversionBuffer  = 0;
     786        pahw->SetupConversion(&_configinfo, pinit->ulOperation, pinit->sMode, pinit->sChannels, pinit->lBitsPerSRate);
     787
     788        if(_configinfo.usConversion != CONVERT_NONE)
     789        {//allocate conversion buffer
     790                PVOID pSelOff;
     791                LIN   linAddr;
     792
     793                if(DevHelp_VMAlloc((VMDHA_FIXED | VMDHA_CONTIG), CONVERSION_BUFFER_SIZE, (ULONG)-1L, &linAddr, &pSelOff) != 0)
     794                {
     795                         rprintf(("Error in DevHelp_VMAlloc Conversion Buffer"));
     796                         DebugInt3(); //should never happen!!
     797                         _configinfo.usConversion = CONVERT_NONE;
     798                }
     799                else _configinfo.pConversionBuffer = linAddr;
     800        }
     801        if(_configinfo.fSampleRateConversion == TRUE)
     802        {//allocate buffer for sample rate conversion
     803                PVOID pSelOff;
     804                LIN   linAddr;
     805
     806                if (DevHelp_VMAlloc((VMDHA_FIXED | VMDHA_CONTIG), CONVERSION_BUFFER_SIZE, (ULONG)-1L, &linAddr, &pSelOff) != 0)
     807                {
     808                        rprintf(("Error in DevHelp_VMAlloc SR Conversion Buffer"));
     809                        DebugInt3(); //should never happen!!
     810                }
     811                else _configinfo.pSRateConvBuffer = linAddr;
     812        }
     813
     814        pinit->ulFlags |= pahw->QueryDataFlags(pinit->ulOperation, pinit->sMode, pinit->lBitsPerSRate);
     815
     816        StreamId        = 0;
     817
     818        if(pahw->Open(current_device, ulStreamType, ulSysFileNum, &StreamId) != TRUE)
     819        {
     820                rprintf(("pahw->Open failed!!"));
     821                DebugInt3();
     822        }
    741823
    742824        //dprintf(("WAVESTREAM stream %lx ctor %lx: rate %d bps %d numchan %d type %x", hstream, StreamId, (USHORT)_configinfo.ulSampleRate, (USHORT)_configinfo.ulBitsPerSample, (USHORT)_configinfo.ulNumChannels, (USHORT)_configinfo.ulNumChannels, (USHORT)_configinfo.ulDataType));
     
    747829{
    748830        //dprintf(("WAVESTREAM stream %x dtor %lx", hstream, StreamId));
    749     if(_configinfo.pConversionBuffer) {
    750         if(DevHelp_VMFree(_configinfo.pConversionBuffer) != 0) {
    751             DebugInt3();
    752         }
    753     }
    754     if(_configinfo.pSRateConvBuffer) {
    755         if(DevHelp_VMFree(_configinfo.pSRateConvBuffer) != 0) {
    756             DebugInt3();
    757         }
    758     }
    759     if(pahw) {
    760         if (ulStreamState == STREAM_STREAMING)
    761            pahw->Stop(StreamId);
    762 
    763         pahw->Close(StreamId);
    764         StreamId = 0;
    765     }
    766 }
    767 //******************************************************************************
    768 //******************************************************************************
    769 
     831        if(_configinfo.pConversionBuffer) {
     832                if(DevHelp_VMFree(_configinfo.pConversionBuffer) != 0) {
     833                        DebugInt3();
     834                }
     835        }
     836        if(_configinfo.pSRateConvBuffer) {
     837                if(DevHelp_VMFree(_configinfo.pSRateConvBuffer) != 0) {
     838                        DebugInt3();
     839                }
     840        }
     841        if(pahw) {
     842                if (ulStreamState == STREAM_STREAMING)
     843                   pahw->Stop(StreamId);
     844
     845                pahw->Close(StreamId);
     846                StreamId = 0;
     847        }
     848}
     849//******************************************************************************
     850//******************************************************************************
     851
Note: See TracChangeset for help on using the changeset viewer.