mirror of
				https://github.com/vsariola/sointu.git
				synced 2025-11-04 00:45:35 -05:00 
			
		
		
		
	refactor(vm): simplify flattenSequence code
This commit is contained in:
		@ -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)
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user