Note displayed at the wrong octave but played correclty
Hi,
I'm writing a plugin to make Chords progression workouts.
I've got an issue when adding two specific notes : the B and the Bb.
They are played correctly but displayed one octave to high.
From my log, it seems they are set correctly:
Debug: delta:5, pitch:53, tpc:13, name:F3
Debug: delta:7, pitch:55, tpc:15, name:G3
Debug: delta:9, pitch:57, tpc:17, name:A3
Debug: delta:10, pitch:58, tpc:12, name:B♭3 // <---
Debug: delta:12, pitch:60, tpc:14, name:C4
Debug: delta:6, pitch:54, tpc:20, name:F♯3
Debug: delta:8, pitch:56, tpc:22, name:G♯3
Debug: delta:10, pitch:58, tpc:24, name:A♯3 // <---
Debug: delta:11, pitch:59, tpc:19, name:B3 // <---
Debug: delta:13, pitch:61, tpc:21, name:C♯4
Debug: delta:7, pitch:55, tpc:15, name:G3
Debug: delta:9, pitch:57, tpc:17, name:A3
Debug: delta:11, pitch:59, tpc:19, name:B3 // <---
Debug: delta:12, pitch:60, tpc:14, name:C4
Debug: delta:14, pitch:62, tpc:16, name:D4
Debug: delta:8, pitch:56, tpc:10, name:A♭3
Debug: delta:10, pitch:58, tpc:12, name:B♭3
Debug: delta:12, pitch:60, tpc:14, name:C4
Debug: delta:13, pitch:61, tpc:9, name:D♭4
Debug: delta:15, pitch:63, tpc:11, name:E♭4
What could explain this ?
Where should I look at ?
Attachment | Size |
---|---|
B octave.png | 8.16 KB |
Comments
I reproduced it in a simpler version:
qml file
https://gist.github.com/lgvr123/34c7cb73d888dd9fa972f92d37e0b184
And javascript library that needs to be stored in the plugin folder as "zparkingb/notehelper.js":
https://gist.github.com/lgvr123/647508df432bf4af98210e7e13cd6cb6
This example produces this:
Is this for a transposing instrument? We've had bugs before is the two tpc's get out of sync with each other, but as far as I know those are all fixed internally. Make sure your plugin sets them both correctly.
In reply to Is this for a transposing… by Marc Sabatella
Hi Marc, This issue seems to be indeed related to the fact this is a transposing instrument or not.
I picked some similarly-ranged instruments in this MuseScore instrument file.
The same code is giving different results depending on the instrument:
for the bass-flute (non transposing instrument):
for the saxophone (transposing instrument):
BTW: the two
tpc1
andtpc2
are set to the same value, the note's resultingtpc
being equal to thosetpc1
andtpc2
In reply to Hi Marc, This issue seems to… by parkingb
The tpc's shouldn't be the same for transposing instruments - one needs to be the correct concert pitch spelling, the other the correct transposed spelling. They are allowed to be out of sync (eg, for a Bb instrument, you're allowed to have a concert E that is transposed to Gb instead of F#) but they have to describe the correct pitches.
In reply to The tpc's shouldn't be the… by Marc Sabatella
In order to deduce the adaptation to do, is there a way, from the API, to know if an instrument is transposing and how ?
In reply to In order to deduce the… by parkingb
I don't know, but internally, this would be a "part" (parent of staff) property. In some contexts this is also known as "instrument". If that property isn't available, then maybe there is some more neutral way of adding a note without setting tpc explicitly, then read the tpc to deduce the transposition?
In reply to I don't know, but internally… by Marc Sabatella
I did, in the past, a lot of trials to add/change notes via a plugin. And the tpc is definitely needed if one wants to have the note be displayed correctly with the correct alteration (e.g. "Bb" and not "A#" or "Cbb")... :-(
And as far as read the doc, one can retrieve the instrument from the part, but only a few properties of it, like name, short name,... Not the transposing values.
Maybe I'll need to hardcode them for the few instruments I use in my plugins. I don't like that. But if there is no other way...
In reply to In order to deduce the… by parkingb
Try cursor.addNote which only requires the pitch; then access that note element to read its tpc's and thus deduce the transposition for it?
In reply to Try cursor.addNote which… by jeetee
I think this is a promising start point... A few test shows that can deduce the delta in the tpc that way. I need to apply it to the rest of my code. Thanks.
In reply to Try cursor.addNote which… by jeetee
This was the right approach. Thanks.
Here is how I do:
pitch, tpc1 and tpc2 are set upfront in order to match the desired pitch/representation
In reply to This was the right approach… by parkingb
After many, many, ... tests, trials&errors, the tpc are not the solution. I didn't even came to a solution working at 100%.
Deducing the transposition from the tpc doesn't work because the tpc are not sorted by any musical logic (first the ♭♭ then the ♭ then the naturals, then the ...).
My new algorithm works for all transpositions except for G and F instruments.
It is based on some rules-of-thumb, importing the tpc array and adding to it its "semi-tones delta" (e.g. tpc = 7 is for G is therefore a 7 semi-tones deviation).
See an example in annex.
This being said, I think there are some missing methods in the API to better take into account transposing instruments and accidentals.
I have 2 ideas in mind:
Extend the
cursor.addNote(pitch)
with 2 new optional arguments.cursor.addNote(pitch, isConcertPitch, accidentalPreference)
isConcertPitch : true/false
If true or blank: the note must be added must have the desired pitch (same as today)
If false, the note must be added transposed in order to look like the desired pitch.
Example, on Eb instrument,
*
cursor.addNote(60)
andcursor.addNote(60,true)
gives a note with pitch=60, tpc1=14 (C), tpc2=16 (A)*
cursor.addNote(60,true)
gives a note with pitch=63, tpc1=11 (eb), tpc2=14 (C)accidentalPreference: default/sharp/flat
This sets for a note if a SHARP or a FLAT must be used.
If default, it let's MuseScore choose the right accidental
If sharp, it forces it to a sharp
if flat, it forces it a flat.
Examples:
* The 7th degree of the G scale is a F#. "default" gives "F#", "sharp" gives "F#", "flat" gives "Gb".
* The 4th degree of the F scale is a Bb. "default" gives "Bb", "sharp" gives "A#", "flat" gives "Bb".
With that suggestion, the developper has not to take care of the transposition.
Build an API to consult the instruments.xml file
...in order to retreive by instrument its
transposeChromatic
value.On top of that we could have a method on the note object to change its accidental mode, such as
note.setAccidentalPreference(["default", "sharp", "flat"])
in order for MuseScore to adapt the note tpcs transparently for the developper.What do you think ?
In reply to After many, many, ... tests,… by parkingb
Not sure what issue you are having specifically, but TPC's are most definitely in a logical order - circle of fifths.
In reply to Not sure what issue you are… by Marc Sabatella
Hi Marc, I don't have issues with the tpc's. The system is working great. My only points is that managing transposing instruments (meaning modifying the pitch of note and carefully adapting its tpc's) or switching the b or # of a note (meaning modifying the note tpc's) is not obvious.
E.g. In order to determine if an instrument is transposing and how, one must:
1. Add a note,
2. Retrieve its tpc1 and tpc2 and then compute chromaticTransposition = ((note.tpc2-note.tpc1)*5)%12
3. Adapt the pitch note.pitch+=chromaticTransposition
4. Realigning the note tpc's (basically note.tpc1-=deltaTpc; note.tpc2-=deltaTpc; Basic, but sometimes ugly. More code is needed to get to a decent result)
My proposition was to hide all that logic within the API.