Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3596432
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 18, 20262026-05-18T19:59:14+00:00 2026-05-18T19:59:14+00:00

I am looking at the ‘Metronome’ sample code from the iOS SDK ( http://developer.apple.com/library/ios/#samplecode/Metronome/Introduction/Intro.html

  • 0

I am looking at the ‘Metronome’ sample code from the iOS SDK (http://developer.apple.com/library/ios/#samplecode/Metronome/Introduction/Intro.html). I am running the metronome at 60 BPM, which means a tick every second. When I look at an external watch (the PC’s watch), I see the metronome is running too slow – it misses about one beat each minute, which is app. 15msec of consistent error. The relevant code piece is:

- (void)startDriverTimer:(id)info {    
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];       

    // Give the sound thread high priority to keep the timing steady.    
    [NSThread setThreadPriority:1.0];    
    BOOL continuePlaying = YES;   

    while (continuePlaying) {  // Loop until cancelled.   
        // An autorelease pool to prevent the build-up of temporary objects.    
        NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];     
        [self playSound];

        [self performSelectorOnMainThread:@selector(animateArmToOppositeExtreme) withObject:nil waitUntilDone:NO];    
        NSDate *curtainTime = [[NSDate alloc] initWithTimeIntervalSinceNow:self.duration];    
        NSDate *currentTime = [[NSDate alloc] init];  
        // Wake up periodically to see if we've been cancelled. 
        while (continuePlaying && ([currentTime compare:curtainTime] != NSOrderedDescending)) {     
            if ([soundPlayerThread isCancelled] == YES) {    
                continuePlaying = NO;    
            }    
            [NSThread sleepForTimeInterval:0.01];    
            [currentTime release];    
            currentTime = [[NSDate alloc] init];    
        }

        [curtainTime release];   
        [currentTime release];     
        [loopPool drain];    
    }    
    [pool drain];    
}

Where

self.duration

is 1.0 second in the case of 60 BPM. I wonder where this error comes from, and how can I make a more accurate timer/interval counter.

EDIT: The problem exists as well when I change the sleep time to smaller values, e.g .001.

EDIT2 (update): The problem exists as well when I use the CFAbsoluteTimeGetCurrent() method for timing. When I use the same method to measure timing between a button tap events, the timing seems accurate – I tap once a second (while watching a watch), and the measured rate is 60 BPM (on average). So I guess it must be some issue with the NSThread (?). Another thing is that on the device (iPod) the problem seems more severe then on the simulator.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-18T19:59:15+00:00Added an answer on May 18, 2026 at 7:59 pm

    Ok, I have some answers after doing some more tests, so I am sharing it with anyone who is interested.

    I’ve placed a variable to measure time intervals between ticks, inside the play method (the method that actually sends the play message to the AVAudioPlayer object), and as my simple compare-to-external-watch experiment showed, the 60 BPM was too slow – I got these time intervals (in seconds):

    1.004915
    1.009982
    1.010014
    1.010013
    1.010028
    1.010105
    1.010095
    1.010105
    

    My conclusion was that some overhead time elapses after each 1-second-interval is counted, and that extra time (about 10msec) is accumulated to a noticeable amount after a few tens of seconds — quite bad for a metronome. So instead of measuring the interval between calls, I decided to measure the total interval from the first call, so that the error won’t be accumulated. In other words I’ve replaced this condition:

    while (continuePlaying && ((currentTime0 + [duration doubleValue]) >= currentTime1)
    

    with this condition:

    while (continuePlaying && ((_currentTime0 + _cnt * [duration doubleValue]) >= currentTime1 ))
    

    where now _currentTime0 and _cnt are class members (sorry if it’s a c++ jargon, I am quite new to Obj-C), the former holds the time stamp of the first call to the method, and the latter is an int counting number of ticks (==function calls). This resulted in the following measured time intervals:

    1.003942
    0.999754
    0.999959
    1.000213
    0.999974
    0.999451
    1.000581
    0.999470
    1.000370
    0.999723
    1.000244
    1.000222
    0.999869
    

    and it is evident even without calculating the average, that these values fluctuate around 1.0 second (and the average is close to 1.0 with at least a millisecond of accuracy).

    I will be happy to hear more insights regarding what causes the extra time to elapse – 10msec sounds as eternity for a modern CPU – though I am not familiar with the specs of the iPod CPU (it’s iPod 4G, and Wikipedia says the CUP is PowerVR SGX GPU 535 @ 200 MHz)

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Looking for feedback on : http://code.google.com/p/google-perftools/wiki/GooglePerformanceTools
Looking for a C++ async HTTP library so I can download some zip files
Looking to add RXTXcomm.jar (the javax.comm replacement) from http://rxtx.qbang.org/ I can add RXTXcomm.jar to
Looking at some code written by another developer, I came across this: for($i=1; $i<=30;
Looking at some assembly code for x86_64 on my Mac, I see the following
Looking at some of the code System.Linq I've come across some examples of Buffer<TSource>
Looking around at different code bases I see a variety of styles: Class interfaces
Looking for a better way of extracting a number from the last line in
Looking at the new spring property support in 3.1 ( http://blog.springsource.org/2011/02/15/spring-3-1-m1-unified-property-management/ ), it looks
Looking for simple php class routing, like this: http://fatfree.sourceforge.net/page/routing-engine Is there a ready-made solutions?

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.