mirror of
https://github.com/vsariola/sointu.git
synced 2026-02-20 23:23:23 -05:00
drafting
This commit is contained in:
parent
c424d2b847
commit
179ebb7cc3
@ -1,11 +1,9 @@
|
||||
package gioui
|
||||
|
||||
import (
|
||||
"image"
|
||||
"math"
|
||||
|
||||
"gioui.org/layout"
|
||||
"gioui.org/op/clip"
|
||||
"gioui.org/op/paint"
|
||||
"gioui.org/unit"
|
||||
"github.com/vsariola/sointu/tracker"
|
||||
)
|
||||
@ -15,11 +13,13 @@ type (
|
||||
resolutionNumber *NumericUpDownState
|
||||
smoothingBtn *Clickable
|
||||
chnModeBtn *Clickable
|
||||
plot *Plot
|
||||
}
|
||||
)
|
||||
|
||||
func NewSpectrumState() *SpectrumState {
|
||||
return &SpectrumState{
|
||||
plot: NewPlot(plotRange{0, 1}, plotRange{-1, 0}),
|
||||
resolutionNumber: NewNumericUpDownState(),
|
||||
smoothingBtn: new(Clickable),
|
||||
chnModeBtn: new(Clickable),
|
||||
@ -56,8 +56,64 @@ func (s *SpectrumState) Layout(gtx C) D {
|
||||
chnModeBtn := Btn(t.Theme, &t.Theme.Button.Filled, s.chnModeBtn, chnModeTxt, "Channel mode")
|
||||
smoothBtn := Btn(t.Theme, &t.Theme.Button.Filled, s.smoothingBtn, smoothTxt, "Smoothing")
|
||||
|
||||
numchns := 0
|
||||
speclen := len(t.Model.Spectrum()[0])
|
||||
if speclen > 0 {
|
||||
numchns = 1
|
||||
if len(t.Model.Spectrum()[1]) == speclen {
|
||||
numchns = 2
|
||||
}
|
||||
}
|
||||
|
||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||
layout.Flexed(1, s.drawSpectrum),
|
||||
layout.Flexed(1, func(gtx C) D {
|
||||
data := func(chn int, xr plotRange) (yr plotRange) {
|
||||
xr.a = softplus(xr.a*10) / 10
|
||||
xr.b = softplus(xr.b*10) / 10
|
||||
xr.a = float32(math.Log(float64(xr.a))) + 1
|
||||
xr.b = float32(math.Log(float64(xr.b))) + 1
|
||||
w1, f1 := math.Modf(float64(xr.a) * float64(speclen))
|
||||
w2, f2 := math.Modf(float64(xr.b) * float64(speclen))
|
||||
x1 := max(int(w1), 0)
|
||||
x2 := min(int(w2), speclen-1)
|
||||
if x1 > x2 {
|
||||
return plotRange{1, 0}
|
||||
}
|
||||
y1 := float32(math.Inf(-1))
|
||||
y2 := float32(math.Inf(+1))
|
||||
switch {
|
||||
case x2 <= x1+1 && x2 < speclen-1: // perform smoothstep interpolation when we are overlapping only a few bins
|
||||
l := t.Model.Spectrum()[chn][x1]
|
||||
r := t.Model.Spectrum()[chn][x1+1]
|
||||
y1 = smoothInterpolate(l, r, float32(f1))
|
||||
l = t.Model.Spectrum()[chn][x2]
|
||||
r = t.Model.Spectrum()[chn][x2+1]
|
||||
y2 = smoothInterpolate(l, r, float32(f2))
|
||||
y1, y2 = max(y1, y2), min(y1, y2)
|
||||
default:
|
||||
for i := x1; i <= x2; i++ {
|
||||
sample := t.Model.Spectrum()[chn][i]
|
||||
y1 = max(y1, sample)
|
||||
y2 = min(y2, sample)
|
||||
}
|
||||
}
|
||||
y1 = (y1 / 80) + 1
|
||||
y2 = (y2 / 80) + 1
|
||||
y1 = softplus(y1*10) / 10
|
||||
y2 = softplus(y2*10) / 10
|
||||
|
||||
return plotRange{-y1, -y2}
|
||||
}
|
||||
xticks := func(r plotRange, yield func(pos float32, label string)) {
|
||||
yield(0, "")
|
||||
yield(1, "")
|
||||
}
|
||||
yticks := func(r plotRange, yield func(pos float32, label string)) {
|
||||
yield(-1, "")
|
||||
yield(0, "")
|
||||
}
|
||||
return s.plot.Layout(gtx, data, xticks, yticks, 0, numchns)
|
||||
}),
|
||||
layout.Rigid(func(gtx C) D {
|
||||
return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx,
|
||||
layout.Rigid(leftSpacer),
|
||||
@ -71,6 +127,15 @@ func (s *SpectrumState) Layout(gtx C) D {
|
||||
)
|
||||
}
|
||||
|
||||
func softplus(f float32) float32 {
|
||||
return float32(math.Log(1 + math.Exp(float64(f))))
|
||||
}
|
||||
|
||||
func smoothInterpolate(a, b float32, t float32) float32 {
|
||||
t = t * t * (3 - 2*t)
|
||||
return (1-t)*a + t*b
|
||||
}
|
||||
|
||||
func (s *SpectrumState) Update(gtx C) {
|
||||
t := TrackerFromContext(gtx)
|
||||
for s.chnModeBtn.Clicked(gtx) {
|
||||
@ -81,22 +146,3 @@ func (s *SpectrumState) Update(gtx C) {
|
||||
t.Model.SpecAnSmoothing().SetValue((t.SpecAnSmoothing().Value()+1)%(r.Max-r.Min+1) + r.Min)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SpectrumState) drawSpectrum(gtx C) D {
|
||||
t := TrackerFromContext(gtx)
|
||||
for chn := range 2 {
|
||||
paint.ColorOp{Color: t.Theme.Oscilloscope.CurveColors[chn]}.Add(gtx.Ops)
|
||||
p := t.Spectrum()[chn]
|
||||
if len(p) <= 0 {
|
||||
continue
|
||||
}
|
||||
fillRect(gtx, clip.Rect{Min: image.Pt(0, 0), Max: image.Pt(gtx.Constraints.Max.X, 1)})
|
||||
fillRect(gtx, clip.Rect{Min: image.Pt(0, gtx.Constraints.Min.Y-1), Max: image.Pt(gtx.Constraints.Max.X, gtx.Constraints.Max.Y)})
|
||||
for px := range gtx.Constraints.Max.X {
|
||||
y2 := gtx.Constraints.Max.Y - 1
|
||||
y1 := int(-p[px*len(p)/gtx.Constraints.Max.X] / 80 * float32(y2))
|
||||
fillRect(gtx, clip.Rect{Min: image.Pt(px, y1), Max: image.Pt(px+1, y2+1)})
|
||||
}
|
||||
}
|
||||
return D{Size: image.Pt(gtx.Constraints.Max.X, gtx.Constraints.Max.Y)}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user