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

📄 pa_win_wmme.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 5 页
字号:
            {                result = hostOutputSampleSize;                goto error;            }            if( outputStreamInfo                && ( outputStreamInfo->flags & paWinMmeUseMultipleDevices ) )            {                /* set effectiveOutputChannelCount to the largest number of                    channels on any one device.                */                effectiveOutputChannelCount = 0;                for( i=0; i< outputStreamInfo->deviceCount; ++i )                {                    if( outputStreamInfo->devices[i].channelCount > effectiveOutputChannelCount )                        effectiveOutputChannelCount = outputStreamInfo->devices[i].channelCount;                }            }            else            {                effectiveOutputChannelCount = outputChannelCount;            }            hostOutputFrameSize = hostOutputSampleSize * effectiveOutputChannelCount;                        maximumBufferSize = (long) ((PA_MME_MAX_HOST_BUFFER_SECS_ * sampleRate) * hostOutputFrameSize);            if( maximumBufferSize > PA_MME_MAX_HOST_BUFFER_BYTES_ )                maximumBufferSize = PA_MME_MAX_HOST_BUFFER_BYTES_;            /* compute the following in bytes, then convert back to frames */            SelectBufferSizeAndCount(                ((framesPerBuffer == paFramesPerBufferUnspecified)                    ? PA_MME_MIN_HOST_BUFFER_FRAMES_WHEN_UNSPECIFIED_                    : framesPerBuffer ) * hostOutputFrameSize, /* baseBufferSize */                ((unsigned long)(suggestedOutputLatency * sampleRate)) * hostOutputFrameSize, /* suggestedLatency */                4, /* baseBufferCount */                minimumBufferCount,                maximumBufferSize,                &hostBufferSizeBytes, &hostBufferCount );            *framesPerHostOutputBuffer = hostBufferSizeBytes / hostOutputFrameSize;            *hostOutputBufferCount = hostBufferCount;            if( inputChannelCount > 0 )            {                /* ensure that both input and output buffer sizes are the same.                    if they don't match at this stage, choose the smallest one                    and use that for input and output                */                if( *framesPerHostOutputBuffer != *framesPerHostInputBuffer )                {                    if( framesPerHostInputBuffer < framesPerHostOutputBuffer )                    {                        unsigned long framesPerHostBuffer = *framesPerHostInputBuffer;                                                minimumBufferCount = PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_;                        ReselectBufferCount(                            framesPerHostBuffer * hostOutputFrameSize, /* bufferSize */                            ((unsigned long)(suggestedOutputLatency * sampleRate)) * hostOutputFrameSize, /* suggestedLatency */                            4, /* baseBufferCount */                            minimumBufferCount,                            &hostBufferCount );                        *framesPerHostOutputBuffer = framesPerHostBuffer;                        *hostOutputBufferCount = hostBufferCount;                    }                    else                    {                        unsigned long framesPerHostBuffer = *framesPerHostOutputBuffer;                                                minimumBufferCount = PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_;                        ReselectBufferCount(                            framesPerHostBuffer * hostInputFrameSize, /* bufferSize */                            ((unsigned long)(suggestedInputLatency * sampleRate)) * hostInputFrameSize, /* suggestedLatency */                            4, /* baseBufferCount */                            minimumBufferCount,                            &hostBufferCount );                        *framesPerHostInputBuffer = framesPerHostBuffer;                        *hostInputBufferCount = hostBufferCount;                    }                }               }        }    }    else    {        *framesPerHostOutputBuffer = 0;        *hostOutputBufferCount = 0;    }error:    return result;}typedef struct{    HANDLE bufferEvent;    void *waveHandles;    unsigned int deviceCount;    /* unsigned int channelCount; */    WAVEHDR **waveHeaders;                  /* waveHeaders[device][buffer] */    unsigned int bufferCount;    unsigned int currentBufferIndex;    unsigned int framesPerBuffer;    unsigned int framesUsedInCurrentBuffer;}PaWinMmeSingleDirectionHandlesAndBuffers;/* prototypes for functions operating on PaWinMmeSingleDirectionHandlesAndBuffers */static void InitializeSingleDirectionHandlesAndBuffers( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers );static PaError InitializeWaveHandles( PaWinMmeHostApiRepresentation *winMmeHostApi,        PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers,        unsigned long bytesPerHostSample,        double sampleRate, PaWinMmeDeviceAndChannelCount *devices,        unsigned int deviceCount, int isInput );static PaError TerminateWaveHandles( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput, int currentlyProcessingAnError );static PaError InitializeWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers,        unsigned long hostBufferCount,        PaSampleFormat hostSampleFormat,        unsigned long framesPerHostBuffer,        PaWinMmeDeviceAndChannelCount *devices,        int isInput );static void TerminateWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput );static void InitializeSingleDirectionHandlesAndBuffers( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers ){    handlesAndBuffers->bufferEvent = 0;    handlesAndBuffers->waveHandles = 0;    handlesAndBuffers->deviceCount = 0;    handlesAndBuffers->waveHeaders = 0;    handlesAndBuffers->bufferCount = 0;}    static PaError InitializeWaveHandles( PaWinMmeHostApiRepresentation *winMmeHostApi,        PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers,        unsigned long bytesPerHostSample,        double sampleRate, PaWinMmeDeviceAndChannelCount *devices,        unsigned int deviceCount, int isInput ){    PaError result;    MMRESULT mmresult;    unsigned long bytesPerFrame;    WAVEFORMATEX wfx;    signed int i;    /* for error cleanup we expect that InitializeSingleDirectionHandlesAndBuffers()        has already been called to zero some fields */           result = CreateEventWithPaError( &handlesAndBuffers->bufferEvent, NULL, FALSE, FALSE, NULL );    if( result != paNoError ) goto error;    if( isInput )        handlesAndBuffers->waveHandles = (void*)PaUtil_AllocateMemory( sizeof(HWAVEIN) * deviceCount );    else        handlesAndBuffers->waveHandles = (void*)PaUtil_AllocateMemory( sizeof(HWAVEOUT) * deviceCount );    if( !handlesAndBuffers->waveHandles )    {        result = paInsufficientMemory;        goto error;    }    handlesAndBuffers->deviceCount = deviceCount;    for( i = 0; i < (signed int)deviceCount; ++i )    {        if( isInput )            ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] = 0;        else            ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] = 0;    }    wfx.wFormatTag = WAVE_FORMAT_PCM;    wfx.nSamplesPerSec = (DWORD) sampleRate;    wfx.cbSize = 0;        for( i = 0; i < (signed int)deviceCount; ++i )    {        UINT winMmeDeviceId;        winMmeDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, devices[i].device );        wfx.nChannels = (WORD)devices[i].channelCount;        bytesPerFrame = wfx.nChannels * bytesPerHostSample;        wfx.nAvgBytesPerSec = (DWORD)(bytesPerFrame * sampleRate);        wfx.nBlockAlign = (WORD)bytesPerFrame;        wfx.wBitsPerSample = (WORD)((bytesPerFrame/wfx.nChannels) * 8);        /* REVIEW: consider not firing an event for input when a full duplex            stream is being used. this would probably depend on the            neverDropInput flag. */        if( isInput )            mmresult = waveInOpen( &((HWAVEIN*)handlesAndBuffers->waveHandles)[i], winMmeDeviceId, &wfx,                               (DWORD)handlesAndBuffers->bufferEvent, (DWORD)0, CALLBACK_EVENT );        else            mmresult = waveOutOpen( &((HWAVEOUT*)handlesAndBuffers->waveHandles)[i], winMmeDeviceId, &wfx,                                (DWORD)handlesAndBuffers->bufferEvent, (DWORD)0, CALLBACK_EVENT );        if( mmresult != MMSYSERR_NOERROR )        {            switch( mmresult )            {                case MMSYSERR_ALLOCATED:    /* Specified resource is already allocated. */                    result = paDeviceUnavailable;                    break;                case MMSYSERR_NODRIVER:	    /* No device driver is present. */                    result = paDeviceUnavailable;                    break;                case MMSYSERR_NOMEM:	    /* Unable to allocate or lock memory. */                    result = paInsufficientMemory;                    break;                case MMSYSERR_BADDEVICEID:	/* Specified device identifier is out of range. */                    /* falls through */                case WAVERR_BADFORMAT:      /* Attempted to open with an unsupported waveform-audio format. */                    /* falls through */                default:                    result = paUnanticipatedHostError;                    if( isInput )                    {                        PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );                    }                    else                    {                        PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );                    }            }            goto error;        }    }    return result;error:    TerminateWaveHandles( handlesAndBuffers, isInput, 1 /* currentlyProcessingAnError */ );    return result;}static PaError TerminateWaveHandles( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput, int currentlyProcessingAnError ){    PaError result = paNoError;    MMRESULT mmresult;    signed int i;        if( handlesAndBuffers->waveHandles )    {        for( i = handlesAndBuffers->deviceCount-1; i >= 0; --i )        {            if( isInput )            {                if( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] )                    mmresult = waveInClose( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] );            }            else            {                if( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] )                    mmresult = waveOutClose( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] );            }            if( mmresult != MMSYSERR_NOERROR &&                !currentlyProcessingAnError ) /* don't update the error state if we're already processing an error */            {                result = paUnanticipatedHostError;                if( isInput )                {                    PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );                }                else                {                    PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );                }                /* note that we don't break here, we try to continue closing devices */            }        }        PaUtil_FreeMemory( handlesAndBuffers->waveHandles );        handlesAndBuffers->waveHandles = 0;    }    if( handlesAndBuffers->bufferEvent )    {        result = CloseHandleWithPaError( handlesAndBuffers->bufferEvent );        handlesAndBuffers->bufferEvent = 0;    }        return result;}static PaError InitializeWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers,        unsigned long hostBufferCount,        PaSampleFormat hostSampleFormat,        unsigned long framesPerHostBuffer,        PaWinMmeDeviceAndChannelCount *devices,        int isInput ){    PaError result = paNoError;    MMRESULT mmresult;    WAVEHDR *deviceWaveHeaders;    signed int i, j;    /* for error cleanup we expect that InitializeSingleDirectionHandlesAndBuffers()        has already been called to zero some fields */            /* allocate an array of pointers to arrays of wave headers, one array of        wave headers per device */    handlesAndBuffers->waveHeaders = (WAVEHDR**)PaUtil_AllocateMemory( sizeof(WAVEHDR*) * handlesAndBuffers->deviceCount );    if( !handlesAndBuffers->waveHeaders )    {        result = paInsufficientMemory;        goto error;    }        for( i = 0; i < (signed int)handlesAndBuffers->deviceCount; ++i )        handlesAndBuffers->waveHeaders[i] = 0;    handlesAndBuffers->bufferCount = hostBufferCount;    for( i = 0; i < (signed int)handlesAndBuffers->deviceCount; ++i )    {        int bufferBytes = Pa_GetSampleSize( hostSampleFormat ) *                framesPerHostBuffer * devices[i].channelCount;        if( bufferBytes < 0 )

⌨️ 快捷键说明

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