Looping a sound file in Cocoa Touch - iphone

I'm trying to get a sound to play once the view loads and repeat the music throughout the app even while switching from different views. It does play once the view is loaded and continues after switching to different views but I can't get it to loop. I am using for the sounds. Any help to get me to loop would be awesome
-(void)viewDidLoad {
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef)#"beat", CFSTR ("mp3"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
}

try to use the AVAudioPlayer instead, the solution would be something like this (with using ARC).
you need to define a variable in you class...
#interface MyClass : AnyParentClass {
AVAudioPlayer *audioPlayer;
}
// ...
#end
...and you can put the following code in any of your methods to start playing...
NSURL *urlForSoundFile = // ... whatever but it must be a valid URL for your sound file
NSError *error;
if (audioPlayer == nil) {
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:urlForSoundFile error:&error];
if (audioPlayer) {
[audioPlayer setNumberOfLoops:-1]; // -1 for the forever looping
[audioPlayer prepareToPlay];
[audioPlayer play];
} else {
NSLog(#"%#", error);
}
}
...to stop the playing is very easy.
if (audioPlayer) [audioPlayer stop];

Try moving you code into your Application Delegate and use a repeating NSTimer to repeat your playing action.
Example code:
// appDelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
UInt32 soundID;
}
//appDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef)#"beat", CFSTR ("mp3"), NULL);
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
[NSTimer scheduledTimerWithTimeInterval:lenghtOfSound target:self selector:#selector(tick:) userInfo:nil repeats:YES];
return YES;
}
-(void)tick:(NSTimer *)timer
{
AudioServicesPlaySystemSound(soundID);
}

Register a callback using the AudioServicesAddSystemSoundCompletion function, as the AudioServicesPlaySystemSound function description advises. The problem with the timer is you may not start it exactly when the previous sound has finished.

Related

How do you make a sound file play automatically thought an iOS app and loop using Objective-C?

I am making a game for iPhone using objective-c. I have the music I want to play in a file in the project. I need to know how to make it begin playing when the app launches, and loop at the end. Does anyone know how to do this? Code examples would be great! Thanks.
you can use AVAudioPlayer in App Delegate.
First in your App Delegate .h file add these lines:
#import <AVFoundation/AVFoundation.h>
and these one:
AVAudioPlayer *musicPlayer;
In your .m file add this method:
- (void)playMusic {
NSString *musicPath = [[NSBundle mainBundle] pathForResource:#"phone_loop" ofType:#"wav"];
NSURL *musicURL = [NSURL fileURLWithPath:musicPath];
musicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:musicURL error:nil];
[musicPlayer setNumberOfLoops:-1]; // Negative number means loop forever
[musicPlayer prepareToPlay];
[musicPlayer play];
}
Finally call it in the didFinishLaunchingWithOptions method:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
[self playMusic];
...
}
If you want to stop the music just:
[musicPlayer stop];
Aditionally you can check the Apple Documentation for AVAudioPlayer delegate for Handling Audio Interruptions http://developer.apple.com/library/ios/#DOCUMENTATION/AVFoundation/Reference/AVAudioPlayerDelegateProtocolReference/Reference/Reference.html
PS: Remember to import the AVFoundation Framework to your project.
First import AVFoundation Framework to your project. Then insert the music file into your project.
declare
#import <AVFoundation/AVFoundation.h>
And then
AVAudioPlayer *audioPlayer;
NSURL *file = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:#"soundName" ofType:#"mp3"]];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:file error:nil];
audioPlayer.numberOfLoops = -1; // Infinite loops
[audioPlayer setVolume:1.0];
[audioPlayer prepareToPlay];
[audioPlayer start]
You can stop the sound before application goes to backgound by using
[audioPlayer stop];

Adding Sound to splash screen in iPhone

