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

📄 pa_win_wmme.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 5 页
字号:
    wmmeStreamData->abortEvent = CreateEvent( NULL, TRUE, FALSE, NULL );    if( wmmeStreamData->abortEvent == NULL )    {        result = paHostError;        sPaHostError = GetLastError();        goto error;    }    wmmeStreamData->abortEventInited = 1;    mmresult = waveOutOpen( &wmmeStreamData->hWaveOut, outputMmID, &wfx,                      (DWORD)wmmeStreamData->bufferEvent, (DWORD) stream, CALLBACK_EVENT );#endif    if( mmresult != MMSYSERR_NOERROR )    {        ERR_RPT(("PortAudio: PaHost_OpenOutputStream() failed!\n"));        result = paHostError;        sPaHostError = mmresult;        goto error;    }    /* Allocate an array to hold the buffer pointers. */    wmmeStreamData->outputBuffers = (WAVEHDR *) PaHost_AllocateTrackedMemory( sizeof(WAVEHDR)*wmmeStreamData->numHostBuffers ); /* MEM */    if( wmmeStreamData->outputBuffers == NULL )    {        result = paInsufficientMemory;        goto error;    }    /* Allocate each buffer. */    for( i=0; i<wmmeStreamData->numHostBuffers; i++ )    {        wmmeStreamData->outputBuffers[i].lpData = (char *) PaHost_AllocateTrackedMemory( wmmeStreamData->bytesPerHostOutputBuffer ); /* MEM */        if( wmmeStreamData->outputBuffers[i].lpData == NULL )        {            result = paInsufficientMemory;            goto error;        }        wmmeStreamData->outputBuffers[i].dwBufferLength = wmmeStreamData->bytesPerHostOutputBuffer;        wmmeStreamData->outputBuffers[i].dwUser = i;        if( (mmresult = waveOutPrepareHeader( wmmeStreamData->hWaveOut, &wmmeStreamData->outputBuffers[i], sizeof(WAVEHDR) )) != MMSYSERR_NOERROR )        {            result = paHostError;            sPaHostError = mmresult;            goto error;        }    }    return result;error:    return result;}/*******************************************************************/PaError PaHost_GetTotalBufferFrames( internalPortAudioStream *stream ){    PaWMMEStreamData *wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;    return wmmeStreamData->numHostBuffers * wmmeStreamData->framesPerHostBuffer;}/******************************************************************* * Determine number of WAVE Buffers * and how many User Buffers we can put into each WAVE buffer. */static void PaHost_CalcNumHostBuffers( internalPortAudioStream *stream ){    PaWMMEStreamData *wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;    unsigned int  minNumBuffers;    int           minframesPerHostBuffer;    int           maxframesPerHostBuffer;    int           minTotalFrames;    int           userBuffersPerHostBuffer;    int           framesPerHostBuffer;    int           numHostBuffers;    /* Calculate minimum and maximum sizes based on timing and sample rate. */    minframesPerHostBuffer = (int) (PA_MIN_MSEC_PER_HOST_BUFFER * stream->past_SampleRate * 0.001);    minframesPerHostBuffer = (minframesPerHostBuffer + 7) & ~7;    DBUG(("PaHost_CalcNumHostBuffers: minframesPerHostBuffer = %d\n", minframesPerHostBuffer ));    maxframesPerHostBuffer = (int) (PA_MAX_MSEC_PER_HOST_BUFFER * stream->past_SampleRate * 0.001);    maxframesPerHostBuffer = (maxframesPerHostBuffer + 7) & ~7;    DBUG(("PaHost_CalcNumHostBuffers: maxframesPerHostBuffer = %d\n", maxframesPerHostBuffer ));    /* Determine number of user buffers based on minimum latency. */    minNumBuffers = Pa_GetMinNumBuffers( stream->past_FramesPerUserBuffer, stream->past_SampleRate );    stream->past_NumUserBuffers = ( minNumBuffers > stream->past_NumUserBuffers ) ? minNumBuffers : stream->past_NumUserBuffers;    DBUG(("PaHost_CalcNumHostBuffers: min past_NumUserBuffers = %d\n", stream->past_NumUserBuffers ));    minTotalFrames = stream->past_NumUserBuffers * stream->past_FramesPerUserBuffer;    /* We cannot make the WAVE buffers too small because they may not get serviced quickly enough. */    if( (int) stream->past_FramesPerUserBuffer < minframesPerHostBuffer )    {        userBuffersPerHostBuffer =            (minframesPerHostBuffer + stream->past_FramesPerUserBuffer - 1) /            stream->past_FramesPerUserBuffer;    }    else    {        userBuffersPerHostBuffer = 1;    }    framesPerHostBuffer = stream->past_FramesPerUserBuffer * userBuffersPerHostBuffer;    /* Calculate number of WAVE buffers needed. Round up to cover minTotalFrames. */    numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;    /* Make sure we have anough WAVE buffers. */    if( numHostBuffers < PA_MIN_NUM_HOST_BUFFERS)    {        numHostBuffers = PA_MIN_NUM_HOST_BUFFERS;    }    else if( (numHostBuffers > PA_MAX_NUM_HOST_BUFFERS) &&             ((int) stream->past_FramesPerUserBuffer < (maxframesPerHostBuffer/2) ) )    {        /* If we have too many WAVE buffers, try to put more user buffers in a wave buffer. */        while(numHostBuffers > PA_MAX_NUM_HOST_BUFFERS)        {            userBuffersPerHostBuffer += 1;            framesPerHostBuffer = stream->past_FramesPerUserBuffer * userBuffersPerHostBuffer;            numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;            /* If we have gone too far, back up one. */            if( (framesPerHostBuffer > maxframesPerHostBuffer) ||                    (numHostBuffers < PA_MAX_NUM_HOST_BUFFERS) )            {                userBuffersPerHostBuffer -= 1;                framesPerHostBuffer = stream->past_FramesPerUserBuffer * userBuffersPerHostBuffer;                numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;                break;            }        }    }    wmmeStreamData->userBuffersPerHostBuffer = userBuffersPerHostBuffer;    wmmeStreamData->framesPerHostBuffer = framesPerHostBuffer;    wmmeStreamData->numHostBuffers = numHostBuffers;    DBUG(("PaHost_CalcNumHostBuffers: userBuffersPerHostBuffer = %d\n", wmmeStreamData->userBuffersPerHostBuffer ));    DBUG(("PaHost_CalcNumHostBuffers: numHostBuffers = %d\n", wmmeStreamData->numHostBuffers ));    DBUG(("PaHost_CalcNumHostBuffers: framesPerHostBuffer = %d\n", wmmeStreamData->framesPerHostBuffer ));    DBUG(("PaHost_CalcNumHostBuffers: past_NumUserBuffers = %d\n", stream->past_NumUserBuffers ));}/*******************************************************************/PaError PaHost_OpenStream( internalPortAudioStream *stream ){    PaError             result = paNoError;    PaWMMEStreamData *wmmeStreamData;    result = PaHost_AllocateWMMEStreamData( stream );    if( result != paNoError ) return result;    wmmeStreamData = PaHost_GetWMMEStreamData( stream );    /* Figure out how user buffers fit into WAVE buffers. */    PaHost_CalcNumHostBuffers( stream );    {        int msecLatency = (int) ((PaHost_GetTotalBufferFrames(stream) * 1000) / stream->past_SampleRate);        DBUG(("PortAudio on WMME - Latency = %d frames, %d msec\n", PaHost_GetTotalBufferFrames(stream), msecLatency ));    }    InitializeCriticalSection( &wmmeStreamData->streamLock );    wmmeStreamData->streamLockInited = 1;#if (PA_USE_TIMER_CALLBACK == 0)    wmmeStreamData->bufferEventInited = 0;    wmmeStreamData->bufferEvent = CreateEvent( NULL, FALSE, FALSE, NULL );    if( wmmeStreamData->bufferEvent == NULL )    {        result = paHostError;        sPaHostError = GetLastError();        goto error;    }    wmmeStreamData->bufferEventInited = 1;#endif /* (PA_USE_TIMER_CALLBACK == 0) */    /* ------------------ OUTPUT */    wmmeStreamData->bytesPerUserOutputBuffer = stream->past_FramesPerUserBuffer * stream->past_NumOutputChannels * sizeof(short);    wmmeStreamData->bytesPerHostOutputBuffer = wmmeStreamData->userBuffersPerHostBuffer * wmmeStreamData->bytesPerUserOutputBuffer;    if( (stream->past_OutputDeviceID != paNoDevice) && (stream->past_NumOutputChannels > 0) )    {        result = PaHost_OpenOutputStream( stream );        if( result < 0 ) goto error;    }    /* ------------------ INPUT */    wmmeStreamData->bytesPerUserInputBuffer = stream->past_FramesPerUserBuffer * stream->past_NumInputChannels * sizeof(short);    wmmeStreamData->bytesPerHostInputBuffer = wmmeStreamData->userBuffersPerHostBuffer * wmmeStreamData->bytesPerUserInputBuffer;    if( (stream->past_InputDeviceID != paNoDevice) && (stream->past_NumInputChannels > 0) )    {        result = PaHost_OpenInputStream( stream );        if( result < 0 ) goto error;    }    Pa_InitializeCpuUsageScalar( stream );    return result;error:    PaHost_CloseStream( stream );    return result;}/*************************************************************************/PaError PaHost_StartOutput( internalPortAudioStream *stream ){    PaError          result = paNoError;    MMRESULT         mmresult;    int              i;    PaWMMEStreamData *wmmeStreamData = PaHost_GetWMMEStreamData( stream );    if( wmmeStreamData == NULL ) return paInternalError;    if( stream->past_OutputDeviceID != paNoDevice )    {        if( (mmresult = waveOutPause( wmmeStreamData->hWaveOut )) != MMSYSERR_NOERROR )        {            result = paHostError;            sPaHostError = mmresult;            goto error;        }        for( i=0; i<wmmeStreamData->numHostBuffers; i++ )        {            ZeroMemory( wmmeStreamData->outputBuffers[i].lpData, wmmeStreamData->outputBuffers[i].dwBufferLength );            mmresult = waveOutWrite( wmmeStreamData->hWaveOut, &wmmeStreamData->outputBuffers[i], sizeof(WAVEHDR) );            if( mmresult != MMSYSERR_NOERROR )            {                result = paHostError;                sPaHostError = mmresult;                goto error;            }            stream->past_FrameCount += wmmeStreamData->framesPerHostBuffer;        }        wmmeStreamData->currentOutputBuffer = 0;        if( (mmresult = waveOutRestart( wmmeStreamData->hWaveOut )) != MMSYSERR_NOERROR )        {            result = paHostError;            sPaHostError = mmresult;            goto error;        }    }error:    DBUG(("PaHost_StartOutput: wave returned mmresult = 0x%X.\n", mmresult));    return result;}/*************************************************************************/PaError PaHost_StartInput( internalPortAudioStream *internalStream ){    PaError          result = paNoError;    MMRESULT         mmresult;    int              i;    PaWMMEStreamData *wmmeStreamData = PaHost_GetWMMEStreamData( internalStream );    if( wmmeStreamData == NULL ) return paInternalError;    if( internalStream->past_InputDeviceID != paNoDevice )    {        for( i=0; i<wmmeStreamData->numHostBuffers; i++ )        {            mmresult = waveInAddBuffer( wmmeStreamData->hWaveIn, &wmmeStreamData->inputBuffers[i], sizeof(WAVEHDR) );            if( mmresult != MMSYSERR_NOERROR )            {                result = paHostError;                sPaHostError = mmresult;                goto error;            }        }        wmmeStreamData->currentInputBuffer = 0;        mmresult = waveInStart( wmmeStreamData->hWaveIn );        DBUG(("Pa_StartStream: waveInStart returned = 0x%X.\n", mmresult));        if( mmresult != MMSYSERR_NOERROR )        {            result = paHostError;            sPaHostError = mmresult;            goto error;        }    }error:    return result;}/*************************************************************************/PaError PaHost_StartEngine( internalPortAudioStream *stream ){    PaError             result = paNoError;    PaWMMEStreamData *wmmeStreamData = PaHost_GetWMMEStreamData( stream );#if PA_USE_TIMER_CALLBACK    int                 resolution;    int                 bufsPerTimerCallback;    int                 msecPerBuffer;#endif /* PA_USE_TIMER_CALLBACK */    if( wmmeStreamData == NULL ) return paInternalError;    stream->past_StopSoon = 0;    stream->past_StopNow = 0;    stream->past_IsActive = 1;    wmmeStreamData->framesPlayed = 0.0;    wmmeStreamData->lastPosition = 0;#if PA_TRACE_START_STOP    AddTraceMessage( "PaHost_StartEngine: TimeSlice() returned ", result );#endif#if PA_USE_TIMER_CALLBACK    /* Create timer that will wake us up so we can fill the DSound buffer. */    bufsPerTimerCallback = wmmeStreamData->numHostBuffers/4;    if( bufsPerTimerCallback < 1 ) bufsPerTimerCallback = 1;    if( bufsPerTimerCallback < 1 ) bufsPerTimerCallback = 1;    msecPerBuffer = (1000 * bufsPerTimerCallback *                     wmmeStreamData->userBuffersPerHostBuffer *                     internalStream->past_FramesPerUserBuffer ) / (int) internalStream->past_SampleRate;    if( msecPerBuffer < 10 ) msecPerBuffer = 10;    else if( msecPerBuffer > 100 ) msecPerBuffer = 100;    resolution = msecPerBuffer/4;    wmmeStreamData->timerID = timeSetEvent( msecPerBuffer, resolution,                                         (LPTIMECALLBACK) Pa_TimerCallback,                                         (DWORD) stream, TIME_PERIODIC );    if( wmmeStreamData->timerID == 0 )    {        result = paHostError;        sPaHostError = GetLastError();;        goto error;    }#else /* PA_USE_TIMER_CALLBACK */    ResetEvent( wmmeStreamData->abortEvent );    /* Create thread that waits for audio buffers to be ready for processing. */    wmmeStreamData->engineThread = CreateThread( 0, 0, WinMMPa_OutputThreadProc, stream, 0, &wmmeStreamData->engineThreadID );    if( wmmeStreamData->engineThread == NULL )    {        result = paHostError;        sPaHostError = GetLastError();;        goto error;    }#if PA_TRACE_START_STOP    AddTraceMessage( "PaHost_StartEngine: thread ", (int) wmmeStreamData->engineThread );#endif    /* I used to pass the thread which was failing. I now pass GetCurrentProcess().     * This fix could improve latency for some applications. It could also result in CPU     * starvation if the callback did too much processing.     * I also added result checks, so we might see more failures at initialization.     * Thanks to Alberto di Bene for spotting this.     */#if 0  /* dmazzoni: this seems to cause problems */    if( !SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS ) ) /* PLB20010816 */    {        result = paHostError;        sPaHostError = GetLastError();;        goto error;    }#endif    if( !SetThreadPriority( wmmeStreamData->engineThread, THREAD_PRIORITY_HIGHEST ) )    {        result = paHostError;        sPaHostError = GetLastError();;        goto error;

⌨️ 快捷键说明

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