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

Support sending deferred messages #3

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from

Conversation

chrisguttandin
Copy link

This PR adds support for the optional timestamp parameter. It uses setTimeout() to re-schedule the messages if necessary.

It's the most simple way I could think of to implement this functionality. However I think it would be more accurate to schedule everything using the Web Audio API.

@notator
Copy link
Owner

notator commented Sep 1, 2024

Thanks for the PR! Very useful! :-)

I´ve taken a good look at your code. Its subtler than one might think, and I´m sure it works fine in your application.
But there´s a problem: messages would have to be pushed on to the stack in sequence. Pushing messages to different, parallel channels ought to be possible without having to sort them first.
So I´m leaving this PR open, and treating it like a feature request. :-)
I´ll be implementing timestamps in due course -- if nobody beats me to it. :-)

Current thoughts (21.11.2024)
Before implementing this, we need to think about Use Cases. Does a ResidentSynth really need to implement timestamps?
If an implementation would be useful, I think it would be best done along the lines of my first thoughts (02.09.2024) below:

  1. Rename the existing send(message) function to something like sendImmediately(message).
  2. Define a new send(message, timestamp) function that implements the necessary delays before calling sendImmediately(message). I imagine the implementation would be something like my original sketch (02.09.2024 below).

This would mean that, apart from renaming send(), we wouldn't need to touch any existing code.
Testing the new code would have to be done in a new application that actually needs timestamps.


Current thoughts (04.10.2024)
I should first try @chrisguttandin 's simple solution before making any changes. Maybe he's right, and I'm just not taking enough notice of send() being an async function!
If that doesn't work: The way mixtures and ornaments work needs to be looked at before making any changes. As I remember, they are realised by triggering midi messages from a master message...
A possible (simple but not nice, because not standard) solution occurred to me: The unsorted list of timestamped messages could be sandwiched between Sysex Start (0xF0) and End (0xF7) messages. They could then be sorted as they arrive (see below), and sent at the proper, relative time when the Sysex End message arrives..

Current thoughts (02.09.2024):
I think this problem should be tackled as simply as possible at the synth´s top level (i.e. in the send() function) and not at the low Web Audio API level (inside residentSynthNode.js). It would be best not to touch the code for mixtures and ornaments (which assumes that they are executed immediately when their master-note arrives).
A possible solution would be something like:

  1. insert incoming [message, timestamp] arrays into a single pendingMessages array that is kept sorted by timestamp.
  2. send messages (and delete them) from the pendingMessages array, using a separate Web Worker thread, when performance.now() reaches the earliest timestamp in the array.

My current code already tracks sounding notes (so that they are affected by pitchBend etc.). Maintaining a pendingMessages array would not be so very different.

@notator notator added feature request Feature request help wanted Extra attention is needed labels Oct 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Feature request help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants