iOS开发-AudioUnit实时录音-OC

这篇博客介绍了如何在iOS应用中使用AudioUnit进行实时录音,特别是针对双声道录音的需求。通过提供的ZDUnitRecorder类,开发者可以分别提取左右声道的缓冲区,以支持蓝牙耳机的语音识别等特性。示例代码包括ZDUnitRecorder的头文件和实现文件。
摘要由CSDN通过智能技术生成

1.单声道录音

//  FSUnitRecorder.h

#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>

NS_ASSUME_NONNULL_BEGIN

typedef void (^kAudioUnitRecorderOnputBlock)(AudioBufferList *bufferList);

@interface FSUnitRecorder : NSObject

@property (assign, nonatomic) double sampleRate;
@property (assign, nonatomic, readonly) BOOL isRecording;
@property (copy, nonatomic) kAudioUnitRecorderOnputBlock bufferListBlock;

- (void)start;
- (void)stop;

@end

NS_ASSUME_NONNULL_END
//  FSUnitRecorder.m
#import "FSUnitRecorder.h"

@interface FSUnitRecorder ()
{
   
    AudioUnit audioUnit;
    BOOL audioComponentInitialized;
}

@property (nonatomic,assign) AudioStreamBasicDescription inputStreamDesc;

@end

@implementation FSUnitRecorder

- (instancetype)init {
   
    self = [super init];
    if (self) {
   
        self = [super init];
        if (self) {
   
            [self defaultSetting];
        }
        return self;
    }
    return self;
}

- (void)defaultSetting {
   
  // 优先16000,如果设备不支持使用其它采样率
    NSArray *sampleRates = @[@16000, @11025, @22050, @44100];
    for (NSNumber *sampleRate in sampleRates) {
   
        OSStatus status = [self prepareRecord:sampleRate.doubleValue];
        if (status == noErr) {
   
            self.sampleRate = [sampleRate doubleValue];
            break;
        }
    }
}

- (OSStatus)prepareRecord:(double)sampleRate {
   
    OSStatus status = noErr;

    NSError *error;
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionAllowBluetooth  error:&error];
    [[AVAudioSession sharedInstance] setActive:YES error:&error];
  // This doesn't seem to really indicate a problem (iPhone 6s Plus)
#ifdef IGNORE
    NSInteger inputChannels = session.inputNumberOfChannels;
    if (!inputChannels) {
   
        NSLog(@"ERROR: NO AUDIO INPUT DEVICE");
        return -1;
  }
#endif

      if (!audioComponentInitialized) {
   
        audioComponentInitialized = YES;
        // Describe the RemoteIO unit
        AudioComponentDescription audioComponentDescription;
        audioComponentDescription.componentType = kAudioUnitType_Output;
        audioComponentDescription.componentSubType = kAudioUnitSubType_RemoteIO;
        audioComponentDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
        audioComponentDescription.componentFlags = 0;
        audioComponentDescription.componentFlagsMask = 0;

        // Get the RemoteIO unit
        AudioComponent remoteIOComponent = AudioComponentFindNext(NULL,&audioComponentDescription);
        status = AudioComponentInstanceNew(remoteIOComponent,&(self->audioUnit));
        if (CheckError(status, "Couldn't get RemoteIO unit instance")) {
   
          return status;
        }
      }

      UInt32 oneFlag = 1;
      AudioUnitElement bus0 = 0;
      AudioUnitElement bus1 = 1;

      if ((NO)) {
   
        // Configure the RemoteIO unit for playback
        status = AudioUnitSetProperty (self->audioUnit,
                                       kAudioOutputUnitProperty_EnableIO,
                                       kAudioUnitScope_Output,
                                       bus0,
                                       &oneFlag,
                                       sizeof(oneFlag));
        if (CheckError(status, "Couldn't enable RemoteIO output")) {
   
          return status;
        }
      }

      // Configure the RemoteIO unit for input
      status = AudioUnitSetProperty(self->audioUnit,
                                    kAudioOutputUnitProperty_EnableIO,
                                    kAudioUnitScope_Input,
                                    bus1,
                                    &oneFlag,
                                    sizeof(oneFlag));
      if (CheckError(status, "Couldn't enable RemoteIO input")) {
   
        return status;
      }

      AudioStreamBasicDescription asbd;
      memset(&asbd, 0, sizeof(asbd));
      asbd.mSampleRate = sampleRate; // 采样率
      asbd.mFormatID = kAudioFormatLinearPCM;
      asbd.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
      asbd.mBytesPerPacket = 2;
      asbd.mFramesPerPacket = 1;
      asbd.mBytesPerFrame = 2;
      asbd.mChannelsPerFrame = 2;
      asbd.mBitsPerChannel = 16;

      // Set format for output (bus 0) on the RemoteIO's input scope
      status = AudioUnitSetProperty(self->audioUnit,
                                    kAudioUnitProperty_StreamFormat,
                                    kAudioUnitScope_Input,
                                    bus0,
                                    &asbd,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值