//
// AudioRecordManager.h
// Demo
//
// Created by tao on 2020/7/8.
// Copyright © 2020 idst. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
@protocol AudioRecorderManagerDelegate <NSObject>
/**
* @discuss Recorder启动回调,在主线程中调用
*/
-(void)recorderDidStart;
/**
* @discuss Recorde停止回调,在主线程中调用
*/
-(void)recorderDidStop;
/**
* @discuss Recorder收录到数据,通常涉及VAD及压缩等操作,为了避免阻塞主线,因此将在在AudioQueue的线程中调用,注意线程安全!!!
*/
-(void)voiceRecorded:(NSData *_Nonnull) frame;
/**
* @discuss Recorder录制录音时返回音量大小
*/
-(void)voiceVolume:(NSInteger)volume;
@end
NS_ASSUME_NONNULL_BEGIN
@interface AudioRecordManager : NSObject
@property (nonatomic, assign) id<AudioRecorderManagerDelegate> delegate;
@property (nonatomic, assign) BOOL isRecording;
+ (instancetype)sharedManager;
- (void)start;
- (void)stop;
@end
NS_ASSUME_NONNULL_END
//
// AudioRecordManager.m
// Demo
//
// Created by tao on 2020/7/8.
// Copyright © 2020 idst. All rights reserved.
//
#import "AudioRecordManager.h"
#define BufferSeconds 0.02 // 20ms
@interface AudioRecordManager () {
AudioQueueRef _audioQRef; //音频队列对象指针
AudioStreamBasicDescription _audioRecordFormat; //音频流配置
AudioQueueBufferRef _audioQBufferRefs[3]; //音频流缓冲区对象
}
@property (nonatomic, assign) AudioFileID recordFileID; //音频文件标识
@property (nonatomic, assign) SInt64 recordPacket; //录音文件的当前包
@property (nonatomic, copy) NSString *originAudioSessionCategory; //原本的category
@property (nonatomic, strong) NSMutableData *bufferedAudioData; //缓冲数据
@end
@implementation AudioRecordManager
/*!
@discussion
AudioQueue 音频录制回调函数
@param inAQ
回调函数的音频队列.
@param inBuffer
是一个被音频队列填充新的音频数据的音频队列缓冲区,它包含了回调函数写入文件所需要的新数据.
@param inStartTime
是缓冲区中的一采样的参考时间
@param inNumberPacketDescriptions
参数中包描述符(packet descriptions)的数量,如果你正在录制一个VBR(可变比特率(variable bitrate))格式, 音频队列将会提供这个参数给你的回调函数,这个参数可以让你传递给AudioFileWritePackets函数. CBR (常量比特率(constant bitrate)) 格式不使用包描述符。对于CBR录制,音频队列会设置这个参数并且将inPacketDescs这个参数设置为NULL
*/
static void inputAudioQueueBufferHandler(void * __nullable inUserData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp * inStartTime,