3 #include <AudioUnit/AudioUnit.h> 
    8 struct AudioDataRenderer
 
   16     int TotalNumberOfFrames;
 
   19     char* AudioDataBuffer;
 
   26     void* HandleChannelMixer;
 
   31         return IsInfiniteLoop || NumberOfLoops > 0;
 
   34     void CopyDataToBuffer(
char* &outBuffer, 
int nbFrameToCopy, 
int nbOfChannels)
 
   36         char* inPtr = AudioDataBuffer + 
sizeof(short) * nbOfChannels * CurrentFrame;
 
   37         int sizeToCopy = 
sizeof(short) * nbFrameToCopy * nbOfChannels;
 
   39         memcpy(outBuffer, inPtr, sizeToCopy);
 
   41         CurrentFrame += nbFrameToCopy;
 
   42         outBuffer += sizeToCopy;
 
   45     int AudioDataMixerCallback(uint busIndex, 
int totalNbOfFrameToWrite,  AudioBufferList* data)
 
   47         char* outPtr = (
char*)data->mBuffers[0].mData;
 
   49         int remainingFramesToWrite = totalNbOfFrameToWrite;
 
   50         while (remainingFramesToWrite > 0)
 
   52             int nbOfFrameToWrite = std::min(remainingFramesToWrite, (ShouldBeLooped() ? LoopEndPoint : TotalNumberOfFrames) - CurrentFrame);
 
   54             CopyDataToBuffer(outPtr, nbOfFrameToWrite, NumberOfChannels);
 
   56             remainingFramesToWrite -= nbOfFrameToWrite;
 
   59             if (ShouldBeLooped() && CurrentFrame >= LoopEndPoint)
 
   62                 CurrentFrame = LoopStartPoint;
 
   66             if (CurrentFrame >= TotalNumberOfFrames)
 
   68                 AudioUnitSetParameter((AudioUnit)HandleChannelMixer, kMultiChannelMixerParam_Enable, kAudioUnitScope_Input, busIndex, 0, 0);
 
   69                 AudioUnitSetParameter((AudioUnit)Handle3DMixer, k3DMixerParam_Enable, kAudioUnitScope_Input, busIndex, 0, 0);
 
   77                 int sizeToBlank = 
sizeof(short) * NumberOfChannels * remainingFramesToWrite;
 
   78                 memset(outPtr, 0, sizeToBlank);
 
   87     OSStatus RendererCallbackChannelMixer(uint busNumber, uint numberFrames, AudioBufferList* data)
 
   92         OSStatus ret = AudioDataMixerCallback(busNumber, (
int)numberFrames, data);
 
   97     OSStatus RendererCallback3DMixer(uint busNumber, uint numberFrames, AudioBufferList* data)
 
  102         return AudioDataMixerCallback(busNumber, (
int)numberFrames, data);
 
  106 static OSStatus NullRenderCallback (
void                        *inRefCon,
 
  107                                     AudioUnitRenderActionFlags  *ioActionFlags,
 
  108                                     const AudioTimeStamp        *inTimeStamp,
 
  110                                     UInt32                      inNumberFrames,
 
  111                                     AudioBufferList             *ioData)
 
  113     memset(ioData->mBuffers[0].mData, 0, ioData->mBuffers[0].mDataByteSize);
 
  118 static OSStatus DefaultRenderCallbackChannelMixer ( 
void                        *inRefCon,
 
  119                                                     AudioUnitRenderActionFlags  *ioActionFlags,
 
  120                                                     const AudioTimeStamp        *inTimeStamp,
 
  122                                                     UInt32                      inNumberFrames,
 
  123                                                     AudioBufferList             *ioData)
 
  125     return ((AudioDataRenderer*)inRefCon)->RendererCallbackChannelMixer(inBusNumber, inNumberFrames, ioData);
 
  128 static OSStatus DefaultRenderCallback3DMixer (  
void                        *inRefCon,
 
  129                                                 AudioUnitRenderActionFlags  *ioActionFlags,
 
  130                                                 const AudioTimeStamp        *inTimeStamp,
 
  132                                                 UInt32                      inNumberFrames,
 
  133                                                 AudioBufferList             *ioData)
 
  135     return ((AudioDataRenderer*)inRefCon)->RendererCallback3DMixer(inBusNumber, inNumberFrames, ioData);
 
  138 static AURenderCallbackStruct NullRenderCallbackStruct = { NullRenderCallback, NULL };
 
  140 static std::map<uint, AURenderCallbackStruct*> BusIndexToChannelMixerCallbackStructures;
 
  141 static std::map<uint, AURenderCallbackStruct*> BusIndexTo3DMixerCallbackStructures;
 
  143 extern "C" int SetInputRenderCallbackToChannelMixerDefault(
void* inUnit, uint element, 
void* userData)
 
  145     AURenderCallbackStruct* pCallbackData = 
new AURenderCallbackStruct;
 
  146     pCallbackData->inputProc = DefaultRenderCallbackChannelMixer;
 
  147     pCallbackData->inputProcRefCon = userData;
 
  149     int status = AudioUnitSetProperty((AudioUnit)inUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, element, pCallbackData, 
sizeof(AURenderCallbackStruct));
 
  152     if(BusIndexToChannelMixerCallbackStructures.find(element) != BusIndexToChannelMixerCallbackStructures.end())
 
  154         if(BusIndexToChannelMixerCallbackStructures[element] != NULL)
 
  156             delete BusIndexToChannelMixerCallbackStructures[element];
 
  157             BusIndexToChannelMixerCallbackStructures[element] = NULL;
 
  160     BusIndexToChannelMixerCallbackStructures[element] = pCallbackData;
 
  165 extern "C" int SetInputRenderCallbackTo3DMixerDefault(
void* inUnit, uint element, 
void* userData)
 
  167     AURenderCallbackStruct* pCallbackData = 
new AURenderCallbackStruct;
 
  168     pCallbackData->inputProc = DefaultRenderCallback3DMixer;
 
  169     pCallbackData->inputProcRefCon = userData;
 
  171     int status = AudioUnitSetProperty((AudioUnit)inUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, element, pCallbackData, 
sizeof(AURenderCallbackStruct));
 
  174     if(BusIndexTo3DMixerCallbackStructures.find(element) != BusIndexTo3DMixerCallbackStructures.end())
 
  176         if(BusIndexTo3DMixerCallbackStructures[element] != NULL)
 
  178             delete BusIndexTo3DMixerCallbackStructures[element];
 
  179             BusIndexTo3DMixerCallbackStructures[element] = NULL;
 
  182     BusIndexTo3DMixerCallbackStructures[element] = pCallbackData;
 
  187 extern "C" int SetInputRenderCallbackToNull(
void* inUnit, uint element)
 
  189     return AudioUnitSetProperty((AudioUnit)inUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, element, &NullRenderCallbackStruct, 
sizeof(AURenderCallbackStruct));