i am creating a application in which sound is played when a button is pressed and using a UISlider with which volume can be adjusted.Sometimes the volume of sound is too high and sometimes its too low even after increasing the volume of iphone to the full.How can i keep the volume to always high?? any possible way to integrate system volume with slider volume?? Using MPVolumview will get my app rejected i guess..
the code i am using on button touch is this
NSString* resourcePath = [[NSBundle mainBundle] resourcePath];
resourcePath = [resourcePath stringByAppendingString:#"/sound.mp3"];
NSLog(#"Path to play: %#", resourcePath);
player = [[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath:resourcePath] error:&err];
player.delegate = self;
[player play];
player.volume=.50;
player.numberOfLoops=-10;
-(IBAction)slidervaluechanged
{ player.volume=slider.value; }
}
Hemant,
The maximum volume you can have is when player.volume is equal to 1.0 (so long as the ringer volume is all the way maximum as well).
If the ringer volume is not at maximum, you can only go as high as whatever it is at by again using the value of 1.0
However, you could implement the MPVolumeView (I'm almost positive, as Pandora does it) and then you use that slider in your app instead. Then you can just set player.volume always equal to 1.0 and let the slider change the ringer volume.
More information on if you want to use MPVolumeView: http://developer.apple.com/iphone/library/documentation/MediaPlayer/Reference/MPVolumeView_Class/Reference/Reference.html and How do you implement an MPVolumeView?
I may be wrong, but I think Apple allows MPVolumeView if you use it as-is. They say in the class reference that it now changes the device ringer volume when you move the slider (which it didn't used to and that's why people were having to access private API to do). I'm going to try and implement it on my next update here in a week, so if I get rejected, I'll come back here and update this post to let everyone know.
Related
I'm using AVAudioPlayer to play a little shot sound when a user clicks a button. The sounds lasts about 3 seconds and I want that, if a user hit a button multiple times, the shot should sound multiple times. If the user clicks twice in 2 seconds, then the second sound should overlap the first shot.
My problem is that the shot only sounds every 3 seconds (if the user clicks rapidly) instead of every hit of the button.
Inside ViewDidLoad
NSString *path = [[NSBundle mainBundle] pathForResource:#"shot" ofType:#"caf"];
urlShotCaf = [NSURL fileURLWithPath:path];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:urlShotCaf error:nil] ;
[player prepareToPlay];
And when a person clicks the shot button
- (IBAction)tap:(id)sender {
clicks++;
[player play];
}
Can I do this with AVAudioPlayer? Should I use another framework?
As stated in reference here:
Play multiple sounds simultaneously, one sound per audio player, with precise synchronization
I guess you need a AVAudioPlayer for every sound you want to play simultaneously. Otherwise you could use any simple library like CocosDenshion that is really simple, easy to embed and powerful (it resides on OpenAL).
Just do
[SimpleAudioEngine sharedEngine] playEffect:#"yoursound.wav"];
and you are done.
Please try this. It works for me.
- (IBAction) tap:(id)sender {
if ([player isPlaying]) {
[player stop];
[player setCurrentTime:0.0];
}
[player play];
}
If high level frameworks fail, then you can dip down to AUSampler - an AudioUnit sample player (typically used for playback of sampled instruments, drum sounds, and so on). This should have very fast response times and support multiple active notes. Configure the sample's playback as one-shot. When the button is pressed, simulate a note on event. You could also map different samples (audio recordings) to different notes and velocity ranges.
The FoneHome iPhone app has a feature where you can play a sound as part of a local notification. That sound is loud regardless of what the iPhone's volume level is set at.
How is it possible to get a local notification (or push) to play an audio alert that is loud independent of what the current iPhone volume level is? I tried just setting the soundName to a WAV file but it plays at whatever the current volume is, and I see no options to set it otherwise.
Try using the following code
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/audiofile.mp3", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
[audioPlayer setVolume:x];
if (audioPlayer == nil)
NSLog([error description]);
else
[audioPlayer play];
Here 'x' is a floating point value which normally ranges from 0.0 to 1.0. However to increase the Volume level assign x value >10.0. But doing this may distort the sound a bit.
In my application, I am displaying multiple images in rows and columns when i click on a image i will play corresponding sound using
someName = [someName stringByAppendingFormat:#".mp3"];
[audioPlayer stop];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/%s", [[NSBundle mainBundle] resourcePath],[someName UTF8String]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.delegate = self;
When i am clicking on the one image i will get particular image sound. When i click on the another image the previous sound will be stopped and new sound corresponding the image will be played.
My requirement is when i click on the first image the sound must come and when i click on the second image the first sound must not stop and both must play and when i click on the third one the three sounds must play.
Please help me out
Apple recommends using an IMA4 encoded *.caf file for playing multiple sounds at once.
I need your help. How should I proceed to change the sound volume in my app. I don't want to use a volume slider. Instead I have an UIImageView which is a volume knob, in which I rotate clockwise to increase, and anti clockwise to decrease the sound volume. The rotation is just an animation and I've already done that part.
I need your help and advice on how to increase/decrease the volume. Thanks
I view this as a bug in Apple's code and have reported it to them both with Bug Reports and in person, but since they insist its a feature, you might as well benefit from it.
Use the following code to change your application's volume:
[[MPMusicPlayerController applicationMusicPlayer] setVolume:newVolume];
This will only work after you have established your audio session, either by playing a sound or by setting it active as such:
[[AVAudioSession sharedInstance] setActive:YES error:NULL];
Note as that you'll need MediaPlayer.framework and AVFoundation.framework and that the volume is between 0.0 and 1.0.
I would be careful calling setValue on an MPVolumeView since it probably won't do anything other than update the appearance of the slider, but not the actual device volume level. You would instead have to call _commitVolumeChange which is private API and will likely get your app rejected.
A short answer to how to control volume: It really depends on what you're trying to control the volume of.
If you want a "controls every sound within the app" sort of control then you can use an MPVolumeView but you cannot change it's value programmatically. You would then only be able to change the volume by either moving the slider with a touch or using the volume buttons on the side of the device. The best thing to do is create a global object that stores the volume level which any of your objects can read before they play their sound.
If it's an AVAudioPlayer object, you'd create the object and use [theAudioPlayerObject setVolume: someFloat]; where someFloat is a value between 0.0 and 1.0.
If it's a SystemSound object, you can't control volume.
If it's an AudioQueue you'd change it via AudioQueueSetParameter
Like I said.. it all depends on how you are playing the sound.
Update based on comment
For that particular example, you would set the volume like this:
Add to the AudioStreamer.h file
- (void)setVolume:(float)Level;
Add to the AudioStreamer.m file
- (void)setVolume:(float)Level
{
OSStatus errorMsg = AudioQueueSetParameter(audioQueue, kAudioQueueParam_Volume, Level);
if (errorMsg) {
NSLog(#"AudioQueueSetParameter returned %d when setting the volume.", errorMsg);
}
}
Add to the view controller for where the volume knob will be (this goes in the .m file.. i just did this as a couple UIButtons real quick, you'll have to do your own) and set up an IBAction to change the volume for a given value (you can pass in 0.0 thru 1.0 as a float)
- (IBAction)volumeUp:(id)sender
{
[streamer setVolume:1.0];
}
- (IBAction)volumeDown:(id)sender
{
[streamer setVolume:0.0];
}
Well, take the min Rotation (R1) and max Rotation (R2). Then do rotation / (R2 - R1) to get a % like a slider does.
EDIT:
To commit the volume change, add the following:
MPVolumeView *systemVolumeSlider = [[MPVolumeView alloc] initWithFrame: self.view.bounds];
[systemVolumeSlider setHidden:YES];
[systemVolumeSlider setUserInteractionEnabled:NO];
[self.view addSubview:systemVolumeSlider];
(Make sure to release systemVolumeSlider in dealloc)
Then, when the volume is changed, use setValue to set its value. You will also need to handle what happens when your user presses volume +/- buttons on the device.
When I use my app (on the device), the actual volume works OK for a while, but after a few days it seems to get 'stuck' at a low level.
Adjusting the volume rocker has no effect - and it shows 'Ringer' text. I've noticed that other people's apps are similarly affected if they show the 'Ringer' text when adjusting the volume. But apps which don't show 'Ringer' text are not affected by this.
How would I remove the 'Ringer' text and get my app to respond properly to different volumes?
I found some code on Apple's forums which fixes it. You have to use the AVFoundation.framework and put a bit of code into your app delegate. And put an audio file called 'blank.aif' into your project. Basically, it's a hack which prepares a file to play, but then never plays it. This fools the system into thinking that sound is being played all the time, which allows the user to use the main volume control.
#import <AVFoundation/AVFoundation.h>
//...
-(void)applicationDidFinishLaunching:(UIApplication *)application {
//volume control hack
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"blanksound" ofType:#"aif"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath];
AVAudioPlayer *volumeHack = [[[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil]retain];
[fileURL release];
[volumeHack prepareToPlay];
// other applicationDidFinishLaunching stuff
}