AudioServicesPlaySystemSound Volume on iPad - ios

in my application I use AudioServicesPlaySystemSound to play little caf files.
When run my app on the iPhone and I change volume by lateral buttons, the app's sound changes
too, but on iPad the sound's volume in my app is always the same.
Maybe because on the iPhone is the ring volume, instead on the iPad is device volume.
How can I obtain same iPhone behavior on iPad?
Excuse me for my bad English....

I had the same problem but if you change the system sounds volume with buttons all the system sounds will be modified along with your app's. I found this really annoying.
The solution is to use AVAudioPlayer in place of AudioServices: as easy, but way more versatile. And there you can finely tune the volume for each sound, programmatically.
NSURL *soundurl = [[NSBundle mainBundle] URLForResource: #"mysound" withExtension: #"caf"];
AVAudioPlayer *mySoundPlayer =[[AVAudioPlayer alloc] initWithContentsOfURL:soundurl error:&error];
mySoundPlayer .volume=0.4f; //between 0 and 1
[mySoundPlayer prepareToPlay];
mySoundPlayer.numberOfLoops=0; //or more if needed
[mySoundPlayer play];

Related

AVAudioPlayer not playing on some devices

My code is working perfectly on simulators, on iPad-4 and on iPhone 6+, all running iOS 9.0.2.
However, and I know that's a weird claim, on my iPad Air 2 it looks like it's working, but actually nothing is heard. Also reproduced on other devices like another iPhone 6+ and another iPhone 6 running iOS 8.4. I have create a demo project (link below) so that others can try their own device.
I'm doing this:
Initializing an NSURL *url with a path under [[NSBundle mainBundle] resourcePath]:
/var/mobile/Containers/Bundle/Application/0ACADB94-886E-4C7E-A327-3FFF0E54CEF9/My App.app/sndEfcts/!snap.mp3
Assigning a new object into an ivar:
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&err];
Test url in debugger - good! (notice that the space became %20. I also verified that the file exists):
(lldb) po audioPlayer.url
file:///var/mobile/Containers/Bundle/Application/0ACADB94-886E-4C7E-A327-3FFF0E54CEF9/My%20App.app/sndEfcts/!snap.mp3`
Play if created ok:
if (audioPlayer) {
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
__unused BOOL playOk = [audioPlayer play];
}
Delegate of finish is activated:
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
... and flag is saying YES! - but nothing is heard :(
So everything appears to be ok, and still no sound is heard (although other sounds of other apps do work ok)
Does anyone have an idea for the cause of such behavior?
EDIT
I have create a simple project to demonstrate. It is happening on various devices, even on 8.4. On simulators it is always working
I have found the solution.
On problematic devices, "mute" was on, affecting some of the sounds in the device. To prevent this, call this somewhere on beginning of your app:
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: nil];
This will cause the audio to be treated as playback and thus not be muted by the mute option.
I have learned that users typically don't know where to find the mute on/off control. On iPad Air 2: raise the lower pane from bottom and press the speaker icon.

iOS 8 Custom Keyboard that play sounds

I'm trying to build a custom keyboard for iOS 8 that a custom play sound when a key is pressed. I'm using a AVAudioPlayer and small mp3-files.
This works fine in the simulator, but on a real device I don't get any sounds.
RequestOpenAccess is enabled.
Please not that I'm not trying to play the default keyboard click sound, but a custom sound. Most existing questions seems to be about the default system sound.
edit: I've also tried using .caf and .aiff files and loading and playing them with SystemSoundID.
This snippet plays custom sound in my keyboard project.
NSString *soundPath = [[NSBundle mainBundle] pathForResource:#"your_custom_sound"
ofType:#"mp3"];
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath: soundPath], &soundID);
AudioServicesPlaySystemSound (soundID);
Cited from:
How to play tock sound when tapping custom keyboard buttons
I'm positive this is not your case but it often happens that the sound on the device is turned off. I made the mistake searching for an hour why sound didn't work. If it could only be that, it would be a quick fix ;)

iOS: aiff quiet on ipad 2 and 3

Three buttons triggering three AVAudioPlayers, identical code, identical sound files except for some pitch shifting.
All three sounds loaded thus:
NSString *pathDigitClick = [[NSBundle mainBundle] pathForResource:#"tickLoVol" ofType:#"aiff"];
_playerDigit=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:pathDigitClick] error:NULL];
[_playerDigit prepareToPlay];
And played so:
[_playerDigit play];
All three the same volume on iPad1, as they should be, but one of the aiffs sounds much quieter on the iPads 2 and 3.
I solved it by using another aiff, but I'd still like to know how it happens that the problem only occurs on the newer iPads.

iOS: how to conveniently store and play many mp3 files

I have a program with about 2000 short mp3 files. I am now storing all those file into folder Supporting Files and when I want to play I call this function:
-(void)playSound:(NSString *)mySoundFileName{
NSString *filePath = [[NSBundle mainBundle] pathForResource:mySoundFileName ofType:#"mp3"];
if ([NSData dataWithContentsOfFile:filePath]) {
url = [NSURL fileURLWithPath:filePath];
audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url
error:nil];
[audioPlayer play];
}
}
However, the first time I play the sound, it always takes long time to search/load the file. More specifically, after pressing "play sound" button to play sound, I have to wait for at least 5 seconds until it plays. It is OK to play other sound after that, i.e, it play almost immediately when I press "play sound" button. Do you have any suggestion to store and play those many files more efficiently? Thank you very much
It can sometimes take an undesirable amount of time for AVAudioPlayer to start playing initially. A good way to solve this is to make the initial alloc/init before you call play. This way the player is ready to play before the user presses the play button. Additionally, calling [player prepareToPlay]; before play will help improve performance slightly.

iOS audio samples play only on earphone output

I'm developing a program that plays a short sample when a button is pressed. The problem is that it only plays through earphone output and not through the device's speaker. I've tried .wav and .aiff and AVAudioPlayer and SystemSoundID. On the simulator I can hear the sound. I'm using iPod Touch 4th gen. running iOS 4.1. Example code:
NSString *soundFile = [[NSBundle mainBundle] pathForResource:#"button" ofType:#"wav"];
NSURL *url = [NSURL fileURLWithPath:soundFile];
AudioServicesCreateSystemSoundID( (CFURLRef)url, &buttonID);
AudioServicesPlaySystemSound( buttonID );
Edit (solution found): I tried with another .wav file and it worked. Odd, because the original .wav's format is supported by iOS.
Sounds like you've solved the issue, but as a heads-up, you should only be using SystemSoundID style playback for user interface related sounds.
If the audio is a key part of your app, you need to set the appropriate AVAudioSession category and use (for example) the AVAudioPlayer playback methods.
Then again, this might not be relevant. :-)

Resources