//
//
//
//
//
//
//
#include <AudioToolbox/AudioToolbox.h>
#include <Foundation/Foundation.h>
#include <libkern/OSAtomic.h>
#include "CAStreamBasicDescription
#include "CAXException.h"
#define kNumberRecordBuffers
class AQRecorder
{
public:
AQRecorder();
~AQRecorder();
UInt32
CFStringRef
AudioQueueRef
CAStreamBasicDescription
void
void
Boolean
void EncodeBuffer(short* buf,int len);
UInt64
CGFloat mFileDuration;
FILE *_AmrFile;
int* _destate;
private:
CFStringRef
AudioQueueRef
AudioQueueBufferRef
AudioFileID
SInt64
CAStreamBasicDescription
Boolean
void
void
int
static void MyInputBufferHandler(
AudioQueueRef
AudioQueueBufferRef
const AudioTimeStamp *
UInt32
const AudioStreamPacketDescrip
};
//
//
//
//
//
//
//
#include "AQRecorder.h"
extern "C"
{
#include "interf_enc.h"
}
#define SAMPLES_PER_SECOND 8000.0f
const float kBufferDurationSeconds = 0.5;
// Determine the size, in bytes, of a buffer necessary to represent the supplied number
// of seconds of audio data.
int AQRecorder::ComputeRecordBufferSize(const AudioStreamBasicDescript
{
catch (CAXException e) {
}
// ____________________________________________________________________________________
// AudioQueue callback function, called when an input buffers has been filled.
void AQRecorder::MyInputBufferHandler(
{
//
// inPacketDesc, aqr->mRecordPacket, &inNumPackets, inBuffer->mAudioData),
//
//
for (int i =0; i < inBuffer->mAudioDataByteSize ;i+=160*2) {
short * pPacket = (short *)(((unsigned char*)(inBuffer->mAudioData))+i);
const short par = 2;
for (int j=0; j<160; j++) {
if (pPacket[j]<(0x7FFF/par)&&pPacket[j]>(-0x7FFF/par)) {
if (pPacket[j] > 0x7FFF/2) {
pPacket[j] = 0x7FFF-1;
}else if (pPacket[j] < -0x7FFF/2) {
pPacket[j] = -0x7FFF+1;
}else{
pPacket[j] = pPacket[j]*par;
}
}
}
aqr->EncodeBuffer(pPacket,320);
}
aqr->mRecordPacket += inNumPackets;
//int duration
aqr->mFileDuration = (aqr->mRecordPacket * (aqr->mRecordFormat).mFramesPerPacket) / (aqr->mRecordFormat).mSampleRate;// + duration;
}
AQRecorder::AQRecorder()
{
_destate = (int*) Encoder_Interface_init(0);
mFileName=NULL;
}
AQRecorder::~AQRecorder()
{
Encoder_Interface_exit((void*)_destate);
_destate = 0;
if (_AmrFile)
{
fclose(_AmrFile);
}
}
// ____________________________________________________________________________________
// Copy a queue's encoder's magic cookie to an audio file.
void AQRecorder::CopyEncoderCookieToFile()
{
}
void AQRecorder::SetupAudioFormat(UInt32 inFormatID)
{
memset(&mRecordFormat, 0, sizeof(mRecordFormat));
mRecordFormat.mFormatID = inFormatID;
if (inFormatID == kAudioFormatLinearPCM)
{
// if we want pcm, default to signed 16-bit little-endian
mRecordFormat.mSampleRate = SAMPLES_PER_SECOND; // amr 8khz
mRecordFormat.mFormatFlags = kLinearPCMFormatFlagIsSi
mRecordFormat.mBitsPerChannel = 16;
mRecordFormat.mChannelsPerFrame = 1;
mRecordFormat.mFramesPerPacket = 1;
mRecordFormat.mBytesPerFrame = (mRecordFormat.mBitsPerChannel/8) * mRecordFormat.mChannelsPerFrame;
mRecordFormat.mBytesPerPacket =
}
}
//void AQRecorder::SetupAudioFormat(UInt32 inFormatID)
//{
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//}
void AQRecorder::StartRecord(CFStringRef inRecordFile)
{
&mRecordFormat,
MyInputBufferHandler,
this ,
NULL , NULL ,
0 , &mQueue), "AudioQueueNewInput failed");
//--独立线程模式
//XThrowIfError(AudioQueueNewInput(
// &mRecordFormat,
// MyInputBufferHandler,
// self ,
// CFRunLoopGetCurrent(), kCFRunLoopCommonModes ,
// 0 , &mQueue), "AudioQueueNewInput failed");
//---
// &mRecordFormat, &size), "couldn't get queue's format");
//
//
//
//
//
//
//
// &mRecordFile), "AudioFileCreateWithURL failed");
//
//
//
//
//
AudioQueueFlush(mQueue);
if(mFileName){
CFRelease(mFileName);
mFileName = nil;
}
mFileName = CFStringCreateCopy(kCFAllocatorDefault, inRecordFile);
mRecordPacket = 0;
if (0!=mFileName) {
_AmrFile = fopen((const char *)[mFileName UTF8String], "wb+");
XThrowIfError(0 == _AmrFile, "Amr file create failed");
fwrite("#!AMR\n", 1, strlen("#!AMR\n"), _AmrFile);
}
}
void AQRecorder::StopRecord()
{
if (mQueue) {
AudioQueueDispose(mQueue, true);
}
AudioFileClose(mRecordFile);
}
if (_AmrFile)
{
fclose(_AmrFile);
_AmrFile=nil;
}
}
void AQRecorder::EncodeBuffer(short *buf,int len)
{
unsigned char serialbuf[320]= {0};
memset(serialbuf, 0, sizeof(serialbuf));
int FrameLen =0;
FrameLen= Encoder_Interface_Encode(_destate,MR475,buf,serialbuf,0);
// printf("amr Frame len = %d\n",FrameLen);
int ilen = 0;
if (0!= _AmrFile) {
ilen = fwrite((unsigned char *)serialbuf,1,FrameLen,_AmrFile);
}
}