mirror of
https://github.com/vsariola/sointu.git
synced 2025-11-18 16:49:06 -05:00
drafting
This commit is contained in:
parent
7f03664870
commit
fa7901c7c6
@ -1,5 +1,7 @@
|
||||
package tracker
|
||||
|
||||
import "fmt"
|
||||
|
||||
type (
|
||||
Bool struct {
|
||||
value BoolValue
|
||||
@ -76,7 +78,8 @@ func (m *Model) getCoresBit(bit int) bool {
|
||||
if m.d.InstrIndex < 0 || m.d.InstrIndex >= len(m.d.Song.Patch) {
|
||||
return false
|
||||
}
|
||||
return m.d.Song.Patch[m.d.InstrIndex].CoreBitMask&(1<<bit) != 0
|
||||
mask := m.d.Song.Patch[m.d.InstrIndex].CoreMaskM1 + 1
|
||||
return mask&(1<<bit) != 0
|
||||
}
|
||||
|
||||
func (m *Model) setCoresBit(bit int, value bool) {
|
||||
@ -84,10 +87,34 @@ func (m *Model) setCoresBit(bit int, value bool) {
|
||||
return
|
||||
}
|
||||
defer (*Model)(m).change("CoreBitMask", PatchChange, MinorChange)()
|
||||
mask := m.d.Song.Patch[m.d.InstrIndex].CoreMaskM1 + 1
|
||||
if value {
|
||||
m.d.Song.Patch[m.d.InstrIndex].CoreBitMask |= (1 << bit)
|
||||
mask |= (1 << bit)
|
||||
} else {
|
||||
m.d.Song.Patch[m.d.InstrIndex].CoreBitMask &^= (1 << bit)
|
||||
mask &^= (1 << bit)
|
||||
}
|
||||
m.d.Song.Patch[m.d.InstrIndex].CoreMaskM1 = max(mask-1, 0) // -1 would have all cores disabled, so make that 0 i.e. use core 1 only
|
||||
m.warnAboutCrossCoreSends()
|
||||
}
|
||||
|
||||
func (m *Model) warnAboutCrossCoreSends() {
|
||||
for i, instr := range m.d.Song.Patch {
|
||||
for _, unit := range instr.Units {
|
||||
if unit.Type == "send" {
|
||||
targetID, ok := unit.Parameters["target"]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
it, _, err := m.d.Song.Patch.FindUnit(targetID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if instr.CoreMaskM1 != m.d.Song.Patch[it].CoreMaskM1 {
|
||||
m.Alerts().AddNamed("CrossCoreSend", fmt.Sprintf("Instrument %d '%s' has a send to instrument %d '%s' but they are not on the same cores, which may cause issues", i+1, instr.Name, it+1, m.d.Song.Patch[it].Name), Warning)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,14 +5,17 @@ import (
|
||||
"image"
|
||||
"image/color"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gioui.org/gesture"
|
||||
"gioui.org/layout"
|
||||
"gioui.org/op/clip"
|
||||
"gioui.org/op/paint"
|
||||
"gioui.org/unit"
|
||||
"github.com/vsariola/sointu"
|
||||
"github.com/vsariola/sointu/tracker"
|
||||
"github.com/vsariola/sointu/version"
|
||||
"github.com/vsariola/sointu/vm"
|
||||
"golang.org/x/exp/shiny/materialdesign/icons"
|
||||
)
|
||||
|
||||
@ -110,9 +113,24 @@ func (t *SongPanel) layoutSongOptions(gtx C) D {
|
||||
}
|
||||
oversamplingBtn := Btn(tr.Theme, &tr.Theme.Button.Text, t.OversamplingBtn, oversamplingTxt, "")
|
||||
|
||||
cpuload := tr.Model.CPULoad()
|
||||
cpuLabel := Label(tr.Theme, &tr.Theme.SongPanel.RowValue, fmt.Sprintf("%.0f %%", cpuload*100))
|
||||
if cpuload >= 1 {
|
||||
var sb strings.Builder
|
||||
var loadArr [vm.MAX_CORES]sointu.CPULoad
|
||||
tr.Model.CPULoad(loadArr[:])
|
||||
c := min(vm.MAX_CORES, tr.Model.NumCores())
|
||||
high := false
|
||||
for i := range c {
|
||||
if i > 0 {
|
||||
// unless this is the first item, add the separator before it.
|
||||
fmt.Fprint(&sb, ", ")
|
||||
}
|
||||
cpuLoad := loadArr[i]
|
||||
fmt.Fprintf(&sb, "%.0f %%", cpuLoad*100)
|
||||
if cpuLoad >= 1 {
|
||||
high = true
|
||||
}
|
||||
}
|
||||
cpuLabel := Label(tr.Theme, &tr.Theme.SongPanel.RowValue, sb.String())
|
||||
if high {
|
||||
cpuLabel.Color = tr.Theme.SongPanel.ErrorColor
|
||||
}
|
||||
|
||||
|
||||
@ -397,7 +397,8 @@ func (m *Model) ProcessMsg(msg MsgToModel) {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Model) CPULoad() float64 { return m.playerStatus.CPULoad }
|
||||
func (m *Model) NumCores() int { return m.playerStatus.NumCores }
|
||||
func (m *Model) CPULoad(buf []sointu.CPULoad) { copy(buf, m.playerStatus.CPULoad[:]) }
|
||||
|
||||
func (m *Model) SignalAnalyzer() *ScopeModel { return m.signalAnalyzer }
|
||||
func (m *Model) Broker() *Broker { return m.broker }
|
||||
|
||||
@ -5,7 +5,6 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/vsariola/sointu"
|
||||
"github.com/vsariola/sointu/vm"
|
||||
@ -42,7 +41,8 @@ type (
|
||||
PlayerStatus struct {
|
||||
SongPos sointu.SongPos // the current position in the score
|
||||
VoiceLevels [vm.MAX_VOICES]float32 // a level that can be used to visualize the volume of each voice
|
||||
CPULoad float64 // current CPU load of the player, used to adjust the render rate
|
||||
NumCores int
|
||||
CPULoad [vm.MAX_CORES]sointu.CPULoad // current CPU load of the player, used to adjust the render rate
|
||||
}
|
||||
|
||||
// PlayerProcessContext is the context given to the player when processing
|
||||
@ -97,9 +97,6 @@ func NewPlayer(broker *Broker, synther sointu.Synther) *Player {
|
||||
// buffer. It is used to trigger and release notes during processing. The
|
||||
// context is also used to get the current BPM from the host.
|
||||
func (p *Player) Process(buffer sointu.AudioBuffer, context PlayerProcessContext) {
|
||||
startTime := time.Now()
|
||||
startFrame := p.frame
|
||||
|
||||
p.processMessages(context)
|
||||
p.events.adjustTimes(p.frameDeltas, p.frame, p.frame+int64(len(buffer)))
|
||||
|
||||
@ -164,7 +161,10 @@ func (p *Player) Process(buffer sointu.AudioBuffer, context PlayerProcessContext
|
||||
}
|
||||
// when the buffer is full, return
|
||||
if len(buffer) == 0 {
|
||||
p.updateCPULoad(time.Since(startTime), p.frame-startFrame)
|
||||
if p.synth != nil {
|
||||
p.status.NumCores = p.synth.NumCores()
|
||||
p.synth.CPULoad(p.status.CPULoad[:])
|
||||
}
|
||||
p.send(nil)
|
||||
return
|
||||
}
|
||||
@ -448,14 +448,3 @@ func (p *Player) processNoteEvent(ev NoteEvent) {
|
||||
p.synth.Trigger(oldestVoice, ev.Note)
|
||||
TrySend(p.broker.ToModel, MsgToModel{TriggerChannel: instrIndex + 1})
|
||||
}
|
||||
|
||||
func (p *Player) updateCPULoad(duration time.Duration, frames int64) {
|
||||
if frames <= 0 {
|
||||
return // no frames rendered, so cannot compute CPU load
|
||||
}
|
||||
realtime := float64(duration) / 1e9
|
||||
songtime := float64(frames) / 44100
|
||||
newload := realtime / songtime
|
||||
alpha := math.Exp(-songtime) // smoothing factor, time constant of 1 second
|
||||
p.status.CPULoad = float64(p.status.CPULoad)*alpha + newload*(1-alpha)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user