MPMusicPlayerController not responding to currentPlaybackRate near 1 - ios

I'm trying to use the currentPlaybackRate property on MPMusicPlayerController to adjust the tempo of a music track as it plays. The property works as expected when the rate is less than 0.90 or greater than 1.13, but for the range just above and below 1, there seems to be no change in tempo. Here's what I'm trying:
UIAppDelegate.musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
... load music player with track from library
[UIAppDelegate.musicPlayer play];
- (void)speedUp{
UIAppDelegate.musicPlayer.currentPlaybackRate = UIAppDelegate.musicPlayer.currentPlaybackRate + 0.03125;
}
- (void)speedDown
{
UIAppDelegate.musicPlayer.currentPlaybackRate = UIAppDelegate.musicPlayer.currentPlaybackRate - 0.03125;
}
I can monitor the value currentPlaybackRate and see that it's being correctly set, but there seems to be no different in playback tempo until the 0.9 or 1.13 threshold has been reached. Does anyone have any guidance or experience on the matter?

I'm no expert, but I suspect that this phenomenon may be merely an artefact of the algorithm used to change the playback speed without raising or lowering the pitch. It's a tricky business, and here it must be done in real time without much distortion, so probably an integral multiple of the tempo is needed. You might want to read the wikipedia article on time stretching, http://en.wikipedia.org/wiki/Audio_timescale-pitch_modification

Actually I've found out the problem: the sentence myMusicPlayer.currentPlaybackRate = 1.2 must be placed after the sentence .play(). If you put the rate setting before the .play(), it would not work.

Related

AKOscillator frequency range for theremin sound in iOS

I want to create similar sound to theremin using touch coordinate on screen. I'm using y axis as frequency, x axis as amplitude.
Due to my small research I believe I can create it using AKOscillator or AKFMOscillator from AudioKit framework (please let me know if any other oscillator works better in this case). I'm open to other frameworks like built-in AudioToolbox (MIDINoteMessage etc.) if I can create similar sound to theremin.
Here it says theremin has two oscillators. One with fixed-frequency on 260kHz and one is dynamic between 257-260kHz. It superimposes their output (it takes difference of them I guess?). And it outputs between frequency between 0-3 kHz.
When I create sounds using AKFMOscillator with baseFrequency between 257-260 kHz, it sounds high-pitched.
When I try with one oscillator range between 0-3kHz it sounds very robotic. How I can simulate timbre of theremin?
How can I make it sound better? Should I mix two oscillators? I tried mixing with AKMixer but when both oscillators use same frequency and amplitude, it makes no difference.
I tried to mapping to nearest note (auto-tune), I tried limiting the frequency between 3-4 octaves. It sounds better but still not good as theremin.
What should use ( AKOscillator or AKFMOscillator, OscillatorBank), with which parameters (rampDuration, baseFrequency, modulationIndex, amplitude) to simulate more thereminish sound?
Update:
I did some more research and played with Synth One presets. Now, I know I need two oscillators mixed (both set to saw-shape wave). Changing ADSR(envelope) values to specific ranges creates richer sound (this gives the instrumental sound type). And a lfo to create the wavy (or spooky) sound effect. Playing notes (specific frequencies) creates good sounds, if you play every frequency in between note frequencies it doesn't sound good.

How to change the percentage according to the recorded audio volume