I would like to add some background music to the splash screen in the iPhone. I have already increased the splash screen time by few seconds.. And the music isn't long... But I am not sure how to do it? Need some guidance...
Use following function for playing sound file.
-(void)playSoundFromFileName:(NSString*)pstrFileName ofType:(NSString*)pstrFileType
{
SystemSoundID bell;
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:pstrFileName ofType:pstrFileType]], &bell);
AudioServicesPlaySystemSound (bell);
}
Call this function in application delegate didfinishlaunchingwithoptions method...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
[self playSoundFromFileName:#"yourfile" ofType:#"extension"];
}
my personal taste: don't bother your users, and get out of the splash as fast as you can
How about putting it in you application didFinishLaunching but be sure to instantiate it in you .h and .m.
Something like this should do your problem:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSString* resourcePath = [[NSBundle mainBundle] resourcePath];
resourcePath = [resourcePath stringByAppendingString:#"/YOURMUSICNAME.mp3"];
NSLog(#"Path to play: %#", resourcePath);
NSError* err;
//Initialize our player pointing to the path to our resource
player = [[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath:resourcePath] error:&err];
if( err ){
//bail!
NSLog(#"Failed with reason: %#", [err localizedDescription]);
}
else{
//set our delegate and begin playback
player.delegate = self;
[player play];
player.numberOfLoops = -1;
player.currentTime = 0;
player.volume = 1.0;
}
}
Then if you want to stop it:
[player stop];
or pause it :
[player pause];
and also import it in your header file:
#import <AVFoundation/AVFoundation.h>
and add this to your header the bold part:
#interface ViewController : UIViewController <AVAudioPlayerDelegate>

How to auto play music as soon as my app starts?

I need some help with my app I have recently started. I am a very big starter to coding so please do help me, it'll mean a lot. I need a piece of music to play as soon as the user enters my app, i have followed other youtube tutorials but they only work for the older Xcode versions, so please help thank you so much.
How about putting it in you application didFinishLaunching but be sure to instantiate it in you .h and .m.
Something like this should do your problem:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSString* resourcePath = [[NSBundle mainBundle] resourcePath];
resourcePath = [resourcePath stringByAppendingString:#"/YOURMUSICNAME.wav"];
NSLog(#"Path to play: %#", resourcePath);
NSError* err;
//Initialize our player pointing to the path to our resource
player = [[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath:resourcePath] error:&err];
if( err ){
//bail!
NSLog(#"Failed with reason: %#", [err localizedDescription]);
}
else{
//set our delegate and begin playback
player.delegate = self;
[player play];
player.numberOfLoops = -1;
player.currentTime = 0;
player.volume = 1.0;
}
}
Then if you want to stop it:
[player stop];
or pause it :
[player pause];
and also import it in your header file:
#import <AVFoundation/AVFoundation.h>
EDIT:
You should to ofcourse declare it in your header, then synthesize it.
//.h and add the bold part:
#interface ViewController : UIViewController <AVAudioPlayerDelegate> {
AVAudioPlayer *player;
}
#property (nonatomic, retain) AVAudioPlayer *player;
//.m
#synthesize player;
You can use the AVAudioPlayer. It pretty straight forward to use:
NSURL *path = [[NSURL alloc] initFileURLWithPath:[DataPersister getQualifiedPathForFileInDirectory:DataPersisterPathBundle fileName:#"music.mp3"]];
NSError *outError;
AVAudioPlayer *musicSound = [[AVAudioPlayer alloc] initWithContentsOfURL:path error:&outError];
[musicSound play];
[path release];
Remember to import
#import <AVFoundation/AVFoundation.h>
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/MUSIC.mp3", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = -1;
[audioPlayer play];
audioPlayer.volume = 1.0;
audioPlayer.currentTime = 2;
Use this at - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method will play music for sure
Happy Coding ;)

Running the voice recorder while in another view?

Hello Okay right I have a view called 'RecordViewController' this has the voice recorder function so once the user presses 'record', it records their voice, I have also created a 'back' button. But once that back button is tapped the voice recording also stops. I want it so once the user goes back, its still recording their voice. Here is the code I used:
.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreAudio/CoreAudioTypes.h>
#interface RecordViewController : UIViewController <AVAudioRecorderDelegate> {
IBOutlet UIButton * btnStart;
IBOutlet UIButton * btnPlay;
IBOutlet UIActivityIndicatorView * actSpinner;
BOOL toggle;
NSURL * recordedTmpFile;
AVAudioRecorder * recorder;
NSError * error;
NSTimer *theTimer;
IBOutlet UILabel *seconds;
int mainInt;
NSString *timeRemainingString;
}
#property (nonatomic,retain)IBOutlet UIActivityIndicatorView * actSpinner;
#property (nonatomic,retain)IBOutlet UIButton * btnStart;
#property (nonatomic,retain)IBOutlet UIButton * btnPlay;
- (IBAction) start_button_pressed;
- (IBAction) play_button_pressed;
- (IBAction)goBack:(id)sender;
- (void)countUp;
#end
.m
#import "RecordViewController.h"
#implementation RecordViewController
#synthesize actSpinner, btnStart, btnPlay;
- (void)countUp {
mainInt += 1;
seconds.text = [NSString stringWithFormat:#"%02d", mainInt];
}
- (IBAction)goBack:(id)sender; {
[self dismissModalViewControllerAnimated:YES];
}
- (void)viewDidLoad {
[super viewDidLoad];
//Start the toggle in true mode.
toggle = YES;
btnPlay.hidden = YES;
//Instanciate an instance of the AVAudioSession object.
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
//Setup the audioSession for playback and record.
//We could just use record and then switch it to playback leter, but
//since we are going to do both lets set it up once.
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
error: &error];
//Activate the session
[audioSession setActive:YES error: &error];
}
- (IBAction)start_button_pressed {
if(toggle) {
toggle = NO;
[actSpinner startAnimating];
[btnStart setImage:[UIImage imageNamed:#"stoprecording.png"]
forState:UIControlStateNormal];
mainInt = 0;
theTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(countUp) userInfo:nil repeats:YES];
btnPlay.enabled = toggle;
btnPlay.hidden = !toggle;
//Begin the recording session.
//Error handling removed. Please add to your own code.
//Setup the dictionary object with all the recording settings that this
//Recording sessoin will use
//Its not clear to me which of these are required and which are the bare minimum.
//This is a good resource: http://www.totodotnet.net/tag/avaudiorecorder/
NSMutableDictionary* recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue :[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
//Now that we have our settings we are going to instanciate an instance of our recorder instance.
//Generate a temp file for use by the recording.
//This sample was one I found online and seems to be a good choice for making a tmp file that
//will not overwrite an existing one.
NSString *fileName = [NSString stringWithFormat:#"%.0f.caf", [NSDate timeIntervalSinceReferenceDate] * 1000.0];
NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName];
recordedTmpFile = [NSURL fileURLWithPath:path];
NSLog(#"Using File called: %#",recordedTmpFile);
//Setup the recorder to use this file and record to it.
recorder = [[AVAudioRecorder alloc] initWithURL:recordedTmpFile settings:recordSetting error:&error];
//Use the recorder to start the recording.
//Im not sure why we set the delegate to self yet.
//Found this in antother example, but Im fuzzy on this still.
[recorder setDelegate:self];
//We call this to start the recording process and initialize
//the subsstems so that when we actually say "record" it starts right away.
[recorder prepareToRecord];
//Start the actual Recording
[recorder record];
//There is an optional method for doing the recording for a limited time see
//[recorder recordForDuration:(NSTimeInterval) 10]
} else {
toggle = YES;
[actSpinner stopAnimating];
[btnStart setImage:[UIImage imageNamed:#"recordrecord.png"] forState:UIControlStateNormal];
btnPlay.enabled = toggle;
btnPlay.hidden = !toggle;
[theTimer invalidate];
NSLog(#"Using File called: %#",recordedTmpFile);
//Stop the recorder.
[recorder stop];
}
}
- (IBAction)play_button_pressed{
//The play button was pressed...
//Setup the AVAudioPlayer to play the file that we just recorded.
AVAudioPlayer * avPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:recordedTmpFile error:&error];
[avPlayer prepareToPlay];
[avPlayer play];
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
//Clean up the temp file.
NSFileManager * fm = [NSFileManager defaultManager];
[fm removeItemAtPath:[recordedTmpFile path] error:&error];
//Call the dealloc on the remaining objects.
[recorder dealloc];
recorder = nil;
recordedTmpFile = nil;
}
#end
As you have structured your code now, the audio recording code is completely dependent on the presence of the user interface. As soon as your view controller gets deallocated, the audio recorder gets destroyed, too.
You have to decouple the audio recording code from the user interface code. Create a separate class that contains all properties and functionality that is related to recording. Then create an instance of that class outside your view controller (e.g. in your application delegate) and only pass this object to your view controller. The important thing is that the recorder object is totally unaffected by the presence or absence of the view controller.

Playing sound when app loads

trying to play a sound when app loads
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//sleep(2);
[NSThread sleepForTimeInterval:2.0];
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"austinpowers", CFSTR("wav"), NULL);
if (soundFileURLRef) {
CFStringRef url = CFURLGetString(soundFileURLRef);
}
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
// Override point for customization after application launch.
// Add the view controller's view to the window and display.
[self.window addSubview:viewController.view];
[self.window makeKeyAndVisible];
return YES;
}
it plays the sound, but only when the loading wallpaper (default.png) has gone.
if someone can help me, or point me in the right direction
thanks
Do not use Default.png, but create your custom splash screen view controller where you can display your image and play sound.
This issue was solved for me by doing the following in the AppDelegate.m file
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
NSURL *clip = [[NSBundle mainBundle] URLForResource: #"intro" withExtension:#"caf"];
self.startupPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:clip error:NULL];
[self.startupPlayer play];
}
This may work for you as well.