pa_mac_core.c
字号:
deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; /* Get the device name. Fail if we can't get it. */ err = ERR(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL)); if (err) return err; name = PaUtil_GroupAllocateMemory(auhalHostApi->allocations,propSize); if ( !name ) return paInsufficientMemory; err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, name)); if (err) return err; deviceInfo->name = name; /* Try to get the default sample rate. Don't fail if we can't get this. */ propSize = sizeof(Float64); err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyNominalSampleRate, &propSize, &sampleRate)); if (err) deviceInfo->defaultSampleRate = 0.0; else deviceInfo->defaultSampleRate = sampleRate; /* Get the maximum number of input and output channels. Fail if we can't get this. */ err = GetChannelInfo(auhalHostApi, deviceInfo, macCoreDeviceId, 1); if (err) return err; err = GetChannelInfo(auhalHostApi, deviceInfo, macCoreDeviceId, 0); if (err) return err; return paNoError;}PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ){ PaError result = paNoError; int i; PaMacAUHAL *auhalHostApi; PaDeviceInfo *deviceInfoArray; VVDBUG(("PaMacCore_Initialize(): hostApiIndex=%d\n", hostApiIndex)); auhalHostApi = (PaMacAUHAL*)PaUtil_AllocateMemory( sizeof(PaMacAUHAL) ); if( !auhalHostApi ) { result = paInsufficientMemory; goto error; } auhalHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !auhalHostApi->allocations ) { result = paInsufficientMemory; goto error; } auhalHostApi->devIds = NULL; auhalHostApi->devCount = 0; /* get the info we need about the devices */ result = gatherDeviceInfo( auhalHostApi ); if( result != paNoError ) goto error; *hostApi = &auhalHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paCoreAudio; (*hostApi)->info.name = "Core Audio"; (*hostApi)->info.defaultInputDevice = paNoDevice; (*hostApi)->info.defaultOutputDevice = paNoDevice; (*hostApi)->info.deviceCount = 0; if( auhalHostApi->devCount > 0 ) { (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( auhalHostApi->allocations, sizeof(PaDeviceInfo*) * auhalHostApi->devCount); if( !(*hostApi)->deviceInfos ) { result = paInsufficientMemory; goto error; } /* allocate all device info structs in a contiguous block */ deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory( auhalHostApi->allocations, sizeof(PaDeviceInfo) * auhalHostApi->devCount ); if( !deviceInfoArray ) { result = paInsufficientMemory; goto error; } for( i=0; i < auhalHostApi->devCount; ++i ) { int err; err = InitializeDeviceInfo( auhalHostApi, &deviceInfoArray[i], auhalHostApi->devIds[i], hostApiIndex ); if (err == paNoError) { /* copy some info and set the defaults */ (*hostApi)->deviceInfos[(*hostApi)->info.deviceCount] = &deviceInfoArray[i]; if (auhalHostApi->devIds[i] == auhalHostApi->defaultIn) (*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount; if (auhalHostApi->devIds[i] == auhalHostApi->defaultOut) (*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount; (*hostApi)->info.deviceCount++; } else { /* there was an error. we need to shift the devices down, so we ignore this one */ int j; auhalHostApi->devCount--; for( j=i; j<auhalHostApi->devCount; ++j ) auhalHostApi->devIds[j] = auhalHostApi->devIds[j+1]; i--; } } } (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &auhalHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &auhalHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); return result;error: if( auhalHostApi ) { if( auhalHostApi->allocations ) { PaUtil_FreeAllAllocations( auhalHostApi->allocations ); PaUtil_DestroyAllocationGroup( auhalHostApi->allocations ); } PaUtil_FreeMemory( auhalHostApi ); } return result;}static void Terminate( struct PaUtilHostApiRepresentation *hostApi ){ PaMacAUHAL *auhalHostApi = (PaMacAUHAL*)hostApi; VVDBUG(("Terminate()\n")); /* IMPLEMENT ME: - clean up any resources not handled by the allocation group TODO: Double check that everything is handled by alloc group */ if( auhalHostApi->allocations ) { PaUtil_FreeAllAllocations( auhalHostApi->allocations ); PaUtil_DestroyAllocationGroup( auhalHostApi->allocations ); } PaUtil_FreeMemory( auhalHostApi );}static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ){ int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; VVDBUG(("IsFormatSupported(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld sampleRate=%g\n", inputParameters ? inputParameters->channelCount : -1, inputParameters ? inputParameters->sampleFormat : -1, outputParameters ? outputParameters->channelCount : -1, outputParameters ? outputParameters->sampleFormat : -1, (float) sampleRate )); /** These first checks are standard PA checks. We do some fancier checks later. */ if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( inputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* 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; } else { inputChannelCount = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( outputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support outputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; } else { outputChannelCount = 0; } /* FEEDBACK */ /* I think the only way to check a given format SR combo is */ /* to try opening it. This could be disruptive, is that Okay? */ /* The alternative is to just read off available sample rates, */ /* but this will not work %100 of the time (eg, a device that */ /* supports N output at one rate but only N/2 at a higher rate.)*/ /* The following code opens the device with the requested parameters to see if it works. */ { PaError err; PaStream *s; err = OpenStream( hostApi, &s, inputParameters, outputParameters, sampleRate, 1024, 0, (PaStreamCallback *)1, NULL ); if( err != paNoError && err != paInvalidSampleRate ) DBUG( ( "OpenStream @ %g returned: %d: %s\n", (float) sampleRate, err, Pa_GetErrorText( err ) ) ); if( err ) return err; err = CloseStream( s ); if( err ) { /* FEEDBACK: is this more serious? should we assert? */ DBUG( ( "WARNING: could not close Stream. %d: %s\n", err, Pa_GetErrorText( err ) ) ); } } return paFormatIsSupported;}static PaError OpenAndSetupOneAudioUnit( const PaStreamParameters *inStreamParams, const PaStreamParameters *outStreamParams, const unsigned long requestedFramesPerBuffer, unsigned long *actualInputFramesPerBuffer, unsigned long *actualOutputFramesPerBuffer, const PaMacAUHAL *auhalHostApi, AudioUnit *audioUnit, AudioConverterRef *srConverter, AudioDeviceID *audioDevice, const double sampleRate, void *refCon ){ ComponentDescription desc; Component comp; /*An Apple TN suggests using CAStreamBasicDescription, but that is C++*/ AudioStreamBasicDescription desiredFormat; OSErr result = noErr; PaError paResult = paNoError; int line = 0; UInt32 callbackKey; AURenderCallbackStruct rcbs; unsigned long macInputStreamFlags = paMacCorePlayNice; unsigned long macOutputStreamFlags = paMacCorePlayNice; VVDBUG(("OpenAndSetupOneAudioUnit(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld, requestedFramesPerBuffer=%ld\n", inStreamParams ? inStreamParams->channelCount : -1, inStreamParams ? inStreamParams->sampleFormat : -1, outStreamParams ? outStreamParams->channelCount : -1, outStreamParams ? outStreamParams->sampleFormat : -1, requestedFramesPerBuffer )); /* -- handle the degenerate case -- */ if( !inStreamParams && !outStreamParams ) { *audioUnit = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -