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

📄 pa_mac_core_old.c

📁 一个开源SIP协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
    err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyNominalSampleRate, &propSize, &sampleRate));
    if (!err) {
        deviceInfo->defaultSampleRate = sampleRate;
    }


    // Get channel info
    err = GetChannelInfo(deviceInfo, macCoreDeviceId, 1);
    err = GetChannelInfo(deviceInfo, macCoreDeviceId, 0);

    return err;
}

static PaError InitializeDeviceInfos( PaMacCoreHostApiRepresentation *macCoreHostApi, PaHostApiIndex hostApiIndex )
{
    PaError result = paNoError;
    PaUtilHostApiRepresentation *hostApi;
    PaMacCoreDeviceInfo *deviceInfoArray;

    // initialise device counts and default devices under the assumption that there are no devices. These values are incremented below if and when devices are successfully initialized.
    hostApi = &macCoreHostApi->inheritedHostApiRep;
    hostApi->info.deviceCount = 0;
    hostApi->info.defaultInputDevice = paNoDevice;
    hostApi->info.defaultOutputDevice = paNoDevice;
    
    UInt32 propsize;
    AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &propsize, NULL);
    int numDevices = propsize / sizeof(AudioDeviceID);
    hostApi->info.deviceCount = numDevices;
    if (numDevices > 0) {
        hostApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
                                            macCoreHostApi->allocations, sizeof(PaDeviceInfo*) * numDevices );
        if( !hostApi->deviceInfos )
        {
            return paInsufficientMemory;
        }

        // allocate all device info structs in a contiguous block
        deviceInfoArray = (PaMacCoreDeviceInfo*)PaUtil_GroupAllocateMemory(
                                macCoreHostApi->allocations, sizeof(PaMacCoreDeviceInfo) * numDevices );
        if( !deviceInfoArray )
        {
            return paInsufficientMemory;
        }
        
        macCoreHostApi->macCoreDeviceIds = PaUtil_GroupAllocateMemory(macCoreHostApi->allocations, propsize);
        AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &propsize, macCoreHostApi->macCoreDeviceIds);

        AudioDeviceID defaultInputDevice, defaultOutputDevice;
        propsize = sizeof(AudioDeviceID);
        AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &propsize, &defaultInputDevice);
        AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &propsize, &defaultOutputDevice);
        
        UInt32 i;
        for (i = 0; i < numDevices; ++i) {
            if (macCoreHostApi->macCoreDeviceIds[i] == defaultInputDevice) {
                hostApi->info.defaultInputDevice = i;
            }
            if (macCoreHostApi->macCoreDeviceIds[i] == defaultOutputDevice) {
                hostApi->info.defaultOutputDevice = i;
            }
            InitializeDeviceInfo(&deviceInfoArray[i], macCoreHostApi->macCoreDeviceIds[i], hostApiIndex);
            hostApi->deviceInfos[i] = &(deviceInfoArray[i].inheritedDeviceInfo);      
        }
    }

    return result;
}

static OSStatus CheckFormat(AudioDeviceID macCoreDeviceId, const PaStreamParameters *parameters, double sampleRate, int isInput)
{
    UInt32 propSize = sizeof(AudioStreamBasicDescription);
    AudioStreamBasicDescription *streamDescription = PaUtil_AllocateMemory(propSize);

    streamDescription->mSampleRate = sampleRate;
    streamDescription->mFormatID = 0;
    streamDescription->mFormatFlags = 0;
    streamDescription->mBytesPerPacket = 0;
    streamDescription->mFramesPerPacket = 0;
    streamDescription->mBytesPerFrame = 0;
    streamDescription->mChannelsPerFrame = 0;
    streamDescription->mBitsPerChannel = 0;
    streamDescription->mReserved = 0;

    OSStatus result = AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamFormatSupported, &propSize, streamDescription);
    PaUtil_FreeMemory(streamDescription);
    return result;
}

