mirror of
https://github.com/vsariola/sointu.git
synced 2025-07-16 03:54:31 -04:00
feat(sointu): make patterns local to track
The global pattern table is constructed only during compilation. At this point, we can do also all sorts of optimizations / changes e.g. remove unnecessary releases and reuse patterns if there's a pattern already that could be used.
This commit is contained in:
@ -33,9 +33,8 @@ func TestPlayer(t *testing.T) {
|
||||
sointu.Unit{Type: "mulp", Parameters: map[string]int{"stereo": 0}},
|
||||
sointu.Unit{Type: "out", Parameters: map[string]int{"stereo": 1, "gain": 128}},
|
||||
}}}}
|
||||
patterns := [][]byte{{64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0}}
|
||||
tracks := []sointu.Track{sointu.Track{1, []byte{0}}}
|
||||
song := sointu.Song{BPM: 100, Patterns: patterns, Tracks: tracks, Patch: patch, Output16Bit: false, Hold: 1}
|
||||
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}}}}
|
||||
song := sointu.Song{BPM: 100, Tracks: tracks, Patch: patch, Output16Bit: false, Hold: 1}
|
||||
synth, err := bridge.Synth(patch)
|
||||
if err != nil {
|
||||
t.Fatalf("Compiling patch failed: %v", err)
|
||||
|
@ -85,6 +85,10 @@ func (com *Compiler) Song(song *sointu.Song) (map[string]string, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(`could not encode patch: %v`, err)
|
||||
}
|
||||
encodedSong, err := EncodeSong(song)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(`could not encode song: %v`, err)
|
||||
}
|
||||
for _, templateName := range templates {
|
||||
compilerMacros := *NewCompilerMacros(*com)
|
||||
featureSetMacros := FeatureSetMacros{features}
|
||||
@ -99,7 +103,8 @@ func (com *Compiler) Song(song *sointu.Song) (map[string]string, error) {
|
||||
X86Macros
|
||||
SongMacros
|
||||
*EncodedPatch
|
||||
}{compilerMacros, featureSetMacros, x86Macros, songMacros, encodedPatch}
|
||||
EncodedSong *EncodedSong
|
||||
}{compilerMacros, featureSetMacros, x86Macros, songMacros, encodedPatch, encodedSong}
|
||||
populatedTemplate, extension, err = com.compile(templateName, &data)
|
||||
} else if com.Arch == "wasm" {
|
||||
wasmMacros := *NewWasmMacros()
|
||||
@ -109,7 +114,8 @@ func (com *Compiler) Song(song *sointu.Song) (map[string]string, error) {
|
||||
WasmMacros
|
||||
SongMacros
|
||||
*EncodedPatch
|
||||
}{compilerMacros, featureSetMacros, wasmMacros, songMacros, encodedPatch}
|
||||
EncodedSong *EncodedSong
|
||||
}{compilerMacros, featureSetMacros, wasmMacros, songMacros, encodedPatch, encodedSong}
|
||||
populatedTemplate, extension, err = com.compile(templateName, &data)
|
||||
}
|
||||
if err != nil {
|
||||
|
146
compiler/encoded_song.go
Normal file
146
compiler/encoded_song.go
Normal file
@ -0,0 +1,146 @@
|
||||
package compiler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/vsariola/sointu"
|
||||
)
|
||||
|
||||
// EncodedSong has a single global pattern table and all track sequences are
|
||||
// indices to this table. This is in contrast with sointu. Song, which has one
|
||||
// pattern table per track.
|
||||
type EncodedSong struct {
|
||||
Patterns [][]byte
|
||||
Sequences [][]byte
|
||||
}
|
||||
|
||||
// flattenPatterns returns the track sequences flattened into linear arrays.
|
||||
// Additionally, after first release (value 0), it replaces every release or
|
||||
// hold with -1, denoting "don't care if it's either release (0) or hold (1)".
|
||||
// As we reconstruct the pattern table, we may use any pattern that has either 0
|
||||
// or hold in place of don't cares.
|
||||
func flattenPatterns(song *sointu.Song) [][]int {
|
||||
ret := make([][]int, 0, len(song.Tracks))
|
||||
for _, t := range song.Tracks {
|
||||
flatSequence := make([]int, 0, song.TotalRows())
|
||||
dontCare := false
|
||||
for _, s := range t.Sequence {
|
||||
for _, note := range t.Patterns[s] {
|
||||
if !dontCare || note > song.Hold {
|
||||
if note == song.Hold {
|
||||
flatSequence = append(flatSequence, 1) // replace holds with 1s, we'll get rid of song.Hold soon and do the hold replacement at the last minute
|
||||
} else {
|
||||
flatSequence = append(flatSequence, int(note))
|
||||
}
|
||||
dontCare = note == 0 // after 0 aka release, we don't care if further releases come along
|
||||
} else {
|
||||
flatSequence = append(flatSequence, -1)
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = append(ret, flatSequence)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// constructPatterns finds the smallest global pattern table for a given list of
|
||||
// flattened patterns. If the patterns are not divisible with the patternLength,
|
||||
// then: a) if the last note of a track is release (0) or don't care (-1), the
|
||||
// track is extended with don't cares (-1) until the total length of the song is
|
||||
// divisible with the patternLength. b) Otherwise, the track is extended with a
|
||||
// single release (0), followed by don't care about release & hold (-1).
|
||||
//
|
||||
// In otherwords: any playing notes are released when the original song ends.
|
||||
func constructPatterns(tracks [][]int, patternLength int) ([][]byte, [][]byte, error) {
|
||||
patternTable := make([][]int, 0)
|
||||
sequences := make([][]byte, 0, len(tracks))
|
||||
for _, t := range tracks {
|
||||
var sequence []byte
|
||||
for s := 0; s < len(t); s += patternLength {
|
||||
pat := t[s : s+patternLength]
|
||||
if len(pat) < patternLength {
|
||||
extension := make([]int, patternLength-len(pat))
|
||||
for i := range extension {
|
||||
if pat[len(pat)-1] > 0 && i == 0 {
|
||||
extension[i] = 0
|
||||
} else {
|
||||
extension[i] = -1
|
||||
}
|
||||
}
|
||||
pat = append(pat, extension...)
|
||||
}
|
||||
// go through the current pattern table to see if there's already a
|
||||
// pattern that could be used
|
||||
patternIndex := -1
|
||||
for j, p := range patternTable {
|
||||
match := true
|
||||
for k, n := range p {
|
||||
if (n > -1 && pat[k] > -1 && n != pat[k]) ||
|
||||
(n == -1 && pat[k] > 1) ||
|
||||
(n > 1 && pat[k] == -1) {
|
||||
match = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if match {
|
||||
// if there was any don't cares in the pattern table where
|
||||
// the new pattern has non don't cares, copy them to the
|
||||
// patterns that was already in the pattern table
|
||||
for k, n := range pat {
|
||||
if n != -1 {
|
||||
patternTable[j][k] = n
|
||||
}
|
||||
}
|
||||
patternIndex = j
|
||||
break
|
||||
}
|
||||
}
|
||||
if patternIndex == -1 {
|
||||
patternIndex = len(patternTable)
|
||||
patternTable = append(patternTable, pat)
|
||||
}
|
||||
if patternIndex > 255 {
|
||||
return nil, nil, errors.New("encoding the song would result more than 256 different unique patterns")
|
||||
}
|
||||
sequence = append(sequence, byte(patternIndex))
|
||||
}
|
||||
sequences = append(sequences, sequence)
|
||||
}
|
||||
// finally, if there are still some don't cares in the table, just replace them with zeros
|
||||
byteTable := make([][]byte, 0, len(patternTable))
|
||||
for _, pat := range patternTable {
|
||||
bytePat := make([]byte, 0, patternLength)
|
||||
for _, n := range pat {
|
||||
if n >= 0 {
|
||||
bytePat = append(bytePat, byte(n))
|
||||
} else {
|
||||
bytePat = append(bytePat, 0)
|
||||
}
|
||||
}
|
||||
byteTable = append(byteTable, bytePat)
|
||||
}
|
||||
return byteTable, sequences, nil
|
||||
}
|
||||
|
||||
func (e *EncodedSong) PatternLength() int {
|
||||
return len(e.Patterns[0])
|
||||
}
|
||||
|
||||
func (e *EncodedSong) SequenceLength() int {
|
||||
return len(e.Sequences[0])
|
||||
}
|
||||
|
||||
func (e *EncodedSong) TotalRows() int {
|
||||
return e.SequenceLength() * e.PatternLength()
|
||||
}
|
||||
|
||||
func EncodeSong(song *sointu.Song) (*EncodedSong, error) {
|
||||
// TODO: we could give the user the possibility to encode the patterns with a different length here also
|
||||
patLength := song.PatternRows()
|
||||
patterns, sequences, err := constructPatterns(flattenPatterns(song), patLength)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error during constructPatterns: %v", err)
|
||||
}
|
||||
return &EncodedSong{Patterns: patterns, Sequences: sequences}, nil
|
||||
}
|
81
compiler/encoded_song_test.go
Normal file
81
compiler/encoded_song_test.go
Normal file
@ -0,0 +1,81 @@
|
||||
package compiler_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/vsariola/sointu"
|
||||
"github.com/vsariola/sointu/compiler"
|
||||
)
|
||||
|
||||
func TestPatternReusing(t *testing.T) {
|
||||
song := sointu.Song{
|
||||
Hold: 1,
|
||||
Tracks: []sointu.Track{{
|
||||
Patterns: [][]byte{{64, 1, 1, 1, 0, 0, 0, 0}, {72, 0, 0, 0, 0, 0, 0, 0}},
|
||||
Sequence: []byte{0, 1},
|
||||
}, {
|
||||
Patterns: [][]byte{{64, 1, 1, 1, 0, 0, 0, 0}, {84, 0, 0, 0, 0, 0, 0, 0}},
|
||||
Sequence: []byte{0, 1},
|
||||
}},
|
||||
}
|
||||
encodedSong, err := compiler.EncodeSong(&song)
|
||||
if err != nil {
|
||||
t.Fatalf("song encoding error: %v", err)
|
||||
}
|
||||
expected := compiler.EncodedSong{
|
||||
Sequences: [][]byte{{0, 1}, {0, 2}},
|
||||
Patterns: [][]byte{{64, 1, 1, 1, 0, 0, 0, 0}, {72, 0, 0, 0, 0, 0, 0, 0}, {84, 0, 0, 0, 0, 0, 0, 0}},
|
||||
}
|
||||
if !reflect.DeepEqual(*encodedSong, expected) {
|
||||
t.Fatalf("got different EncodedSong than expected. got: %v expected: %v", *encodedSong, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnnecessaryHolds(t *testing.T) {
|
||||
song := sointu.Song{
|
||||
Hold: 1,
|
||||
Tracks: []sointu.Track{{
|
||||
Patterns: [][]byte{{64, 1, 1, 1, 0, 1, 0, 0}, {72, 0, 1, 0, 1, 0, 0, 0}},
|
||||
Sequence: []byte{0, 1},
|
||||
}, {
|
||||
Patterns: [][]byte{{64, 1, 1, 1, 0, 0, 1, 0}, {84, 0, 0, 0, 1, 1, 0, 0}},
|
||||
Sequence: []byte{0, 1},
|
||||
}},
|
||||
}
|
||||
encodedSong, err := compiler.EncodeSong(&song)
|
||||
if err != nil {
|
||||
t.Fatalf("song encoding error: %v", err)
|
||||
}
|
||||
expected := compiler.EncodedSong{
|
||||
Sequences: [][]byte{{0, 1}, {0, 2}},
|
||||
Patterns: [][]byte{{64, 1, 1, 1, 0, 0, 0, 0}, {72, 0, 0, 0, 0, 0, 0, 0}, {84, 0, 0, 0, 0, 0, 0, 0}},
|
||||
}
|
||||
if !reflect.DeepEqual(*encodedSong, expected) {
|
||||
t.Fatalf("got different EncodedSong than expected. got: %v expected: %v", *encodedSong, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDontCares(t *testing.T) {
|
||||
song := sointu.Song{
|
||||
Hold: 1,
|
||||
Tracks: []sointu.Track{{
|
||||
Patterns: [][]byte{{64, 1, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}},
|
||||
Sequence: []byte{0, 1},
|
||||
}, {
|
||||
Patterns: [][]byte{{64, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 0, 0, 0, 0, 0}},
|
||||
Sequence: []byte{0, 1},
|
||||
}},
|
||||
}
|
||||
encodedSong, err := compiler.EncodeSong(&song)
|
||||
if err != nil {
|
||||
t.Fatalf("song encoding error: %v", err)
|
||||
}
|
||||
expected := compiler.EncodedSong{
|
||||
Sequences: [][]byte{{0, 1}, {2, 1}},
|
||||
Patterns: [][]byte{{64, 1, 1, 1, 0, 0, 0, 0}, {1, 1, 1, 0, 0, 0, 0, 0}, {64, 1, 1, 1, 1, 1, 1, 1}},
|
||||
}
|
||||
if !reflect.DeepEqual(*encodedSong, expected) {
|
||||
t.Fatalf("got different EncodedSong than expected. got: %v expected: %v", *encodedSong, expected)
|
||||
}
|
||||
}
|
43
sointu.go
43
sointu.go
@ -56,7 +56,8 @@ func (patch Patch) InstrumentForVoice(voice int) (int, error) {
|
||||
|
||||
type Track struct {
|
||||
NumVoices int
|
||||
Sequence []byte `yaml:",flow"`
|
||||
Sequence []byte `yaml:",flow"`
|
||||
Patterns [][]byte `yaml:",flow"`
|
||||
}
|
||||
|
||||
type Synth interface {
|
||||
@ -214,13 +215,12 @@ type Song struct {
|
||||
BPM int
|
||||
Output16Bit bool
|
||||
Hold byte
|
||||
Patterns [][]byte `yaml:",flow"`
|
||||
Tracks []Track
|
||||
Patch Patch
|
||||
}
|
||||
|
||||
func (s *Song) PatternRows() int {
|
||||
return len(s.Patterns[0])
|
||||
return len(s.Tracks[0].Patterns[0])
|
||||
}
|
||||
|
||||
func (s *Song) SequenceLength() int {
|
||||
@ -249,9 +249,16 @@ func (s *Song) Validate() error {
|
||||
if s.BPM < 1 {
|
||||
return errors.New("BPM should be > 0")
|
||||
}
|
||||
for i := range s.Patterns[:len(s.Patterns)-1] {
|
||||
if len(s.Patterns[i]) != len(s.Patterns[i+1]) {
|
||||
return errors.New("Every pattern should have the same length")
|
||||
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] {
|
||||
@ -263,7 +270,7 @@ func (s *Song) Validate() error {
|
||||
for _, track := range s.Tracks {
|
||||
totalTrackVoices += track.NumVoices
|
||||
for _, p := range track.Sequence {
|
||||
if p < 0 || int(p) >= len(s.Patterns) {
|
||||
if p < 0 || int(p) >= len(track.Patterns) {
|
||||
return errors.New("Tracks use a non-existing pattern")
|
||||
}
|
||||
}
|
||||
@ -291,7 +298,7 @@ func Play(synth Synth, song Song) ([]float32, error) {
|
||||
pattern := row / song.PatternRows()
|
||||
for t := range song.Tracks {
|
||||
patternIndex := song.Tracks[t].Sequence[pattern]
|
||||
note := song.Patterns[patternIndex][patternRow]
|
||||
note := song.Tracks[t].Patterns[patternIndex][patternRow]
|
||||
if note > 0 && note <= song.Hold { // anything but hold causes an action.
|
||||
continue
|
||||
}
|
||||
@ -322,17 +329,21 @@ func (s *Song) UpdateHold(newHold byte) error {
|
||||
if newHold == 0 {
|
||||
return errors.New("hold value cannot be 0, 0 is reserved for release")
|
||||
}
|
||||
for _, pat := range s.Patterns {
|
||||
for _, v := range pat {
|
||||
if v > s.Hold && v <= newHold {
|
||||
return errors.New("song uses note values greater or equal to the new hold value")
|
||||
for _, track := range s.Tracks {
|
||||
for _, pat := range track.Patterns {
|
||||
for _, v := range pat {
|
||||
if v > s.Hold && v <= newHold {
|
||||
return errors.New("song uses note values greater or equal to the new hold value")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, pat := range s.Patterns {
|
||||
for i, v := range pat {
|
||||
if v > 0 && v <= s.Hold {
|
||||
pat[i] = newHold
|
||||
for _, track := range s.Tracks {
|
||||
for _, pat := range track.Patterns {
|
||||
for i, v := range pat {
|
||||
if v > 0 && v <= s.Hold {
|
||||
pat[i] = newHold
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ su_render_sampleloop: ; loop through every sample in the row
|
||||
jl su_render_sampleloop
|
||||
{{.Pop .AX}} ; Stack: pushad ptr
|
||||
inc eax
|
||||
cmp eax, {{.Song.TotalRows}}
|
||||
cmp eax, {{.EncodedSong.TotalRows}}
|
||||
jl su_render_rowloop
|
||||
; rewind the stack the entropy of multiple pop {{.AX}} is probably lower than add
|
||||
{{- range slice .Stacklocs $prologsize}}
|
||||
@ -91,7 +91,7 @@ su_render_sampleloop: ; loop through every sample in the row
|
||||
{{- if ne .VoiceTrackBitmask 0}}
|
||||
; The more complicated implementation: one track can trigger multiple voices
|
||||
xor edx, edx
|
||||
mov ebx, {{.Song.PatternRows}} ; we could do xor ebx,ebx; mov bl,PATTERN_SIZE, but that would limit patternsize to 256...
|
||||
mov ebx, {{.EncodedSong.PatternLength}} ; we could do xor ebx,ebx; mov bl,PATTERN_SIZE, but that would limit patternsize to 256...
|
||||
div ebx ; eax = current pattern, edx = current row in pattern
|
||||
{{.Prepare "su_tracks"}}
|
||||
lea {{.SI}}, [{{.Use "su_tracks"}}+{{.AX}}] ; esi points to the pattern data for current track
|
||||
@ -100,7 +100,7 @@ su_render_sampleloop: ; loop through every sample in the row
|
||||
mov {{.BP}}, {{.PTRWORD}} su_synth_obj ; ebp points to the current_voiceno array
|
||||
su_update_voices_trackloop:
|
||||
movzx eax, byte [{{.SI}}] ; eax = current pattern
|
||||
imul eax, {{.Song.PatternRows}} ; eax = offset to current pattern data
|
||||
imul eax, {{.EncodedSong.PatternLength}} ; eax = offset to current pattern data
|
||||
{{- .Prepare "su_patterns" .AX | indent 4}}
|
||||
movzx eax,byte [{{.Use "su_patterns" .AX}},{{.DX}}] ; eax = note
|
||||
push {{.DX}} ; Stack: ptrnrow
|
||||
@ -138,7 +138,7 @@ su_update_voices_skipreset:
|
||||
su_update_voices_nexttrack:
|
||||
pop {{.BX}} ; ebx=first voice of next instrument, Stack: ptrnrow
|
||||
pop {{.DX}} ; edx=patrnrow
|
||||
add {{.SI}}, {{.Song.SequenceLength}}
|
||||
add {{.SI}}, {{.EncodedSong.SequenceLength}}
|
||||
inc {{.BP}}
|
||||
{{- $addrname := len .Song.Tracks | printf "su_synth_obj + %v"}}
|
||||
{{- .Prepare $addrname | indent 8}}
|
||||
@ -149,7 +149,7 @@ su_update_voices_nexttrack:
|
||||
; The simple implementation: each track triggers always the same voice
|
||||
xor edx, edx
|
||||
xor ebx, ebx
|
||||
mov bl, {{.Song.PatternRows}} ; rows per pattern
|
||||
mov bl, {{.EncodedSong.PatternLength}} ; rows per pattern
|
||||
div ebx ; eax = current pattern, edx = current row in pattern
|
||||
{{- .Prepare "su_tracks" | indent 4}}
|
||||
lea {{.SI}}, [{{.Use "su_tracks"}}+{{.AX}}]; esi points to the pattern data for current track
|
||||
@ -157,7 +157,7 @@ su_update_voices_nexttrack:
|
||||
mov bl, {{len .Song.Tracks}} ; MAX_TRACKS is always <= 32 so this is ok
|
||||
su_update_voices_trackloop:
|
||||
movzx eax, byte [{{.SI}}] ; eax = current pattern
|
||||
imul eax, {{.Song.PatternRows}} ; multiply by rows per pattern, eax = offset to current pattern data
|
||||
imul eax, {{.EncodedSong.PatternLength}} ; multiply by rows per pattern, eax = offset to current pattern data
|
||||
{{- .Prepare "su_patterns" .AX | indent 8}}
|
||||
movzx eax, byte [{{.Use "su_patterns" .AX}} + {{.DX}}] ; ecx = note
|
||||
cmp al, {{.Song.Hold}} ; anything but hold causes action
|
||||
@ -173,7 +173,7 @@ su_update_voices_retrigger:
|
||||
su_update_voices_nexttrack:
|
||||
add {{.DI}}, su_voice.size
|
||||
su_update_voices_skipadd:
|
||||
add {{.SI}}, {{.Song.SequenceLength}}
|
||||
add {{.SI}}, {{.EncodedSong.SequenceLength}}
|
||||
dec ebx
|
||||
jnz short su_update_voices_trackloop
|
||||
ret
|
||||
@ -185,7 +185,7 @@ su_update_voices_skipadd:
|
||||
; Patterns
|
||||
;-------------------------------------------------------------------------------
|
||||
{{.Data "su_patterns"}}
|
||||
{{- range .Song.Patterns}}
|
||||
{{- range .EncodedSong.Patterns}}
|
||||
db {{. | toStrings | join ","}}
|
||||
{{- end}}
|
||||
|
||||
@ -193,8 +193,8 @@ su_update_voices_skipadd:
|
||||
; Tracks
|
||||
;-------------------------------------------------------------------------------
|
||||
{{.Data "su_tracks"}}
|
||||
{{- range .Song.Tracks}}
|
||||
db {{.Sequence | toStrings | join ","}}
|
||||
{{- range .EncodedSong.Sequences}}
|
||||
db {{. | toStrings | join ","}}
|
||||
{{- end}}
|
||||
|
||||
{{- if gt (.SampleOffsets | len) 0}}
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/}}
|
||||
{{- .SetLabel "su_patterns"}}
|
||||
{{- $m := .}}
|
||||
{{- range .Song.Patterns}}
|
||||
{{- range .EncodedSong.Patterns}}
|
||||
{{- range .}}
|
||||
{{- $.DataB .}}
|
||||
{{- end}}
|
||||
@ -20,8 +20,8 @@
|
||||
*/}}
|
||||
{{- .SetLabel "su_tracks"}}
|
||||
{{- $m := .}}
|
||||
{{- range .Song.Tracks}}
|
||||
{{- range .Sequence}}
|
||||
{{- range .EncodedSong.Sequences}}
|
||||
{{- range .}}
|
||||
{{- $.DataB .}}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
@ -111,7 +111,7 @@
|
||||
;; TODO: only export start and length with certain compiler options; in demo use, they can be hard coded
|
||||
;; in the intro
|
||||
(global $outputStart (export "s") i32 (i32.const 8388608)) ;; TODO: do not hard code, layout memory somehow intelligently
|
||||
(global $outputLength (export "l") i32 (i32.const {{if .Song.Output16Bit}}{{mul .Song.TotalRows .Song.SamplesPerRow 4}}{{else}}{{mul .Song.TotalRows .Song.SamplesPerRow 8}}{{end}}))
|
||||
(global $outputLength (export "l") i32 (i32.const {{if .Song.Output16Bit}}{{mul .EncodedSong.TotalRows .Song.SamplesPerRow 4}}{{else}}{{mul .EncodedSong.TotalRows .Song.SamplesPerRow 8}}{{end}}))
|
||||
(global $output16bit (export "t") i32 (i32.const {{if .Song.Output16Bit}}1{{else}}0{{end}}))
|
||||
|
||||
|
||||
@ -183,17 +183,17 @@
|
||||
(br_if $sample_loop (i32.lt_s (global.get $sample) (i32.const {{.Song.SamplesPerRow}})))
|
||||
end
|
||||
(global.set $row (i32.add (global.get $row) (i32.const 1)))
|
||||
(br_if $row_loop (i32.lt_s (global.get $row) (i32.const {{.Song.PatternRows}})))
|
||||
(br_if $row_loop (i32.lt_s (global.get $row) (i32.const {{.EncodedSong.PatternLength}})))
|
||||
end
|
||||
(global.set $pattern (i32.add (global.get $pattern) (i32.const 1)))
|
||||
(br_if $pattern_loop (i32.lt_s (global.get $pattern) (i32.const {{.Song.SequenceLength}})))
|
||||
(br_if $pattern_loop (i32.lt_s (global.get $pattern) (i32.const {{.EncodedSong.SequenceLength}})))
|
||||
end
|
||||
)
|
||||
|
||||
{{- if ne .VoiceTrackBitmask 0}}
|
||||
;; the complex implementation of update_voices: at least one track has more than one voice
|
||||
(func $su_update_voices (local $si i32) (local $di i32) (local $tracksRemaining i32) (local $note i32) (local $firstVoice i32) (local $nextTrackStartsAt i32) (local $numVoices i32) (local $voiceNo i32)
|
||||
(local.set $tracksRemaining (i32.const {{len .Song.Tracks}}))
|
||||
(local.set $tracksRemaining (i32.const {{len .EncodedSong.Sequences}}))
|
||||
(local.set $si (global.get $pattern))
|
||||
(local.set $nextTrackStartsAt (i32.const 0))
|
||||
loop $track_loop
|
||||
@ -212,7 +212,7 @@
|
||||
br_if $voiceLoop
|
||||
end
|
||||
(i32.load8_u offset={{index .Labels "su_tracks"}} (local.get $si))
|
||||
(i32.mul (i32.const {{.Song.PatternRows}}))
|
||||
(i32.mul (i32.const {{.EncodedSong.PatternLength}}))
|
||||
(i32.add (global.get $row))
|
||||
(i32.load8_u offset={{index .Labels "su_patterns"}})
|
||||
(local.tee $note)
|
||||
@ -246,7 +246,7 @@
|
||||
(i32.store8 offset=768 (local.get $tracksRemaining) (local.get $voiceNo))
|
||||
))
|
||||
))
|
||||
(local.set $si (i32.add (local.get $si) (i32.const {{.Song.SequenceLength}})))
|
||||
(local.set $si (i32.add (local.get $si) (i32.const {{.EncodedSong.SequenceLength}})))
|
||||
(br_if $track_loop (local.tee $tracksRemaining (i32.sub (local.get $tracksRemaining) (i32.const 1))))
|
||||
end
|
||||
)
|
||||
@ -254,12 +254,12 @@
|
||||
{{- else}}
|
||||
;; the simple implementation of update_voices: each track has exactly one voice
|
||||
(func $su_update_voices (local $si i32) (local $di i32) (local $tracksRemaining i32) (local $note i32)
|
||||
(local.set $tracksRemaining (i32.const {{len .Song.Tracks}}))
|
||||
(local.set $tracksRemaining (i32.const {{len .EncodedSong.Sequences}}))
|
||||
(local.set $si (global.get $pattern))
|
||||
(local.set $di (i32.const 4160))
|
||||
loop $track_loop
|
||||
(i32.load8_u offset={{index .Labels "su_tracks"}} (local.get $si))
|
||||
(i32.mul (i32.const {{.Song.PatternRows}}))
|
||||
(i32.mul (i32.const {{.EncodedSong.PatternLength}}))
|
||||
(i32.add (global.get $row))
|
||||
(i32.load8_u offset={{index .Labels "su_patterns"}})
|
||||
(local.tee $note)
|
||||
@ -271,7 +271,7 @@
|
||||
))
|
||||
))
|
||||
(local.set $di (i32.add (local.get $di) (i32.const 4096)))
|
||||
(local.set $si (i32.add (local.get $si) (i32.const {{.Song.SequenceLength}})))
|
||||
(local.set $si (i32.add (local.get $si) (i32.const {{.EncodedSong.SequenceLength}})))
|
||||
(br_if $track_loop (local.tee $tracksRemaining (i32.sub (local.get $tracksRemaining) (i32.const 1))))
|
||||
end
|
||||
)
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,14 +1,16 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 0, 0, 68, 0, 0, 0, 66, 0, 0, 0, 69, 0, 0, 0], [0, 68, 0, 0, 71, 0, 0, 0, 69, 0, 0, 0, 73, 0, 0, 0], [0, 0, 71, 0, 75, 0, 0, 0, 73, 0, 0, 0, 76, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 0, 0, 68, 0, 0, 0, 66, 0, 0, 0, 69, 0, 0, 0]]
|
||||
- numvoices: 1
|
||||
sequence: [1]
|
||||
sequence: [0]
|
||||
patterns: [[0, 68, 0, 0, 71, 0, 0, 0, 69, 0, 0, 0, 73, 0, 0, 0]]
|
||||
- numvoices: 1
|
||||
sequence: [2]
|
||||
sequence: [0]
|
||||
patterns: [[0, 0, 71, 0, 75, 0, 0, 0, 73, 0, 0, 0, 76, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 3
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,12 +1,13 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65], [76, 0, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65]]
|
||||
- numvoices: 1
|
||||
sequence: [1]
|
||||
sequence: [0]
|
||||
patterns: [[76, 0, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,12 +1,13 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65], [76, 0, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65]]
|
||||
- numvoices: 1
|
||||
sequence: [1]
|
||||
sequence: [0]
|
||||
patterns: [[76, 0, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: true
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,12 +1,13 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 64, 1, 1, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
- numvoices: 1
|
||||
sequence: [1]
|
||||
sequence: [0]
|
||||
patterns: [[0, 0, 0, 0, 0, 0, 0, 0, 64, 1, 1, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,12 +1,13 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
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]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [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]]
|
||||
- numvoices: 1
|
||||
sequence: [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]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,12 +1,13 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
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]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [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]]
|
||||
- numvoices: 1
|
||||
sequence: [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]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 68, 1, 32, 1, 1, 1, 75, 1, 78, 1, 1, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 2
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 68, 1, 32, 1, 1, 1, 75, 1, 78, 1, 1, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,12 +1,13 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 0, 64, 64, 64, 0, 64, 64, 64, 0, 64, 64, 65, 0, 65, 65], [64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [81, 0, 52, 0, 81, 0, 52, 0, 81, 0, 52, 0, 81, 0, 52, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0, 0]
|
||||
patterns: [[64, 0, 64, 64, 64, 0, 64, 64, 64, 0, 64, 64, 65, 0, 65, 65]]
|
||||
- numvoices: 1
|
||||
sequence: [1, 2]
|
||||
sequence: [0, 1]
|
||||
patterns: [[64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [81, 0, 52, 0, 81, 0, 52, 0, 81, 0, 52, 0, 81, 0, 52, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
bpm: 100
|
||||
output16bit: false
|
||||
hold: 1
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
tracks:
|
||||
- numvoices: 1
|
||||
sequence: [0]
|
||||
patterns: [[64, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]]
|
||||
patch:
|
||||
instruments:
|
||||
- numvoices: 1
|
||||
|
@ -4,15 +4,9 @@ import "github.com/vsariola/sointu"
|
||||
|
||||
var defaultSong = sointu.Song{
|
||||
BPM: 100,
|
||||
Patterns: [][]byte{
|
||||
{64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0},
|
||||
{64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 75, 0, 75, 0, 80, 0},
|
||||
{0, 0, 64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0},
|
||||
{32, 0, 64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 68, 0, 68, 0},
|
||||
},
|
||||
Tracks: []sointu.Track{
|
||||
{NumVoices: 2, Sequence: []byte{0, 0, 0, 1}},
|
||||
{NumVoices: 2, Sequence: []byte{2, 2, 2, 3}},
|
||||
{NumVoices: 2, Sequence: []byte{0, 0, 0, 1}, Patterns: [][]byte{{64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0, 0, 0}, {64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 75, 0, 75, 0, 80, 0}}},
|
||||
{NumVoices: 2, Sequence: []byte{0, 0, 0, 1}, Patterns: [][]byte{{0, 0, 64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 78, 0, 0, 0}, {32, 0, 64, 0, 68, 0, 32, 0, 0, 0, 75, 0, 68, 0, 68, 0}}},
|
||||
},
|
||||
Patch: sointu.Patch{
|
||||
Instruments: []sointu.Instrument{{NumVoices: 4, Units: []sointu.Unit{
|
||||
|
@ -117,12 +117,12 @@ func (t *Tracker) KeyEvent(e key.Event) bool {
|
||||
|
||||
// setCurrent sets the (note) value in current pattern under cursor to iv
|
||||
func (t *Tracker) setCurrent(iv byte) {
|
||||
t.song.Patterns[t.song.Tracks[t.ActiveTrack].Sequence[t.DisplayPattern]][t.CursorRow] = iv
|
||||
t.song.Tracks[t.ActiveTrack].Patterns[t.song.Tracks[t.ActiveTrack].Sequence[t.DisplayPattern]][t.CursorRow] = iv
|
||||
}
|
||||
|
||||
// getCurrent returns the current (note) value in current pattern under the cursor
|
||||
func (t *Tracker) getCurrent() byte {
|
||||
return t.song.Patterns[t.song.Tracks[t.ActiveTrack].Sequence[t.DisplayPattern]][t.CursorRow]
|
||||
return t.song.Tracks[t.ActiveTrack].Patterns[t.song.Tracks[t.ActiveTrack].Sequence[t.DisplayPattern]][t.CursorRow]
|
||||
}
|
||||
|
||||
// NotePressed handles incoming key presses while in the note column
|
||||
|
@ -30,7 +30,7 @@ func (t *Tracker) layoutTracker(gtx layout.Context) layout.Dimensions {
|
||||
}
|
||||
for i, trk := range t.song.Tracks {
|
||||
flexTracks[i] = layout.Rigid(Lowered(t.layoutTrack(
|
||||
t.song.Patterns[trk.Sequence[t.DisplayPattern]],
|
||||
trk.Patterns[trk.Sequence[t.DisplayPattern]],
|
||||
t.ActiveTrack == i,
|
||||
t.CursorRow,
|
||||
t.CursorColumn,
|
||||
|
@ -96,7 +96,7 @@ func (t *Tracker) sequencerLoop(closer <-chan struct{}) {
|
||||
notes := make([]Note, 0, 32)
|
||||
for track := range t.song.Tracks {
|
||||
patternIndex := t.song.Tracks[track].Sequence[t.PlayPattern]
|
||||
note := t.song.Patterns[patternIndex][t.PlayRow]
|
||||
note := t.song.Tracks[track].Patterns[patternIndex][t.PlayRow]
|
||||
if note == 1 { // anything but hold causes an action.
|
||||
continue
|
||||
}
|
||||
|
Reference in New Issue
Block a user