Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performing actions from accelerometer

I'm very new to programming in Xcode and have already hit a brick wall. What I am trying to do is to get a sound to play if there is sufficient acceleration detected. Can someone please advise me on what I am doing wrong? (I suspect its everything).

CODE:

#import "LZDViewController.h"

@interface LZDViewController ()

@end

@implementation LZDViewController

- (void)viewDidLoad;{

[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CMAccelerometerData *accelerometerData = self.motionManager.accelerometerData;
if (fabsf(accelerometerData.acceleration.x) > 1.2
    || fabsf(accelerometerData.acceleration.y) > 1.2
    || fabsf(accelerometerData.acceleration.z) > 1.2)
{
    NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/audio.wav", [[NSBundle mainBundle] resourcePath]]];
    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
    audioPlayer.numberOfLoops = 0;



    [audioPlayer play];


}
}

@end

EDIT: Here is the code for my .h

#import <UIKit/UIKit.h>
#import <CoreMotion/CoreMotion.h>
#import <AVFoundation/AVFoundation.h>
@interface LZDViewController : UIViewController
//{AVAudioPlayer *audioPlayer;}

@property (strong, nonatomic) CMMotionManager *motionManager;
@property (strong, nonatomic) AVAudioPlayer *audioPlayer;




@end

I'm still not getting any joy at all, and I do apologise for the hand holding. All I get is a white screen but the sound file never plays. I have imported the correct framework and can get the sound playing with just a button, but I really want to play with the accelerometer. Thanks

like image 482
Brian Howard Avatar asked Jul 12 '26 19:07

Brian Howard


1 Answers

Alright, the first thing you're going to want to do is define two properties in either your interface file, or in the interface extension at the top of your implementation file. These will be the motion manager, and the audio player.

@property (strong, nonatomic) CMMotionManager *motionManager;
@property (strong, nonatomic) AVAudioPlayer *audioPlayer;

Then we can get everything else done in viewDidLoad. The code below sets up a new operation queue for the motion manager to receive accelerometer events on, initializes the audio player and the motion manager, and then starts getting accelerometer updates at an interval of 30 times per second.

Finally, within the accelerometers update block, just use the same logic you already build to check the acceleration data and if it meets your requirements continue on to the next condition.

**I have configured this example to not start playing the sound again if the player is already playing

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSOperationQueue *motionQueue = [NSOperationQueue new];

    NSURL *url = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"audioFile" ofType:@"m4a"]];
    self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
    [self.audioPlayer prepareToPlay];

    self.motionManager = [CMMotionManager new];
    [self.motionManager setAccelerometerUpdateInterval:1.0f/30.0f];

    [self.motionManager startAccelerometerUpdatesToQueue:motionQueue withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
        if (fabsf(accelerometerData.acceleration.x) > 1.8 || fabsf(accelerometerData.acceleration.y) > 1.8 || fabsf(accelerometerData.acceleration.z) > 1.8) {
            NSLog(@"%@",accelerometerData);
            if (self.audioPlayer) {
                if (!self.audioPlayer.isPlaying) {
                    [self.audioPlayer play];
                }
            }
        }
    }];
}
like image 68
Mick MacCallum Avatar answered Jul 14 '26 09:07

Mick MacCallum



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!