Convert code to function - iphone

Hello everyone i need to convert this code to a function with 2 parameters in this case the first parameter is News and the second one aif can u do this ??
-(IBAction)news
{
CFURLRef soundFileURLRef;
SystemSoundID soundFileObject;
CFBundleRef mainBundle;
mainBundle = CFBundleGetMainBundle ();
// Get the URL to the sound file to play
soundFileURLRef = CFBundleCopyResourceURL (mainBundle,
CFSTR ("News"),
CFSTR ("aif"),
NULL);
// Create a system sound object representing the sound file
AudioServicesCreateSystemSoundID (soundFileURLRef, &soundFileObject);
AudioServicesPlaySystemSound (soundFileObject);
return;
}

If the CFSTR thing is the problem, then the solution is:
-(void) playNews: (NSString*) news type: (NSString*) type
{
CFURLRef soundFileURLRef;
SystemSoundID soundFileObject;
CFBundleRef mainBundle;
mainBundle = CFBundleGetMainBundle ();
// Get the URL to the sound file to play
soundFileURLRef = CFBundleCopyResourceURL (mainBundle,
(CFStringRef)news,
(CFStringRef)type,
NULL);
// Create a system sound object representing the sound file
AudioServicesCreateSystemSoundID (soundFileURLRef, &soundFileObject);
AudioServicesPlaySystemSound (soundFileObject);
}
But the (IBAction) declaration makes no sense here because this method cannot be directly used from Interface Builder.

If this is meant to be an action received by a class from a user using a control, then the only thing you can do is -(IBAction)nameOfAction:(id)sender;. Otherwise, then you need to write the command to take the two arguments you require and call that from an IBAction.

Related

Playing Sound Loop or Stoping Play with AudioServices

I created this method to easily play sounds in an XCode iPhone application.
void playSound(NSString* myString) {
CFBundleRef mainBundle = CFBundleGetMainBundle();
NSString *string = myString;
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (__bridge CFStringRef) string, CFSTR ("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
}
The problem with this is, I don't know how to later stop the sound or to make the sound play on a loop forever until it is stopped. How would I go about doing this? Could I possibly make the method return the sound, and then put that in a variable to later be modified?
I'm afraid i dont know how to stop it, but try this for looping:
soundFile = [NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource:#"AudioName" ofType:#"wav"]];
sound = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFile error:nil];
sound.numberOfLoops = -1; //infinite
[sound play];
From documentation: "The interface does not provide level, positioning, looping, or timing control, and does not support simultaneous playback...".
http://developer.apple.com/library/ios/#documentation/AudioToolbox/Reference/SystemSoundServicesReference/Reference/reference
So for sound playback it is better use AVFoundation classes.
System Sound Services usually is used to play short sounds/alerts/etc and pausing/stopping probably should be avoided. If this is really needed you could try AudioServicesDisposeSystemSoundID(systemSoundID) to stop the sound.
As for looping you could create recursive function to loop the sound using AudioServicesPlaySystemSoundWithCompletion.
Example (swift 3):
func playSystemSound(systemSoundID: SystemSoundID, count: Int){
AudioServicesPlaySystemSoundWithCompletion(systemSoundID) {
if count > 0 {
self.playSystemSound(systemSoundID: systemSoundID, count: count - 1)
}
}
}
So in your example you would just replace AudioServicesPlaySystemSound(soundID); with playSystemSound(systemSoundID: soundID, count: numOfPlays)
In case if you want to decide to play a sound based on a bool variable,
private func playSound() {
if isStarted {
AudioServicesPlaySystemSoundWithCompletion(kSystemSoundID_Vibrate, {
if self.isStarted {
self.playSound()
}
})
}
}

Yellow warning triangle when implementing sounds I don't understand

When I implement sounds in my apps, I always ge a couple of yellow warning triangles with the warning:
"implicit declaration of function "audio services create system soundID" is invalid in C99"
It doesn't effect anything in my app I just wondered if it's something in my code and something I should be addressing?
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"btnclick", CFSTR
("mp3"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID (soundFileURLRef, &soundID);
AudioServicesPlaySystemSound (soundID);
The compiler isn't finding declarations of the AudioServices functions and is complaining about that.
The documentation for those functions says which framework they come from, so an import...
#import <AudioToolbox/AudioToolbox.h>
...should get rid of the warnings.

iPhone AudioServicesPlaySystemSound: route though headphones?

I'm having trouble using AudioServicesPlaySystemSound. Things work great when output goes through the speakers. However, when a user plugs in headphones, there is no output. Is there an easy way to set up some kind of listener so that audio is automatically routed through the headphones when they are plugged in, and otherwise through the speaker?
I'm using the following method to play short, simple AIF sound samples:
-(void)playAif:(NSString *)filename {
SystemSoundID soundID;
NSString *path = [[NSBundle mainBundle]
pathForResource:filename ofType:#"aif"];
if (path) { // test for path, to guard against crashes
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path],&soundID);
AudioServicesPlaySystemSound (soundID);
}
}
I know I must be missing something, some bit of setup that would do this. Any ideas?
Thanks #Till for pointing me to the relevant portion of the docs. For others with this issue, the solution is to explicitly set the session category, in my case to ambient sound. This code snipped from apple's docs:
UInt32 sessionCategory = kAudioSessionCategory_AmbientSound; // 1
AudioSessionSetProperty (
kAudioSessionProperty_AudioCategory, // 2
sizeof (sessionCategory), // 3
&sessionCategory // 4
);
So, my method for playing audio now looks like this:
-(void)playAif:(NSString *)filename {
// NSLog(#"play: %#", filename);
SystemSoundID soundID;
NSString *path = [[NSBundle mainBundle]
pathForResource:filename ofType:#"aif"];
if (path) { // test for path, to guard against crashes
UInt32 sessionCategory = kAudioSessionCategory_AmbientSound; // 1
AudioSessionSetProperty (
kAudioSessionProperty_AudioCategory, // 2
sizeof (sessionCategory), // 3
&sessionCategory // 4
);
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path],&soundID);
AudioServicesPlaySystemSound (soundID);
}
}
This solves my problem handily! The only worry I have is that setting it explicitly every single time I play a sound might be excessive. Anyone know a better and safer way to set it and forget it? Otherwise, this works delightfully.

