Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

midi clock support? #232

Open
Pomax opened this issue Mar 11, 2022 · 7 comments
Open

midi clock support? #232

Pomax opened this issue Mar 11, 2022 · 7 comments
Labels
class: substantive https://www.w3.org/2023/Process-20230612/#correction-classes status: blocked Another issue or external dependency needs to be resolved before proceeding
Milestone

Comments

@Pomax
Copy link

Pomax commented Mar 11, 2022

Are there any plans to also make sure there's MIDI clock support, in the sense that the browser has a mechanism for starting a stable clock with event emission every 24th of a quarter note, based on a BPM value (or even mirroring the MIDI spec, where the tempo is set by specifying the number of microseconds per quarter note).

Right now our options are pretty crazy bad, and having a reliable time keeper on the JS side would enable a bunch of work that's currently just impossible (both for syncing MIDI devices using the browser as authority, as well as--in good old JS tradition-- complete spec-unrelated work that just needs an actually reliable interval trigger).

@djipco
Copy link

djipco commented Mar 11, 2022

While it's not a metronome per-se, did you check out Chris Wilson's approach to timing?

Having said that, it would be awesome to have a reliable and precise timing mechanism capable of dispatching events. I'm just not sure if and how JavaScript's architecture could permit that.

@Pomax
Copy link
Author

Pomax commented Mar 11, 2022

Indeed, it's also referenced by the link from my comment, and I'm literally working on a fork of his code to make it more 2022 JSish, but... it's way more code than anyone should ever have to write to get a reliable (midi) clock going, and it's still not properly accurate (there's stable lag anywhere from 20ms to over 100ms depending which device you're running on, and drift between ticks that ranges from negligible to 10ms thanks to a combination of setInterval and postMessage, which is very not negligible).

Especially for Web audio and MIDI, we still need a proper high precision trigger timer (like how we have performance.now() for when Date.now() isn't accurate enough, although of course firefox has helpfully made them the same resolution, so that's not great). Code that only works on a tower desktop that happens to have enough free resources for everything to run as fast as possible is "we're not there yet" code =)

So, as the MIDI spec has the concept of the clock built right into it, it would make sense to have some kind of MIDIClock or MIDI.Clock etc. global that can be told to create timer instances with some BPM or micros-per-quarter value, that generates midi tick messages (explicitly not using the current JS timer definition that back setTimeout/setInterval) that can be forwarded to a MIDI device, and/or have code kick in when ticks fly by.

@boourns
Copy link

boourns commented Apr 9, 2022

So, as the MIDI spec has the concept of the clock built right into it, it would make sense to have some kind of MIDIClock or MIDI.Clock etc. global that can be told to create timer instances with some BPM or micros-per-quarter value, that generates midi tick messages (explicitly not using the current JS timer definition that back setTimeout/setInterval) that can be forwarded to a MIDI device, and/or have code kick in when ticks fly by.

While your proposal may solve the issue of generating a stable MIDI clock in isolation, it would not integrate well with an audio application that is trying to syncronize MIDI clocks, MIDI events, and audio input or output.

I would like to propose an alternative solution: please add direct access to the Web MIDI API from the audio thread.

if the Web MIDI API was available on the audio thread, then we could do low-latency scheduling of all MIDI events in a sample-accurate manner by writing an AudioWorklet that emits MIDI during it's process function. With this API somebody could build a MIDI.Clock AudioNode / AudioProcessor pair that implements the API described in the above comment.

I'm still getting up to speed with the history of web midi spec and if the audio thread has already been proposed or discussed i apologize.

I've written a few sample-accurate MIDI sequencers with this approach built as Web Audio Modules, for example this piano roll but the problem I have is there is no way to emit the MIDI messages to a hardware MIDI port without first posting to the main thread, introducing all sorts of timing issues.

image

@djipco
Copy link

djipco commented Apr 12, 2022

I would like to propose an alternative solution: please add direct access to the Web MIDI API from the audio thread.

This is definitely worth looking into. Another suggested approach is to make the Web MIDI API avaible in a worker thread.

@cwilso
Copy link
Contributor

cwilso commented Apr 12, 2022

@djipco Web MIDI availability in workers is issue #99.

@mjwilson-google mjwilson-google added class: substantive https://www.w3.org/2023/Process-20230612/#correction-classes status: needs WG review Needs to be discussed with the Audio Working Group before proceeding labels Sep 13, 2023
@mjwilson-google mjwilson-google added this to the CR milestone Sep 25, 2023
@mjwilson-google
Copy link
Contributor

mjwilson-google commented Sep 25, 2023

I will tentatively schedule this for CR, following #99, but I would like to discuss how Web MIDI and Web Audio interact with the Audio Working Group.

I think it would make it easier for application developers if we can schedule MIDI event timing from the audio render thread (this is how JACK works, for instance), but I still don' t have a good idea of what spec work would be involved and how much implementers would have to change to make that possible.

@mjwilson-google
Copy link
Contributor

Audio Working Group 2023-10-05 meeting conclusions:

  • It should be possible to make a stable output MIDI clock by using existing JavaScript APIs (not necessarily Web MIDI though)
  • We don't see a way to do stable MIDI clock input from an external MIDI clock source with the existing JavaScript APIs
  • We would like to pursue making Web MIDI available in workers (MIDI API should be available from Workers? #99) first, which may give a path to resolve this.

@mjwilson-google mjwilson-google added status: blocked Another issue or external dependency needs to be resolved before proceeding and removed status: needs WG review Needs to be discussed with the Audio Working Group before proceeding labels Oct 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
class: substantive https://www.w3.org/2023/Process-20230612/#correction-classes status: blocked Another issue or external dependency needs to be resolved before proceeding
Projects
None yet
Development

No branches or pull requests

5 participants