iOS sound playback volume not respecting volume change or mute - iphone

This is my current code
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);
}
It works, but it doesn't let you change the volume on the device or mute it with the mute switch. What is the simplest way to enable these features? Thanks.

Why don't you use AVFoundation? If all you want is to play simple sound effects, it would be a much better choice as it is a higher level API.
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"file" ofType:#"mp3"];
NSURL *url = [NSURL fileURLWithPath:filePath];
// Assuming audioPlayer is an ivar.
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = -1;
if (audioPlayer == nil)
NSLog([error description]);
else
[audioPlayer play];
AVAudioPlayer should respect the volume settings of the user.

Related

AVAudioPlayer is not working in iPhone 5

I am developing an iPhone application.In this app i am using AVAudioPlayer for playing audio.
This is my code for playing the sound.
NSString* resourcePath = [[NSBundle mainBundle] resourcePath];
resourcePath = [resourcePath stringByAppendingString:#"/sound.mp3"];
NSError* err;
player_ = [[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath:resourcePath] error:&err];
if( err )
{
}
else
{
[player_ prepareToPlay];
[player_ play];
int playingLoops = 0;
player_.numberOfLoops = playingLoops;
}
It is woking fine on iphone devices except iPhone5.While i run the app on iPhone 5 i get following error then app crashes.
2012-11-26 09:02:28.484 test[728:1dd03] <0xb0081000> Error '!obj' trying to fetch default input device's sample rate
2012-11-26 09:02:28.484 test[728:1dd03] <0xb0081000> Error getting audio input device sample rate: '!obj'
2012-11-26 09:02:28.494 test[728:1dd03] <0xb0081000> AQMEIOManager::FindIOUnit: error '!dev'
I was also facing same problem giving the same error. when try to solve this problem i notice that there is no problem in code. we need to update media player or install flash player and it's work fine.
You have to add AVAudioPlayerDelegate to your .h file and following code to your .m file
NSString* resourcePath =[[NSBundle mainBundle]pathForResource:#"sound" ofType:#"mp3"];
NSError* err;
AVAudioPlayer *audioplayer =[[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath: resourcePath] error:&err];
audioplayer.delegate=self;
if( err )
{
NSLog(#"%#",err);
}
else
{
[audioplayer prepareToPlay];
[audioplayer play];
}
This code is working for me and accept the answer if it is working.
Anbu, try below code.At my end it's working fine.
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/audiofile.mp3", [[NSBundle mainBundle] resourcePath]]];
NSLog(#"File path is:->%#",[NSString stringWithFormat:#"%#/audiofile.mp3", [[NSBundle mainBundle] resourcePath]]);
NSFileManager* manager;
manager = [NSFileManager defaultManager];
if([manager fileExistsAtPath:[NSString stringWithFormat:#"%#/audiofile.mp3", [[NSBundle mainBundle] resourcePath]]])
{
printf("file Exists...\n\n");
}
else
printf("File not exist...\n\n");
NSError *er;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = -1;
if (audioPlayer == nil)
NSLog([er description]);
else
[audioPlayer play];
In any concern, let me know. And, also please check your console for the full path and for file exist or not.

How do you make the iphone acceleromator trigger sound more effectively using avaudioplayer?

I have created a simple app that triggers 3 different sounds based on the x, y, z axis of the accelorometer, like an instrument. At the moment, if I set the frequency update interval of the accelometer too low, it plays the sound to much, and if I set it too high it it isn't responsive enough. I am a complete beginner to objective c and iphone development, can you tell by the code!..
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional
UIAccelerometer* accelerometer = [UIAccelerometer sharedAccelerometer];
[accelerometer setUpdateInterval: 25.0 / 10.0f];
[[AVAudioSession sharedInstance] setDelegate: self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error: nil];
[accelerometer setDelegate:self];
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
player.volume = 0.5;
player.numberOfLoops = 0;
player.delegate = self;
}
- (void)accelerometer:(UIAccelerometer *)acel didAccelerate:(UIAcceleration *)aceler
{
if (aceler.x > 0.5) {
NSString *fileName = [NSString stringWithFormat:#"snare"];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:fileName ofType:#"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
NSLog(#"acceleration.x = %+.6f greater", aceler.x);
[player play];
}
else if (aceler.y > 0.5) {
NSString *fileName = [NSString stringWithFormat:#"kick2"];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:fileName ofType:#"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
NSLog(#"acceleration.y = %+.6f greater", aceler.y);
[player play];
}
else if (aceler.z > 0.5) {
NSString *fileName = [NSString stringWithFormat:#"hat"];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:fileName ofType:#"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
NSLog(#"acceleration.y = %+.6f greater", aceler.z);
[player play];
}
else {
[player stop];
};
}
Setting the accelerometer's update frequency to a low value wont help here. Imagine the following situation:
time: ------------------------>
real world acceleration event: ___X_____X_____X_____X___
acceleration update: X_____X_____X_____X_____X
sound output started: _________________________
This draft represents a user shaking the device with the same frequency as the accelerometer is updated. But the shake event occurs just in the middle between two accelerometer updates. As a result, the shake events won't be registered and no sound is played.
Consider a high accelerometer update frequency in contrast to the prior approach:
real world acceleration event: ___X_____X_____X_____X___
acceleration update: XXXXXXXXXXXXXXXXXXXXXXXXX
sound output started: ___X_____X_____X_____X___
Basically all real world events result in a sound play within this situation.
The amended code is the following:
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"viewDidLoad");
UIAccelerometer* accelerometer = [UIAccelerometer sharedAccelerometer];
//[accelerometer setUpdateInterval: 25.0 / 10.0f];
[accelerometer setUpdateInterval: 0.01f];
[[AVAudioSession sharedInstance] setDelegate: self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error: nil];
[accelerometer setDelegate:self];
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
//player.volume = 0.5;
//player.numberOfLoops = 0;
//player.delegate = self;
}
- (void)accelerometer:(UIAccelerometer *)acel didAccelerate:(UIAcceleration *)aceler
{
if ((aceler.x > ACC_THRESHOLD)&&((playerX == nil)||(playerX.isPlaying == NO))) {
NSString *fileName = [NSString stringWithFormat:#"snare"];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:fileName ofType:#"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
playerX = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
NSLog(#"acceleration.x = %+.6f greater", aceler.x);
playerX.delegate = self;
[playerX play];
}
if ((aceler.y > ACC_THRESHOLD)&&((playerY == nil)||(playerY.isPlaying == NO))) {
NSString *fileName = [NSString stringWithFormat:#"kick2"];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:fileName ofType:#"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
playerY = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
NSLog(#"acceleration.y = %+.6f greater", aceler.y);
playerY.delegate = self;
[playerY play];
}
if ((aceler.z > ACC_THRESHOLD)&&((playerZ== nil)||(playerZ.isPlaying == NO))) {
NSString *fileName = [NSString stringWithFormat:#"hat"];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:fileName ofType:#"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
playerZ = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
NSLog(#"acceleration.z = %+.6f greater", aceler.z);
playerZ.delegate = self;
[playerZ play];
}
//else {
// [player stop];
//};
}
Please note, that multiple sound plays may be triggered by just one event as each dimension is evaluated separately now. A constant has been introduced by #define ACC_THRESHOLD 0.5f. A new sound play for one dimension is started only, after a previous play finished.
After these general change of event handling you may start optimizations with a signal filter.
Additionally you may use AVAudioPlayer's delegate methods for more detailed sound handling:
#pragma mark -
#pragma mark AVAudioPlayerDelegate methods
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
NSLog(#"audioPlayerDidFinishPlaying: %i", flag);
}
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error{
NSLog(#"audioPlayerDecodeErrorDidOccur: %#", error.description);
}

App sounds cause iPod music, Pandora or Pod cast sound to stop

we have different sounds for actions and buttons within our app. We've heard a number of complaints where users background music stops as soon as one of our sounds is played. We're not quite sure why this is happening. Here is the code we're using to toggle our sounds.
- (void)playSound:(NSString *)sound {
if ( playSoundPath == nil ) {
playSoundPath = [[NSBundle mainBundle] pathForResource:sound ofType:#"wav"];
playSound = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:playSoundPath] error:NULL];
playSound.delegate = self;
}else{
playSoundPath = nil;
[playSound release];
playSoundPath = [[NSBundle mainBundle] pathForResource:sound ofType:#"wav"];
playSound = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:playSoundPath] error:NULL];
playSound.delegate = self;
}
BOOL enabled = [[NSUserDefaults standardUserDefaults] boolForKey:#"sounds_key"];
if ( enabled ){
[playSound stop];
[playSound play];
}
}
Update: We've actually ended up changing the above to the following per a few users suggestions. This allows iPod music or pod casts to continue and our sounds to play without stopping this background sound. This is possible by setting our sounds as "ambient" sound. This requires that you add the "AudioToolBox" framework and import this framework into your class using the following,
#import <AudioToolbox/AudioToolbox.h>
Here is the code we're using now,
BOOL enabled = [[NSUserDefaults standardUserDefaults] boolForKey:#"sounds_key"];
if ( enabled ){
AudioSessionInitialize(NULL, NULL, NULL, self);
UInt32 category = kAudioSessionCategory_AmbientSound;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &category);
AudioSessionSetActive(YES);
NSString *path = [NSString stringWithFormat:#"%#/%#.wav",[[NSBundle mainBundle] resourcePath], sound];
SystemSoundID soundID;
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
AudioServicesPlaySystemSound(soundID);
}

how to play music using AVAudioPlayer when screen os locked

i need to play a simple sound using AVAudioPlayer when screen is locked .How can I do that please help
This was answered here before. As the thing suggests you need to set your audio session as in this example
UInt32 category = kAudioSessionCategory_MediaPlayback;
OSStatus result = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
sizeof(category), &category);
if (result){
DebugLog(#"ERROR SETTING AUDIO CATEGORY!\n");
}
result = AudioSessionSetActive(true);
if (result) {
DebugLog(#"ERROR SETTING AUDIO SESSION ACTIVE!\n");
}
First: Add following frameworks into your project
AudioToolbox,
CoreAudio,
MediaPlayer
AVFoundation.
Second: Add your info.plist file a new key
Required background modes = App plays audio
Third: Create a method called keepAwakeForAudio and call it just after playing your audio
-(void)keepAwakeForAudio
{
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory);
AudioSessionSetActive(true);
}
//////
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/rain1_Rain_on_Street.m4a", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = -1;
if (audioPlayer == nil)
NSLog([error description]);
else
[audioPlayer play];
[self **keepAwakeForAudio**];

iPhone SDK - Mute

I have the following to play m background music:
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/bgMusic.mp3", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
bgMusic = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
bgMusic.numberOfLoops = -1;
bgMusic.volume = 0.1;
if (bgMusic == nil)
NSLog([error description]);
else
[bgMusic play];
But how I can I in any view, mute all sounds, not just this, any sound?
Thanks.
[[MPMusicPlayerController applicationMusicPlayer] setVolume:(use a value between 0.0 and 1.0)]
If your MPMoviePlayerController uses the application audio session, this works.