Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6929,7 +6929,11 @@ Note* MusicXmlParserPass2::note(const String& partId,
Color beamColor;
bool noteheadParentheses = false;
String noteheadFilled;
int velocity = round(m_e.doubleAttribute("dynamics") * 0.9);
// velocity as a percentage of the MIDI 1.0 default forte value of 90;
// an explicit dynamics="0" means a silent note, which the score model can
// only represent as velocity 1 (velocity 0 means "unset")
const bool hasDynamics = m_e.hasAttribute("dynamics");
const int velocity = std::clamp(int(round(m_e.doubleAttribute("dynamics") * 0.9)), 1, 127);
bool graceSlash = false;
bool printObject = m_e.asciiAttribute("print-object") != "no";
bool printLyric = (printObject && m_e.asciiAttribute("print-lyric") != "no") || m_e.asciiAttribute("print-lyric") == "yes";
Expand Down Expand Up @@ -7260,7 +7264,7 @@ Note* MusicXmlParserPass2::note(const String& partId,
}
}

if (velocity > 0) {
if (hasDynamics) {
note->setUserVelocity(velocity);
}

Expand Down
84 changes: 84 additions & 0 deletions src/importexport/musicxml/tests/data/testNoteDynamics.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
The dynamics attribute of <note> maps to the note's velocity as a
percentage of the MIDI 1.0 default forte value of 90. The expected
imported velocities (visible as <velocity> in the reference .mscx) are:
- no dynamics attribute -> no <velocity> element (unset)
- dynamics="0" -> velocity 1 (silent note; 0 means "unset"
in the model, so it is clamped
to the lowest representable value)
- dynamics="50" -> velocity 45 (50% of forte = 90)
- dynamics="200" -> velocity 127 (clamped to the MIDI maximum)
-->
<score-partwise version="4.0">
<movement-title>Note dynamics attribute</movement-title>
<part-list>
<score-part id="P1">
<part-name>Voice</part-name>
</score-part>
</part-list>
<part id="P1">
<measure number="1">
<attributes>
<divisions>480</divisions>
<key>
<fifths>0</fifths>
</key>
<time>
<beats>5</beats>
<beat-type>4</beat-type>
</time>
<clef>
<sign>G</sign>
<line>2</line>
</clef>
</attributes>
<note>
<pitch>
<step>C</step>
<octave>4</octave>
</pitch>
<duration>480</duration>
<voice>1</voice>
<type>quarter</type>
</note>
<note dynamics="0">
<pitch>
<step>D</step>
<octave>4</octave>
</pitch>
<duration>480</duration>
<voice>1</voice>
<type>quarter</type>
<notehead>x</notehead>
</note>
<note dynamics="50">
<pitch>
<step>E</step>
<octave>4</octave>
</pitch>
<duration>480</duration>
<voice>1</voice>
<type>quarter</type>
</note>
<note dynamics="200">
<pitch>
<step>F</step>
<octave>4</octave>
</pitch>
<duration>480</duration>
<voice>1</voice>
<type>quarter</type>
</note>
<note>
<pitch>
<step>G</step>
<octave>4</octave>
</pitch>
<duration>480</duration>
<voice>1</voice>
<type>quarter</type>
</note>
</measure>
</part>
</score-partwise>
164 changes: 164 additions & 0 deletions src/importexport/musicxml/tests/data/testNoteDynamics_ref.mscx
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
<?xml version="1.0" encoding="UTF-8"?>
<museScore version="5.00">
<Score>
<eid>B_B</eid>
<Division>480</Division>
<Style>
<hideInstrumentNameIfOneInstrument>0</hideInstrumentNameIfOneInstrument>
<spatium>1.75</spatium>
</Style>
<showInvisible>1</showInvisible>
<showUnprintable>1</showUnprintable>
<showFrames>1</showFrames>
<showMargins>0</showMargins>
<metaTag name="arranger"></metaTag>
<metaTag name="composer"></metaTag>
<metaTag name="copyright"></metaTag>
<metaTag name="lyricist"></metaTag>
<metaTag name="movementNumber"></metaTag>
<metaTag name="movementTitle">Note dynamics attribute</metaTag>
<metaTag name="source"></metaTag>
<metaTag name="translator"></metaTag>
<metaTag name="workNumber"></metaTag>
<metaTag name="workTitle"></metaTag>
<Part id="1">
<eid>C_C</eid>
<Staff>
<eid>D_D</eid>
<StaffType group="pitched">
<name>stdNormal</name>
</StaffType>
</Staff>
<Instrument id="voice">
<InstrumentLabel>
<longName>Voice</longName>
</InstrumentLabel>
<trackName></trackName>
<instrumentId>voice.vocals</instrumentId>
<Articulation>
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="staccatissimo">
<velocity>100</velocity>
<gateTime>33</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="portato">
<velocity>100</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="marcato">
<velocity>120</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>150</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="sforzatoStaccato">
<velocity>150</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoStaccato">
<velocity>120</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoTenuto">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
<program value="0"/>
<controller ctrl="10" value="63"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">
<VBox>
<height>10</height>
<eid>E_E</eid>
<Text>
<eid>F_F</eid>
<style>title</style>
<text>Note dynamics attribute</text>
</Text>
</VBox>
<Measure>
<eid>G_G</eid>
<voice>
<Clef>
<concertClefType>G</concertClefType>
<transposingClefType>G</transposingClefType>
<isHeader>1</isHeader>
<eid>H_H</eid>
</Clef>
<TimeSig>
<eid>I_I</eid>
<sigN>5</sigN>
<sigD>4</sigD>
</TimeSig>
<Chord>
<eid>J_J</eid>
<durationType>quarter</durationType>
<Note>
<eid>K_K</eid>
<pitch>60</pitch>
<tpc>14</tpc>
</Note>
</Chord>
<Chord>
<eid>L_L</eid>
<durationType>quarter</durationType>
<Note>
<eid>M_M</eid>
<pitch>62</pitch>
<tpc>16</tpc>
<head>cross</head>
<velocity>1</velocity>
</Note>
</Chord>
<Chord>
<eid>N_N</eid>
<durationType>quarter</durationType>
<Note>
<eid>O_O</eid>
<pitch>64</pitch>
<tpc>18</tpc>
<velocity>45</velocity>
</Note>
</Chord>
<Chord>
<eid>P_P</eid>
<durationType>quarter</durationType>
<Note>
<eid>Q_Q</eid>
<pitch>65</pitch>
<tpc>13</tpc>
<velocity>127</velocity>
</Note>
</Chord>
<Chord>
<eid>R_R</eid>
<durationType>quarter</durationType>
<Note>
<eid>S_S</eid>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
</Chord>
<BarLine>
<eid>T_T</eid>
</BarLine>
</voice>
</Measure>
</Staff>
</Score>
</museScore>
3 changes: 3 additions & 0 deletions src/importexport/musicxml/tests/musicxml_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,9 @@ TEST_F(MusicXml_Tests, noteAttributes3) {
TEST_F(MusicXml_Tests, noteColor) {
musicXmlIoTest("testNoteColor");
}
TEST_F(MusicXml_Tests, noteDynamics) {
musicXmlImportTestRef("testNoteDynamics");
}
TEST_F(MusicXml_Tests, noteheadNames) {
musicXmlIoTest("testNoteheadNames");
}
Expand Down
Loading