AudioKit新手求助:如何连续改变AKMorphingOscillatorBank频率?
嘿,作为AudioKit新手,你想做的这个可调谐、带波形变形还能同步其他振荡器的单音波形表振荡器,确实用AKMorphingOscillatorBank会遇到实时调频的问题——毕竟这个类是为多复音音符触发设计的,它的频率绑定MIDI音符号,没法直接在播放过程中连续修改基频。我给你捋两个实用的解决方案:
方案一:改用单音版AKMorphingOscillator(最推荐)
单音的AKMorphingOscillator就是为这种实时参数调整场景设计的,它直接暴露了frequency属性,支持你随时连续修改,同时也保留了波形变形的index参数。
核心代码示例
import AudioKit class TunableMorphSynth { private let audioEngine = AudioEngine() private var morphOsc: AKMorphingOscillator! private let outputMixer: AKMixer! init() { // 初始化波形表,你可以替换成自定义的波形数组 let waveforms = [ AKTable(.sine), AKTable(.triangle), AKTable(.sawtooth), AKTable(.square) ] morphOsc = AKMorphingOscillator(waveformArray: waveforms) // 初始参数设置 morphOsc.frequency = 440.0 // 默认A4 morphOsc.amplitude = 0.5 morphOsc.index = 0.0 // 起始用正弦波 // 路由到输出 outputMixer = AKMixer(morphOsc) audioEngine.output = outputMixer // 启动音频引擎 do { try audioEngine.start() } catch { print("音频引擎启动失败: \(error.localizedDescription)") } } // 控制振荡器启停 func togglePlay() { morphOsc.isStarted ? morphOsc.stop() : morphOsc.start() } // 连续调整基频(直接绑定旋钮/滑块的输入值) func updateBaseFrequency(_ newValue: Double) { // newValue可以是20~20000Hz范围内的任意数值 morphOsc.frequency = newValue } // 调整波形变形程度(0~1之间连续变化,平滑切换波形) func updateMorphIndex(_ newValue: Double) { morphOsc.index = newValue } // 和其他振荡器同步频率 func syncFrequency(with otherOscillator: AKOscillator) { otherOscillator.frequency = morphOsc.frequency } }
为什么这个方案更合适?
AKMorphingOscillatorBank是为多复音场景设计的,每次触发MIDI音符时它会创建一个独立的振荡器实例,频率由音符号决定,没法直接修改正在发声的那个振荡器的频率。而单音版本完全由你直接控制参数,完美适配“播放时用旋钮连续调基频”的需求。
方案二:如果非要用AKMorphingOscillatorBank(仅限小范围调频)
如果你有复音需求,必须用Bank类,那可以通过**弯音(Pitch Bend)**来实现小范围的频率调整,但这个方法只能做相对偏移,没法直接设置绝对基频:
// 假设你已经触发了一个MIDI音符(比如69对应A4=440Hz) // 计算要偏移的半音数:比如从440调到450,半音数是 log2(450/440)*12 ≈ 0.39半音 let targetFrequency = 450.0 let currentFrequency = 440.0 let pitchBendValue = log2(targetFrequency / currentFrequency) * 12 // 应用弯音 morphingOscBank.setPitchBend(pitchBendValue)
注意:弯音的默认范围是±2半音,如果需要更大范围,你需要先设置morphingOscBank.pitchBendRange = 12(比如±12半音),但这种方式始终是基于触发音符的相对偏移,不如单音振荡器直接调绝对频率灵活。
额外提示:波形变形的细节
不管用哪个方案,index参数都是0到1之间的连续值,对应波形数组里的波形平滑过渡。比如index=0.25就是第一个和第二个波形的混合,index=0.75是第三个和第四个波形的混合,完全支持实时旋钮调节。
内容的提问来源于stack exchange,提问作者headkit

