mirror of
https://github.com/vsariola/sointu.git
synced 2025-07-21 22:44:50 -04:00
feat(tracker): compile with midi support only when CGO is available
Also add the midi context to the VSTI, so VSTI can use MIDI if they wish so.
This commit is contained in:
parent
3881b8eb22
commit
602b3b05cc
12
cmd/midi_cgo.go
Normal file
12
cmd/midi_cgo.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
//go:build cgo
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/vsariola/sointu/tracker"
|
||||||
|
"github.com/vsariola/sointu/tracker/gomidi"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewMidiContext(broker *tracker.Broker) tracker.MIDIContext {
|
||||||
|
return gomidi.NewContext(broker)
|
||||||
|
}
|
12
cmd/midi_not_cgo.go
Normal file
12
cmd/midi_not_cgo.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
//go:build !cgo
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/vsariola/sointu/tracker"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewMidiContext(broker *tracker.Broker) tracker.MIDIContext {
|
||||||
|
// with no cgo, we cannot use MIDI, so return a null context
|
||||||
|
return tracker.NullMIDIContext{}
|
||||||
|
}
|
@ -16,7 +16,6 @@ import (
|
|||||||
"github.com/vsariola/sointu/oto"
|
"github.com/vsariola/sointu/oto"
|
||||||
"github.com/vsariola/sointu/tracker"
|
"github.com/vsariola/sointu/tracker"
|
||||||
"github.com/vsariola/sointu/tracker/gioui"
|
"github.com/vsariola/sointu/tracker/gioui"
|
||||||
"github.com/vsariola/sointu/tracker/gomidi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
|
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
|
||||||
@ -47,7 +46,7 @@ func main() {
|
|||||||
recoveryFile = filepath.Join(configDir, "Sointu", "sointu-track-recovery")
|
recoveryFile = filepath.Join(configDir, "Sointu", "sointu-track-recovery")
|
||||||
}
|
}
|
||||||
broker := tracker.NewBroker()
|
broker := tracker.NewBroker()
|
||||||
midiContext := gomidi.NewContext(broker)
|
midiContext := cmd.NewMidiContext(broker)
|
||||||
defer midiContext.Close()
|
defer midiContext.Close()
|
||||||
midiContext.TryToOpenBy(*defaultMidiInput, *firstMidiInput)
|
midiContext.TryToOpenBy(*defaultMidiInput, *firstMidiInput)
|
||||||
model := tracker.NewModel(broker, cmd.MainSynther, midiContext, recoveryFile)
|
model := tracker.NewModel(broker, cmd.MainSynther, midiContext, recoveryFile)
|
||||||
@ -65,7 +64,7 @@ func main() {
|
|||||||
|
|
||||||
trackerUi := gioui.NewTracker(model)
|
trackerUi := gioui.NewTracker(model)
|
||||||
audioCloser := audioContext.Play(func(buf sointu.AudioBuffer) error {
|
audioCloser := audioContext.Play(func(buf sointu.AudioBuffer) error {
|
||||||
player.Process(buf, midiContext)
|
player.Process(buf, tracker.NullPlayerProcessContext{})
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -24,16 +24,8 @@ type (
|
|||||||
eventIndex int
|
eventIndex int
|
||||||
host vst2.Host
|
host vst2.Host
|
||||||
}
|
}
|
||||||
|
|
||||||
NullMIDIContext struct{}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m NullMIDIContext) InputDevices(yield func(tracker.MIDIDevice) bool) {}
|
|
||||||
|
|
||||||
func (m NullMIDIContext) Close() {}
|
|
||||||
|
|
||||||
func (m NullMIDIContext) HasDeviceOpen() bool { return false }
|
|
||||||
|
|
||||||
func (c *VSTIProcessContext) BPM() (bpm float64, ok bool) {
|
func (c *VSTIProcessContext) BPM() (bpm float64, ok bool) {
|
||||||
timeInfo := c.host.GetTimeInfo(vst2.TempoValid)
|
timeInfo := c.host.GetTimeInfo(vst2.TempoValid)
|
||||||
if timeInfo == nil || timeInfo.Flags&vst2.TempoValid == 0 || timeInfo.Tempo == 0 {
|
if timeInfo == nil || timeInfo.Flags&vst2.TempoValid == 0 || timeInfo.Tempo == 0 {
|
||||||
@ -54,7 +46,7 @@ func init() {
|
|||||||
recoveryFile = filepath.Join(configDir, "sointu", "sointu-vsti-recovery-"+hex.EncodeToString(randBytes))
|
recoveryFile = filepath.Join(configDir, "sointu", "sointu-vsti-recovery-"+hex.EncodeToString(randBytes))
|
||||||
}
|
}
|
||||||
broker := tracker.NewBroker()
|
broker := tracker.NewBroker()
|
||||||
model := tracker.NewModel(broker, cmd.MainSynther, NullMIDIContext{}, recoveryFile)
|
model := tracker.NewModel(broker, cmd.MainSynther, cmd.NewMidiContext(broker), recoveryFile)
|
||||||
player := tracker.NewPlayer(broker, cmd.MainSynther)
|
player := tracker.NewPlayer(broker, cmd.MainSynther)
|
||||||
detector := tracker.NewDetector(broker)
|
detector := tracker.NewDetector(broker)
|
||||||
go detector.Run()
|
go detector.Run()
|
||||||
|
@ -117,8 +117,11 @@ type (
|
|||||||
InputDevices(yield func(MIDIDevice) bool)
|
InputDevices(yield func(MIDIDevice) bool)
|
||||||
Close()
|
Close()
|
||||||
HasDeviceOpen() bool
|
HasDeviceOpen() bool
|
||||||
|
TryToOpenBy(name string, first bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NullMIDIContext struct{}
|
||||||
|
|
||||||
MIDIDevice interface {
|
MIDIDevice interface {
|
||||||
String() string
|
String() string
|
||||||
Open() error
|
Open() error
|
||||||
@ -385,6 +388,11 @@ func (d *modelData) Copy() modelData {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m NullMIDIContext) InputDevices(yield func(MIDIDevice) bool) {}
|
||||||
|
func (m NullMIDIContext) Close() {}
|
||||||
|
func (m NullMIDIContext) HasDeviceOpen() bool { return false }
|
||||||
|
func (m NullMIDIContext) TryToOpenBy(name string, first bool) {}
|
||||||
|
|
||||||
func (m *Model) resetSong() {
|
func (m *Model) resetSong() {
|
||||||
m.d.Song = defaultSong.Copy()
|
m.d.Song = defaultSong.Copy()
|
||||||
for _, instr := range m.d.Song.Patch {
|
for _, instr := range m.d.Song.Patch {
|
||||||
|
@ -13,18 +13,10 @@ import (
|
|||||||
|
|
||||||
type NullContext struct{}
|
type NullContext struct{}
|
||||||
|
|
||||||
func (NullContext) FinishBlock(frame int) {}
|
|
||||||
|
|
||||||
func (NullContext) BPM() (bpm float64, ok bool) {
|
func (NullContext) BPM() (bpm float64, ok bool) {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (NullContext) InputDevices(yield func(tracker.MIDIDevice) bool) {}
|
|
||||||
|
|
||||||
func (NullContext) HasDeviceOpen() bool { return false }
|
|
||||||
|
|
||||||
func (NullContext) Close() {}
|
|
||||||
|
|
||||||
type modelFuzzState struct {
|
type modelFuzzState struct {
|
||||||
model *tracker.Model
|
model *tracker.Model
|
||||||
clipboard []byte
|
clipboard []byte
|
||||||
@ -261,7 +253,7 @@ func FuzzModel(f *testing.F) {
|
|||||||
reader := bytes.NewReader(slice)
|
reader := bytes.NewReader(slice)
|
||||||
synther := vm.GoSynther{}
|
synther := vm.GoSynther{}
|
||||||
broker := tracker.NewBroker()
|
broker := tracker.NewBroker()
|
||||||
model := tracker.NewModel(broker, synther, NullContext{}, "")
|
model := tracker.NewModel(broker, synther, tracker.NullMIDIContext{}, "")
|
||||||
player := tracker.NewPlayer(broker, synther)
|
player := tracker.NewPlayer(broker, synther)
|
||||||
buf := make([][2]float32, 2048)
|
buf := make([][2]float32, 2048)
|
||||||
closeChan := make(chan struct{})
|
closeChan := make(chan struct{})
|
||||||
|
@ -51,6 +51,8 @@ type (
|
|||||||
BPM() (bpm float64, ok bool)
|
BPM() (bpm float64, ok bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NullPlayerProcessContext struct{}
|
||||||
|
|
||||||
// NoteEvent describes triggering or releasing of a note. The timestamps are
|
// NoteEvent describes triggering or releasing of a note. The timestamps are
|
||||||
// in frames, and relative to the clock of the event source. Different
|
// in frames, and relative to the clock of the event source. Different
|
||||||
// sources can use different clocks. Player tries to adjust the timestamps
|
// sources can use different clocks. Player tries to adjust the timestamps
|
||||||
@ -200,6 +202,10 @@ func (p *Player) advanceRow() {
|
|||||||
p.send(nil) // just send volume and song row information
|
p.send(nil) // just send volume and song row information
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p NullPlayerProcessContext) BPM() (bpm float64, ok bool) {
|
||||||
|
return 0, false // no BPM available
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Player) processMessages(context PlayerProcessContext) {
|
func (p *Player) processMessages(context PlayerProcessContext) {
|
||||||
loop:
|
loop:
|
||||||
for { // process new message
|
for { // process new message
|
||||||
|
Reference in New Issue
Block a user