off a sound effect with NSUserDefaults - iphone

i try to off a sound effect on my app
play method is ' [myMusic play];
-(void)viewDidLoad {
BOOL soundIsOff = [defaults boolForKey:#"sound_off"];
//the problem is here
//xcode compiler doesn't copile this code
[myMusic play] = soundIsOff;
}
sound code :
'
///sound effect
NSString * musicSonati = [[NSBundle mainBundle] pathForResource:#"sound" ofType:#"wav"];
myMusic = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:musicSonati] error:NULL];
myMusic.delegate = self;
myMusic.numberOfLoops = 0;
Shake API Code :
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
if (event.subtype == UIEventSubtypeMotionShake)
//Play sound :
[myMusic play] ;
}
}

Looks like you are trying to assign a value to a method call. That is why you are getting the compiler error:
[myMusic play] = soundIsOff //This does not work.
You probably want something like this:
if(!soundIsOff) {
[myMusic play];
}
The question is unclear however, so this is a guess at this point.

I am confused by the question, but if what you want is to stop the sound, then you just need:
[myMusic stop];

Like the others, I can only guess at what you want to do here. Perhaps you are trying to do this:
soundIsOff ? [music stop] : [music play];

Related

how to stop AVAudioPlayer securely

i have an AVAudioPlayer with two buttons : Play and Stop.
The play button is hidden when playing, and vice versa.
The problem is that a crash occurs when i attempt to push the Stop button, just at the end of the playing, at the moment when the method "audioPlayerDidFinishPlaying" is invoked.
Indeed, this method release the AVAudioPlayer, and when i push the stop button (which release the object too...) it crashes.
But still, i test if the player is nil before releasing it manually, so why does it crashes and how to avoid this ?
My code :
in the .h :
#private AVAudioPlayer* monPlayer;
in the .m :
-(IBAction)playSound{
NSString *path = nil;
if(path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"sounds/%d", idoiseau] ofType:#"m4a"])
{
monPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
monPlayer.delegate = self;
[monPlayer play];
[buttonPlay setEnabled:NO];
[buttonStop setEnabled:YES];
}
else return;
}
-(IBAction)stopSound{
if(!monPlayer) return;
[monPlayer stop];
[monPlayer release];
monPlayer = nil;
[buttonPlay setEnabled:YES];
[buttonStop setEnabled:NO];
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
[player release];
player = nil;
[buttonPlay setEnabled:YES];
[buttonStop setEnabled:NO];
}
edit : just replace the local variable "player" by the instance variable "monPlayer" in the delegate method, and it works. Thanks to hotpaw2 :-)
Your code seems to be setting the local parameter player to nil instead of the object instance variable monPlayer.

Touchesbegan always fire when using touchesmoved?

