我是AudioKit的新手。我想建立一个VCO谁的音高是由一个可重触发的A(H)R-包络控制(可调衰减),我正在寻找最好的或最常见的方法。
经过一些研究(和错误的方向),在我看来,我必须和AKOperationGenerator和AKOperation一起去。
最好的例子是来自操场的滤波包络例。
我试过:
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)
)效果很好。但我只听到一个无穷无尽的音调(用正确的频率)。只有第一个扳机在俯仰时膨胀。其他的触发器不会重新触发信封。怎么会.我错了什么?丁烯
发布于 2018-03-08 21:11:25
似乎我需要找到正确的时间门的长度(注意到顺序步长的持续时间),还需要发送一个关口事件来将门设置为零。
...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
}编辑:好的-我找到了正确的答案,我贴了这里
https://stackoverflow.com/questions/49140013
复制相似问题