feat(sointu, tracker,...): restructure domain & tracker models

send targets are now by ID and Song has "Score" part, which is the notes for it. also, moved the model part separate of the actual gioui dependend stuff.

sorry to my future self about the code bomb; ended up too far and did not find an easy way to rewrite the history to make the steps smaller, so in the end, just squashed everything.
This commit is contained in:
vsariola
2021-02-23 23:55:42 +02:00
parent fd1d018e82
commit adcf3ebce8
155 changed files with 5520 additions and 4914 deletions

11
audio.go Normal file
View File

@ -0,0 +1,11 @@
package sointu
type AudioSink interface {
WriteAudio(buffer []float32) error
Close() error
}
type AudioContext interface {
Output() AudioSink
Close() error
}

View File

@ -23,7 +23,7 @@ func (s BridgeService) Compile(patch sointu.Patch) (sointu.Synth, error) {
func Synth(patch sointu.Patch) (*C.Synth, error) { func Synth(patch sointu.Patch) (*C.Synth, error) {
s := new(C.Synth) s := new(C.Synth)
comPatch, err := compiler.Encode(&patch, compiler.AllFeatures{}) comPatch, err := compiler.Encode(patch, compiler.AllFeatures{})
if err != nil { if err != nil {
return nil, fmt.Errorf("error compiling patch: %v", err) return nil, fmt.Errorf("error compiling patch: %v", err)
} }
@ -102,7 +102,7 @@ func (s *C.Synth) Release(voice int) {
// Update // Update
func (s *C.Synth) Update(patch sointu.Patch) error { func (s *C.Synth) Update(patch sointu.Patch) error {
comPatch, err := compiler.Encode(&patch, compiler.AllFeatures{}) comPatch, err := compiler.Encode(patch, compiler.AllFeatures{})
if err != nil { if err != nil {
return fmt.Errorf("error compiling patch: %v", err) return fmt.Errorf("error compiling patch: %v", err)
} }

View File

@ -29,8 +29,7 @@ const su_max_samples = SAMPLES_PER_ROW * TOTAL_ROWS
// const bufsize = su_max_samples * 2 // const bufsize = su_max_samples * 2
func TestOscillatSine(t *testing.T) { func TestOscillatSine(t *testing.T) {
patch := sointu.Patch{ patch := sointu.Patch{sointu.Instrument{NumVoices: 1, Units: []sointu.Unit{
Instruments: []sointu.Instrument{sointu.Instrument{NumVoices: 1, Units: []sointu.Unit{
sointu.Unit{Type: "envelope", Parameters: map[string]int{"stereo": 0, "attack": 32, "decay": 32, "sustain": 64, "release": 64, "gain": 128}}, sointu.Unit{Type: "envelope", Parameters: map[string]int{"stereo": 0, "attack": 32, "decay": 32, "sustain": 64, "release": 64, "gain": 128}},
sointu.Unit{Type: "oscillator", Parameters: map[string]int{"stereo": 0, "transpose": 64, "detune": 64, "phase": 0, "color": 96, "shape": 64, "gain": 128, "type": sointu.Sine, "lfo": 0, "unison": 0}}, sointu.Unit{Type: "oscillator", Parameters: map[string]int{"stereo": 0, "transpose": 64, "detune": 64, "phase": 0, "color": 96, "shape": 64, "gain": 128, "type": sointu.Sine, "lfo": 0, "unison": 0}},
sointu.Unit{Type: "mulp", Parameters: map[string]int{"stereo": 0}}, sointu.Unit{Type: "mulp", Parameters: map[string]int{"stereo": 0}},
@ -38,9 +37,9 @@ func TestOscillatSine(t *testing.T) {
sointu.Unit{Type: "oscillator", Parameters: map[string]int{"stereo": 0, "transpose": 72, "detune": 64, "phase": 64, "color": 64, "shape": 96, "gain": 128, "type": sointu.Sine, "lfo": 0, "unison": 0}}, sointu.Unit{Type: "oscillator", Parameters: map[string]int{"stereo": 0, "transpose": 72, "detune": 64, "phase": 64, "color": 64, "shape": 96, "gain": 128, "type": sointu.Sine, "lfo": 0, "unison": 0}},
sointu.Unit{Type: "mulp", Parameters: map[string]int{"stereo": 0}}, sointu.Unit{Type: "mulp", Parameters: map[string]int{"stereo": 0}},
sointu.Unit{Type: "out", Parameters: map[string]int{"stereo": 1, "gain": 128}}, sointu.Unit{Type: "out", Parameters: map[string]int{"stereo": 1, "gain": 128}},
}}}} }}}
tracks := []sointu.Track{{NumVoices: 1, Sequence: []byte{0}, Patterns: [][]byte{{64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0}}}} tracks := []sointu.Track{{NumVoices: 1, Order: []int{0}, Patterns: [][]byte{{64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0}}}}
song := sointu.Song{BPM: 100, RowsPerPattern: 16, RowsPerBeat: 4, Tracks: tracks, Patch: patch} song := sointu.Song{BPM: 100, RowsPerBeat: 4, Score: sointu.Score{RowsPerPattern: 16, Length: 1, Tracks: tracks}, Patch: patch}
synth, err := bridge.Synth(patch) synth, err := bridge.Synth(patch)
if err != nil { if err != nil {
t.Fatalf("Compiling patch failed: %v", err) t.Fatalf("Compiling patch failed: %v", err)
@ -53,13 +52,11 @@ func TestOscillatSine(t *testing.T) {
} }
func TestRenderSamples(t *testing.T) { func TestRenderSamples(t *testing.T) {
patch := sointu.Patch{ patch := sointu.Patch{sointu.Instrument{NumVoices: 1, Units: []sointu.Unit{
Instruments: []sointu.Instrument{
sointu.Instrument{NumVoices: 1, Units: []sointu.Unit{
sointu.Unit{Type: "envelope", Parameters: map[string]int{"stereo": 0, "attack": 64, "decay": 64, "sustain": 64, "release": 80, "gain": 128}}, sointu.Unit{Type: "envelope", Parameters: map[string]int{"stereo": 0, "attack": 64, "decay": 64, "sustain": 64, "release": 80, "gain": 128}},
sointu.Unit{Type: "envelope", Parameters: map[string]int{"stereo": 0, "attack": 95, "decay": 64, "sustain": 64, "release": 80, "gain": 128}}, sointu.Unit{Type: "envelope", Parameters: map[string]int{"stereo": 0, "attack": 95, "decay": 64, "sustain": 64, "release": 80, "gain": 128}},
sointu.Unit{Type: "out", Parameters: map[string]int{"stereo": 1, "gain": 128}}, sointu.Unit{Type: "out", Parameters: map[string]int{"stereo": 1, "gain": 128}},
}}}} }}}
synth, err := bridge.Synth(patch) synth, err := bridge.Synth(patch)
if err != nil { if err != nil {
@ -107,7 +104,7 @@ func TestAllRegressionTests(t *testing.T) {
t.Fatalf("Compiling patch failed: %v", err) t.Fatalf("Compiling patch failed: %v", err)
} }
buffer, err := sointu.Play(synth, song) buffer, err := sointu.Play(synth, song)
buffer = buffer[:song.TotalRows()*song.SamplesPerRow()*2] // extend to the nominal length always. buffer = buffer[:song.Score.LengthInRows()*song.SamplesPerRow()*2] // extend to the nominal length always.
if err != nil { if err != nil {
t.Fatalf("Play failed: %v", err) t.Fatalf("Play failed: %v", err)
} }
@ -138,11 +135,9 @@ func TestAllRegressionTests(t *testing.T) {
} }
func TestStackUnderflow(t *testing.T) { func TestStackUnderflow(t *testing.T) {
patch := sointu.Patch{ patch := sointu.Patch{sointu.Instrument{NumVoices: 1, Units: []sointu.Unit{
Instruments: []sointu.Instrument{
sointu.Instrument{NumVoices: 1, Units: []sointu.Unit{
sointu.Unit{Type: "pop", Parameters: map[string]int{}}, sointu.Unit{Type: "pop", Parameters: map[string]int{}},
}}}} }}}
synth, err := bridge.Synth(patch) synth, err := bridge.Synth(patch)
if err != nil { if err != nil {
t.Fatalf("bridge compile error: %v", err) t.Fatalf("bridge compile error: %v", err)
@ -156,10 +151,9 @@ func TestStackUnderflow(t *testing.T) {
func TestStackBalancing(t *testing.T) { func TestStackBalancing(t *testing.T) {
patch := sointu.Patch{ patch := sointu.Patch{
Instruments: []sointu.Instrument{
sointu.Instrument{NumVoices: 1, Units: []sointu.Unit{ sointu.Instrument{NumVoices: 1, Units: []sointu.Unit{
sointu.Unit{Type: "push", Parameters: map[string]int{}}, sointu.Unit{Type: "push", Parameters: map[string]int{}},
}}}} }}}
synth, err := bridge.Synth(patch) synth, err := bridge.Synth(patch)
if err != nil { if err != nil {
t.Fatalf("bridge compile error: %v", err) t.Fatalf("bridge compile error: %v", err)
@ -173,7 +167,6 @@ func TestStackBalancing(t *testing.T) {
func TestStackOverflow(t *testing.T) { func TestStackOverflow(t *testing.T) {
patch := sointu.Patch{ patch := sointu.Patch{
Instruments: []sointu.Instrument{
sointu.Instrument{NumVoices: 1, Units: []sointu.Unit{ sointu.Instrument{NumVoices: 1, Units: []sointu.Unit{
sointu.Unit{Type: "loadval", Parameters: map[string]int{"value": 128}}, sointu.Unit{Type: "loadval", Parameters: map[string]int{"value": 128}},
sointu.Unit{Type: "loadval", Parameters: map[string]int{"value": 128}}, sointu.Unit{Type: "loadval", Parameters: map[string]int{"value": 128}},
@ -193,7 +186,7 @@ func TestStackOverflow(t *testing.T) {
sointu.Unit{Type: "pop", Parameters: map[string]int{}}, sointu.Unit{Type: "pop", Parameters: map[string]int{}},
sointu.Unit{Type: "pop", Parameters: map[string]int{}}, sointu.Unit{Type: "pop", Parameters: map[string]int{}},
sointu.Unit{Type: "pop", Parameters: map[string]int{}}, sointu.Unit{Type: "pop", Parameters: map[string]int{}},
}}}} }}}
synth, err := bridge.Synth(patch) synth, err := bridge.Synth(patch)
if err != nil { if err != nil {
t.Fatalf("bridge compile error: %v", err) t.Fatalf("bridge compile error: %v", err)
@ -206,13 +199,11 @@ func TestStackOverflow(t *testing.T) {
} }
func TestDivideByZero(t *testing.T) { func TestDivideByZero(t *testing.T) {
patch := sointu.Patch{ patch := sointu.Patch{sointu.Instrument{NumVoices: 1, Units: []sointu.Unit{
Instruments: []sointu.Instrument{
sointu.Instrument{NumVoices: 1, Units: []sointu.Unit{
sointu.Unit{Type: "loadval", Parameters: map[string]int{"value": 128}}, sointu.Unit{Type: "loadval", Parameters: map[string]int{"value": 128}},
sointu.Unit{Type: "invgain", Parameters: map[string]int{"invgain": 0}}, sointu.Unit{Type: "invgain", Parameters: map[string]int{"invgain": 0}},
sointu.Unit{Type: "pop", Parameters: map[string]int{}}, sointu.Unit{Type: "pop", Parameters: map[string]int{}},
}}}} }}}
synth, err := bridge.Synth(patch) synth, err := bridge.Synth(patch)
if err != nil { if err != nil {
t.Fatalf("bridge compile error: %v", err) t.Fatalf("bridge compile error: %v", err)

View File

@ -122,6 +122,9 @@ func main() {
if song.RowsPerBeat == 0 { if song.RowsPerBeat == 0 {
song.RowsPerBeat = 4 song.RowsPerBeat = 4
} }
if song.Score.Length == 0 {
song.Score.Length = len(song.Score.Tracks[0].Patterns)
}
var compiledPlayer map[string]string var compiledPlayer map[string]string
if compile { if compile {
var err error var err error

View File

@ -125,7 +125,7 @@ func main() {
fmt.Fprintln(outputFile, "// Code generated by go generate; DO NOT EDIT.") fmt.Fprintln(outputFile, "// Code generated by go generate; DO NOT EDIT.")
fmt.Fprintln(outputFile, "package tracker") fmt.Fprintln(outputFile, "package tracker")
fmt.Fprintln(outputFile, "") fmt.Fprintln(outputFile, "")
fmt.Fprintln(outputFile, "var gmDlsEntries = []GmDlsEntry{") fmt.Fprintln(outputFile, "var GmDlsEntries = []GmDlsEntry{")
readChunk(0, inputFile, &gmDlsVisitor{outputFile: outputFile}) readChunk(0, inputFile, &gmDlsVisitor{outputFile: outputFile})
fmt.Fprintln(outputFile, "}") fmt.Fprintln(outputFile, "}")
} }

View File

@ -4,11 +4,9 @@ import (
"fmt" "fmt"
"os" "os"
"gioui.org/app"
"gioui.org/unit"
"github.com/vsariola/sointu/bridge" "github.com/vsariola/sointu/bridge"
"github.com/vsariola/sointu/oto" "github.com/vsariola/sointu/oto"
"github.com/vsariola/sointu/tracker" "github.com/vsariola/sointu/tracker/gioui"
) )
func main() { func main() {
@ -19,18 +17,5 @@ func main() {
} }
defer audioContext.Close() defer audioContext.Close()
synthService := bridge.BridgeService{} synthService := bridge.BridgeService{}
go func() { gioui.Main(audioContext, synthService)
w := app.NewWindow(
app.Size(unit.Dp(800), unit.Dp(600)),
app.Title("Sointu Tracker"),
)
t := tracker.New(audioContext, synthService)
defer t.Close()
if err := t.Run(w); err != nil {
fmt.Println(err)
os.Exit(1)
}
os.Exit(0)
}()
app.Main()
} }

View File

@ -82,7 +82,7 @@ func (com *Compiler) Song(song *sointu.Song) (map[string]string, error) {
} }
features := NecessaryFeaturesFor(song.Patch) features := NecessaryFeaturesFor(song.Patch)
retmap := map[string]string{} retmap := map[string]string{}
encodedPatch, err := Encode(&song.Patch, features) encodedPatch, err := Encode(song.Patch, features)
if err != nil { if err != nil {
return nil, fmt.Errorf(`could not encode patch: %v`, err) return nil, fmt.Errorf(`could not encode patch: %v`, err)
} }

View File

@ -22,16 +22,22 @@ type SampleOffset struct {
LoopLength uint16 LoopLength uint16
} }
func Encode(patch *sointu.Patch, featureSet FeatureSet) (*EncodedPatch, error) { func Encode(patch sointu.Patch, featureSet FeatureSet) (*EncodedPatch, error) {
var c EncodedPatch var c EncodedPatch
sampleOffsetMap := map[SampleOffset]int{} sampleOffsetMap := map[SampleOffset]int{}
for instrIndex, instr := range patch.Instruments { globalAddrs := map[int]uint16{}
globalFixups := map[int]([]int){}
voiceNo := 0
for instrIndex, instr := range patch {
if len(instr.Units) > 63 { if len(instr.Units) > 63 {
return nil, errors.New("An instrument can have a maximum of 63 units") return nil, errors.New("An instrument can have a maximum of 63 units")
} }
if instr.NumVoices < 1 { if instr.NumVoices < 1 {
return nil, errors.New("Each instrument must have at least 1 voice") return nil, errors.New("Each instrument must have at least 1 voice")
} }
localAddrs := map[int]uint16{}
localFixups := map[int]([]int){}
localUnitNo := 0
for _, unit := range instr.Units { for _, unit := range instr.Units {
if unit.Type == "" { // empty units are just ignored & skipped if unit.Type == "" { // empty units are just ignored & skipped
continue continue
@ -113,44 +119,62 @@ func Encode(patch *sointu.Patch, featureSet FeatureSet) (*EncodedPatch, error) {
} }
values = append(values, byte(flags)) values = append(values, byte(flags))
} else if unit.Type == "send" { } else if unit.Type == "send" {
targetID := unit.Parameters["target"]
targetInstrIndex, _, err := patch.FindSendTarget(targetID)
targetVoice := unit.Parameters["voice"] targetVoice := unit.Parameters["voice"]
var targetInstrument int var addr uint16 = uint16(unit.Parameters["port"]) & 7
if targetVoice == 0 {
targetInstrument = instrIndex
} else {
var err error
targetInstrument, err = patch.InstrumentForVoice(targetVoice - 1)
if err != nil {
return nil, fmt.Errorf("send targeted a voice %v, which out of the range of instruments", targetVoice-1)
}
}
origTarget := unit.Parameters["unit"]
targetUnit := origTarget
for k := 0; k < origTarget; k++ {
units := patch.Instruments[targetInstrument].Units
if k >= len(units) {
break
}
if units[k].Type == "" {
targetUnit--
}
}
address := ((targetUnit + 1) << 4) + unit.Parameters["port"] // each unit is 16 dwords, 8 workspace followed by 8 ports. +1 is for skipping the note/release/inputs
if unit.Parameters["voice"] > 0 {
address += 0x8000 + 16 + (unit.Parameters["voice"]-1)*1024 // global send, +16 is for skipping the out/aux ports
}
if unit.Parameters["sendpop"] == 1 { if unit.Parameters["sendpop"] == 1 {
address += 0x8 addr += 0x8
} }
values = append(values, byte(address&255), byte(address>>8))
if err == nil {
// local send is only possible if targetVoice is "auto" (0) and
// the targeted unit is in the same instrument as send
if targetInstrIndex == instrIndex && targetVoice == 0 {
if v, ok := localAddrs[targetID]; ok {
addr += v
} else {
localFixups[targetID] = append(localFixups[targetID], len(c.Values)+len(values))
}
} else {
addr += 0x8000
if targetVoice > 0 { // "auto" (0) means for global send that it targets voice 0 of that instrument
addr += uint16((targetVoice - 1) * 0x400)
}
if v, ok := globalAddrs[targetID]; ok {
addr += v
} else {
globalFixups[targetID] = append(globalFixups[targetID], len(c.Values)+len(values))
}
}
} else {
// if no target will be found, the send will trash some of
// the last values of the last port of the last voice, which
// is unlikely to cause issues. We still honor the POP bit.
addr &= 0x8
addr |= 0xFFF7
}
values = append(values, byte(addr&255), byte(addr>>8))
} else if unit.Type == "delay" { } else if unit.Type == "delay" {
countTrack := (unit.Parameters["count"] << 1) - 1 + unit.Parameters["notetracking"] // 1 means no note tracking and 1 delay, 2 means notetracking with 1 delay, 3 means no note tracking and 2 delays etc. countTrack := (unit.Parameters["count"] << 1) - 1 + unit.Parameters["notetracking"] // 1 means no note tracking and 1 delay, 2 means notetracking with 1 delay, 3 means no note tracking and 2 delays etc.
values = append(values, byte(unit.Parameters["delay"]), byte(countTrack)) values = append(values, byte(unit.Parameters["delay"]), byte(countTrack))
} }
c.Commands = append(c.Commands, byte(opcode+unit.Parameters["stereo"])) c.Commands = append(c.Commands, byte(opcode+unit.Parameters["stereo"]))
c.Values = append(c.Values, values...) c.Values = append(c.Values, values...)
if unit.ID != 0 {
localAddr := uint16((localUnitNo + 1) << 4)
fixUp(c.Values, localFixups[unit.ID], localAddr)
localFixups[unit.ID] = nil
localAddrs[unit.ID] = localAddr
globalAddr := localAddr + 16 + uint16(voiceNo)*1024
fixUp(c.Values, globalFixups[unit.ID], globalAddr)
globalFixups[unit.ID] = nil
globalAddrs[unit.ID] = globalAddr
}
localUnitNo++ // a command in command stream means the wrkspace addr gets also increased
} }
c.Commands = append(c.Commands, byte(0)) // advance c.Commands = append(c.Commands, byte(0)) // advance
voiceNo += instr.NumVoices
c.NumVoices += uint32(instr.NumVoices) c.NumVoices += uint32(instr.NumVoices)
for k := 0; k < instr.NumVoices-1; k++ { for k := 0; k < instr.NumVoices-1; k++ {
c.PolyphonyBitmask = (c.PolyphonyBitmask << 1) + 1 c.PolyphonyBitmask = (c.PolyphonyBitmask << 1) + 1
@ -163,3 +187,12 @@ func Encode(patch *sointu.Patch, featureSet FeatureSet) (*EncodedPatch, error) {
return &c, nil return &c, nil
} }
func fixUp(values []byte, positions []int, delta uint16) {
for _, pos := range positions {
orig := (uint16(values[pos+1]) << 8) + uint16(values[pos])
new := orig + delta
values[pos] = byte(new & 255)
values[pos+1] = byte(new >> 8)
}
}

View File

@ -17,6 +17,7 @@ type FeatureSet interface {
SupportsParamValueOtherThan(unitType string, paramName string, value int) bool SupportsParamValueOtherThan(unitType string, paramName string, value int) bool
SupportsModulation(unitType string, paramName string) bool SupportsModulation(unitType string, paramName string) bool
SupportsPolyphony() bool SupportsPolyphony() bool
SupportsGlobalSend() bool
} }
type Instruction struct { type Instruction struct {
@ -58,6 +59,10 @@ func (_ AllFeatures) SupportsPolyphony() bool {
return true return true
} }
func (_ AllFeatures) SupportsGlobalSend() bool {
return true
}
func (_ AllFeatures) Opcode(unitType string) (int, bool) { func (_ AllFeatures) Opcode(unitType string) (int, bool) {
code, ok := allOpcodes[unitType] code, ok := allOpcodes[unitType]
return code, ok return code, ok
@ -114,12 +119,13 @@ type NecessaryFeatures struct {
instructions []string instructions []string
supportsParamValue map[paramKey](map[int]bool) supportsParamValue map[paramKey](map[int]bool)
supportsModulation map[paramKey]bool supportsModulation map[paramKey]bool
globalSend bool
polyphony bool polyphony bool
} }
func NecessaryFeaturesFor(patch sointu.Patch) NecessaryFeatures { func NecessaryFeaturesFor(patch sointu.Patch) NecessaryFeatures {
features := NecessaryFeatures{opcodes: map[string]int{}, supportsParamValue: map[paramKey](map[int]bool){}, supportsModulation: map[paramKey]bool{}} features := NecessaryFeatures{opcodes: map[string]int{}, supportsParamValue: map[paramKey](map[int]bool){}, supportsModulation: map[paramKey]bool{}}
for instrNo, instrument := range patch.Instruments { for instrIndex, instrument := range patch {
for _, unit := range instrument.Units { for _, unit := range instrument.Units {
if _, ok := features.opcodes[unit.Type]; !ok { if _, ok := features.opcodes[unit.Type]; !ok {
features.instructions = append(features.instructions, unit.Type) features.instructions = append(features.instructions, unit.Type)
@ -133,27 +139,20 @@ func NecessaryFeaturesFor(patch sointu.Patch) NecessaryFeatures {
features.supportsParamValue[key][v] = true features.supportsParamValue[key][v] = true
} }
if unit.Type == "send" { if unit.Type == "send" {
targetInstrument := instrNo targetInstrIndex, targetUnitIndex, err := patch.FindSendTarget(unit.Parameters["target"])
if unit.Parameters["voice"] > 0 {
v, err := patch.InstrumentForVoice(unit.Parameters["voice"] - 1)
if err != nil { if err != nil {
continue continue
} }
targetInstrument = v targetUnit := patch[targetInstrIndex].Units[targetUnitIndex]
} portList := sointu.Ports[targetUnit.Type]
if unit.Parameters["unit"] < 0 || unit.Parameters["unit"] >= len(patch.Instruments[targetInstrument].Units) { portIndex := unit.Parameters["port"]
continue // send is modulating outside the range of the target instrument; probably a bug in patch, but at least it's not modulating the uniType we're after if portIndex < 0 || portIndex >= len(portList) {
} continue
targetUnit := patch.Instruments[targetInstrument].Units[unit.Parameters["unit"]]
modulatedPortNo := 0
for _, v := range sointu.UnitTypes[targetUnit.Type] {
if v.CanModulate {
if modulatedPortNo == unit.Parameters["port"] {
features.supportsModulation[paramKey{targetUnit.Type, v.Name}] = true
}
modulatedPortNo++
} }
if targetInstrIndex != instrIndex || unit.Parameters["voice"] > 0 {
features.globalSend = true
} }
features.supportsModulation[paramKey{targetUnit.Type, portList[portIndex]}] = true
} }
} }
if instrument.NumVoices > 1 { if instrument.NumVoices > 1 {
@ -204,3 +203,7 @@ func (n NecessaryFeatures) InputNumber(unitType string, paramName string) int {
func (_ NecessaryFeatures) TransformCount(unitType string) int { func (_ NecessaryFeatures) TransformCount(unitType string) int {
return allTransformCounts[unitType] return allTransformCounts[unitType]
} }
func (n NecessaryFeatures) SupportsGlobalSend() bool {
return n.globalSend
}

View File

@ -32,11 +32,17 @@ func fixPatternLength(patterns [][]byte, fixedLength int) [][]int {
func flattenSequence(patterns [][]int, sequence []int) []int { func flattenSequence(patterns [][]int, sequence []int) []int {
sumLen := 0 sumLen := 0
for _, patIndex := range sequence { for _, patIndex := range sequence {
if patIndex < 0 || patIndex >= len(patterns) {
continue
}
sumLen += len(patterns[patIndex]) sumLen += len(patterns[patIndex])
} }
notes := make([]int, sumLen) notes := make([]int, sumLen)
window := notes window := notes
for _, patIndex := range sequence { for _, patIndex := range sequence {
if patIndex < 0 || patIndex >= len(patterns) {
continue
}
elementsCopied := copy(window, patterns[patIndex]) elementsCopied := copy(window, patterns[patIndex])
window = window[elementsCopied:] window = window[elementsCopied:]
} }
@ -167,12 +173,12 @@ func bytesToInts(array []byte) []int {
} }
func ConstructPatterns(song *sointu.Song) ([][]byte, [][]byte, error) { func ConstructPatterns(song *sointu.Song) ([][]byte, [][]byte, error) {
patLength := song.RowsPerPattern patLength := song.Score.RowsPerPattern
sequences := make([][]byte, len(song.Tracks)) sequences := make([][]byte, len(song.Score.Tracks))
var patterns [][]int var patterns [][]int
for i, t := range song.Tracks { for i, t := range song.Score.Tracks {
fixed := fixPatternLength(t.Patterns, patLength) fixed := fixPatternLength(t.Patterns, patLength)
flat := flattenSequence(fixed, bytesToInts(t.Sequence)) flat := flattenSequence(fixed, t.Order)
dontCares := markDontCares(flat) dontCares := markDontCares(flat)
// TODO: we could give the user the possibility to use another length during encoding that during composing // TODO: we could give the user the possibility to use another length during encoding that during composing
chunks := splitSequence(dontCares, patLength) chunks := splitSequence(dontCares, patLength)

View File

@ -10,14 +10,16 @@ import (
func TestPatternReusing(t *testing.T) { func TestPatternReusing(t *testing.T) {
song := sointu.Song{ song := sointu.Song{
Score: sointu.Score{
RowsPerPattern: 8, RowsPerPattern: 8,
Tracks: []sointu.Track{{ Tracks: []sointu.Track{{
Patterns: [][]byte{{64, 1, 1, 1, 0, 0, 0, 0}, {72, 0, 0, 0, 0, 0, 0, 0}}, Patterns: [][]byte{{64, 1, 1, 1, 0, 0, 0, 0}, {72, 0, 0, 0, 0, 0, 0, 0}},
Sequence: []byte{0, 1}, Order: []int{0, 1},
}, { }, {
Patterns: [][]byte{{64, 1, 1, 1, 0, 0, 0, 0}, {84, 0, 0, 0, 0, 0, 0, 0}}, Patterns: [][]byte{{64, 1, 1, 1, 0, 0, 0, 0}, {84, 0, 0, 0, 0, 0, 0, 0}},
Sequence: []byte{0, 1}, Order: []int{0, 1},
}}, }},
},
} }
patterns, sequences, err := compiler.ConstructPatterns(&song) patterns, sequences, err := compiler.ConstructPatterns(&song)
if err != nil { if err != nil {
@ -35,14 +37,15 @@ func TestPatternReusing(t *testing.T) {
func TestUnnecessaryHolds(t *testing.T) { func TestUnnecessaryHolds(t *testing.T) {
song := sointu.Song{ song := sointu.Song{
Score: sointu.Score{
RowsPerPattern: 8, RowsPerPattern: 8,
Tracks: []sointu.Track{{ Tracks: []sointu.Track{{
Patterns: [][]byte{{64, 1, 1, 1, 0, 1, 0, 0}, {72, 0, 1, 0, 1, 0, 0, 0}}, Patterns: [][]byte{{64, 1, 1, 1, 0, 1, 0, 0}, {72, 0, 1, 0, 1, 0, 0, 0}},
Sequence: []byte{0, 1}, Order: []int{0, 1},
}, { }, {
Patterns: [][]byte{{64, 1, 1, 1, 0, 0, 1, 0}, {84, 0, 0, 0, 1, 1, 0, 0}}, Patterns: [][]byte{{64, 1, 1, 1, 0, 0, 1, 0}, {84, 0, 0, 0, 1, 1, 0, 0}},
Sequence: []byte{0, 1}, Order: []int{0, 1},
}}, }}},
} }
patterns, sequences, err := compiler.ConstructPatterns(&song) patterns, sequences, err := compiler.ConstructPatterns(&song)
if err != nil { if err != nil {
@ -60,14 +63,17 @@ func TestUnnecessaryHolds(t *testing.T) {
func TestDontCares(t *testing.T) { func TestDontCares(t *testing.T) {
song := sointu.Song{ song := sointu.Song{
Score: sointu.Score{
Length: 2,
RowsPerPattern: 8, RowsPerPattern: 8,
Tracks: []sointu.Track{{ Tracks: []sointu.Track{{
Patterns: [][]byte{{64, 1, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}}, Patterns: [][]byte{{64, 1, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}},
Sequence: []byte{0, 1}, Order: []int{0, 1},
}, { }, {
Patterns: [][]byte{{64, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 0, 0, 0, 0, 0}}, Patterns: [][]byte{{64, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 0, 0, 0, 0, 0}},
Sequence: []byte{0, 1}, Order: []int{0, 1},
}}, }},
},
} }
patterns, sequences, err := compiler.ConstructPatterns(&song) patterns, sequences, err := compiler.ConstructPatterns(&song)
if err != nil { if err != nil {

View File

@ -13,10 +13,10 @@ type SongMacros struct {
} }
func NewSongMacros(s *sointu.Song) *SongMacros { func NewSongMacros(s *sointu.Song) *SongMacros {
maxSamples := s.SamplesPerRow() * s.TotalRows() maxSamples := s.SamplesPerRow() * s.Score.LengthInRows()
p := SongMacros{Song: s, MaxSamples: maxSamples} p := SongMacros{Song: s, MaxSamples: maxSamples}
trackVoiceNumber := 0 trackVoiceNumber := 0
for _, t := range s.Tracks { for _, t := range s.Score.Tracks {
for b := 0; b < t.NumVoices-1; b++ { for b := 0; b < t.NumVoices-1; b++ {
p.VoiceTrackBitmask += 1 << trackVoiceNumber p.VoiceTrackBitmask += 1 << trackVoiceNumber
trackVoiceNumber++ trackVoiceNumber++
@ -28,7 +28,7 @@ func NewSongMacros(s *sointu.Song) *SongMacros {
func (p *SongMacros) NumDelayLines() string { func (p *SongMacros) NumDelayLines() string {
total := 0 total := 0
for _, instr := range p.Song.Patch.Instruments { for _, instr := range p.Song.Patch {
for _, unit := range instr.Units { for _, unit := range instr.Units {
if unit.Type == "delay" { if unit.Type == "delay" {
total += unit.Parameters["count"] * (1 + unit.Parameters["stereo"]) total += unit.Parameters["count"] * (1 + unit.Parameters["stereo"])

16
instrument.go Normal file
View File

@ -0,0 +1,16 @@
package sointu
// Instrument includes a list of units consisting of the instrument, and the number of polyphonic voices for this instrument
type Instrument struct {
Name string `yaml:",omitempty"`
NumVoices int
Units []Unit
}
func (instr *Instrument) Copy() Instrument {
units := make([]Unit, len(instr.Units))
for i, u := range instr.Units {
units[i] = u.Copy()
}
return Instrument{Name: instr.Name, NumVoices: instr.NumVoices, Units: units}
}

150
patch.go Normal file
View File

@ -0,0 +1,150 @@
package sointu
import (
"errors"
"fmt"
"math"
)
// Patch is simply a list of instruments used in a song
type Patch []Instrument
func (p Patch) Copy() Patch {
instruments := make([]Instrument, len(p))
for i, instr := range p {
instruments[i] = instr.Copy()
}
return instruments
}
func (p Patch) NumVoices() int {
ret := 0
for _, i := range p {
ret += i.NumVoices
}
return ret
}
func (p Patch) FirstVoiceForInstrument(instrIndex int) int {
ret := 0
for _, t := range p[:instrIndex] {
ret += t.NumVoices
}
return ret
}
func (p Patch) InstrumentForVoice(voice int) (int, error) {
if voice < 0 {
return 0, errors.New("voice cannot be negative")
}
for i, instr := range p {
if voice < instr.NumVoices {
return i, nil
}
voice -= instr.NumVoices
}
return 0, errors.New("voice number is beyond the total voices of an instrument")
}
func (p Patch) FindSendTarget(id int) (int, int, error) {
if id == 0 {
return 0, 0, errors.New("send targets unit id 0")
}
for i, instr := range p {
for u, unit := range instr.Units {
if unit.ID == id {
return i, u, nil
}
}
}
return 0, 0, fmt.Errorf("send targets an unit with id %v, could not find a unit with such an ID in the patch", id)
}
func (p Patch) ParamHintString(instrIndex, unitIndex int, param string) string {
if instrIndex < 0 || instrIndex >= len(p) {
return ""
}
instr := p[instrIndex]
if unitIndex < 0 || unitIndex >= len(instr.Units) {
return ""
}
unit := instr.Units[unitIndex]
value := unit.Parameters[param]
switch unit.Type {
case "envelope":
switch param {
case "attack":
return engineeringTime(math.Pow(2, 24*float64(value)/128) / 44100)
case "decay":
return engineeringTime(math.Pow(2, 24*float64(value)/128) / 44100 * (1 - float64(unit.Parameters["sustain"])/128))
case "release":
return engineeringTime(math.Pow(2, 24*float64(value)/128) / 44100 * float64(unit.Parameters["sustain"]) / 128)
}
case "oscillator":
switch param {
case "type":
switch value {
case Sine:
return "Sine"
case Trisaw:
return "Trisaw"
case Pulse:
return "Pulse"
case Gate:
return "Gate"
case Sample:
return "Sample"
default:
return "Unknown"
}
case "transpose":
relvalue := value - 64
octaves := relvalue / 12
semitones := relvalue % 12
if octaves != 0 {
return fmt.Sprintf("%v oct, %v st", octaves, semitones)
}
return fmt.Sprintf("%v st", semitones)
case "detune":
return fmt.Sprintf("%v st", float32(value-64)/64.0)
}
case "compressor":
switch param {
case "attack":
fallthrough
case "release":
alpha := math.Pow(2, -24*float64(value)/128) // alpha is the "smoothing factor" of first order low pass iir
sec := -1 / (44100 * math.Log(1-alpha)) // from smoothing factor to time constant, https://en.wikipedia.org/wiki/Exponential_smoothing
return engineeringTime(sec)
case "ratio":
return fmt.Sprintf("1 : %.3f", 1-float64(value)/128)
}
case "send":
switch param {
case "voice":
if value == 0 {
return "auto"
}
return fmt.Sprintf("%v", value)
case "target":
instrIndex, unitIndex, err := p.FindSendTarget(unit.Parameters["target"])
if err != nil {
return "invalid target"
}
instr := p[instrIndex]
unit := instr.Units[unitIndex]
return fmt.Sprintf("%v / %v%v", instr.Name, unit.Type, unitIndex)
case "port":
instrIndex, unitIndex, err := p.FindSendTarget(unit.Parameters["target"])
if err != nil {
return fmt.Sprintf("%v ???", value)
}
portList := Ports[p[instrIndex].Units[unitIndex].Type]
if value < 0 || value >= len(portList) {
return fmt.Sprintf("%v ???", value)
}
return fmt.Sprintf(portList[value])
}
}
return ""
}

35
score.go Normal file
View File

@ -0,0 +1,35 @@
package sointu
type Score struct {
Tracks []Track
RowsPerPattern int
Length int // length of the song, in number of patterns
}
func (l Score) Copy() Score {
tracks := make([]Track, len(l.Tracks))
for i, t := range l.Tracks {
tracks[i] = t.Copy()
}
return Score{Tracks: tracks, RowsPerPattern: l.RowsPerPattern, Length: l.Length}
}
func (l Score) NumVoices() int {
ret := 0
for _, t := range l.Tracks {
ret += t.NumVoices
}
return ret
}
func (l Score) FirstVoiceForTrack(track int) int {
ret := 0
for _, t := range l.Tracks[:track] {
ret += t.NumVoices
}
return ret
}
func (l Score) LengthInRows() int {
return l.RowsPerPattern * l.Length
}

587
sointu.go
View File

@ -1,587 +0,0 @@
package sointu
import (
"errors"
"fmt"
"math"
)
// Unit is e.g. a filter, oscillator, envelope and its parameters
type Unit struct {
Type string
Parameters map[string]int `yaml:",flow"`
VarArgs []int `yaml:",flow,omitempty"`
}
func (u *Unit) Copy() Unit {
parameters := make(map[string]int)
for k, v := range u.Parameters {
parameters[k] = v
}
varArgs := make([]int, len(u.VarArgs))
copy(varArgs, u.VarArgs)
return Unit{Type: u.Type, Parameters: parameters, VarArgs: varArgs}
}
const (
Sine = iota
Trisaw = iota
Pulse = iota
Gate = iota
Sample = iota
)
// Instrument includes a list of units consisting of the instrument, and the number of polyphonic voices for this instrument
type Instrument struct {
Name string
NumVoices int
Units []Unit
}
func (instr *Instrument) Copy() Instrument {
units := make([]Unit, len(instr.Units))
for i, u := range instr.Units {
units[i] = u.Copy()
}
return Instrument{Name: instr.Name, NumVoices: instr.NumVoices, Units: units}
}
// Patch is simply a list of instruments used in a song
type Patch struct {
Instruments []Instrument
}
func (p *Patch) Copy() Patch {
instruments := make([]Instrument, len(p.Instruments))
for i, instr := range p.Instruments {
instruments[i] = instr.Copy()
}
return Patch{Instruments: instruments}
}
func (p Patch) TotalVoices() int {
ret := 0
for _, i := range p.Instruments {
ret += i.NumVoices
}
return ret
}
func (patch Patch) InstrumentForVoice(voice int) (int, error) {
if voice < 0 {
return 0, errors.New("voice cannot be negative")
}
for i, instr := range patch.Instruments {
if voice < instr.NumVoices {
return i, nil
} else {
voice -= instr.NumVoices
}
}
return 0, errors.New("voice number is beyond the total voices of an instrument")
}
type Track struct {
NumVoices int
Sequence []byte `yaml:",flow"`
Patterns [][]byte `yaml:",flow"`
}
func (t *Track) Copy() Track {
sequence := make([]byte, len(t.Sequence))
copy(sequence, t.Sequence)
patterns := make([][]byte, len(t.Patterns))
for i, oldPat := range t.Patterns {
newPat := make([]byte, len(oldPat))
copy(newPat, oldPat)
patterns[i] = newPat
}
return Track{
NumVoices: t.NumVoices,
Sequence: sequence,
Patterns: patterns,
}
}
type Synth interface {
Render(buffer []float32, maxtime int) (int, int, error)
Update(patch Patch) error
Trigger(voice int, note byte)
Release(voice int)
}
func Render(synth Synth, buffer []float32) error {
s, _, err := synth.Render(buffer, math.MaxInt32)
if err != nil {
return fmt.Errorf("sointu.Render failed: %v", err)
}
if s != len(buffer)/2 {
return errors.New("in sointu.Render, synth.Render should have filled the whole buffer but did not")
}
return nil
}
type SynthService interface {
Compile(patch Patch) (Synth, error)
}
type AudioSink interface {
WriteAudio(buffer []float32) (err error)
Close() error
}
type AudioSource interface {
ReadAudio(buffer []float32) (n int, err error)
Close() error
}
type AudioContext interface {
Output() AudioSink
Close() error
}
// UnitParameter documents one parameter that an unit takes
type UnitParameter struct {
Name string // thould be found with this name in the Unit.Parameters map
MinValue int // minimum value of the parameter, inclusive
MaxValue int // maximum value of the parameter, inclusive
CanSet bool // if this parameter can be set before hand i.e. through the gui
CanModulate bool // if this parameter can be modulated i.e. has a port number in "send" unit
}
func engineeringTime(sec float64) string {
if sec < 1e-3 {
return fmt.Sprintf("%.2f us", sec*1e6)
} else if sec < 1 {
return fmt.Sprintf("%.2f ms", sec*1e3)
}
return fmt.Sprintf("%.2f s", sec)
}
// UnitTypes documents all the available unit types and if they support stereo variant
// and what parameters they take.
var UnitTypes = map[string]([]UnitParameter){
"add": []UnitParameter{{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false}},
"addp": []UnitParameter{{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false}},
"pop": []UnitParameter{{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false}},
"loadnote": []UnitParameter{{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false}},
"mul": []UnitParameter{{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false}},
"mulp": []UnitParameter{{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false}},
"push": []UnitParameter{{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false}},
"xch": []UnitParameter{{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false}},
"distort": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "drive", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true}},
"hold": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "holdfreq", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true}},
"crush": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "resolution", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true}},
"gain": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "gain", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true}},
"invgain": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "invgain", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true}},
"filter": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "frequency", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "resonance", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "lowpass", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "bandpass", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "highpass", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "negbandpass", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "neghighpass", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false}},
"clip": []UnitParameter{{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false}},
"pan": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "panning", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true}},
"delay": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "pregain", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "dry", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "feedback", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "damp", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "notetracking", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "delaytime", MinValue: 0, MaxValue: -1, CanSet: false, CanModulate: true}},
"compressor": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "attack", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "release", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "invgain", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "threshold", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "ratio", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true}},
"speed": []UnitParameter{},
"out": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "gain", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true}},
"outaux": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "outgain", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "auxgain", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true}},
"aux": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "gain", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "channel", MinValue: 0, MaxValue: 6, CanSet: true, CanModulate: false}},
"send": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "amount", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "voice", MinValue: 0, MaxValue: 32, CanSet: true, CanModulate: false},
{Name: "unit", MinValue: 0, MaxValue: 63, CanSet: true, CanModulate: false},
{Name: "port", MinValue: 0, MaxValue: 7, CanSet: true, CanModulate: false},
{Name: "sendpop", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false}},
"envelope": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "attack", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "decay", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "sustain", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "release", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "gain", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true}},
"noise": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "shape", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "gain", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true}},
"oscillator": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "transpose", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "detune", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "phase", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "color", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "shape", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "gain", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true},
{Name: "type", MinValue: int(Sine), MaxValue: int(Sample), CanSet: true, CanModulate: false},
{Name: "lfo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "unison", MinValue: 0, MaxValue: 3, CanSet: true, CanModulate: false},
{Name: "samplestart", MinValue: 0, MaxValue: 1720329, CanSet: true, CanModulate: false},
{Name: "loopstart", MinValue: 0, MaxValue: 65535, CanSet: true, CanModulate: false},
{Name: "looplength", MinValue: 0, MaxValue: 65535, CanSet: true, CanModulate: false}},
"loadval": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "value", MinValue: 0, MaxValue: 128, CanSet: true, CanModulate: true}},
"receive": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "left", MinValue: 0, MaxValue: -1, CanSet: false, CanModulate: true},
{Name: "right", MinValue: 0, MaxValue: -1, CanSet: false, CanModulate: true}},
"in": []UnitParameter{
{Name: "stereo", MinValue: 0, MaxValue: 1, CanSet: true, CanModulate: false},
{Name: "channel", MinValue: 0, MaxValue: 6, CanSet: true, CanModulate: false}},
}
var Ports = make(map[string]([]string))
func init() {
for name, unitType := range UnitTypes {
unitPorts := make([]string, 0)
for _, param := range unitType {
if param.CanModulate {
unitPorts = append(unitPorts, param.Name)
}
}
Ports[name] = unitPorts
}
}
type Song struct {
BPM int
RowsPerPattern int
RowsPerBeat int
Tracks []Track
Patch Patch
}
func (s *Song) Copy() Song {
tracks := make([]Track, len(s.Tracks))
for i, t := range s.Tracks {
tracks[i] = t.Copy()
}
return Song{BPM: s.BPM, RowsPerPattern: s.RowsPerPattern, RowsPerBeat: s.RowsPerBeat, Tracks: tracks, Patch: s.Patch.Copy()}
}
func (s *Song) SequenceLength() int {
return len(s.Tracks[0].Sequence)
}
func (s *Song) TotalRows() int {
return s.RowsPerPattern * s.SequenceLength()
}
func (s *Song) SamplesPerRow() int {
return 44100 * 60 / (s.BPM * s.RowsPerBeat)
}
func (s *Song) FirstTrackVoice(track int) int {
ret := 0
for _, t := range s.Tracks[:track] {
ret += t.NumVoices
}
return ret
}
func (s *Song) FirstInstrumentVoice(instrument int) int {
ret := 0
for _, i := range s.Patch.Instruments[:instrument] {
ret += i.NumVoices
}
return ret
}
func (s *Song) TotalTrackVoices() int {
ret := 0
for _, t := range s.Tracks {
ret += t.NumVoices
}
return ret
}
// TBD: Where shall we put methods that work on pure domain types and have no dependencies
// e.g. Validate here
func (s *Song) Validate() error {
if s.BPM < 1 {
return errors.New("BPM should be > 0")
}
var patternLen int
for i, t := range s.Tracks {
for j, pat := range t.Patterns {
if i == 0 && j == 0 {
patternLen = len(pat)
} else {
if len(pat) != patternLen {
return errors.New("Every pattern should have the same length")
}
}
}
}
for i := range s.Tracks[:len(s.Tracks)-1] {
if len(s.Tracks[i].Sequence) != len(s.Tracks[i+1].Sequence) {
return errors.New("Every track should have the same sequence length")
}
}
totalTrackVoices := 0
for _, track := range s.Tracks {
totalTrackVoices += track.NumVoices
for _, p := range track.Sequence {
if p < 0 || int(p) >= len(track.Patterns) {
return errors.New("Tracks use a non-existing pattern")
}
}
}
if totalTrackVoices > s.Patch.TotalVoices() {
return errors.New("Tracks use too many voices")
}
return nil
}
func (p *Patch) FindSendTarget(i, u int) (int, int, int, error) {
if i < 0 || i >= len(p.Instruments) {
return -1, -1, -1, errors.New("instrument index out of range")
}
instr := p.Instruments[i]
if u < 0 || u >= len(instr.Units) {
return -1, -1, -1, errors.New("unit index out of range")
}
unit := instr.Units[u]
var targetInstrIndex int
if unit.Parameters["voice"] == 0 {
targetInstrIndex = i
} else {
var err error
targetInstrIndex, err = p.InstrumentForVoice(unit.Parameters["voice"] - 1)
if err != nil {
return -1, -1, -1, errors.New("the target voice was out of range")
}
}
targetInstr := p.Instruments[targetInstrIndex]
targetUnitIndex := unit.Parameters["unit"]
if targetUnitIndex < 0 || targetUnitIndex >= len(targetInstr.Units) {
return targetInstrIndex, -1, -1, errors.New("the target unit was out of range")
}
targetUnit := targetInstr.Units[targetUnitIndex]
port := unit.Parameters["port"]
if port < 0 {
return targetInstrIndex, targetUnitIndex, -1, errors.New("the target port was out of range")
}
for k, param := range UnitTypes[targetUnit.Type] {
if param.CanModulate {
port--
if port < 0 {
return targetInstrIndex, targetUnitIndex, k, nil
}
}
}
return targetInstrIndex, targetUnitIndex, -1, errors.New("the target port was out of range")
}
func (s *Song) ParamHintString(instrIndex, unitIndex int, param string) string {
if instrIndex < 0 || instrIndex >= len(s.Patch.Instruments) {
return ""
}
instr := s.Patch.Instruments[instrIndex]
if unitIndex < 0 || unitIndex >= len(instr.Units) {
return ""
}
unit := instr.Units[unitIndex]
value := unit.Parameters[param]
switch unit.Type {
case "envelope":
switch param {
case "attack":
return engineeringTime(math.Pow(2, 24*float64(value)/128) / 44100)
case "decay":
return engineeringTime(math.Pow(2, 24*float64(value)/128) / 44100 * (1 - float64(unit.Parameters["sustain"])/128))
case "release":
return engineeringTime(math.Pow(2, 24*float64(value)/128) / 44100 * float64(unit.Parameters["sustain"]) / 128)
}
case "oscillator":
switch param {
case "type":
switch value {
case Sine:
return "Sine"
case Trisaw:
return "Trisaw"
case Pulse:
return "Pulse"
case Gate:
return "Gate"
case Sample:
return "Sample"
default:
return "Unknown"
}
case "transpose":
relvalue := value - 64
octaves := relvalue / 12
semitones := relvalue % 12
if octaves != 0 {
return fmt.Sprintf("%v oct, %v st", octaves, semitones)
}
return fmt.Sprintf("%v st", semitones)
case "detune":
return fmt.Sprintf("%v st", float32(value-64)/64.0)
}
case "compressor":
switch param {
case "attack":
fallthrough
case "release":
alpha := math.Pow(2, -24*float64(value)/128) // alpha is the "smoothing factor" of first order low pass iir
sec := -1 / (44100 * math.Log(1-alpha)) // from smoothing factor to time constant, https://en.wikipedia.org/wiki/Exponential_smoothing
return engineeringTime(sec)
case "ratio":
return fmt.Sprintf("1 : %.3f", 1-float64(value)/128)
}
case "send":
if param == "voice" || param == "unit" || param == "port" {
targetVoice := unit.Parameters["voice"]
if param == "voice" && targetVoice == 0 {
return "self"
}
targetInstrument := instrIndex
if targetVoice > 0 { // global send, find the instrument
if targetVoice > s.Patch.TotalVoices() {
return ""
}
targetVoice--
targetInstrument = 0
for targetVoice >= s.Patch.Instruments[targetInstrument].NumVoices {
targetVoice -= s.Patch.Instruments[targetInstrument].NumVoices
targetInstrument++
}
}
if param == "voice" {
return fmt.Sprintf("%v (voice %v)", s.Patch.Instruments[targetInstrument].Name, targetVoice)
}
targetUnitIndex := unit.Parameters["unit"]
units := s.Patch.Instruments[targetInstrument].Units
if targetUnitIndex < 0 || targetUnitIndex >= len(units) {
return ""
}
if param == "unit" {
return fmt.Sprintf("%v#%v", units[targetUnitIndex].Type, targetUnitIndex)
}
port := value
for _, param := range UnitTypes[units[targetUnitIndex].Type] {
if param.CanModulate {
port--
if port < 0 {
return param.Name
}
}
}
}
}
return ""
}
func (u *Unit) StackChange() int {
switch u.Type {
case "addp", "mulp", "pop", "out", "outaux", "aux":
return -1 - u.Parameters["stereo"]
case "envelope", "oscillator", "push", "noise", "receive", "loadnote", "loadval", "in", "compressor":
return 1 + u.Parameters["stereo"]
case "pan":
return 1 - u.Parameters["stereo"]
case "speed":
return -1
case "send":
return (-1 - u.Parameters["stereo"]) * u.Parameters["sendpop"]
}
return 0
}
func (u *Unit) StackNeed() int {
switch u.Type {
case "", "envelope", "oscillator", "noise", "receive", "loadnote", "loadval", "in":
return 0
case "mulp", "mul", "add", "addp", "xch":
return 2 * (1 + u.Parameters["stereo"])
case "speed":
return 1
}
return 1 + u.Parameters["stereo"]
}
func Play(synth Synth, song Song) ([]float32, error) {
err := song.Validate()
if err != nil {
return nil, err
}
curVoices := make([]int, len(song.Tracks))
for i := range curVoices {
curVoices[i] = song.FirstTrackVoice(i)
}
initialCapacity := song.TotalRows() * song.SamplesPerRow() * 2
buffer := make([]float32, 0, initialCapacity)
rowbuffer := make([]float32, song.SamplesPerRow()*2)
for row := 0; row < song.TotalRows(); row++ {
patternRow := row % song.RowsPerPattern
pattern := row / song.RowsPerPattern
for t := range song.Tracks {
patternIndex := song.Tracks[t].Sequence[pattern]
note := song.Tracks[t].Patterns[patternIndex][patternRow]
if note > 0 && note <= 1 { // anything but hold causes an action.
continue
}
synth.Release(curVoices[t])
if note > 1 {
curVoices[t]++
first := song.FirstTrackVoice(t)
if curVoices[t] >= first+song.Tracks[t].NumVoices {
curVoices[t] = first
}
synth.Trigger(curVoices[t], note)
}
}
tries := 0
for rowtime := 0; rowtime < song.SamplesPerRow(); {
samples, time, _ := synth.Render(rowbuffer, song.SamplesPerRow()-rowtime)
rowtime += time
buffer = append(buffer, rowbuffer[:samples*2]...)
if tries > 100 {
return nil, fmt.Errorf("Song speed modulation likely so slow that row never advances; error at pattern %v, row %v", pattern, patternRow)
}
}
}
return buffer, nil
}

61
song.go Normal file
View File

@ -0,0 +1,61 @@
package sointu
import (
"errors"
)
type Song struct {
BPM int
RowsPerBeat int
Score Score
Patch Patch
}
func (s *Song) Copy() Song {
return Song{BPM: s.BPM, RowsPerBeat: s.RowsPerBeat, Score: s.Score.Copy(), Patch: s.Patch.Copy()}
}
func (s *Song) SamplesPerRow() int {
return 44100 * 60 / (s.BPM * s.RowsPerBeat)
}
// TBD: Where shall we put methods that work on pure domain types and have no dependencies
// e.g. Validate here
func (s *Song) Validate() error {
if s.BPM < 1 {
return errors.New("BPM should be > 0")
}
if len(s.Score.Tracks) == 0 {
return errors.New("song contains no tracks")
}
var patternLen int
for i, t := range s.Score.Tracks {
for j, pat := range t.Patterns {
if i == 0 && j == 0 {
patternLen = len(pat)
} else {
if len(pat) != patternLen {
return errors.New("Every pattern should have the same length")
}
}
}
}
for i := range s.Score.Tracks[:len(s.Score.Tracks)-1] {
if len(s.Score.Tracks[i].Order) != len(s.Score.Tracks[i+1].Order) {
return errors.New("Every track should have the same sequence length")
}
}
totalTrackVoices := 0
for _, track := range s.Score.Tracks {
totalTrackVoices += track.NumVoices
for _, p := range track.Order {
if p < 0 || int(p) >= len(track.Patterns) {
return errors.New("Tracks use a non-existing pattern")
}
}
}
if totalTrackVoices > s.Patch.NumVoices() {
return errors.New("Tracks use too many voices")
}
return nil
}

85
synth.go Normal file
View File

@ -0,0 +1,85 @@
package sointu
import (
"errors"
"fmt"
"math"
)
type Synth interface {
Render(buffer []float32, maxtime int) (int, int, error)
Update(patch Patch) error
Trigger(voice int, note byte)
Release(voice int)
}
type SynthService interface {
Compile(patch Patch) (Synth, error)
}
func Render(synth Synth, buffer []float32) error {
s, _, err := synth.Render(buffer, math.MaxInt32)
if err != nil {
return fmt.Errorf("sointu.Render failed: %v", err)
}
if s != len(buffer)/2 {
return errors.New("in sointu.Render, synth.Render should have filled the whole buffer but did not")
}
return nil
}
func Play(synth Synth, song Song) ([]float32, error) {
err := song.Validate()
if err != nil {
return nil, err
}
curVoices := make([]int, len(song.Score.Tracks))
for i := range curVoices {
curVoices[i] = song.Score.FirstVoiceForTrack(i)
}
initialCapacity := song.Score.LengthInRows() * song.SamplesPerRow() * 2
buffer := make([]float32, 0, initialCapacity)
rowbuffer := make([]float32, song.SamplesPerRow()*2)
for row := 0; row < song.Score.LengthInRows(); row++ {
patternRow := row % song.Score.RowsPerPattern
pattern := row / song.Score.RowsPerPattern
for t := range song.Score.Tracks {
order := song.Score.Tracks[t].Order
if pattern < 0 || pattern >= len(order) {
continue
}
patternIndex := song.Score.Tracks[t].Order[pattern]
patterns := song.Score.Tracks[t].Patterns
if patternIndex < 0 || int(patternIndex) >= len(patterns) {
continue
}
pattern := patterns[patternIndex]
if patternRow < 0 || patternRow >= len(pattern) {
continue
}
note := pattern[patternRow]
if note > 0 && note <= 1 { // anything but hold causes an action.
continue
}
synth.Release(curVoices[t])
if note > 1 {
curVoices[t]++
first := song.Score.FirstVoiceForTrack(t)
if curVoices[t] >= first+song.Score.Tracks[t].NumVoices {
curVoices[t] = first
}
synth.Trigger(curVoices[t], note)
}
}
tries := 0
for rowtime := 0; rowtime < song.SamplesPerRow(); {
samples, time, _ := synth.Render(rowbuffer, song.SamplesPerRow()-rowtime)
rowtime += time
buffer = append(buffer, rowbuffer[:samples*2]...)
if tries > 100 {
return nil, fmt.Errorf("Song speed modulation likely so slow that row never advances; error at pattern %v, row %v", pattern, patternRow)
}
}
}
return buffer, nil
}

View File

@ -40,7 +40,7 @@ su_render_sampleloop: ; loop through every sample in the row
{{- if .SupportsPolyphony}} {{- if .SupportsPolyphony}}
{{.Push (.PolyphonyBitmask | printf "%v") "PolyphonyBitmask"}} ; does the next voice reuse the current opcodes? {{.Push (.PolyphonyBitmask | printf "%v") "PolyphonyBitmask"}} ; does the next voice reuse the current opcodes?
{{- end}} {{- end}}
{{.Push (.Song.Patch.TotalVoices | printf "%v") "VoicesRemain"}} {{.Push (.Song.Patch.NumVoices | printf "%v") "VoicesRemain"}}
mov {{.DX}}, {{.PTRWORD}} su_synth_obj ; {{.DX}} points to the synth object mov {{.DX}}, {{.PTRWORD}} su_synth_obj ; {{.DX}} points to the synth object
mov {{.COM}}, {{.PTRWORD}} su_patch_code ; COM points to vm code mov {{.COM}}, {{.PTRWORD}} su_patch_code ; COM points to vm code
mov {{.VAL}}, {{.PTRWORD}} su_patch_parameters ; VAL points to unit params mov {{.VAL}}, {{.PTRWORD}} su_patch_parameters ; VAL points to unit params
@ -140,7 +140,7 @@ su_update_voices_nexttrack:
pop {{.DX}} ; edx=patrnrow pop {{.DX}} ; edx=patrnrow
add {{.SI}}, {{.SequenceLength}} add {{.SI}}, {{.SequenceLength}}
inc {{.BP}} inc {{.BP}}
{{- $addrname := len .Song.Tracks | printf "su_synth_obj + %v"}} {{- $addrname := len .Song.Score.Tracks | printf "su_synth_obj + %v"}}
{{- .Prepare $addrname | indent 8}} {{- .Prepare $addrname | indent 8}}
cmp {{.BP}},{{.Use $addrname}} cmp {{.BP}},{{.Use $addrname}}
jl su_update_voices_trackloop jl su_update_voices_trackloop
@ -154,7 +154,7 @@ su_update_voices_nexttrack:
{{- .Prepare "su_tracks" | indent 4}} {{- .Prepare "su_tracks" | indent 4}}
lea {{.SI}}, [{{.Use "su_tracks"}}+{{.AX}}]; esi points to the pattern data for current track lea {{.SI}}, [{{.Use "su_tracks"}}+{{.AX}}]; esi points to the pattern data for current track
mov {{.DI}}, {{.PTRWORD}} su_synth_obj+su_synthworkspace.voices mov {{.DI}}, {{.PTRWORD}} su_synth_obj+su_synthworkspace.voices
mov bl, {{len .Song.Tracks}} ; MAX_TRACKS is always <= 32 so this is ok mov bl, {{len .Song.Score.Tracks}} ; MAX_TRACKS is always <= 32 so this is ok
su_update_voices_trackloop: su_update_voices_trackloop:
movzx eax, byte [{{.SI}}] ; eax = current pattern movzx eax, byte [{{.SI}}] ; eax = current pattern
imul eax, {{.PatternLength}} ; multiply by rows per pattern, eax = offset to current pattern data imul eax, {{.PatternLength}} ; multiply by rows per pattern, eax = offset to current pattern data

View File

@ -8,8 +8,8 @@
#define SU_SAMPLE_RATE 44100 #define SU_SAMPLE_RATE 44100
#define SU_BPM {{.Song.BPM}} #define SU_BPM {{.Song.BPM}}
#define SU_ROWS_PER_BEAT {{.Song.RowsPerBeat}} #define SU_ROWS_PER_BEAT {{.Song.RowsPerBeat}}
#define SU_PATTERN_SIZE {{.Song.RowsPerPattern}} #define SU_PATTERN_SIZE {{.Song.Score.RowsPerPattern}}
#define SU_MAX_PATTERNS {{.Song.SequenceLength}} #define SU_MAX_PATTERNS {{.Song.Score.Length}}
#define SU_TOTAL_ROWS (SU_MAX_PATTERNS*SU_PATTERN_SIZE) #define SU_TOTAL_ROWS (SU_MAX_PATTERNS*SU_PATTERN_SIZE)
#define SU_SAMPLES_PER_ROW (SU_SAMPLE_RATE*60/(SU_BPM*SU_ROWS_PER_BEAT)) #define SU_SAMPLES_PER_ROW (SU_SAMPLE_RATE*60/(SU_BPM*SU_ROWS_PER_BEAT))

View File

@ -89,7 +89,7 @@ su_op_aux_mono:
{{.Func "su_op_send" "Opcode"}} {{.Func "su_op_send" "Opcode"}}
lodsw lodsw
mov {{.CX}}, [{{.Stack "Voice"}}] ; load pointer to voice mov {{.CX}}, [{{.Stack "Voice"}}] ; load pointer to voice
{{- if .SupportsParamValueOtherThan "send" "voice" 0}} {{- if .SupportsGlobalSend}}
pushf ; uh ugly: we save the flags just for the stereo carry bit. Doing the .CX loading later crashed the synth for stereo sends as loading the synth address from stack was f'd up by the "call su_op_send_mono" pushf ; uh ugly: we save the flags just for the stereo carry bit. Doing the .CX loading later crashed the synth for stereo sends as loading the synth address from stack was f'd up by the "call su_op_send_mono"
test {{.AX}}, 0x8000 test {{.AX}}, 0x8000
jz su_op_send_skipglobal jz su_op_send_skipglobal

View File

@ -170,7 +170,7 @@
{{- end}} {{- end}}
(global.set $WRK (i32.const 4160)) (global.set $WRK (i32.const 4160))
(global.set $voice (i32.const 4160)) (global.set $voice (i32.const 4160))
(global.set $voicesRemain (i32.const {{.Song.Patch.TotalVoices | printf "%v"}})) (global.set $voicesRemain (i32.const {{.Song.Patch.NumVoices | printf "%v"}}))
{{- if .HasOp "delay"}} {{- if .HasOp "delay"}}
(global.set $delayWRK (i32.const 262144)) ;; BAD IDEA: we are limited to something like 30 delay lines (global.set $delayWRK (i32.const 262144)) ;; BAD IDEA: we are limited to something like 30 delay lines
;; after that, the delay lines start to overwrite the outputbuffer. Find a way to layout the memory ;; after that, the delay lines start to overwrite the outputbuffer. Find a way to layout the memory

View File

@ -95,12 +95,12 @@
loop $stereoLoop loop $stereoLoop
{{- end}} {{- end}}
(local.set $scaledAddress (i32.add (i32.mul (i32.and (local.get $address) (i32.const 0x7FF7)) (i32.const 4)) (local.set $scaledAddress (i32.add (i32.mul (i32.and (local.get $address) (i32.const 0x7FF7)) (i32.const 4))
{{- if .SupportsParamValueOtherThan "send" "voice" 0}} {{- if .SupportsGlobalSend}}
(select (select
(i32.const 4096) (i32.const 4096)
{{- end}} {{- end}}
(global.get $voice) (global.get $voice)
{{- if .SupportsParamValueOtherThan "send" "voice" 0}} {{- if .SupportsGlobalSend}}
(i32.and (local.get $address)(i32.const 0x8000)) (i32.and (local.get $address)(i32.const 0x8000))
) )
{{- end}} {{- end}}

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,18 +1,19 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 0, 0, 68, 0, 0, 0, 66, 0, 0, 0, 69, 0, 0, 0]] patterns: [[64, 0, 0, 0, 68, 0, 0, 0, 66, 0, 0, 0, 69, 0, 0, 0]]
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[0, 68, 0, 0, 71, 0, 0, 0, 69, 0, 0, 0, 73, 0, 0, 0]] patterns: [[0, 68, 0, 0, 71, 0, 0, 0, 69, 0, 0, 0, 73, 0, 0, 0]]
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[0, 0, 71, 0, 75, 0, 0, 0, 73, 0, 0, 0, 76, 0, 0, 0]] patterns: [[0, 0, 71, 0, 75, 0, 0, 0, 73, 0, 0, 0, 76, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 3 - numvoices: 3
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,15 +1,16 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65]] patterns: [[64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65]]
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[76, 0, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0]] patterns: [[76, 0, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
@ -23,9 +24,9 @@ patch:
- type: mulp - type: mulp
parameters: {stereo: 1} parameters: {stereo: 1}
- type: send - type: send
parameters: {amount: 128, port: 0, sendpop: 1, stereo: 0, unit: 0, voice: 3} parameters: {amount: 128, port: 0, sendpop: 1, stereo: 0, target: 1}
- type: send - type: send
parameters: {amount: 128, port: 1, sendpop: 1, stereo: 0, unit: 0, voice: 3} parameters: {amount: 128, port: 1, sendpop: 1, stereo: 0, target: 1}
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
@ -39,13 +40,14 @@ patch:
- type: mulp - type: mulp
parameters: {stereo: 1} parameters: {stereo: 1}
- type: send - type: send
parameters: {amount: 128, port: 0, sendpop: 1, stereo: 0, unit: 0, voice: 3} parameters: {amount: 128, port: 0, sendpop: 1, stereo: 0, target: 1}
- type: send - type: send
parameters: {amount: 128, port: 1, sendpop: 1, stereo: 0, unit: 0, voice: 3} parameters: {amount: 128, port: 1, sendpop: 1, stereo: 0, target: 1}
- numvoices: 1 - numvoices: 1
units: units:
- type: receive - type: receive
parameters: {stereo: 1} parameters: {stereo: 1}
id: 1
- type: compressor - type: compressor
parameters: {attack: 32, invgain: 32, ratio: 96, release: 64, stereo: 0, threshold: 64} parameters: {attack: 32, invgain: 32, ratio: 96, release: 64, stereo: 0, threshold: 64}
- type: mulp - type: mulp

View File

@ -1,15 +1,16 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65]] patterns: [[64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65]]
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[76, 0, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0]] patterns: [[76, 0, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
@ -23,9 +24,9 @@ patch:
- type: mulp - type: mulp
parameters: {stereo: 1} parameters: {stereo: 1}
- type: send - type: send
parameters: {amount: 128, port: 0, sendpop: 1, stereo: 0, unit: 0, voice: 3} parameters: {amount: 128, port: 0, sendpop: 1, stereo: 0, target: 1}
- type: send - type: send
parameters: {amount: 128, port: 1, sendpop: 1, stereo: 0, unit: 0, voice: 3} parameters: {amount: 128, port: 1, sendpop: 1, stereo: 0, target: 1}
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
@ -39,13 +40,14 @@ patch:
- type: mulp - type: mulp
parameters: {stereo: 1} parameters: {stereo: 1}
- type: send - type: send
parameters: {amount: 128, port: 0, sendpop: 1, stereo: 0, unit: 0, voice: 3} parameters: {amount: 128, port: 0, sendpop: 1, stereo: 0, target: 1}
- type: send - type: send
parameters: {amount: 128, port: 1, sendpop: 1, stereo: 0, unit: 0, voice: 3} parameters: {amount: 128, port: 1, sendpop: 1, stereo: 0, target: 1}
- numvoices: 1 - numvoices: 1
units: units:
- type: receive - type: receive
parameters: {stereo: 1} parameters: {stereo: 1}
id: 1
- type: compressor - type: compressor
parameters: {attack: 32, invgain: 32, ratio: 96, release: 64, stereo: 1, threshold: 64} parameters: {attack: 32, invgain: 32, ratio: 96, release: 64, stereo: 1, threshold: 64}
- type: mulp - type: mulp

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
@ -18,6 +19,7 @@ patch:
- type: delay - type: delay
parameters: {damp: 64, dry: 128, feedback: 125, notetracking: 0, pregain: 40, stereo: 0} parameters: {damp: 64, dry: 128, feedback: 125, notetracking: 0, pregain: 40, stereo: 0}
varargs: [11025] varargs: [11025]
id: 1
- type: pan - type: pan
parameters: {panning: 64, stereo: 0} parameters: {panning: 64, stereo: 0}
- type: out - type: out
@ -25,4 +27,4 @@ patch:
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0}
- type: send - type: send
parameters: {amount: 32, port: 3, sendpop: 1, stereo: 0, unit: 3, voice: 0} parameters: {amount: 32, port: 3, sendpop: 1, stereo: 0, target: 1}

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
@ -18,6 +19,7 @@ patch:
- type: delay - type: delay
parameters: {damp: 64, dry: 128, feedback: 125, notetracking: 0, pregain: 40, stereo: 0} parameters: {damp: 64, dry: 128, feedback: 125, notetracking: 0, pregain: 40, stereo: 0}
varargs: [11025] varargs: [11025]
id: 1
- type: pan - type: pan
parameters: {panning: 64, stereo: 0} parameters: {panning: 64, stereo: 0}
- type: out - type: out
@ -25,4 +27,4 @@ patch:
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0}
- type: send - type: send
parameters: {amount: 32, port: 1, sendpop: 1, stereo: 0, unit: 3, voice: 0} parameters: {amount: 32, port: 1, sendpop: 1, stereo: 0, target: 1}

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
@ -18,6 +19,7 @@ patch:
- type: delay - type: delay
parameters: {damp: 64, dry: 128, feedback: 125, notetracking: 0, pregain: 40, stereo: 0} parameters: {damp: 64, dry: 128, feedback: 125, notetracking: 0, pregain: 40, stereo: 0}
varargs: [11025] varargs: [11025]
id: 1
- type: pan - type: pan
parameters: {panning: 64, stereo: 0} parameters: {panning: 64, stereo: 0}
- type: out - type: out
@ -25,4 +27,4 @@ patch:
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0}
- type: send - type: send
parameters: {amount: 32, port: 2, sendpop: 1, stereo: 0, unit: 3, voice: 0} parameters: {amount: 32, port: 2, sendpop: 1, stereo: 0, target: 1}

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]] patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
@ -18,6 +19,7 @@ patch:
- type: delay - type: delay
parameters: {damp: 64, dry: 128, feedback: 0, notetracking: 0, pregain: 40, stereo: 0} parameters: {damp: 64, dry: 128, feedback: 0, notetracking: 0, pregain: 40, stereo: 0}
varargs: [1000] varargs: [1000]
id: 1
- type: pan - type: pan
parameters: {panning: 64, stereo: 0} parameters: {panning: 64, stereo: 0}
- type: out - type: out
@ -25,4 +27,4 @@ patch:
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 50, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 50, type: 0, unison: 0}
- type: send - type: send
parameters: {amount: 65, port: 4, sendpop: 1, stereo: 0, unit: 3, voice: 0} parameters: {amount: 65, port: 4, sendpop: 1, stereo: 0, target: 1}

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
@ -18,6 +19,7 @@ patch:
- type: delay - type: delay
parameters: {damp: 64, dry: 128, feedback: 125, notetracking: 0, pregain: 40, stereo: 0} parameters: {damp: 64, dry: 128, feedback: 125, notetracking: 0, pregain: 40, stereo: 0}
varargs: [11025] varargs: [11025]
id: 1
- type: pan - type: pan
parameters: {panning: 64, stereo: 0} parameters: {panning: 64, stereo: 0}
- type: out - type: out
@ -25,4 +27,4 @@ patch:
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0}
- type: send - type: send
parameters: {amount: 32, port: 0, sendpop: 1, stereo: 0, unit: 3, voice: 0} parameters: {amount: 32, port: 0, sendpop: 1, stereo: 0, target: 1}

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,27 +1,30 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
parameters: {attack: 64, decay: 64, gain: 128, release: 80, stereo: 0, sustain: 64} parameters: {attack: 64, decay: 64, gain: 128, release: 80, stereo: 0, sustain: 64}
- type: distort - type: distort
parameters: {drive: 32, stereo: 0} parameters: {drive: 32, stereo: 0}
id: 1
- type: envelope - type: envelope
parameters: {attack: 64, decay: 64, gain: 128, release: 80, stereo: 0, sustain: 64} parameters: {attack: 64, decay: 64, gain: 128, release: 80, stereo: 0, sustain: 64}
- type: distort - type: distort
parameters: {drive: 96, stereo: 0} parameters: {drive: 96, stereo: 0}
id: 2
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0}
- type: send - type: send
parameters: {amount: 68, port: 0, sendpop: 0, stereo: 0, unit: 1, voice: 0} parameters: {amount: 68, port: 0, sendpop: 0, stereo: 0, target: 1}
- type: send - type: send
parameters: {amount: 68, port: 0, sendpop: 1, stereo: 0, unit: 3, voice: 0} parameters: {amount: 68, port: 0, sendpop: 1, stereo: 0, target: 2}
- type: out - type: out
parameters: {gain: 128, stereo: 1} parameters: {gain: 128, stereo: 1}

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,27 +1,30 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
parameters: {attack: 80, decay: 80, gain: 128, release: 80, stereo: 0, sustain: 64} parameters: {attack: 80, decay: 80, gain: 128, release: 80, stereo: 0, sustain: 64}
id: 1
- type: envelope - type: envelope
parameters: {attack: 80, decay: 80, gain: 128, release: 80, stereo: 0, sustain: 64} parameters: {attack: 80, decay: 80, gain: 128, release: 80, stereo: 0, sustain: 64}
id: 2
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 0, shape: 96, stereo: 0, transpose: 120, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 0, shape: 96, stereo: 0, transpose: 120, type: 0, unison: 0}
- type: send - type: send
parameters: {amount: 68, port: 0, sendpop: 0, stereo: 0, unit: 0, voice: 0} parameters: {amount: 68, port: 0, sendpop: 0, stereo: 0, target: 1}
- type: send - type: send
parameters: {amount: 68, port: 1, sendpop: 0, stereo: 0, unit: 0, voice: 0} parameters: {amount: 68, port: 1, sendpop: 0, stereo: 0, target: 1}
- type: send - type: send
parameters: {amount: 68, port: 3, sendpop: 0, stereo: 0, unit: 0, voice: 0} parameters: {amount: 68, port: 3, sendpop: 0, stereo: 0, target: 1}
- type: send - type: send
parameters: {amount: 68, port: 4, sendpop: 1, stereo: 0, unit: 1, voice: 0} parameters: {amount: 68, port: 4, sendpop: 1, stereo: 0, target: 2}
- type: out - type: out
parameters: {gain: 110, stereo: 1} parameters: {gain: 110, stereo: 1}

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
@ -17,6 +18,7 @@ patch:
parameters: {stereo: 0} parameters: {stereo: 0}
- type: filter - type: filter
parameters: {bandpass: 1, frequency: 32, highpass: 0, lowpass: 0, negbandpass: 0, neghighpass: 0, resonance: 64, stereo: 0} parameters: {bandpass: 1, frequency: 32, highpass: 0, lowpass: 0, negbandpass: 0, neghighpass: 0, resonance: 64, stereo: 0}
id: 1
- type: pan - type: pan
parameters: {panning: 64, stereo: 0} parameters: {panning: 64, stereo: 0}
- type: out - type: out
@ -24,4 +26,4 @@ patch:
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0}
- type: send - type: send
parameters: {amount: 32, port: 0, sendpop: 1, stereo: 0, unit: 3, voice: 0} parameters: {amount: 32, port: 0, sendpop: 1, stereo: 0, target: 1}

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
@ -17,6 +18,7 @@ patch:
parameters: {stereo: 0} parameters: {stereo: 0}
- type: filter - type: filter
parameters: {bandpass: 1, frequency: 32, highpass: 0, lowpass: 0, negbandpass: 0, neghighpass: 0, resonance: 64, stereo: 0} parameters: {bandpass: 1, frequency: 32, highpass: 0, lowpass: 0, negbandpass: 0, neghighpass: 0, resonance: 64, stereo: 0}
id: 1
- type: pan - type: pan
parameters: {panning: 64, stereo: 0} parameters: {panning: 64, stereo: 0}
- type: out - type: out
@ -24,4 +26,4 @@ patch:
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0}
- type: send - type: send
parameters: {amount: 32, port: 1, sendpop: 1, stereo: 0, unit: 3, voice: 0} parameters: {amount: 32, port: 1, sendpop: 1, stereo: 0, target: 1}

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,27 +1,30 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
parameters: {attack: 64, decay: 64, gain: 128, release: 80, stereo: 0, sustain: 64} parameters: {attack: 64, decay: 64, gain: 128, release: 80, stereo: 0, sustain: 64}
- type: hold - type: hold
parameters: {holdfreq: 3, stereo: 0} parameters: {holdfreq: 3, stereo: 0}
id: 1
- type: envelope - type: envelope
parameters: {attack: 64, decay: 64, gain: 128, release: 80, stereo: 0, sustain: 64} parameters: {attack: 64, decay: 64, gain: 128, release: 80, stereo: 0, sustain: 64}
- type: hold - type: hold
parameters: {holdfreq: 3, stereo: 0} parameters: {holdfreq: 3, stereo: 0}
id: 2
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0}
- type: send - type: send
parameters: {amount: 68, port: 0, sendpop: 0, stereo: 0, unit: 1, voice: 0} parameters: {amount: 68, port: 0, sendpop: 0, stereo: 0, target: 1}
- type: send - type: send
parameters: {amount: 68, port: 0, sendpop: 1, stereo: 0, unit: 3, voice: 0} parameters: {amount: 68, port: 0, sendpop: 1, stereo: 0, target: 2}
- type: out - type: out
parameters: {gain: 128, stereo: 1} parameters: {gain: 128, stereo: 1}

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadnote - type: loadnote

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadnote - type: loadnote

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,15 +1,16 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[0, 0, 0, 0, 0, 0, 0, 0, 64, 1, 1, 0, 0, 0, 0, 0]] patterns: [[0, 0, 0, 0, 0, 0, 0, 0, 64, 1, 1, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: noise - type: noise

View File

@ -1,18 +1,20 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]] patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
parameters: {attack: 80, decay: 80, gain: 128, release: 80, stereo: 0, sustain: 64} parameters: {attack: 80, decay: 80, gain: 128, release: 80, stereo: 0, sustain: 64}
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 0, phase: 0, shape: 64, stereo: 0, transpose: 64, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 0, phase: 0, shape: 64, stereo: 0, transpose: 64, type: 0, unison: 0}
id: 1
- type: mulp - type: mulp
parameters: {stereo: 0} parameters: {stereo: 0}
- type: push - type: push
@ -20,6 +22,6 @@ patch:
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0}
- type: send - type: send
parameters: {amount: 68, port: 3, sendpop: 1, stereo: 0, unit: 1, voice: 0} parameters: {amount: 68, port: 3, sendpop: 1, stereo: 0, target: 1}
- type: out - type: out
parameters: {gain: 128, stereo: 1} parameters: {gain: 128, stereo: 1}

View File

@ -1,18 +1,20 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]] patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
parameters: {attack: 80, decay: 80, gain: 128, release: 80, stereo: 0, sustain: 64} parameters: {attack: 80, decay: 80, gain: 128, release: 80, stereo: 0, sustain: 64}
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 0, phase: 0, shape: 64, stereo: 0, transpose: 64, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 0, phase: 0, shape: 64, stereo: 0, transpose: 64, type: 0, unison: 0}
id: 1
- type: mulp - type: mulp
parameters: {stereo: 0} parameters: {stereo: 0}
- type: push - type: push
@ -20,6 +22,6 @@ patch:
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0}
- type: send - type: send
parameters: {amount: 96, port: 1, sendpop: 1, stereo: 0, unit: 1, voice: 0} parameters: {amount: 96, port: 1, sendpop: 1, stereo: 0, target: 1}
- type: out - type: out
parameters: {gain: 128, stereo: 1} parameters: {gain: 128, stereo: 1}

View File

@ -1,18 +1,20 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]] patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
parameters: {attack: 80, decay: 80, gain: 128, release: 80, stereo: 0, sustain: 64} parameters: {attack: 80, decay: 80, gain: 128, release: 80, stereo: 0, sustain: 64}
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 0, phase: 0, shape: 64, stereo: 0, transpose: 64, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 0, phase: 0, shape: 64, stereo: 0, transpose: 64, type: 0, unison: 0}
id: 1
- type: mulp - type: mulp
parameters: {stereo: 0} parameters: {stereo: 0}
- type: push - type: push
@ -20,6 +22,6 @@ patch:
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0}
- type: send - type: send
parameters: {amount: 68, port: 5, sendpop: 1, stereo: 0, unit: 1, voice: 0} parameters: {amount: 68, port: 5, sendpop: 1, stereo: 0, target: 1}
- type: out - type: out
parameters: {gain: 128, stereo: 1} parameters: {gain: 128, stereo: 1}

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,18 +1,20 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]] patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
parameters: {attack: 80, decay: 80, gain: 128, release: 80, stereo: 0, sustain: 64} parameters: {attack: 80, decay: 80, gain: 128, release: 80, stereo: 0, sustain: 64}
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 0, phase: 0, shape: 64, stereo: 0, transpose: 64, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 0, phase: 0, shape: 64, stereo: 0, transpose: 64, type: 0, unison: 0}
id: 1
- type: mulp - type: mulp
parameters: {stereo: 0} parameters: {stereo: 0}
- type: push - type: push
@ -20,6 +22,6 @@ patch:
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0}
- type: send - type: send
parameters: {amount: 128, port: 2, sendpop: 1, stereo: 0, unit: 1, voice: 0} parameters: {amount: 128, port: 2, sendpop: 1, stereo: 0, target: 1}
- type: out - type: out
parameters: {gain: 128, stereo: 1} parameters: {gain: 128, stereo: 1}

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,15 +1,16 @@
bpm: 100 bpm: 100
rowsperpattern: 8
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 8
length: 8
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [1, 0, 2, 0, 3, 0, 4, 0] order: [1, 0, 2, 0, 3, 0, 4, 0]
patterns: [[0, 0, 0, 0, 0, 0, 0, 0], [72, 1, 1, 1, 1, 1, 1, 0], [64, 1, 1, 1, 1, 1, 1, 0], [60, 1, 1, 1, 1, 1, 1, 0], [40, 1, 1, 1, 1, 1, 1, 0]] patterns: [[0, 0, 0, 0, 0, 0, 0, 0], [72, 1, 1, 1, 1, 1, 1, 0], [64, 1, 1, 1, 1, 1, 1, 0], [60, 1, 1, 1, 1, 1, 1, 0], [40, 1, 1, 1, 1, 1, 1, 0]]
- numvoices: 1 - numvoices: 1
sequence: [0, 1, 0, 2, 0, 3, 0, 4] order: [0, 1, 0, 2, 0, 3, 0, 4]
patterns: [[0, 0, 0, 0, 0, 0, 0, 0], [72, 1, 1, 1, 1, 1, 1, 0], [64, 1, 1, 1, 1, 1, 1, 0], [60, 1, 1, 1, 1, 1, 1, 0], [40, 1, 1, 1, 1, 1, 1, 0]] patterns: [[0, 0, 0, 0, 0, 0, 0, 0], [72, 1, 1, 1, 1, 1, 1, 0], [64, 1, 1, 1, 1, 1, 1, 0], [60, 1, 1, 1, 1, 1, 1, 0], [40, 1, 1, 1, 1, 1, 1, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
@ -17,9 +18,9 @@ patch:
- type: envelope - type: envelope
parameters: {attack: 32, decay: 32, gain: 128, release: 64, stereo: 0, sustain: 64} parameters: {attack: 32, decay: 32, gain: 128, release: 64, stereo: 0, sustain: 64}
- type: oscillator - type: oscillator
parameters: {color: 0, detune: 64, gain: 128, lfo: 0, looplength: 106, loopstart: 1341, phase: 64, shape: 64, samplestart: 1678611, stereo: 0, transpose: 68, type: 4, unison: 0} parameters: {color: 0, detune: 64, gain: 128, lfo: 0, looplength: 106, loopstart: 1341, phase: 64, samplestart: 1678611, shape: 64, stereo: 0, transpose: 68, type: 4, unison: 0}
- type: oscillator - type: oscillator
parameters: {color: 0, detune: 64, gain: 128, lfo: 0, looplength: 95, loopstart: 1483, phase: 64, shape: 64, samplestart: 1680142, stereo: 0, transpose: 66, type: 4, unison: 0} parameters: {color: 0, detune: 64, gain: 128, lfo: 0, looplength: 95, loopstart: 1483, phase: 64, samplestart: 1680142, shape: 64, stereo: 0, transpose: 66, type: 4, unison: 0}
- type: mulp - type: mulp
parameters: {stereo: 1} parameters: {stereo: 1}
- type: out - type: out

View File

@ -1,15 +1,16 @@
bpm: 100 bpm: 100
rowsperpattern: 8
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 8
length: 8
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [1, 0, 2, 0, 3, 0, 4, 0] order: [1, 0, 2, 0, 3, 0, 4, 0]
patterns: [[0, 0, 0, 0, 0, 0, 0, 0], [72, 1, 1, 1, 1, 1, 1, 0], [64, 1, 1, 1, 1, 1, 1, 0], [60, 1, 1, 1, 1, 1, 1, 0], [40, 1, 1, 1, 1, 1, 1, 0]] patterns: [[0, 0, 0, 0, 0, 0, 0, 0], [72, 1, 1, 1, 1, 1, 1, 0], [64, 1, 1, 1, 1, 1, 1, 0], [60, 1, 1, 1, 1, 1, 1, 0], [40, 1, 1, 1, 1, 1, 1, 0]]
- numvoices: 1 - numvoices: 1
sequence: [0, 1, 0, 2, 0, 3, 0, 4] order: [0, 1, 0, 2, 0, 3, 0, 4]
patterns: [[0, 0, 0, 0, 0, 0, 0, 0], [72, 1, 1, 1, 1, 1, 1, 0], [64, 1, 1, 1, 1, 1, 1, 0], [60, 1, 1, 1, 1, 1, 1, 0], [40, 1, 1, 1, 1, 1, 1, 0]] patterns: [[0, 0, 0, 0, 0, 0, 0, 0], [72, 1, 1, 1, 1, 1, 1, 0], [64, 1, 1, 1, 1, 1, 1, 0], [60, 1, 1, 1, 1, 1, 1, 0], [40, 1, 1, 1, 1, 1, 1, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
@ -17,7 +18,7 @@ patch:
- type: envelope - type: envelope
parameters: {attack: 32, decay: 32, gain: 128, release: 64, stereo: 0, sustain: 64} parameters: {attack: 32, decay: 32, gain: 128, release: 64, stereo: 0, sustain: 64}
- type: oscillator - type: oscillator
parameters: {color: 0, detune: 32, gain: 128, lfo: 0, looplength: 106, loopstart: 1341, phase: 64, shape: 64, samplestart: 1678611, stereo: 1, transpose: 68, type: 4, unison: 0} parameters: {color: 0, detune: 32, gain: 128, lfo: 0, looplength: 106, loopstart: 1341, phase: 64, samplestart: 1678611, shape: 64, stereo: 1, transpose: 68, type: 4, unison: 0}
- type: mulp - type: mulp
parameters: {stereo: 1} parameters: {stereo: 1}
- type: out - type: out

View File

@ -1,18 +1,20 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]] patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
parameters: {attack: 80, decay: 80, gain: 128, release: 80, stereo: 0, sustain: 64} parameters: {attack: 80, decay: 80, gain: 128, release: 80, stereo: 0, sustain: 64}
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 0, phase: 0, shape: 64, stereo: 0, transpose: 64, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 0, phase: 0, shape: 64, stereo: 0, transpose: 64, type: 0, unison: 0}
id: 1
- type: mulp - type: mulp
parameters: {stereo: 0} parameters: {stereo: 0}
- type: push - type: push
@ -20,6 +22,6 @@ patch:
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0}
- type: send - type: send
parameters: {amount: 68, port: 4, sendpop: 1, stereo: 0, unit: 1, voice: 0} parameters: {amount: 68, port: 4, sendpop: 1, stereo: 0, target: 1}
- type: out - type: out
parameters: {gain: 128, stereo: 1} parameters: {gain: 128, stereo: 1}

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,18 +1,20 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]] patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope
parameters: {attack: 80, decay: 80, gain: 128, release: 80, stereo: 0, sustain: 64} parameters: {attack: 80, decay: 80, gain: 128, release: 80, stereo: 0, sustain: 64}
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 0, phase: 0, shape: 64, stereo: 0, transpose: 64, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 0, phase: 0, shape: 64, stereo: 0, transpose: 64, type: 0, unison: 0}
id: 1
- type: mulp - type: mulp
parameters: {stereo: 0} parameters: {stereo: 0}
- type: push - type: push
@ -20,6 +22,6 @@ patch:
- type: oscillator - type: oscillator
parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0} parameters: {color: 128, detune: 64, gain: 128, lfo: 1, phase: 64, shape: 64, stereo: 0, transpose: 70, type: 0, unison: 0}
- type: send - type: send
parameters: {amount: 68, port: 0, sendpop: 1, stereo: 0, unit: 1, voice: 0} parameters: {amount: 68, port: 0, sendpop: 1, stereo: 0, target: 1}
- type: out - type: out
parameters: {gain: 128, stereo: 1} parameters: {gain: 128, stereo: 1}

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]] patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 2 - numvoices: 2
sequence: [0] order: [0]
patterns: [[64, 1, 68, 1, 32, 1, 1, 1, 75, 1, 78, 1, 1, 0, 0, 0]] patterns: [[64, 1, 68, 1, 32, 1, 1, 1, 75, 1, 78, 1, 1, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: envelope - type: envelope

View File

@ -1,12 +1,13 @@
bpm: 100 bpm: 100
rowsperpattern: 16
rowsperbeat: 4 rowsperbeat: 4
score:
rowsperpattern: 16
length: 1
tracks: tracks:
- numvoices: 1 - numvoices: 1
sequence: [0] order: [0]
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]] patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
patch: patch:
instruments:
- numvoices: 1 - numvoices: 1
units: units:
- type: loadval - type: loadval

Some files were not shown because too many files have changed in this diff Show More