paulrosen / abcjs

javascript for rendering abc music notation
Other
1.94k stars 285 forks source link

Hide but play voice #731

Open jbouzi opened 3 years ago

jbouzi commented 3 years ago

Hi, trying to figure out a way to hide but still play a voice. The use-case is for an orchestra - you only want to see your voice but want to play along with the whole orchestra. Any ideas?

I tried rendering with add_classes and hiding voices with the css - however it turns out quite awkward (see example: https://jbouzi.github.io/show.html?song=take5BT). Might be an idea to implement as stated in the abcnotation.com 11.1 Voice Grouping: "Voices that appear in the tune body, but not in the score directive, won't be printed."?

Btw, thanks for a brilliant lib!

paulrosen commented 3 years ago

What I do for this case is send a string to the synth that has all the voices. And a string with just one voice to the page.

But I wasn't aware of the line in the standard. I can implement that.

It doesn't really say if those hidden voices are sent to the synth, though. I guess it makes sense that they are played since the synth doesn't care about the %%score directive.

Note that the opposite is implemented - you can turn off selected voices. That is useful to not have the synth for the voice you are performing but the synth for the other voices.

I don't know when I'll get to the feature but I'll try to this year.

jbouzi commented 3 years ago

What I do for this case is send a string to the synth that has all the voices. And a string with just one voice to the page.

How do you manage this? I've tried by having two ABCJS.renderAbc, one to display and one hidden that play - however I never solved how to get the Timing Callbacks and the cursor to follow the playback working on the displayed version as the Elements from the events comes from the hidden one.

paulrosen commented 2 years ago

That's true, I wasn't doing the cursor. But you can probably figure it out from the beatCallback or eventCallback in a roundabout way. First, for the visual tune object, call setUpAudio() so that the midi info is generated. Then you can find the analogous position, I think. Something like:

var visualObj = renderAbc(...)
visualObj[0].setUpAudio()
console.log(visualObj[0].noteTimings)

I haven't tried it, but theoretically it should work.