feat: midi note input for the tracker

This commit is contained in:
qm210
2024-10-21 22:00:50 +02:00
committed by Veikko Sariola
parent 216cde2365
commit 8dfadacafe
17 changed files with 299 additions and 63 deletions

View File

@ -41,6 +41,11 @@ type (
BPM() (bpm float64, ok bool)
}
EventProcessor interface {
ProcessMessage(msg interface{})
ProcessEvent(event MIDINoteEvent)
}
// MIDINoteEvent is a MIDI event triggering or releasing a note. In
// processing, the Frame is relative to the start of the current buffer. In
// a Recording, the Frame is relative to the start of the recording.
@ -89,9 +94,11 @@ const numRenderTries = 10000
// model. context tells the player which MIDI events happen during the current
// 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) {
p.processMessages(context)
func (p *Player) Process(buffer sointu.AudioBuffer, context PlayerProcessContext, ui EventProcessor) {
p.processMessages(context, ui)
midi, midiOk := context.NextEvent()
frame := 0
if p.recState == recStateRecording {
@ -116,6 +123,10 @@ func (p *Player) Process(buffer sointu.AudioBuffer, context PlayerProcessContext
} else {
p.releaseInstrument(midi.Channel, midi.Note)
}
if ui != nil {
ui.ProcessEvent(midi)
}
midi, midiOk = context.NextEvent()
}
framesUntilMidi := len(buffer)
@ -224,7 +235,7 @@ func (p *Player) advanceRow() {
p.rowtime = 0
}
func (p *Player) processMessages(context PlayerProcessContext) {
func (p *Player) processMessages(context PlayerProcessContext, uiProcessor EventProcessor) {
loop:
for { // process new message
select {
@ -296,6 +307,9 @@ loop:
default:
// ignore unknown messages
}
if uiProcessor != nil {
uiProcessor.ProcessMessage(msg)
}
default:
break loop
}