recording against a metronome of set length using remote IO

462 views Asked by At

I was able to create the exact functionality I wanted to avaudioplayer and avaudiorecorder but of course experienced latency problems. So after reading pretty much every article on the web and reviewing stacks of sample code, I'm still not sure how to achieve the following:

  1. User chooses to record a sample 2 bars long (4 beats per bar) with a pre-roll/count-in
  2. User clicks record
  3. A metronome starts which counts in 4 beats (accent on the first beat)
  4. The app automatically starts recording on the start of the next bar
  5. The app automatically turns off recording at the end of the 3rd bar (the 2 bars + the pre-roll)
  6. The user can then playback their recording or delete it and start again.

So, with avaudioplayer and avaudiorecorder I simply created a 'caf' using audacity with a metronome set at the correct bpm (bpm is set for the app). I then setup and play the avaudioplayer and using the audiodidfinishsuccessfully delegate method, performed some logic to start the recorder, restart the player, maintain a loop count etc. to turn off recording and audio.

As I mentioned, I was pretty much able to achieve the user experience I am after but the latency problems are not acceptable.

I have been working with audio units and the remote IO and have setup a project with a playback callback and recorder callback etc. but now face the problem of working how to make this work based on the description above. I am trying to work out the following things for starters:

  1. If I create a 1 beat caf file, how could I make use of audio units and remote IO to play x amount of beats and then stop?
  2. How could I do the pre-roll and start the recording callback after 4 beats

Can anyone give me some ideas or point me in the right direction. As I have mentioned, I have already done a stack of research including buying the core audio book, reading every article on atastypixel.com, timbolstad.com etc and trawled through the apple docs.

Thanks in advance for your help.

1

There are 1 answers

0
user3447100 On

I start an NSTimer. Use values based on BPM (Beats per Minute) / 60. So if user wants to record a 2 bar file with a count in might do something like this:

//timer interval=100BPM/60secs per minute
timerInterval=100/60;

    metroTimer = [NSTimer scheduledTimerWithTimeInterval:timerinterval target:self selector:@selector(blinkMetroLight) userInfo:nil repeats:YES];




 - (void)blinkMetroLight
    {

        if(beatNumber == 0)
        {
            beatNumber = 1;


        }
        else if (beatNumber == 5)
        {
            [self audioProcessorStart];
        }
        if (beatNumber == 8)
        {

                [self audioProcessorStop];
                [metroTimer invalidate]; metroTimer = nil;
        }

    beatNumber++ 
    }