I'm using the code that can be found here. I've tried to change sample rate using:
[[AVAudioSession sharedInstance] setPreferredHardwareSampleRate:SAMPLE_RATE error:nil];
Inside the init function on SoundRecoder.m file. (SAMPLE_RATE is 16000.0)
When I'm checking the file it seems that still the metadata says the sample rate is 44100, I've tried also to use (as suggested here):
AudioSessionSetProperty ( kAudioSessionProperty_PreferredHardwareSampleRate ,sizeof(F64sampleRate) , &F64sampleRate );
When F64sampleRate is 16000 but still same failure.
Does the device can choose which rate to sample (it is called preferred) is there any way I can set it no matter what?
Any idea to solve this code problem would help.
Thanks!
UPDATE: I think the issue is related with the queue itself. Because sample rate there is 44100.
Here is my whole code based on the code I've linked to earlier:
#import "SoundRecoder.h" #import <AVFoundation/AVFoundation.h> #import <FLAC/all.h> #define SAMPLE_RATE 16000.0 // Sample rate I want the Flac file to have @interface SoundRecoder () <AVCaptureAudioDataOutputSampleBufferDelegate>{ AVCaptureSession *_session; int _frameIndex; BOOL _ready; int _sampleRate; int _totalSampleCount; int _maxSampleCount; NSString *_savedPath; /////////////////////// FLAC__StreamEncoder *_encoder; int32_t *_buffer; int32_t _bufferCapacity; } @end @implementation SoundRecoder @synthesize delegate = _delegate; @synthesize savedPath = _savedPath; -(id)init{ OSStatus error; union { OSStatus propertyResult; char a[4]; } u; //Float64 F64sampleRate = 8192.0; Float64 F64sampleRate = SAMPLE_RATE; Float64 F64realSampleRate = 0; UInt32 F64datasize = 8; self = [super init]; AVAudioSession *audioSession = [AVAudioSession sharedInstance]; if ([audioSession respondsToSelector:@selector(isInputAvailable)]){ if( ![audioSession isInputAvailable] ){ NSLog(@"No sound input available"); return FALSE; } } else{ // Need to check the case of iOS 5 NSLog(@"No isInputAvailable function"); // return FALSE; } [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord withOptions:AVAudioQualityLow error:nil]; if ([[AVAudioSession sharedInstance] setPreferredSampleRate:SAMPLE_RATE error:nil]) { NSLog(@"Sample rate was updated"); }else{ NSLog(@"**** Unable to set this sample rate! ****"); }; [[AVAudioSession sharedInstance] setActive:YES error:nil]; u.propertyResult = AudioSessionGetProperty ( kAudioSessionProperty_CurrentHardwareSampleRate , &F64datasize, &F64realSampleRate ); NSLog(@"Get Error Current Sample Rate %ld %lx %c%c%c%c",u.propertyResult,u.propertyResult,u.a[3],u.a[2],u.a[1],u.a[0]); NSLog(@"Sample Rate is %f",F64realSampleRate); NSLog(@"Hardware sample rate is %f", [[AVAudioSession sharedInstance] sampleRate]); _session = [[AVCaptureSession alloc] init]; AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeAudio]; AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:NULL]; [_session addInput:input]; AVCaptureAudioDataOutput *output = [[AVCaptureAudioDataOutput alloc] init]; [output setSampleBufferDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0)]; //new [_session addOutput:output]; [output release]; _maxSampleCount = SAMPLE_RATE*10; // 10sec if ([[AVAudioSession sharedInstance] setPreferredSampleRate:SAMPLE_RATE error:nil]) { NSLog(@"2nd - Sample rate was updated"); }else{ NSLog(@"2nd **** Unable to set this sample rate! ****"); }; return self; } - (void)dealloc { [_session release]; if( _buffer ){ free(_buffer); } [super dealloc]; } -(BOOL)startRecording:(NSString*)savePath{ if( !_session || [_session isRunning] ){ return FALSE; } [_savedPath release]; _savedPath = [savePath copy]; AVCaptureAudioDataOutput *output = [[_session outputs] objectAtIndex:0]; [output setSampleBufferDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0)]; _ready = NO; _frameIndex = 0; _totalSampleCount = 0; [_session startRunning]; return TRUE; } -(BOOL)stopRecording{ if( ![_session isRunning] ){ return FALSE; } _ready = NO; AVCaptureAudioDataOutput *output = [[_session outputs] objectAtIndex:0]; [output setSampleBufferDelegate:nil queue:nil]; [_session stopRunning]; FLAC__stream_encoder_finish(_encoder); FLAC__stream_encoder_delete(_encoder); [_delegate soundRecoderDidFinishRecording:self]; return TRUE; } -(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{ if( _frameIndex++==0 ){ CMAudioFormatDescriptionRef fmt = CMSampleBufferGetFormatDescription(sampleBuffer); //const AudioStreamBasicDescription *desc = CMAudioFormatDescriptionGetStreamBasicDescription(fmt); AudioStreamBasicDescription *desc; desc = (AudioStreamBasicDescription *)CMAudioFormatDescriptionGetStreamBasicDescription(fmt); if( !desc->mFormatID == kAudioFormatLinearPCM ){ return; } if( desc->mChannelsPerFrame != 1 || desc->mBitsPerChannel != 16) { return; } NSLog(@"(int)desc->mSampleRate = %d", (int)desc->mSampleRate); _sampleRate = (int)desc->mSampleRate; _encoder = FLAC__stream_encoder_new(); FLAC__stream_encoder_set_verify(_encoder,true); FLAC__stream_encoder_set_compression_level(_encoder, 5); FLAC__stream_encoder_set_channels(_encoder,1); FLAC__stream_encoder_set_bits_per_sample(_encoder, 16); FLAC__stream_encoder_set_sample_rate(_encoder,_sampleRate); FLAC__stream_encoder_set_total_samples_estimate(_encoder, _maxSampleCount); FLAC__StreamEncoderInitStatus init_status; init_status = FLAC__stream_encoder_init_file(_encoder, [_savedPath UTF8String], NULL, NULL); if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK ) { NSLog(@"FLAC: Failed to initialize encoder: %s", FLAC__StreamEncoderInitStatusString[init_status]); FLAC__stream_encoder_delete(_encoder); _encoder = NULL; return; } if( !_buffer ){ _bufferCapacity = 4096; _buffer = (int32_t*)malloc(4*_bufferCapacity); } _ready = YES; } if( !_ready || !_buffer ){ return; } CMBlockBufferRef audioBuffer = CMSampleBufferGetDataBuffer(sampleBuffer); size_t offset, length; int16_t *samples = NULL; CMBlockBufferGetDataPointer(audioBuffer, 0, &offset, &length, (char**)&samples); int sampleCount = CMSampleBufferGetNumSamples(sampleBuffer); if( sampleCount > _bufferCapacity ){ free(_buffer); _bufferCapacity = sampleCount; _buffer = (int32_t*)malloc(4*_bufferCapacity); } for(int i=0;i<sampleCount;i++){ _buffer[i] = samples[i]; } FLAC__stream_encoder_process_interleaved(_encoder,_buffer,sampleCount); _totalSampleCount += sampleCount; if( _totalSampleCount > _maxSampleCount ){ [self stopRecording]; } } @end
When I'm changing the sample rate on the Flac I'm getting a slow voice (because input is still 44kHz).
Any suggestions?