首先,我只想感谢 AudioKit 的团队通过他们的代码阐明了一些难题。我有几个问题。
1:如果播放器在到达文件/缓冲区末尾之前停止,则不会出现 AKAudioPlayer 类应用现场淡入淡出。AudioKit 库中是否还有其他地方可以处理这个问题?
2:有人知道AVAudioMixer节点的音量可以实时调节吗?EG 我可以每 1/441 毫秒进行一次调整以跟随我的渐变包络曲线吗?还有带有 globalGain 属性的 AVAudioUnitEQ。
3: 是否可以在 AVAudioPCMBuffer 的 floatChannelData 被调度后写入,并且正在播放?
我正在用 AVFoundation 编写一个采样器应用程序。当需要解决在 AVAudioPlayerNodes 中对加载的音频文件应用淡入淡出的问题时,我的第一个计划是实时调整连接到我的播放器节点的混音器节点的音量。这似乎没有任何效果。这样做完全有可能我的时机不对。
当我最终查看 AKAudioPlayer 类时,我意识到可以调整与音频文件关联的实际缓冲区。经过一两天的调试,我能够将 AKAudioPlayer 类中的代码调整到我的 PadModel 类中,但有一些细微差别,而且效果很好。
但是,每当我在文件结束之前停止播放我的一个 Pad 时,我仍然会收到那些讨厌的小点击,因为我应用的淡入淡出仅在文件/缓冲区的开头和结尾处到位。
就我的第一个问题而言,在查看 AKAudioPlayer 类时,似乎唯一应用于缓冲区的淡入淡出发生在缓冲区的开头和结尾。stop() 方法似乎没有对缓冲区应用任何类型的现场淡入淡出。
在我看来,一旦停止事件发生,淡出的唯一方法就是在所述停止事件之后应用它,对吗?
我试过这样做,在我的播放器节点上调用 stop 后立即播放一个 10 毫秒长的淡出缓冲区,该缓冲区由停止位置后 10 毫秒的缓冲区组成。它没有预期的效果。我从一开始就对这个方案没有太大的信心,但似乎值得一试。
需要明确的是,一旦我的 stop() 方法被调用,在实际停止播放器节点之前,我分配了 10 毫秒的淡入淡出缓冲区,在它当前所在的位置读入缓冲区,因为我的淡入淡出缓冲区包含的帧数的。然后我将信封应用到最近分配的淡出缓冲区,就像在 AKAudioPlayer 类的 fadeBuffer() 方法中所做的那样。此时我终于在播放节点上调用了 stop(),然后调度并播放淡出缓冲区。
显然,停止缓冲区和播放淡出缓冲区之间会有不连续性,例如,当我将淡入淡出应用于淡出缓冲区时,我分配给局部变量的停止帧位置将不再有效,等等确实,一旦我放开一个打击垫,播放的声音只能用断断续续来形容。
我能想到的唯一其他解决方案让我觉得这是一项艰巨的任务,那就是在播放缓冲区时,在当前播放位置之前不断地实时将淡入淡出包络应用于样本。我目前不相信我有编码能力来解决这个问题。
无论如何,我查看了所有与 AudioKit 相关的 SO 问题,但似乎没有出现这个特定主题。因此,任何人对此事的想法将不胜感激。提前致谢!
如果有人想查看我的代码,PadModel 类从该文件的第 223 行开始: