In my app i have to record audio and play this audio and add proximity when play this audio near your ear so for this i have to do this code when play button click:
- (IBAction)btnPlayPauseTapped:(id)sender {
UIDevice *device = [UIDevice currentDevice];
[device setProximityMonitoringEnabled: YES];
if (device.proximityMonitoringEnabled == YES) {
[[NSNotificationCenter defaultCenter] removeObserver:APP_DELEGATE name:#"UIDeviceProximityStateDidChangeNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:APP_DELEGATE selector:#selector(proximityChanged:) name:#"UIDeviceProximityStateDidChangeNotification" object:device];
//other code
}
Notification call this method when proximity enable:
- (void) proximityChanged:(NSNotification *)notification {
NSLog(#"proximity changed called");
UIDevice *device = [notification object];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
if(device.proximityState == 1){
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:nil];
[audioSession setActive:YES error:nil];
}
else{
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];
[audioSession setActive:YES error:nil];
}
}
when player stop playing or pause i add this:
UIDevice *device = [UIDevice currentDevice];
[device setProximityMonitoringEnabled: NO];
but when i again start playing audio and put device near ear that time it called notification method(proximityChanged) and at that time proximity state also get 1 and audio session category also set as playandrecord but it did not play this audio in ear speaker . it play audio in main speaker.
please help me in this.
Thank you in Advance.
I Solved my problem after 2 days in that when player stop player as I disable proximity is correct but I changed audiosession category in proximitychange method.
- (void) proximityChanged:(NSNotification *)notification {
UIDevice *device = [notification object];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
BOOL success;
success = [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
if(device.proximityState == 1){
NSLog(#"bool %s", success ? "true" : "false");
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:nil];
[audioSession setActive:YES error:nil];
}
else{
NSLog(#"bool %s", success ? "true" : "false");
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];
[audioSession setActive:YES error:nil];
}
Related
How to set audio session category so that external Bluetooth airpod device can record audio using airpod microphone and works flowless with other bluetooth device as well. Here is my code.
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
/*
optimum to minimize delay, must put a software resampler to deal with 8khz
*/
NSError *error;
[audioSession setPreferredSampleRate:8000.0 error:&error];
if([[UIDevice currentDevice] systemVersion].floatValue>=10.0)
{
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions:AVAudioSessionCategoryOptionAllowBluetoothA2DP
error:&error];
}
else
{
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions:AVAudioSessionCategoryOptionAllowBluetooth
error:&error];
}
I am using in my
viewDidLoad:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *setCategoryError = nil;
BOOL success = [audioSession setCategory:AVAudioSessionCategoryAmbient error:&setCategoryError];
if (!success) { /**handle the error condition */ }
NSError *activationError = nil;
success = [audioSession setActive:YES error:&activationError];
if (!success) { /**handle the error condition */ }
NSURL *SoundURL1 = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"music1" ofType:#"caf"]];
and have initialized in the interface
AVAudioPlayer *playSoundURL1;
and called in my method
[playSoundURL1 play];
Sound plays perfectly fine when I'm using headphones when ringer is silent or not silent. However, without any headphones I can only hear the sound when the ringer is not silenced.
I am implementing Audio Video Call like feature. I am using AVAudioSession for Voice feature. I want to configure the AVAudioSession such that it should work on the receive speaker and loud speaker as well as the headphones.I am using the following initialisation for AVAudioSession:
NSError *err = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:&err];
[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&err];
[[AVAudioSession sharedInstance] setMode:AVAudioSessionModeVideoChat error:&err];
[[AVAudioSession sharedInstance] setActive: YES error: NULL];
The above code works fine for loud speaker and headphones but the voice quality from loud speaker is very low.
I have tried the code below for switching the audio route to receiver speaker. But it doesn't work.
NSError *err = nil;
[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:&err];
Can somebody please help me with this?
I got similar problem.i solve it by
[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:nil];
NSArray *outputs =[[[AVAudioSession sharedInstance] currentRoute] outputs];
BOOL haveSpeaker = NO;
for (AVAudioSessionPortDescription *currentPut in outputs) {
if ([currentPut.portType isEqualToString:#"Speaker"]) {
haveSpeaker = YES;
break;
}
}
if (haveSpeaker) {
NSError *error;
[[AVAudioSession sharedInstance]setCategory:AVAudioSessionCategoryRecord error:nil];
[[AVAudioSession sharedInstance]setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:&error];
[[AVAudioSession sharedInstance]setActive:YES error:nil];
}
In my opinion AVAudioSessionCategoryOptionDefaultNone is not reciver,it's default route. so u hava changed the default route for this mode;
I have these code and both method call are SUCCESS.
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory: AVAudioSessionCategoryPlayAndRecord error: NULL];
[audioSession setActive: YES error: NULL];
And these code to start recording:
[self.recorder prepareToRecord];
[self.recorder recordForDuration: 60];
I have a timer function to update meters
- (void)updateMeters
{
[self.recorder updateMeters];
float peakPower = [self.recorder averagePowerForChannel: 0];
double ALPHA = 0.05;
double peakPowerForChannel = pow(10, (ALPHA * peakPower));
self.recordView.progress = peakPowerForChannel;
NSLog(#"%f", peakPower);
}
But I do not know why peakPower is always 160. I have another demo(from web) can work well, but I can not find any difference between them.
Just try to set:
recorder.meteringEnabled = YES;
Set the category to AVAudioSessionCategoryPlayAndRecord and check
NSError *error;
[[AVAudioSession sharedInstance]
setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
if (error) {
NSLog(#"Error description: %#", [error description]);
}
It is strange that [audioSession setCategory: AVAudioSessionCategoryPlayAndRecord error: &err] and [[AVAudioRecorder alloc] initWithURL: [NSURL fileURLWithPath: self.recordPath] settings: recordSetting error: NULL] must in the same function...It is the answer of this question.
I want to manually trigger to play some alert sound during recording audio, and I want the alert sound be recorded. So I want the alert play loudly in speaker instead of Receiver during recording audio.
I use AVAudioRecorder to record audio and use AVAudioPlayer to play the alert sound.
Code for recorder
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *sessionError;
[session setCategory:AVAudioSessionCategoryRecord error:&sessionError];
if(session == nil)
NSLog(#"Error creating session: %#", [sessionError description]);
else
[session setActive:YES error:nil];
recorder = [[AVAudioRecorder alloc] initWithURL:_recordedFile settings:recordSettings error:nil];
[recorder prepareToRecord];
[recorder record];
Code for player
AVAudioSession *session = [AVAudioSession sharedInstance];
// session.outputDataSources
NSError *sessionError;
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];
// use the louder speaker
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,
sizeof (audioRouteOverride),&audioRouteOverride);
if(session == nil)
NSLog(#"Error creating session: %#", [sessionError description]);
else
[session setActive:YES error:nil];
NSError *error;
player = [[AVAudioPlayer alloc] initWithContentsOfURL:self.filePath error:&error];
player.delegate =self;
player.volume = 1.0;
player.numberOfLoops = 0;
self.timeDuration = player.duration;
If I stop the recording, and manually trigger the play alert, it plays in speaker.
But during recording, when I manually trigger the play alert, nothing happens.
Is there anything wrong here? Or Is it possible to play sound in speaker when recording?
Just change category as below thats all
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:&err];