- Go 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .gitignore | ||
| calibration.go | ||
| command.go | ||
| command_test.go | ||
| engine.go | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| modulation.go | ||
| modulation_test.go | ||
| portaudio.go | ||
| README.md | ||
CV Engine is an open-source sample accurate CV renderer written in Go. It allows programmatic output of CV when using a DC-coupled audio card. It's only dependency is PortAudio. It has a bespoke detune algorithm spirtually aligned with an out of tune guitar, and has easy configuration of many EDO. It's purpose for existing is so that you can create wrappers for various live-coding environments, or any other sequencing software that speaks OSC, and connect it to your CV synthesisers.
Atm, we have wrappers for the following OSC compatible live-coding environments:
- Electra
- Orca: orcv
- Tidal Cycles: tidal-cvcles
api
import cv "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)
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.
edo
engine.SetEDO(19)
detune
engine.SetDetune(10)
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.
modulation
engine.SetLFO(cv.LFOConfig{
Channel: 0,
Wave: cv.Sine,
Frequency: 0.5,
Amplitude: 2,
Offset: 0,
})
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.