static OSStatus CopyInputData(PaMacClientData* destination, const AudioBufferList *source, unsigned long frameCount)
{
    int frameSpacing, channelSpacing;
    if (destination->inputSampleFormat & paNonInterleaved) {
        frameSpacing = 1;
        channelSpacing = destination->inputChannelCount;
    }
    else {
        frameSpacing = destination->inputChannelCount;
        channelSpacing = 1;
    }
    
    AudioBuffer const *inputBuffer = &source->mBuffers[0];
    void *coreAudioBuffer = inputBuffer->mData;
    void *portAudioBuffer = destination->inputBuffer;
    UInt32 i, streamNumber, streamChannel;
    for (i = streamNumber = streamChannel = 0; i < destination->inputChannelCount; ++i, ++streamChannel) {
        if (streamChannel >= inputBuffer->mNumberChannels) {
            ++streamNumber;
            inputBuffer = &source->mBuffers[streamNumber];
            coreAudioBuffer = inputBuffer->mData;
            streamChannel = 0;
        }
        destination->inputConverter(portAudioBuffer, frameSpacing, coreAudioBuffer, inputBuffer->mNumberChannels, frameCount, destination->ditherGenerator);
        coreAudioBuffer += sizeof(Float32);
        portAudioBuffer += Pa_GetSampleSize(destination->inputSampleFormat) * channelSpacing;
    }
    return noErr;
}

static OSStatus CopyOutputData(AudioBufferList* destination, PaMacClientData *source, unsigned long frameCount)
{
    int frameSpacing, channelSpacing;
    if (source->outputSampleFormat & paNonInterleaved) {
        frameSpacing = 1;
        channelSpacing = source->outputChannelCount;
    }
    else {
        frameSpacing = source->outputChannelCount;
        channelSpacing = 1;
    }
    
    AudioBuffer *outputBuffer = &destination->mBuffers[0];
    void *coreAudioBuffer = outputBuffer->mData;
    void *portAudioBuffer = source->outputBuffer;
    UInt32 i, streamNumber, streamChannel;
    for (i = streamNumber = streamChannel = 0; i < source->outputChannelCount; ++i, ++streamChannel) {
        if (streamChannel >= outputBuffer->mNumberChannels) {
            ++streamNumber;
            outputBuffer = &destination->mBuffers[streamNumber];
            coreAudioBuffer = outputBuffer->mData;
            streamChannel = 0;
        }
        source->outputConverter(coreAudioBuffer, outputBuffer->mNumberChannels, portAudioBuffer, frameSpacing, frameCount, NULL);
        coreAudioBuffer += sizeof(Float32);
        portAudioBuffer += Pa_GetSampleSize(source->outputSampleFormat) * channelSpacing;
    }
    return noErr;
}

static OSStatus AudioIOProc( AudioDeviceID inDevice,
                      const AudioTimeStamp* inNow,
                      const AudioBufferList* inInputData,
                      const AudioTimeStamp* inInputTime,
                      AudioBufferList* outOutputData, 
                      const AudioTimeStamp* inOutputTime,
                      void* inClientData)
{
    PaMacClientData *clientData = (PaMacClientData *)inClientData;
    PaStreamCallbackTimeInfo *timeInfo = InitializeTimeInfo(inNow, inInputTime, inOutputTime);
    
    PaUtil_BeginCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer );
    
    AudioBuffer *outputBuffer = &outOutputData->mBuffers[0];
    unsigned long frameCount = outputBuffer->mDataByteSize / (outputBuffer->mNumberChannels * sizeof(Float32));

    if (clientData->inputBuffer) {
        CopyInputData(clientData, inInputData, frameCount);
    }
    PaStreamCallbackResult result = clientData->callback(clientData->inputBuffer, clientData->outputBuffer, frameCount, timeInfo, paNoFlag, clientData->userData);
    if (clientData->outputBuffer) {
        CopyOutputData(outOutputData, clientData, frameCount);
    }

    PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount );
    
    if (result == paComplete || result == paAbort) {
        Pa_StopStream(clientData->stream);
    }

    PaUtil_FreeMemory( timeInfo );
    return noErr;
}

