70
70
#include "pa_mac_core_utilities.h"
71
71
#include "pa_mac_core_blocking.h"
77
#endif /* __cplusplus */
73
79
/* prototypes for functions declared in this file */
78
#endif /* __cplusplus */
80
81
PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
84
* Function declared in pa_mac_core.h. Sets up a PaMacCoreStreamInfoStruct
85
* with the requested flags and initializes channel map.
87
void PaMacCore_SetupStreamInfo( PaMacCoreStreamInfo *data, const unsigned long flags )
89
bzero( data, sizeof( PaMacCoreStreamInfo ) );
90
data->size = sizeof( PaMacCoreStreamInfo );
91
data->hostApiType = paCoreAudio;
94
data->channelMap = NULL;
95
data->channelMapSize = 0;
99
* Function declared in pa_mac_core.h. Adds channel mapping to a PaMacCoreStreamInfoStruct
101
void PaMacCore_SetupChannelMap( PaMacCoreStreamInfo *data, const SInt32 * const channelMap, const unsigned long channelMapSize )
103
data->channelMap = channelMap;
104
data->channelMapSize = channelMapSize;
106
static char *channelName = NULL;
107
static int channelNameSize = 0;
108
static bool ensureChannelNameSize( int size )
110
if( size >= channelNameSize ) {
112
channelName = (char *) malloc( ( channelNameSize = size ) + 1 );
121
* Function declared in pa_mac_core.h. retrives channel names.
123
const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input )
125
struct PaUtilHostApiRepresentation *hostApi;
128
err = PaUtil_GetHostApiRepresentation( &hostApi, paCoreAudio );
129
assert(err == paNoError);
130
PaMacAUHAL *macCoreHostApi = (PaMacAUHAL*)hostApi;
131
AudioDeviceID hostApiDevice = macCoreHostApi->devIds[device];
135
error = AudioDeviceGetPropertyInfo( hostApiDevice,
138
kAudioDevicePropertyChannelName,
144
bool isDeviceName = false;
145
size = sizeof( name );
146
error = AudioDeviceGetProperty( hostApiDevice,
149
kAudioDevicePropertyChannelNameCFString,
152
if( error ) { //as a last-ditch effort, get the device name. Later we'll append the channel number.
153
size = sizeof( name );
154
error = AudioDeviceGetProperty( hostApiDevice,
157
kAudioDevicePropertyDeviceNameCFString,
165
name = CFStringCreateWithFormat( NULL, NULL, CFSTR( "%@: %d"), name, channelIndex + 1 );
168
CFIndex length = CFStringGetLength(name);
169
while( ensureChannelNameSize( length * sizeof(UniChar) + 1 ) ) {
170
if( CFStringGetCString( name, channelName, channelNameSize, kCFStringEncodingUTF8 ) ) {
184
//continue with C string:
185
if( !ensureChannelNameSize( size ) )
188
error = AudioDeviceGetProperty( hostApiDevice,
191
kAudioDevicePropertyChannelName,
206
AudioDeviceID PaMacCore_GetStreamInputDevice( PaStream* s )
208
PaMacCoreStream *stream = (PaMacCoreStream*)s;
209
VVDBUG(("PaMacCore_GetStreamInputHandle()\n"));
211
return ( stream->inputDevice );
214
AudioDeviceID PaMacCore_GetStreamOutputDevice( PaStream* s )
216
PaMacCoreStream *stream = (PaMacCoreStream*)s;
217
VVDBUG(("PaMacCore_GetStreamOutputHandle()\n"));
219
return ( stream->outputDevice );
82
222
#ifdef __cplusplus
84
224
#endif /* __cplusplus */
621
760
AURenderCallbackStruct rcbs;
622
761
unsigned long macInputStreamFlags = paMacCorePlayNice;
623
762
unsigned long macOutputStreamFlags = paMacCorePlayNice;
763
SInt32 const *inChannelMap = NULL;
764
SInt32 const *outChannelMap = NULL;
765
unsigned long inChannelMapSize = 0;
766
unsigned long outChannelMapSize = 0;
625
768
VVDBUG(("OpenAndSetupOneAudioUnit(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld, requestedFramesPerBuffer=%ld\n",
626
769
inStreamParams ? inStreamParams->channelCount : -1,
639
782
/* -- get the user's api specific info, if they set any -- */
640
783
if( inStreamParams && inStreamParams->hostApiSpecificStreamInfo )
641
785
macInputStreamFlags=
642
((paMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo)
786
((PaMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo)
788
inChannelMap = ((PaMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo)
790
inChannelMapSize = ((PaMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo)
644
793
if( outStreamParams && outStreamParams->hostApiSpecificStreamInfo )
645
795
macOutputStreamFlags=
646
((paMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo)
796
((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo)
798
outChannelMap = ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo)
800
outChannelMapSize = ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo)
648
803
/* Override user's flags here, if desired for testing. */
753
909
requestedFramesPerBuffer,
754
910
actualInputFramesPerBuffer );
755
911
if( paResult ) goto error;
756
if( macInputStreamFlags & paMacCore_ChangeDeviceParameters ) {
912
if( macInputStreamFlags & paMacCoreChangeDeviceParameters ) {
757
913
bool requireExact;
758
requireExact=macInputStreamFlags&paMacCore_FailIfConversionRequired;
914
requireExact=macInputStreamFlags & paMacCoreFailIfConversionRequired;
759
915
paResult = setBestSampleRateForDevice( *audioDevice, FALSE,
760
916
requireExact, sampleRate );
761
917
if( paResult ) goto error;
771
927
requestedFramesPerBuffer,
772
928
actualOutputFramesPerBuffer );
773
929
if( paResult ) goto error;
774
if( macOutputStreamFlags & paMacCore_ChangeDeviceParameters ) {
930
if( macOutputStreamFlags & paMacCoreChangeDeviceParameters ) {
775
931
bool requireExact;
776
requireExact=macOutputStreamFlags&paMacCore_FailIfConversionRequired;
932
requireExact=macOutputStreamFlags & paMacCoreFailIfConversionRequired;
777
933
paResult = setBestSampleRateForDevice( *audioDevice, TRUE,
778
934
requireExact, sampleRate );
779
935
if( paResult ) goto error;
964
1120
sizeof(rcbs)) );
966
/*IMPLEMENTME: may need to worry about channel mapping.*/
1122
/* channel mapping. */
1125
UInt32 mapSize = inChannelMapSize *sizeof(SInt32);
1127
//for each channel of desired input, map the channel from
1128
//the device's output channel.
1129
ERR_WRAP( AudioUnitSetProperty(*audioUnit,
1130
kAudioOutputUnitProperty_ChannelMap,
1131
kAudioUnitScope_Output,
1138
UInt32 mapSize = outChannelMapSize *sizeof(SInt32);
1140
//for each channel of desired output, map the channel from
1141
//the device's output channel.
1142
ERR_WRAP(AudioUnitSetProperty(*audioUnit,
1143
kAudioOutputUnitProperty_ChannelMap,
1144
kAudioUnitScope_Output,
968
1149
/* initialize the audio unit */
969
1150
ERR_WRAP( AudioUnitInitialize(*audioUnit) );
1449
1629
void *dummyData;
1450
1630
long dummySize;
1451
RingBuffer *rb = (RingBuffer *) inUserData;
1631
PaUtilRingBuffer *rb = (PaUtilRingBuffer *) inUserData;
1453
1633
VVDBUG(("ringBufferIOProc()\n"));
1455
1635
assert( sizeof( UInt32 ) == sizeof( long ) );
1456
if( RingBuffer_GetReadAvailable( rb ) == 0 ) {
1636
if( PaUtil_GetRingBufferReadAvailable( rb ) == 0 ) {
1457
1637
*outData = NULL;
1458
1638
*ioDataSize = 0;
1459
1639
return RING_BUFFER_EMPTY;
1461
RingBuffer_GetReadRegions( rb, *ioDataSize,
1462
outData, (long *)ioDataSize,
1463
&dummyData, &dummySize );
1641
PaUtil_GetRingBufferReadRegions( rb, *ioDataSize,
1642
outData, (long *)ioDataSize,
1643
&dummyData, &dummySize );
1465
1645
assert( *ioDataSize );
1466
RingBuffer_AdvanceReadIndex( rb, *ioDataSize );
1646
PaUtil_AdvanceRingBufferReadIndex( rb, *ioDataSize );
1685
1865
framesProcessed =
1686
1866
PaUtil_EndBufferProcessing( &(stream->bufferProcessor),
1687
1867
&callbackResult );
1688
RingBuffer_AdvanceReadIndex(&stream->inputRingBuffer, size1 );
1868
PaUtil_AdvanceRingBufferReadIndex(&stream->inputRingBuffer, size1 );
1689
1869
} else if( ( size1 + size2 ) / ( flsz * inChan ) < frames ) {
1690
1870
/*we underflowed. take what data we can, zero the rest.*/
1691
float data[frames*inChan];
1871
unsigned char data[frames*inChan*flsz];
1693
1873
memcpy( data, data1, size1 );
1968
2164
if( stream->inputUnit )
1970
2166
ERR_WRAP(AudioOutputUnitStop(stream->inputUnit) );
2167
ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->inputUnit,1) );
1971
2168
ERR_WRAP(AudioUnitReset(stream->inputUnit,kAudioUnitScope_Global,1));
1973
2170
if( stream->outputUnit )
1975
2172
ERR_WRAP(AudioOutputUnitStop(stream->outputUnit));
2173
ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->outputUnit,0) );
1976
2174
ERR_WRAP(AudioUnitReset(stream->outputUnit,kAudioUnitScope_Global,0));
1979
2177
if( stream->inputRingBuffer.buffer ) {
1980
RingBuffer_Flush( &stream->inputRingBuffer );
2178
PaUtil_FlushRingBuffer( &stream->inputRingBuffer );
1981
2179
bzero( (void *)stream->inputRingBuffer.buffer,
1982
2180
stream->inputRingBuffer.bufferSize );
1983
2181
/* advance the write point a little, so we are reading from the
1984
2182
middle of the buffer. We'll need extra at the end because
1985
2183
testing has shown that this helps. */
1986
2184
if( stream->outputUnit )
1987
RingBuffer_AdvanceWriteIndex( &stream->inputRingBuffer,
1988
stream->inputRingBuffer.bufferSize
1989
/ RING_BUFFER_ADVANCE_DENOMINATOR );
2185
PaUtil_AdvanceRingBufferWriteIndex( &stream->inputRingBuffer,
2186
stream->inputRingBuffer.bufferSize
2187
/ RING_BUFFER_ADVANCE_DENOMINATOR );
1992
2190
stream->xrunFlags = 0;
2039
2237
return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
2042
/* Use this function to initialize a paMacCoreStreamInfo struct
2043
using the requested flags. */
2044
void paSetupMacCoreStreamInfo( paMacCoreStreamInfo *data, unsigned long flags )
2046
bzero( data, sizeof( paMacCoreStreamInfo ) );
2047
data->size = sizeof( paMacCoreStreamInfo );
2048
data->hostApiType = paCoreAudio;
2049
data->version = 0x01;
2050
data->flags = flags;
2053
AudioDeviceID PaMacCore_GetStreamInputDevice( PaStream* s )
2055
PaMacCoreStream *stream = (PaMacCoreStream*)s;
2056
VVDBUG(("PaMacCore_GetStreamInputHandle()\n"));
2058
return ( stream->inputDevice );
2061
AudioDeviceID PaMacCore_GetStreamOutputDevice( PaStream* s )
2063
PaMacCoreStream *stream = (PaMacCoreStream*)s;
2064
VVDBUG(("PaMacCore_GetStreamOutputHandle()\n"));
2066
return ( stream->outputDevice );