As shown on the below figure (Source : Disney spot light app https://itunes.apple.com/in/app/disney-spotlight-karaoke/id455072135?mt=8)
I want to change the percentage value, depends on recorded sound while recording audio.
if we keep the device in the quite silent places, the peracentage not to be changed..
If we keep the device at a full loudly place, song/ voice / machine sound or any sound.. the percentage needs to be increase according to the volume recorded.
How can we do it in iOS using objective c
Supposing you're using an AVAudioRecorder to record your sounds, you can call:
[audioRecorder setMeteringEnabled:YES];
before starting to record in order to enable the audio-level metering. Then at any time you can call:
[audioRecorder updateMeters];
float audioPower = [audioRecorder averagePowerForChannel:0]; // You can change 0 according to your input channels
audioPower will give you a float value between -160 and 0 dB, that you then can adapt to your needs.
If you want to constantly poll the audio level you can call the code above through an NSTimer action or use an NSOperationQueue
Check AVAudioRecorder reference for more details on these methods

OpenAL offset race condition

I'm using OpenAL on iOS and seem to be getting some kind of race condition where rapid alternating calls to get and set AL_BYTE_OFFSET end up resetting the value to 0. This is all done while the audio source is playing.
+ (void) seekTrackSeconds:(float)bytesDelta
{
ALint position;
alGetSourcei(sourcesArr[targetSourceIdx], AL_BYTE_OFFSET, &position);
NSLog(#"byte pos read: %d", position);
alSourcei(sourcesArr[targetSourceIdx], AL_BYTE_OFFSET, position + bytesDelta);
}
After the first 3 calls (always 3...kinda weird), the output of byte pos read resets to 0. I feel like there's a race condition with setting / reading that value. I put a sleep for 20ms between the read and write and get a less frequent occurrence of the error. At 200ms sleep, I don't notice it, but that's unacceptable performance.
Anyone experience the same issue? Background is I'm trying to implement a 'scroll to seek' functionality for song playback. As you scroll a virtual jog wheel, the song should fast forward.

portaudio video/audio sync

I use ffmpeg to decode video/audio stream and use portaudio to play audio. I encounter a sync problem with portaudio. I have a function like below,
double AudioPlayer::getPlaySec() const
{
double const latency = Pa_GetStreamInfo( mPaStream )->outputLatency;
double const bytesPerSec = mSampleRate * Pa_GetSampleSize( mSampleFormat ) * mChannel;
double const playtime = mConsumedBytes / bytesPerSec;
return playtime - latency;
}
mCousumeBytes is the byte count which written into audio device in the portaudio callback function. I thought I could have got the playing time according to the byte count. Actually, when I execute the other process ( like open firefox ) which make cpu busy, the audio become intermittent, but the callback doesn't stop so that mConsumeBytes is more than expected, and getPlaySec return a time which is larger than playing time.
I have no idea how this happened. Any suggestion is welcome. Thanks!
Latency, in PortAudio is defined a bit vaguely. Something like the average time between when you put data into the buffer and when you can expect it to play. That's not something you want to use for this purpose.
Instead, to find the current playback time of the device, you can actually poll the device using the Pa_GetStreamTime function.
You may want to see this document for more detailed info.
I know this is old. But still; PortAudio v19+ can provide you with its own sample rate. You should use that for audio sync, since actual sample rate playback can differ between different hardware. PortAudio might try to compensate (depending on implementation). If you have drift problems, try using that.

AVPlayer rate property for HTTP Live Streaming

I am trying to develop a player using AVFoundation and enable fast forward and rewind. I am setting the player's rate property to 0, 0.25, 0.5, 1, 1.5, 2.0.
rate property of 0,1 is working as expected and setting it to pause and play.
0.25, 0.5 also works and displays video in slow motion.
My question is that setting the property of 1.5, 2.0 is not working, it just keeps playing. This works for .mp4 videos though. Is this not supported for HLS? I am using the sample HLS stream's provided by Apple.
http://devimages.apple.com/iphone/samples/bipbopgear4.html
How do we do enable rewind and fast forward? Should I somehow use seekToTime?
Any help will be appreciated !
Looks like if I have an i-Frame playlist, FF/RW is supported. But then thats only from iOS5.0+.
Confirmed from Apple Dev Forums.
Rate is supported only for I-Frame Playlists for HLS content. For normal playlist, only rate = 0, 1 is supported(which is essentially play/pause)
For non-HLS content, rate can be use for <0, =0,>0 to support FF/RW/Slow forward etc.
The rate property only controls playback speed. 0 for stopped and up to 1 for the normal rate of the current item. Any value over 1 is treated as 1. If you want to "fast forward" to a specific point you will need to use the method you mentioned, "seekToTime". There is no way (AFAIK) to play a movie faster than it's normal rate using public API's. Hope that helps.

Resources