- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在使用 Audio Queue Services API在 iPhone 上通过 TCP 套接字连接播放从服务器流式传输的音频。我可以播放从套接字连接填充的缓冲区,我似乎无法让我的 AudioQueue 调用我的 AudioQueueOutputCallback 函数,而且我没有想法。
缓冲区全部填满入队成功,音频流听得一清二楚。为了进行测试,我使用了大量缓冲区 (15),并且所有缓冲区都无缝播放,但从未调用 AudioQueueOutputCallback,因此我从不重新排队任何这些缓冲区,尽管事实上一切似乎都运行良好。如果我不等待我的回调,假设它永远不会被调用,而是根据写入的数据驱动缓冲区入队,我可以无限期地播放音频流,重复使用和重新入队缓冲区,就像它们一样回调已明确返回给我。这是事实:我可以在根据需要重用缓冲区的同时完美地播放流,这让我最困惑。为什么没有调用回调?
流的格式是 16 位线性 PCM,8 kHz,单声道:
_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);
我的回调原型(prototype)和实现如下。没什么特别的,而且与我目前看到的每个示例几乎相同:
// 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:
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;
}
然后我像这样排队缓冲区。此时,已知本地缓冲区包含正确数量的用于复制的数据:
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
的运行循环,则可能不太好。
尝试将 CFRunLoopGetCurrent()
更改为 CFRunLoopGetMain()
或确保 AudioQueueNewOutput()
和 CFRunLoopGetCurrent()
在主线程或您可以控制并具有适当运行循环的线程上执行。
关于iphone - 为什么我的 AudioQueueOutputCallback 不会被调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7575670/
我正在使用 Audio Queue Services API在 iPhone 上通过 TCP 套接字连接播放从服务器流式传输的音频。我可以播放从套接字连接填充的缓冲区,我似乎无法让我的 AudioQu
我是一名优秀的程序员,十分优秀!