// This is not for input-only streams, this is for streams where the input device is different from the output device
static OSStatus AudioInputProc( AudioDeviceID inDevice,
                         const AudioTimeStamp* inNow,
                         const AudioBufferList* inInputData,
                         const AudioTimeStamp* inInputTime,
                         AudioBufferList* outOutputData, 
                         const AudioTimeStamp* inOutputTime,
                         void* inClientData)
{
    PaMacClientData *clientData = (PaMacClientData *)inClientData;
    PaStreamCallbackTimeInfo *timeInfo = InitializeTimeInfo(inNow, inInputTime, inOutputTime);

    PaUtil_BeginCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer );

    AudioBuffer const *inputBuffer = &inInputData->mBuffers[0];
    unsigned long frameCount = inputBuffer->mDataByteSize / (inputBuffer->mNumberChannels * sizeof(Float32));

    CopyInputData(clientData, inInputData, frameCount);
    PaStreamCallbackResult result = clientData->callback(clientData->inputBuffer, clientData->outputBuffer, frameCount, timeInfo, paNoFlag, clientData->userData);
    
    PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount );
    if( result == paComplete || result == paAbort )
       Pa_StopStream(clientData->stream);
    PaUtil_FreeMemory( timeInfo );
    return noErr;
}

// This is not for output-only streams, this is for streams where the input device is different from the output device
static OSStatus AudioOutputProc( AudioDeviceID inDevice,
                          const AudioTimeStamp* inNow,
                          const AudioBufferList* inInputData,
                          const AudioTimeStamp* inInputTime,
                          AudioBufferList* outOutputData, 
                          const AudioTimeStamp* inOutputTime,
                          void* inClientData)
{
    PaMacClientData *clientData = (PaMacClientData *)inClientData;
    //PaStreamCallbackTimeInfo *timeInfo = InitializeTimeInfo(inNow, inInputTime, inOutputTime);

    PaUtil_BeginCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer );

    AudioBuffer *outputBuffer = &outOutputData->mBuffers[0];
    unsigned long frameCount = outputBuffer->mDataByteSize / (outputBuffer->mNumberChannels * sizeof(Float32));

    //clientData->callback(NULL, clientData->outputBuffer, frameCount, timeInfo, paNoFlag, clientData->userData);

    CopyOutputData(outOutputData, clientData, frameCount);

    PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount );
    return noErr;
}

static PaError SetSampleRate(AudioDeviceID device, double sampleRate, int isInput)
{
    PaError result = paNoError;
    
    double actualSampleRate;
    UInt32 propSize = sizeof(double);
    result = conv_err(AudioDeviceSetProperty(device, NULL, 0, isInput, kAudioDevicePropertyNominalSampleRate, propSize, &sampleRate));
    
    result = conv_err(AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyNominalSampleRate, &propSize, &actualSampleRate));
    
    if (result == paNoError && actualSampleRate != sampleRate) {
        result = paInvalidSampleRate;
    }
    
    return result;    
}

static PaError SetFramesPerBuffer(AudioDeviceID device, unsigned long framesPerBuffer, int isInput)
{
    PaError result = paNoError;
    UInt32 preferredFramesPerBuffer = framesPerBuffer;
    //    while (preferredFramesPerBuffer > UINT32_MAX) {
    //        preferredFramesPerBuffer /= 2;
    //    }
    
    UInt32 actualFramesPerBuffer;
    UInt32 propSize = sizeof(UInt32);
    result = conv_err(AudioDeviceSetProperty(device, NULL, 0, isInput, kAudioDevicePropertyBufferFrameSize, propSize, &preferredFramesPerBuffer));
    
    result = conv_err(AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyBufferFrameSize, &propSize, &actualFramesPerBuffer));
    
    if (result != paNoError) {
        // do nothing
    }
    else if (actualFramesPerBuffer > framesPerBuffer) {
        result = paBufferTooSmall;
    }
    else if (actualFramesPerBuffer < framesPerBuffer) {
        result = paBufferTooBig;
    }
    
    return result;    
}
    
static PaError SetUpUnidirectionalStream(AudioDeviceID device, double sampleRate, unsigned long framesPerBuffer, int isInput)
{
    PaError err = paNoError;
    err = SetSampleRate(device, sampleRate, isInput);
    if( err == paNoError )
        err = SetFramesPerBuffer(device, framesPerBuffer, isInput);
    return err;
}

// =====  PortAudio functions  =====
#pragma mark PortAudio functions

#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
    
    PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
    
#ifdef __cplusplus
}
#endif // __cplusplus

static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
{
    PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation*)hostApi;

⌨️ 快捷键说明

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