diff --git a/sointu.go b/sointu.go index b185878..942303f 100644 --- a/sointu.go +++ b/sointu.go @@ -268,6 +268,20 @@ var UnitTypes = map[string]([]UnitParameter){ {Name: "channel", MinValue: 0, MaxValue: 6, CanSet: true, CanModulate: false}}, } +var Ports = make(map[string]([]string)) + +func init() { + for name, unitType := range UnitTypes { + unitPorts := make([]string, 0) + for _, param := range unitType { + if param.CanModulate { + unitPorts = append(unitPorts, param.Name) + } + } + Ports[name] = unitPorts + } +} + type Song struct { BPM int RowsPerPattern int @@ -358,6 +372,46 @@ func (s *Song) Validate() error { return nil } +func (p *Patch) FindSendTarget(i, u int) (int, int, int, error) { + if i < 0 || i >= len(p.Instruments) { + return -1, -1, -1, errors.New("instrument index out of range") + } + instr := p.Instruments[i] + if u < 0 || u >= len(instr.Units) { + return -1, -1, -1, errors.New("unit index out of range") + } + unit := instr.Units[u] + var targetInstrIndex int + if unit.Parameters["voice"] == 0 { + targetInstrIndex = i + } else { + var err error + targetInstrIndex, err = p.InstrumentForVoice(unit.Parameters["voice"] - 1) + if err != nil { + return -1, -1, -1, errors.New("the target voice was out of range") + } + } + targetInstr := p.Instruments[targetInstrIndex] + targetUnitIndex := unit.Parameters["unit"] + if targetUnitIndex < 0 || targetUnitIndex >= len(targetInstr.Units) { + return targetInstrIndex, -1, -1, errors.New("the target unit was out of range") + } + targetUnit := targetInstr.Units[targetUnitIndex] + port := unit.Parameters["port"] + if port < 0 { + return targetInstrIndex, targetUnitIndex, -1, errors.New("the target port was out of range") + } + for k, param := range UnitTypes[targetUnit.Type] { + if param.CanModulate { + port-- + if port < 0 { + return targetInstrIndex, targetUnitIndex, k, nil + } + } + } + return targetInstrIndex, targetUnitIndex, -1, errors.New("the target port was out of range") +} + func (s *Song) ParamHintString(instrIndex, unitIndex int, param string) string { if instrIndex < 0 || instrIndex >= len(s.Patch.Instruments) { return "" diff --git a/tracker/uniteditor.go b/tracker/uniteditor.go index 20504d2..af171ed 100644 --- a/tracker/uniteditor.go +++ b/tracker/uniteditor.go @@ -67,6 +67,19 @@ func (t *Tracker) layoutUnitSliders(gtx C) D { } value = params[name] min, max = ut[index].MinValue, ut[index].MaxValue + if u.Type == "send" && name == "voice" { + max = t.song.Patch.TotalVoices() + } else if u.Type == "send" && name == "unit" { // set the maximum values depending on the send target + instrIndex, _, _, _ := t.song.Patch.FindSendTarget(t.CurrentInstrument, t.CurrentUnit) + if instrIndex != -1 { + max = len(t.song.Patch.Instruments[instrIndex].Units) - 1 + } + } else if u.Type == "send" && name == "port" { // set the maximum values depending on the send target + instrIndex, unitIndex, _, _ := t.song.Patch.FindSendTarget(t.CurrentInstrument, t.CurrentUnit) + if instrIndex != -1 && unitIndex != -1 { + max = len(sointu.Ports[t.song.Patch.Instruments[instrIndex].Units[unitIndex].Type]) - 1 + } + } hint := t.song.ParamHintString(t.CurrentInstrument, t.CurrentUnit, name) if hint != "" { valueText = fmt.Sprintf("%v / %v", value, hint) @@ -77,6 +90,9 @@ func (t *Tracker) layoutUnitSliders(gtx C) D { if !t.ParameterSliders[index].Dragging() { t.ParameterSliders[index].Value = float32(value) } + if max < min { + max = min + } sliderStyle := material.Slider(t.Theme, t.ParameterSliders[index], float32(min), float32(max)) sliderStyle.Color = t.Theme.Fg return layout.Flex{Axis: layout.Horizontal, Alignment: layout.Middle}.Layout(gtx,