I'm new to iPhone programing.
I'm trying to do a simple window with a cat doing two sounds. When you click at the cat icon it should do "miaau", and when wou drag over window (stroke) it should make "mrrrr".
It works, but always when I try to make cat mrrrrr function TouchesBegan fires and cat also do "miaaau".
What to do to make the interface recognize I want only stroke cat, not to touch it for doing the first option, "miaau"?
I suggest to add a NSTimer to touchesBegan method with small time interval (say 0.1 sec):
BOOL tap_event = NO; //ivar declared in header
-(void) touchesBegan:... {
tap_event = YES;
[NSTimer scheduledTimerWithTimeInterval: 0.1 target: self selector: #selector(checkTap:) userInfo: nil repeats: NO];
}
-(void) checkTap:(NSTimer*) t {
if( tap_event ) //miauu here
tap_event = NO;
}
-(void) touchesMoved:... {
tap_event = NO;
//mrrrr here
}
Or as an option check docs for UIGestureRecognizers
This may help you
When does a touchesBegan become a touchesMoved?
touchesBegin & touchesMove Xcode Obj C Question
Max' solution is correct. It will definitely work. I am having an alternative, see this approach.
Make your player object in an .h file then allocate it in viewDidLoad and release in dealloc.
-(void) touchesBegan:... {
//Play the miauu sound.
}
-(void) touchesMoved:... {
[self.yourPlayer stop];
//Play mrrrr.
}
Edit
.h file,
AVAudioPlayer *avPlayer1;
AVAudioPlayer *avPlayer2;
.m file
-(void) touchesBegan:... {
NSString *path = [[NSBundle mainBundle] pathForResource:#"cat" ofType:#"wav"];
avPlayer1 = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[avPlayer1 play];
}
-(void) touchesMoved:... {
[avPlayer1 stop];
NSString *path = [[NSBundle mainBundle] pathForResource:#"cat" ofType:#"wav"];
avPlayer2 = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[avPlayer2 play];
}
-(void)dealloc
{
[avPlayer1 release];
[avPlayer2 release];
[super dealloc];
}

AVaudioPlayer regarding song overlapping

I have using AVAudioPlayer in my app but the problem is that when i play the song from list it will played while before stopping the song i am again goes to song list then select another song then both song will start playing simultaneously so please tell me the code which will terminate my first song.
I use flag variable for initializing the song file---
fileURL = [[NSURL alloc] initFileURLWithPath: [[NSBundle mainBundle] pathForResource:#" Om Namo" ofType:#"aac"]];
self._player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
if (self._player)
{
_fileName.text = [NSString stringWithFormat: #"%# (%d ch.)", [[self._player.url relativePath] lastPathComponent], self._player.numberOfChannels, nil];
[self updateViewForPlayerInfo];
[self updateViewForPlayerState];
}
[fileURL release];
break;
Play and push function---
- (void)startPlayback
{
if ([self._player play])
{
//[self stop];
[self updateViewForPlayerState];
self._player.delegate = self;
}
else
NSLog(#"Could not play %#\n", self._player.url);
}
- (void)pausePlayback
{
[self._player pause];
[self updateViewForPlayerState];
}
I also make stop function---
-(void)stop
{
[_player release];
self._player=nil;
}
Please help me .
Is correct my stop function.
and where i put our stop function or any other solution to fix this problem...
I can think of 3 things :
1) You can make code look like code by putting 4 spaces infront of each line. The reason you've gt no answers so far is probably because your question is almost unreadable ;)
2) In your stop method you might want to try this :
- (void) stop {
[_player stop];
self._player = nil;
}
3) Apple highly discourage using an underscore in front of member names. I've never run into problems but I'd rename _player to player.

Can you see anything wrong in this code?

NSString *path = [[NSBundle mainBundle] pathForResource:[arraySub objectAtIndex:indexPathHere.row] ofType:#"mp3"];
NSURL *file = [[NSURL alloc] initFileURLWithPath:path];
AVAudioPlayer *myPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:file error:nil];
self.player = myPlayer;
[player prepareToPlay];
[player setDelegate:self];
[self.player play];
NSTimeInterval lenghtMusic = player.duration;
if (player.currentTime == lenghtMusic) {
NSLog(#"It worked");
[tableThing deselectRowAtIndexPath:indexPathHere animated:YES];
[myPlayer autorelease];
[file autorelease];
}
Can you see anything wrong?
Apparently, the "if"-statement never gets called...
If I read your code correctly you are trying to find out when the player has finished playing and then you want to deselect the current rode and release the player. Your problem is that you start the player and then immediately checks where it is currently playing. Unless you have an almost 0 length file the currentTime and length will NEVER be equal.
If that is what you are trying to do you should use the AVAudioPlayerDelegate Protocol and especially the:
– audioPlayerDidFinishPlaying:successfully:
method that is called when the player is finished.
So you need to change your class that controls the player by editing the .h file to use the AVAudioPlayerDelegate Protocol. Obviously keep extending whatever you were before.
#interface YourClass <AVAudioPlayerDelegate>
#end
In your .m file:
Then when you have created and assigned your player instance:
[player setDelegate:self];
In the .m file also add the method
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
// Your success code goes here
}
You are comparing double's with ==, which is almost always false due to round-off errors.
Compare with a range e.g.
if (fabs(player.currentTime - lenghtMusic) < 0.0001) {
...
}
I'm a noob iPhone dev, but are you sure that player.currentTime is a NSTimeInterval? That looks like the most obvious candidate.
Also, I'd log out what your player.currentTime is and what lenghtMusic is before your if and that'll probably let you know what's going on.

How can I play a sound on the iPhone using MonoTouch?

I am looking for something like
PlaySound (uint frequency)
Does it exist?
From the HowTo at: http://wiki.monotouch.net/HowTo/Sound/Play_a_Sound_or_Alert
var sound = SystemSound.FromFile (new NSUrl ("File.caf"));
sound.PlaySystemSound ();
I don't know about mono, but in the iPhone SDK it isn't easy that easy to create and play sound. Other alternatives are to provide the sound as a file and play that, or create an array representing a sinusoid, and wrap it in a audio wrapper, and pass it to one of many sound APIs.
If mono proves to be just as limited, then search stackoverflow.com for System Sound Services and AVAudioPlayer as starting points.
Here are two ways to play a sound file:
SoundEffect.c (based on Apple's)
#import "SoundEffect.h"
#implementation SoundEffect
+ (id)soundEffectWithContentsOfFile:(NSString *)aPath {
if (aPath) {
return [[[SoundEffect alloc] initWithContentsOfFile:aPath] autorelease];
}
return nil;
}
- (id)initWithContentsOfFile:(NSString *)path {
self = [super init];
if (self != nil) {
NSURL *aFileURL = [NSURL fileURLWithPath:path isDirectory:NO];
if (aFileURL != nil) {
SystemSoundID aSoundID;
OSStatus error = AudioServicesCreateSystemSoundID((CFURLRef)aFileURL, &aSoundID);
if (error == kAudioServicesNoError) { // success
_soundID = aSoundID;
} else {
NSLog(#"Error %d loading sound at path: %#", error, path);
[self release], self = nil;
}
} else {
NSLog(#"NSURL is nil for path: %#", path);
[self release], self = nil;
}
}
return self;
}
-(void)dealloc {
AudioServicesDisposeSystemSoundID(_soundID);
NSLog(#"Releasing in SoundEffect");
[super dealloc];
// self = nil;
}
-(void)play {
AudioServicesPlaySystemSound(_soundID);
}
-(void)playvibe {
AudioServicesPlayAlertSound(_soundID);
}
+(void)justvibe {
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
}
#end
SoundEffect.h:
#import <AudioToolbox/AudioServices.h>
#interface SoundEffect : NSObject {
SystemSoundID _soundID;
}
+ (id)soundEffectWithContentsOfFile:(NSString *)aPath;
- (id)initWithContentsOfFile:(NSString *)path;
- (void)play;
- (void)playvibe;
+ (void)justvibe;
#end
How to use it:
// load the sound
gameOverSound = [[SoundEffect alloc] initWithContentsOfFile:[mainBundle pathForResource:#"buzz" ofType:#"caf"]];
// play the sound
[gameOverSound playvibe];
This is useful for when you want to play sound at the same volume as the iPhone's volume control setting, and you won't need to stop or pause the sound.
Another way is:
+ (AVAudioPlayer *) newSoundWithName: (NSString *) name;
{
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource: name ofType: #"caf"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: fileURL
error: nil];
[fileURL release];
// if the sound is large and you need to preload it:
[newPlayer prepareToPlay];
return (newPlayer);
}
and use it (you can see all the extras when you go with AVAudioPlayer):
timePassingSound = [AVAudioPlayer newSoundWithName:#"ClockTicking"];
[timePassingSound play];
// change the volume
[timePassingSound volume:0.5];
// pause to keep it at the same place in the sound
[timePassingSound pause];
// stop to stop completely, and go to beginning
[timePassingSound stop];
// check to see if sound is still playing
[timePassingSound isPlaying];