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

📄 pa_mac_core_old.c

📁 一个开源SIP协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
    
    CleanUp(macCoreHostApi);
}

static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
                                  const PaStreamParameters *inputParameters,
                                  const PaStreamParameters *outputParameters,
                                  double sampleRate )
{
    PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation*)hostApi;
    PaDeviceInfo *deviceInfo;
    
    PaError result = paNoError;
    if (inputParameters) {
        deviceInfo = macCoreHostApi->inheritedHostApiRep.deviceInfos[inputParameters->device];
        if (inputParameters->channelCount > deviceInfo->maxInputChannels)
            result = paInvalidChannelCount;
        else if (CheckFormat(macCoreHostApi->macCoreDeviceIds[inputParameters->device], inputParameters, sampleRate, 1) != kAudioHardwareNoError) {
            result = paInvalidSampleRate;
        }
    }
    if (outputParameters && result == paNoError) {
        deviceInfo = macCoreHostApi->inheritedHostApiRep.deviceInfos[outputParameters->device];
        if (outputParameters->channelCount > deviceInfo->maxOutputChannels)
            result = paInvalidChannelCount;
        else if (CheckFormat(macCoreHostApi->macCoreDeviceIds[outputParameters->device], outputParameters, sampleRate, 0) != kAudioHardwareNoError) {
            result = paInvalidSampleRate;
        }
    }

    return result;
}

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 err = paNoError;
    PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation *)hostApi;
    PaMacCoreStream *stream = PaUtil_AllocateMemory(sizeof(PaMacCoreStream));
    stream->isActive = 0;
    stream->isStopped = 1;
    stream->inputDevice = kAudioDeviceUnknown;
    stream->outputDevice = kAudioDeviceUnknown;
    
    PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
                                           ( (streamCallback)
                                             ? &macCoreHostApi->callbackStreamInterface
                                             : &macCoreHostApi->blockingStreamInterface ),
                                           streamCallback, userData );
    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
    
    *s = (PaStream*)stream;
    PaMacClientData *clientData = PaUtil_AllocateMemory(sizeof(PaMacClientData));
    clientData->stream = stream;
    clientData->callback = streamCallback;
    clientData->userData = userData;
    clientData->inputBuffer = 0;
    clientData->outputBuffer = 0;
    clientData->ditherGenerator = PaUtil_AllocateMemory(sizeof(PaUtilTriangularDitherGenerator));
    PaUtil_InitializeTriangularDitherState(clientData->ditherGenerator);
    
    if (inputParameters != NULL) {
        stream->inputDevice = macCoreHostApi->macCoreDeviceIds[inputParameters->device];
        clientData->inputConverter = PaUtil_SelectConverter(paFloat32, inputParameters->sampleFormat, streamFlags);
        clientData->inputBuffer = PaUtil_AllocateMemory(Pa_GetSampleSize(inputParameters->sampleFormat) * framesPerBuffer * inputParameters->channelCount);
        clientData->inputChannelCount = inputParameters->channelCount;
        clientData->inputSampleFormat = inputParameters->sampleFormat;
        err = SetUpUnidirectionalStream(stream->inputDevice, sampleRate, framesPerBuffer, 1);
    }
    
    if (err == paNoError && outputParameters != NULL) {
        stream->outputDevice = macCoreHostApi->macCoreDeviceIds[outputParameters->device];
        clientData->outputConverter = PaUtil_SelectConverter(outputParameters->sampleFormat, paFloat32, streamFlags);
        clientData->outputBuffer = PaUtil_AllocateMemory(Pa_GetSampleSize(outputParameters->sampleFormat) * framesPerBuffer * outputParameters->channelCount);
        clientData->outputChannelCount = outputParameters->channelCount;
        clientData->outputSampleFormat = outputParameters->sampleFormat;
        err = SetUpUnidirectionalStream(stream->outputDevice, sampleRate, framesPerBuffer, 0);
    }

    if (inputParameters == NULL || outputParameters == NULL || stream->inputDevice == stream->outputDevice) {
        AudioDeviceID device = (inputParameters == NULL) ? stream->outputDevice : stream->inputDevice;

        AudioDeviceAddIOProc(device, AudioIOProc, clientData);
    }
    else {
        // using different devices for input and output
        AudioDeviceAddIOProc(stream->inputDevice, AudioInputProc, clientData);
        AudioDeviceAddIOProc(stream->outputDevice, AudioOutputProc, clientData);
    }
    
    return err;
}

// Note: When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted.
static PaError CloseStream( PaStream* s )
{
    PaError err = paNoError;
    PaMacCoreStream *stream = (PaMacCoreStream*)s;

    PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer );

    if (stream->inputDevice != kAudioDeviceUnknown) {
        if (stream->outputDevice == kAudioDeviceUnknown || stream->outputDevice == stream->inputDevice) {
            err = conv_err(AudioDeviceRemoveIOProc(stream->inputDevice, AudioIOProc));
        }
        else {
            err = conv_err(AudioDeviceRemoveIOProc(stream->inputDevice, AudioInputProc));
            err = conv_err(AudioDeviceRemoveIOProc(stream->outputDevice, AudioOutputProc));
        }
    }
    else {
        err = conv_err(AudioDeviceRemoveIOProc(stream->outputDevice, AudioIOProc));
    }
    
    return err;
}


