views:

264

answers:

3

I'm trying to implement a function that detects a user shaking his/her iPhone, and then the app will make a barking sound. So far I've got the code attached below, and it works. But, if I shake the phone harder, it makes 2 or more barks one immediately after the other. How do I make sure this only happens once per shake, no matter how hard?

- (void)accelerometer:(UIAccelerometer *)accelerometer 
    didAccelerate:(UIAcceleration *)acceleration {
        if (acceleration.x > kAccelerationThreshold ||
      acceleration.y > kAccelerationThreshold ||
      acceleration.z > kAccelerationThreshold) {
         // BARKING SOUND
        }
    }
+3  A: 

Why not keep a value around with the last time you played the sound?

time_t last_time_played_bark = 0;


#define MINIMUM_TIME_BETWEEN_BARKS 5   // in seconds
time_t now = time(NULL);

if (last_time_played_bark + MINIMUM_TIME_BETWEEN_BARKS < now) {
    // BARKING_SOUND
    last_time_played_bark = now;
}

Presumably you'll want MINIMUM_TIME_BETWEEN_BARKS to be at least as long as it takes to play the sound.

Epsilon Prime
Thanks! Works like a charm!
isaaclimdc
Hold on.. is that a Java function? This won't work in objective-C:time_t now = time();
isaaclimdc
Ah, forgot the parameter to time(). Fixed example.
Epsilon Prime
Yes, time() is a standard C call.
Epsilon Prime
+4  A: 

You could use an NSTimer - look here: section "Timer"

After playing the sound, set a boolean variable called "hasBarked" to YES and call the timer then. After two seconds, the timer sets "hasBarked" to NO and disables itself. Finally, put the whole sound-playing method into an if block that only plays the sound if "hasBarked" is NO.

Yassin
Interesting solution. The trade off between my solution and yours is the NSTimer solution presumably either spawns a thread or uses an OS/hardware timer (which would depend on the NSTimer implementation). The time() solution has the added cost of an OS call every time it checks the acceleration (which means a task switch).
Epsilon Prime
+1  A: 

As a side note, if you just want to detect shake gestures, you might find it easier to use the motion events added in OS 3.0 than trying to roll your own from raw accelerometer data.

I agree with Epsilon Prime's suggestion to store the timestamp of the last time you played the sound as a means to throttle how often you play it.

Sixten Otto