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

Natural accidentals are not remembered within measure #1383

Open
chbauman opened this issue May 20, 2023 · 20 comments · May be fixed by #1384
Open

Natural accidentals are not remembered within measure #1383

chbauman opened this issue May 20, 2023 · 20 comments · May be fixed by #1384

Comments

@chbauman
Copy link
Contributor

chbauman commented May 20, 2023

When there is an accidental, it is not remembered for subsequent notes within the same measure.
This can leads to redundant naturals or missing sharps / flats.

As an example, the following was rendered by MuseScore:
musescore

Now when rendered by OSMD it looks as follows:

before

Which is not correct.

@chbauman
Copy link
Contributor Author

The relevant musicxml file is in the following .zip:

Debug.zip

(Attaching .musicxml directly is now working)

chbauman added a commit to chbauman/opensheetmusicdisplay that referenced this issue May 20, 2023
@sschmidTU
Copy link
Contributor

Actually your sample is working fine for me (without transposition):
image

What settings and version of OSMD did you use to get your result?
I would also guess that this was the same before our release of 1.7.6 today, because the changes shouldn't have affected transposition, but I could be wrong of course.

@chbauman
Copy link
Contributor Author

chbauman commented Jun 7, 2023

I can still reproduce the original issue with version opensheetmusicdisplay@1.7.6.

Did you use the pull request branch? Because there I added some more changes that fixed some of the newly introduced problems with the first commits.

But I think there was still the issue with the double natural in "Dichterliebe" that remained and I did not have the time yet to look further into that.

I extended my debugging score to the following: (MuseScore)
image

OSMD 1.7.6:
image

Branch chbauman:patch-1:
image

@sschmidTU
Copy link
Contributor

I meant that I can't reproduce it in the public demo, which is base OSMD 1.7.6.

https://opensheetmusicdisplay.github.io/demo/

@chbauman
Copy link
Contributor Author

chbauman commented Jun 7, 2023

Oh you're right it looks like this:
image

There is still a redundant flat tho.

But I guess there may be issues on my application that uses OSMD and not OSMD itself.

@sschmidTU
Copy link
Contributor

Do you use Transpose? There's an issue where sometimes accidentals change if you change Transpose after render()

@fablau
Copy link
Sponsor Contributor

fablau commented Jul 28, 2023

Simon, I think the problem appears when you transpose the music, let's say to -2, then revert back to 0. In that case, all accidentals are marked on each note, even though they are in the key signatures. Naturals are always marked.

Look at this example, the first shot below is how the music is shown by default:

TraspStart

Here below, the same music is transposed correctly one tone lower (-2):

TraspC

Then, I transpose it back to its original key (tranposition to 0):

TraspZero

Is that something that can be fixed?

@sschmidTU
Copy link
Contributor

sschmidTU commented Jul 28, 2023

Right, that makes sense, good find.
I mean, you can work around it by just loading it again when you switch back to the original key signature. Since load() takes almost no time, it's not really a drawback other than having to implement the workaround.
As for the root causes, it would need a deeper look. The transposing and accidental code is tricky, I've tried to improve it a few times in the past. It's hard to catch all edge cases.

@fablau
Copy link
Sponsor Contributor

fablau commented Jul 29, 2023

I understand. The only problem with "reloading" the file is that if you have hidden any instruments from the score, they'll reappear, and you may need to hide them again. And I think the same would happen to any other modification you may have done to the score. So the operation may become cumbersome. It'd be nice to have the transposing feature to just work correctly without having to reload the file ;)

@ammatwain
Copy link
Contributor

ammatwain commented Jul 29, 2023

Hi @sschmidTU , hi @fablau !
By removing the condition "transposeHalftones !== 0" from the function "createGraphicalMeasure" and function "checkNoteForAccidental" in the file MusicSheetCalculator.ts, this workaround is no longer necessary, provided that a TransposeCalculator handles it correctly.
You see, the crucial point for me is this:
In particular (in createGraphicalMeasure) in the group of conditions where the value of "transposeHalftones" is evaluated, it is also checked whether TransposeCalculator is an existing object.
Well, I believe that when the TransposeCalculator is brought into play, the TransposeCalculator must dance 🚀.
By the way, this modification is present in the pull request #1420 of the ExtendedTransposeCalculator in my fork :)

