📄 pa_mac_core.c
字号:
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 ); if( !data ) { result = paInsufficientMemory; goto error; } /* now we can initialize the ring buffer */ PaUtil_InitializeRingBuffer( &stream->inputRingBuffer, ringSize*szfl, data ) ; /* advance the read point a little, so we are reading from the middle of the buffer */ if( stream->outputUnit ) PaUtil_AdvanceRingBufferWriteIndex( &stream->inputRingBuffer, ringSize*szfl / RING_BUFFER_ADVANCE_DENOMINATOR ); } } /* -- initialize Blio Buffer Processors -- */ if( !streamCallback ) { long ringSize; ringSize = computeRingBufferSize( inputParameters, outputParameters, stream->inputFramesPerBuffer, stream->outputFramesPerBuffer, sampleRate ); result = initializeBlioRingBuffers( &stream->blio, inputParameters?inputParameters->sampleFormat:0 , outputParameters?outputParameters->sampleFormat:0 , MAX(stream->inputFramesPerBuffer,stream->outputFramesPerBuffer), ringSize, inputParameters?inputChannelCount:0 , outputParameters?outputChannelCount:0 ) ; if( result != paNoError ) goto error; } /* -- initialize Buffer Processor -- */ { unsigned long maxHostFrames = stream->inputFramesPerBuffer; if( stream->outputFramesPerBuffer > maxHostFrames ) maxHostFrames = stream->outputFramesPerBuffer; result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, hostInputSampleFormat, outputChannelCount, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerBuffer, /* If sample rate conversion takes place, the buffer size will not be known. */ maxHostFrames, stream->inputSRConverter ? paUtilUnknownHostBufferSize : paUtilBoundedHostBufferSize, streamCallback ? streamCallback : BlioCallback, streamCallback ? userData : &stream->blio ); if( result != paNoError ) goto error; } stream->bufferProcessorIsInitialized = TRUE; /* IMPLEMENT ME: initialise the following fields with estimated or actual values. I think this is okay the way it is br 12/1/05 maybe need to change input latency estimate if IO devs differ */ stream->streamRepresentation.streamInfo.inputLatency = PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor)/sampleRate; stream->streamRepresentation.streamInfo.outputLatency = PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor)/sampleRate; stream->streamRepresentation.streamInfo.sampleRate = sampleRate; stream->sampleRate = sampleRate; stream->outDeviceSampleRate = 0; if( stream->outputUnit ) { Float64 rate; UInt32 size = sizeof( rate ); result = ERR( AudioDeviceGetProperty( stream->outputDevice, 0, FALSE, kAudioDevicePropertyNominalSampleRate, &size, &rate ) ); if( result ) goto error; stream->outDeviceSampleRate = rate; } stream->inDeviceSampleRate = 0; if( stream->inputUnit ) { Float64 rate; UInt32 size = sizeof( rate ); result = ERR( AudioDeviceGetProperty( stream->inputDevice, 0, TRUE, kAudioDevicePropertyNominalSampleRate, &size, &rate ) ); if( result ) goto error; stream->inDeviceSampleRate = rate; } stream->userInChan = inputChannelCount; stream->userOutChan = outputChannelCount; stream->isTimeSet = FALSE; stream->state = STOPPED; stream->xrunFlags = 0; *s = (PaStream*)stream; return result;error: CloseStream( stream ); return result;}PaTime GetStreamTime( PaStream *s ){ /* FIXME: I am not at all sure this timing info stuff is right. patest_sine_time reports negative latencies, which is wierd.*/ PaMacCoreStream *stream = (PaMacCoreStream*)s; AudioTimeStamp timeStamp; VVDBUG(("GetStreamTime()\n")); if ( !stream->isTimeSet ) return (PaTime)0; if ( stream->outputDevice ) { AudioDeviceGetCurrentTime( stream->outputDevice, &timeStamp); return (PaTime)(timeStamp.mSampleTime - stream->startTime.mSampleTime)/stream->outDeviceSampleRate; } else if ( stream->inputDevice ) { AudioDeviceGetCurrentTime( stream->inputDevice, &timeStamp); return (PaTime)(timeStamp.mSampleTime - stream->startTime.mSampleTime)/stream->inDeviceSampleRate; } else { return (PaTime)0; }}static void setStreamStartTime( PaStream *stream ){ /* FIXME: I am not at all sure this timing info stuff is right. patest_sine_time reports negative latencies, which is wierd.*/ PaMacCoreStream *s = (PaMacCoreStream *) stream; VVDBUG(("setStreamStartTime()\n")); if( s->outputDevice ) AudioDeviceGetCurrentTime( s->outputDevice, &s->startTime); else if( s->inputDevice ) AudioDeviceGetCurrentTime( s->inputDevice, &s->startTime); else bzero( &s->startTime, sizeof( s->startTime ) ); //FIXME: we need a memory barier here s->isTimeSet = TRUE;}static PaTime TimeStampToSecs(PaMacCoreStream *stream, const AudioTimeStamp* timeStamp){ VVDBUG(("TimeStampToSecs()\n")); //printf( "ATS: %lu, %g, %g\n", timeStamp->mFlags, timeStamp->mSampleTime, timeStamp->mRateScalar ); if (timeStamp->mF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -