📄 pa_win_wmme.c
字号:
{ outputMultipleDeviceChannelCount += outputStreamInfo->devices[i].channelCount; outputDeviceInfo = hostApi->deviceInfos[ outputStreamInfo->devices[i].device ]; /* check that output device can support outputChannelCount */ if( outputStreamInfo->devices[i].channelCount <= 0 || outputStreamInfo->devices[i].channelCount > outputDeviceInfo->maxOutputChannels ) return paInvalidChannelCount; /* test for valid sample rate, see comment above */ winMmeOutputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, outputStreamInfo->devices[i].device ); paerror = QueryFormatSupported( outputDeviceInfo, QueryOutputWaveFormatEx, winMmeOutputDeviceId, outputStreamInfo->devices[i].channelCount, sampleRate ); if( paerror != paNoError ) return paInvalidSampleRate; } if( outputMultipleDeviceChannelCount != outputChannelCount ) return paIncompatibleHostApiSpecificStreamInfo; } else { if( outputStreamInfo && (outputStreamInfo->flags & paWinMmeUseMultipleDevices) ) return paIncompatibleHostApiSpecificStreamInfo; /* paUseHostApiSpecificDeviceSpecification was not supplied as the output device */ outputDeviceInfo = hostApi->deviceInfos[ outputParameters->device ]; /* check that output device can support outputChannelCount */ if( outputChannelCount > outputDeviceInfo->maxOutputChannels ) return paInvalidChannelCount; /* test for valid sample rate, see comment above */ winMmeOutputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, outputParameters->device ); paerror = QueryFormatSupported( outputDeviceInfo, QueryOutputWaveFormatEx, winMmeOutputDeviceId, outputChannelCount, sampleRate ); if( paerror != paNoError ) return paInvalidSampleRate; } } /* - if a full duplex stream is requested, check that the combination of input and output parameters is supported - check that the device supports sampleRate for mme all we can do is test that the input and output devices support the requested sample rate and number of channels. we cannot test for full duplex compatibility. */ return paFormatIsSupported;}static void SelectBufferSizeAndCount( unsigned long baseBufferSize, unsigned long requestedLatency, unsigned long baseBufferCount, unsigned long minimumBufferCount, unsigned long maximumBufferSize, unsigned long *hostBufferSize, unsigned long *hostBufferCount ){ unsigned long sizeMultiplier, bufferCount, latency; unsigned long nextLatency, nextBufferSize; int baseBufferSizeIsPowerOfTwo; sizeMultiplier = 1; bufferCount = baseBufferCount; /* count-1 below because latency is always determined by one less than the total number of buffers. */ latency = (baseBufferSize * sizeMultiplier) * (bufferCount-1); if( latency > requestedLatency ) { /* reduce number of buffers without falling below suggested latency */ nextLatency = (baseBufferSize * sizeMultiplier) * (bufferCount-2); while( bufferCount > minimumBufferCount && nextLatency >= requestedLatency ) { --bufferCount; nextLatency = (baseBufferSize * sizeMultiplier) * (bufferCount-2); } }else if( latency < requestedLatency ){ baseBufferSizeIsPowerOfTwo = (! (baseBufferSize & (baseBufferSize - 1))); if( baseBufferSizeIsPowerOfTwo ){ /* double size of buffers without exceeding requestedLatency */ nextBufferSize = (baseBufferSize * (sizeMultiplier*2)); nextLatency = nextBufferSize * (bufferCount-1); while( nextBufferSize <= maximumBufferSize && nextLatency < requestedLatency ) { sizeMultiplier *= 2; nextBufferSize = (baseBufferSize * (sizeMultiplier*2)); nextLatency = nextBufferSize * (bufferCount-1); } }else{ /* increase size of buffers upto first excess of requestedLatency */ nextBufferSize = (baseBufferSize * (sizeMultiplier+1)); nextLatency = nextBufferSize * (bufferCount-1); while( nextBufferSize <= maximumBufferSize && nextLatency < requestedLatency ) { ++sizeMultiplier; nextBufferSize = (baseBufferSize * (sizeMultiplier+1)); nextLatency = nextBufferSize * (bufferCount-1); } if( nextLatency < requestedLatency ) ++sizeMultiplier; } /* increase number of buffers until requestedLatency is reached */ latency = (baseBufferSize * sizeMultiplier) * (bufferCount-1); while( latency < requestedLatency ) { ++bufferCount; latency = (baseBufferSize * sizeMultiplier) * (bufferCount-1); } } *hostBufferSize = baseBufferSize * sizeMultiplier; *hostBufferCount = bufferCount;}static void ReselectBufferCount( unsigned long bufferSize, unsigned long requestedLatency, unsigned long baseBufferCount, unsigned long minimumBufferCount, unsigned long *hostBufferCount ){ unsigned long bufferCount, latency; unsigned long nextLatency; bufferCount = baseBufferCount; /* count-1 below because latency is always determined by one less than the total number of buffers. */ latency = bufferSize * (bufferCount-1); if( latency > requestedLatency ) { /* reduce number of buffers without falling below suggested latency */ nextLatency = bufferSize * (bufferCount-2); while( bufferCount > minimumBufferCount && nextLatency >= requestedLatency ) { --bufferCount; nextLatency = bufferSize * (bufferCount-2); } }else if( latency < requestedLatency ){ /* increase number of buffers until requestedLatency is reached */ latency = bufferSize * (bufferCount-1); while( latency < requestedLatency ) { ++bufferCount; latency = bufferSize * (bufferCount-1); } } *hostBufferCount = bufferCount;}/* CalculateBufferSettings() fills the framesPerHostInputBuffer, hostInputBufferCount, framesPerHostOutputBuffer and hostOutputBufferCount parameters based on the values of the other parameters.*/static PaError CalculateBufferSettings( unsigned long *framesPerHostInputBuffer, unsigned long *hostInputBufferCount, unsigned long *framesPerHostOutputBuffer, unsigned long *hostOutputBufferCount, int inputChannelCount, PaSampleFormat hostInputSampleFormat, PaTime suggestedInputLatency, PaWinMmeStreamInfo *inputStreamInfo, int outputChannelCount, PaSampleFormat hostOutputSampleFormat, PaTime suggestedOutputLatency, PaWinMmeStreamInfo *outputStreamInfo, double sampleRate, unsigned long framesPerBuffer ){ PaError result = paNoError; int effectiveInputChannelCount, effectiveOutputChannelCount; int hostInputFrameSize = 0; unsigned int i; if( inputChannelCount > 0 ) { int hostInputSampleSize = Pa_GetSampleSize( hostInputSampleFormat ); if( hostInputSampleSize < 0 ) { result = hostInputSampleSize; goto error; } if( inputStreamInfo && ( inputStreamInfo->flags & paWinMmeUseMultipleDevices ) ) { /* set effectiveInputChannelCount to the largest number of channels on any one device. */ effectiveInputChannelCount = 0; for( i=0; i< inputStreamInfo->deviceCount; ++i ) { if( inputStreamInfo->devices[i].channelCount > effectiveInputChannelCount ) effectiveInputChannelCount = inputStreamInfo->devices[i].channelCount; } } else { effectiveInputChannelCount = inputChannelCount; } hostInputFrameSize = hostInputSampleSize * effectiveInputChannelCount; if( inputStreamInfo && ( inputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) ) { if( inputStreamInfo->bufferCount <= 0 || inputStreamInfo->framesPerBuffer <= 0 ) { result = paIncompatibleHostApiSpecificStreamInfo; goto error; } *framesPerHostInputBuffer = inputStreamInfo->framesPerBuffer; *hostInputBufferCount = inputStreamInfo->bufferCount; } else { unsigned long hostBufferSizeBytes, hostBufferCount; unsigned long minimumBufferCount = (outputChannelCount > 0) ? PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ : PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_; unsigned long maximumBufferSize = (long) ((PA_MME_MAX_HOST_BUFFER_SECS_ * sampleRate) * hostInputFrameSize); 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 ) * hostInputFrameSize, /* baseBufferSize */ ((unsigned long)(suggestedInputLatency * sampleRate)) * hostInputFrameSize, /* suggestedLatency */ 4, /* baseBufferCount */ minimumBufferCount, maximumBufferSize, &hostBufferSizeBytes, &hostBufferCount ); *framesPerHostInputBuffer = hostBufferSizeBytes / hostInputFrameSize; *hostInputBufferCount = hostBufferCount; } } else { *framesPerHostInputBuffer = 0; *hostInputBufferCount = 0; } if( outputChannelCount > 0 ) { if( outputStreamInfo && ( outputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) ) { if( outputStreamInfo->bufferCount <= 0 || outputStreamInfo->framesPerBuffer <= 0 ) { result = paIncompatibleHostApiSpecificStreamInfo; goto error; } *framesPerHostOutputBuffer = outputStreamInfo->framesPerBuffer; *hostOutputBufferCount = outputStreamInfo->bufferCount; if( inputChannelCount > 0 ) /* full duplex */ { if( *framesPerHostInputBuffer != *framesPerHostOutputBuffer ) { if( inputStreamInfo && ( inputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) ) { /* a custom StreamInfo was used for specifying both input and output buffer sizes, the larger buffer size must be a multiple of the smaller buffer size */ if( *framesPerHostInputBuffer < *framesPerHostOutputBuffer ) { if( *framesPerHostOutputBuffer % *framesPerHostInputBuffer != 0 ) { result = paIncompatibleHostApiSpecificStreamInfo; goto error; } } else { assert( *framesPerHostInputBuffer > *framesPerHostOutputBuffer ); if( *framesPerHostInputBuffer % *framesPerHostOutputBuffer != 0 ) { result = paIncompatibleHostApiSpecificStreamInfo; goto error; } } } else { /* a custom StreamInfo was not used for specifying the input buffer size, so use the output buffer size, and approximately the same latency. */ *framesPerHostInputBuffer = *framesPerHostOutputBuffer; *hostInputBufferCount = (((unsigned long)(suggestedInputLatency * sampleRate)) / *framesPerHostInputBuffer) + 1; if( *hostInputBufferCount < PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ ) *hostInputBufferCount = PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_; } } } } else { unsigned long hostBufferSizeBytes, hostBufferCount; unsigned long minimumBufferCount = PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_; unsigned long maximumBufferSize; int hostOutputFrameSize; int hostOutputSampleSize; hostOutputSampleSize = Pa_GetSampleSize( hostOutputSampleFormat ); if( hostOutputSampleSize < 0 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -