我是 AudioKit 的新手。我想构建一个 VCO,其音调由可重新触发的 A(H)R 包络(具有可调衰减)控制,并且我正在寻找最好或最常见的方法来实现它。
经过一番研究(和错误的方向 https://stackoverflow.com/questions/49094157/how-to-build-an-oscillator-with-an-envelope-on-its-frequency-pitch-in-audiokit)在我看来,我必须使用 AKOperationGenerator 和 AKOperation。
最好的例子是滤波器包络示例 http://audiokit.io/playgrounds/Synthesis/Filter%20Envelope/从游乐场。
I tried:
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 }
}
}
with
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