Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "github.com/gordonklaus/portaudio"
- "github.com/dalloriam/synthia/modular"
- "github.com/dalloriam/synthia"
- )
- const (
- bufferSize = 512 // Size of the audio buffer.
- sampleRate = 44100 // Audio sample rate.
- audioChannelCount = 2 // Stereo.
- mixerChannelCount = 2 // Three oscillators.
- )
- type AudioBackend struct {
- params portaudio.StreamParameters
- }
- func (b *AudioBackend) Start(callback func(in []float32, out [][]float32)) error {
- stream, err := portaudio.OpenStream(b.params, callback)
- if err != nil {
- return err
- }
- return stream.Start()
- }
- func (b *AudioBackend) FrameSize() int {
- return b.params.FramesPerBuffer
- }
- func newBackend() *AudioBackend {
- // Quick-and-dirty way to initialize portaudio
- if err := portaudio.Initialize(); err != nil {
- panic(err)
- }
- devices, err := portaudio.Devices()
- if err != nil {
- panic(err)
- }
- inDevice, outDevice := devices[0], devices[1]
- params := portaudio.LowLatencyParameters(inDevice, outDevice)
- params.Input.Channels = 1
- params.Output.Channels = audioChannelCount
- params.SampleRate = float64(sampleRate)
- params.FramesPerBuffer = bufferSize
- return &AudioBackend{params}
- }
- func main() {
- backend := newBackend()
- // Set tempo to 60 bpm
- clock := modular.NewClock()
- clock.Tempo.SetValue(60)
- // Set the sequence to a C Major scale
- seq := modular.NewSequencer([]float64{130.81, 146.83, 164.1, 174.61, 196, 220, 246.94, 261.63})
- seq.Clock = clock
- // Play the sequence in eighth notes
- seq.BeatsPerStep = 1.0 / 2.0
- gateSeq := make([]float64, 32)
- for i := 0; i < 32; i++ {
- if i%2 == 0{
- gateSeq[i] = 1
- } else {
- gateSeq[i] = 0
- }
- }
- gate := modular.NewSequencer(gateSeq)
- gate.Clock = clock
- gate.BeatsPerStep = 1.0/12.0
- env := modular.NewEnvelope()
- env.Trigger = gate
- // Create an oscillator and attach the sequencer to it.
- osc1 := modular.NewOscillator()
- osc1.Frequency.Line = seq
- osc1.Volume.Line = env
- // Create the synthesizer with two mixer channels and set it to output to our audio backend.
- synth := synthia.New(mixerChannelCount, bufferSize, backend)
- phaser := modular.NewLFO(1, -1)
- phaser.Osc.Frequency.SetValue(1)
- // Map two different waves to the two outputs of our mixer.
- synth.Mixer.Channels[0].Input = osc1.Saw
- synth.Mixer.Channels[0].Pan.Line = phaser
- // Block until terminated
- select{}
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement