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

Multiple players playing simultaneously #502

Open
cifkao opened this issue Aug 26, 2020 · 7 comments
Open

Multiple players playing simultaneously #502

cifkao opened this issue Aug 26, 2020 · 7 comments
Labels

Comments

@cifkao
Copy link
Contributor

cifkao commented Aug 26, 2020

It is currently not possible to have multiple players playing (or even paused) simultaneously because they are implemented using Tone.Transport (see #403, #418). This leads to the following problems:

  • To avoid a bad user experience (playback won't start if a different player is already playing), one has to keep track of the currently playing player to stop it when needed (as in html-midi-player).
  • A paused player still prevents other players from playing. For this reason I don't use the pause feature at all, but then I can only seek when the player is playing. In any case, you can seek at most one player at a time, which is clumsy.
  • It also prevents other code from using Tone.Transport.

@tambien suggested using Clock instead of Transport, but that would basically mean re-implementing a Transport. So I think the best would be to just instantiate one Transport for each player. Is something preventing that?

@notwaldorf
Copy link
Collaborator

I thought there was only one global Transport available (i.e. the global Tone.Transport). Are there instances? How would that look like?

@cifkao
Copy link
Contributor Author

cifkao commented Aug 28, 2020

The docs say that Transport is a singleton. But looking at the code, I don't see anything that would keep me from instantiating it (it has a public constructor). 🤔

@tambien
Copy link
Contributor

tambien commented Aug 30, 2020

Each Context has one Transport created with it, so you could create multiple Tone.Context's. You might run into browser implementation constraints. For example, i know Safari can only have something like 4 or 5 AudioContext instances running at once, so you'll have to be mindful to close the unused contexts before creating a new one.

@cifkao
Copy link
Contributor Author

cifkao commented Aug 30, 2020

@tambien Thanks for chiming in. So I guess my idea was bad. 😒

Then I see two possible ways to implement playback:

  • Using Clock directly as you suggested, re-implementing some of the functionality of Transport and Part.
  • Instead of starting/stopping Transport, start/stop the Part. To pause it, just remember the offset. (I don't know enough about Tone to see whether this would work.)

The first option seems cleaner to me, but it would probably be more work to implement it. What do you think?

@cifkao
Copy link
Contributor Author

cifkao commented Aug 30, 2020

By the way, if someone ends up reimplementing playback, it would be great to keep #415 and #301 in mind.

@notwaldorf
Copy link
Collaborator

I think I want to push back a little and understand why you need several players so i can give you a qorkaround -- is it to turn on and off some instruments? in that case, we can just make some utility methods that concatenate these note sequences into the one "played" one. The complicated part here will be to dynamically add notes to it, but even switching the part that a player is using shouldn't be thaaaat bad.

I'm not sure I understand why just stopping the Part is bad or won't work. Reimplementing Transport/Part is almost definitely not what we want to do (whatever problems Tone has we will eventually have, only then we can't look to @tambien to fix it 😅), so using whatever Tone is giving us is crucial imo

@cifkao
Copy link
Contributor Author

cifkao commented Aug 30, 2020

I think I want to push back a little and understand why you need several players so i can give you a qorkaround

It's not hard to imagine that there will be more than one player on the page, see e.g. my interpolation demo or the html-midi-player demo. I don't need them playing simultaneously. But the user will try to fiddle with multiple players at the same time and expect some reasonable behavior (ideally the same as with the audio element). I'm OK with my workaround for the first issue (stop the current player before starting another one). For the second issue (seeking while stopped), the workaround would require adding an offset parameter to start().

I'm not sure I understand why just stopping the Part is bad or won't work. Reimplementing Transport/Part is almost definitely not what we want to do

By that I didn't mean actually writing a new implementation of Transport. I just meant implementing the scheduling of notes directly using Clock as @tambien suggested earlier, rather than using Transport (which also uses a Clock internally). I think it shouldn't be too hard.

is it to turn on and off some instruments?

I didn't have that in mind, but that would be awesome too. In my application, I just disable the instrument checkboxes while playing (which is OK as a workaround, but can be a bit annoying).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants