3

An iPhone app starts a thread using NSThread that plays short audio tick on regular intervals to give pace.

Code that starts and plays sound:

tickingThread = [[NSThread alloc] initWithTarget:self
                                            selector:@selector(playStepTicks:)
                                              object:nil];

-(void)playStepTicks:(id) arg
{
    NSLog(@"Started ticking.");
    NSThread *cur = [NSThread currentThread];
    NSTimeInterval stime = 0.3;
    while (!cur.isCancelled) {
        CFTimeInterval t = CACurrentMediaTime();
        NSLog(@"Tick: %f", t);
        AudioServicesPlaySystemSound (tickSound);
        t = CACurrentMediaTime() - t;
        [NSThread sleepForTimeInterval:stime-t];
    };
    NSLog(@"Stopped ticking.");
}

Audio loop runs very precisely on iOS6 and is not distracted by UI events when the screen is on.

We enabled proximity sensor on iPhone 4S to save power.

Unfortunately this has an unpleasant effect on the audio loop: ticks are played with large jitter (see video on YouTube).

How can this problem be solved on iOS 6?

matejk
  • 798
  • 1
  • 14
  • 27
  • 1
    I think a good starting point in debugging this is working out where the unpredictable blocking is going on. Is it on `[NSSleep sleepForTimeInterval:]`, random context switches occurring during execution, or one of the other API calls blocking. Instruments can help a lot with this. – marko Sep 23 '13 at 22:11
  • 1
    Also, never do console IO anywhere you want predictable scheduling behaviour - it can and does block. – marko Sep 23 '13 at 22:13
  • @marko Thanks for hints. App was profiled with Instruments and NSLog did indeed take most of CPU time in that thread. However removing NSLog and increasing thread priority to 1.0 did not help. Sound is still played very irregularly when proximity sensor is covered. I assume that it has to do something with thread scheduling. Thread that is reading sensors (like accelerometer) uses most of the CPU time. – matejk Sep 24 '13 at 19:18

1 Answers1

1

After asking for help on Apple's developer forum, we decided to use Audio Units to generate continuous audio signal and properly set its amplitude (zero for silence and constant for tick) to achieve the tick effect.

The code was written based on iOS Tone Generator.

matejk
  • 798
  • 1
  • 14
  • 27