iOS上音频接口数据通讯(2)

上一篇, 主要总结的是数据发送(音频播放)的实现

接下来,我们来说一下数据接收。音频的数据接收主要就是录音的操作,对输入数据进行解析,将波形数据转化为字节码

这个主要取决于算法,实现的方法有很多,大家可以自由发挥

好了,老规矩,还是上代码吧〜〜〜

//
//  MFAudioRecorder.h
//  audiotest
//
//  Created by Chen Jiaqi(winton.chen@gmail.com) on 15/3/19.
//  Copyright (c) 2015年 MoreFun-et. All rights reserved.
//

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

typedef int (*MFAudioRecvFunc)(char *data, int datalen);

//#define MF_DEBUG_RECORDER

// use Audio Queue
#define kNumberBuffers      3
#define kDataBufferSize     (2 * 1024 * 1024)
typedef struct AQCallbackStruct
{
    AudioStreamBasicDescription mDataFormat;
    AudioQueueRef               queue;
    AudioQueueBufferRef         mBuffers[kNumberBuffers];
    AudioFileID                 outputFile;
    
    UInt32                      frameSize;
    long long                   recPtr;
    int                         run;
    
} AQCallbackStruct;

@interface MFAudioRecorder: NSObject
{
    AQCallbackStruct            aqc;
    AudioFileTypeID             fileFormat;
    long                        audioDataLength;
#ifdef MF_DEBUG_RECORDER
    Byte                        audioByte[kDataBufferSize];
#endif
    long                        audioDataIndex;
    
    MFAudioRecvFunc             recvFunc;
    //NSTimer                     *recvTimer;
}

-(id) init;
-(void) start;
-(void) stop;
-(void) pause;
#ifdef MF_DEBUG_RECORDER
-(Byte *) getBytes;
#endif
-(void) setRecvFunc: (MFAudioRecvFunc)func;
-(void) dealloc;

@property (nonatomic, assign) AQCallbackStruct aqc;
@property (nonatomic, assign) long audioDataLength;

@end

//
//  MFAudioRecorder.mm
//  audiotest
//
//  Created by Chen Jiaqi(winton.chen@gmail.com) on 15/3/19.
//  Copyright (c) 2015年 MoreFun-et. All rights reserved.
//

#import "MFAudioRecorder.h"
#import "MFAudioConstant.h"

#include "MFAudioDecode.h"
static MFAudioDecode audioDecode;

@implementation MFAudioRecorder

@synthesize aqc;
@synthesize audioDataLength;

static void AQInputCallback (void                               *inUserData,
                             AudioQueueRef                      inAQ,
                             AudioQueueBufferRef                inBuffer,
                             const AudioTimeStamp               *inStartTime,
                             UInt32                             inNumPackets,
                             const AudioStreamPacketDescription *inPacketDescs)
{
    
    MFAudioRecorder *engine = (__bridge MFAudioRecorder *) inUserData;
    
    if (inNumPackets > 0) {
        [engine processAudioBuffer:inBuffer withQueue: inAQ];
    }
    
    if (engine.aqc.run) {
        AudioQueueEnqueueBuffer(engine.aqc.queue, inBuffer, 0, NULL);
    }
}

-(id) init
{
    self = [super init];
    if (self) {
        aqc.mDataFormat.mSampleRate = SAMPLE_RATE;
        aqc.mDataFormat.mFormatID = kAudioFormatLinearPCM;
        aqc.mDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger |kLinearPCMFormatFlagIsPacked;
        aqc.mDataFormat.mFramesPerPacket = 1;
        aqc.mDataFormat.mChannelsPerFrame = NUM_CHANNELS;
        aqc.mDataFormat.mBitsPerChannel = BITS_PER_CHANNEL;
        aqc.mDataFormat.mBytesPerPacket = BYTES_PER_FRAME;
        aqc.mDataFormat.mBytesPerFrame = BYTES_PER_FRAME;
        aqc.frameSize = 0x400;
        
        // create the queue
        AudioQueueNewInput(&aqc.mDataFormat, AQInputCallback, (__bridge void *)(self), NULL, kCFRunLoopCommonModes,0, &aqc.queue);
        
        for (int i=0;i<kNumberBuffers;i++) {
            AudioQueueAllocateBuffer(aqc.queue, aqc.frameSize, &aqc.mBuffers[i]);
            AudioQueueEnqueueBuffer(aqc.queue, aqc.mBuffers[i], 0, NULL);
        }
        aqc.recPtr = 0;
        aqc.run = 0;
        
        audioDataIndex = 0;
        
        //recvTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(checkDecoder) userInfo:nil repeats:YES];
    }
    return self;
}

- (void) dealloc
{
    printf("MFAudioRecorder dealloc.\n");
    AudioQueueStop(aqc.queue, true);
    aqc.run = 0;
    AudioQueueDispose(aqc.queue, true);
}

- (void) start
{
    printf("MFAudioRecorder start.\n");
    audioDataIndex = 0;
    aqc.run = 1;
    AudioQueueStart(aqc.queue, NULL);
}

- (void) stop
{
    printf("MFAudioRecorder stop.\n");
    aqc.run = 0;
    AudioQueueStop(aqc.queue, true);
}

- (void) pause
{
    printf("MFAudioRecorder pause.\n");
    aqc.run = 0;
    AudioQueuePause(aqc.queue);
}

-(void) setRecvFunc: (MFAudioRecvFunc)func
{
    recvFunc = func;
}

#ifdef MF_DEBUG_RECORDER
- (Byte *)getBytes
{
    return audioByte;
}
#endif

-(void) checkDecoder
{
    if (aqc.run) {
        if (audioDecode.getDecodeStatus() == 1) {
            // decode finish
            //printf("decode finish\n");
            audioDecode.resetDecodeStatus();
            if (recvFunc) {
                recvFunc(audioDecode.getDecodeBuffer(), audioDecode.getDecodeLength());
            }
        }
    }
}

- (void) processAudioBuffer:(AudioQueueBufferRef) buffer withQueue:(AudioQueueRef) queue
{
    //printf("processAudioData :%d\n", buffer->mAudioDataByteSize);
    
    audioDecode.decode((const SAMPLE *)buffer->mAudioData, buffer->mAudioDataByteSize / 2);
    [self checkDecoder];
    
#ifdef MF_DEBUG_RECORDER
    if (kDataBufferSize - audioDataIndex > buffer->mAudioDataByteSize) {
        memcpy(audioByte+audioDataIndex, buffer->mAudioData, buffer->mAudioDataByteSize);
        audioDataIndex += buffer->mAudioDataByteSize;
        audioDataLength = audioDataIndex;
    } else {
        printf("record full...\n");
        audioDataIndex = audioDataLength = 0;
    }
#endif
}

@end


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值