📄 pa_mac_core_old.c
字号:
/* * $Id: pa_mac_core_old.c 946 2005-12-24 01:22:52Z bjornroche $ * 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. * * 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. * * 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. * */#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 implementationtypedef 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 implementationtypedef 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 functionstypedef 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 codesstatic 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; case kAudioHardwareUnsupportedOperationError: result = paInternalError; break; case kAudioDeviceUnsupportedFormatError: result = paSampleFormatNotSupported; break; case kAudioDevicePermissionsError: result = paDeviceUnavailable; break; default: result = paInternalError; } return result;}/* This function is unusedstatic 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 functionsstatic 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); err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyNominalSampleRate, &propSize, &sampleRate)); if (!err) { deviceInfo->defaultSampleRate = sampleRate; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -