我已经完成了一项白噪声功能的工作,我的一个应用程序使用NSSound播放10秒AAC编码的预录白噪声循环。
[sound setLoops: YES]
应该是所有必需的,对吧?
它就像一个魅力,但我注意到声音文件完成和重新启动之间有一个可听见的暂停..一种“噗”声。循环原始声音文件时不存在这种情况,经过一个小时左右的尝试来解决这个问题,我得出的结论是NSSound糟透了,声音暂停是私人后台线程同步的人工制品播放声音。它似乎以某种方式依赖于主运行循环,这导致声音结束和重新启动之间的声音差距。
我对声音的东西知之甚少,这是一个非常小的功能,所以我不想深入了解CoreAudio只是为了播放一个循环的10s声音片段..所以我去追逐一个不错的选择,但似乎没有什么比较合适:
我看到iOS 4上的AVFoundation将是播放声音的一种很好的方式,但这只是为Mac OS X 10.7安排的。
Mac OS X 10.5 +上是否有任何易于使用的可靠循环声音的方式?
AudioQueue或Core Audio是否有任何示例代码可以解决从Objective-C应用程序中使用它们的痛苦?
非常感谢任何帮助..
致以最诚挚的问候,
谢
答案 0 :(得分:2)
使用QTKit。为声音创建QTMovie
,将其设置为循环播放,然后将其保持播放状态。
答案 1 :(得分:2)
只是为了档案。
QTKit在一场比赛结束和下一场比赛开始之间也存在差距。它似乎与以某种方式重新初始化数据(可能从磁盘重新读取它?)有关。使用体积小得多但高度压缩的m4a格式比播放未压缩的aiff文件要明显得多,但它仍然存在。
我找到的解决方案是使用音频队列服务:
和
音频队列调用一个回调函数来准备和排队下一个缓冲区,所以当你到达当前文件的末尾时,你需要从头开始。这样可以完全无间隙播放。
文档中的示例代码中有两个陷阱。
第一个是一个实际的错误(我会联系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();
也可以循环播放。