5

我在寻找没有过渡中断的起音(声音开始)/维持(循环声音)/衰减(声音结束)序列的资源时遇到问题。是否有任何好的库来处理这个问题,或者我应该使用 AVAudioPlayer 自己动手?AudioQueue 是一个更好的地方吗?我曾经使用 SoundEngine.cpp,但它已经很久没有使用了。CAF 仍然是最好的格式吗?

谢谢!

4

2 回答 2

3

根据您的描述,听起来好像您正在尝试编写软件合成器。您可以用于此类操作的唯一方法是AVAudioPlayer将音符的整个持续时间组合为单个 WAV 文件,然后使用AVAudioPlayer.

要创建任意持续时间的音符声音,它会响应用户操作(如点击按钮)开始播放,然后继续播放直到第二个用户操作(如点击“停止”按钮或将手指从第一个按钮上移开) ) 开始将循环区域的音量降低到零的过程(“释放”部分),您需要使用AudioQueue(AVAudioPlayer可用于播放完全在内存中构建的音频,但必须在播放开始之前构建整个播放,这意味着您无法更改正在播放的内容以响应用户操作 [除了停止播放])。

这是另一个问题/答案,它简单地显示了如何使用AudioQueue. AudioQueue每当需要加载更多数据以播放时调用回调方法 - 您必须实现循环和信封包装原始 WAV 文件数据的所有代码。

于 2011-10-31T20:47:26.263 回答
1

创建自己的包络生成器非常简单。困难的部分将是更新您的程序以使用较低级别的音频服务,以便直接改变信号。

为此,您将需要:

  • 音频文件的样本
  • 设置一个 AudioQueue (这是一种方法,但我会使用它,因为它在 OP 中提到,它是用户提供的样本缓冲区的相对高级 API)
  • 向队列提供信号
  • 确定您的程序是最好的实时还是预渲染

即时的

  • 允许实时变化
  • 管理您的循环点
  • 管理您的渲染位置
  • 能够根据您正在读取的样本位置范围确定要应用的幅度

或者

预渲染

  • 可能需要更多内存
  • 需要更少的 CPU
  • 将信封应用到样本缓冲区的副本
  • 管理您的渲染位置

我还假设您只需要缓慢/简单的过渡。如果你想要一些疯狂/快速的 LFO,没有混叠,你将有更多的工作要做。除非您的更改过于突然,否则此方法不应产生可听见的混叠:

编写一个简单的包络发生器(EG)很容易;如果您需要朝那个方向推进,请查看 Apple 的 SinSynth 以获得非常基本的 EG。

于 2011-10-27T06:00:09.467 回答