setPreferredHardwareSampleRate不起作用

时间:2013-08-11 20:46:00

标签: iphone ios audio avcapturesession avaudiosession

我正在使用可以找到here的代码。我尝试使用以下方法更改采样率:

[[AVAudioSession sharedInstance] setPreferredHardwareSampleRate:SAMPLE_RATE error:nil];

SoundRecoder.m文件中的init函数内部。 (SAMPLE_RATE是16000.0)

当我检查文件时,似乎元数据仍然显示采样率是44100,我也尝试使用(如建议here):

AudioSessionSetProperty (  kAudioSessionProperty_PreferredHardwareSampleRate ,sizeof(F64sampleRate) , &F64sampleRate );

当F64sampleRate为16000但仍然失败时。

设备是否可以选择要采样的速率(它被称为首选)是否有任何方法可以设置它,无论是什么?

解决此代码问题的任何想法都会有所帮助。

谢谢!

更新:我认为问题与队列本身有关。因为采样率有44100.

以下是基于我之前链接的代码的完整代码:

#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

当我改变Flac上的采样率时,我的声音很慢(因为输入仍然是44kHz)。

有什么建议吗?

0 个答案:

没有答案