//
// AudioCapture.m
// live
//
// Created by lujunjie on 2016/11/5.
// Copyright © 2016年 lujunjie. All rights reserved.
//
#import "AudioQueueCapture.h"
#import <AudioToolbox/AudioToolbox.h>
#define QUEUE_BUFFER_SIZE 10 //队列缓冲个数
#define MIN_SIZE_PER_FRAME 1000 //每帧最小数据长度
@interface AudioQueueCapture()
{
AudioQueueRef audioQueue;//音频播放队列
AudioQueueBufferRef audioQueueBuffer[QUEUE_BUFFER_SIZE];//音频缓存
AudioStreamBasicDescription audioDescription;//音频参数
}
@end
@implementation AudioQueueCapture
- (instancetype)init
{
if (self=[super init]) {
audioDescription.mSampleRate = 8000;//采样率
audioDescription.mFormatID = kAudioFormatLinearPCM;
audioDescription.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioDescription.mChannelsPerFrame = 1;///单声道 每一帧数据包含的通道数
audioDescription.mFramesPerPacket = 1;//每个包数据的样本帧的数量
audioDescription.mBitsPerChannel = 16;//每个采样点16bit量化 每一帧数据的每一个通道的采样位的数量
audioDescription.mBytesPerPacket = 2; // 每个包数据的字节数量
audioDescription.mBytesPerFrame = 2;//单帧包含的字节数据
}
return self;
}
- (void)stop
{
if (audioQueue) {
AudioQueueStop(audioQueue, YES);
AudioQueueDispose(audioQueue, YES);
audioQueue = NULL;
}
}
- (void)start
{
// 创建音频输入队列
if (AudioQueueNewInput(&audioDescription, audioQueueInputCallback, (__bridge void * _Nullable)(self), NULL, NULL, 0, &audioQueue) != noErr){
return;
}
for (int i = 0; i < QUEUE_BUFFER_SIZE; i++) {
//请求音频队列对象来分配一个音频队列缓存。
AudioQueueAllocateBuffer(audioQueue, MIN_SIZE_PER_FRAME, &audioQueueBuffer[i]);
//给录音或者回放音频队列的缓存中添加一个缓存数据
AudioQueueEnqueueBuffer(audioQueue, audioQueueBuffer[i], 0, NULL);
}
if (audioQueue) {
//开始录音
AudioQueueStart(audioQueue, NULL);
}
}
void audioQueueInputCallback (void *inUserData,AudioQueueRef inoQueueRef, AudioQueueBufferRef inBuffer,const AudioTimeStamp *inStartTime, UInt32 inNumberPacketDescriptions, const AudioStreamPacketDescription *inPacketDescs) {
AudioQueueCapture *self = (__bridge AudioQueueCapture *)inUserData;
[self.delegate audioQueueCaptureData:inBuffer->mAudioData dataLength:inBuffer->mAudioDataBytesCapacity];
AudioQueueEnqueueBuffer(inoQueueRef, inBuffer, 0, NULL);
}
- (void)dealloc {
[self stop];
self.delegate = nil;
}
@end