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

📄 pa_win_ds.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 4 页
字号:
        /* Check for underflow */        if( dsw->dsw_OutputUnderflows != previousUnderflowCount )            stream->callbackFlags |= paOutputUnderflow;    }    if( (numInFramesReady > 0) && (numOutFramesReady > 0) )    {        framesToXfer = (numOutFramesReady < numInFramesReady) ? numOutFramesReady : numInFramesReady;    }    if( framesToXfer > 0 )    {        PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );    /* The outputBufferDacTime parameter should indicates the time at which        the first sample of the output buffer is heard at the DACs. */        timeInfo.currentTime = PaUtil_GetTime();        timeInfo.outputBufferDacTime = timeInfo.currentTime + outputLatency;        PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, stream->callbackFlags );        stream->callbackFlags = 0;            /* Input */        if( stream->bufferProcessor.inputChannelCount > 0 )        {            bytesToXfer = framesToXfer * dsw->dsw_BytesPerInputFrame;            hresult = IDirectSoundCaptureBuffer_Lock ( dsw->dsw_InputBuffer,                dsw->dsw_ReadOffset, bytesToXfer,                (void **) &lpInBuf1, &dwInSize1,                (void **) &lpInBuf2, &dwInSize2, 0);            if (hresult != DS_OK)            {                ERR_RPT(("DirectSound IDirectSoundCaptureBuffer_Lock failed, hresult = 0x%x\n",hresult));                result = paUnanticipatedHostError;                PA_DS_SET_LAST_DIRECTSOUND_ERROR( hresult );                goto error2;            }            numFrames = dwInSize1 / dsw->dsw_BytesPerInputFrame;            PaUtil_SetInputFrameCount( &stream->bufferProcessor, numFrames );            PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, lpInBuf1, 0 );        /* Is input split into two regions. */            if( dwInSize2 > 0 )            {                numFrames = dwInSize2 / dsw->dsw_BytesPerInputFrame;                PaUtil_Set2ndInputFrameCount( &stream->bufferProcessor, numFrames );                PaUtil_Set2ndInterleavedInputChannels( &stream->bufferProcessor, 0, lpInBuf2, 0 );            }        }    /* Output */        if( stream->bufferProcessor.outputChannelCount > 0 )        {            bytesToXfer = framesToXfer * dsw->dsw_BytesPerOutputFrame;            hresult = IDirectSoundBuffer_Lock ( dsw->dsw_OutputBuffer,                dsw->dsw_WriteOffset, bytesToXfer,                (void **) &lpOutBuf1, &dwOutSize1,                (void **) &lpOutBuf2, &dwOutSize2, 0);            if (hresult != DS_OK)            {                ERR_RPT(("DirectSound IDirectSoundBuffer_Lock failed, hresult = 0x%x\n",hresult));                result = paUnanticipatedHostError;                PA_DS_SET_LAST_DIRECTSOUND_ERROR( hresult );                goto error1;            }            numFrames = dwOutSize1 / dsw->dsw_BytesPerOutputFrame;            PaUtil_SetOutputFrameCount( &stream->bufferProcessor, numFrames );            PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, lpOutBuf1, 0 );        /* Is output split into two regions. */            if( dwOutSize2 > 0 )            {                numFrames = dwOutSize2 / dsw->dsw_BytesPerOutputFrame;                PaUtil_Set2ndOutputFrameCount( &stream->bufferProcessor, numFrames );                PaUtil_Set2ndInterleavedOutputChannels( &stream->bufferProcessor, 0, lpOutBuf2, 0 );            }        }        result = paContinue;        numFrames = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &result );        stream->framesWritten += numFrames;                if( stream->bufferProcessor.outputChannelCount > 0 )        {        /* FIXME: an underflow could happen here */        /* Update our buffer offset and unlock sound buffer */            bytesProcessed = numFrames * dsw->dsw_BytesPerOutputFrame;            dsw->dsw_WriteOffset = (dsw->dsw_WriteOffset + bytesProcessed) % dsw->dsw_OutputSize;            IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, lpOutBuf1, dwOutSize1, lpOutBuf2, dwOutSize2);            dsw->dsw_FramesWritten += numFrames;        }error1:        if( stream->bufferProcessor.inputChannelCount > 0 )        {        /* FIXME: an overflow could happen here */        /* Update our buffer offset and unlock sound buffer */            bytesProcessed = numFrames * dsw->dsw_BytesPerInputFrame;            dsw->dsw_ReadOffset = (dsw->dsw_ReadOffset + bytesProcessed) % dsw->dsw_InputSize;            IDirectSoundCaptureBuffer_Unlock( dsw->dsw_InputBuffer, lpInBuf1, dwInSize1, lpInBuf2, dwInSize2);        }error2:        PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, numFrames );    }        return result;}/*******************************************************************/static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2){    PaWinDsStream *stream;    /* suppress unused variable warnings */    (void) uID;    (void) uMsg;    (void) dw1;    (void) dw2;        stream = (PaWinDsStream *) dwUser;    if( stream == NULL ) return;    if( stream->isActive )    {        if( stream->abortProcessing )        {            stream->isActive = 0;        }        else if( stream->stopProcessing )        {            DSoundWrapper   *dsw = &stream->directSoundWrapper;            if( stream->bufferProcessor.outputChannelCount > 0 )            {                DSW_ZeroEmptySpace( dsw );                /* clear isActive when all sound played */                if( dsw->dsw_FramesPlayed >= stream->framesWritten )                {                    stream->isActive = 0;                }            }            else            {                stream->isActive = 0;            }        }        else        {            if( Pa_TimeSlice( stream ) != 0)  /* Call time slice independant of timing method. */            {                /* FIXME implement handling of paComplete and paAbort if possible */                stream->stopProcessing = 1;            }        }        if( !stream->isActive ){            if( stream->streamRepresentation.streamFinishedCallback != 0 )                stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );        }    }}/***********************************************************************************    When CloseStream() is called, the multi-api layer ensures that    the stream has already been stopped or aborted.*/static PaError CloseStream( PaStream* s ){    PaError result = paNoError;    PaWinDsStream *stream = (PaWinDsStream*)s;    DSW_Term( &stream->directSoundWrapper );    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );    PaUtil_FreeMemory( stream );    return result;}/***********************************************************************************/static PaError StartStream( PaStream *s ){    PaError          result = paNoError;    PaWinDsStream   *stream = (PaWinDsStream*)s;    HRESULT          hr;    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );        if( stream->bufferProcessor.inputChannelCount > 0 )    {        hr = DSW_StartInput( &stream->directSoundWrapper );        DBUG(("StartStream: DSW_StartInput returned = 0x%X.\n", hr));        if( hr != DS_OK )        {            result = paUnanticipatedHostError;            PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );            goto error;        }    }    stream->framesWritten = 0;    stream->callbackFlags = 0;    stream->abortProcessing = 0;    stream->stopProcessing = 0;    stream->isActive = 1;    if( stream->bufferProcessor.outputChannelCount > 0 )    {        /* Give user callback a chance to pre-fill buffer. REVIEW - i thought we weren't pre-filling, rb. */        result = Pa_TimeSlice( stream );        if( result != paNoError ) return result; // FIXME - what if finished?        hr = DSW_StartOutput( &stream->directSoundWrapper );        DBUG(("PaHost_StartOutput: DSW_StartOutput returned = 0x%X.\n", hr));        if( hr != DS_OK )        {            result = paUnanticipatedHostError;            PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );            goto error;        }    }    /* Create timer that will wake us up so we can fill the DSound buffer. */    {        int resolution;        int framesPerWakeup = stream->framesPerDSBuffer / 4;        int msecPerWakeup = MSEC_PER_SECOND * framesPerWakeup / (int) stream->streamRepresentation.streamInfo.sampleRate;        if( msecPerWakeup < 10 ) msecPerWakeup = 10;        else if( msecPerWakeup > 100 ) msecPerWakeup = 100;        resolution = msecPerWakeup/4;        stream->timerID = timeSetEvent( msecPerWakeup, resolution, (LPTIMECALLBACK) Pa_TimerCallback,                                             (DWORD) stream, TIME_PERIODIC );    }    if( stream->timerID == 0 )    {        stream->isActive = 0;        result = paUnanticipatedHostError;        PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );        goto error;    }    stream->isStarted = TRUE;error:    return result;}/***********************************************************************************/static PaError StopStream( PaStream *s ){    PaError result = paNoError;    PaWinDsStream *stream = (PaWinDsStream*)s;    HRESULT          hr;    int timeoutMsec;    stream->stopProcessing = 1;    /* Set timeout at 20% beyond maximum time we might wait. */    timeoutMsec = (int) (1200.0 * stream->framesPerDSBuffer / stream->streamRepresentation.streamInfo.sampleRate);    while( stream->isActive && (timeoutMsec > 0)  )    {        Sleep(10);        timeoutMsec -= 10;    }    if( stream->timerID != 0 )    {        timeKillEvent(stream->timerID);  /* Stop callback timer. */        stream->timerID = 0;    }    if( stream->bufferProcessor.outputChannelCount > 0 )    {        hr = DSW_StopOutput( &stream->directSoundWrapper );    }    if( stream->bufferProcessor.inputChannelCount > 0 )    {        hr = DSW_StopInput( &stream->directSoundWrapper );    }    stream->isStarted = FALSE;    return result;}/***********************************************************************************/static PaError AbortStream( PaStream *s ){    PaWinDsStream *stream = (PaWinDsStream*)s;    stream->abortProcessing = 1;    return StopStream( s );}/***********************************************************************************/static PaError IsStreamStopped( PaStream *s ){    PaWinDsStream *stream = (PaWinDsStream*)s;    return !stream->isStarted;}/***********************************************************************************/static PaError IsStreamActive( PaStream *s ){    PaWinDsStream *stream = (PaWinDsStream*)s;    return stream->isActive;}/***********************************************************************************/static PaTime GetStreamTime( PaStream *s ){    /* suppress unused variable warnings */    (void) s;    /*    new behavior for GetStreamTime is to return a stream based seconds clock    used for the outTime parameter to the callback.    FIXME: delete this comment when the other unnecessary related code has    been cleaned from this file.    PaWinDsStream *stream = (PaWinDsStream*)s;    DSoundWrapper   *dsw;    dsw = &stream->directSoundWrapper;    return dsw->dsw_FramesPlayed;*/    return PaUtil_GetTime();}/***********************************************************************************/static double GetStreamCpuLoad( PaStream* s ){    PaWinDsStream *stream = (PaWinDsStream*)s;    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );}/***********************************************************************************    As separate stream interfaces are used for blocking and callback    streams, the following functions can be guaranteed to only be called    for blocking streams.*/static PaError ReadStream( PaStream* s,                           void *buffer,                           unsigned long frames ){    PaWinDsStream *stream = (PaWinDsStream*)s;    /* suppress unused variable warnings */    (void) buffer;    (void) frames;    (void) stream;    /* IMPLEMENT ME, see portaudio.h for required behavior*/    return paNoError;}/***********************************************************************************/static PaError WriteStream( PaStream* s,                            const void *buffer,                            unsigned long frames ){    PaWinDsStream *stream = (PaWinDsStream*)s;    /* suppress unused variable warnings */    (void) buffer;    (void) frames;    (void) stream;    /* IMPLEMENT ME, see portaudio.h for required behavior*/    return paNoError;}/***********************************************************************************/static signed long GetStreamReadAvailable( PaStream* s ){    PaWinDsStream *stream = (PaWinDsStream*)s;    /* suppress unused variable warnings */    (void) stream;    /* IMPLEMENT ME, see portaudio.h for required behavior*/    return 0;}/***********************************************************************************/static signed long GetStreamWriteAvailable( PaStream* s ){    PaWinDsStream *stream = (PaWinDsStream*)s;    /* suppress unused variable warnings */    (void) stream;        /* IMPLEMENT ME, see portaudio.h for required behavior*/    return 0;}

⌨️ 快捷键说明

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