1 /*
2 MusicXML Library
3 Copyright (C) Grame 2006-2013
4
5 This Source Code Form is subject to the terms of the Mozilla Public
6 License, v. 2.0. If a copy of the MPL was not distributed with this
7 file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
9 Grame Research Laboratory, 11, cours de Verdun Gensoul 69002 Lyon - France
10 research@grame.fr
11 */
12
13 #include <iostream>
14 #include <sstream>
15
16 #include <climits> // INT_MIN, INT_MAX
17
18 #include "utilities.h"
19
20 #include "msrBasicTypes.h"
21 #include "lpsrBasicTypes.h"
22
23 #include "setTraceOahIfDesired.h"
24 #ifdef TRACE_OAH
25 #include "traceOah.h"
26 #endif
27
28 #include "generalOah.h"
29 #include "lpsrOah.h"
30
31 #include "messagesHandling.h"
32
33
34 using namespace std;
35
36 namespace MusicXML2
37 {
38
39 //_______________________________________________________________________________
lpsrDurationBinaryLogarithm(int duration)40 int lpsrDurationBinaryLogarithm (int duration)
41 {
42 int result = INT_MIN;
43
44 /*
45 with LilyPond's limitation to 128th of a whole note,
46 valid denominators binary logarithms, i.e. their exponent, are:
47 */
48
49 switch (duration) {
50 case 1:
51 result = 0;
52 break;
53 case 2:
54 result = 1;
55 break;
56 case 4:
57 result = 2;
58 break;
59 case 8:
60 result = 3;
61 break;
62 case 16:
63 result = 4;
64 break;
65 case 32:
66 result = 5;
67 break;
68 case 64:
69 result = 6;
70 break;
71 case 128:
72 result = 7;
73 break;
74 case 256: // JMI
75 result = 8;
76 break;
77
78 default:
79 ;
80 } // switch
81
82 return result;
83 }
84
85 //_______________________________________________________________________________
lpsrNumberOfDots(int n)86 int lpsrNumberOfDots (int n)
87 {
88 int result = INT_MIN;
89
90 switch (n) {
91 case 1:
92 result = 0;
93 break;
94 case 3:
95 result = 1;
96 break;
97 case 7:
98 result = 2;
99 break;
100 case 15:
101 result = 3;
102 break;
103 case 31:
104 result = 4;
105 break;
106 case 63:
107 result = 5;
108 break;
109 case 127:
110 result = 6;
111 break;
112
113 default:
114 ;
115 } // switch
116
117 return result;
118 }
119
120 //_______________________________________________________________________________
wholeNotesAsLilypondString(int inputLineNumber,rational wholeNotes,int & dotsNumber)121 string wholeNotesAsLilypondString (
122 int inputLineNumber,
123 rational wholeNotes,
124 int& dotsNumber)
125 {
126 // this algorithm is inspired by musicxml2ly
127
128 #ifdef TRACE_OAH
129 if (gTraceOah->fTraceWholeNotes) {
130 gLogOstream <<
131 "--> wholeNotesAsLilypondString() 1 -------------------------------------" <<
132 ", wholeNotes: " << wholeNotes <<
133 ", line " << inputLineNumber <<
134 endl;
135 }
136 #endif
137
138 int
139 numerator = wholeNotes.getNumerator (),
140 denominator = wholeNotes.getDenominator ();
141
142 #ifdef TRACE_OAH
143 if (gTraceOah->fTraceWholeNotes) {
144 gLogOstream <<
145 "--> numerator: " << numerator <<
146 endl <<
147 "--> denominator: " << denominator <<
148 endl <<
149 endl;
150 }
151 #endif
152
153 /* JMI
154 if (false && numerator <= 0) { // JMI
155 stringstream s;
156
157 s <<
158 "%{ZERO_LENGTH: " <<
159 wholeNotes << // JMI
160 ", line " <<
161 inputLineNumber <<
162 " %}";
163
164 return s.str ();
165 }
166 */
167
168 // sanity check
169 if (numerator <= 0) {
170 stringstream s;
171
172 s <<
173 "numerator is not positive in wholeNotesAsLilypondString()" <<
174 ", wholeNotes = " << wholeNotes;
175
176 // msrMusicXMLError ( JMI
177 msrMusicXMLWarning (
178 gOahOah->fInputSourceName,
179 inputLineNumber,
180 // __FILE__, __LINE__,
181 s.str ());
182 abort (); // JMI
183 return "???";
184 }
185
186 wholeNotes.rationalise ();
187
188 #ifdef TRACE_OAH
189 if (gTraceOah->fTraceWholeNotesDetails) {
190 gLogOstream <<
191 "--> wholeNotes rationalised: " << wholeNotes <<
192 endl;
193 }
194 #endif
195
196 bool
197 rationalHasBeenSimplified =
198 wholeNotes.getNumerator () != numerator; // denominators could be used too
199
200 if (rationalHasBeenSimplified) {
201 numerator = wholeNotes.getNumerator (),
202 denominator = wholeNotes.getDenominator ();
203 }
204
205 bool
206 integralNumberOfWholeNotes = denominator == 1;
207
208 #ifdef TRACE_OAH
209 if (gTraceOah->fTraceWholeNotesDetails) {
210 gLogOstream <<
211 "--> rationalHasBeenSimplified: " <<
212 booleanAsString (
213 rationalHasBeenSimplified) <<
214 endl <<
215 "--> integralNumberOfWholeNotes: " <<
216 booleanAsString (
217 integralNumberOfWholeNotes) <<
218 endl <<
219 endl;
220 }
221 #endif
222
223 /*
224 augmentation dots add half the preceding increment to the duration:
225 they constitue a series of frations or the form '(2^n-1) / 2^n',
226 starting with 3/2, 7/4, 15/8,
227 that tends towards 2 while always remaining less than two.
228
229 with MusicXML's limitation to 1024th of a whole note,
230 with LilyPond's limitation to 128th of a whole note,
231 valid numerators are:
232 */
233
234 int numeratorDots = lpsrNumberOfDots (numerator);
235
236 #ifdef TRACE_OAH
237 if (gTraceOah->fTraceWholeNotesDetails) {
238 gLogOstream <<
239 "--> numeratorDots " << " : " << numeratorDots <<
240 endl <<
241 endl;
242 }
243 #endif
244
245 /*
246 default:
247 if (! integralNumberOfWholeNotes) {
248 // multiplyingFactorIsToBeUsed = true;
249 }
250 else {
251 // there can be integral numbers of whole notes up to 15,
252 // corresponding to a \maxima...
253 stringstream s;
254
255 s <<
256 "numerator " << numerator <<
257 " is not one of 1, 3, 7, 15, 31, 63 or 127" <<
258 // " is not one of 1, 3, 7, 15, 31, 63, 127, 255, 511 or 1023" <<
259 ", whole notes duration " <<
260 numerator << "/" << denominator;
261
262 if (rationalHasBeenSimplified) {
263 s <<
264 " (" << numerator << "/" << denominator << ")" <<
265 endl;
266 }
267
268 s <<
269 " it will be represented using a multiplying factor";
270
271 msrMusicXMLWarning (
272 gOahOah->fInputSourceName,
273 inputLineNumber,
274 s.str ());
275
276 // multiplyingFactorIsToBeUsed = true;
277 }
278 } // switch
279 */
280
281 /*
282 valid denominators are powers of 2
283
284 the rational representing a dotted duration has to be brought
285 to a value less than two, as explained above
286
287 this is done by changing it denominator in the resulting string:
288
289 whole notes string
290 3/1 \breve.
291 3/2 1.
292 3/4 2.
293 3/8 4.
294
295 7/1 \longa..
296 7/2 \breve..
297 7/4 1..
298 7/8 2..
299
300 since such resulting denominators can be fractions of wholes notes
301 as well as multiple thereof,
302 we'll be better of using binary logarithms for the computations
303 */
304
305 int denominatorDurationLog =
306 lpsrDurationBinaryLogarithm (denominator);
307
308 if (denominatorDurationLog == INT_MIN) {
309 string result;
310
311 {
312 stringstream s;
313
314 s <<
315 1 <<
316 "*" <<
317 numerator <<
318 "/" <<
319 denominator;
320
321 result = s.str ();
322 }
323
324 #ifdef TRACE_OAH
325 if (gTraceOah->fTraceWholeNotesDetails) {
326 stringstream s;
327
328 s <<
329 "denominator " << denominator <<
330 " is no power of two between 1 and 128" <<
331 // " is no power of 2 between 1 and 1024" <<
332 ", whole notes duration " <<
333 numerator << "/" << denominator;
334
335 if (rationalHasBeenSimplified) {
336 s <<
337 " (" << numerator << "/" << denominator << ")" <<
338 endl;
339 }
340
341 s <<
342 " cannot be represented as a dotted power of 2" <<
343 ", " <<
344 result <<
345 " will be used";
346
347 // msrMusicXMLError ( JMI
348 msrMusicXMLWarning (
349 gOahOah->fInputSourceName,
350 inputLineNumber,
351 // __FILE__, __LINE__,
352 s.str ());
353 }
354 #endif
355
356 return result;
357 }
358
359 #ifdef TRACE_OAH
360 if (gTraceOah->fTraceWholeNotesDetails) {
361 gLogOstream <<
362 "--> denominatorDurationLog" << " : " <<
363 denominatorDurationLog <<
364 endl <<
365 endl;
366 }
367 #endif
368
369 // bring the resulting fraction to be less that two if needed
370 if (integralNumberOfWholeNotes) {
371 // adapt the duration to avoid even numerators if can be,
372 // since dotted durations cannot be recognized otherwise
373 // 6/1 thus becomes 3\breve, hence \longa.
374 #ifdef TRACE_OAH
375 if (gTraceOah->fTraceWholeNotesDetails) {
376 gLogOstream <<
377 "--> integralNumberOfWholeNotes,"
378 " bringing the faction to be less that 2" <<
379 endl;
380 }
381 #endif
382
383 while (numerator % 2 == 0) {
384 numerator /= 2;
385 denominatorDurationLog -= 1;
386
387 #ifdef TRACE_OAH
388 if (gTraceOah->fTraceWholeNotesDetails) {
389 gLogOstream <<
390 "--> numerator" << " : " <<
391 numerator <<
392 endl <<
393 "--> denominatorDurationLog " << " : " <<
394 denominatorDurationLog <<
395 endl <<
396 endl;
397 }
398 #endif
399 } // while
400
401 // update the number of dots
402 numeratorDots = lpsrNumberOfDots (numerator);
403 }
404
405 #ifdef TRACE_OAH
406 if (gTraceOah->fTraceWholeNotesDetails) {
407 gLogOstream <<
408 "--> numerator" << " : " <<
409 numerator <<
410 endl <<
411 "--> denominatorDurationLog" << " : " <<
412 denominatorDurationLog <<
413 endl <<
414 "--> numeratorDots " << " : " <<
415 numeratorDots <<
416 endl <<
417 endl;
418 }
419 #endif
420
421 // take care of the dots
422 int multiplyingFactor = 1;
423
424 if (numeratorDots >= 0 && denominatorDurationLog >= numeratorDots) {
425 // take the dots into account
426 denominatorDurationLog -= numeratorDots;
427
428 #ifdef TRACE_OAH
429 if (gTraceOah->fTraceWholeNotesDetails) {
430 gLogOstream <<
431 "--> denominatorDurationLog" << " : " <<
432 denominatorDurationLog <<
433 endl <<
434 "--> multiplyingFactor " << " : " <<
435 multiplyingFactor <<
436 endl <<
437 endl;
438 }
439 #endif
440 }
441 else {
442 // set the multiplying factor
443 #ifdef TRACE_OAH
444 if (gTraceOah->fTraceWholeNotesDetails) {
445 gLogOstream <<
446 "--> setting the multiplying factor" <<
447 endl;
448 }
449 #endif
450
451 // 5/8 becomes 8*5
452
453 multiplyingFactor = numerator;
454 numerator = 1;
455
456 /* JMI
457 multiplyingFactor = numerator;
458
459 #ifdef TRACE_OAH
460 if (gTraceOah->fTraceWholeNotesDetails) {
461 gLogOstream <<
462 "--> denominatorDurationLog" << " : " <<
463 denominatorDurationLog <<
464 endl <<
465 "--> multiplyingFactor " << " : " <<
466 multiplyingFactor <<
467 endl <<
468 endl;
469 }
470 #endif
471
472 while (multiplyingFactor >= 2) {
473 // double duration
474 denominatorDurationLog--;
475
476 // adapt multiplying factor
477 multiplyingFactor /= 2;
478
479 #ifdef TRACE_OAH
480 if (gTraceOah->fTraceWholeNotesDetails) {
481 gLogOstream <<
482 "--> denominatorDurationLog" << " : " <<
483 denominatorDurationLog <<
484 endl <<
485 "--> multiplyingFactor " << " : " <<
486 multiplyingFactor <<
487 endl <<
488 endl;
489 }
490 #endif
491 } // while
492 */
493 }
494
495 #ifdef TRACE_OAH
496 if (gTraceOah->fTraceWholeNotesDetails) {
497 gLogOstream <<
498 "--> numerator " << " : " <<
499 numerator <<
500 endl <<
501 "--> numeratorDots " << " : " <<
502 numeratorDots <<
503 endl <<
504 "--> denominatorDurationLog" << " : " <<
505 denominatorDurationLog <<
506 endl <<
507 "--> multiplyingFactor " << " : " <<
508 multiplyingFactor <<
509 endl <<
510 endl;
511 }
512 #endif
513
514 // generate the code for the duration
515 stringstream s;
516
517 switch (denominatorDurationLog) {
518 case -3:
519 s << "\\maxima";
520 break;
521 case -2:
522 s << "\\longa";
523 break;
524 case -1:
525 s << "\\breve";
526 break;
527
528 default:
529 s << (1 << denominatorDurationLog);
530 } // switch
531
532 // append the dots if any
533 if (numeratorDots > 0) {
534 for (int i = 0; i < numeratorDots; i++) {
535 s << ".";
536 } // for
537 }
538
539 if (multiplyingFactor != 1) {
540 // append the multiplying factor
541 s <<
542 "*" << multiplyingFactor;
543
544 /* JMI
545 if (integralNumberOfWholeNotes) {
546 s <<
547 "*" << multiplyingFactor;
548 }
549 else {
550 s <<
551 "*" << multiplyingFactor << "/" << 1; // ??? denominator;
552 }
553 */
554 }
555
556 string result = s.str ();
557
558 #ifdef TRACE_OAH
559 if (gTraceOah->fTraceWholeNotes) {
560 gLogOstream <<
561 "--> wholeNotesAsLilypondString() 2 -------------------------------------" <<
562 ", result: \"" << result << "\"" <<
563 ", numeratorDots" << " : " << numeratorDots <<
564 endl;
565 }
566 #endif
567
568 // return the result
569 dotsNumber = numeratorDots;
570
571 return result;
572 }
573
wholeNotesAsLilypondString(int inputLineNumber,rational wholeNotes)574 string wholeNotesAsLilypondString (
575 int inputLineNumber,
576 rational wholeNotes)
577 {
578 int dotsNumber; // not used
579
580 return
581 wholeNotesAsLilypondString (
582 inputLineNumber,
583 wholeNotes,
584 dotsNumber);
585 }
586
587 //_______________________________________________________________________________
dottedDurationAsLilypondString(int inputLineNumber,msrDottedDuration dottedDuration)588 string dottedDurationAsLilypondString (
589 int inputLineNumber,
590 msrDottedDuration dottedDuration)
591 {
592 return
593 wholeNotesAsLilypondString (
594 inputLineNumber,
595 dottedDuration.dottedDurationAsWholeNotes (
596 inputLineNumber));
597 }
598
dottedDurationAsLilypondStringWithoutBackSlash(int inputLineNumber,msrDottedDuration dottedDuration)599 string dottedDurationAsLilypondStringWithoutBackSlash (
600 int inputLineNumber,
601 msrDottedDuration dottedDuration)
602 {
603 string result =
604 wholeNotesAsLilypondString (
605 inputLineNumber,
606 dottedDuration.dottedDurationAsWholeNotes (
607 inputLineNumber));
608
609 if (result [0] == '\\') {
610 result = result.substr (1);
611 }
612
613 return result;
614 }
615
616 //_______________________________________________________________________________
restMeasuresWholeNoteAsLilypondString(int inputLineNumber,rational wholeNotes)617 string restMeasuresWholeNoteAsLilypondString (
618 int inputLineNumber,
619 rational wholeNotes)
620 {
621 stringstream s;
622
623 rational
624 denominatorAsFraction =
625 rational (
626 1,
627 wholeNotes.getDenominator ());
628
629 int numberOfWholeNotes =
630 wholeNotes.getNumerator ();
631
632 s <<
633 wholeNotesAsLilypondString (
634 inputLineNumber,
635 denominatorAsFraction);
636
637 if (numberOfWholeNotes != 1) {
638 s <<
639 "*" << numberOfWholeNotes;
640 }
641
642 return s.str ();
643 }
644
645 //_______________________________________________________________________________
writeTextsListAsLilypondString(const list<string> & textsList,ostream & os)646 void writeTextsListAsLilypondString (
647 const list<string>& textsList,
648 ostream& os)
649 {
650 string contents;
651
652 if (textsList.size ()) {
653 list<string>::const_iterator
654 iBegin = textsList.begin (),
655 iEnd = textsList.end (),
656 i = iBegin;
657
658 for ( ; ; ) {
659 contents += (*i);
660 if (++i == iEnd) break;
661 // JMI os << ", ";
662 } // for
663 }
664
665 size_t found = contents.find("\"");
666 if (found != std::string::npos) {
667 os << doubleQuoteString (contents);
668 }
669 else {
670 os << doubleQuoteStringIfNonAlpha (contents); // JMI
671 }
672 }
673
674 // score output kinds
675 //______________________________________________________________________________
676
677 map<string, lpsrScoreOutputKind>
678 gLpsrScoreOutputKindsMap;
679
lpsrScoreOutputKindAsString(lpsrScoreOutputKind scoreOutputKind)680 string lpsrScoreOutputKindAsString (
681 lpsrScoreOutputKind scoreOutputKind)
682 {
683 string result;
684
685 // no CamelCase here, these strings are used in the command line options
686
687 switch (scoreOutputKind) {
688 case kScoreOnly: // default value
689 result = "score-only";
690 break;
691 case kScoreAndParts:
692 result = "score-and-parts";
693 break;
694 case kPartsAndScore:
695 result = "parts-and-score";
696 break;
697 case kPartsOnly:
698 result = "parts-only";
699 break;
700 case kScoreAndPartsOneFile:
701 result = "score-and-parts-one-file";
702 break;
703 case kPartsAndScoreOneFile:
704 result = "parts-and-score-one-file";
705 break;
706 case kPartsOnlyOneFile:
707 result = "parts-only-one-file";
708 break;
709 } // switch
710
711 return result;
712 }
713
initializeLpsrScoreOutputKindsMap()714 void initializeLpsrScoreOutputKindsMap ()
715 {
716 // register the LilyPond score output kinds
717 // --------------------------------------
718
719 // no CamelCase here, these strings are used in the command line options
720
721 gLpsrScoreOutputKindsMap ["score-only"] = kScoreOnly;
722 gLpsrScoreOutputKindsMap ["score-and-parts"] = kScoreAndParts;
723 gLpsrScoreOutputKindsMap ["parts-and-score"] = kPartsAndScore;
724 gLpsrScoreOutputKindsMap ["parts-only"] = kPartsOnly;
725 gLpsrScoreOutputKindsMap ["score-and-parts-one-file"] = kScoreAndPartsOneFile;
726 gLpsrScoreOutputKindsMap ["parts-and-score-one-file"] = kPartsAndScoreOneFile;
727 gLpsrScoreOutputKindsMap ["parts-only-one-file"] = kPartsOnlyOneFile;
728 }
729
existingLpsrScoreOutputKinds(int namesListMaxLength)730 string existingLpsrScoreOutputKinds (int namesListMaxLength)
731 {
732 stringstream s;
733
734 if (gLpsrScoreOutputKindsMap.size ()) {
735 map<string, lpsrScoreOutputKind>::const_iterator
736 iBegin = gLpsrScoreOutputKindsMap.begin (),
737 iEnd = gLpsrScoreOutputKindsMap.end (),
738 i = iBegin;
739
740 int cumulatedLength = 0;
741
742 for ( ; ; ) {
743 string theString = (*i).first;
744
745 s << theString;
746
747 cumulatedLength += theString.size ();
748 if (cumulatedLength >= K_NAMES_LIST_MAX_LENGTH) break;
749
750 if (++i == iEnd) break;
751
752 if (next (i) == iEnd) {
753 s << " and ";
754 }
755 else {
756 s << ", ";
757 }
758 } // for
759
760 /* JMI BUG IN MAP ITERATORS...???
761 {
762 list<string> lpsrScoreOutputKindsList;
763 for (
764 map<string, lpsrScoreOutputKind>::const_iterator i = gLpsrScoreOutputKindsMap.begin ();
765 i != gLpsrScoreOutputKindsMap.end ();
766 ++i
767 ) {
768 lpsrScoreOutputKindsList.push_back ((*i).first);
769 } // for
770
771 list<string>::const_iterator
772 iBegin = lpsrScoreOutputKindsList.begin (),
773 iEnd = lpsrScoreOutputKindsList.end (),
774 i = iBegin;
775
776 int cumulatedLength = 0;
777
778 for ( ; ; ) {
779 string theString = (*i);
780
781 s << theString;
782
783 cumulatedLength += theString.size ();
784 if (cumulatedLength >= K_NAMES_LIST_MAX_LENGTH) break;
785
786 if (++i == iEnd) break;
787 if (next (i) == iEnd) {
788 s << " and ";
789 }
790 else {
791 s << ", ";
792 }
793 } // for
794 }
795 */
796 }
797
798 return s.str ();
799 }
800
801 // octave entry kinds
802 //______________________________________________________________________________
803
804 map<string, lpsrOctaveEntryKind>
805 gLpsrOctaveEntryKindsMap;
806
lpsrOctaveEntryKindAsString(lpsrOctaveEntryKind octaveEntryKind)807 string lpsrOctaveEntryKindAsString (
808 lpsrOctaveEntryKind octaveEntryKind)
809 {
810 string result;
811
812 // no CamelCase here, these strings are used in the command line options
813
814 switch (octaveEntryKind) {
815 case kOctaveEntryRelative: // default value
816 result = "relative";
817 break;
818 case kOctaveEntryAbsolute:
819 result = "absolute";
820 break;
821 case kOctaveEntryFixed:
822 result = "fixed";
823 break;
824 } // switch
825
826 return result;
827 }
828
initializeLpsrOctaveEntryKindsMap()829 void initializeLpsrOctaveEntryKindsMap ()
830 {
831 // register the LilyPond score output kinds
832 // --------------------------------------
833
834 // no CamelCase here, these strings are used in the command line options
835
836 gLpsrOctaveEntryKindsMap ["relative"] = kOctaveEntryRelative;
837 gLpsrOctaveEntryKindsMap ["absolute"] = kOctaveEntryAbsolute;
838 gLpsrOctaveEntryKindsMap ["fixed"] = kOctaveEntryFixed;
839 }
840
existingLpsrOctaveEntryKinds(int namesListMaxLength)841 string existingLpsrOctaveEntryKinds (int namesListMaxLength)
842 {
843 stringstream s;
844
845 if (gLpsrOctaveEntryKindsMap.size ()) {
846 map<string, lpsrOctaveEntryKind>::const_iterator
847 iBegin = gLpsrOctaveEntryKindsMap.begin (),
848 iEnd = gLpsrOctaveEntryKindsMap.end (),
849 i = iBegin;
850
851 int cumulatedLength = 0;
852
853 for ( ; ; ) {
854 string theString = (*i).first;
855
856 s << theString;
857
858 cumulatedLength += theString.size ();
859 if (cumulatedLength >= K_NAMES_LIST_MAX_LENGTH) break;
860
861 if (++i == iEnd) break;
862 if (next (i) == iEnd) {
863 s << " and ";
864 }
865 else {
866 s << ", ";
867 }
868 } // for
869 }
870
871 return s.str ();
872 }
873
874 // accidental styles
875 //______________________________________________________________________________
876
877 map<string, lpsrAccidentalStyleKind>
878 gLpsrAccidentalStyleKindsMap;
879
lpsrAccidentalStyleKindAsString(lpsrAccidentalStyleKind accidentalStyleKind)880 string lpsrAccidentalStyleKindAsString (
881 lpsrAccidentalStyleKind accidentalStyleKind)
882 {
883 string result;
884
885 switch (accidentalStyleKind) {
886 case kDefault: // default value
887 result = "default";
888 break;
889 case kVoice:
890 result = "voice";
891 break;
892 case kModern:
893 result = "modern";
894 break;
895 case kModernCautionary:
896 result = "modernCautionary";
897 break;
898 case kModernVoice:
899 result = "modernVoice";
900 break;
901 case kModernVoiceCautionary:
902 result = "modernVoiceCautionary";
903 break;
904 case kPiano:
905 result = "piano";
906 break;
907 case kPianoCautionary:
908 result = "pianoCautionary";
909 break;
910 case kNeoModern:
911 result = "neoModern";
912 break;
913 case kNeoModernCautionary:
914 result = "neoModernCautionary";
915 break;
916 case kNeoModernVoice:
917 result = "neoModernVoice";
918 break;
919 case kNeoModernVoiceCautionary:
920 result = "neoModernVoiceCautionary";
921 break;
922 case kDodecaphonic:
923 result = "dodecaphonic";
924 break;
925 case kDodecaphonicNoRepeat:
926 result = "dodecaphonicNoRepeat";
927 break;
928 case kDodecaphonicFirst:
929 result = "dodecaphonicFirst";
930 break;
931 case kTeaching:
932 result = "teaching";
933 break;
934 case kNoReset:
935 result = "noReset";
936 break;
937 case kForget:
938 result = "Forget";
939 break;
940 } // switch
941
942 return result;
943 }
944
lpsrAccidentalStyleKindAsLilypondString(lpsrAccidentalStyleKind accidentalStyleKind)945 string lpsrAccidentalStyleKindAsLilypondString (
946 lpsrAccidentalStyleKind accidentalStyleKind)
947 {
948 string result;
949
950 switch (accidentalStyleKind) {
951 case kDefault: // default value
952 result = "default";
953 break;
954 case kVoice:
955 result = "voice";
956 break;
957 case kModern:
958 result = "modern";
959 break;
960 case kModernCautionary:
961 result = "modern-cautionary";
962 break;
963 case kModernVoice:
964 result = "modern-voice";
965 break;
966 case kModernVoiceCautionary:
967 result = "modern-voice-cautionary";
968 break;
969 case kPiano:
970 result = "piano";
971 break;
972 case kPianoCautionary:
973 result = "piano-cautionary";
974 break;
975 case kNeoModern:
976 result = "neo-modern";
977 break;
978 case kNeoModernCautionary:
979 result = "neo-modern-cautionary";
980 break;
981 case kNeoModernVoice:
982 result = "neo-modern-voice";
983 break;
984 case kNeoModernVoiceCautionary:
985 result = "neo-modern--voice-cautionary";
986 break;
987 case kDodecaphonic:
988 result = "dodecaphonic";
989 break;
990 case kDodecaphonicNoRepeat:
991 result = "dodecaphonic-no-repeat";
992 break;
993 case kDodecaphonicFirst:
994 result = "dodecaphonic-first";
995 break;
996 case kTeaching:
997 result = "teaching";
998 break;
999 case kNoReset:
1000 result = "no-reset";
1001 break;
1002 case kForget:
1003 result = "forget";
1004 break;
1005 } // switch
1006
1007 return result;
1008 }
1009
initializeLpsrAccidentalStyleKindsMap()1010 void initializeLpsrAccidentalStyleKindsMap ()
1011 {
1012 // register the LilyPond accidental styles
1013 // --------------------------------------
1014
1015 gLpsrAccidentalStyleKindsMap ["default"] = kDefault;
1016 gLpsrAccidentalStyleKindsMap ["voice"] = kVoice;
1017 gLpsrAccidentalStyleKindsMap ["modern"] = kModern;
1018 gLpsrAccidentalStyleKindsMap ["modern-cautionary"] = kModernCautionary;
1019 gLpsrAccidentalStyleKindsMap ["modern-voice"] = kModernVoice;
1020 gLpsrAccidentalStyleKindsMap ["modern-voice-cautionary"] = kModernVoiceCautionary;
1021 gLpsrAccidentalStyleKindsMap ["piano"] = kPiano;
1022 gLpsrAccidentalStyleKindsMap ["piano-cautionary"] = kPianoCautionary;
1023 gLpsrAccidentalStyleKindsMap ["neo-modern"] = kNeoModern;
1024 gLpsrAccidentalStyleKindsMap ["neo-modern-cautionary"] = kNeoModernCautionary;
1025 gLpsrAccidentalStyleKindsMap ["neo-modern-voice"] = kNeoModernVoice;
1026 gLpsrAccidentalStyleKindsMap ["neo-modern-voice-cautionary"] = kNeoModernVoiceCautionary;
1027 gLpsrAccidentalStyleKindsMap ["dodecaphonic"] = kDodecaphonic;
1028 gLpsrAccidentalStyleKindsMap ["dodecaphonic-no-repeat"] = kDodecaphonicNoRepeat;
1029 gLpsrAccidentalStyleKindsMap ["dodecaphonic-first"] = kDodecaphonicFirst;
1030 gLpsrAccidentalStyleKindsMap ["teaching"] = kTeaching;
1031 gLpsrAccidentalStyleKindsMap ["no-reset"] = kNoReset;
1032 gLpsrAccidentalStyleKindsMap ["forget"] = kForget;
1033 }
1034
existingLpsrAccidentalStyleKinds(int namesListMaxLength)1035 string existingLpsrAccidentalStyleKinds (int namesListMaxLength)
1036 {
1037 stringstream s;
1038
1039 if (gLpsrAccidentalStyleKindsMap.size ()) {
1040 map<string, lpsrAccidentalStyleKind>::const_iterator
1041 iBegin = gLpsrAccidentalStyleKindsMap.begin (),
1042 iEnd = gLpsrAccidentalStyleKindsMap.end (),
1043 i = iBegin;
1044
1045 int cumulatedLength = 0;
1046
1047 for ( ; ; ) {
1048 string theString = (*i).first;
1049
1050 s << theString;
1051
1052 cumulatedLength += theString.size ();
1053 if (cumulatedLength >= K_NAMES_LIST_MAX_LENGTH) break;
1054
1055 if (++i == iEnd) break;
1056
1057 if (next (i) == iEnd) {
1058 s << " and ";
1059 }
1060 else {
1061 s << ", ";
1062 }
1063 } // for
1064 }
1065
1066 return s.str ();
1067 }
1068
1069 // chords languages
1070 //______________________________________________________________________________
1071
1072 map<string, lpsrChordsLanguageKind>
1073 gLpsrChordsLanguageKindsMap;
1074
initializeLpsrChordsLanguageKindsMap()1075 void initializeLpsrChordsLanguageKindsMap ()
1076 {
1077 gLpsrChordsLanguageKindsMap ["ignatzek"] = k_IgnatzekChords; // default
1078 gLpsrChordsLanguageKindsMap ["german"] = k_GermanChords;
1079 gLpsrChordsLanguageKindsMap ["semiGerman"] = k_SemiGermanChords;
1080 gLpsrChordsLanguageKindsMap ["italian"] = k_ItalianChords;
1081 gLpsrChordsLanguageKindsMap ["french"] = k_FrenchChords;
1082 }
1083
lpsrChordsLanguageKindAsString(lpsrChordsLanguageKind languageKind)1084 string lpsrChordsLanguageKindAsString (
1085 lpsrChordsLanguageKind languageKind)
1086 {
1087 string result;
1088
1089 switch (languageKind) {
1090 case k_IgnatzekChords: // default value
1091 result = "ignatzek";
1092 break;
1093 case k_GermanChords:
1094 result = "german";
1095 break;
1096 case k_SemiGermanChords:
1097 result = "semiGerman";
1098 break;
1099 case k_ItalianChords:
1100 result = "italian";
1101 break;
1102 case k_FrenchChords:
1103 result = "french";
1104 break;
1105 } // switch
1106
1107 return result;
1108 }
1109
existingLpsrChordsLanguageKinds(int namesListMaxLength)1110 string existingLpsrChordsLanguageKinds (int namesListMaxLength)
1111 {
1112 stringstream s;
1113
1114 if (gLpsrChordsLanguageKindsMap.size ()) {
1115 map<string, lpsrChordsLanguageKind>::const_iterator
1116 iBegin = gLpsrChordsLanguageKindsMap.begin (),
1117 iEnd = gLpsrChordsLanguageKindsMap.end (),
1118 i = iBegin;
1119
1120 int cumulatedLength = 0;
1121
1122 for ( ; ; ) {
1123 string theString = (*i).first;
1124
1125 s << theString;
1126
1127 cumulatedLength += theString.size ();
1128 if (cumulatedLength >= K_NAMES_LIST_MAX_LENGTH) break;
1129
1130 if (next (i) == iEnd) {
1131 s << " and ";
1132 }
1133 else {
1134 s << ", ";
1135 }
1136 } // for
1137 }
1138
1139 return s.str ();
1140 }
1141
1142 //______________________________________________________________________________
msrSemiTonesPitchAndOctaveAsLilypondString(msrQuarterTonesPitchesLanguageKind languageKind,S_msrSemiTonesPitchAndOctave semiTonesPitchAndOctave)1143 string msrSemiTonesPitchAndOctaveAsLilypondString (
1144 msrQuarterTonesPitchesLanguageKind languageKind,
1145 S_msrSemiTonesPitchAndOctave semiTonesPitchAndOctave)
1146 {
1147 stringstream s;
1148
1149 msrQuarterTonesPitchKind
1150 quarterTonesPitchKind =
1151 quarterTonesPitchKindFromSemiTonesPitchKind (
1152 semiTonesPitchAndOctave->getSemiTonesPitchKind ());
1153
1154 map<msrQuarterTonesPitchKind, string>
1155 *pitchNamesMapPTR =
1156 &gNederlandsPitchNamesMap; // default LilyPond value
1157
1158 // is quarterTonesPitchName in the part renaming map?
1159 switch (languageKind) {
1160 case kNederlands:
1161 pitchNamesMapPTR = &gNederlandsPitchNamesMap;
1162 break;
1163 case kCatalan:
1164 pitchNamesMapPTR = &gCatalanPitchNamesMap;
1165 break;
1166 case kDeutsch:
1167 pitchNamesMapPTR = &gDeutschPitchNamesMap;
1168 break;
1169 case kEnglish:
1170 pitchNamesMapPTR = &gEnglishPitchNamesMap;
1171 break;
1172 case kEspanol:
1173 pitchNamesMapPTR = &gEspanolPitchNamesMap;
1174 break;
1175 case kFrancais:
1176 pitchNamesMapPTR = &gFrancaisPitchNamesMap;
1177 break;
1178 case kItaliano:
1179 pitchNamesMapPTR = &gItalianoPitchNamesMap;
1180 break;
1181 case kNorsk:
1182 pitchNamesMapPTR = &gNorskPitchNamesMap;
1183 break;
1184 case kPortugues:
1185 pitchNamesMapPTR = &gPortuguesPitchNamesMap;
1186 break;
1187 case kSuomi:
1188 pitchNamesMapPTR = &gSuomiPitchNamesMap;
1189 break;
1190 case kSvenska:
1191 pitchNamesMapPTR = &gSvenskaPitchNamesMap;
1192 break;
1193 case kVlaams:
1194 pitchNamesMapPTR = &gVlaamsPitchNamesMap;
1195 break;
1196 } // switch
1197
1198 s << (*pitchNamesMapPTR) [quarterTonesPitchKind];
1199
1200 switch (semiTonesPitchAndOctave->getOctave ()) {
1201 case -7:
1202 s << ",,,,,,,,,,";
1203 break;
1204 case -6:
1205 s << ",,,,,,,,,,";
1206 break;
1207 case -5:
1208 s << ",,,,,,,,,";
1209 break;
1210 case -4:
1211 s << ",,,,,,,";
1212 break;
1213 case -3:
1214 s << ",,,,,,";
1215 break;
1216 case -2:
1217 s << ",,,,,";
1218 break;
1219 case -1:
1220 s << ",,,,";
1221 break;
1222 case 0:
1223 s << ",,,";
1224 break;
1225 case 1:
1226 s << ",,";
1227 break;
1228 case 2:
1229 s << ",";
1230 break;
1231 case 3:
1232 s << "";
1233 break;
1234 case 4:
1235 s << "'";
1236 break;
1237 case 5:
1238 s << "''";
1239 break;
1240 case 6:
1241 s << "'''";
1242 break;
1243 case 7:
1244 s << "''''";
1245 break;
1246 case 8:
1247 s << "'''''";
1248 break;
1249 case 9:
1250 s << "''''''";
1251 break;
1252 case 10:
1253 s << "'''''''";
1254 break;
1255 case 11:
1256 s << "''''''''";
1257 break;
1258 case 12:
1259 s << "'''''''''";
1260 break;
1261 case 13:
1262 s << "''''''''''";
1263 break;
1264 case 14:
1265 s << "'''''''''''";
1266 break;
1267 case 15:
1268 s << "''''''''''''";
1269 break;
1270 case 16:
1271 s << "'''''''''''''";
1272 break;
1273 default:
1274 s << "!!!";
1275 } // switch
1276
1277 #ifdef TRACE_OAH
1278 if (gTraceOah->fTraceNotesOctaveEntry) {
1279 s <<
1280 " %{ " <<
1281 semiTonesPitchAndOctave->asString () <<
1282 " %}";
1283 }
1284 #endif
1285
1286 return s.str ();
1287 }
1288
1289 /* JMI
1290 string msrSemiTonesPitchAndOctaveAsLilypondString (
1291 msrQuarterTonesPitchesLanguageKind languageKind,
1292 S_msrSemiTonesPitchAndOctave semiTonesPitchAndOctave)
1293 {
1294 msrQuarterTonesPitchKind
1295 quarterTonesPitchKind =
1296 quarterTonesPitchKindFromSemiTonesPitchKind (
1297 semiTonesPitchKind);
1298
1299 return
1300 msrQuarterTonesPitchAndOctaveAsLilypondString (
1301 languageKind,
1302 quarterTonesPitchKind);
1303
1304 return "??????";
1305 }
1306 */
1307
1308 // lyrics durations
1309 //______________________________________________________________________________
1310
1311 map<string, lpsrLyricsDurationsKind>
1312 gLpsrLyricsDurationsKindsMap;
1313
lpsrLyricsDurationsKindAsString(lpsrLyricsDurationsKind lyricsDurationsKind)1314 string lpsrLyricsDurationsKindAsString (
1315 lpsrLyricsDurationsKind lyricsDurationsKind)
1316 {
1317 string result;
1318
1319 // no CamelCase here, these strings are used in the command line options
1320
1321 switch (lyricsDurationsKind) {
1322 case kLyricsDurationsImplicit:
1323 result = "lyricsDurationsImplicit";
1324 break;
1325 case kLyricsDurationsExplicit:
1326 result = "lyricsDurationsExplicit";
1327 break;
1328 } // switch
1329
1330 return result;
1331 }
1332
initializeLpsrLyricsDurationsKindsMap()1333 void initializeLpsrLyricsDurationsKindsMap ()
1334 {
1335 // register the LilyPond score output kinds
1336 // --------------------------------------
1337
1338 // no CamelCase here, these strings are used in the command line options
1339
1340 gLpsrLyricsDurationsKindsMap ["implicit"] = kLyricsDurationsImplicit;
1341 gLpsrLyricsDurationsKindsMap ["explicit"] = kLyricsDurationsExplicit;
1342 }
1343
existingLpsrLyricsDurationsKinds(int namesListMaxLength)1344 string existingLpsrLyricsDurationsKinds (int namesListMaxLength)
1345 {
1346 stringstream s;
1347
1348 if (gLpsrLyricsDurationsKindsMap.size ()) {
1349 map<string, lpsrLyricsDurationsKind>::const_iterator
1350 iBegin = gLpsrLyricsDurationsKindsMap.begin (),
1351 iEnd = gLpsrLyricsDurationsKindsMap.end (),
1352 i = iBegin;
1353
1354 int cumulatedLength = 0;
1355
1356 for ( ; ; ) {
1357 string theString = (*i).first;
1358
1359 s << theString;
1360
1361 cumulatedLength += theString.size ();
1362 if (cumulatedLength >= K_NAMES_LIST_MAX_LENGTH) break;
1363
1364 if (++i == iEnd) break;
1365 if (next (i) == iEnd) {
1366 s << " and ";
1367 }
1368 else {
1369 s << ", ";
1370 }
1371 } // for
1372 }
1373
1374 return s.str ();
1375 }
1376
1377 //______________________________________________________________________________
initializeLPSRBasicTypes()1378 void initializeLPSRBasicTypes ()
1379 {
1380 #ifdef TRACE_OAH
1381 if (gTraceOah->fTraceOah && ! gGeneralOah->fQuiet) {
1382 gLogOstream <<
1383 "Initializing LPSR basic types handling" <<
1384 endl;
1385 }
1386 #endif
1387
1388 // LPSR score output handling
1389 // ------------------------------------------------------
1390
1391 initializeLpsrScoreOutputKindsMap ();
1392
1393 // LPSR octave entry handling
1394 // ------------------------------------------------------
1395
1396 initializeLpsrOctaveEntryKindsMap ();
1397
1398 // LPSR accidental styles handling
1399 // ------------------------------------------------------
1400
1401 initializeLpsrAccidentalStyleKindsMap ();
1402
1403 // LPSR chords languages handling
1404 // ------------------------------------------------------
1405
1406 initializeLpsrChordsLanguageKindsMap ();
1407
1408
1409 // LPSR lyrics durations kinds handling
1410 // ------------------------------------------------------
1411
1412 initializeLpsrLyricsDurationsKindsMap ();
1413 }
1414
1415
1416 }
1417