rism-digital / verovio

🎵 Music notation engraving library for MEI with MusicXML and Humdrum support and various toolkits (JavaScript, Python)
https://www.verovio.org
GNU Lesser General Public License v3.0
669 stars 184 forks source link

Implicit accidentals in converter example? #190

Closed craigsapp closed 8 years ago

craigsapp commented 8 years ago

In the converter example music on the page https://github.com/rism-ch/verovio/blob/master/doc/importer.md is there a way of including "implicit" accidentals on notes? (also referencing the SVG output from verovio on the page: https://github.com/rism-ch/verovio/blob/master/doc/importer.svg )

In other words, the second note in the 4th measure is a C-sharp, but the sharp is not shown since it is in the key signature:

screen shot 2016-06-15 at 8 44 29 pm

In the example encoding of the music, there is no sharp on this C:

note = new Note();
note->SetDur(DURATION_16);
note->SetPname(PITCHNAME_c);
note->SetOct(5);
beam->AddLayerElement(note);

Is this an error? I would want to see some "implicit" sharp or a logical/gestural sharp added to this note. And I wonder why there is no natural sign automatically forced in the notation due to the lack of a sharp?

If this is not an error, then note that it is very dangerous to not explicitly encode the sounding accidental within the note element, whether or not it is displayed in the notation.

Calculating the correct pitch for MIDI playback would be a nightmare as you have to read linearly through the music keeping track of key signatures and previous alterations of notes on the staff (across separate layers), also keeping track of accidentals related to ties across barlines. Transposition of the notes could be equally difficult. Extracting measures without the accompanying key signatures would cause problems as well. etc.

lpugin commented 8 years ago

In MEI this is encoded as a @accid.ges. So you should do

note->SetAccidGes(ACCIDENTAL_IMPLICIT_s)
craigsapp commented 8 years ago

Thanks! I notice that there is no ACCIDENTAL_IMPLICIT_x in libmei/atttypes.h. Is an implicit double-sharp supposed to be missing? There is an ACCIDENTAL_EXPLICIT_x in the file, but the closest implicit one I see is ACCIDENTAL_IMPLICIT_ss:

https://github.com/rism-ch/verovio/blob/master/libmei/atttypes.h#L50-L64

I also just created a branch called ACCIDENTAL_IMPLICIT_ss as I was typing a search for that term, but putting the text in the wrong text box on the page (one which creates branches rather than finding files). I'll let you delete it, so I don't accidentally delete something else when trying to get rid of it....

pe-ro commented 8 years ago

Since @accid.ges is intended to represent performance, not visual information, so the value set for implicit accidentals is limited to the unique set of perform-able accidentals.

craigsapp commented 8 years ago

Then that leads me back to square one. How should this example be corectly encoded in MEI/verovio:

screen shot 2016-06-16 at 7 27 17 am

Must I use @accid on the second two notes, and is @accid.ges actually optional for the first note?

What happened to @accid.vis? That should be the "explicit" accidental forced to be displayed in the music. @accid.vis="none" should be used to force suppression of an accidental, and @accid should store the "logical" accidental, i.e., the local information about the accidental state so that it does not have to be inferred from the musical context (key signature, etc). If there is no @accid.vis, then verovio should calculate it from @accid states of notes.

I want to do: @accid="s" for the first note (no @accid parameter) for the second note, as the default should be to assume natural. @accid="s" for the third note

And leave it up to verovio to calculate @accid.vis (unless @accid.vis is present for the note): @accid="s" --> @accid.vis="none" since the key signature handles this sharp (no @accid) --> @accid.vis="n" since previous note accidental needs to be changed. @accid="s" --> @accid.vis = "s" since previous note accidental needs to be changed.

Must I myself calculate whether an accidental should be displayed or not depending on the key signature, previous states for that diatonic pitch previously in the measure, as well as notes tied across barlines? I can do that but I don't see the purpose, as SCORE is the only program I use which does what I think is happening here. Here is my code to do such with SCORE data, and which should be present in verovio for doing what I want: https://github.com/craigsapp/scorelib/blob/master/src-library/ScorePage_pitch.cpp#L50-L147

