I'm using SCListener to get the iPhone's volume, but I'd like to put an observer on the volume. So when it changes I can update the volume meter on the screen. But doing something like:
SCListener *listener = [SCListener sharedListener];
[listener addObserver:self
forKeyPath:#"peakPower"
options:NSKeyValueObservingOptionOld
context:NULL];
doesn't do the trick because peakPower isn't a variable. How would I put an observer on the function? Or how would a create a listener I could stop and start to keep track of the peak power in a variable I could put an observer on?
Thanks in advance for the help!
SCListener is not Key Value Observer compliant. AFAIK, you have to poll for the values.
Simply set up a repeating timer, and read the levels each time the timer fires.
Related
I'm trying to create an MPMoviePlayer as paused at appearance.
I've tried doing just a regular pause, as a selector with 0.1s delay, let NSNotificationCenter pause it as soon as the movie started (This did work, but with a slight delay. The movie played for a second before paus).
Is there a way to keep it paused from first appearance?
Thanks in advance
use pause method to do it
[moviePlayer pause];
Sorry for taking y'alls time...
A friend helped me just after I posted the question.
Apparently there is a property called shouldAutoplay that I missed in the documentation.
Just use that.
I would like to track the last position of a media item (song or podcast). I can access the total duration using the MPMediaItemPropertyPlaybackDuration property of the MPMediaItem. I am interested in way to store and track the last played position.
Does every player do this on their own ? Would I get it for free if I just play entities with the MediaPlayer ?
I have not hooked media player to play items yet, I would like to understand if I need to implement my own bookmarking method.
[audioPlayer currentPlaybackTime]
Will give you the current playback time. I have a resume feature on a podcast player and I simply watch for interruptions with:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playPlaybackStateChanged:) name:MPMoviePlayerPlaybackStateDidChangeNotification object:self.audioPlayer];
and then inside that callback function, check the state:
if(self.audioPlayer.playbackState == MPMoviePlaybackStateInterrupted)
and record the playback time on interruption...
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.
I have implemented application in which there is one speedo meter and three buttons.
1)Start 2)stop 3)review
When i press the start button than UIAccelerometer is start
when i press stop button than UIAccelerometer is stop.
when i press review button than in next view it will show hisry of time.
My problem is that:
When i press the start button than apliuction is terminated.
how to start and stop UIAccelerometer ??
Use this to start the accelerometer measurement via delegate method accelerometer:didAccelerate:
[UIAccelerometer sharedAccelerometer].delegate = self;
And this to stop it
[UIAccelerometer sharedAccelerometer].delegate = nil;
To "start" and "stop" accelerometer (i.e. to register and ignore the accelerometer inputs), set the UIAccelerometer delegate to the class which will use the data (on start) or set the delegate to nil (to stop). If you set the delegate to nil, the accelerometer data will not be used by your app.
In case the issue is something else (an error in your code etc), please post what you have tried till now and you'll get more helpful answers.
Comment out the UIAccelerometer code and then try start, stop, review, and start to see if it still crashes.
I want to use AVAudioPlayer to play short sounds... because I have more control than System Sound.
I have several buttons which are hooked up to play several different short sounds.
Each sound file is about 1.5 - 2.0 seconds.
Everything works fine ...except ...I have to wait for the sound to stop before I can press the button and the sound will play again.
Currently the individual AVAudioPlayers are created on viewDidLoad ... and the sounds are called to play when the buttons are pressed
I tried creating the players when the button is pressed... this solves the above problem... but after a while the app crashes... all sound stops working.
Any ideas?
Thanks
Jonathan
If AVAudioPlayer stops playing sounds, it is usually because there are too many player instances created, usually leaked. You should make sure you release some after you are done.
You need to set the currentTime of the player to 0 before playing. Calling [player play] when it is already playing has no effect.
player.currentTime = 0;
[player play];
Creating new ones is fine, but make sure your header declares and does this:
- (void) audioPlayerDidFinishPlaying: (AVAudioPlayer *) player successfully: (BOOL) completed {
[player release];
}
if your app is simple, that will release the memory of anything done that's no longer necessary, as per mahboudz' suggestion.
This might not totally prevent crashing, depending on your sound file sizes, and if you dealloc the scene. You might want to add
if (self.view.superview) { //release }
or something.
This is all memory handling. You may want to brush up on pointers to know how to handle your player objects, literally within any function, and still feel comfortable placing release in dealloc OR the didFinish: delegate function, and know why it doesn't belong in the other one.
The iPhone can be interrupted, stopped, and messed with at any time, so you have to know how to handle the memory and how to deal with it when it happens. I just had a crash of a similar nature, and everything above applied to it. NSXML delegates would be a nightmare without knowing pointers... same for AVAudioPlayer
If you plan to use a lof of short sounds, you might want to think about switching to OpenAL.
It's not a lot more complicated and you will save yourselve some trouble in more complicated audio settings later on.
There's a tutorial and some useful code available here (archived here).
this is MAYBE because you have created the AVAudioPlayers inside the viewDidLoad(). I remember I had the same problem. Just initialize them inside the class but not there. hope it works!
EDIT:
ok i saw the date... 2009...