⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pa_win_wmme.c

📁 IAX client库, 一个VOIP的库. 支持H.323和SIP, PBX就是采用的它
💻 C
📖 第 1 页 / 共 5 页
字号:
        /* Use an input buffer if one is available. */        gotInput = 0;        inBufPtr = NULL;        if( ( stream->past_NumInputChannels > 0 ) &&                (wmmeStreamData->inputBuffers[ wmmeStreamData->currentInputBuffer ].dwFlags & WHDR_DONE) )        {            inBufPtr = wmmeStreamData->inputBuffers[ wmmeStreamData->currentInputBuffer ].lpData;            gotInput = 1;#if PA_TRACE_RUN            AddTraceMessage("Pa_TimeSlice: got input buffer at ", (int)inBufPtr );            AddTraceMessage("Pa_TimeSlice: got input buffer # ", wmmeStreamData->currentInputBuffer );#endif        }        /* If we can't do anything then bail out. */        if( !gotInput && !gotOutput ) break;        buffersProcessed += 1;        /* Each Wave buffer contains multiple user buffers so do them all now. */        /* Base Usage on time it took to process one host buffer. */        Pa_StartUsageCalculation( stream );        for( i=0; i<wmmeStreamData->userBuffersPerHostBuffer; i++ )        {            if( done )            {                if( gotOutput )                {                    /* Clear remainder of wave buffer if we are waiting for stop. */                    AddTraceMessage("Pa_TimeSlice: zero rest of wave buffer ", i );                    memset( outBufPtr, 0, wmmeStreamData->bytesPerUserOutputBuffer );                }            }            else            {                /* Convert 16 bit native data to user data and call user routine. */                result = Pa_CallConvertInt16( stream, (short *) inBufPtr, (short *) outBufPtr );                if( result != 0) done = 1;            }            if( gotInput ) inBufPtr += wmmeStreamData->bytesPerUserInputBuffer;            if( gotOutput) outBufPtr += wmmeStreamData->bytesPerUserOutputBuffer;        }        Pa_EndUsageCalculation( stream );        /* Send WAVE buffer to Wave Device to be refilled. */        if( gotInput )        {            mmresult = waveInAddBuffer( wmmeStreamData->hWaveIn,                                       &wmmeStreamData->inputBuffers[ wmmeStreamData->currentInputBuffer ],                                       sizeof(WAVEHDR) );            if( mmresult != MMSYSERR_NOERROR )            {                sPaHostError = mmresult;                result = paHostError;                break;            }            wmmeStreamData->currentInputBuffer = (wmmeStreamData->currentInputBuffer+1 >= wmmeStreamData->numHostBuffers) ?                                              0 : wmmeStreamData->currentInputBuffer+1;        }        /* Write WAVE buffer to Wave Device. */        if( gotOutput )        {#if PA_TRACE_START_STOP            AddTraceMessage( "Pa_TimeSlice: writing buffer ", wmmeStreamData->currentOutputBuffer );#endif            mmresult = waveOutWrite( wmmeStreamData->hWaveOut,                                    &wmmeStreamData->outputBuffers[ wmmeStreamData->currentOutputBuffer ],                                    sizeof(WAVEHDR) );            if( mmresult != MMSYSERR_NOERROR )            {                sPaHostError = mmresult;                result = paHostError;                break;            }            wmmeStreamData->currentOutputBuffer = (wmmeStreamData->currentOutputBuffer+1 >= wmmeStreamData->numHostBuffers) ?                                               0 : wmmeStreamData->currentOutputBuffer+1;        }    }#if PA_TRACE_RUN    AddTraceMessage("Pa_TimeSlice: buffersProcessed ", buffersProcessed );#endif    return (result != 0) ? result : done;}/*******************************************************************/static PaError PaHost_BackgroundManager( internalPortAudioStream *stream ){    PaError      result = paNoError;    int          i;    int          numQueuedoutputBuffers = 0;    PaWMMEStreamData *wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;    /* Has someone asked us to abort by calling Pa_AbortStream()? */    if( stream->past_StopNow )    {        stream->past_IsActive = 0; /* Will cause thread to return. */    }    /* Has someone asked us to stop by calling Pa_StopStream()     * OR has a user callback returned '1' to indicate finished.     */    else if( stream->past_StopSoon )    {        /* Poll buffer and when all have played then exit thread. */        /* Count how many output buffers are queued. */        numQueuedoutputBuffers = 0;        if( stream->past_NumOutputChannels > 0 )        {            for( i=0; i<wmmeStreamData->numHostBuffers; i++ )            {                if( !( wmmeStreamData->outputBuffers[ i ].dwFlags & WHDR_DONE) )                {#if PA_TRACE_START_STOP                    AddTraceMessage( "PaHost_BackgroundManager: waiting for buffer ", i );#endif                    numQueuedoutputBuffers++;                }            }        }#if PA_TRACE_START_STOP        AddTraceMessage( "PaHost_BackgroundManager: numQueuedoutputBuffers ", numQueuedoutputBuffers );#endif        if( numQueuedoutputBuffers == 0 )        {            stream->past_IsActive = 0; /* Will cause thread to return. */        }    }    else    {        /* Process full input buffer and fill up empty output buffers. */        if( (result = Pa_TimeSlice( stream )) != 0)        {            /* User callback has asked us to stop. */#if PA_TRACE_START_STOP            AddTraceMessage( "PaHost_BackgroundManager: TimeSlice() returned ", result );#endif            stream->past_StopSoon = 1; /* Request that audio play out then stop. */            result = paNoError;        }    }    PaHost_UpdateStreamTime( wmmeStreamData );    return result;}#if PA_USE_TIMER_CALLBACK/*******************************************************************/static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2){    internalPortAudioStream   *stream;    PaWMMEStreamData        *wmmeStreamData;    PaError                    result;    stream = (internalPortAudioStream *) dwUser;    if( stream == NULL ) return;    wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;    if( wmmeStreamData == NULL ) return;    if( wmmeStreamData->ifInsideCallback )    {        if( wmmeStreamData->timerID != 0 )        {            timeKillEvent(wmmeStreamData->timerID);  /* Stop callback timer. */            wmmeStreamData->timerID = 0;        }        return;    }    wmmeStreamData->ifInsideCallback = 1;    /* Manage flags and audio processing. */    result = PaHost_BackgroundManager( stream );    if( result != paNoError )    {        stream->past_IsActive = 0;    }    wmmeStreamData->ifInsideCallback = 0;}#else /* PA_USE_TIMER_CALLBACK *//*******************************************************************/static DWORD WINAPI WinMMPa_OutputThreadProc( void *pArg ){    internalPortAudioStream *stream;    PaWMMEStreamData      *wmmeStreamData;    HANDLE       events[2];    int          numEvents = 0;    DWORD        result = 0;    DWORD        waitResult;    DWORD        numTimeouts = 0;    DWORD        timeOut;    stream = (internalPortAudioStream *) pArg;    wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;#if PA_TRACE_START_STOP    AddTraceMessage( "WinMMPa_OutputThreadProc: timeoutPeriod", timeoutPeriod );    AddTraceMessage( "WinMMPa_OutputThreadProc: past_NumUserBuffers", stream->past_NumUserBuffers );#endif    /* Calculate timeOut as half the time it would take to play all buffers. */    timeOut = (DWORD) (500.0 * PaHost_GetTotalBufferFrames( stream ) / stream->past_SampleRate);    /* Get event(s) ready for wait. */    events[numEvents++] = wmmeStreamData->bufferEvent;    if( wmmeStreamData->abortEventInited ) events[numEvents++] = wmmeStreamData->abortEvent;    /* Stay in this thread as long as we are "active". */    while( stream->past_IsActive )    {        /*******************************************************************/        /******** WAIT here for an event from WMME or PA *******************/        /*******************************************************************/        waitResult = WaitForMultipleObjects( numEvents, events, FALSE, timeOut );        /* Error? */        if( waitResult == WAIT_FAILED )        {            sPaHostError = GetLastError();            result = paHostError;            stream->past_IsActive = 0;        }        /* Timeout? Don't stop. Just keep polling for DONE.*/        else if( waitResult == WAIT_TIMEOUT )        {#if PA_TRACE_START_STOP            AddTraceMessage( "WinMMPa_OutputThreadProc: timed out ", numQueuedoutputBuffers );#endif            numTimeouts += 1;        }        /* Manage flags and audio processing. */        result = PaHost_BackgroundManager( stream );        if( result != paNoError )        {            stream->past_IsActive = 0;        }    }    return result;}#endif/*******************************************************************/PaError PaHost_OpenInputStream( internalPortAudioStream   *stream ){    PaError          result = paNoError;    MMRESULT         mmresult;    PaWMMEStreamData *wmmeStreamData;    int              i;    int              inputMmId;    int              bytesPerInputFrame;    WAVEFORMATEX     wfx;    const PaDeviceInfo  *deviceInfo;    wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;    DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", stream->past_InputDeviceID));    deviceInfo = Pa_GetDeviceInfo( stream->past_InputDeviceID );    if( deviceInfo == NULL ) return paInternalError;    switch( deviceInfo->nativeSampleFormats  )    {    case paInt32:    case paFloat32:        bytesPerInputFrame = sizeof(float) * stream->past_NumInputChannels;        break;    default:        bytesPerInputFrame = sizeof(short) * stream->past_NumInputChannels;        break;    }    wfx.wFormatTag = WAVE_FORMAT_PCM;    wfx.nChannels = (WORD) stream->past_NumInputChannels;    wfx.nSamplesPerSec = (DWORD) stream->past_SampleRate;    wfx.nAvgBytesPerSec = (DWORD)(bytesPerInputFrame * stream->past_SampleRate);    wfx.nBlockAlign = (WORD)bytesPerInputFrame;    wfx.wBitsPerSample = (WORD)((bytesPerInputFrame/stream->past_NumInputChannels) * 8);    wfx.cbSize = 0;    inputMmId = PaDeviceIdToWinId( stream->past_InputDeviceID );#if PA_USE_TIMER_CALLBACK    mmresult = waveInOpen( &wmmeStreamData->hWaveIn, inputMmId, &wfx,                     0, 0, CALLBACK_NULL );#else    mmresult = waveInOpen( &wmmeStreamData->hWaveIn, inputMmId, &wfx,                     (DWORD)wmmeStreamData->bufferEvent, (DWORD) stream, CALLBACK_EVENT );#endif    if( mmresult != MMSYSERR_NOERROR )    {        ERR_RPT(("PortAudio: PaHost_OpenInputStream() failed!\n"));        result = paHostError;        sPaHostError = mmresult;        goto error;    }    /* Allocate an array to hold the buffer pointers. */    wmmeStreamData->inputBuffers = (WAVEHDR *) PaHost_AllocateTrackedMemory( sizeof(WAVEHDR)*wmmeStreamData->numHostBuffers ); /* MEM */    if( wmmeStreamData->inputBuffers == NULL )    {        result = paInsufficientMemory;        goto error;    }    /* Allocate each buffer. */    for( i=0; i<wmmeStreamData->numHostBuffers; i++ )    {        wmmeStreamData->inputBuffers[i].lpData = (char *)PaHost_AllocateTrackedMemory( wmmeStreamData->bytesPerHostInputBuffer ); /* MEM */        if( wmmeStreamData->inputBuffers[i].lpData == NULL )        {            result = paInsufficientMemory;            goto error;        }        wmmeStreamData->inputBuffers[i].dwBufferLength = wmmeStreamData->bytesPerHostInputBuffer;        wmmeStreamData->inputBuffers[i].dwUser = i;        if( ( mmresult = waveInPrepareHeader( wmmeStreamData->hWaveIn, &wmmeStreamData->inputBuffers[i], sizeof(WAVEHDR) )) != MMSYSERR_NOERROR )        {            result = paHostError;            sPaHostError = mmresult;            goto error;        }    }    return result;error:    return result;}/*******************************************************************/PaError PaHost_OpenOutputStream( internalPortAudioStream *stream ){    PaError          result = paNoError;    MMRESULT         mmresult;    PaWMMEStreamData *wmmeStreamData;    int              i;    int              outputMmID;    int              bytesPerOutputFrame;    WAVEFORMATEX     wfx;    const PaDeviceInfo *deviceInfo;    wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;    DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", stream->past_OutputDeviceID));    deviceInfo = Pa_GetDeviceInfo( stream->past_OutputDeviceID );    if( deviceInfo == NULL ) return paInternalError;    switch( deviceInfo->nativeSampleFormats  )    {    case paInt32:    case paFloat32:        bytesPerOutputFrame = sizeof(float) * stream->past_NumOutputChannels;        break;    default:        bytesPerOutputFrame = sizeof(short) * stream->past_NumOutputChannels;        break;    }    wfx.wFormatTag = WAVE_FORMAT_PCM;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -