AVCaptureSession with BluetoothHFP device - ios

I need to stream the voice data to server, so I can't use AVAudioRecorder.
Here is my approach.
set it Allow Bluetooth and activate it
NSError* e;
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryRecord
withOptions:AVAudioSessionCategoryOptionAllowBluetooth
error:nil];
[audioSession setActive:YES withOptions:0 error:&e];
I did setup the notification for AVAudioSessionRouteChangeNotification
so I see the input source changed to BluetoothHFP
but seems there is no way to configure a BluetoothHFP input to AVCaptureDeviceInput.
self.captureSession = [[AVCaptureSession alloc] init];
self.captureSession.sessionPreset = AVCaptureSessionPresetLow;
AVCaptureDevice* captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
AVCaptureDeviceInput* audioInput = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if(audioInput && [self.captureSession canAddInput:audioInput]){
[self.captureSession addInput:audioInput];
}
after doing so, the input source changed to iPhone MicroPhone.
is there anyway I can get the BluetoothHFP input as AVCaptureDeviceInput??

Related

iOS: AVAudioSession sample rate is not changing when playing a sound from speaker

When setting the preferred sample rate to 16000 it is working fine. However, when I want to play the sound from the speaker and print the sample rate I find it 48000.
I tried to set the sample rate again after playing from the speaker, but it is not working.
NSError *err = nil;
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:NO error:&err];
BOOL successfullySatSampleRate = [session setPreferredSampleRate:SAMPLING_FREQUENCY error:&err];
if(err != nil)
{
NSLog(#"Error in setting up audio: %#", err);
}
if(!successfullySatSampleRate)
{
NSLog(#"Error in setting up sample rate");
}
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error: nil];
[session setActive:YES error:&err];
NSLog(#"initialize Session preferredSampleRate = %f, hardware sampleRate = %f",[session preferredSampleRate],[session sampleRate]);
What should I do to keep the sample rate 16000?

AVCaputeDeviceInput capture bluetooth input

I know how to set the AVAudioSession to be able to read audio input from a bluetooth device. I accomplish this by the following code:
NSError *error;
[[AVAudioSession sharedInstance] setActive:NO error:&error];
[self.audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:nil];
NSError *errorTwo;
[self.audioSession setActive:YES error:&errorTwo];
By setting the options to AVAudioSessionOptionAllowBlueTooth I am able set this up. However, I'm trying to get this to work with a video recorder and I'm struggling to get this to work.
I'll post what I have starting from the AVCaptureSession:
self.captureSession = [AVCaptureSession new];
NSError *error;
[[AVAudioSession sharedInstance] setActive:NO error:&error];
self.captureSession.automaticallyConfiguresApplicationAudioSession = YES;
self.captureSession.automaticallyConfiguresApplicationAudioSession = true;
[self.audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:nil];
NSError *errorTwo;
[self.audioSession setActive:YES error:&errorTwo];
[self addAudioCapture];
AVCaptureDevice *audioInputDevice = [self audioDevice];
- (BOOL)addAudioCapture
{
AVCaptureDevice *audioInputDevice = [self audioDevice];
DLog(#"AUDIO INPUT DEVICE: %#", [audioInputDevice description]);
AVCaptureDeviceInput *audioIn = [[AVCaptureDeviceInput alloc] initWithDevice:audioInputDevice error:nil];
if ([self.captureSession canAddInput:audioIn])
{
[self.captureSession addInput:audioIn];
}
else
{
return NO;
}
self.audioOut = [[AVCaptureAudioDataOutput alloc] init];
dispatch_queue_t audioCaptureQueue = dispatch_queue_create("Audio Capture Queue", DISPATCH_QUEUE_SERIAL);
[self.audioOut setSampleBufferDelegate:self queue:audioCaptureQueue];
if ([self.captureSession canAddOutput:self.audioOut])
{
[self.captureSession addOutput:self.audioOut];
}
else
{
return NO;
}
self.audioConnection = [self.audioOut connectionWithMediaType:AVMediaTypeAudio];
return YES;
}
- (AVCaptureDevice *)audioDevice
{
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio];
if ([devices count] > 0)
{
return [devices objectAtIndex:0];
}
return nil;
}
However, the problem I'm facing is the audioInputDevice is always the iPhone microphone. I've confirmed that my bluetooth device is paired with my phone and I've written a separate application to test what input / output I'm currently using and I can confirm the the bluetooth device is readable by the iPhone. However, in the main app I'm working in I'm unable to set this. Any tips or advice on how to achieve this would be appreciated.

iOS How to play alert sound in speaker when recording

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];

No sound recorded using iPhone5

I am using below code to capture sound. It works fine on all devices expect iPhone5 ios7.
Please help.
AVCaptureDevice *audioCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
NSError *error = nil;
AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioCaptureDevice error:&error];
if (audioInput)
{
[CaptureSession addInput:audioInput];
}
Try setting the below code in before getting the AVCaptureDevice instance
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error: nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
UInt32 doChangeDefault = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(doChangeDefault), &doChangeDefault);

Route output to bluetooth

For an AvAudioSession I am able to switch between speaker and earpiece using the
// To speaker
AVAudioSession *session = [AVAudioSession sharedInstance];
BOOL enableSpeaker = [session overrideOutputAudioPort:AvAudioSessionPortOverrideSpeaker error:&error];
// To earpiece
AVAudioSession *session = [AVAudioSession sharedInstance];
BOOL enableSpeaker = [session overrideOutputAudioPort:AvAudioSessionPortOverrideNone error:&error];
Is there a way to route to bluetooth if it is connected. The AudioSessionSetProperty is deprecated so do not want to use that.I need a way to switch between speaker, earpiece and bluetooth.

Resources