abcjs icon indicating copy to clipboard operation
abcjs copied to clipboard

Checking if features already exist. Slides and Macros

Open kasravi opened this issue 4 years ago • 5 comments

Hey. Thanks for the great work. I am working on transcribing/synthesizing Persian traditional music and cannot find some of the features I need. So I decided to add them myself (in a fork). I just want to know maybe there already is a way to fulfill these and if there isn't which one of these you think is suitable to be added (so I can help this repo and don't PR with the features only I need)

  1. Ability to play slides (slurs?) -> currently a !slide! c shows the bow but cannot play it (a continuous shift between two notes which takes time as first note's duration)
  2. User defined decorations -> A way to define how a certain decoration should alter the playing, just like how trill changes the sound. I was wondering maybe macro header (m: ) can be used here, but it is not obvious from the standard if macros will alter the transcription or playing. For example m: "^...."n2=n1/8n1/8n1/8n1/8n1/8 should interpret four dots on a note of value 2 as 5 notes of value 1/8 but does not change transcription (timing can be wrong, responsibility of user) currently macro header is not implemented at all. I don't know if this is a hijack of that header or an implementation.
  3. free repeats -> text decorations !repeat(! and !repeat)2! !repeat)3! etc. to be able to repeat any group of notes regardless of bar line 2 times, three times, etc. This might be the least useful among others for western music.

Any comments/guidance/critics will help. Thanks Again!

kasravi avatar Oct 11 '21 09:10 kasravi

It sounds like all of these are sound related.

  1. This should be in the library, for sure. I'm not sure how easy it would be to add, though. I can detune a note but to create the slide I'd need to detune a bunch of intervals. There is probably a way to do this with the system's audio filters, but I'm not sure.
  2. I don't think macros are the way to go with this. I'm not sure what an approach that uses the abc string would look like offhand, but it would need to be some extension. When you change the decoration is that in one place or every place that appears? A new parameter could be passed in to the synth to control how decorations are created. That would be a useful extension. I haven't spent much time on the decorations so I'm sure they could use a lot of improvement.
  3. There are "invisible bars" [|] that you could use to hang the repeat off of. That will show the standard "first ending" line above the music, though. You could hide that with CSS. I'd think it would be confusing though if the playback didn't match the written music. You can control what gets played back, though. If you create the TimingCallbacks object and start it at the same time as the synth, you can get a callback at a certain beat and seek to some other beat.

There is a way to tweak the output after the file has been processed but before the sound is created. See https://paulrosen.github.io/abcjs/examples/modify-synth-input.html for an example where the durations are tweaked to create swing. You might be able to get your effects using that, or that would at least do part of it.

Let me know how you are doing and I'll point you in possibly the right direction.

(Slightly off topic, did you see the example https://paulrosen.github.io/abcjs/examples/change_glyphs.html in case you need to produce the quarter tones and use that system.)

paulrosen avatar Oct 12 '21 02:10 paulrosen

You're absolutely right, apart from that weird repeat I have no problem transcribing the music. (Also yes I saw the change glyph sample and was fascinated that you know about those :))

Going with extension path is perfect in my eyes. I can write one that is only useful for Persian music and won't push useless stuff in repo. If there is a doc about that, or sample code, I guess I can do it. There is a way to tweak the output after the file has been processed but before the sound is created. If it can be plugged in here then we have a solution. the decorations are same everywhere. so it can be defined externally. for example if I can define this mapping externally image I am all set.

for free repeats we need to show them also image It really look strange, I know, but not really necessary to show boxes per se. any start and end with number will do. Can we implement that with extensions also?

Thanks again, I've been searching for a solution for a long time and your implementation is really close to reach what we need.

kasravi avatar Oct 12 '21 11:10 kasravi

So the decoration is a new one - the four horizontal dots? What is the name of that? Can it have different numbers of dots to mean different sounds? I don't think it would hurt anything to add them - no one who doesn't use them would care. There isn't a doc about how to add a decoration. What I do is search for a similar one and follow the pattern. In this case I'd probably look at staccato since this decoration goes in a similar place to that one.

The free repeats is a little more complicated. My first thought is to use bars to mark the edges, use add_classes: true to get as much info as possible, then post process after drawing.

For instance, if you have the input string:

K:C
Bc !mark!| dc !3!| d/Tc2 !mark!|cB !2!| !2!|

Then, right after renderAbc, look for all the elements that contain the class abcjs-bar you can hide those elements and create a box that goes where the elements were. If the element just before an abcjs-bar element has the class abcjs-annotation then that is the number to use. The beginning of the box contains the class mark.

There are complexities but that might be enough of a hack.

That doesn't help playback, though. For that you would need to intercept the sequence output and modify it. Unfortunately there is probably a lot to modify but it is a simple structure so maybe it is doable.

paulrosen avatar Oct 12 '21 17:10 paulrosen

Yes the decorations I need are not standard. That one is called "riz". It has a two and three dot version (different names) image then there are up, down, up and down, and down and up touches image image and few others.

I agree that pushing them into code base would not hurt anyone, but surely makes the code based unnecessarily complex, and hard to maintain. As all of these are just combination of notes, if we had some kind of macro to define those using abc itself (like how m: macro is suggesting) but only for playback, that should help abc to be even more powerful. Think about it like having a set of headers for Persian music and another set for Irish. Then one can maintain those headers separately and use as needed. I'm looking at them more like a library written in abc. What do you think?

About others I guess I have a lot of info and will try to code a bit. Thanks again.

kasravi avatar Oct 13 '21 14:10 kasravi

Another possibility is to co-opt another decoration and redraw it as a post processing step. That would work easily for everything but the riz. For that you might be able to co-opt the staccato and redraw it. Or, since that doesn't take up space you could just find the note and add it. That is:

<div id="paper"></div>
...
renderAbc("paper", abcString, { add_classes: true})
var notes = document.querySelectorAll("#paper .abcjs-note")
// Then for each note you can get its position with getBBox() and insert what you want.

paulrosen avatar Oct 13 '21 19:10 paulrosen