Below is an example chorale excerpt. The red notes have accidentals which are not musically necessary, but given as a courtesy to the performer. These are the only notes where I would want to encode an "explicit" accidental (which seems to currently mean @accid, but I want as @accid.vis), and the rest I want to encode as "implicit" accidentals (which would be encoded with what note attribute, and I want @accid)? I would expect verovio to take care of the implicit accidentals (displaying then when necessary according to the standard rules of accidental display) so that I don't have to calculate the visible states myself.

screen shot 2016-06-16 at 7 35 02 am

pe-ro commented 8 years ago

I'm sorry, but it's much too late to reconsider the names and functions of the accidental-related attributes.

The correct encoding of your 3-note example is

<note pname="f" oct="4" accid.ges="s"/> <!-- @accid.ges captures performed accidental -->
<note pname="f" oct="4" accid="n"/> <!-- @accid records written accidental -->
<note pname="f" oct="4" accid="s"/> <!-- ditto -->

This provides enough information to calculate the proper written or sounding pitch from the note without having to reference the key signature, doesn't it? (N.B. Since @accid.ges is optional, sometimes calculation based on the prevailing key signature may be necessary. You may choose to always supply it, but it can't be required syntactically.)

In the choral example, every note with a written accidental (not just the red ones) should use @accid to record the presence of a written accidental. @accid.ges isn't necessary because the performed pitch will the same as the written one.

You may want to consider using <accid> (as a child of <note>) instead of @accid. This will allow the use of @func to indicate the accidental's purpose (cautionary or editorial) and provide another "handle" for making display / performance decisions.

craigsapp commented 8 years ago
<note pname="f" oct="4" accid.ges="s"/> <!-- @accid.ges captures performed accidental -->
<note pname="f" oct="4" accid="n"/> <!-- @accid records written accidental -->
<note pname="f" oct="4" accid="s"/> <!-- ditto -->

This provides enough information to calculate the proper written or sounding pitch from the note without having to reference the key signature, doesn't it?

Yes that is sufficient, but I am wondering what is the accidental state of a note if neither @accid.ges nor @accid are given? I would prefer that that means there is an inferred @accid.ges="n" for the note, rather than saying that the inferred accidental must be extracted from the key signature/previous pitch in the measure/tied note in previous measure(s).

You may choose to always supply it, but it can't be required syntactically

Early music notation can have undefined @accid.ges (musica ficta), but it is a fairly definitive property of notes after 1600. Do you mean syntactically in a technical sense, as in not enforceable by an XML Schema/DTD? Or do you mean that it can't be required since it wasn't previously required? Or something else?

Mostly I seem to be irritated that @accid.ges is not always required (if the note is not natural), and secondly that I have to calculate @accid from @accid.ges rather than leaving that up to verovio. Relying on the prevailing key signature for any interpretation of a note's accidental is bad from a computational analysis point of view due to the complexity of the assignment (both calculation time and increased chance of bugs).

For example, calculating intervals between pitches would be complex. Suppose that you want to identify parallel perfect 5ths in a chorale. There would have to be an intermediate step of filling in any inferred @accid.ges from the key signature/previous accidental states of notes in the measure, or tied notes from previous measures(s) before the intervals could be identified.

Changing a key signature without transposing the music would also be complex process: Suppose that a C-sharp gets its property of a sharpness from a D major key signature. Now change the key signature to B-flat major. The original C-sharp would now be interpreted as a C natural. In other words, modal transpositions would be easy, but preserving the original intervals would not.

I'm sorry, but it's much too late to reconsider the names and functions of the accidental-related attributes.

I have never heard that excuse from you before :-)

But OK, I will do that, although I will be grumbly due to the extra code and complexity involved. But also I will not be keen on manipulating MEI data, such as transposition and other analytic processes involving pitch if it is not locally defined or inferable within the note element.

<note pname="f" oct="4" accid.ges="s"/> <!-- @accid.ges captures performed accidental -->
<note pname="f" oct="4" accid="n"/> <!-- @accid records written accidental -->
<note pname="f" oct="4" accid="s"/> <!-- ditto -->

