1313/* exported saveMxmlOutput */
1414
1515saveMxmlOutput = ( logo ) => {
16- // temporary until I get more things sorted out
1716 const ignore = [ "voice two" , "voice one" , "one voice" ] ;
1817 let res = "" ;
1918 let indent = 0 ;
2019
2120 const add = ( str ) => {
22- for ( let i = 0 ; i < indent ; i ++ ) {
23- res += " " ;
24- }
25- res += str + "\n" ;
21+ res += " " . repeat ( indent ) + str + "\n" ;
22+ } ;
23+
24+ const addDirection = ( type ) => {
25+ add ( '<direction placement="above">' ) ;
26+ indent ++ ;
27+ add ( "<direction-type>" ) ;
28+ indent ++ ;
29+ add ( `<wedge type="${ type } "/>` ) ;
30+ indent -- ;
31+ add ( "</direction-type>" ) ;
32+ indent -- ;
33+ add ( "</direction>" ) ;
34+ } ;
35+
36+ const addMeasureAttributes = ( measure , div , beats , beatType ) => {
37+ add ( `<measure number="${ measure } "> <attributes> <divisions>${ div } </divisions> <key> <fifths>0</fifths> </key> <time> <beats>${ beats } </beats> <beat-type>${ beatType } </beat-type> </time> <clef> <sign>G</sign> <line>2</line> </clef> </attributes>` ) ;
2638 } ;
2739
2840 add ( "<?xml version='1.0' encoding='UTF-8'?>" ) ;
29- add (
30- '<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">'
31- ) ;
41+ add ( '<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">' ) ;
3242 add ( '<score-partwise version="3.1">' ) ;
3343 indent ++ ;
3444 add ( "<part-list>" ) ;
3545 indent ++ ;
3646
37- // Why is logo.notation.notationStaging an object and not an array?
3847 Object . keys ( logo . notation . notationStaging ) . forEach ( ( voice ) => {
39- if ( logo . notation . notationStaging [ voice ] . length === 0 ) {
40- return ;
41- }
48+ if ( logo . notation . notationStaging [ voice ] . length === 0 ) return ;
4249 voiceNum = parseInt ( voice ) + 1 ;
43- add ( ' <score-part id="P' + voiceNum + '">' ) ;
50+ add ( ` <score-part id="P${ voiceNum } ">` ) ;
4451 indent ++ ;
45- add ( " <part-name> Voice #" + voiceNum + " </part-name>" ) ;
52+ add ( ` <part-name> Voice #${ voiceNum } </part-name>` ) ;
4653 indent -- ;
4754 add ( "</score-part>" ) ;
4855 } ) ;
@@ -51,71 +58,35 @@ saveMxmlOutput = (logo) => {
5158 indent -- ;
5259
5360 Object . keys ( logo . notation . notationStaging ) . forEach ( ( voice ) => {
54- if ( logo . notation . notationStaging [ voice ] . length === 0 ) {
55- return ;
56- }
61+ if ( logo . notation . notationStaging [ voice ] . length === 0 ) return ;
5762 voiceNum = parseInt ( voice ) + 1 ;
5863 indent ++ ;
59- add ( ' <part id="P' + voiceNum + '">' ) ;
64+ add ( ` <part id="P${ voiceNum } ">` ) ;
6065 indent ++ ;
6166
62- // assume 4/4 time, 32 divisions bc smallest note is 1/32
63- // key is C by default
64- let currMeasure = 1 ;
65- let divisions = 32 ;
66- let beats = 4 ;
67- let beatType = 4 ;
68- let beatsChanged = false ;
69- let newDivisions = - 1 ;
70- let newBeats = - 1 ;
71- let newBeatType = - 1 ;
72- let openedMeasureTag = false ;
73- let queuedTempo = null ;
74- let firstMeasure = true ;
67+ let currMeasure = 1 , divisions = 32 , beats = 4 , beatType = 4 ;
68+ let beatsChanged = false , newDivisions = - 1 , newBeats = - 1 , newBeatType = - 1 ;
69+ let openedMeasureTag = false , queuedTempo = null , firstMeasure = true ;
7570 indent ++ ;
7671 let divisionsLeft = divisions ;
7772 const notes = logo . notation . notationStaging [ voice ] ;
7873
79- for ( let i = 0 ; i < notes . length ; i += 1 ) {
80- // obj = [note, duration, dotCount, tupletValue, roundDown, insideChord, staccato]
74+ for ( let i = 0 ; i < notes . length ; i ++ ) {
8175 const obj = notes [ i ] ;
82- if ( [ "tie" , "begin slur" , "end slur" ] . includes ( obj ) ) {
83- continue ;
84- }
76+ if ( [ "tie" , "begin slur" , "end slur" ] . includes ( obj ) || ignore . includes ( obj ) ) continue ;
8577
86- if ( ignore . includes ( obj ) ) {
87- continue ;
88- }
89-
90- // ignore key
9178 if ( obj === "key" ) {
9279 i += 2 ;
9380 continue ;
9481 }
9582
9683 if ( obj === "begin crescendo" ) {
97- add ( '<direction placement="above">' ) ;
98- indent ++ ;
99- add ( "<direction-type>" ) ;
100- indent ++ ;
101- add ( '<wedge type="crescendo"/>' ) ;
102- indent -- ;
103- add ( "</direction-type>" ) ;
104- indent -- ;
105- add ( "</direction>" ) ;
84+ addDirection ( "crescendo" ) ;
10685 continue ;
10786 }
10887
10988 if ( obj === "begin decrescendo" ) {
110- add ( '<direction placement="above">' ) ;
111- indent ++ ;
112- add ( "<direction-type>" ) ;
113- indent ++ ;
114- add ( '<wedge type="diminuendo"/>' ) ;
115- indent -- ;
116- add ( "</direction-type>" ) ;
117- indent -- ;
118- add ( "</direction>" ) ;
89+ addDirection ( "diminuendo" ) ;
11990 continue ;
12091 }
12192
@@ -136,11 +107,10 @@ saveMxmlOutput = (logo) => {
136107 const bpm = notes [ i + 1 ] ;
137108 const beatMeasure = notes [ i + 2 ] ;
138109 const bpmAdjusted = Math . floor ( bpm * ( 4 / beatMeasure ) ) ;
139-
140110 if ( openedMeasureTag ) {
141- add ( ' <sound tempo="' + bpmAdjusted + ' "/>' ) ;
111+ add ( ` <sound tempo="${ bpmAdjusted } "/>` ) ;
142112 } else {
143- queuedTempo = ' <sound tempo="' + bpmAdjusted + ' "/>' ;
113+ queuedTempo = ` <sound tempo="${ bpmAdjusted } "/>` ;
144114 }
145115 i += 2 ;
146116 continue ;
@@ -149,23 +119,19 @@ saveMxmlOutput = (logo) => {
149119 if ( obj === "meter" ) {
150120 newBeats = notes [ i + 1 ] ;
151121 newBeatType = notes [ i + 2 ] ;
152-
153- // divisions per beat == how many 1/32 notes fit in one beat?
154122 newDivisions = newBeats * ( 1 / newBeatType / ( 1 / 32 ) ) ;
155123 i += 2 ;
156124 beatsChanged = true ;
157125 continue ;
158126 }
159127
160- // We only add </chord> tag to the non-first elements in a chord
161128 let isChordNote = false ;
162129 for ( const p of obj [ 0 ] ) {
163130 let dur = 32 / obj [ 1 ] ;
164131 for ( let j = 0 ; j < obj [ 2 ] ; j ++ ) dur += dur / 2 ;
165132
166133 if ( divisionsLeft < dur && ! isChordNote ) {
167134 if ( openedMeasureTag ) {
168- // throw "big chungus";
169135 add ( "</measure>" ) ;
170136 currMeasure ++ ;
171137 divisionsLeft = divisions ;
@@ -176,37 +142,17 @@ saveMxmlOutput = (logo) => {
176142 if ( ! isChordNote ) {
177143 if ( divisionsLeft === divisions ) {
178144 if ( firstMeasure ) {
179- add (
180- '<measure number="' +
181- currMeasure +
182- '"> <attributes> <divisions>' +
183- divisions +
184- "</divisions> <key> <fifths>0</fifths> </key> <time> <beats>" +
185- beats +
186- "</beats> <beat-type>" +
187- beatType +
188- "</beat-type> </time> <clef> <sign>G</sign> <line>2</line> </clef> </attributes>"
189- ) ;
145+ addMeasureAttributes ( currMeasure , divisions , beats , beatType ) ;
190146 firstMeasure = false ;
191147 } else if ( beatsChanged ) {
192148 beats = newBeats ;
193149 beatType = newBeatType ;
194150 divisions = newDivisions ;
195151 divisionsLeft = divisions ;
196- add (
197- '<measure number="' +
198- currMeasure +
199- '"> <attributes> <divisions>' +
200- newDivisions +
201- "</divisions> <key> <fifths>0</fifths> </key> <time> <beats>" +
202- newBeats +
203- "</beats> <beat-type>" +
204- newBeatType +
205- "</beat-type> </time> <clef> <sign>G</sign> <line>2</line> </clef> </attributes>"
206- ) ;
152+ addMeasureAttributes ( currMeasure , newDivisions , newBeats , newBeatType ) ;
207153 beatsChanged = false ;
208154 } else {
209- add ( ' <measure number="' + currMeasure + '">' ) ;
155+ add ( ` <measure number="${ currMeasure } ">` ) ;
210156 }
211157 openedMeasureTag = true ;
212158 if ( queuedTempo !== null ) {
@@ -217,15 +163,7 @@ saveMxmlOutput = (logo) => {
217163 divisionsLeft -= dur ;
218164 }
219165
220- let alter ;
221-
222- if ( p [ 1 ] === "\u266d" ) {
223- alter = - 1 ; // flat
224- } else if ( p [ 1 ] === "\u266F" ) {
225- alter = 1 ; // sharp
226- } else {
227- alter = 0 ; // no accidental
228- }
166+ let alter = p [ 1 ] === "\u266d" ? - 1 : p [ 1 ] === "\u266F" ? 1 : 0 ;
229167
230168 add ( "<note>" ) ;
231169 indent ++ ;
@@ -236,16 +174,14 @@ saveMxmlOutput = (logo) => {
236174 } else {
237175 add ( "<pitch>" ) ;
238176 indent ++ ;
239- add ( "<step>" + p [ 0 ] + "</step>" ) ;
240- if ( alter != 0 ) {
241- add ( "<alter>" + alter + "</alter>" ) ;
242- }
243- add ( "<octave>" + p [ p . length - 1 ] + "</octave>" ) ;
177+ add ( `<step>${ p [ 0 ] } </step>` ) ;
178+ if ( alter !== 0 ) add ( `<alter>${ alter } </alter>` ) ;
179+ add ( `<octave>${ p [ p . length - 1 ] } </octave>` ) ;
244180 indent -- ;
245181 add ( "</pitch>" ) ;
246182 }
247183
248- add ( " <duration>" + dur + " </duration>" ) ;
184+ add ( ` <duration>${ dur } </duration>` ) ;
249185 if ( notes [ i + 1 ] === "tie" ) {
250186 add ( '<tie type="start"/>' ) ;
251187 } else if ( notes [ i - 1 ] === "tie" ) {
@@ -257,9 +193,7 @@ saveMxmlOutput = (logo) => {
257193 indent ++ ;
258194 add ( "<articulations>" ) ;
259195 indent ++ ;
260- if ( obj [ 6 ] ) {
261- add ( '<staccato placement="below"/>' ) ;
262- }
196+ if ( obj [ 6 ] ) add ( '<staccato placement="below"/>' ) ;
263197 indent -- ;
264198 add ( "</articulations>" ) ;
265199 indent -- ;
@@ -296,7 +230,6 @@ saveMxmlOutput = (logo) => {
296230 } ) ;
297231 add ( "</score-partwise>" ) ;
298232
299- // Filter voices
300233 let mi = 1e5 ;
301234 for ( let i = 0 ; i < res . length - 1 ; i ++ ) {
302235 if ( ( res [ i ] === "P" || res [ i ] === "#" ) && "123456789" . includes ( res [ i + 1 ] ) ) {
0 commit comments