Swift AudioKit:如何建立一个由AR信封控制音高的VCO?

我是AudioKit的新手。 我想建立一个VCO,其音高由可重新触发的A(H)R-包络(具有可调衰减)控制,我正在寻找最佳或最常用的方法。

经过一些研究( 和错误的指示 )后,我认为我必须使用AKOperationGenerator和AKOperation。

最好的例子是游乐场的Filter Envelope示例 。

我试过了:

enum PitchEnvVCOSynthParameter: Int { case frequency, decayTime, gate } struct PitchEnvVCO { static var frequency: AKOperation { return AKOperation.parameters[PitchEnvVCOSynthParameter.frequency.rawValue] } static var decayTime: AKOperation { return AKOperation.parameters[PitchEnvVCOSynthParameter.decayTime.rawValue] } static var gate: AKOperation { return AKOperation.parameters[PitchEnvVCOSynthParameter.gate.rawValue] } } extension AKOperationGenerator { var frequency: Double { get { return self.parameters[PitchEnvVCOSynthParameter.frequency.rawValue] } set(newValue) { self.parameters[PitchEnvVCOSynthParameter.frequency.rawValue] = newValue } } var decayTime: Double { get { return self.parameters[PitchEnvVCOSynthParameter.decayTime.rawValue] } set(newValue) { self.parameters[PitchEnvVCOSynthParameter.decayTime.rawValue] = newValue } } var gate: Double { get { return self.parameters[PitchEnvVCOSynthParameter.gate.rawValue] } set(newValue) { self.parameters[PitchEnvVCOSynthParameter.gate.rawValue] = newValue } } } 

 class SimpleGenerator: AKNode { var generator = AKOperationGenerator { parameters in var oscillator = AKOperation.squareWave(frequency: PitchEnvVCO.frequency.triggeredWithEnvelope( trigger: PitchEnvVCO.gate, attack: 0.01, hold: 0.01, release: 0.2 )).triggeredWithEnvelope(trigger: PitchEnvVCO.gate, attack: 0.1, hold: 0.01, release: 0.5) return oscillator } var vco1Freq: Double = 440.0 { didSet { generator.parameters[PitchEnvVCOSynthParameter.frequency.rawValue] = vco1Freq } } var pitchDecay: Double = 0.1 { didSet { generator.parameters[PitchEnvVCOSynthParameter.decayTime.rawValue] = pitchDecay } } var sourceMixer = AKMixer() func start() { generator.parameters = [vco1Freq, pitchDecay, 0] // Initialize the array generator.start() } func triggerGate(_ freq: Double) { vco1FreqOffset = freq generator.parameters[PitchEnvVCOSynthParameter.gate.rawValue] = 1 // or generator.trigger(1) } override init() { sourceMixer = AKMixer(generator) super.init() avAudioNode = sourceMixer.avAudioNode } } 

我通过音序器轨道触发发生器,触发回调

 let seqPositioncallbackTrack = sequencer.newTrack() seqPositioncallbackTrack?.setMIDIOutput(sequencerCallbackInst.midiIn) sequencerCallbackInst.callback = { status, noteNumber, velocity in self.onSequencerStepChange(status: status, noteNumber: noteNumber, velocity: velocity) } //...for i in 0 ..< numberOfSteps...etc. seqPositioncallbackTrack?.add(noteNumber: MIDINoteNumber(i), velocity: 100, position: AKDuration(beats: Double(i)), duration: AKDuration(beats: 0.5) ) 

哪个工作正常。 但我只是听到无尽的音调(频率正确)。 只有第一个触发器在音高上膨胀。 其他触发器不会重新触发包络。 怎么来 – 我错了什么? 日Thnx

看起来我需要找到正确的栅极导通时间长度(注意音序器步长持续时间的长度),并发送栅极关闭事件以将栅极设置为零。

 ...duration: AKDuration(seconds: 0.03) private func onSequencerStepChange(status: AKMIDIStatus, noteNumber: MIDINoteNumber, velocity: MIDIVelocity) { if status == .noteOn { core.triggerGateOn(seq1Values[Int(noteNumber)]) } else if status == .noteOff { core.triggerGateOff() } else { return } } ... // splitting func triggerGate(_ freq: Double) into on/off: func triggerGateOn(_ freq: Double) { generator.parameters[PitchEnvVCOSynthParameter.gate.rawValue] = 1 } func triggerGateOff() { generator.parameters[PitchEnvVCOSynthParameter.gate.rawValue] = 0 } 

当持续时间太短时,它似乎也不起作用,意味着<0.03 - 然后我想门启动设置为关闭比攻击时间完成更快。 还有我必须使用发布时间来模拟的衰减时间

 let generator = AKOperationGenerator { parameters in let oscillator = AKOperation.squareWave( frequency: PitchEnvVCO.frequency.triggeredWithEnvelope( trigger: PitchEnvVCO.gate, attack: 0.01, hold: 0.0, release: PitchEnvVCO.freqDecayTime ), amplitude: PitchEnvVCO.amplitude.triggeredWithEnvelope( trigger: PitchEnvVCO.gate, attack: 0.01, hold: 0.0, release: PitchEnvVCO.ampDecayTime ) ) return oscillator } 

编辑:好的 – 我找到的正确答案我发布在这里