欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

pa_mac_core.c

基于sip协议的网络电话源码
C
第 1 页 / 共 5 页
字号:
/* * Implementation of the PortAudio API for Apple AUHAL * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. *  * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, 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. *//** @file pa_mac_core @ingroup hostapi_src @author Bjorn Roche @brief AUHAL implementation of PortAudio*//* FIXME: not all error conditions call PaUtil_SetLastHostErrorInfo() * PaMacCore_SetError() will do this. */#include "pa_mac_core_internal.h"#include <string.h> /* strlen(), memcmp() etc. */#include "pa_mac_core.h"#include "pa_mac_core_utilities.h"#include "pa_mac_core_blocking.h"/* prototypes for functions declared in this file */#ifdef __cplusplusextern "C"{#endif /* __cplusplus */PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );#ifdef __cplusplus}#endif /* __cplusplus */#define RING_BUFFER_ADVANCE_DENOMINATOR (4)static void Terminate( struct PaUtilHostApiRepresentation *hostApi );static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,                                  const PaStreamParameters *inputParameters,                                  const PaStreamParameters *outputParameters,                                  double sampleRate );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 );static PaError CloseStream( PaStream* stream );static PaError StartStream( PaStream *stream );static PaError StopStream( PaStream *stream );static PaError AbortStream( PaStream *stream );static PaError IsStreamStopped( PaStream *s );static PaError IsStreamActive( PaStream *stream );static PaTime GetStreamTime( PaStream *stream );static void setStreamStartTime( PaStream *stream );static OSStatus AudioIOProc( void *inRefCon,                               AudioUnitRenderActionFlags *ioActionFlags,                               const AudioTimeStamp *inTimeStamp,                               UInt32 inBusNumber,                               UInt32 inNumberFrames,                               AudioBufferList *ioData );static double GetStreamCpuLoad( PaStream* stream );static PaError GetChannelInfo( PaMacAUHAL *auhalHostApi,                               PaDeviceInfo *deviceInfo,                               AudioDeviceID macCoreDeviceId,                               int isInput);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 );/* for setting errors. */#define PA_AUHAL_SET_LAST_HOST_ERROR( errorCode, errorText ) \    PaUtil_SetLastHostErrorInfo( paInDevelopment, errorCode, errorText )/*currently, this is only used in initialization, but it might be modified  to be used when the list of devices changes.*/static PaError gatherDeviceInfo(PaMacAUHAL *auhalHostApi){    UInt32 size;    UInt32 propsize;    VVDBUG(("gatherDeviceInfo()\n"));    /* -- free any previous allocations -- */    if( auhalHostApi->devIds )        PaUtil_GroupFreeMemory(auhalHostApi->allocations, auhalHostApi->devIds);    auhalHostApi->devIds = NULL;    /* -- figure out how many devices there are -- */    AudioHardwareGetPropertyInfo( kAudioHardwarePropertyDevices,                                  &propsize,                                  NULL );    auhalHostApi->devCount = propsize / sizeof( AudioDeviceID );    VDBUG( ( "Found %ld device(s).\n", auhalHostApi->devCount ) );    /* -- copy the device IDs -- */    auhalHostApi->devIds = (AudioDeviceID *)PaUtil_GroupAllocateMemory(                             auhalHostApi->allocations,                             propsize );    if( !auhalHostApi->devIds )        return paInsufficientMemory;    AudioHardwareGetProperty( kAudioHardwarePropertyDevices,                                  &propsize,                                  auhalHostApi->devIds );#ifdef MAC_CORE_VERBOSE_DEBUG    {       int i;       for( i=0; i<auhalHostApi->devCount; ++i )          printf( "Device %d\t: %ld\n", i, auhalHostApi->devIds[i] );    }#endif    size = sizeof(AudioDeviceID);    auhalHostApi->defaultIn  = kAudioDeviceUnknown;    auhalHostApi->defaultOut = kAudioDeviceUnknown;    /* determine the default device. */    /* I am not sure how these calls to AudioHardwareGetProperty()       could fail, but in case they do, we use the first available       device as the default. */    if( 0 != AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,                     &size,                     &auhalHostApi->defaultIn) ) {       int i;       auhalHostApi->defaultIn  = kAudioDeviceUnknown;       VDBUG(("Failed to get default input device from OS."));       VDBUG((" I will substitute the first available input Device."));       for( i=0; i<auhalHostApi->devCount; ++i ) {          PaDeviceInfo devInfo;          if( 0 != GetChannelInfo( auhalHostApi, &devInfo,                                   auhalHostApi->devIds[i], TRUE ) )             if( devInfo.maxInputChannels ) {                auhalHostApi->defaultIn = auhalHostApi->devIds[i];                break;             }       }    }       if( 0 != AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,                     &size,                     &auhalHostApi->defaultOut) ) {       int i;       auhalHostApi->defaultIn  = kAudioDeviceUnknown;       VDBUG(("Failed to get default output device from OS."));       VDBUG((" I will substitute the first available output Device."));       for( i=0; i<auhalHostApi->devCount; ++i ) {          PaDeviceInfo devInfo;          if( 0 != GetChannelInfo( auhalHostApi, &devInfo,                                   auhalHostApi->devIds[i], FALSE ) )             if( devInfo.maxOutputChannels ) {                auhalHostApi->defaultOut = auhalHostApi->devIds[i];                break;             }       }    }       VDBUG( ( "Default in : %ld\n", auhalHostApi->defaultIn  ) );    VDBUG( ( "Default out: %ld\n", auhalHostApi->defaultOut ) );    return paNoError;}static PaError GetChannelInfo( PaMacAUHAL *auhalHostApi,                               PaDeviceInfo *deviceInfo,                               AudioDeviceID macCoreDeviceId,                               int isInput){    UInt32 propSize;    PaError err = paNoError;    UInt32 i;    int numChannels = 0;    AudioBufferList *buflist = NULL;    UInt32 frameLatency;    VVDBUG(("GetChannelInfo()\n"));    /* Get the number of channels from the stream configuration.       Fail if we can't get this. */    err = ERR(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamConfiguration, &propSize, NULL));    if (err)        return err;    buflist = PaUtil_AllocateMemory(propSize);    if( !buflist )       return paInsufficientMemory;    err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamConfiguration, &propSize, buflist));    if (err)        goto error;    for (i = 0; i < buflist->mNumberBuffers; ++i)        numChannels += buflist->mBuffers[i].mNumberChannels;    if (isInput)        deviceInfo->maxInputChannels = numChannels;    else        deviceInfo->maxOutputChannels = numChannels;          if (numChannels > 0) /* do not try to retrieve the latency if there is no channels. */    {       /* Get the latency.  Don't fail if we can't get this. */       /* default to something reasonable */       deviceInfo->defaultLowInputLatency = .01;       deviceInfo->defaultHighInputLatency = .10;       deviceInfo->defaultLowOutputLatency = .01;       deviceInfo->defaultHighOutputLatency = .10;       propSize = sizeof(UInt32);       err = WARNING(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyLatency, &propSize, &frameLatency));       if (!err)       {          /** FEEDBACK:           * This code was arrived at by trial and error, and some extentive, but not exhaustive           * testing. Sebastien Beaulieu <seb@plogue.com> has suggested using           * kAudioDevicePropertyLatency + kAudioDevicePropertySafetyOffset + buffer size instead.           * At the time this code was written, many users were reporting dropouts with audio           * programs that probably used this formula. This was probably           * around 10.4.4, and the problem is probably fixed now. So perhaps           * his formula should be reviewed and used.           * */          double secondLatency = frameLatency / deviceInfo->defaultSampleRate;          if (isInput)          {             deviceInfo->defaultLowInputLatency = 3 * secondLatency;             deviceInfo->defaultHighInputLatency = 3 * 10 * secondLatency;          }          else          {             deviceInfo->defaultLowOutputLatency = 3 * secondLatency;             deviceInfo->defaultHighOutputLatency = 3 * 10 * secondLatency;          }       }    }    PaUtil_FreeMemory( buflist );    return paNoError; error:    PaUtil_FreeMemory( buflist );    return err;}static PaError InitializeDeviceInfo( PaMacAUHAL *auhalHostApi,                                     PaDeviceInfo *deviceInfo,                                     AudioDeviceID macCoreDeviceId,                                     PaHostApiIndex hostApiIndex ){    Float64 sampleRate;    char *name;    PaError err = paNoError;    UInt32 propSize;    VVDBUG(("InitializeDeviceInfo(): macCoreDeviceId=%ld\n", macCoreDeviceId));    memset(deviceInfo, 0, sizeof(deviceInfo));

⌨️ 快捷键说明

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