我正在编写一个打开AudioQueue并分析其特征的类,然后在某些条件下可以开始或结束从已经实例化的AudioQueue写出文件。这是我的代码(完全基于SpeakHere)打开AudioQueue而不向tmp写任何东西:
void AQRecorder::StartListen() {
int i, bufferByteSize;
UInt32 size;
try {
SetupAudioFormat(kAudioFormatLinearPCM);
XThrowIfError(AudioQueueNewInput(&mRecordFormat,
MyInputBufferHandler,
this,
NULL, NULL,
0, &mQueue), "AudioQueueNewInput failed");
mRecordPacket = 0;
size = sizeof(mRecordFormat);
XThrowIfError(AudioQueueGetProperty(mQueue, kAudioQueueProperty_StreamDescription,
&mRecordFormat, &size), "couldn't get queue's format");
bufferByteSize = ComputeRecordBufferSize(&mRecordFormat, kBufferDurationSeconds);
for (i = 0; i < kNumberRecordBuffers; ++i) {
XThrowIfError(AudioQueueAllocateBuffer(mQueue, bufferByteSize, &mBuffers[i]),
"AudioQueueAllocateBuffer failed");
XThrowIfError(AudioQueueEnqueueBuffer(mQueue, mBuffers[i], 0, NULL),
"AudioQueueEnqueueBuffer failed");
}
mIsRunning = true;
XThrowIfError(AudioQueueStart(mQueue, NULL), "AudioQueueStart failed");
}
catch (CAXException &e) {
char buf[256];
fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
}
catch (...) {
fprintf(stderr, "An unknown error occurred\n");
}
}
但是我有点不清楚如何编写一个函数来告诉这个队列“从现在开始直到停止信号,开始将这个队列写入tmp作为文件”。我理解如何告诉AudioQueue在创建文件时写出文件,如何设置文件格式等,但不知道如何告诉它开始和停止中游。非常感谢任何指针,谢谢。
答案 0 :(得分:4)
您可以随时使用AudioQueuePause(AudioQueueRef inAQ)和AudioQueueStart(AudioQueueRef inAQ,const AudioTimeStamp * inStartTime)暂停/启动audioqueue;
还有更多的可能性。因为您在回调函数中编写audiofile,您可以选择何时以及应保存哪些数据。
要控制写入数据,请在记录器类中创建bool标志,例如“doWrite”,并仅在设置为YES时写入。队列开始从开始接收数据并持续填充缓冲区,但是您只需在回调中将这些数据传入,直到标志保持为NO。然后在任何时刻设置doWrite = YES并将下一个缓冲区保存到文件中。当您根据声音本身更改录音时,此方法尤其有用(例如,只有当声音比某个thredhold值更响时才录制)。
void AQRecorder::MyInputBufferHandler( void * inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, const AudioTimeStamp * inStartTime, UInt32 inNumPackets, const AudioStreamPacketDescription* inPacketDesc)
{
AQRecorder *aqr = (AQRecorder *)inUserData;
try {
if (inNumPackets > 0) {
if (aqr.doWrite){
// write packets to file
XThrowIfError(AudioFileWritePackets(aqr->mRecordFile, FALSE, inBuffer->mAudioDataByteSize, inPacketDesc, aqr->mRecordPacket, &inNumPackets, inBuffer->mAudioData), "AudioFileWritePackets failed");
aqr->mRecordPacket += inNumPackets;
}
}
// if we're not stopping, re-enqueue the buffe so that it gets filled again
if (aqr->IsRunning())
XThrowIfError(AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL), "AudioQueueEnqueueBuffer failed");
} catch (CAXException e) {
char buf[256];
fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
}
}