static PaError StartStream( PaStream *s )
{
    PaError err = paNoError;
    PaMacCoreStream *stream = (PaMacCoreStream*)s;

    if (stream->inputDevice != kAudioDeviceUnknown) {
        if (stream->outputDevice == kAudioDeviceUnknown || stream->outputDevice == stream->inputDevice) {
            err = conv_err(AudioDeviceStart(stream->inputDevice, AudioIOProc));
        }
        else {
            err = conv_err(AudioDeviceStart(stream->inputDevice, AudioInputProc));
            err = conv_err(AudioDeviceStart(stream->outputDevice, AudioOutputProc));
        }
    }
    else {
        err = conv_err(AudioDeviceStart(stream->outputDevice, AudioIOProc));
    }
    
    stream->isActive = 1;
    stream->isStopped = 0;
    return err;
}

static PaError AbortStream( PaStream *s )
{
    PaError err = paNoError;
    PaMacCoreStream *stream = (PaMacCoreStream*)s;
    
    if (stream->inputDevice != kAudioDeviceUnknown) {
        if (stream->outputDevice == kAudioDeviceUnknown || stream->outputDevice == stream->inputDevice) {
            err = conv_err(AudioDeviceStop(stream->inputDevice, AudioIOProc));
        }
        else {
            err = conv_err(AudioDeviceStop(stream->inputDevice, AudioInputProc));
            err = conv_err(AudioDeviceStop(stream->outputDevice, AudioOutputProc));
        }
    }
    else {
        err = conv_err(AudioDeviceStop(stream->outputDevice, AudioIOProc));
    }
    
    stream->isActive = 0;
    stream->isStopped = 1;
    return err;
}    

static PaError StopStream( PaStream *s )
{
    // TODO: this should be nicer than abort
    return AbortStream(s);
}

static PaError IsStreamStopped( PaStream *s )
{
    PaMacCoreStream *stream = (PaMacCoreStream*)s;
    
    return stream->isStopped;
}


static PaError IsStreamActive( PaStream *s )
{
    PaMacCoreStream *stream = (PaMacCoreStream*)s;

    return stream->isActive;
}


static PaTime GetStreamTime( PaStream *s )
{
    OSStatus err;
    PaTime result;
    PaMacCoreStream *stream = (PaMacCoreStream*)s;

    AudioTimeStamp *timeStamp = PaUtil_AllocateMemory(sizeof(AudioTimeStamp));
    if (stream->inputDevice != kAudioDeviceUnknown) {
        err = AudioDeviceGetCurrentTime(stream->inputDevice, timeStamp);
    }
    else {
        err = AudioDeviceGetCurrentTime(stream->outputDevice, timeStamp);
    }
    
    result = err ? 0 : timeStamp->mSampleTime;
    PaUtil_FreeMemory(timeStamp);

    return result;
}


static double GetStreamCpuLoad( PaStream* s )
{
    PaMacCoreStream *stream = (PaMacCoreStream*)s;
    
    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
}


// As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams.

static PaError ReadStream( PaStream* s,
                           void *buffer,
                           unsigned long frames )
{
    return paInternalError;
}


static PaError WriteStream( PaStream* s,
                            const void *buffer,
                            unsigned long frames )
{
    return paInternalError;
}


static signed long GetStreamReadAvailable( PaStream* s )
{
    return paInternalError;
}


static signed long GetStreamWriteAvailable( PaStream* s )
{
    return paInternalError;
}

// HostAPI-specific initialization function
PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
{
    PaError result = paNoError;
    PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation *)PaUtil_AllocateMemory( sizeof(PaMacCoreHostApiRepresentation) );
    if( !macCoreHostApi )
    {
        result = paInsufficientMemory;
        goto error;
    }
    
    macCoreHostApi->allocations = PaUtil_CreateAllocationGroup();
    if( !macCoreHostApi->allocations )
    {
        result = paInsufficientMemory;
        goto error;
    }
    
    *hostApi = &macCoreHostApi->inheritedHostApiRep;
    (*hostApi)->info.structVersion = 1;
    (*hostApi)->info.type = paCoreAudio;
    (*hostApi)->info.name = "CoreAudio";

    result = InitializeDeviceInfos(macCoreHostApi, hostApiIndex);
    if (result != paNoError) {
        goto error;
    }
    
    // Set up the proper callbacks to this HostApi's functions
    (*hostApi)->Terminate = Terminate;
    (*hostApi)->OpenStream = OpenStream;
    (*hostApi)->IsFormatSupported = IsFormatSupported;
    
    PaUtil_InitializeStreamInterface( &macCoreHostApi->callbackStreamInterface, CloseStream, StartStream,
                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
                                      GetStreamTime, GetStreamCpuLoad,
                                      PaUtil_DummyRead, PaUtil_DummyWrite,
                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
    
    PaUtil_InitializeStreamInterface( &macCoreHostApi->blockingStreamInterface, CloseStream, StartStream,
                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
    
    return result;
    
error:
        if( macCoreHostApi ) {
            CleanUp(macCoreHostApi);
        }
    
    return result;
}

⌨️ 快捷键说明

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