An iPhone app starts a thread using NSThread that plays short audio tick on regular intervals to give pace.
Code that starts and plays sound:
tickingThread = [[NSThread alloc] initWithTarget:self
selector:#selector(playStepTicks:)
object:nil];
-(void)playStepTicks:(id) arg
{
NSLog(#"Started ticking.");
NSThread *cur = [NSThread currentThread];
NSTimeInterval stime = 0.3;
while (!cur.isCancelled) {
CFTimeInterval t = CACurrentMediaTime();
NSLog(#"Tick: %f", t);
AudioServicesPlaySystemSound (tickSound);
t = CACurrentMediaTime() - t;
[NSThread sleepForTimeInterval:stime-t];
};
NSLog(#"Stopped ticking.");
}
Audio loop runs very precisely on iOS6 and is not distracted by UI events when the screen is on.
We enabled proximity sensor on iPhone 4S to save power.
Unfortunately this has an unpleasant effect on the audio loop: ticks are played with large jitter (see video on YouTube).
How can this problem be solved on iOS 6?
After asking for help on Apple's developer forum, we decided to use Audio Units to generate continuous audio signal and properly set its amplitude (zero for silence and constant for tick) to achieve the tick effect.
The code was written based on iOS Tone Generator.
Related
I have an application that uses location services in the background. Works fine.
But what I want to do, at a certain point, is to check some audio levels while the application is in the background. For some reason it doesn't seem to work. When running in foreground, the function works fine, but when in the back ground, the audio recorder average and peak input is always -120..
This is what I use to do the trick (that doesn't seem to work apparently..)
....
[recorder record];
if (levelTimer == nil) {
bgTask = 0;
app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
}];
levelTimer = [NSTimer scheduledTimerWithTimeInterval: 0.02 target: self selector: #selector(levelTimerCallback:) userInfo: nil repeats: YES];
}
...
And yes, the levelTimerCallback is called every 0.02 seconds, even when in the background, so I assume that the beginBackgroundTaskWithExpirationHandler works fine.
Any thoughts or some hints?
Currently, the only supported way to record in the background on an iOS device is to include audio for the UIBackgroundModes key in the app's plist, enable an appropriate Audio Session for recording, and start recording (or playing) audio before the app goes into the background.
If the app uses the Audio Queues or the RemoteIO Audio Unit API for recording, the buffer callbacks can just throw away all the audio buffers until the time of interest, and then compute the energy represented by the PCM samples for the amount of time required when needed.
I dont think iPhone will allow recording in the background. Only few services are allowed when the app goes into background. Logically if your app stays into background for a long time it would then consume a lot of battery as well as buffer to store audio, unless you have time and memory managed these resources. This would also pose issues for your app when you submit it to the App Store.
Although you can refer to this link for knowing what can be run in the background.
I hope this might help u clear things in a way.
iPhone : Running services in the background
Good Luck!!!
There is an app I know of that has background recording. Beatmaker 2. You need to turn run in the background on in the settings of device under beatmaker 2. In beatmaker create an audio track and start recording. Them use the home button on device to exit app but its still recording. You can get creative with different interfaces as well. I do this to feed the iPhone 4 line out into an audio track in beatmaker 2. You can record the audio of anything playing in the foreground. (YouTube videos apps music from your iTunes library. You can edit the waves also after recorded.
I am developing an audio streamer and have declared an interruption listener,
that means when an interruption occurs - like an incoming call or an sms.After complete my call again automatically play that audio live stream
Explain
my first question Is it possible.... (that means if my song is ten min . After 2 min playing, suddenly incoming call is coming at that time i am talking 4 min... So my song should be continue from 6th min(that means 4 min should be background running without noise ) )
I am MPMoviePlayer in IOS5
player = [[MPMoviePlayerController alloc] initWithContentURL:audioUrl];
[player prepareToPlay];
My guess is you can do it by:
Capture the current time when you app got interrupted.
When applicationDidBecomeActive got called. Calculate the elapsed time base on the time captured above.
Initialize the MPMoviePlayerController with initialPlaybackTime to seek to the calculated offset.
I want to measure sound in dB(A) in iPhone.
How can I do it?
Is there any example or tutorial?
If you use AVAudioPlayer, you can use this method
AVAudioPlayer *avPlayer = ...
[avPlayer play...];
[avPlayer averagePowerForChannel:0];
[avPlayer averagePowerForChannel:1];
From Apple's doc
- (float)averagePowerForChannel:(NSUInteger)channelNumber
Description
Returns the average power for a given channel, in decibels, for the sound being played.
I am developing an application where the user can tap multiple hit areas which produces sounds.
But the result is a little laggy, when multiple sounds start at the same time, the sounds are played with an ugly delay.
I am using AVAudioPlayer instances for each sound.
Is there a better way to play sounds and prevent this lag?
Here's the code:
#import "MBImageView.h"
#import <AVFoundation/AVFoundation.h>
#implementation MBImageView
-(void)awakeFromNib
{
NSURL* audioFile = [NSURL fileURLWithPath[[NSBundlemainBundle] pathForResource:#"shaker"
ofType:#"caf"]];
AudioServicesCreateSystemSoundID((CFURLRef)audioFile, &shortSound);
}
- (id)initWithImage:(UIImage *)image{
return self;
}
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
AudioServicesPlaySystemSound(shortSound);
}
#end
Regards.
Most of these sounds (AVAudioPlayer and AudioServices) are playing after your runloop ends. That is, you say play and they get queued for playing, and they don't start playing immediately.
If you want lag free sound, you use Audio Unit:
To provide lowest latency audio,
especially when doing simultaneous
input and output (such as for a VoIP
application), use the I/O unit or the
Voice Processing I/O unit. See “Audio
Unit Support in iPhone OS.”
You may also want to look at Audio Toolbox:
Use the Audio Toolbox framework to
play audio with synchronization
capabilities, access packets of
incoming audio, parse audio streams,
convert audio formats, and record
audio with access to individual
packets. For details, see Audio
Toolbox Framework Reference and the
SpeakHere sample code project.
If they're short sounds that you don't mind loading into memory, the C-based System Sound Services might suit you better.
I've used the SoundEffect class in Audio Toolbox with good results. My short sounds play with no delay.
Also one other thing to consider with audio delays; make sure your audio files has no "whitespace" before the actual sound - I beat my head into a wall once looking for the sound delay, only to find it in the actual audio file itself.
Hope this helps.
is there a way to adjust the speed of the playback of an audio while playing in Objective C for the iPhone/iPod touch?
Also would be interesting if playing a file backwards would be possible.
Thanks
Tom
AVAudioPlayer doesn't give you speed control, but it does let you set the position, so you could do a poor man's speed up/reverse the same way QuickTime Player does: by jumping through the file and playing small snippets at normal speed.
Or you decompress the samples yourself with an offline AudioQueue and do whatever rate you want. That's what I do.
A cheesy way to do it is to tweak the sample rate when you send it to the playback engine (Audio Queue, Remote I/O Unit, OpenAL). For PCM -- and I'm not sure this would work for anything other than PCM (so you'd have to decompress an MP3 or AAC with Audio Converter Services first) -- you could speed up your audio by adjusting the AudioStreamBasicDescription like this:
audioStreamDesc.mSampleRate = audioStreamDesc.mSampleRate * 1.2;
Note that this also changes the pitch of your audio: not only is it faster, it's also higher pitched. The Mac has a system-supplied audio unit that allows you to change playback speed without changing pitch, but it seems to be absent on iPhone.
As of iOS 6 (and I believe 5) you can adjust playback rate within AVAudioPlayer; no extra code necessary:
player = [[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath:path] error:&err];
player.enableRate=YES;
player.rate = 0.5;
[player play];
Rate can range between .5 and 2.0, and can be adjusted during playback as long as enableRate is set to YES before playback starts.