| 
							- /*
 - Copyright (C) 2010 Grame
 - 
 - This program is free software; you can redistribute it and/or modify
 - it under the terms of the GNU General Public License as published by
 - the Free Software Foundation; either version 2 of the License, or
 - (at your option) any later version.
 - 
 - This program is distributed in the hope that it will be useful,
 - but WITHOUT ANY WARRANTY; without even the implied warranty of
 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - GNU General Public License for more details.
 - 
 - You should have received a copy of the GNU General Public License
 - along with this program; if not, write to the Free Software
 - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 - 
 - */
 - 
 - #include "TiPhoneCoreAudioRenderer.h"
 - 
 - static void PrintStreamDesc(AudioStreamBasicDescription *inDesc)
 - {
 -     printf("- - - - - - - - - - - - - - - - - - - -\n");
 -     printf("  Sample Rate:%f\n", inDesc->mSampleRate);
 -     printf("  Format ID:%.*s\n", (int) sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID);
 -     printf("  Format Flags:%lX\n", inDesc->mFormatFlags);
 -     printf("  Bytes per Packet:%ld\n", inDesc->mBytesPerPacket);
 -     printf("  Frames per Packet:%ld\n", inDesc->mFramesPerPacket);
 -     printf("  Bytes per Frame:%ld\n", inDesc->mBytesPerFrame);
 -     printf("  Channels per Frame:%ld\n", inDesc->mChannelsPerFrame);
 -     printf("  Bits per Channel:%ld\n", inDesc->mBitsPerChannel);
 -     printf("- - - - - - - - - - - - - - - - - - - -\n");
 - }
 - 
 - static void printError(OSStatus err)
 - {
 -     switch (err) {
 -       	case kAudioConverterErr_FormatNotSupported:
 -             printf("error code : kAudioConverterErr_FormatNotSupported\n");
 -             break;
 -         case kAudioConverterErr_OperationNotSupported:
 -             printf("error code : kAudioConverterErr_OperationNotSupported\n");
 -             break;
 -         case kAudioConverterErr_PropertyNotSupported:
 -             printf("error code : kAudioConverterErr_PropertyNotSupported\n");
 -             break;
 -         case kAudioConverterErr_InvalidInputSize:
 -             printf("error code : kAudioConverterErr_InvalidInputSize\n");
 -             break;
 -         case kAudioConverterErr_InvalidOutputSize:
 -             printf("error code : kAudioConverterErr_InvalidOutputSize\n");
 -             break;
 -         case kAudioConverterErr_UnspecifiedError:
 -             printf("error code : kAudioConverterErr_UnspecifiedError\n");
 -             break;
 -         case kAudioConverterErr_BadPropertySizeError:
 -             printf("error code : kAudioConverterErr_BadPropertySizeError\n");
 -             break;
 -         case kAudioConverterErr_RequiresPacketDescriptionsError:
 -             printf("error code : kAudioConverterErr_RequiresPacketDescriptionsError\n");
 -             break;
 -         case kAudioConverterErr_InputSampleRateOutOfRange:
 -             printf("error code : kAudioConverterErr_InputSampleRateOutOfRange\n");
 -             break;
 -         case kAudioConverterErr_OutputSampleRateOutOfRange:
 -             printf("error code : kAudioConverterErr_OutputSampleRateOutOfRange\n");
 -             break;
 -         default:
 -             printf("error code : unknown\n");
 -             break;
 -     }
 - }
 - 
 - OSStatus TiPhoneCoreAudioRenderer::Render(void *inRefCon,
 -                                          AudioUnitRenderActionFlags *ioActionFlags,
 -                                          const AudioTimeStamp *inTimeStamp,
 -                                          UInt32,
 -                                          UInt32 inNumberFrames,
 -                                          AudioBufferList *ioData)
 - {
 -     TiPhoneCoreAudioRendererPtr renderer = (TiPhoneCoreAudioRendererPtr)inRefCon;
 -     AudioUnitRender(renderer->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, renderer->fCAInputData);
 -     
 -     float coef = float(LONG_MAX);
 -     float inv_coef = 1.f/float(LONG_MAX);
 -     
 -     for (int chan = 0; chan < renderer->fDevNumInChans; chan++) {
 -         for (int frame = 0; frame < inNumberFrames; frame++) {
 -             renderer->fInChannel[chan][frame] = float(((int*)renderer->fCAInputData->mBuffers[chan].mData)[frame]) * inv_coef;
 -         }
 -     }
 -     
 -     renderer->PerformAudioCallback((int)inNumberFrames);
 -     
 -     for (int chan = 0; chan < renderer->fDevNumOutChans; chan++) {
 -         for (int frame = 0; frame < inNumberFrames; frame++) {
 -            ((int*)ioData->mBuffers[chan].mData)[frame] = int(renderer->fOutChannel[chan][frame] * coef); 
 -         }
 -     }
 -     
 -   	return 0;
 - }
 - 
 - void TiPhoneCoreAudioRenderer::InterruptionListener(void *inClientData, UInt32 inInterruption)
 - {
 - 	TiPhoneCoreAudioRenderer *obj = (TiPhoneCoreAudioRenderer*)inClientData;
 - 	printf("Session interrupted! --- %s ---", inInterruption == kAudioSessionBeginInterruption ? "Begin Interruption" : "End Interruption");
 - 	
 - 	if (inInterruption == kAudioSessionEndInterruption) {
 - 		// make sure we are again the active session
 - 		AudioSessionSetActive(true);
 - 		AudioOutputUnitStart(obj->fAUHAL);
 - 	}
 - 	
 - 	if (inInterruption == kAudioSessionBeginInterruption) {
 - 		AudioOutputUnitStop(obj->fAUHAL);
 -     }
 - }
 - 
 - int TiPhoneCoreAudioRenderer::Open(int bufferSize, int samplerate)
 - {
 -     OSStatus err1;
 -     UInt32 outSize;
 -     UInt32 enableIO;
 - 	AudioStreamBasicDescription srcFormat, dstFormat;
 -     
 -     printf("Open fDevNumInChans = %ld fDevNumOutChans = %ld bufferSize = %ld samplerate = %ld\n", fDevNumInChans, fDevNumOutChans, bufferSize, samplerate);
 - 	  
 -     // Initialize and configure the audio session
 -     err1 = AudioSessionInitialize(NULL, NULL, InterruptionListener, this);
 -     if (err1 != noErr) {
 -         printf("Couldn't initialize audio session\n");
 -         printError(err1);
 -         return OPEN_ERR;
 -     }
 -     
 -     err1 = AudioSessionSetActive(true);
 -     if (err1 != noErr) {
 -         printf("Couldn't set audio session active\n");
 -         printError(err1);
 -         return OPEN_ERR;
 -     }
 -   			
 -     UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord;
 - 	err1 = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory);
 -     if (err1 != noErr) {
 -         printf("Couldn't set audio category\n");
 -         printError(err1);
 -         return OPEN_ERR;
 -     }
 -     
 -    	//err1 = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, propListener, self), "couldn't set property listener");
 -     
 -     Float64 hwSampleRate;
 -     outSize = sizeof(hwSampleRate);
 - 	err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &outSize, &hwSampleRate);
 -     if (err1 != noErr) {
 -         printf("Couldn't get hw sample rate\n");
 -         printError(err1);
 -         return OPEN_ERR;
 -     } else {
 -          printf("Get hw sample rate %f\n", hwSampleRate);
 -     }
 -     
 -     Float32 hwBufferSize;
 -     outSize = sizeof(hwBufferSize);
 - 	err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareIOBufferDuration, &outSize, &hwBufferSize);
 -     if (err1 != noErr) {
 -         printf("Couldn't get hw buffer duration\n");
 -         printError(err1);
 -         return OPEN_ERR;
 -     } else {
 -          printf("Get hw buffer duration %f\n", hwBufferSize);
 -     }
 - 
 -     UInt32 hwInput;
 -     outSize = sizeof(hwInput);
 - 	err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels, &outSize, &hwInput);
 -     if (err1 != noErr) {
 -         printf("Couldn't get hw input channels\n");
 -         printError(err1);
 -         return OPEN_ERR;
 -     } else {
 -         printf("Get hw input channels %d\n", hwInput);
 -     }
 - 
 -     UInt32 hwOutput;
 -     outSize = sizeof(hwOutput);
 - 	err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputNumberChannels, &outSize, &hwOutput);
 -     if (err1 != noErr) {
 -         printf("Couldn't get hw output channels\n");
 -         printError(err1);
 -         return OPEN_ERR;
 -     } else {
 -         printf("Get hw output channels %d\n", hwOutput);
 -     }
 - 			
 -     Float32 preferredBufferSize = float(bufferSize) / float(samplerate);
 -     printf("preferredBufferSize %f \n", preferredBufferSize);
 -     
 - 	err1 = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredBufferSize), &preferredBufferSize);
 -     if (err1 != noErr) {
 -         printf("Couldn't set i/o buffer duration\n");
 -         printError(err1);
 -         return OPEN_ERR;
 -     }
 -   	
 -     Float64 preferredSamplerate = float(samplerate);
 - 	err1 = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareSampleRate, sizeof(preferredSamplerate), &preferredSamplerate);
 -     if (err1 != noErr) {
 -         printf("Couldn't set i/o sample rate\n");
 -         printError(err1);
 -         return OPEN_ERR;
 -     }
 -   	
 -     // AUHAL
 -     AudioComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple, 0, 0};
 -     AudioComponent HALOutput = AudioComponentFindNext(NULL, &cd);
 - 
 -     err1 = AudioComponentInstanceNew(HALOutput, &fAUHAL);
 -     if (err1 != noErr) {
 - 		printf("Error calling OpenAComponent\n");
 -         printError(err1);
 -         goto error;
 - 	}
 - 
 -     enableIO = 1;
 -     err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO));
 -     if (err1 != noErr) {
 -         printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output\n");
 -         printError(err1);
 -         goto error;
 -     }
 -     
 -     enableIO = 1;
 -     err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO));
 -     if (err1 != noErr) {
 -         printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input\n");
 -         printError(err1);
 -         goto error;
 -     }
 -     
 -     UInt32 maxFPS;
 -     outSize = sizeof(maxFPS);
 -     err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, &maxFPS, &outSize);
 -     if (err1 != noErr) {
 -         printf("Couldn't get kAudioUnitProperty_MaximumFramesPerSlice\n");
 -         printError(err1);
 -         goto error;
 -     } else {
 -         printf("Get kAudioUnitProperty_MaximumFramesPerSlice %d\n", maxFPS);
 -     }
 -    
 -     err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&bufferSize, sizeof(UInt32));
 -     if (err1 != noErr) {
 -         printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n");
 -         printError(err1);
 -         goto error;
 -     }
 - 
 -     err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, (UInt32*)&bufferSize, sizeof(UInt32));
 -     if (err1 != noErr) {
 -         printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n");
 -         printError(err1);
 -         goto error;
 -     }
 - 
 -     err1 = AudioUnitInitialize(fAUHAL);
 -     if (err1 != noErr) {
 - 		printf("Cannot initialize AUHAL unit\n");
 - 		printError(err1);
 -         goto error;
 - 	}
 - 
 -     // Setting format
 -   	
 -     if (fDevNumInChans > 0) {
 -         outSize = sizeof(AudioStreamBasicDescription);
 -         err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &outSize);
 -         if (err1 != noErr) {
 -             printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
 -             printError(err1);
 -         }
 -         PrintStreamDesc(&srcFormat);
 -         
 -         srcFormat.mFormatID = kAudioFormatLinearPCM;
 -         srcFormat.mFormatFlags = kAudioFormatFlagsCanonical | kLinearPCMFormatFlagIsNonInterleaved;
 -         srcFormat.mBytesPerPacket = sizeof(AudioUnitSampleType);
 -         srcFormat.mFramesPerPacket = 1;
 -         srcFormat.mBytesPerFrame = sizeof(AudioUnitSampleType);
 -         srcFormat.mChannelsPerFrame = fDevNumInChans;
 -         srcFormat.mBitsPerChannel = 32;
 -         
 -         PrintStreamDesc(&srcFormat);
 -         
 -         err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription));
 -         if (err1 != noErr) {
 -             printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
 -             printError(err1);
 -         }    
 -     }
 - 	
 -     if (fDevNumOutChans > 0) {
 -         outSize = sizeof(AudioStreamBasicDescription);
 -         err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &outSize);
 -         if (err1 != noErr) {
 -             printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input\n");
 -             printError(err1);
 -         }
 -         PrintStreamDesc(&dstFormat);
 -         
 -         dstFormat.mFormatID = kAudioFormatLinearPCM;
 -         dstFormat.mFormatFlags = kAudioFormatFlagsCanonical | kLinearPCMFormatFlagIsNonInterleaved;
 -         dstFormat.mBytesPerPacket = sizeof(AudioUnitSampleType);
 -         dstFormat.mFramesPerPacket = 1;
 -         dstFormat.mBytesPerFrame = sizeof(AudioUnitSampleType);
 -         dstFormat.mChannelsPerFrame = fDevNumOutChans;
 -         dstFormat.mBitsPerChannel = 32;
 -         
 -         PrintStreamDesc(&dstFormat);
 - 
 -         err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription));
 -         if (err1 != noErr) {
 -             printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input\n");
 -             printError(err1);
 -         }
 -     }
 -     
 -     if (fDevNumInChans > 0 && fDevNumOutChans == 0) {
 -         AURenderCallbackStruct output;
 -         output.inputProc = Render;
 -         output.inputProcRefCon = this;
 -         err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &output, sizeof(output));
 -         if (err1 != noErr) {
 -             printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1\n");
 -             printError(err1);
 -             goto error;
 -         }
 -     } else {
 -         AURenderCallbackStruct output;
 -         output.inputProc = Render;
 -         output.inputProcRefCon = this;
 -         err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &output, sizeof(output));
 -         if (err1 != noErr) {
 -             printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0\n");
 -             printError(err1);
 -             goto error;
 -         }
 -     }
 -     
 -     // Prepare buffers
 -     fCAInputData = (AudioBufferList*)malloc(sizeof(UInt32) + fDevNumInChans * sizeof(AudioBuffer));
 -     fCAInputData->mNumberBuffers = fDevNumInChans;
 -     for (int i = 0; i < fDevNumInChans; i++) {
 -         fCAInputData->mBuffers[i].mNumberChannels = 1;
 -         fCAInputData->mBuffers[i].mDataByteSize = bufferSize * sizeof(int);
 -         fCAInputData->mBuffers[i].mData = malloc(bufferSize * sizeof(int));
 -     }
 -     
 -     /*
 -     // Add listeners
 -     err1 = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDeviceProcessorOverload, DeviceNotificationCallback, this);
 -     if (err != noErr) {
 -         jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDeviceProcessorOverload");
 -         printError(err);
 -         return -1;
 -     }
 -     */
 - 
 -     return NO_ERR;
 - 
 - error:
 -     AudioUnitUninitialize(fAUHAL);
 -     AudioComponentInstanceDispose(fAUHAL);
 -     return OPEN_ERR;
 - }
 - 
 - int TiPhoneCoreAudioRenderer::Close()
 - {
 -     AudioUnitUninitialize(fAUHAL);
 -     AudioComponentInstanceDispose(fAUHAL);
 -     if (fCAInputData) {
 -          // Free buffers and list
 -         for (int i = 0; i < fDevNumInChans; i++) {
 -             free(fCAInputData->mBuffers[i].mData);
 -         }
 -         free(fCAInputData);
 -     }
 -     return NO_ERR;
 - }
 - 
 - int TiPhoneCoreAudioRenderer::Start()
 - {
 -     AudioSessionSetActive(true);
 - 	OSStatus err = AudioOutputUnitStart(fAUHAL);
 -   
 -     if (err != noErr) {
 -         printf("Error while opening device : device open error \n");
 -         return OPEN_ERR;
 -     } else {
 -         return NO_ERR;
 - 	}
 - }
 - 
 - int TiPhoneCoreAudioRenderer::Stop()
 - {
 -     OSStatus err = AudioOutputUnitStop(fAUHAL);
 - 
 -     if (err != noErr) {
 -         printf("Error while closing device : device close error \n");
 -         return OPEN_ERR;
 -     } else {
 -         return NO_ERR;
 - 	}
 - }
 
 
  |