diff --git a/cmd/synthers.go b/cmd/synthers.go index 7da1d1c..cec6412 100644 --- a/cmd/synthers.go +++ b/cmd/synthers.go @@ -5,7 +5,4 @@ import ( "github.com/vsariola/sointu/vm" ) -var Synthers = []sointu.Synther{ - vm.GoSynther{}, - vm.MakeMultithreadSynther(vm.GoSynther{}), -} +var Synthers = []sointu.Synther{vm.GoSynther{}} diff --git a/cmd/synthers_native.go b/cmd/synthers_native.go index 3ef7009..a03c126 100644 --- a/cmd/synthers_native.go +++ b/cmd/synthers_native.go @@ -3,11 +3,9 @@ package cmd import ( - "github.com/vsariola/sointu/vm" "github.com/vsariola/sointu/vm/compiler/bridge" ) func init() { Synthers = append(Synthers, bridge.NativeSynther{}) - Synthers = append(Synthers, vm.MakeMultithreadSynther(bridge.NativeSynther{})) } diff --git a/tracker/gioui/song_panel.go b/tracker/gioui/song_panel.go index f08a3aa..af22dbc 100644 --- a/tracker/gioui/song_panel.go +++ b/tracker/gioui/song_panel.go @@ -31,9 +31,10 @@ type SongPanel struct { CPUExpander *Expander SpectrumExpander *Expander - WeightingTypeBtn *Clickable - OversamplingBtn *Clickable - SynthBtn *Clickable + WeightingTypeBtn *Clickable + OversamplingBtn *Clickable + SynthBtn *Clickable + MultithreadingBtn *Clickable BPM *NumericUpDownState RowsPerPattern *NumericUpDownState @@ -67,9 +68,10 @@ func NewSongPanel(tr *Tracker) *SongPanel { MenuBar: NewMenuBar(tr), PlayBar: NewPlayBar(), - WeightingTypeBtn: new(Clickable), - OversamplingBtn: new(Clickable), - SynthBtn: new(Clickable), + WeightingTypeBtn: new(Clickable), + OversamplingBtn: new(Clickable), + SynthBtn: new(Clickable), + MultithreadingBtn: new(Clickable), SongSettingsExpander: &Expander{Expanded: true}, ScopeExpander: &Expander{}, @@ -159,7 +161,8 @@ func (t *SongPanel) layoutSongOptions(gtx C) D { return cpuLabel.Layout(gtx) } - synthBtn := Btn(tr.Theme, &tr.Theme.Button.Text, t.SynthBtn, tr.Model.Play().SyntherName(), "") + synthBtn := Btn(tr.Theme, &tr.Theme.Button.Text, t.SynthBtn, tr.Model.Play().SyntherIndex().String(), "") + multithreadingBtn := ToggleIconBtn(tr.Play().Multithreading(), tr.Theme, t.MultithreadingBtn, icons.ToggleCheckBoxOutlineBlank, icons.ToggleCheckBox, "Threading disabled", "Threading enabled") listItem := func(gtx C, index int) D { switch index { @@ -198,6 +201,7 @@ func (t *SongPanel) layoutSongOptions(gtx C) D { return layout.Flex{Axis: layout.Vertical, Alignment: layout.End}.Layout(gtx, layout.Rigid(func(gtx C) D { return layoutSongOptionRow(gtx, tr.Theme, "Load", cpuEnlargedWidget) }), layout.Rigid(func(gtx C) D { return layoutSongOptionRow(gtx, tr.Theme, "Synth", synthBtn.Layout) }), + layout.Rigid(func(gtx C) D { return layoutSongOptionRow(gtx, tr.Theme, "Multithreading", multithreadingBtn.Layout) }), ) }, ) diff --git a/tracker/instrument.go b/tracker/instrument.go index e272378..c315950 100644 --- a/tracker/instrument.go +++ b/tracker/instrument.go @@ -237,7 +237,7 @@ func (m *InstrModel) warnAboutCrossThreadSends() { func (m *InstrModel) warnNoMultithreadSupport() { for _, instr := range m.d.Song.Patch { - if instr.ThreadMaskM1 > 0 && !m.synthers[m.syntherIndex].SupportsMultithreading() { + if instr.ThreadMaskM1 > 0 && !m.curSynther.SupportsMultithreading() { (*Alerts)(m).AddNamed("NoMultithreadSupport", "The current synth does not support multithreading and the patch was configured to use more than one thread", Warning) return } diff --git a/tracker/model.go b/tracker/model.go index 5b3593b..3605df3 100644 --- a/tracker/model.go +++ b/tracker/model.go @@ -82,8 +82,10 @@ type ( alerts []Alert dialog Dialog - syntherIndex int // the index of the synther used to create new synths - synthers []sointu.Synther // the synther used to create new synths + syntherIndex int // the index of the synther used to create new synths + synthers []sointu.Synther // the synther used to create new synths + multithreading bool // is the multithreading enabled or not + curSynther sointu.Synther // the current synther, either multithreaded or not depending on multithreading broker *Broker @@ -197,6 +199,7 @@ func NewModel(broker *Broker, synthers []sointu.Synther, midiContext MIDIContext m.derived.searchResults = make([]string, 0, len(sointu.UnitNames)) m.Unit().updateDerivedUnitSearch() m.MIDI().Refresh().Do() + m.Play().setSynther(0, false) go runDetector(broker) go runSpecAnalyzer(broker) return m diff --git a/tracker/play.go b/tracker/play.go index 45508a9..d2ae858 100644 --- a/tracker/play.go +++ b/tracker/play.go @@ -1,6 +1,9 @@ package tracker -import "github.com/vsariola/sointu" +import ( + "github.com/vsariola/sointu" + "github.com/vsariola/sointu/vm" +) type Play Model @@ -175,11 +178,7 @@ type playSyntherIndex Play func (v *playSyntherIndex) Value() int { return v.syntherIndex } func (v *playSyntherIndex) Range() RangeInclusive { return RangeInclusive{0, len(v.synthers) - 1} } func (v *playSyntherIndex) SetValue(value int) bool { - if value < 0 || value >= len(v.synthers) { - return false - } - v.syntherIndex = value - TrySend(v.broker.ToPlayer, any(v.synthers[value])) + (*Play)(v).setSynther(value, v.multithreading) return true } func (v *playSyntherIndex) StringOf(value int) string { @@ -189,8 +188,26 @@ func (v *playSyntherIndex) StringOf(value int) string { return v.synthers[value].Name() } -// SyntherName returns the name of the currently selected synther. -func (v *Play) SyntherName() string { return v.synthers[v.syntherIndex].Name() } +func (m *Play) Multithreading() Bool { return MakeBool((*playMultithreading)(m)) } + +type playMultithreading Play + +func (v *playMultithreading) Value() bool { return v.multithreading } +func (v *playMultithreading) SetValue(value bool) { (*Play)(v).setSynther(v.syntherIndex, value) } + +func (m *Play) setSynther(index int, multithreading bool) { + if index < 0 || index >= len(m.synthers) { + return + } + m.syntherIndex = index + m.multithreading = multithreading + if multithreading { + m.curSynther = vm.MakeMultithreadSynther(m.synthers[m.syntherIndex]) + } else { + m.curSynther = m.synthers[m.syntherIndex] + } + TrySend(m.broker.ToPlayer, any(m.curSynther)) +} // CPULoad fills the given buffer with CPU load information and returns the // number of threads filled. diff --git a/tracker/song.go b/tracker/song.go index af5fe5f..3239dee 100644 --- a/tracker/song.go +++ b/tracker/song.go @@ -346,7 +346,7 @@ func (m *SongModel) WriteWav(w io.WriteCloser, pcm16 bool) { b := make([]byte, 32+2) rand.Read(b) name := fmt.Sprintf("%x", b)[2 : 32+2] - data, err := sointu.Play(m.synthers[m.syntherIndex], song, func(p float32) { + data, err := sointu.Play(m.curSynther, song, func(p float32) { txt := fmt.Sprintf("Exporting song: %.0f%%", p*100) TrySend(m.broker.ToModel, MsgToModel{Data: Alert{Message: txt, Priority: Info, Name: name, Duration: defaultAlertDuration}}) }) // render the song to calculate its length