类似NSSound的框架可以工作,但不需要处理陡峭的学习曲线

时间:2010-08-24 13:26:34

标签: cocoa macos core-audio audioqueueservices nssound

我已经完成了一项白噪声功能的工作,我的一个应用程序使用NSSound播放10秒AAC编码的预录白噪声循环。

[sound setLoops: YES]

应该是所有必需的,对吧?

它就像一个魅力,但我注意到声音文件完成和重新启动之间有一个可听见的暂停..一种“噗”声。循环原始声音文件时不存在这种情况,经过一个小时左右的尝试来解决这个问题,我得出的结论是NSSound糟透了,声音暂停是私人后台线程同步的人工制品播放声音。它似乎以某种方式依赖于主运行循环,这导致声音结束和重新启动之间的声音差距。

我对声音的东西知之甚少,这是一个非常小的功能,所以我不想深入了解CoreAudio只是为了播放一个循环的10s声音片段..所以我去追逐一个不错的选择,但似乎没有什么比较合适:

  • 核心音频:总体矫枉过正,但至少是标准框架
  • AudioQueue:复杂,带有C ++示例代码!?
  • MusicKit / SndKit:基于大量开源资料等方面的巨大学习曲线。

我看到iOS 4上的AVFoundation将是播放声音的一种很好的方式,但这只是为Mac OS X 10.7安排的。

Mac OS X 10.5 +上是否有任何易于使用的可靠循环声音的方式?

AudioQueue或Core Audio是否有任何示例代码可以解决从Objective-C应用程序中使用它们的痛苦?

非常感谢任何帮助..

致以最诚挚的问候,

3 个答案:

答案 0 :(得分:2)

使用QTKit。为声音创建QTMovie,将其设置为循环播放,然后将其保持播放状态。

答案 1 :(得分:2)

只是为了档案。

QTKit在一场比赛结束和下一场比赛开始之间也存在差距。它似乎与以某种方式重新初始化数据(可能从磁盘重新读取它?)有关。使用体积小得多但高度压缩的m4a格式比播放未压缩的aiff文件要明显得多,但它仍然存在。

我找到的解决方案是使用音频队列服务:

http://developer.apple.com/mac/library/documentation/MusicAudio/Conceptual/AudioQueueProgrammingGuide/AQPlayback/PlayingAudio.html#//apple_ref/doc/uid/TP40005343-CH3-SW1

http://developer.apple.com/mac/library/samplecode/AudioQueueTools/Listings/aqplay_cpp.html#//apple_ref/doc/uid/DTS10004380-aqplay_cpp-DontLinkElementID_4

音频队列调用一个回调函数来准备和排队下一个缓冲区,所以当你到达当前文件的末尾时,你需要从头开始。这样可以完全无间隙播放。

文档中的示例代码中有两个陷阱。

第一个是一个实际的错误(我会联系DTS关于这个,以便他们可以纠正它)。在分配和启动音频缓冲区之前,自定义结构必须打开播放,否则音频缓冲区永远不会被启动并且没有播放任何内容:

    aqData.mIsRunning = 1;

第二个问题是代码不能在Cocoa中运行,而是作为独立工具运行,因此代码将音频队列连接到新的运行循环,并实际上将运行循环本身实现为程序的最后一步。 / p>

不要传递CFRunLoopGetCurrent(),只需传递NULL,这会导致AudioQueue在自己的运行循环中运行。

result = AudioQueueNewOutput (                                // 1
                     &aqData.mDataFormat,                             // 2
                     HandleOutputBuffer,                              // 3
                     &aqData,                                         // 4
                     NULL, //CFRunLoopGetCurrent (),                          // 5
                     kCFRunLoopCommonModes,                           // 6
                     0,                                               // 7
                     &aqData.mQueue                                   // 8
                     );

我希望这可以挽救可怜的可怜的人在未来的某个时间做同样的事情: - )

答案 2 :(得分:0)

可悲的是,在OS X上开发音频应用程序时会有很多痛苦。学习曲线非常陡峭,因为文档很少。

如果你不介意Objective-C ++,我已经为这类事情编写了一个框架:SFBAudioEngine。如果你想用我的代码播放声音,你可以这样做:

DSPAudioPlayer *player = new DSPAudioPlayer();
player->Enqueue((CFURLRef)audioURL);
player->Play();

也可以循环播放。