X-Git-Url: https://scm.cri.ensmp.fr/git/Faustine.git/blobdiff_plain/1059e1cc0c2ecfa237406949aa26155b6a5b9154..66f23d4fabf89ad09adbd4dfc15ac6b5b2b7da83:/interpreter/preprocessor/faust-0.9.47mr3/architecture/iphone-cocoa.cpp diff --git a/interpreter/preprocessor/faust-0.9.47mr3/architecture/iphone-cocoa.cpp b/interpreter/preprocessor/faust-0.9.47mr3/architecture/iphone-cocoa.cpp new file mode 100644 index 0000000..cf3858e --- /dev/null +++ b/interpreter/preprocessor/faust-0.9.47mr3/architecture/iphone-cocoa.cpp @@ -0,0 +1,578 @@ +/************************************************************************ + + IMPORTANT NOTE : this file contains two clearly delimited sections : + the ARCHITECTURE section (in two parts) and the USER section. Each section + is governed by its own copyright and license. Please check individually + each section for license and copyright information. +*************************************************************************/ + +/*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/ + +/************************************************************************ + FAUST Architecture File + Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale + --------------------------------------------------------------------- + This Architecture section 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 3 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, see . + + EXCEPTION : As a special exception, you may create a larger work + that contains this FAUST architecture section and distribute + that work under terms of your choice, so long as this FAUST + architecture section is not modified. + + + ************************************************************************ + ************************************************************************/ + +/* link with */ +#include +/* link with */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace std; + +/****************************************************************************** +******************************************************************************* + + VECTOR INTRINSICS + +******************************************************************************* +*******************************************************************************/ + +<> + +/****************************************************************************** +******************************************************************************* + + USER INTERFACE + +******************************************************************************* +*******************************************************************************/ + +#include "CocoaUI.h" +#include "audio/dsp.h" +#include "misc.h" + +/********************END ARCHITECTURE SECTION (part 1/2)****************/ + +/**************************BEGIN USER SECTION **************************/ + +<> + +/***************************END USER SECTION ***************************/ + +/*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/ + +mydsp DSP; + +/****************************************************************************** +******************************************************************************* + + COREAUDIO INTERFACE + +******************************************************************************* +*******************************************************************************/ + +#define MAX_CHANNELS 256 +#define OPEN_ERR -1 +#define NO_ERR 0 + +class TiPhoneCoreAudioRenderer +{ + + private: + + AudioUnit fAUHAL; + + int fDevNumInChans; + int fDevNumOutChans; + + int fHWNumInChans; + int fHWNumOutChans; + + AudioBufferList* fCAInputData; + + float* fInChannel[MAX_CHANNELS]; + float* fOutChannel[MAX_CHANNELS]; + + static OSStatus Render(void *inRefCon, + AudioUnitRenderActionFlags *ioActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList *ioData); + + static void InterruptionListener(void *inClientData, UInt32 inInterruption); + + public: + + TiPhoneCoreAudioRenderer(int input, int output) + :fDevNumInChans(input), fDevNumOutChans(output), fCAInputData(NULL) + { + memset(fInChannel, 0, sizeof(float*) * MAX_CHANNELS); + memset(fOutChannel, 0, sizeof(float*) * MAX_CHANNELS); + + for (int i = 0; i < fDevNumInChans; i++) { + fInChannel[i] = new float[8192]; + } + + for (int i = 0; i < fDevNumOutChans; i++) { + fOutChannel[i] = new float[8192]; + } + } + + virtual ~TiPhoneCoreAudioRenderer() + { + for (int i = 0; i < fDevNumInChans; i++) { + delete[] fInChannel[i]; + } + + for (int i = 0; i < fDevNumOutChans; i++) { + delete[] fOutChannel[i]; + } + + if (fCAInputData) { + for (int i = 0; i < fDevNumInChans; i++) { + free(fCAInputData->mBuffers[i].mData); + } + free(fCAInputData); + } + } + + int Open(int bufferSize, int sampleRate); + int Close(); + + int Start(); + int Stop(); + +}; + +typedef TiPhoneCoreAudioRenderer * TiPhoneCoreAudioRendererPtr; + +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); + + if (renderer->fHWNumInChans == 1) { + // Mono ==> stereo + for (int chan = 0; chan < renderer->fDevNumInChans; chan++) { + for (int frame = 0; frame < inNumberFrames; frame++) { + renderer->fInChannel[chan][frame] = float(((int*)renderer->fCAInputData->mBuffers[0].mData)[frame]) * inv_coef; + } + } + } else { + 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; + } + } + } + + DSP.compute((int)inNumberFrames, renderer->fInChannel, renderer->fOutChannel); + + for (int chan = 0; chan < renderer->fDevNumOutChans; chan++) { + for (int frame = 0; frame < inNumberFrames; frame++) { + ((long*)ioData->mBuffers[chan].mData)[frame] = long(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("OpenDefault 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); + } + + outSize = sizeof(fHWNumInChans); + err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels, &outSize, &fHWNumInChans); + if (err1 != noErr) { + printf("Couldn't get hw input channels\n"); + printError(err1); + return OPEN_ERR; + } else { + printf("Get hw input channels %d\n", fHWNumInChans); + } + + outSize = sizeof(fHWNumOutChans); + err1 = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputNumberChannels, &outSize, &fHWNumOutChans); + if (err1 != noErr) { + printf("Couldn't get hw output channels\n"); + printError(err1); + return OPEN_ERR; + } else { + printf("Get hw output channels %d\n", fHWNumOutChans); + } + + 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)); + } + + return NO_ERR; + +error: + AudioUnitUninitialize(fAUHAL); + AudioComponentInstanceDispose(fAUHAL); + return OPEN_ERR; +} + +int TiPhoneCoreAudioRenderer::Close() +{ + AudioUnitUninitialize(fAUHAL); + AudioComponentInstanceDispose(fAUHAL); + 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; + } +} + + +/********************END ARCHITECTURE SECTION (part 2/2)****************/ + +