mirror of
https://github.com/vsariola/sointu.git
synced 2026-02-08 16:50:12 -05:00
feat: add multithreaded rendering to the tracker side
The compiled player does not support multithreading, but with this, users can already start composing songs with slightly less powerful machines, even when targeting high-end machines. Related to #199
This commit is contained in:
parent
c583156d1b
commit
9b9dc3548f
35
patch.go
35
patch.go
@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/bits"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
@ -19,8 +20,12 @@ type (
|
||||
Name string `yaml:",omitempty"`
|
||||
Comment string `yaml:",omitempty"`
|
||||
NumVoices int
|
||||
Units []Unit
|
||||
Mute bool `yaml:",omitempty"` // Mute is only used in the tracker for soloing/muting instruments; the compiled player ignores this field
|
||||
// ThreadMaskM1 is a bit mask of which threads are used, minus 1. Minus
|
||||
// 1 is done so that the default value 0 means bit mask 0b0001 i.e. only
|
||||
// thread 1 is rendering the instrument.
|
||||
ThreadMaskM1 int `yaml:",omitempty"`
|
||||
Units []Unit
|
||||
}
|
||||
|
||||
// Unit is e.g. a filter, oscillator, envelope and its parameters
|
||||
@ -347,13 +352,14 @@ func init() {
|
||||
|
||||
// Copy makes a deep copy of a unit.
|
||||
func (u *Unit) Copy() Unit {
|
||||
parameters := make(map[string]int)
|
||||
ret := *u
|
||||
ret.Parameters = make(map[string]int, len(u.Parameters))
|
||||
for k, v := range u.Parameters {
|
||||
parameters[k] = v
|
||||
ret.Parameters[k] = v
|
||||
}
|
||||
varArgs := make([]int, len(u.VarArgs))
|
||||
copy(varArgs, u.VarArgs)
|
||||
return Unit{Type: u.Type, Parameters: parameters, VarArgs: varArgs, ID: u.ID, Disabled: u.Disabled, Comment: u.Comment}
|
||||
ret.VarArgs = make([]int, len(u.VarArgs))
|
||||
copy(ret.VarArgs, u.VarArgs)
|
||||
return ret
|
||||
}
|
||||
|
||||
var stackUseSource = [2]StackUse{
|
||||
@ -473,11 +479,12 @@ func (u *Unit) StackNeed() int {
|
||||
|
||||
// Copy makes a deep copy of an Instrument
|
||||
func (instr *Instrument) Copy() Instrument {
|
||||
units := make([]Unit, len(instr.Units))
|
||||
ret := *instr
|
||||
ret.Units = make([]Unit, len(instr.Units))
|
||||
for i, u := range instr.Units {
|
||||
units[i] = u.Copy()
|
||||
ret.Units[i] = u.Copy()
|
||||
}
|
||||
return Instrument{Name: instr.Name, Comment: instr.Comment, NumVoices: instr.NumVoices, Units: units, Mute: instr.Mute}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Implement the counter interface
|
||||
@ -536,6 +543,16 @@ func (p Patch) NumSyncs() int {
|
||||
return total
|
||||
}
|
||||
|
||||
func (p Patch) NumThreads() int {
|
||||
numThreads := 1
|
||||
for _, instr := range p {
|
||||
if l := bits.Len((uint)(instr.ThreadMaskM1 + 1)); l > numThreads {
|
||||
numThreads = l
|
||||
}
|
||||
}
|
||||
return numThreads
|
||||
}
|
||||
|
||||
// FirstVoiceForInstrument returns the index of the first voice of given
|
||||
// instrument. For example, if the Patch has three instruments (0, 1 and 2),
|
||||
// with 1, 3, 2 voices, respectively, then FirstVoiceForInstrument(0) returns 0,
|
||||
|
||||
Reference in New Issue
Block a user