I would prefer a slight alteration, as you were mentioning by always reporting the sounding accidental in @accid.ges:

<note pname="f" oct="4" accid.ges="s"/> <!-- @accid.ges captures performed accidental -->
<note pname="f" oct="4" accid="n" accid.ges="n" /> <!-- @accid records written accidental -->
<note pname="f" oct="4" accid="s" accid.ges="s"/> <!-- ditto -->

In that way I encode the analytic accidental in a consistent location.

Here is a case where not supplying the @accid.ges would involve a lot of searching for the correct answer for the accidental state of the note in the last measure:

screen shot 2016-06-16 at 9 52 37 pm

​The last note can be inferred to be an f-natural, but you have to traverse back to the start of the piece to identify the accidental.

Here is a special case where the accidental is undefined:

screen shot 2016-06-16 at 9 58 43 pm

​It could be an F-sharp or an F-natural, depending on what the missing note on the other side of the tie is. If a measure is extracted from an MEI file, an inferred accidental for such a note would become undefined. To properly extract a measure, the accidental state would have to be analyzed before extracting and filled into @accid.ges.

Was there never an @accid.vis? I see talk about it last year in the verovio issues: https://github.com/music-encoding/sibmei/issues/38 I don't see it in the MEI 201005 documentation. Where is the earlier documentation, or was that the first PDF version of the documentation?

In the choral example, every note with a written accidental (not just the red ones) should use @accid to record the presence of a written accidental. @accid.ges isn't necessary because the performed pitch will the same as the written one.

A-ha, but does that mean that if @accid and @accid.ges are not the same, then @accid.ges should be specified? (which is close to my initial complaint that neither @accid or @accid.ges were given, but @accid.ges is inferred from the key signature rather than being given on the note).

You may want to consider using (as a child of ) instead of @accid. This will allow the use of @func to indicate the accidental's purpose (cautionary or editorial) and provide another "handle" for making display / performance decisions.

Those will be useful (presuming that verovio allows me to add the accid subelement :-). Cautionary accidentals will be identified in the process of calculating @accid. Editorial accidentals will be useful to add to the converter as well. accid@func="caution" is the format for cautionary accidentals I see, and accid@func="edit" for editorial accidentals. Is there a way of specifying the style, such as how to encode the editorial F# such as in this example above the note:

screen shot 2016-06-16 at 10 17 39 pm


Here is an analysis of MusicXML's behavior in Finale encoding:

screen shot 2016-06-16 at 10 43 50 pm

First the most proper way:

                        <note>
                                <pitch>
                                        <step>F</step>
                                        <alter>1</alter>
                                        <octave>4</octave>
                                </pitch>
                                <duration>1</duration>
                                <voice>1</voice>
                                <type>quarter</type>
                        </note>
                        <note>
                                <pitch>
                                        <step>F</step>
                                        <octave>4</octave>
                                </pitch>
                                <duration>1</duration>
                                <voice>1</voice>
                                <type>quarter</type>
                                <accidental>natural</accidental>
                        </note>
                        <note>
                                <pitch>
                                        <step>F</step>
                                        <alter>1</alter>
                                        <octave>4</octave>
                                </pitch>
                                <duration>1</duration>
                                <voice>1</voice>
                                <type>quarter</type>
                                <accidental>sharp</accidental>
                        </note>

note/pitch/alter is the equivalent of note@accid.ges, and note/accidental is the equivalent of note@accid.

This notates as expected in Finale:

screen shot 2016-06-16 at 10 46 12 pm

If I remove the note/accidental elements it behaves similar to how you say MEI behaves:

screen shot 2016-06-16 at 10 47 41 pm

No accidentals are displayed, but the gestural accidentals from note/pitch/alter yield the same MIDI playback.

An interesting thing happens when the note/pitch/alter elements are removed from the first and last notes, but the note/accidental is left on the last note:

screen shot 2016-06-16 at 10 57 14 pm

The printed music has F#, Fn, Fn while the MIDI playback is Fn, Fn, Fn. So note/accidental is ignored if it is in conflict with note/pitch/alter. If I add an note/accidental="sharp" to the first note, but do not give note/alter="1", then it behaves similar to the last note in the previous case:

