mirror of
https://github.com/vsariola/sointu.git
synced 2025-05-28 03:10:24 -04:00
refactor(sointu): add explicit RowsPerPattern to the song
This commit is contained in:
parent
08dcbb9edb
commit
61437db0d6
@ -40,7 +40,7 @@ func TestOscillatSine(t *testing.T) {
|
|||||||
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, 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}
|
song := sointu.Song{BPM: 100, RowsPerPattern: 16, 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)
|
||||||
|
@ -167,7 +167,7 @@ func bytesToInts(array []byte) []int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ConstructPatterns(song *sointu.Song) ([][]byte, [][]byte, error) {
|
func ConstructPatterns(song *sointu.Song) ([][]byte, [][]byte, error) {
|
||||||
patLength := song.PatternRows()
|
patLength := song.RowsPerPattern
|
||||||
sequences := make([][]byte, len(song.Tracks))
|
sequences := make([][]byte, len(song.Tracks))
|
||||||
var patterns [][]int
|
var patterns [][]int
|
||||||
for i, t := range song.Tracks {
|
for i, t := range song.Tracks {
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
func TestPatternReusing(t *testing.T) {
|
func TestPatternReusing(t *testing.T) {
|
||||||
song := sointu.Song{
|
song := sointu.Song{
|
||||||
|
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},
|
Sequence: []byte{0, 1},
|
||||||
@ -34,6 +35,7 @@ func TestPatternReusing(t *testing.T) {
|
|||||||
|
|
||||||
func TestUnnecessaryHolds(t *testing.T) {
|
func TestUnnecessaryHolds(t *testing.T) {
|
||||||
song := sointu.Song{
|
song := sointu.Song{
|
||||||
|
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},
|
Sequence: []byte{0, 1},
|
||||||
@ -58,6 +60,7 @@ func TestUnnecessaryHolds(t *testing.T) {
|
|||||||
|
|
||||||
func TestDontCares(t *testing.T) {
|
func TestDontCares(t *testing.T) {
|
||||||
song := sointu.Song{
|
song := sointu.Song{
|
||||||
|
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},
|
Sequence: []byte{0, 1},
|
||||||
|
17
sointu.go
17
sointu.go
@ -254,9 +254,10 @@ var UnitTypes = map[string]([]UnitParameter){
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Song struct {
|
type Song struct {
|
||||||
BPM int
|
BPM int
|
||||||
Tracks []Track
|
RowsPerPattern int
|
||||||
Patch Patch
|
Tracks []Track
|
||||||
|
Patch Patch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Song) Copy() Song {
|
func (s *Song) Copy() Song {
|
||||||
@ -267,16 +268,12 @@ func (s *Song) Copy() Song {
|
|||||||
return Song{BPM: s.BPM, Tracks: tracks, Patch: s.Patch.Copy()}
|
return Song{BPM: s.BPM, Tracks: tracks, Patch: s.Patch.Copy()}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Song) PatternRows() int {
|
|
||||||
return len(s.Tracks[0].Patterns[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Song) SequenceLength() int {
|
func (s *Song) SequenceLength() int {
|
||||||
return len(s.Tracks[0].Sequence)
|
return len(s.Tracks[0].Sequence)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Song) TotalRows() int {
|
func (s *Song) TotalRows() int {
|
||||||
return s.PatternRows() * s.SequenceLength()
|
return s.RowsPerPattern * s.SequenceLength()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Song) SamplesPerRow() int {
|
func (s *Song) SamplesPerRow() int {
|
||||||
@ -350,8 +347,8 @@ func Play(synth Synth, song Song) ([]float32, error) {
|
|||||||
buffer := make([]float32, 0, initialCapacity)
|
buffer := make([]float32, 0, initialCapacity)
|
||||||
rowbuffer := make([]float32, song.SamplesPerRow()*2)
|
rowbuffer := make([]float32, song.SamplesPerRow()*2)
|
||||||
for row := 0; row < song.TotalRows(); row++ {
|
for row := 0; row < song.TotalRows(); row++ {
|
||||||
patternRow := row % song.PatternRows()
|
patternRow := row % song.RowsPerPattern
|
||||||
pattern := row / song.PatternRows()
|
pattern := row / song.RowsPerPattern
|
||||||
for t := range song.Tracks {
|
for t := range song.Tracks {
|
||||||
patternIndex := song.Tracks[t].Sequence[pattern]
|
patternIndex := song.Tracks[t].Sequence[pattern]
|
||||||
note := song.Tracks[t].Patterns[patternIndex][patternRow]
|
note := song.Tracks[t].Patterns[patternIndex][patternRow]
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#define SU_SAMPLE_RATE 44100
|
#define SU_SAMPLE_RATE 44100
|
||||||
#define SU_BPM {{.Song.BPM}}
|
#define SU_BPM {{.Song.BPM}}
|
||||||
#define SU_PATTERN_SIZE {{.Song.PatternRows}}
|
#define SU_PATTERN_SIZE {{.Song.RowsPerPattern}}
|
||||||
#define SU_MAX_PATTERNS {{.Song.SequenceLength}}
|
#define SU_MAX_PATTERNS {{.Song.SequenceLength}}
|
||||||
#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*4*60/(SU_BPM*16))
|
#define SU_SAMPLES_PER_ROW (SU_SAMPLE_RATE*4*60/(SU_BPM*16))
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 8
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [1, 0, 2, 0, 3, 0, 4, 0]
|
sequence: [1, 0, 2, 0, 3, 0, 4, 0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 8
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [1, 0, 2, 0, 3, 0, 4, 0]
|
sequence: [1, 0, 2, 0, 3, 0, 4, 0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 2
|
- numvoices: 2
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0, 0]
|
sequence: [0, 0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
bpm: 100
|
bpm: 100
|
||||||
|
rowsperpattern: 16
|
||||||
tracks:
|
tracks:
|
||||||
- numvoices: 1
|
- numvoices: 1
|
||||||
sequence: [0]
|
sequence: [0]
|
||||||
|
@ -13,7 +13,8 @@ var defaultInstrument = sointu.Instrument{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var defaultSong = sointu.Song{
|
var defaultSong = sointu.Song{
|
||||||
BPM: 100,
|
BPM: 100,
|
||||||
|
RowsPerPattern: 16,
|
||||||
Tracks: []sointu.Track{
|
Tracks: []sointu.Track{
|
||||||
{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{{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}}},
|
{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}}},
|
||||||
|
@ -75,7 +75,7 @@ func (t *Tracker) KeyEvent(e key.Event) bool {
|
|||||||
case key.NameUpArrow:
|
case key.NameUpArrow:
|
||||||
delta := -1
|
delta := -1
|
||||||
if e.Modifiers.Contain(key.ModCtrl) {
|
if e.Modifiers.Contain(key.ModCtrl) {
|
||||||
delta = -t.song.PatternRows()
|
delta = -t.song.RowsPerPattern
|
||||||
}
|
}
|
||||||
t.Cursor.Row += delta
|
t.Cursor.Row += delta
|
||||||
t.Cursor.Clamp(t.song)
|
t.Cursor.Clamp(t.song)
|
||||||
@ -87,7 +87,7 @@ func (t *Tracker) KeyEvent(e key.Event) bool {
|
|||||||
case key.NameDownArrow:
|
case key.NameDownArrow:
|
||||||
delta := 1
|
delta := 1
|
||||||
if e.Modifiers.Contain(key.ModCtrl) {
|
if e.Modifiers.Contain(key.ModCtrl) {
|
||||||
delta = t.song.PatternRows()
|
delta = t.song.RowsPerPattern
|
||||||
}
|
}
|
||||||
t.Cursor.Row += delta
|
t.Cursor.Row += delta
|
||||||
t.Cursor.Clamp(t.song)
|
t.Cursor.Clamp(t.song)
|
||||||
|
@ -18,21 +18,21 @@ type SongRect struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *SongRow) Wrap(song sointu.Song) {
|
func (r *SongRow) Wrap(song sointu.Song) {
|
||||||
totalRow := r.Pattern*song.PatternRows() + r.Row
|
totalRow := r.Pattern*song.RowsPerPattern + r.Row
|
||||||
r.Row = mod(totalRow, song.PatternRows())
|
r.Row = mod(totalRow, song.RowsPerPattern)
|
||||||
r.Pattern = mod((totalRow-r.Row)/song.PatternRows(), song.SequenceLength())
|
r.Pattern = mod((totalRow-r.Row)/song.RowsPerPattern, song.SequenceLength())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *SongRow) Clamp(song sointu.Song) {
|
func (r *SongRow) Clamp(song sointu.Song) {
|
||||||
totalRow := r.Pattern*song.PatternRows() + r.Row
|
totalRow := r.Pattern*song.RowsPerPattern + r.Row
|
||||||
if totalRow < 0 {
|
if totalRow < 0 {
|
||||||
totalRow = 0
|
totalRow = 0
|
||||||
}
|
}
|
||||||
if totalRow >= song.TotalRows() {
|
if totalRow >= song.TotalRows() {
|
||||||
totalRow = song.TotalRows() - 1
|
totalRow = song.TotalRows() - 1
|
||||||
}
|
}
|
||||||
r.Row = totalRow % song.PatternRows()
|
r.Row = totalRow % song.RowsPerPattern
|
||||||
r.Pattern = ((totalRow - r.Row) / song.PatternRows()) % song.SequenceLength()
|
r.Pattern = ((totalRow - r.Row) / song.RowsPerPattern) % song.SequenceLength()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *SongPoint) Wrap(song sointu.Song) {
|
func (p *SongPoint) Wrap(song sointu.Song) {
|
||||||
|
@ -26,7 +26,7 @@ func (t *Tracker) layoutTrack(trackNo int) layout.Widget {
|
|||||||
op.Offset(f32.Pt(0, float32(gtx.Constraints.Max.Y/2)-trackRowHeight)).Add(gtx.Ops)
|
op.Offset(f32.Pt(0, float32(gtx.Constraints.Max.Y/2)-trackRowHeight)).Add(gtx.Ops)
|
||||||
// TODO: this is a time bomb; as soon as one of the patterns is not the same length as rest. Find a solution
|
// TODO: this is a time bomb; as soon as one of the patterns is not the same length as rest. Find a solution
|
||||||
// to fix the pattern lengths to a constant value
|
// to fix the pattern lengths to a constant value
|
||||||
cursorSongRow := t.Cursor.Pattern*t.song.PatternRows() + t.Cursor.Row
|
cursorSongRow := t.Cursor.Pattern*t.song.RowsPerPattern + t.Cursor.Row
|
||||||
op.Offset(f32.Pt(0, (-1*trackRowHeight)*float32(cursorSongRow))).Add(gtx.Ops)
|
op.Offset(f32.Pt(0, (-1*trackRowHeight)*float32(cursorSongRow))).Add(gtx.Ops)
|
||||||
patternRect := SongRect{
|
patternRect := SongRect{
|
||||||
Corner1: SongPoint{SongRow: SongRow{Pattern: t.Cursor.Pattern}, Track: t.Cursor.Track},
|
Corner1: SongPoint{SongRow: SongRow{Pattern: t.Cursor.Pattern}, Track: t.Cursor.Track},
|
||||||
@ -38,7 +38,7 @@ func (t *Tracker) layoutTrack(trackNo int) layout.Widget {
|
|||||||
}
|
}
|
||||||
for i, s := range t.song.Tracks[trackNo].Sequence {
|
for i, s := range t.song.Tracks[trackNo].Sequence {
|
||||||
if patternRect.Contains(SongPoint{Track: trackNo, SongRow: SongRow{Pattern: i}}) {
|
if patternRect.Contains(SongPoint{Track: trackNo, SongRow: SongRow{Pattern: i}}) {
|
||||||
paint.FillShape(gtx.Ops, activeTrackColor, clip.Rect{Max: image.Pt(trackWidth, trackRowHeight*t.song.PatternRows())}.Op())
|
paint.FillShape(gtx.Ops, activeTrackColor, clip.Rect{Max: image.Pt(trackWidth, trackRowHeight*t.song.RowsPerPattern)}.Op())
|
||||||
}
|
}
|
||||||
for j, c := range t.song.Tracks[trackNo].Patterns[s] {
|
for j, c := range t.song.Tracks[trackNo].Patterns[s] {
|
||||||
songRow := SongRow{Pattern: i, Row: j}
|
songRow := SongRow{Pattern: i, Row: j}
|
||||||
|
@ -188,7 +188,7 @@ func (t *Tracker) AddTrack() {
|
|||||||
t.SaveUndo()
|
t.SaveUndo()
|
||||||
if t.song.TotalTrackVoices() < t.song.Patch.TotalVoices() {
|
if t.song.TotalTrackVoices() < t.song.Patch.TotalVoices() {
|
||||||
seq := make([]byte, t.song.SequenceLength())
|
seq := make([]byte, t.song.SequenceLength())
|
||||||
patterns := [][]byte{make([]byte, t.song.PatternRows())}
|
patterns := [][]byte{make([]byte, t.song.RowsPerPattern)}
|
||||||
t.song.Tracks = append(t.song.Tracks, sointu.Track{
|
t.song.Tracks = append(t.song.Tracks, sointu.Track{
|
||||||
NumVoices: 1,
|
NumVoices: 1,
|
||||||
Patterns: patterns,
|
Patterns: patterns,
|
||||||
@ -233,7 +233,7 @@ func (t *Tracker) SetCurrentPattern(pat byte) {
|
|||||||
if int(pat) >= length {
|
if int(pat) >= length {
|
||||||
tail := make([][]byte, int(pat)-length+1)
|
tail := make([][]byte, int(pat)-length+1)
|
||||||
for i := range tail {
|
for i := range tail {
|
||||||
tail[i] = make([]byte, t.song.PatternRows())
|
tail[i] = make([]byte, t.song.RowsPerPattern)
|
||||||
}
|
}
|
||||||
t.song.Tracks[t.Cursor.Track].Patterns = append(t.song.Tracks[t.Cursor.Track].Patterns, tail...)
|
t.song.Tracks[t.Cursor.Track].Patterns = append(t.song.Tracks[t.Cursor.Track].Patterns, tail...)
|
||||||
}
|
}
|
||||||
@ -261,8 +261,8 @@ func (t *Tracker) SetSongLength(value int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tracker) getSelectionRange() (int, int, int, int) {
|
func (t *Tracker) getSelectionRange() (int, int, int, int) {
|
||||||
r1 := t.Cursor.Pattern*t.song.PatternRows() + t.Cursor.Row
|
r1 := t.Cursor.Pattern*t.song.RowsPerPattern + t.Cursor.Row
|
||||||
r2 := t.SelectionCorner.Pattern*t.song.PatternRows() + t.SelectionCorner.Row
|
r2 := t.SelectionCorner.Pattern*t.song.RowsPerPattern + t.SelectionCorner.Row
|
||||||
if r2 < r1 {
|
if r2 < r1 {
|
||||||
r1, r2 = r2, r1
|
r1, r2 = r2, r1
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user