Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如何开始写入现有音频队列以响应事件?_Iphone_Cocoa_Audio_Sdk_Audioqueueservices - Fatal编程技术网

Iphone 如何开始写入现有音频队列以响应事件?

Iphone 如何开始写入现有音频队列以响应事件?,iphone,cocoa,audio,sdk,audioqueueservices,Iphone,Cocoa,Audio,Sdk,Audioqueueservices,我正在编写一个类,该类打开一个AudioQueue并分析其特征,然后在某些条件下可以开始或结束从该AudioQueue中写入一个已经实例化的文件。这是我的代码(完全基于SpeakHere),它打开AudioQueue而不向tmp写入任何内容: void AQRecorder::StartListen() { int i, bufferByteSize; UInt32 size; try { SetupAudioFormat(kAudioFormatLinearPCM);

我正在编写一个类,该类打开一个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");
}
}
void AQRecorder::StartListen(){
inti,bufferByteSize;
UInt32尺寸;
试试{
SetupAudioFormat(kAudioFormatLinearPCM);
XThrowIfError(AudioQueueNewInput和mRecordFormat,
MyInputBufferHandler,
这
空,空,,
0,&MQUE),“AudioQueueNewInput失败”);
mRecordPacket=0;
size=sizeof(mRecordFormat);
XThrowIfError(AudioQueueGetProperty(MQUE、KAUDIOQUUEProperty_StreamDescription、,
&mRecordFormat,&size),“无法获取队列的格式”);
bufferByteSize=ComputeRecordBufferSize(&mRecordFormat,kBufferDurationSeconds);
对于(i=0;i

但我不太清楚如何编写一个函数,告诉这个队列“从现在起直到停止信号,开始将这个队列作为文件写入tmp”。我知道如何告诉AudioQueue在创建时将其作为文件写入,如何设置文件格式等,但不知道如何告诉它在中途启动和停止。非常感谢任何提示。

您可以使用AudioQueuePause(AudioQueueRef inAQ)和AudioQueueStart(AudioQueueRef inAQ,const AudioTimeStamp*inStartTime)随时暂停/启动audioqueue

还有更多的可能性。因为您在回调函数中编写音频文件,所以您可以在那里选择何时以及保存什么数据

要控制是否写入数据,请在recorder类中创建bool标志,例如“doWrite”,并仅在其设置为“是”时写入。队列开始从start接收数据并不断填充缓冲区,但您只需在回调中输入这些数据,直到标志保持为“否”。然后随时设置doWrite=YES,下一个缓冲区将保存到文件中。当您根据声音本身更改录制时(例如,仅当声音大于某个thredhold值时录制),此方法特别有用


谢谢Vladimir,MyInputBufferHandler的布尔标志方法工作得非常好。我想补充一点(对于任何阅读本文并想尝试它的人来说),我上面的函数需要更改为包含对AudioFileCreateWithURL的调用,以便它在被告知要写入时有一个音频文件要写入-函数StartRecord()在苹果公司的示例代码项目SpeakHere中,我们展示了一个很好的例子。
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));
    }
}