screen shot 2016-06-16 at 11 01 12 pm

So not giving the note/pitch/alter (note@accid.ges) in MusicXML generates erratic behavior. If it disagrees with note/accidental (note@accid), then it is overriding that parameter and displaying the gestural accidental.

Here is the code that my Humdrum to MusicXML convert uses to do what I will also have to do in the MEI converter:

https://github.com/craigsapp/humextra/blob/master/src-programs/hum2xml.cpp#L2043-L2128


Humdrum accidentals can be categorized as MEI @accid.ges accidentals. Here is the Humdrum encoding of the example music:

**kern
*M3/4
*k[f#]
=1-
4f#
4f
4f#
==
*-

Here is how I convert to MuseData:

F#4    1      1 q
F4     1      1 q
F#4    1      1 q

which generates this graphical notation:

screen shot 2016-06-16 at 11 10 18 pm

In MuseData, the pitch names in the first columns also function as MEI @accid.ges; however, the @accid values are inferred from the @accid.ges information. If the expected spelling of a note does not match the current @accid.ges state, then the @accid value would be assigned from the @accid.ges value internally when printing. This is the sort of system I was expecting to find in verovio.

In Humdrum, I indicate cautionary accidentals by adding an "X" after the accidental:

**kern
*M3/4
*k[f#]
=1-
4f#X
4f
4f#
==
*-

Another way of thinking about it is that in "4f#" the accidental is @accid.ges, while in "4f#X", the accidental is @accid. In both cases the indication that the note posses a sharp is present, and it is forbidden to leave it off (otherwise it becomes an F-natural: "4f" which would mean @accid.ges="n").

Here is the conversion to MuseData:

F#4    1      1 q               +
F4     1      1 q
F#4    1      1 q

The plus on the right indicates that the accidental should be displayed even if it is not required to be displayed.

And the graphical representation:

screen shot 2016-06-16 at 11 15 47 pm

Lilypond also behaves in a similar manner to MuseData (and as I wish verovio to behave):

\score{ {\key g \major fis' f' fis'} }

screen shot 2016-06-16 at 11 29 27 pm

\score{ {\key g \major f' fis'} }

screen shot 2016-06-16 at 11 31 39 pm

lpugin commented 8 years ago

@craigsapp this was already discussed a while ago. The rule is actually pretty simple: @accid also applies to the gestural domain unless they are different. So

<note pname="f" oct="4" accid.ges="s"/>
<note pname="f" oct="4" accid="n" /> 
<note pname="f" oct="4" accid="s" /> 

"Means"

<note pname="f" oct="4" accid.ges="s"/> <!-- @accid.ges captures performed accidental -->
<note pname="f" oct="4" accid="n" accid.ges="n" /> <!-- @accid records written accidental -->
<note pname="f" oct="4" accid="s" accid.ges="s"/> <!-- ditto -->

But the attribute is not duplicated. So there is no need to look at the key signature. You only look at both @accid and accid.ges. Very small overhead with the advantage of not duplicating information (which also has drawbacks).

craigsapp commented 8 years ago

I am happy if the pitch is locally defined within a note element and the accidental state is not influenced by the key signature, etc.,

@accid implying @accid.ges is fine. Does this also mean that @accid.ges can imply @accid?

Going back to my original example:

screen shot 2016-06-17 at 7 25 46 am On the page: https://github.com/rism-ch/verovio/blob/master/doc/importer.md

you encoded the last note as:

note = new Note();
note->SetDur(DURATION_16);
note->SetPname(PITCHNAME_c);
note->SetOct(5);
beam->AddLayerElement(note);

The note is a C-sharp, but you do not include

note->SetAccidGes(ACCIDENTAL_IMPLICIT_s);

Was it incorrect for you to omit that line?

Without SetAccidGes(), what is the accidental state of this note? If the accidental state of the note is defined locally within the note element, then the note is a C-natural. However, in the verovio rendering, the note is an implicit C-sharp:

screen shot 2016-06-17 at 7 37 50 am

The verovio graphical notation rendering is incorrect since the note is an implicit C-natural, but an implicit C-sharp is being displayed instead. Eventhough @accid is empty, the implied @accid.ges is a natural, and the rendering should force a natural in the notation, overriding the undefined @accid. If the note is a natural and yet the notation should not show the required natural sign, then there should be an additional state added to @accid such as @accid="none" to suppress an accidental which is otherwise obligatory.

If the note in question is a implicit C-natural, and verovio's rendering is correct, then how can anyone sanely proofread MEI data by examining the musical notation output of verovio, since the C-natural looks instead to be a C-sharp?

The logical conclusion is that I end up being very happy, because I will convert **kern accidentals into @accid.ges with no @accid supplied (except in cases where I want to force an accidental). And it is up to verovio to determine the correct implied @accid value.


For further comparison, here is the example encoded in Lilypond:

\score{
    { \key d \major \partial 8 r8
      \compressFullBarRests
      \override MultiMeasureRest.expand-limit = #2
      R1*3  
      b'8[ c''16] \staccato
    }
}

screen shot 2016-06-17 at 8 05 08 am

Note that the C has an implicit natural sign which is made explicit in the graphical rendering; otherwise, leaving out the accidental would place an implicit sharp sign on the note.


MuseData analysis:

The MuseData encoding:

$  K:2   Q:1   T:2/4   C:4
B4     1      1 q     d
C5     1      1 q     d
mheavy2

Produces:

screen shot 2016-06-17 at 8 18 10 am

In MEI terminology, both lilypond and MuseData are encoding accidentals in @accid.ges, and the programs are calculating @accid according to standard modern accidental displaying rules.

In MuseData, @accid would only be used to force an accidental to be displayed that would otherwise be hidden (and cannot be used to hide an otherwise obligatory accidental):

$  K:1   Q:1   T:4/4   C:4
F#4    1      1 q
F#4    1      1 q
F#4    1      1 q
F#4    1      1 q
mheavy2

screen shot 2016-06-17 at 8 26 10 am

Adding explicit @accid information in MuseData:

$  K:1   Q:1   T:4/4   C:4
F#4    1      1 q              +
F#4    1      1 q              +
F#4    1      1 q              +
F#4    1      1 q              +
mheavy2

screen shot 2016-06-17 at 8 30 16 am

lpugin commented 8 years ago

There is a note->SetAccidGes(ACCIDENTAL_IMPLICIT_s); at the line 132, so I assume everything is OK.

craigsapp commented 8 years ago

That is better :-), but there still is a significant problem if @accid.ges cannot imply @accid:

If the note in question is a implicit C-natural, and verovio's rendering is correct, then how can anyone sanely proofread MEI data by examining the musical notation output of verovio, since the C-natural looks instead to be a C-sharp?

lpugin commented 8 years ago

It is solved by the opposite rule: @accid.ges is implied by @accid ;-) But I understand that this is more work for you because humdrum does not make the distinction between the two domains and you need to look at the keysig (and previous notes in the measure) during the import in order to determine if you need to add a @accid or/and an accid.ges.

craigsapp commented 8 years ago

That does not solve the problem. I can generate the correct output with an hour or so of extra coding, as I have done the same thing in several other converters. The problem is that there will be cases where the MEI data represents something which is impossible to represent in graphical music notation.

If the example music

screen shot 2016-06-17 at 10 27 14 am

contains no @accid or @accid.ges on the last note, then there are two possible interpretations for the accidental state of that note:

1: The note is a C-natural because the accidental state is defined internally to the note element. And since there is no accidental state in either @accid or @accid.ges, the accidental must be inferred to be a natural. 2: The note is a C-sharp because there is no @accid or @accid.ges, and the accidental state is defined external to the note element, which in this case is by the key signature.

There is also a third interpretation, which @pe-ro has already discounted: 3: It is a syntax error if at least one of @accid or @accid.ges is not defined. This interpretation would of course be problematic to enforce, since the convention in MEI encoding is to assume a natural if no accidental is given, similar to if I say "play a C", it is assumed that I mean "play a C-natural".

If interpretation 2 is correct, then I will be very irritable, as processing MEI pitch data would become very complex.

Therefore interpretation 1 is the most likely interpretation. From this logically follows that @accid.ges must be able to imply @accid (if @accid is not explicitly given). If the note is a C-natural, an explicit natural sign must be displayed in front of the note in musical notation; otherwise, the note is implicitly a C-sharp due to the key signature. This means that @accid.ges is forcing @accid="n" onto the data in order to print syntactically correct graphical notation.

If you do not print syntactically correct graphical notation, then it will be impossible to use the graphical notation to proofread the corresponding MEI data: the note looks like a C-sharp in example graphical notation, but the MEI data says that it is a C-natural (before you corrected the data and added the gestural accidental :-).

lpugin commented 8 years ago

then there are two possible interpretations for the accidental state of that note

This is why we need guidelines because the encoding itself does not provide information about how it should be interpreted.

But first, to make sure we are clear, the C is expected to be encoded as

<note pname="c" accid.ges="s"/>

In such a case, Verovio (and any other renderer) should not display a sharp but the sounding value is expected to be C-sharp.

Now with

<note pname="c" />

even if we have 2 sharps at the key signature, a renderer is still expected no to display a sharp and the sounding value is expected to be C (natural).

With

<note pname="c" accid="s"/>

a sharp has to be displayed and the sounding value is C-sharp as well. This is what I mean by "@accid.ges is implied by @accid"

Now there is one thing I think we need to clarify in MEI which is to be able to indicate in the header whereas the gestural domain is encoded or not. This was the problem with the importer example before the @accid.ges was added. That is, it is MEI data the encoded only the visual domain. Unless we think that the gestural domain has to be encoded, but of course this cannot be checked by the schema and is purely a recommendation issue.

craigsapp commented 8 years ago

The general problem is how to handle syntax errors in the rendered musical notation. What are you going to do if someone encodes:

<note pname="c" />

at a point in the music which would otherwise require @accid.vis="n" due to the key signature containing a sharp, or the same diatonic pitch having a C-sharp earlier in the measure? If this note is intended to have an implicit natural accidental, then printing no accidental in front of the note automatically generates a syntax error in the music rendering, and this syntax error would be very hard to track down, and therefore MEI encodings will be prone to having this syntax error. This is a content error which cannot be dealt with by schema/DTD validation of the XML structure, therefore it is the responsibility of the rendering program to deal with it. I propose that the renderer must insert @accid.vis="n" for such a case; otherwise, the printed music contains a hidden syntax error. If the data encoder does not want the renderer to fix the syntax error, then there should be something like @accid.vis="none" permitted in the MEI definition. This would tell the renderer that the apparent syntax error is intentional rather than accidental.

Ideally the MEI format would not permit such syntax errors from being possible, or at least make them harder to generate than the current case where the attribute is left off of the note by accident.

The preferred MEI accidental system would have been:

kepper commented 8 years ago

Hi Craig,

Am 17.06.2016 um 22:16 schrieb Craig Stuart Sapp notifications@github.com:

the printed music contains a hidden syntax error

well, what you call an error really isn't one. Rule number 1 for CMN is "don't trust the rules". I would strongly argue against any renderer trying to correct the data I pass to it, as the way we have to read accidentals is not consistent throughout the CMN period. For instance, in his St. Matthew's passion, Heinrich Sch�tz uses flats and sharps to neutralize the respective other accidental. This results in notes with accid="s" and accid.ges="n". Also, the effective range of accidentals has been different at that time: An accidental affects all following notes of the same pitch, and is neutralized by the first note with a different pitch. Barlines make no difference in this, so you can easily have a sharp in one measure, and as long as all pitches stay the same, it can still apply to a note a couple of measures later. We don't have to go back to Sch�tz to observe this � even JSBach sometimes followed this convention. The "sometimes" indicates why no renderer should take an active decision here: These conflicting conventions are sometimes used side by side in the same score, and you really have to read the music to identify which rules apply. I think it's fine to do some kind of sanity check and hint the encoder to questionable use of accidentals, but if the intention is to faithfully transcribe a (manuscript) source, there is no way around accepting any use of accidentals.

I absolutely agree that MEI lacks a mechanism to indicate which domains have been addressed by an encoding (i.e., how to deal with missing accid.ges attributes), and there may be need for a tool which modifies an MEI file to follow modern use of accidentals, but I would rather not make this a default behavior of a renderer. I just don't believe that the application should pretend that it's cleverer than the encoder � the risk of failure is pretty high, depending on repertoires�

Just my 2c, jo

craigsapp commented 8 years ago

The essential problem is that:

    <note pname="c" accid="s" />
    <note panme="c" />

Should not be rendered as: screen shot 2016-06-18 at 10 34 27 am

Otherwise it will be assumed that the second note must be implicitly C-sharp since the previous one was explicitly C-sharp. And using external contexts outside of the note element is a bad way of defining the accidental of the note in digital encodings.

If someone really wants that graphical rendering, then it should be encoded as:

    <note pname="c" accid="s" />
    <note pname="c" accid="none" />

In other words, the concept of 0 needs to be invented for @accid. The encoder should be required to actively assert non-standard behavior, and that behavior should not be introduced due to an error by the encoder.

Otherwise, how can syntax errors be identified in the MEI encoding? If anything can be done, then nothing is wrong. And error-checking encodings becomes very difficult. The source of this discussion is the example on this page: https://github.com/rism-ch/verovio/blob/master/doc/importer.md Clearly there was an an error (if @pname="c" by itself is supposed to mean "c-natural"), but the encoder did not notice it when encoding, and I did not notice it until looking very very closely at the encoding. Notice that this is only a single line of music. Now imagine dealing with an entire symphony...

By extension, I am saying that all diplomatic encodings of manuscripts should use @accid="none" if there is no visible accidental in the notation for a note. Relying on a default behavior or interpretation if @accid is not given would be dangerous. And also by extension, the MEI guidelines should explicitly discuss what the meaning of @accid being undefined is (and at least try to promise that the undefined state behavior will not be changed). And it is best to cross-index this discussion with the description of the attribute on the element pages which use @accid, such as notes; http://music-encoding.org/documentation/3.0.0/note

Note that there is no feature for searching inside the guidelines: http://music-encoding.org/documentation/3.0.0/chapters There is only a side-wide search on that page. It would be useful to implement a search specific to the guidelines. It would also be great to search for @accid and have the search results return all discussions of that attribute in the guidelines.

The guidelines should instruct how to interpret an unspecified attribute, as in this case where both @accid and @accid.ges are undefined (it seems like we discussed this before, but it is not in my email, so perhaps at a Detmold meeting). So, what the "meaning" of:

    <note pname="c" />

Does is mean C-natural, or C with an undefined accidental? If it means C-natural, then the above graphical rendering cannot be used to display it, as it will be misinterpreted by people reading the notation, particularly if the repertory is in CMN. For encoding diatonic music notation of the early Renaissance, that encoding is somewhat reasonable, but more properly it should be encoded as:

    <note pname="c" @accid="none">

because there is an explicit lack of an accidental sign for the note, but the @accid.ges is undefined (it is to be assigned by a performer and is not an absolute state that can be explicitly inferred from a manuscript).

So, what I am saying is that if @accid is not given, it should not be interpreted as @accid="none", and it should be up to the renderer to apply the correct accidental in @accid based on @accid.ges. If this is not true, then the guidelines should have a lengthly discussion on the topic so that people implementing software for MEI do not make up their own conventions for undefined attributes.

For instance, in his St. Matthew's passion, Heinrich Sch�tz [Schütz] uses flats and sharps to neutralize the respective other accidental. This results in notes with accid="s" and accid.ges="n".

That is what I said :-)

@accid.vis="s" could be used for encoding seventeenth century music where a sharp sign would be used to indicate an e-natural (@accid="n" or @accid unspecified) in the key of C minor (the sharp is a relative sign rather than an absolute sign in this case, so contrary to modern conventions)

It also supports my viewpoint that @accid should be demoted and called "@accid.vis", as it is describing a printed symbol which has multiple interpretations in different repertories (I am not expecting this to happen, however :-). @accid[.ges] should have a consistent meaning across all repertories so that the data can be translated into different visual systems, and @accid.vis should be used to adjust the meaning with the correct visual symbol for the repertory.

I understand what you are saying, as I work with music even older which has even more interpretive sublties. On the Josquin Research Project website, there are always two versions of the graphical score: one showing the literal accidentals in the original sources (@accid biased score), and another given editorial accidentals for performance by modern performers who cannot themselves figure out the implicit accidentals (@accid.ges biased score). But it seems that SCORE would be an ideal encoding system for you... It is purely a visual description of the music on the page, so there are only @accid for notes. And it also has no @pname to worry about either. Note that SCORE has an explicit representation for no visual accidental, and something similar is probably wise to add to MEI as well.

but if the intention is to faithfully transcribe a (manuscript) source, there is no way around accepting any use of accidentals.

So what I am hearing is that you agree that @accid="none" should be created?

I would find it acceptable to have verovio have option for how to treat notes with undefined @accid: either undefined @accid means no accidental, or undefined @accid means undetermined and left up to the renderer to deal with. And if so, then it would be best if the option is specified in the MEI data itself, such as some field in the header for what convention should be applied to cases where @accid is undefined.

craigsapp commented 8 years ago

I have come across an illogical feedback loop in my automatic identification of @accid given @accid.ges: whether to display an accidental or not is contextually dependent on the layout of the music. As I want verovio to layout the music, I have no idea for certain cases if the accidental should be shown or not. Specifically the standard convention in CMN is to suppress the accidental for the note tied over a barline except in the case where the tie crosses a system break:

No accidental on secondary tied note in next measure:

screen shot 2016-06-18 at 12 33 52 pm

Accidental on secondary tied note in next measure after line break:

screen shot 2016-06-18 at 12 42 15 pm

donbyrd commented 8 years ago

Good point that "whether to display an accidental or not is contextually dependent on the layout of the music." But it's not absolutely required across a system break. Gould (p. 87) says "It is helpful to repeat an accidental on a tied note at the beginning of a new system… For music with many tied chords, it is often better not to repeat accidentals…" (emphasis mine) So I'd say that Verovio should have an option to add accidentals on tied notes at the beginning of a new system if it's doing the layout. Ideally it should probably also give the user a choice of whether to enclose such accidentals in parentheses.

craigsapp commented 8 years ago

@donbyrd: That sounds good, although it might be also be nice to have a field in the MEI header which is used to specify an how automated treatment of this situation should be handled in a renderer, and which verovio would use if no option is given directly to verovio. By default no accidentals should be added, but some setting in the MEI header could say that accidentals should be automatically when ties cross system breaks.

craigsapp commented 8 years ago

Another thought: how to deal with app or rdg elements at the note level that would require a change in the value of @accid on a following note in the measure? In cases where the app/rdg would cause a change in the @accid state of a following note in the measure, the app/rdg must moved instead to the measure level?

lpugin commented 8 years ago

@craigsapp, your proposal is basically so switch the precedence of the gestural domain over the visual one (let us forget about the distinction between the analytical and gestural ones since as you say it is identical in most music). Coming with humdrum data, I can understand this ;-)

In the importer example, the gestural domain was not encoded in the first place. But this is not an error, this is MEI that encodes only the visual domain. We all agree MEI is missing the indication whereas the gestural domain is encoded or not, and this is probably a critical issue but not too difficult to fix. Furthermore, you would have detected straight away by listening to it.

Now switching the precedence as you suggest also switches the issue. If I listen to a file where @accid represent the gestural domain, how am I going to detect if accid.vis is properly encoded? One can also say that this is going to be error prone. And here too you would need an indication whereas the visual domain is encoded or not. And here too you can have a tool that fills the secondary domain following the standard practice of accidental handling in CWMN. In the end, for verifying both domains you need rendering of both domains (even though here there is some advantage with the MEI solution because it is easier to render the gestural domain visually, for example with all the accid.ges shown in color, while I cannot think of an similar way of rendering the visual domain in audio).

So the conclusion is that we need better guidelines for this because as you say we have to make sure the encoding is always interpreted in the same way. Are you willing to contribute ? ;-)