为什么我的AudioQueueOutputCallback不能被调用?

编程入门 行业动态 更新时间:2024-10-25 22:25:13
本文介绍了为什么我的AudioQueueOutputCallback不能被调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在使用音频队列服务API ,用于通过iPhone上的TCP套接字连接播放从服务器流式传输的音频。我可以播放从套接字连接填充的缓冲区,我似乎无法让我的AudioQueue调用我的AudioQueueOutputCallback函数,而且我没有想法。

I'm using the Audio Queue Services API to play audio streamed from a server over a TCP socket connection on an iPhone. I can play the buffers that were filled from the socket connection, I just cannot seem to make my AudioQueue call my AudioQueueOutputCallback function, and I'm out of ideas.

  • 数据从套接字连接传递给播放器,并立即将写入内存中的循环缓冲区。
  • 当AudioQueueBuffers变为可用时,数据将从循环缓冲区复制到可用的AudioQueueBuffer中,并立即重新排队。 (或者,如果我的回调发生了)
  • 会发生什么

    缓冲区都已成功填充和排队,我清楚地听到了音频流。为了测试,我使用大量的缓冲区(15)并且所有缓冲区都无缝地播放,但是AudioQueueOutputCallback永远不会被调用,因此我从不重新排队任何缓冲区,尽管事实上一切似乎都在完美地运行。如果我不等待我的回调,假设它永远不会被调用,而是根据写入的数据驱动缓冲区的入队,我可以无限期地播放音频流,重用和重新入队缓冲区,就好像它们一样已经通过回调明确地回复了我。事实就是这样:我可以根据需要重复使用缓冲区来完美地播放流,这让我感到困惑。为什么不调用回调?

    What happens

    The buffers are all filled and enqueued successfully, and I hear the audio stream clearly. For testing, I use a large number of buffers (15) and all of them play through seamlessly, but the AudioQueueOutputCallback is never called, so I never re-queue any of those buffers, despite the fact that everything seems to be working perfectly. If I don't wait for my callback, assuming it will never be called, and instead drive the enqueueing of buffers based on the data as it is written, I can play the audio stream indefinitely, reusing and re-enqueueing buffers as if they had been explicitly returned to me by the callback. It is that fact: that I can play the stream perfectly while reusing buffers as needed, that confuses me the most. Why isn't the callback being called?

    流的格式是16位线性PCM,8 kHz,单声道:

    The format of the stream is 16 bit linear PCM, 8 kHz, Mono:

    _streamDescription.mSampleRate = 8000.0f; _streamDescription.mFormatID = kAudioFormatLinearPCM; _streamDescription.mBytesPerPacket = 2; _streamDescription.mFramesPerPacket = 1; _streamDescription.mBytesPerFrame = sizeof(AudioSampleType); _streamDescription.mChannelsPerFrame = 1; _streamDescription.mBitsPerChannel = 8 * sizeof(AudioSampleType) _streamDescription.mReserved = 0; _streamDescription.mFormatFlags = (kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsPacked);

    我的原型和回调实现如下。没有什么花哨的,与我到目前为止看到的每个例子几乎相同:

    My prototype and implementation of the callback are as follows. Nothing fancy, and pretty much identical to every example I've seen so far:

    // Prototype, declared above the class's @implementation void AQBufferCallback(void* inUserData, AudioQueueRef inAudioQueue, AudioQueueBufferRef inAudioQueueBuffer); // Definition at the bottom of the file. void AQBufferCallback(void* inUserData, AudioQueueRef inAudioQueue, AudioQueueBufferRef inAudioQueueBuffer) { printf("callback\n"); [(MyAudioPlayer *)inUserData audioQueue:inAudioQueue didAquireBufferForReuse:inAudioQueueBuffer]; }

    我像这样创建AudioQueue:

    I create the AudioQueue like this:

    OSStatus status = 0; status = AudioQueueNewOutput(&_streamDescription, AQBufferCallback, // <-- Doesn't work... self, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &_audioQueue); if (status) { // This is not called... NSLog(@"Error creating new audio output queue: %@", [MyAudioPlayer stringForOSStatus:status]); return; }

    我将这样的缓冲区排入队列。此时,已知本地缓冲区包含用于复制的正确数据量:

    And I enqueue buffers like this. At this point, it is known that the local buffer contains the correct amount of data for copying:

    memcpy(aqBuffer->mAudioData, localBuffer, kAQBufferSize); aqBuffer->mAudioDataByteSize = kAQBufferSize; OSStatus status = AudioQueueEnqueueBuffer(_audioQueue, aqBuffer, 0, NULL); if (status) { // This is also not called. NSLog(@"Error enqueueing buffer %@", [MyAudioPlayer stringForOSStatus:status]); }

    请救我。

    推荐答案

    这是在主线程还是后台线程上执行的?如果 CFRunLoopGetCurrent()返回可能消失的线程的运行循环(线程池等),或者是一个不关心 kCFRunLoopCommonModes 。

    Is this executed on the main thread or a background thread? probably not good if CFRunLoopGetCurrent() returns a run loop of a thread that could disappear (thread pool etc) or is a run loop that don't care about kCFRunLoopCommonModes.

    尝试将 CFRunLoopGetCurrent()更改为 CFRunLoopGetMain()或确保执行 AudioQueueNewOutput()和执行CFRunLoopGetCurrent()在主线程或您可以控制的线程上,并且具有正确的运行循环。

    Try to change CFRunLoopGetCurrent() to CFRunLoopGetMain() or make sure AudioQueueNewOutput() and CFRunLoopGetCurrent() is executed on the main thread or a thread that you have control over and has a proper run loop.

    更多推荐

    为什么我的AudioQueueOutputCallback不能被调用?

    本文发布于:2023-11-03 15:59:20,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1555514.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:AudioQueueOutputCallback

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!