mirror of
https://github.com/vsariola/sointu.git
synced 2025-11-12 12:52:53 -05:00
feat(tracker): don't save instrument name in instrument files
The filename is used as the instrument name when it is loaded.
This commit is contained in:
parent
55f9c36bd5
commit
7459437822
@ -105,6 +105,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||||||
([#156][i156])
|
([#156][i156])
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
- When saving instrument to a file, the instrument name is not saved to the name
|
||||||
|
field, as Sointu will anyway use the filename as the instrument's name when it
|
||||||
|
is loaded.
|
||||||
- Native version of the tracker/VSTi was removed. Instead, you can change
|
- Native version of the tracker/VSTi was removed. Instead, you can change
|
||||||
between the two versions of the synth on the fly, by clicking on the "Synth"
|
between the two versions of the synth on the fly, by clicking on the "Synth"
|
||||||
option under the CPU group in the song panel ([#200][i200])
|
option under the CPU group in the song panel ([#200][i200])
|
||||||
|
|||||||
@ -114,13 +114,17 @@ func (m *Model) SaveInstrument(w io.WriteCloser) bool {
|
|||||||
var extension = filepath.Ext(path)
|
var extension = filepath.Ext(path)
|
||||||
var contents []byte
|
var contents []byte
|
||||||
var err error
|
var err error
|
||||||
|
instr := m.d.Song.Patch[m.d.InstrIndex]
|
||||||
|
if _, ok := w.(*os.File); ok {
|
||||||
|
instr.Name = "" // don't save the instrument name to a file; we'll replace the instruments name with the filename when loading from a file
|
||||||
|
}
|
||||||
if extension == ".json" {
|
if extension == ".json" {
|
||||||
contents, err = json.Marshal(m.d.Song.Patch[m.d.InstrIndex])
|
contents, err = json.Marshal(instr)
|
||||||
} else {
|
} else {
|
||||||
contents, err = yaml.Marshal(m.d.Song.Patch[m.d.InstrIndex])
|
contents, err = yaml.Marshal(instr)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
m.Alerts().Add(fmt.Sprintf("Error marshaling a ínstrument file: %v", err), Error)
|
m.Alerts().Add(fmt.Sprintf("Error marshaling an instrument file: %v", err), Error)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
w.Write(contents)
|
w.Write(contents)
|
||||||
@ -163,7 +167,7 @@ func (m *Model) LoadInstrument(r io.ReadCloser) bool {
|
|||||||
success:
|
success:
|
||||||
if f, ok := r.(*os.File); ok {
|
if f, ok := r.(*os.File); ok {
|
||||||
filename := f.Name()
|
filename := f.Name()
|
||||||
// the 4klang instrument names are junk, replace them with the filename without extension
|
// the instrument names are generally junk, replace them with the filename without extension
|
||||||
instrument.Name = filepath.Base(filename[:len(filename)-len(filepath.Ext(filename))])
|
instrument.Name = filepath.Base(filename[:len(filename)-len(filepath.Ext(filename))])
|
||||||
}
|
}
|
||||||
defer m.change("LoadInstrument", PatchChange, MajorChange)()
|
defer m.change("LoadInstrument", PatchChange, MajorChange)()
|
||||||
|
|||||||
47
tracker/generate/clean_presets.go
Normal file
47
tracker/generate/clean_presets.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
//go:build ignore
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/vsariola/sointu"
|
||||||
|
"github.com/vsariola/sointu/tracker"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
filepath.WalkDir("presets", func(path string, d fs.DirEntry, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if d.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
data, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var instr sointu.Instrument
|
||||||
|
if yaml.Unmarshal(data, &instr) != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "could not unmarshal the preset file %v: %v\n", path, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
tracker.RemoveUnusedUnitParameters(&instr) // remove invalid parameters
|
||||||
|
instr.Name = "" // we don't need the names in the preset files as they are derived from the file path
|
||||||
|
outData, err := yaml.Marshal(instr)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "could not marshal the preset file %v: %v\n", path, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err := os.WriteFile(path, outData, 0644); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "could not write the preset file %v: %v\n", path, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -521,21 +521,29 @@ func (m *Model) fixUnitParams() {
|
|||||||
// loop over all instruments and units and check that unit parameter table
|
// loop over all instruments and units and check that unit parameter table
|
||||||
// only has the parameters that are defined in the unit type
|
// only has the parameters that are defined in the unit type
|
||||||
fixed := false
|
fixed := false
|
||||||
for i, instr := range m.d.Song.Patch {
|
for i := range m.d.Song.Patch {
|
||||||
for j, unit := range instr.Units {
|
fixed = RemoveUnusedUnitParameters(&m.d.Song.Patch[i]) || fixed
|
||||||
for paramName := range unit.Parameters {
|
|
||||||
if !validParameters[unit.Type][paramName] {
|
|
||||||
delete(m.d.Song.Patch[i].Units[j].Parameters, paramName)
|
|
||||||
fixed = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if fixed {
|
if fixed {
|
||||||
m.Alerts().AddNamed("InvalidUnitParameters", "Some units had invalid parameters, they were removed", Error)
|
m.Alerts().AddNamed("InvalidUnitParameters", "Some units had invalid parameters, they were removed", Error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveUnusedUnitParameters removes any parameters from the instrument that are not valid for the unit type.
|
||||||
|
// It returns true if any parameters were removed.
|
||||||
|
func RemoveUnusedUnitParameters(instr *sointu.Instrument) bool {
|
||||||
|
fixed := false
|
||||||
|
for _, unit := range instr.Units {
|
||||||
|
for paramName := range unit.Parameters {
|
||||||
|
if !validParameters[unit.Type][paramName] {
|
||||||
|
delete(unit.Parameters, paramName)
|
||||||
|
fixed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fixed
|
||||||
|
}
|
||||||
|
|
||||||
func clamp(a, min, max int) int {
|
func clamp(a, min, max int) int {
|
||||||
if a > max {
|
if a > max {
|
||||||
return max
|
return max
|
||||||
|
|||||||
@ -14,7 +14,8 @@ import (
|
|||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run generate/main.go
|
//go:generate go run generate/gmdls_entries.go
|
||||||
|
//go:generate go run generate/clean_presets.go
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// GmDlsEntry is a single sample entry from the gm.dls file
|
// GmDlsEntry is a single sample entry from the gm.dls file
|
||||||
|
|||||||
Reference in New Issue
Block a user