4

AudioQueue を開いてその特性を分析し、特定の条件下で、すでにインスタンス化されている AudioQueue からファイルの書き出しを開始または終了できるクラスを作成しています。これは、tmp に何も書き出さずに AudioQueue を開く私のコード (完全に SpeakHere に基づく) です。

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 が作成されたときにファイルとして書き出すように指示する方法、ファイル形式を設定する方法などは理解していますが、途中で開始および停止するように指示する方法は理解していません。ポインタに感謝します、ありがとう。

4

1 に答える 1

4

AudioQueuePause(AudioQueueRef inAQ)およびAudioQueueStart(AudioQueueRef inAQ、const AudioTimeStamp * inStartTime)を使用して、いつでもオーディオキューを一時停止/開始できます。

そして、より多くの可能性があります。コールバック関数でオーディオファイルを作成するため、いつ、どのデータを保存するかを選択できます。

書き込みデータを制御するには、レコーダークラスに「doWrite」などのboolフラグを作成し、YESに設定されている場合にのみ書き込みます。キューは開始からデータの受信を開始し、継続的にバッファーをいっぱいにしますが、フラグがNOのままになるまで、コールバックでこれらのデータを無視します。その後、いつでもdoWrite = YESを設定すると、次のバッファがファイルに保存されます。このアプローチは、サウンド自体に基づいて録音を変更する場合に特に便利です(たとえば、サウンドがしきい値よりも大きい場合にのみ録音します)。

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));
    }
}
于 2010-03-18T22:58:32.307 に答える