No description
- Go 100%
| .gitignore | ||
| calibration.go | ||
| command.go | ||
| engine.go | ||
| go.mod | ||
| go.sum | ||
| modulation.go | ||
| modulation_test.go | ||
| portaudio.go | ||
| README.md | ||
cv-engine
sample-accurate CV renderer.
holds pitch. holds gate. retriggers. slides. lfos. envelopes.
go get source.source.auti.sm/australian-tactile-instruments/cv-engine
protocol-agnostic. no midi. no gui. frontends handle OSC, address parsing, arg layout.
api
import cv "source.source.auti.sm/australian-tactile-instruments/cv-engine"
engine, _ := cv.New(cv.Config{
Channels: 16,
Calibration: []cv.Calibration{{MinVolts: -10, MaxVolts: 10}},
})
out, _ := cv.OpenOutput(engine, cv.PortAudioConfig{
DeviceName: "ES-8",
FramesPerBuffer: 32,
})
out.Start()
engine.RenderInterleaved(buffer) // portaudio callback
commands
engine.Trigger(cv.Command{
Kind: cv.PitchCommand,
Channel: 0,
Note: 7,
Octave: 4,
Slide: 50 * time.Millisecond,
})
engine.Trigger(cv.Command{
Kind: cv.GateCommand,
Channel: 1,
Gate: true,
Duration: 100 * time.Millisecond,
})
engine.Trigger(cv.Command{
Kind: cv.TriggerCommand,
Channel: 8,
Gate: true,
Duration: 5 * time.Millisecond,
})
pitch holds until next pitch. gate retriggers on overlap. trigger fires once.
nudge delays by sample frames. queued. applied inside RenderInterleaved.
edo
engine.SetEDO(19) // 0–35. 0 = 12.
pitch voltage: note / EDO.
detune
engine.SetDetune(10) // 0–35. 0 = neutral.
six virtual strings. fixed cent offsets. scaled by detune.
0-4 -16
5-8 +9
9-13 -5
14-18 +18
19-22 -11
23+ +6
deterministic. not chorus, not vibrato, not random.
pitch voltage: note / EDO + cents / 1200.
modulation
engine.SetLFO(cv.LFOConfig{
Channel: 0,
Wave: cv.Sine, // Sine, Triangle, Saw, ReverseSaw, Square
Frequency: 0.5, // Hz
Amplitude: 2, // volts peak
Offset: 0, // volts DC
})
engine.SetADSR(cv.ADSRConfig{
Channel: 1,
AttackTime: 10 * time.Millisecond,
DecayTime: 50 * time.Millisecond,
SustainLevel: 0.7,
ReleaseTime: 200 * time.Millisecond,
Amplitude: 5,
})
lfo runs continuously. adsr triggered by gate — gate-on fires attack, gate-off fires release. summed into channel voltage alongside pitch and gate.
ClearLFO(channel) and ClearADSR(channel) remove modulation.