Closed craigsapp closed 10 months ago
But now I see that the percussion instruments are appended to the end of the list:
MIDINAMES_Gunshot, (last general MIDI instrument, patch change 127)
MIDINAMES_Acoustic_Bass_Drum, (first general MIDI percussion, key number 35)
MIDINAMES_Bass_Drum_1,
MIDINAMES_Side_Stick,
So the enumeration is not intended to match the General MIDI patch-change numbers. But I now am wondering how I can give the General MIDI instrument number to a function and have it return the string name of the instrument? (different from dealing with percussion, which would be some sort of other function to map percussion key numbers to percussion names, perhaps).
There is a list in libmei/atttypes.h
:
But this cannot be accessed directly (since the enumerations of the instruments could change compared to the General MIDI instrument number values).
What is the request? You still want MIDINAMES_NONE
to be -1?
No. Instead It would be nice to have a function that takes a General MIDI instrument number (integer indexed from 0) and have it return the MEI string name. data_MIDINAMES
includes both General MIDI instruments as well as the percussion key numbers on channel 10, so having data_MIDINAMES exactly match the values of General MIDI instrumens is not necessary.
Here is how I am currently doing that:
This is naughty:
data_MIDINAMES idval = (data_MIDINAMES)(gmpc + 1);
idef->SetMidiInstrname(idval);
Since the data_MIDINAMES enumeration could change, causing a bug in this code. I am taking a General MIDI instrument number (from 0 to 127) and casting it to be of type data_MIDINAMES
enumeration.
Probably what I really want is a function similar to:
idef->SetMidiInstrname(idval);
which inputs a General MIDI instrument number instead of a data_MIDINAMES
enumeration value. (These are similar but not identical). And/or a function which converts a General MIDI instrument number (from 0 to 127) into a data_MIDINAMES
enumeration value (from 1-128).
Somewhat related:
In iomusxml.cpp
there is a function that converts a MusicXML instrument name into an MEI instrument name:
In general this will not work since the StrToMidinames
function assumes that the input is an MEI instrument name string:
But the MusicXML midi-name
is an unstructured string rather than an allowed token list:
https://usermanuals.musicxml.com/MusicXML/Content/EL-MusicXML-midi-name.htm
https://usermanuals.musicxml.com/MusicXML/Content/CT-MusicXML-midi-instrument.htm
@craigsapp what is with this issue?
The source of the issue was that I was having problems adding MIDI instrument names to MEI data within verovio, but that problem seems to have been fixed. So the issue can be closed (but see note further below).
Example conversion of a Humdrum score with a soprano clarinet specified:
**kern
*Iclars
*clefG2
*M4/4
=1
1c
==
*-
Which converts to MEI with the instrument name and number, as I was originally wanting to do probably when I submitted the issue:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="http://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="http://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="4.0.0">
<meiHead>
<fileDesc>
<titleStmt>
<title />
</titleStmt>
<pubStmt />
</fileDesc>
<encodingDesc>
<appInfo>
<application isodate="2019-04-11T15:51:28" version="2.1.0-dev-5f615b1">
<name>Verovio</name>
<p>Transcoded from Humdrum</p>
</application>
</appInfo>
</encodingDesc>
<workList>
<work>
<title />
</work>
</workList>
</meiHead>
<music>
<body>
<mdiv xml:id="mdiv-0000001760370640">
<score xml:id="score-0000000667141761">
<scoreDef xml:id="scoredef-0000000072552127" midi.bpm="400">
<staffGrp xml:id="staffgrp-0000001271639941">
<staffDef xml:id="staffdef-0000001331175392" clef.shape="G" clef.line="2" meter.count="4" meter.unit="4" n="1" lines="5">
<label xml:id="label-0000000229569068" />
<instrDef xml:id="instrdef-0000000925153403" midi.instrnum="71" midi.instrname="Clarinet" />
</staffDef>
</staffGrp>
</scoreDef>
<section xml:id="section-L1F1">
<measure xml:id="measure-L5" right="end" n="1">
<staff xml:id="staff-L5F1N1" n="1">
<layer xml:id="layer-L5F1N1" n="1">
<note xml:id="note-L6F1" dur="1" oct="4" pname="c" accid.ges="n" />
</layer>
</staff>
</measure>
</section>
</score>
</mdiv>
</body>
</music>
</mei>
I just updated the humdrum-to-MEI converter to use 0-offset indexing for the instrument numbers (change for MEI 4.0):
https://music-encoding.org/guidelines/v4/elements/instrdef.html
http://fmslogo.sourceforge.net/manual/midi-instrument.html
So in regards to @lpugin's question:
What is the request? You still want MIDINAMES_NONE to be -1?
I would now say yes, since the instrument numbers now start at 0 rather than 1.
In other words my code for setting the instrument number/name is now:
int gminst = 71;
idef->SetMidiInstrnum(gminst);
data_MIDINAMES idval = (data_MIDINAMES)(gminst + 1);
idef->SetMidiInstrname(idval);
It would be preferable to not have to do the +1 to get the name of the instrument.
In libmei/atttypes.h, the enumeration of General MIDI instrument names starts at 1 (with undefined assigned to 0):
https://github.com/rism-ch/verovio/blob/28ec3b58dde0f20fd20a43ff1e9328ccd05ad681/libmei/atttypes.h#L673-L851
However the
instrDef@midi.instrnum
values start at 0 rather than one:http://music-encoding.org/guidelines/v3/data-types/data.midinames.html
So, line 674 above should instead be:
Related to https://github.com/music-encoding/music-encoding/issues/510