mirror of
https://github.com/vsariola/sointu.git
synced 2025-06-04 01:28:45 -04:00
refactor(vm): simplify flattenSequence code
This commit is contained in:
parent
a2723829da
commit
203e8a3ccc
@ -7,48 +7,26 @@ import (
|
||||
"github.com/vsariola/sointu"
|
||||
)
|
||||
|
||||
// fixPatternLength makes sure that every pattern is the same length. During
|
||||
// composing. Patterns shorter than the given length are padded with 1 / "hold";
|
||||
// patterns longer than the given length are cropped.
|
||||
func fixPatternLength(patterns []sointu.Pattern, fixedLength int) [][]int {
|
||||
patternData := make([]int, len(patterns)*fixedLength)
|
||||
ret := make([][]int, len(patterns))
|
||||
for i, pat := range patterns {
|
||||
for j, note := range pat {
|
||||
patternData[j] = int(note)
|
||||
}
|
||||
for j := len(pat); j < fixedLength; j++ {
|
||||
patternData[j] = 1 // pad with hold
|
||||
}
|
||||
ret[i], patternData = patternData[:fixedLength], patternData[fixedLength:]
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// flattenSequence looks up a sequence of patterns and concatenates them into a
|
||||
// single linear array of notes. Note that variable length patterns are
|
||||
// concatenated as such; call fixPatternLength first if you want every pattern
|
||||
// to be constant length.
|
||||
func flattenSequence(patterns [][]int, sequence []int, songLength int, rowsPerPattern int, releaseFirst bool) []int {
|
||||
// flattenSequence returns the notes of a track in a single linear array of
|
||||
// integer notes.
|
||||
func flattenSequence(t sointu.Track, songLength int, rowsPerPattern int, releaseFirst bool) []int {
|
||||
sumLen := rowsPerPattern * songLength
|
||||
notes := make([]int, sumLen)
|
||||
window := notes
|
||||
k := 0
|
||||
for i := 0; i < songLength; i++ {
|
||||
patIndex := -1
|
||||
if i < len(sequence) {
|
||||
patIndex = sequence[i]
|
||||
patIndex := t.Order.Get(i)
|
||||
var pattern sointu.Pattern = nil
|
||||
if patIndex >= 0 && patIndex < len(t.Patterns) {
|
||||
pattern = t.Patterns[patIndex]
|
||||
}
|
||||
var k int
|
||||
if patIndex >= 0 && patIndex < len(patterns) {
|
||||
k = copy(window, patterns[patIndex])
|
||||
for j := 0; j < rowsPerPattern; j++ {
|
||||
note := int(pattern.Get(j))
|
||||
if releaseFirst && i == 0 && j == 0 && note == 1 {
|
||||
note = 0
|
||||
}
|
||||
notes[k] = note
|
||||
k++
|
||||
}
|
||||
for ; k < rowsPerPattern; k++ {
|
||||
window[k] = 1 // pad with holds
|
||||
}
|
||||
if i == 0 && window[0] == 1 && releaseFirst {
|
||||
window[0] = 0
|
||||
}
|
||||
window = window[rowsPerPattern:]
|
||||
}
|
||||
return notes
|
||||
}
|
||||
@ -168,20 +146,11 @@ func intsToBytes(array []int) ([]byte, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func bytesToInts(array []byte) []int {
|
||||
ret := make([]int, len(array))
|
||||
for i, v := range array {
|
||||
ret[i] = int(v)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func ConstructPatterns(song *sointu.Song) ([][]byte, [][]byte, error) {
|
||||
sequences := make([][]byte, len(song.Score.Tracks))
|
||||
var patterns [][]int
|
||||
for i, t := range song.Score.Tracks {
|
||||
fixed := fixPatternLength(t.Patterns, song.Score.RowsPerPattern)
|
||||
flat := flattenSequence(fixed, t.Order, song.Score.Length, song.Score.RowsPerPattern, true)
|
||||
flat := flattenSequence(t, song.Score.Length, song.Score.RowsPerPattern, true)
|
||||
dontCares := markDontCares(flat)
|
||||
// TODO: we could give the user the possibility to use another length during encoding that during composing
|
||||
chunks := splitSequence(dontCares, song.Score.RowsPerPattern)
|
||||
|
Loading…
x
Reference in New Issue
Block a user