I have an iOS/Objective-C program that uses a single audio unit to play a generated signal when a button is pressed. I'd like to add functionality such that:
a) When the button is first pressed, a signal is generated in some kind of numeric array.
b) The audio then begins, and the render callback accesses (and plays) that generated signal.
Given my current code, I feel like these additions will just be a few lines, but I'm having trouble with the syntax, which variable types to use, how to track the current sample, and so on. I've included the related code as it is now:
The button press:
- (IBAction)startPressed:(id)sender {
[self setupAudioPlayer];
[self createSignal];
[self playAudio];
}
A line from setupAudioPlayer:
input.inputProcRefCon=&mySignal; // mySignal is an instance var
The audio creation:
-(void)createSignal{
int beepLength=0.020*Fs; // Fs is sampling frequency
float beepFrequency=440; // Hz
// Declare some kind of numeric array "mySignal", which is an instance var.
mySignal=...?
// Generate audio signal (pure tone)
for (int i=1; i<=beepLength; i++) {
float t=i/Fs;
mySignal[i]=sinf(2*M_PI*beepFrequency*t);
}
}
The render callback:
OSStatus RenderTone(
void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
const int channel1 = 0;
Float32 *buffer = (Float32 *)ioData->mBuffers[channel1].mData;
// This is where things get hazy
Float32 *mySignal=(Float32 *)inRefCon;
for (UInt32 frame = 0; frame < inNumberFrames; frame++)
{
buffer[frame]=mySignal[?];
}
return noErr;
}
So, to summarize my questions: How should mySignal be defined? How do I access this instance variable from RenderTone (my 'hazy' code above is just a guess)? How can I track the current sample in RenderTone? Is there anything else missing/wonky in this approach?
Thanks for reading and for any help, really appreciated!
(I have seen sample code that passes a reference to the view controller's instance into the render callback, and then accesses the instance variables that way. However, perhaps mistakenly, I read elsewhere that this wasn't good form as it may involve too much computational overhead for a callback with such strict timing requirements.)