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

📄 pa_mac_core_old.c

📁 一个开源SIP协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * $Id: pa_mac_core_old.c 770 2006-10-13 17:57:42Z bennylp $
 * pa_mac_core.c
 * Implementation of PortAudio for Mac OS X CoreAudio       
 *                                                                                         
 * PortAudio Portable Real-Time Audio Library
 * Latest Version at: http://www.portaudio.com
 *
 * Authors: Ross Bencina and Phil Burk
 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/*
 * The text above constitutes the entire PortAudio license; however, 
 * the PortAudio community also makes the following non-binding requests:
 *
 * Any person wishing to distribute modifications to the Software is
 * requested to send the modifications to the original developer so that
 * they can be incorporated into the canonical version. It is also 
 * requested that these non-binding requests be included along with the 
 * license above.
 */

#include <CoreAudio/CoreAudio.h>
#include <AudioToolbox/AudioToolbox.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>

#include "portaudio.h"
#include "pa_trace.h"
#include "pa_util.h"
#include "pa_allocation.h"
#include "pa_hostapi.h"
#include "pa_stream.h"
#include "pa_cpuload.h"
#include "pa_process.h"

// =====  constants  =====

// =====  structs  =====
#pragma mark structs

// PaMacCoreHostApiRepresentation - host api datastructure specific to this implementation
typedef struct PaMacCore_HAR
{
    PaUtilHostApiRepresentation inheritedHostApiRep;
    PaUtilStreamInterface callbackStreamInterface;
    PaUtilStreamInterface blockingStreamInterface;
    
    PaUtilAllocationGroup *allocations;
    AudioDeviceID *macCoreDeviceIds;
}
PaMacCoreHostApiRepresentation;

typedef struct PaMacCore_DI
{
    PaDeviceInfo inheritedDeviceInfo;
}
PaMacCoreDeviceInfo;

// PaMacCoreStream - a stream data structure specifically for this implementation
typedef struct PaMacCore_S
{
    PaUtilStreamRepresentation streamRepresentation;
    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
    PaUtilBufferProcessor bufferProcessor;
    
    int primeStreamUsingCallback;
    
    AudioDeviceID inputDevice;
    AudioDeviceID outputDevice;
    
    // Processing thread management --------------
//    HANDLE abortEvent;
//    HANDLE processingThread;
//    DWORD processingThreadId;
    
    char throttleProcessingThreadOnOverload; // 0 -> don't throtte, non-0 -> throttle
    int processingThreadPriority;
    int highThreadPriority;
    int throttledThreadPriority;
    unsigned long throttledSleepMsecs;
    
    int isStopped;
    volatile int isActive;
    volatile int stopProcessing; // stop thread once existing buffers have been returned
    volatile int abortProcessing; // stop thread immediately
    
//    DWORD allBuffersDurationMs; // used to calculate timeouts
}
PaMacCoreStream;

// Data needed by the CoreAudio callback functions
typedef struct PaMacCore_CD
{
    PaMacCoreStream *stream;
    PaStreamCallback *callback;
    void *userData;
    PaUtilConverter *inputConverter;
    PaUtilConverter *outputConverter;
    void *inputBuffer;
    void *outputBuffer;
    int inputChannelCount;
    int outputChannelCount;
    PaSampleFormat inputSampleFormat;
    PaSampleFormat outputSampleFormat;
    PaUtilTriangularDitherGenerator *ditherGenerator;
}
PaMacClientData;

// =====  CoreAudio-PortAudio bridge functions =====
#pragma mark CoreAudio-PortAudio bridge functions

// Maps CoreAudio OSStatus codes to PortAudio PaError codes
static PaError conv_err(OSStatus error)
{
    PaError result;
    
    switch (error) {
        case kAudioHardwareNoError:
            result = paNoError; break;
        case kAudioHardwareNotRunningError:
            result = paInternalError; break;
        case kAudioHardwareUnspecifiedError:
            result = paInternalError; break;
        case kAudioHardwareUnknownPropertyError:
            result = paInternalError; break;
        case kAudioHardwareBadPropertySizeError:
            result = paInternalError; break;
        case kAudioHardwareIllegalOperationError:
            result = paInternalError; break;
        case kAudioHardwareBadDeviceError:
            result = paInvalidDevice; break;
        case kAudioHardwareBadStreamError:
            result = paBadStreamPtr; break;
	//bennylp:
        //case kAudioHardwareUnsupportedOperationError:
        //    result = paInternalError; break;
        case kAudioDeviceUnsupportedFormatError:
            result = paSampleFormatNotSupported; break;
        case kAudioDevicePermissionsError:
            result = paDeviceUnavailable; break;
        default:
            result = paInternalError;
    }
    
    return result;
}