why the volume of sounds does not change in my app?

I used code below in my application, and if I increase or decrease the volume from the iPhone's button it's still the same, but if the phone is in silent mode the voice will be muted.
The code:
-(void) playNote: (NSString *)Note type: (NSString *)type
{
CFURLRef soundFileURLRef;
SystemSoundID soundFileObject;
CFBundleRef mainBundle;
mainBundle = CFBundleGetMainBundle ();
// Get the URL to the sound file to play
soundFileURLRef = CFBundleCopyResourceURL (mainBundle,
(CFStringRef)Note,
(CFStringRef)type,
NULL);
NSLog(#"%#\n", soundFileURLRef);
// Create a system sound object representing the sound file
AudioServicesCreateSystemSoundID (soundFileURLRef, &soundFileObject);
AudioServicesPlaySystemSound (soundFileObject);
}
What am I doing wrong?
You need to set your Audio Category properly before playing back sounds.
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory);

Using system Sound to play sounds

Here is the code:
-(void)stop
{
NSLog(#"Disposing Sounds");
AudioServicesDisposeSystemSoundID (soundID);
//AudioServicesRemoveSystemSoundCompletion (soundID);
}
static void completionCallback (SystemSoundID mySSID, void* myself) {
NSLog(#"completion Callback");
}
- (void) playall: (id) sender {
[self stop];
AudioServicesAddSystemSoundCompletion (soundID,NULL,NULL,
completionCallback,
(void*) self);
OSStatus err = kAudioServicesNoError;
NSString *aiffPath = [[NSBundle mainBundle] pathForResource:#"slide1" ofType:#"m4a"];
NSURL *aiffURL = [NSURL fileURLWithPath:aiffPath];
err = AudioServicesCreateSystemSoundID((CFURLRef) aiffURL, &soundID);
AudioServicesPlaySystemSound (soundID);
NSLog(#"Done Playing");
}
Output:
Disposing Sounds
Done Playing
In actual no sound gets play at all and completion call back isn't called as well. Any idea what could be wrong here?
I want to stop any previous sound before playing current.
AFAIK, the only supported files are .caf, .aif, or .wav:
To play your own sounds, add the sound
file to your application bundle; the
sound file must adhere to the
following requirements:
Must be .caf, .aif, or .wav files.
The audio data in the file must be in PCM or IMA/ADPCM (IMA4) format.
The file's audio duration must be less than 30 seconds.
Audio & Video Coding How-To's
What does err contain? From that you should be able to infer the problem.
You can use AudioToolBox framework for this:
CFBundleRef mainbundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef = CFBundleCopyResourceURL(mainbundle, CFSTR("tap"), CFSTR("aif"), NULL);
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundFileObject);
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
AudioServicesPlaySystemSound(1100);