@fablau
Copy link
Sponsor Contributor

fablau commented Jul 29, 2023

@ammatwain you are absolutely right! I just tried to remove that clause and it works just fine! I hope there are not "side effects" by removing that check.... @sschmidTU can you confirm that? This would solve a great deal of problems ;)

Thank you!

@ammatwain
Copy link
Contributor

ammatwain commented Jul 29, 2023

Grazie a te, Fabrizio!
Okay, let me tell you the problems I encountered while working on my TransposeCalculator extension.

The main idea was to make it work by directly passing the key signature as a value (then I added octaves as requested by Simon). The issue was transposing from key "x" to key C (zero). In this case, TransposeCalculator didn't react.

So, I started "dirtying up" the values passed to Transpose. Instead of passing 0, I passed 0.00000000000001, instead of 1, I passed 1.00000000000001, and so on. This way, the OSMD routines always triggered TransposeCalculator. (Of course, the methods of TransposeCalculator cleaned up the value with Math.floor() in the first instruction).

Essentially, this was a workaround to bypass the condition checks I found in three routines (hopefully, there are no others). Here they are listed and commented:

MusicSheetCalculator.createGraphicalMeasure() {
 ...
   if ( /* transposeHalftones !== 0 && */
 ...
MusicSheetCalculator.checkNoteForAccidental() {
...
   if (/* transposeHalftones !== 0 && */
   graphicalNote.sourceNote.ParentStaffEntry.ParentStaff.ParentInstrument.MidiInstrumentId !== MidiInstrument.Percussion
   // On this line, it's me adding the condition that TransposeCalculator exists.
   && MusicSheetCalculator.transposeCalculator
   ) {
...
MusicSystemBuilder.transposeKeyInstruction() {
...
        if (/* transposeHalftones !== keyInstruction.isTransposedBy && */
...

In the latest version I'm working on, I removed the "dirtying up" from the value passed to Transpose and also removed the conditions that were blocking TransposeCalculator.

Certainly, those conditions were put there cautiously, probably to allow the sheet to regenerate without TransposeCalculator's supervision. However, as you can see, they end up causing problems themselves.

P.S. I have updated the demo of ExtendedTransposeCalculator to version 1.8.2 of OSMD and with the modifications described above. If you want to test it, I remind you that the link is:
https://ammatwain.github.io/extended-transpose-calculator/

Until we write again :)
Amedeo

@ammatwain
Copy link
Contributor

Hello @sschmidTU , is there a variable I can use to know that the score has just been loaded and it's the first time it has been rendered? Something like firstRenderCompleted: boolean?

@sschmidTU
Copy link
Contributor

@ammatwain No, unfortunately not, because usually it doesn't matter and the developer can easily track it, unless of course you're within OSMD. So, we could add such a variable. I would instead make it renderCount: number though, a bit more flexible.

@ammatwain
Copy link
Contributor

renderCount: number would be perfect and could be used in various situations. I'm asking you this because the idea of letting the renderer work in peace during the initial loading, without the intervention of TransposeCalculator, is good and absolutely justified!

@sschmidTU
Copy link
Contributor

agreed! I'll think about where to put it. Probably in osmd.graphic. Or EngravingRules, since that's what almost all objects have access to, unlike graphic.

@ammatwain
Copy link
Contributor

ammatwain commented Jul 30, 2023

I was thinking that renderCount could be useful to be accessible to the three functions mentioned above:

MusicSheetCalculator.createGraphicalMeasure()
MusicSheetCalculator.checkNoteForAccidental()
MusicSystemBuilder.transposeKeyInstruction()

This way, these functions would have something consistent to prevent TransposeCalculator from taking action!

And, of course, it will also be easily accessible to the user/programmer, who may want to use it for various reasons!

Thank you, Simon!

@fablau
Copy link
Sponsor Contributor

fablau commented Jul 30, 2023

Awesome stuff guys! And Great job with the "ETC Transpose Calculator" @ammatwain, I love it ;)

@ammatwain
Copy link
Contributor

ammatwain commented Jul 30, 2023

Thank you so much, @fablau Fabrizio!

@sschmidTU
Copy link
Contributor

osmd.EngravingRules.RenderCount was added in 1e16c6d.

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