/* This function is unused
static AudioStreamBasicDescription *InitializeStreamDescription(const PaStreamParameters *parameters, double sampleRate)
{
    struct AudioStreamBasicDescription *streamDescription = PaUtil_AllocateMemory(sizeof(AudioStreamBasicDescription));
    streamDescription->mSampleRate = sampleRate;
    streamDescription->mFormatID = kAudioFormatLinearPCM;
    streamDescription->mFormatFlags = 0;
    streamDescription->mFramesPerPacket = 1;
    
    if (parameters->sampleFormat & paNonInterleaved) {
        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsNonInterleaved;
        streamDescription->mChannelsPerFrame = 1;
        streamDescription->mBytesPerFrame = Pa_GetSampleSize(parameters->sampleFormat);
        streamDescription->mBytesPerPacket = Pa_GetSampleSize(parameters->sampleFormat);
    }
    else {
        streamDescription->mChannelsPerFrame = parameters->channelCount;
    }
    
    streamDescription->mBytesPerFrame = Pa_GetSampleSize(parameters->sampleFormat) * streamDescription->mChannelsPerFrame;
    streamDescription->mBytesPerPacket = streamDescription->mBytesPerFrame * streamDescription->mFramesPerPacket;
    
    if (parameters->sampleFormat & paFloat32) {
        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsFloat;
        streamDescription->mBitsPerChannel = 32;
    }
    else if (parameters->sampleFormat & paInt32) {
        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
        streamDescription->mBitsPerChannel = 32;
    }
    else if (parameters->sampleFormat & paInt24) {
        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
        streamDescription->mBitsPerChannel = 24;
    }
    else if (parameters->sampleFormat & paInt16) {
        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
        streamDescription->mBitsPerChannel = 16;
    }
    else if (parameters->sampleFormat & paInt8) {
        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
        streamDescription->mBitsPerChannel = 8;
    }    
    else if (parameters->sampleFormat & paInt32) {
        streamDescription->mBitsPerChannel = 8;
    }
    
    return streamDescription;
}
*/

static PaStreamCallbackTimeInfo *InitializeTimeInfo(const AudioTimeStamp* now, const AudioTimeStamp* inputTime, const AudioTimeStamp* outputTime)
{
    PaStreamCallbackTimeInfo *timeInfo = PaUtil_AllocateMemory(sizeof(PaStreamCallbackTimeInfo));
    
    timeInfo->inputBufferAdcTime = inputTime->mSampleTime;
    timeInfo->currentTime = now->mSampleTime;
    timeInfo->outputBufferDacTime = outputTime->mSampleTime;
    
    return timeInfo;
}

// =====  support functions  =====
#pragma mark support functions

static void CleanUp(PaMacCoreHostApiRepresentation *macCoreHostApi)
{
    if( macCoreHostApi->allocations )
    {
        PaUtil_FreeAllAllocations( macCoreHostApi->allocations );
        PaUtil_DestroyAllocationGroup( macCoreHostApi->allocations );
    }
    
    PaUtil_FreeMemory( macCoreHostApi );    
}

static PaError GetChannelInfo(PaDeviceInfo *deviceInfo, AudioDeviceID macCoreDeviceId, int isInput)
{
    UInt32 propSize;
    PaError err = paNoError;
    UInt32 i;
    int numChannels = 0;
    AudioBufferList *buflist;

    err = conv_err(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamConfiguration, &propSize, NULL));
    buflist = PaUtil_AllocateMemory(propSize);
    err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamConfiguration, &propSize, buflist));
    if (!err) {
        for (i = 0; i < buflist->mNumberBuffers; ++i) {
            numChannels += buflist->mBuffers[i].mNumberChannels;
        }
		
		if (isInput)
			deviceInfo->maxInputChannels = numChannels;
		else
			deviceInfo->maxOutputChannels = numChannels;
		
        int frameLatency;
        propSize = sizeof(UInt32);
        err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyLatency, &propSize, &frameLatency));
        if (!err) {
            double secondLatency = frameLatency / deviceInfo->defaultSampleRate;
            if (isInput) {
                deviceInfo->defaultLowInputLatency = secondLatency;
                deviceInfo->defaultHighInputLatency = secondLatency;
            }
            else {
                deviceInfo->defaultLowOutputLatency = secondLatency;
                deviceInfo->defaultHighOutputLatency = secondLatency;
            }
        }
    }
    PaUtil_FreeMemory(buflist);
    
    return err;
}

static PaError InitializeDeviceInfo(PaMacCoreDeviceInfo *macCoreDeviceInfo,  AudioDeviceID macCoreDeviceId, PaHostApiIndex hostApiIndex )
{
    PaDeviceInfo *deviceInfo = &macCoreDeviceInfo->inheritedDeviceInfo;
    deviceInfo->structVersion = 2;
    deviceInfo->hostApi = hostApiIndex;
    
    PaError err = paNoError;
    UInt32 propSize;

    err = conv_err(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL));
    // FIXME: this allocation should be part of the allocations group
    char *name = PaUtil_AllocateMemory(propSize);
    err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, name));
    if (!err) {
        deviceInfo->name = name;
    }
    
    Float64 sampleRate;
    propSize = sizeof(Float64);

⌨️ 快捷键说明

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