使用 AVAudioPlayer 播放声音的最佳方式:起音 / 延音(循环) / 衰减
我在寻找播放攻击(声音开始)/维持(循环声音)/衰减(声音结束)序列而没有过渡中断的资源时遇到问题。是否有任何好的库可以处理这个问题,或者我应该使用 AVAudioPlayer 推出自己的库? AudioQueue 是一个更好的地方吗?我曾经使用 SoundEngine.cpp,但它已经消失了一段时间了。 CAF 仍然是最适合使用的格式吗?
谢谢!
I am having a problem finding resources on playing an attack (start of sound) / sustain (looping sound) / decay (ending of sound) sequence with no transition breaks. Are there any good libraries for handling this, or should I roll my own with AVAudioPlayer? Is AudioQueue a better place to look? I used to use SoundEngine.cpp, but that's been long gone for a while. Is CAF still the best format to use for it?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从你的描述来看,听起来好像你正在尝试编写一个软件合成器。使用
AVAudioPlayer
实现此类操作的唯一方法是将音符的整个持续时间编写为单个 WAV 文件,然后使用AVAudioPlayer
播放整个内容。要创建任意持续时间的音符声音,先响应用户操作(例如点击按钮)开始播放,然后继续播放直到第二个用户操作(例如点击“停止”按钮或将手指从第一个按钮上移开) )开始将循环区域的音量降至零(“释放”部分)的过程,您将需要使用
AudioQueue
(AVAudioPlayer
可用于播放构建的音频完全在记忆中,但整个播放必须在播放开始之前构建,这意味着您无法响应用户操作更改正在播放的内容(停止播放除外)。这是另一个问题/答案 简单地展示了如何使用
AudioQueue
。每当需要加载更多数据进行播放时,AudioQueue 就会调用回调方法 - 您必须实现循环和封装原始 WAV 文件数据的所有代码。From your description, it sounds as if you're trying to write a software synthesizer. The only way that you could use
AVAudioPlayer
for something like this would be to compose the entire duration of a note as a single WAV file and then play the whole thing withAVAudioPlayer
.To create a note sound of arbitrary duration, one that begins playing in response to a user action (like tapping a button) and then continues playing until a second user action (like tapping a "stop" button or lifting the finger off the first button) begins the process of ramping the looped region's volume down to zero (the "release" part), you will need to use
AudioQueue
(AVAudioPlayer
can be used to play audio constructed entirely in memory, but the entire playback has to be constructed before play begins, meaning that you cannot change what is being played in response to user actions [other than to stop playback]).Here's another question/answer that shows simply how to use
AudioQueue
.AudioQueue
calls a callback method whenever it needs to load up more data to play - you would have to implement all the code that loops and envelope-wraps the original WAV file data.创建您自己的包络生成器非常简单。困难的部分是更新您的程序以使用较低级别的音频服务,以便直接改变信号。
为此,您将需要:
实时
或
预渲染
我还假设您只需要缓慢/简单的过渡。如果你想要一些疯狂/快速的低频振荡器,没有锯齿,你将有更多的工作要做。这种方法不应产生可听见的混叠,除非您的更改太突然:
编写一个简单的包络生成器 (EG) 很容易;如果您需要朝这个方向推动,请查看 Apple 的 SinSynth 以获得非常基本的 EG。
creating your own envelope generator is very simple. the tough part will be updating your program to use lower level audio services in order to alter the signal directly.
to do this, you will need:
Realtime
or
Prerendered
I also assume that you need only slow/simple transitions. If you want some crazy/fast LFO, without aliasing, you will have a lot more work to do. This approach should not produce audible aliasing unless your changes are too abrupt:
Writing a simple envelope generator (EG) is easy; check out Apple's SinSynth for a very basic EG if you need a push in that direction.