NSSound stop function - objective-c

Thanks for the help.
This activates basic playback of referenced file:
NSSound *sound = [[NSSound alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"ping" ofType:#"aiff"] byReference:NO];
[sound play];
What's the proper way to terminate playback? No luck implementing the following:
NSSound *sound = [[NSSound alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"ping" ofType:#"aiff"] byReference:NO];
if([sound isPlaying]) {
[sound stop];
Thanks for the assistance.

From the couple code snippets you included in your question, it looks like you are doing this:
// create new sound object
NSSound *sound = [[NSSound alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"ping" ofType:#"aiff"] byReference:NO];
// start it playing
[sound play];
and then you create another new sound object:
// create new sound object
NSSound *sound = [[NSSound alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"ping" ofType:#"aiff"] byReference:NO];
// this cannot be true - you just created the sound object
if([sound isPlaying]) {
[sound stop];
}
Try this very simple example (just add Play and Stop buttons to a view controller and connect them):
#import "ViewController.h"
#interface ViewController() {
NSSound *sound;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// instantiate sound object with file from bundle
sound = [[NSSound alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"1162" ofType:#"aiff"] byReference:NO];
}
- (IBAction)playClicked:(id)sender {
if (sound) {
[sound play];
}
}
- (IBAction)stopClicked:(id)sender {
if (sound && [sound isPlaying]) {
[sound stop];
}
}
- (void)setRepresentedObject:(id)representedObject {
[super setRepresentedObject:representedObject];
}
#end

Related

AVAudioPlayer iOS no sound

Seems to be similar questions asked but none of the solutions seem to work for me. Cant for the life of me understand why my code doesnt work so here it is.
I dont get any errors but also get no sound.
#interface MainApp ()
#property (strong, nonatomic) AVAudioPlayer *audioPlayer;
-(void)playSoundFX:(NSString*) soundFile;
#end
#implementation MainApp
- (void)viewDidLoad {
[super viewDidLoad];
// Play sound
[self playSoundFX:#“sound.mp3"];
}
// Play sound
- (void)playSoundFX:(NSString*)soundFile {
// Setting up path to file url
NSBundle* bundle = [NSBundle mainBundle];
NSString* bundleDirectory = (NSString*)[bundle bundlePath];
NSURL *url = [NSURL fileURLWithPath:[bundleDirectory stringByAppendingPathComponent:soundFile]];
// Make an audioPlayer object and play file
NSError *error;
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
[audioPlayer setVolume:100.0f];
if (audioPlayer == nil)
NSLog(#"%#", [error description]);
else
[audioPlayer play];
}
#end
*********vvvvvvvvv Amended Code that works vvvvvvvvv**********
#interface MainApp ()
#property (strong, nonatomic) AVAudioPlayer *audioPlayer;
-(void)playSoundFX:(NSString*) soundFile;
#end
#implementation MainApp
- (void)viewDidLoad {
[super viewDidLoad];
// Play sound
[self playSoundFX:#“sound.mp3"];
}
// Play sound
- (void)playSoundFX:(NSString*)soundFile {
// Setting up path to file url
NSBundle* bundle = [NSBundle mainBundle];
NSString* bundleDirectory = (NSString*)[bundle bundlePath];
NSURL *url = [NSURL fileURLWithPath:[bundleDirectory stringByAppendingPathComponent:soundFile]];
// Make an audioPlayer object and play file
NSError *error;
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
[self.audioPlayer setVolume:100.0f];
if (self.audioPlayer == nil)
NSLog(#"%#", [error description]);
else
[self.audioPlayer play];
}
#end
I am execute your code on my iPhone. It is work properly.Please Select a device and run your code. I hope it will execute properly with sound.
You got to segregate the functionalities..
Loading audio file in viewDidLoad and play it on play action, some thing like this
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#interface ViewController ()
{
AVAudioPlayer *_audioPlayer;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Construct URL to sound file
NSString *path = [NSString stringWithFormat:#"%#/sound.mp3", [[NSBundle mainBundle] resourcePath]];
NSURL *soundUrl = [NSURL fileURLWithPath:path];
// Create audio player object and initialize with URL to sound
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)playSoundTapped:(id)sender
{
// When button is tapped, play sound
[_audioPlayer play];
}

Cocoa: Simple audio recording

I'm trying to implement some simple audio recording functionality in my application and I can't quite figure out to do it. I've been pointed to this example, but I can't get it to run in XCode, and it appears to be written in C++.
What I need to be able to do is record audio to a file, and then be able to get the current timestamp of the recording whilst recording. I would appreciate any help with this. Thanks!
You can record and play audio using the AVFoundation framework. Firstly you will need to implement this within your .h file and add a framework or library's within your xcode project settings like so:
After adding into your project settings import AVFoundation into your .h file like so:
#import <AVFoundation/AVFoundation.h>
Now Implement your delegates within your .h file:
#interface ViewController : UIViewController <AVAudioRecorderDelegate, AVAudioPlayerDelegate>
After this declare your AVAudioRecorder and AVAudioPlayer in your .h file like so:
#interface ViewController () {
AVAudioRecorder *recorder;
AVAudioPlayer *player;
IBOutlet UIButton *stopButton;
IBOutlet UIButton *playButton ;
}
- (IBAction)recordPauseTapped:(id)sender;
- (IBAction)stopTapped:(id)sender;
- (IBAction)playTapped:(id)sender;
Now set up everything in the -(Void)ViewDidLoad{} :
- (void)viewDidLoad
{
[super viewDidLoad];
// Disable Stop/Play button when application launches
[stopButton setEnabled:NO];
[playButton setEnabled:NO];
// Set the audio file
NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
#"MyAudioMemo.m4a",
nil];
NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
// Setup audio session
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
// Define the recorder setting
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
// Initiate and prepare the recorder
recorder = [[AVAudioRecorder alloc] initWithURL:outputFileURL settings:recordSetting error:NULL];
recorder.delegate = self;
recorder.meteringEnabled = YES;
[recorder prepareToRecord];
}
Now Implement the recording Button Like so...
- (IBAction)recordPauseTapped:(id)sender {
// Stop the audio player before recording
if (player.playing) {
[player stop];
}
if (!recorder.recording) {
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil];
// Start recording
[recorder record];
[recordPauseButton setTitle:#"Pause" forState:UIControlStateNormal];
} else {
// Pause recording
[recorder pause];
[recordPauseButton setTitle:#"Record" forState:UIControlStateNormal];
}
[stopButton setEnabled:YES];
[playButton setEnabled:NO];
}
Now Implement the StopButton IBAction:
- (IBAction)stopTapped:(id)sender {
[recorder stop];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setActive:NO error:nil];
}
Next Implement the playTapped IBAction like so:
- (IBAction)playTapped:(id)sender {
if (!recorder.recording){
player = [[AVAudioPlayer alloc] initWithContentsOfURL:recorder.url error:nil];
[player setDelegate:self];
[player play];
}
}
Lastly Implement the required AVPlayer Delegate by doing this:
- (IBAction)playTapped:(id)sender {
if (!recorder.recording){
player = [[AVAudioPlayer alloc] initWithContentsOfURL:recorder.url error:nil];
[player setDelegate:self];
[player play];
}
}
And that's it! The Finished Product should look something like this...
For more info take a look at These Links:
Link1
Link2
Link3
Documentation Links:
Link 1
Hope This Helps.
The above mentioned AVFoundation framework is iOS only. Dealing with audio on OS X is quite painful in the beginning. CoreAudio, while it is one of the best components I worked with, does require some time spent learning and understanding. You may want to consider for exampel using https://github.com/syedhali/EZAudio for your task.

AVAudioPlayer causing memory leak

Not sure if this is a simulator issue or I am missing something, the following code gives me a memory leak although theAudio is released as in dealloc. I am playing a .wav file and the sound will change depending on the value of an integer. The App runs ok but 16 bit leak is flagged whwn I test this in xcode
Any suggestion is greatly appreciated:
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface Water : UIViewController
<AVAudioPlayerDelegate>
{
}
#property (nonatomic,retain) AVAudioPlayer *theAudio;
-(IBAction) goButMenu: (id) sender;
-(IBAction) goDrinkMenu: (id) sender;
-(IBAction) playwater;
#end
#implementation Water
#synthesize theAudio;
-(IBAction) goDrinkMenu: (id) sender{
ButDrinkMenu *butdrinkmenu1 = [[ButDrinkMenu alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:butdrinkmenu1 animated:YES];
}
-(void) viewDidLoad {
if (BoyOrGirl == 1) {
NSString *path = [[NSBundle mainBundle] pathForResource:#"Applause" ofType:#"wav"];
theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
}
else {
NSString *path = [[NSBundle mainBundle] pathForResource:#"bongo" ofType:#"wav"];
theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
}
}
-(IBAction) playwater{
if (BoyOrGirl == 1) {
NSString *path = [[NSBundle mainBundle] pathForResource:#"Applause" ofType:#"wav"];
theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
}
else {
NSString *path = [[NSBundle mainBundle] pathForResource:#"bongo" ofType:#"wav"];
theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
}
}
Definitely test on the device directly; testing for leaks with the simulator may return inaccurate results.
That said, there are several memory-related concerns with this code sample. You may wish to include your dealloc method here as that may offer some insight, but here's a problem (that appears in several of your allocations):
Your AVAudioPlayer isn't being assigned to your property, nor is it being released in scope. Ideally a player allocation would look more like:
AVAudioPlayer *myPlayer = [[AVAudioPlayer alloc] initWithContents....
[myPlayer setDelegate:self];
[self setTheAudio:myPlayer];
[myPlayer release];
As opposed to how you've implemented it, which assigns the player directly the instance variable:
theAudio = [[AVAudioPlayer alloc] initWith...
Because you assign the player directly to your instance variable, your player isn't being retained. This is likely to result in either premature release and a dangling pointer if you try and balance your calls properly, or it will result in leaking.

Sound stops working in soundboard (Xcode)

In my soundboard app, after some time the sound will stop working until the app is closed and opened again. Can't figure out what is wrong! here is my code:
In the .h file :
(imported files here)
#interface MainView : UIView {
}
- (IBAction)pushButton2:(id)sender;
#end
In the .m file:
(imported files here)
#implementation MainView
- (IBAction)pushButton2:(id)sender {
NSString *path = [[NSBundle mainBundle] pathForResource:#"sound1" ofType:#"mp3"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
}
#end
I'm not sure it would cause the behavior you're seeing, but you're definitely leaking the AVAudioPlayer each time the button is pressed. Additionally, I would just load it once (say, in viewDidLoad), rather than on each button press. Perhaps something like:
#interface MainView : UIView
{
AVAudioPlayer* audioPlayer;
}
- (IBAction)pushButton2:(id)sender;
#end
#implementation MainView
- (void) viewDidLoad
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"sound1" ofType:#"mp3"];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
audioPlayer.delegate = self;
}
- (void) viewDidUnload
{
[audioPlayer release], audioPlayer = nil;
}
- (IBAction)pushButton2:(id)sender
{
[audioPlayer play];
}
#end

sound should start again when over

i've got a sound which is started when the app starts, it's 30 seconds long. how can I repeat the song when it's over no matter in which viewcontroller i am?
my code:
-(void)playBgMusic {
NSString *path = [[NSBundle mainBundle] pathForResource:#"bgmusic" ofType:#"aif"];
theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play]; }
-(id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if(self)
{
[self playBgMusic];
}
return self; }
Try
theAudio.numberOfLoops = -1
Look at Apple's Documentation for more info.
The owner of the audioPlayer instance should be the appDelegate then to let it play wherever the user is in the app.