1
0
mirror of https://github.com/vsariola/sointu.git synced 2025-08-13 09:44:37 -04:00

feat(vm): construct minimal delaytime table using greedy matching

The idea is to find a minimal array that contains all the delay times and then point all delay times into this array.
This commit is contained in:
vsariola
2021-03-26 23:07:20 +02:00
parent 763c4f5136
commit 9b4608e31e
2 changed files with 150 additions and 23 deletions

@ -42,6 +42,11 @@ func Encode(patch sointu.Patch, featureSet FeatureSet) (*BytePatch, error) {
globalAddrs := map[int]uint16{}
globalFixups := map[int]([]int){}
voiceNo := 0
delayTable, delayIndices := constructDelayTimeTable(patch)
c.DelayTimes = make([]uint16, len(delayTable))
for i := range delayTable {
c.DelayTimes[i] = uint16(delayTable[i])
}
for instrIndex, instr := range patch {
if len(instr.Units) > 63 {
return nil, errors.New("An instrument can have a maximum of 63 units")
@ -52,7 +57,7 @@ func Encode(patch sointu.Patch, featureSet FeatureSet) (*BytePatch, error) {
localAddrs := map[int]uint16{}
localFixups := map[int]([]int){}
localUnitNo := 0
for _, unit := range instr.Units {
for unitIndex, unit := range instr.Units {
if unit.Type == "" { // empty units are just ignored & skipped
continue
}
@ -167,28 +172,7 @@ func Encode(patch sointu.Patch, featureSet FeatureSet) (*BytePatch, error) {
continue // skip encoding delays without any delay lines
}
countTrack := count*2 - 1 + unit.Parameters["notetracking"] // 1 means no note tracking and 1 delay, 2 means notetracking with 1 delay, 3 means no note tracking and 2 delays etc.
matchIndex := -1
for i := 0; i <= len(c.DelayTimes)-len(unit.VarArgs); i++ {
match := true
for j, v := range unit.VarArgs {
if uint16(v) != c.DelayTimes[i+j] {
match = false
break
}
}
if match {
matchIndex = i
break
}
}
if matchIndex > -1 {
values = append(values, byte(matchIndex), byte(countTrack))
} else {
values = append(values, byte(len(c.DelayTimes)), byte(countTrack))
for _, v := range unit.VarArgs {
c.DelayTimes = append(c.DelayTimes, uint16(v))
}
}
values = append(values, byte(delayIndices[instrIndex][unitIndex]), byte(countTrack))
}
c.Commands = append(c.Commands, byte(opcode+unit.Parameters["stereo"]))
c.Values = append(c.Values, values...)