pa_mac_core.c
字号:
outStreamParams ? OUTPUT_ELEMENT : INPUT_ELEMENT, &rcbs, sizeof(rcbs)) ); if( inStreamParams && outStreamParams && *srConverter ) ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Output, INPUT_ELEMENT, &rcbs, sizeof(rcbs)) ); /*IMPLEMENTME: may need to worry about channel mapping.*/ /* initialize the audio unit */ ERR_WRAP( AudioUnitInitialize(*audioUnit) ); if( inStreamParams && outStreamParams ) VDBUG( ("Opened device %ld for input and output.\n", *audioDevice ) ); else if( inStreamParams ) VDBUG( ("Opened device %ld for input.\n", *audioDevice ) ); else if( outStreamParams ) VDBUG( ("Opened device %ld for output.\n", *audioDevice ) ); return paNoError;#undef ERR_WRAP error: CloseComponent( *audioUnit ); *audioUnit = NULL; if( result ) return PaMacCore_SetError( result, line, 1 ); return paResult;}/* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ){ PaError result = paNoError; PaMacAUHAL *auhalHostApi = (PaMacAUHAL*)hostApi; PaMacCoreStream *stream = 0; int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; VVDBUG(("OpenStream(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld SR=%g, FPB=%ld\n", inputParameters ? inputParameters->channelCount : -1, inputParameters ? inputParameters->sampleFormat : -1, outputParameters ? outputParameters->channelCount : -1, outputParameters ? outputParameters->sampleFormat : -1, (float) sampleRate, framesPerBuffer )); VDBUG( ("Opening Stream.\n") ); /*These first few bits of code are from paSkeleton with few modifications.*/ if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* Host supports interleaved float32 */ hostInputSampleFormat = paFloat32; } else { inputChannelCount = 0; inputSampleFormat = hostInputSampleFormat = paFloat32; /* Surpress 'uninitialised var' warnings. */ } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support inputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* Host supports interleaved float32 */ hostOutputSampleFormat = paFloat32; } else { outputChannelCount = 0; outputSampleFormat = hostOutputSampleFormat = paFloat32; /* Surpress 'uninitialized var' warnings. */ } /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ stream = (PaMacCoreStream*)PaUtil_AllocateMemory( sizeof(PaMacCoreStream) ); if( !stream ) { result = paInsufficientMemory; goto error; } /* If we fail after this point, we my be left in a bad state, with some data structures setup and others not. So, first thing we do is initialize everything so that if we fail, we know what hasn't been touched. */ stream->inputAudioBufferList.mBuffers[0].mData = NULL; stream->inputRingBuffer.buffer = NULL; bzero( &stream->blio, sizeof( PaMacBlio ) );/* stream->blio.inputRingBuffer.buffer = NULL; stream->blio.outputRingBuffer.buffer = NULL; stream->blio.inputSampleFormat = inputParameters?inputParameters->sampleFormat:0; stream->blio.inputSampleSize = computeSampleSizeFromFormat(stream->blio.inputSampleFormat); stream->blio.outputSampleFormat=outputParameters?outputParameters->sampleFormat:0; stream->blio.outputSampleSize = computeSampleSizeFromFormat(stream->blio.outputSampleFormat);*/ stream->inputSRConverter = NULL; stream->inputUnit = NULL; stream->outputUnit = NULL; stream->inputFramesPerBuffer = 0; stream->outputFramesPerBuffer = 0; stream->bufferProcessorIsInitialized = FALSE; /* assert( streamCallback ) ; */ /* only callback mode is implemented */ if( streamCallback ) { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &auhalHostApi->callbackStreamInterface, streamCallback, userData ); } else { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &auhalHostApi->blockingStreamInterface, BlioCallback, &stream->blio ); } PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); /* -- handle paFramesPerBufferUnspecified -- */ if( framesPerBuffer == paFramesPerBufferUnspecified ) { long requested = 64; if( inputParameters ) requested = MAX( requested, inputParameters->suggestedLatency * sampleRate / 2 ); if( outputParameters ) requested = MAX( requested, outputParameters->suggestedLatency *sampleRate / 2 ); VDBUG( ("Block Size unspecified. Based on Latency, the user wants a Block Size near: %ld.\n", requested ) ); if( requested <= 64 ) { /*requested a realtively low latency. make sure this is in range of devices */ /*try to get the device's min natural buffer size and use that (but no smaller than 64).*/ AudioValueRange audioRange; size_t size = sizeof( audioRange ); if( inputParameters ) { WARNING( result = AudioDeviceGetProperty( auhalHostApi->devIds[inputParameters->device], 0, false, kAudioDevicePropertyBufferFrameSizeRange, &size, &audioRange ) ); if( result ) requested = MAX( requested, audioRange.mMinimum ); } if( outputParameters ) { WARNING( result = AudioDeviceGetProperty( auhalHostApi->devIds[outputParameters->device], 0, false, kAudioDevicePropertyBufferFrameSizeRange, &size, &audioRange ) ); if( result ) requested = MAX( requested, audioRange.mMinimum ); } } else { /* requested a realtively high latency. make sure this is in range of devices */ /*try to get the device's max natural buffer size and use that (but no larger than 1024).*/ AudioValueRange audioRange; size_t size = sizeof( audioRange ); requested = MIN( requested, 1024 ); if( inputParameters ) { WARNING( result = AudioDeviceGetProperty( auhalHostApi->devIds[inputParameters->device], 0, false, kAudioDevicePropertyBufferFrameSizeRange, &size, &audioRange ) ); if( result ) requested = MIN( requested, audioRange.mMaximum ); } if( outputParameters ) { WARNING( result = AudioDeviceGetProperty( auhalHostApi->devIds[outputParameters->device], 0, false, kAudioDevicePropertyBufferFrameSizeRange, &size, &audioRange ) ); if( result ) requested = MIN( requested, audioRange.mMaximum ); } } /* -- double check ranges -- */ if( requested > 1024 ) requested = 1024; if( requested < 64 ) requested = 64; VDBUG(("After querying hardware, setting block size to %ld.\n", requested)); framesPerBuffer = requested; } /* -- Now we actually open and setup streams. -- */ if( inputParameters && outputParameters && outputParameters->device == inputParameters->device ) { /* full duplex. One device. */ result = OpenAndSetupOneAudioUnit( inputParameters, outputParameters, framesPerBuffer, &(stream->inputFramesPerBuffer), &(stream->outputFramesPerBuffer), auhalHostApi, &(stream->inputUnit), &(stream->inputSRConverter), &(stream->inputDevice), sampleRate, stream ); stream->outputUnit = stream->inputUnit; stream->outputDevice = stream->inputDevice; if( result != paNoError ) goto error; } else { /* full duplex, different devices OR simplex */ result = OpenAndSetupOneAudioUnit( NULL, outputParameters, framesPerBuffer, NULL, &(stream->outputFramesPerBuffer), auhalHostApi, &(stream->outputUnit), NULL, &(stream->outputDevice), sampleRate, stream ); if( result != paNoError ) goto error; result = OpenAndSetupOneAudioUnit( inputParameters, NULL, framesPerBuffer, &(stream->inputFramesPerBuffer), NULL, auhalHostApi, &(stream->inputUnit), &(stream->inputSRConverter), &(stream->inputDevice), sampleRate, stream ); if( result != paNoError ) goto error; } if( stream->inputUnit ) { const size_t szfl = sizeof(float); /* setup the AudioBufferList used for input */ bzero( &stream->inputAudioBufferList, sizeof( AudioBufferList ) ); stream->inputAudioBufferList.mNumberBuffers = 1; stream->inputAudioBufferList.mBuffers[0].mNumberChannels = inputChannelCount; stream->inputAudioBufferList.mBuffers[0].mDataByteSize = stream->inputFramesPerBuffer*inputChannelCount*szfl; stream->inputAudioBufferList.mBuffers[0].mData = (float *) calloc( stream->inputFramesPerBuffer*inputChannelCount, szfl ); if( !stream->inputAudioBufferList.mBuffers[0].mData ) { result = paInsufficientMemory; goto error; } /* * If input and output devs are different or we are doing SR conversion, * we also need a * ring buffer to store inpt data while waiting for output * data. */ if( (stream->outputUnit && stream->inputUnit != stream->outputUnit) || stream->inputSRConverter ) { /* May want the ringSize ot initial position in ring buffer to depend somewhat on sample rate change */ void *data; long ringSize; ringSize = computeRingBufferSize( inputParameters, outputParameters, stream->inputFramesPerBuffer, stream->outputFramesPerBuffer, sampleRate ); /*ringSize <<= 4; *//*16x bigger, for testing */ /*now, we need to allocate memory for the ring buffer*/ data = calloc( ringSize, szfl );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -