1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2007-2011 Werner Schweer
6 //
7 //  This program is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License version 2
9 //  as published by the Free Software Foundation and appearing in
10 //  the file LICENCE.GPL
11 //=============================================================================
12 
13 //  This file contains the implementation of an pitch spelling
14 //  algorithmus from Emilios Cambouropoulos as published in:
15 //  "Automatic Pitch Spelling: From Numbers to Sharps and Flats"
16 
17 #include "note.h"
18 #include "key.h"
19 #include "pitchspelling.h"
20 #include "staff.h"
21 #include "chord.h"
22 #include "score.h"
23 #include "part.h"
24 #include "utils.h"
25 
26 #include "audio/midi/event.h"
27 
28 namespace Ms {
29 
30 //---------------------------------------------------------
31 //   tpcIsValid
32 //---------------------------------------------------------
33 
tpcIsValid(int val)34 bool tpcIsValid(int val)
35       {
36       return val >= Tpc::TPC_MIN && val <= Tpc::TPC_MAX;
37       }
38 
39 //---------------------------------------------------------
40 //   step2tpc
41 //---------------------------------------------------------
42 
step2tpc(int step,AccidentalVal alter)43 int step2tpc(int step, AccidentalVal alter)
44       {
45       //    TPC - tonal pitch classes
46       //    "line of fifth's" LOF
47 
48       static const int spellings[] = {
49       //    bbb  bb  b   -   #  ##  ###
50             -7,  0,  7, 14, 21, 28, 35,  // C
51             -5,  2,  9, 16, 23, 30, 37,  // D
52             -3,  4, 11, 18, 25, 32, 39,  // E
53             -8, -1,  6, 13, 20, 27, 34,  // F
54             -6,  1,  8, 15, 22, 29, 36,  // G
55             -4,  3, 10, 17, 24, 31, 38,  // A
56             -2,  5, 12, 19, 26, 33, 40,  // B
57             };
58 
59       int i = (step * TPCS_PER_STEP) + (int(alter) - int(AccidentalVal::MIN));
60       Q_ASSERT(i >= 0 && (i < int(sizeof(spellings)/sizeof(*spellings))));
61       return spellings[i];
62       }
63 
64 static const int tpcByStepAndKey[int(Key::NUM_OF)][STEP_DELTA_OCTAVE] = {
65 // step          C             D             E             F             G             A             B        Key
66       { Tpc::TPC_C_B, Tpc::TPC_D_B, Tpc::TPC_E_B, Tpc::TPC_F_B, Tpc::TPC_G_B, Tpc::TPC_A_B, Tpc::TPC_B_B}, // Cb
67       { Tpc::TPC_C_B, Tpc::TPC_D_B, Tpc::TPC_E_B, Tpc::TPC_F,   Tpc::TPC_G_B, Tpc::TPC_A_B, Tpc::TPC_B_B}, // Gb
68       { Tpc::TPC_C,   Tpc::TPC_D_B, Tpc::TPC_E_B, Tpc::TPC_F,   TPC_G_B,      Tpc::TPC_A_B, Tpc::TPC_B_B}, // Db
69       { Tpc::TPC_C,   Tpc::TPC_D_B, Tpc::TPC_E_B, Tpc::TPC_F,   Tpc::TPC_G,   Tpc::TPC_A_B, Tpc::TPC_B_B}, // Ab
70       { Tpc::TPC_C,   Tpc::TPC_D,   Tpc::TPC_E_B, Tpc::TPC_F,   Tpc::TPC_G,   Tpc::TPC_A_B, Tpc::TPC_B_B}, // Eb
71       { Tpc::TPC_C,   Tpc::TPC_D,   Tpc::TPC_E_B, Tpc::TPC_F,   Tpc::TPC_G,   Tpc::TPC_A,   Tpc::TPC_B_B}, // B
72       { Tpc::TPC_C,   Tpc::TPC_D,   Tpc::TPC_E,   Tpc::TPC_F,   Tpc::TPC_G,   Tpc::TPC_A,   Tpc::TPC_B_B}, // F
73       { Tpc::TPC_C,   Tpc::TPC_D,   Tpc::TPC_E,   Tpc::TPC_F,   Tpc::TPC_G,   Tpc::TPC_A,   Tpc::TPC_B},   // C
74       { Tpc::TPC_C,   Tpc::TPC_D,   Tpc::TPC_E,   Tpc::TPC_F_S, Tpc::TPC_G,   Tpc::TPC_A,   Tpc::TPC_B},   // G
75       { Tpc::TPC_C_S, Tpc::TPC_D,   Tpc::TPC_E,   Tpc::TPC_F_S, Tpc::TPC_G,   Tpc::TPC_A,   Tpc::TPC_B},   // D
76       { Tpc::TPC_C_S, Tpc::TPC_D,   Tpc::TPC_E,   Tpc::TPC_F_S, Tpc::TPC_G_S, Tpc::TPC_A,   Tpc::TPC_B},   // A
77       { Tpc::TPC_C_S, Tpc::TPC_D_S, Tpc::TPC_E,   Tpc::TPC_F_S, Tpc::TPC_G_S, Tpc::TPC_A,   Tpc::TPC_B},   // E
78       { Tpc::TPC_C_S, Tpc::TPC_D_S, Tpc::TPC_E,   Tpc::TPC_F_S, Tpc::TPC_G_S, Tpc::TPC_A_S, Tpc::TPC_B},   // H
79       { Tpc::TPC_C_S, Tpc::TPC_D_S, Tpc::TPC_E_S, Tpc::TPC_F_S, Tpc::TPC_G_S, Tpc::TPC_A_S, Tpc::TPC_B},   // F#
80       { Tpc::TPC_C_S, Tpc::TPC_D_S, Tpc::TPC_E_S, Tpc::TPC_F_S, Tpc::TPC_G_S, Tpc::TPC_A_S, Tpc::TPC_B_S}, // C#
81 };
82 
step2tpcByKey(int step,Key key)83 int step2tpcByKey(int step, Key key)
84       {
85       while (step < 0)
86             step += STEP_DELTA_OCTAVE;
87       while (key < Key::MIN)
88             key  += Key::DELTA_ENHARMONIC;
89       while (key > Key::MAX)
90             key  -= Key::DELTA_ENHARMONIC;
91       return tpcByStepAndKey[int(key) - int(Key::MIN)][step % STEP_DELTA_OCTAVE];
92       }
93 
94 //---------------------------------------------------------
95 //   tpc2step
96 //---------------------------------------------------------
97 
tpc2step(int tpc)98 int tpc2step(int tpc)
99       {
100       // 14 - C
101       // 15 % 7 = 1
102       //                                            f  c  g  d  a  e  b
103       static const int steps[STEP_DELTA_OCTAVE] = { 3, 0, 4, 1, 5, 2, 6 };
104       // TODO: optimize -TCP_MIN
105       return steps[(tpc-Tpc::TPC_MIN) % STEP_DELTA_OCTAVE];
106 // without a table, could also be rendered as:
107 //      return ((tpc-Tpc::TPC_MIN) * STEP_DELTA_TPC) / STEP_DELTA_OCTAVE + TPC_FIRST_STEP;
108       }
109 
110 //---------------------------------------------------------
111 //   tpc2stepByKey
112 //---------------------------------------------------------
113 
tpc2stepByKey(int tpc,Key key,int & alter)114 int tpc2stepByKey(int tpc, Key key, int& alter)
115       {
116       alter = tpc2alterByKey(tpc, key);
117       return tpc2step(tpc);
118       }
119 
120 //---------------------------------------------------------
121 //   step2tpc
122 //---------------------------------------------------------
123 
step2tpc(const QString & stepName,AccidentalVal alter)124 int step2tpc(const QString& stepName, AccidentalVal alter)
125       {
126       if (stepName.isEmpty())
127             return Tpc::TPC_INVALID;
128       int r;
129       switch (stepName[0].toLower().toLatin1()) {
130             case 'c': r = 0; break;
131             case 'd': r = 1; break;
132             case 'e': r = 2; break;
133             case 'f': r = 3; break;
134             case 'g': r = 4; break;
135             case 'a': r = 5; break;
136             case 'b': r = 6; break;
137             default:
138                   return Tpc::TPC_INVALID;
139             }
140       return step2tpc(r, alter);
141       }
142 
143 //---------------------------------------------------------
144 //   step2deltaPitchByKey
145 //
146 // returns the delta pitch above natural C for the given step in the given key
147 // step: 0 - 6
148 // key: -7 - +7
149 //---------------------------------------------------------
150 
151 static const int pitchByStepAndKey[int(Key::NUM_OF)][STEP_DELTA_OCTAVE] = {
152 // step  C   D   E   F   G   A   B           Key
153       { -1,  1,  3,  4,  6,  8, 10},      // Cb
154       { -1,  1,  3,  5,  6,  8, 10},      // Gb
155       {  0,  1,  3,  5,  6,  8, 10},      // Db
156       {  0,  1,  3,  5,  7,  8, 10},      // Ab
157       {  0,  2,  3,  5,  7,  8, 10},      // Eb
158       {  0,  2,  3,  5,  7,  9, 10},      // B
159       {  0,  2,  4,  5,  7,  9, 10},      // F
160       {  0,  2,  4,  5,  7,  9, 11},      // C
161       {  0,  2,  4,  6,  7,  9, 11},      // G
162       {  1,  2,  4,  6,  7,  9, 11},      // D
163       {  1,  2,  4,  6,  8,  9, 11},      // A
164       {  1,  3,  4,  6,  8,  9, 11},      // E
165       {  1,  3,  4,  6,  8, 10, 11},      // H
166       {  1,  3,  5,  6,  8, 10, 11},      // F#
167       {  1,  3,  5,  6,  8, 10, 12},      // C#
168 };
169 
step2deltaPitchByKey(int step,Key key)170 int step2deltaPitchByKey(int step, Key key)
171       {
172       while (step < 0)
173             step+= STEP_DELTA_OCTAVE;
174       while (key < Key::MIN)
175             key += Key::DELTA_ENHARMONIC;
176       while (key > Key::MAX)
177             key -= Key::DELTA_ENHARMONIC;
178       return pitchByStepAndKey[int(key)-int(Key::MIN)][step % STEP_DELTA_OCTAVE];
179       }
180 
181 //---------------------------------------------------------
182 //   tpc2pitch
183 //---------------------------------------------------------
184 
tpc2pitch(int tpc)185 int tpc2pitch(int tpc)
186       {
187       Q_ASSERT(tpcIsValid(tpc));
188 
189       static int pitches[] = {
190 //step:     F   C   G   D   A   E   B
191             2, -3,  4, -1,  6,  1,  8,     // bbb
192             3, -2,  5,  0,  7,  2,  9,     // bb
193             4, -1,  6,  1,  8,  3, 10,     // b
194             5,  0,  7,  2,  9,  4, 11,     // -
195             6,  1,  8,  3, 10,  5, 12,     // #
196             7,  2,  9,  4, 11,  6, 13,     // ##
197             8,  3, 10,  5, 12,  7, 14      // ###
198             };
199       return pitches[tpc - Tpc::TPC_MIN];
200       }
201 
202 //---------------------------------------------------------
203 //   tpc2alterByKey
204 //
205 // returns the alteration (-3 to 3) of a given tpc in the given key
206 // to understand the formula:
207 //    in the highest key (C#Maj), each of the first 7 tpcs (Fbb to Bbb; tpc-Tpc::TPC_MIN: 0 to 7)
208 //          is 3 semitones below its key degree (alter = -3)
209 //    the second 7 tpcs (Fb to Bb; tpc-Tpc::TPC_MIN: 8 to 13) are 2 semitones below (alter = -2) and so on up to 1
210 //    thus, for C#Maj:
211 // (1)      (tpc-Tpc::TPC_MIN) - 0         =  0 to 34 (for tcp-TCP_MIN from 0 to 34)
212 // (2)      (tpc-Tpc::TPC_MIN) - 0) / 7    =  0 to 4  (for each settuple of tcp's) and finally
213 // (3)      (tcp-Tpc::TPC_MIN) - 0) / 7 -3 = -3 to 1  (for each settuple of tcp's)
214 //          where 0 = Key::C_S - Key::MAX
215 //    for each previous key, the result of (1) increases by 1 and the classes of alter are shifted 1 TPC 'up':
216 //          F#Maj: Fbb-Ebb => -3, Bbb to Eb => -2 and so on
217 //          BMaj:  Fbb-Abb => -3, Ebb to Ab => -2 and so on
218 //          and so on
219 //    thus, for any 'key', the formula is:
220 //          ((tcp-Tpc::TPC_MIN) - (key-Key::MAX)) / TCP_DELTA_SEMITONE - 3
221 //---------------------------------------------------------
222 
tpc2alterByKey(int tpc,Key key)223 int tpc2alterByKey(int tpc, Key key) {
224       return (tpc - int(key) - int(Tpc::TPC_MIN) + int(Key::MAX)) / TPC_DELTA_SEMITONE - (int(AccidentalVal::MAX) + 1);
225       }
226 
227 //---------------------------------------------------------
228 //   tpc2name
229 //    return note name
230 //---------------------------------------------------------
231 
tpc2name(int tpc,NoteSpellingType noteSpelling,NoteCaseType noteCase,bool explicitAccidental)232 QString tpc2name(int tpc, NoteSpellingType noteSpelling, NoteCaseType noteCase, bool explicitAccidental)
233       {
234       QString s;
235       QString acc;
236       tpc2name(tpc, noteSpelling, noteCase, s, acc, explicitAccidental);
237       return s + (explicitAccidental ? " " : "") + acc;
238       }
239 
240 //---------------------------------------------------------
241 //   tpc2name
242 //---------------------------------------------------------
243 
tpc2name(int tpc,NoteSpellingType noteSpelling,NoteCaseType noteCase,QString & s,QString & acc,bool explicitAccidental)244 void tpc2name(int tpc, NoteSpellingType noteSpelling, NoteCaseType noteCase, QString& s, QString& acc, bool explicitAccidental)
245       {
246       AccidentalVal accVal;
247       tpc2name(tpc, noteSpelling, noteCase, s, accVal);
248       switch (accVal) {
249             case AccidentalVal::FLAT3:
250                   if (explicitAccidental) {
251                         acc = QObject::tr("triple ♭");
252                         }
253                   else if (noteSpelling == NoteSpellingType::GERMAN_PURE) {
254                         switch (tpc) {
255                               case TPC_A_BBB: acc = "sasas"; break;
256                               case TPC_E_BBB: acc = "seses"; break;
257                               default: acc = "eseses";
258                               }
259                         }
260                   else {
261                         acc = "bbb";
262                         }
263                   break;
264             case AccidentalVal::FLAT2:
265                   if (explicitAccidental) {
266                         acc = QObject::tr("double ♭");
267                         }
268                   else if (noteSpelling == NoteSpellingType::GERMAN_PURE) {
269                         switch (tpc) {
270                               case TPC_A_BB: acc = "sas"; break;
271                               case TPC_E_BB: acc = "ses"; break;
272                               default: acc = "eses";
273                               }
274                         }
275                   else {
276                         acc = "bb";
277                         }
278                   break;
279             case AccidentalVal::FLAT:
280                   if (explicitAccidental)
281                         acc = QObject::tr("♭");
282                   else if (noteSpelling == NoteSpellingType::GERMAN_PURE)
283                         acc = (tpc == TPC_A_B || tpc == TPC_E_B) ? "s" : "es";
284                   else
285                         acc = "b";
286                   break;
287             case  AccidentalVal::NATURAL: acc = ""; break;
288             case  AccidentalVal::SHARP:
289                   if (explicitAccidental)
290                         acc = QObject::tr("♯");
291                   else
292                         acc = (noteSpelling == NoteSpellingType::GERMAN_PURE) ? "is" : "#";
293                   break;
294             case  AccidentalVal::SHARP2:
295                   if (explicitAccidental)
296                         acc = QObject::tr("double ♯");
297                   else
298                         acc = (noteSpelling == NoteSpellingType::GERMAN_PURE) ? "isis" : "##";
299                   break;
300             case AccidentalVal::SHARP3:
301                   if (explicitAccidental)
302                         acc = QObject::tr("triple ♯");
303                   else
304                         acc = (noteSpelling == NoteSpellingType::GERMAN_PURE) ? "isisis" : "###";
305                   break;
306             }
307       }
308 
309 //---------------------------------------------------------
310 //   tpc2name
311 //---------------------------------------------------------
312 
tpc2name(int tpc,NoteSpellingType noteSpelling,NoteCaseType noteCase,QString & s,AccidentalVal & acc)313 void tpc2name(int tpc, NoteSpellingType noteSpelling, NoteCaseType noteCase, QString& s, AccidentalVal& acc)
314       {
315       const char names[]  = "FCGDAEB";
316       const char gnames[] = "FCGDAEH";
317       const QString snames[] = { "Fa", "Do", "Sol", "Re", "La", "Mi", "Si" };
318 
319       acc = tpc2alter(tpc);
320       int idx = (tpc - Tpc::TPC_MIN) % TPC_DELTA_SEMITONE;
321       switch (noteSpelling) {
322             case NoteSpellingType::GERMAN:
323             case NoteSpellingType::GERMAN_PURE:
324                   s = gnames[idx];
325                   if (s == "H" && acc == AccidentalVal::FLAT) {
326                         s = "B";
327                         if (noteSpelling == NoteSpellingType::GERMAN_PURE)
328                               acc = AccidentalVal::NATURAL;
329                         }
330                   break;
331             case NoteSpellingType::SOLFEGGIO:
332                   s = snames[idx];
333                   break;
334             case NoteSpellingType::FRENCH:
335                   s = snames[idx];
336                   if (s == "Re")
337                         s = "Ré";
338                   break;
339             default:
340                   s = names[idx];
341                   break;
342             }
343       switch (noteCase) {
344             case NoteCaseType::LOWER: s = s.toLower(); break;
345             case NoteCaseType::UPPER: s = s.toUpper(); break;
346             case NoteCaseType::CAPITAL:
347             case NoteCaseType::AUTO:
348             default:
349                   break;
350             }
351       }
352 
353 //---------------------------------------------------------
354 //   tpc2stepName
355 //---------------------------------------------------------
356 
tpc2stepName(int tpc)357 QString tpc2stepName(int tpc)
358       {
359       const char names[] = "FCGDAEB";
360       return QString(names[(tpc - Tpc::TPC_MIN) % 7]);
361       }
362 
363 // table of alternative spellings for one octave
364 // each entry is the TPC of the note
365 //    tab1 does not contain double sharps
366 //    tab2 does not contain double flats
367 
368 static const int tab1[24] = {
369       14,  2,  // 60  C   Dbb
370       21,  9,  // 61  C#  Db
371       16,  4,  // 62  D   Ebb
372       23, 11,  // 63  D#  Eb
373       18,  6,  // 64  E   Fb
374       13,  1,  // 65  F   Gbb
375       20,  8,  // 66  F#  Gb
376       15,  3,  // 67  G   Abb
377       22, 10,  // 68  G#  Ab
378       17,  5,  // 69  A   Bbb
379       24, 12,  // 70  A#  Bb
380       19,  7,  // 71  B   Cb
381       };
382 
383 static const int tab2[24] = {
384       26, 14,  // 60  B#  C
385       21,  9,  // 61  C#  Db
386       28, 16,  // 62  C## D
387       23, 11,  // 63  D#  Eb
388       30, 18,  // 64  D## E
389       25, 13,  // 65  E#  F
390       20,  8,  // 66  F#  Gb
391       27, 15,  // 67  F## G
392       22, 10,  // 68  G#  Ab
393       29, 17,  // 69  G## A
394       24, 12,  // 70  A#  Bb
395       31, 19,  // 71  A## B
396       };
397 
398 int intervalPenalty[13] = {
399       0, 0, 0, 0, 0, 0, 1, 3, 1, 1, 1, 3, 3
400       };
401 
402 //---------------------------------------------------------
403 //   enharmonicSpelling
404 //---------------------------------------------------------
405 
406 static const int enharmonicSpelling[15][34] = {
407       {
408 //Ces f  c  g  d  a  e  b
409          1, 1, 1, 1, 1, 1, // bb
410       0, 0, 0, 0, 0, 0, 0, // b
411       1, 1, 1, 1, 1, 1, 1,
412       1, 1, 1, 1, 1, 1, 1, // #
413       1, 1, 1, 1, 1, 1, 1  // ##
414       },
415       {
416 //Ges f  c  g  d  a  e  b
417          1, 1, 1, 1, 1, 1, // bb
418       1, 0, 0, 0, 0, 0, 0, // b
419       0, 1, 1, 1, 1, 1, 1,
420       1, 1, 1, 1, 1, 1, 1, // #
421       1, 1, 1, 1, 1, 1, 1  // ##
422       },
423       {
424 //Des f  c  g  d  a  e  b
425          1, 1, 1, 1, 1, 1, // bb
426       1, 1, 0, 0, 0, 0, 0, // b
427       0, 0, 1, 1, 1, 1, 1,
428       1, 1, 1, 1, 1, 1, 1, // #
429       1, 1, 1, 1, 1, 1, 1  // ##
430       },
431       {
432 //As  f  c  g  d  a  e  b
433          1, 1, 1, 1, 1, 1, // bb
434       1, 1, 0, 0, 0, 0, 0, // b
435       0, 0, 0, 0, 0, 0, 0,
436       0, 1, 1, 1, 1, 1, 1, // #
437       1, 1, 1, 1, 1, 1, 1  // ##
438       },
439       {
440 //Es  f  c  g  d  a  e  b
441          1, 1, 1, 1, 1, 1, // bb
442       1, 1, 0, 0, 0, 0, 0, // b
443       0, 0, 0, 0, 1, 1, 1,
444       0, 0, 1, 1, 1, 1, 1, // #
445       1, 1, 1, 1, 1, 1, 1  // ##
446       },
447       {
448 //Bb  f  c  g  d  a  e  b
449          1, 1, 1, 1, 1, 1, // bb
450       1, 1, 0, 0, 0, 0, 0, // b
451       0, 0, 0, 0, 0, 1, 1,
452       1, 0, 0, 1, 1, 1, 1, // #     // (ws) penalty for f#
453       1, 1, 1, 1, 1, 1, 1  // ##
454       },
455       {
456 //F   f  c  g  d  a  e  b           // extra penalty for a# b
457          1, 1, 1, 1, 1, 1, // bb
458       1, 1, 0, 0, 0, 0, 0, // b
459       0, 0, 0, 0, 0, 0, 1,
460       0, 0, 0, 0, 1, 1, 1, // #
461       1, 1, 1, 1, 1, 1, 1  // ##
462       },
463       {
464 //C   f  c  g  d  a  e  b
465          1, 1, 1, 1, 1, 1, // bb
466       1, 1, 0, 0, 0, 0, 0, // b
467       0, 0, 0, 0, 0, 0, 0,
468       0, 0, 0, 0, 0, 1, 1, // #
469       1, 1, 1, 1, 1, 1, 1  // ##
470       },
471       {
472 //G   f  c  g  d  a  e  b
473          1, 1, 1, 1, 1, 1, // bb
474       1, 1, 1, 0, 0, 0, 0, // b
475       1, 0, 0, 0, 0, 0, 0,
476       0, 0, 0, 0, 0, 1, 1, // #
477       1, 1, 1, 1, 1, 1, 1  // ##
478       },
479       {
480 //D   f  c  g  d  a  e  b
481          1, 1, 1, 1, 1, 1, // bb
482       1, 1, 1, 1, 0, 0, 0, // b
483       1, 1, 0, 0, 0, 0, 0,
484       0, 0, 0, 0, 0, 1, 1, // #
485       1, 1, 1, 1, 1, 1, 1  // ##
486       },
487       {
488 //A   f  c  g  d  a  e  b
489          1, 1, 1, 1, 1, 1, // bb
490       1, 1, 1, 1, 1, 0, 0, // b
491       1, 1, 1, 0, 0, 0, 0,
492       0, 0, 0, 0, 0, 1, 1, // #
493       1, 1, 1, 1, 1, 1, 1  // ##
494       },
495       {
496 //E   f  c  g  d  a  e  b
497          1, 1, 1, 1, 1, 1, // bb
498       1, 1, 1, 1, 1, 1, 0, // b
499       1, 1, 1, 1, 0, 0, 0,
500       0, 0, 0, 0, 0, 1, 1, // #
501       0, 0, 1, 1, 1, 1, 1  // ##
502       },
503       {
504 //H   f  c  g  d  a  e  b
505          1, 1, 1, 1, 1, 1, // bb
506       1, 1, 1, 1, 1, 1, 1, // b
507       1, 1, 1, 1, 1, 0, 0,
508       0, 0, 0, 0, 0, 1, 1, // #
509       1, 1, 1, 1, 1, 1, 1  // ##
510       },
511       {
512 //Fis f  c  g  d  a  e  b
513          1, 1, 1, 1, 1, 1, // bb
514       1, 1, 1, 1, 1, 1, 1, // b
515       100, 1, 1, 1, 1, 1, 0,
516       0, 0, 0, 0, 0, 0, 0, // #
517       0, 1, 1, 1, 1, 1, 1  // ##
518       },
519       {
520 //Cis f  c  g  d  a  e  b
521          1, 1, 1, 1, 1, 1, // bb
522       1, 1, 0, 0, 0, 0, 0, // b  //Fis
523       100, 1, 1, 1, 1, 0, 0,
524       0, 0, 0, 0, 0, 0, 0, // #
525       0, 0, 1, 1, 1, 1, 1  // ##
526       }
527       };
528 
529 //---------------------------------------------------------
530 //   penalty
531 //---------------------------------------------------------
532 
penalty(int lof1,int lof2,int k)533 static int penalty(int lof1, int lof2, int k)
534       {
535       if (k < 0 || k >= 15)
536             qFatal("Illegal key %d >= 15", k);
537       Q_ASSERT(lof1 >= 0 && lof1 < 34);
538       Q_ASSERT(lof2 >= 0 && lof2 < 34);
539       int penalty  = enharmonicSpelling[k][lof1] * 4 + enharmonicSpelling[k][lof2] * 4;
540       int distance = lof2 > lof1 ? lof2 - lof1 : lof1 - lof2;
541       if (distance > 12)
542             penalty += 3;
543       else
544             penalty += intervalPenalty[distance];
545       return penalty;
546       }
547 
548 static const int WINDOW       = 9;
549 #if 0 // yet(?) unused
550 static const int WINDOW_SHIFT = 3;
551 static const int ASIZE        = 1024;   // 2 ** WINDOW
552 #endif
553 
554 //---------------------------------------------------------
555 //   tpc
556 //---------------------------------------------------------
557 
tpc(int idx,int pitch,int opt)558 int tpc(int idx, int pitch, int opt)
559       {
560       const int* tab;
561       if (opt < 0) {
562             tab = tab2;
563             opt *= -1;
564             }
565       else
566             tab = tab1;
567       int i = (pitch % 12) * 2 + ((opt & (1 << idx)) >> idx);
568       Q_ASSERT(i >= 0 && i < 24);
569       return tab[i];
570       }
571 
572 //---------------------------------------------------------
573 //   computeWindow
574 //---------------------------------------------------------
575 
computeWindow(const std::vector<Note * > & notes,int start,int end)576 int computeWindow(const std::vector<Note*>& notes, int start, int end)
577       {
578       int p   = 10000;
579       int idx = -1;
580       int pitch[10];
581       int key[10];
582 
583       int i = start;
584       int k = 0;
585       while (i < end) {
586             pitch[k] = notes[i]->pitch() % 12;
587             Fraction tick = notes[i]->chord()->tick();
588             key[k]   = int(notes[i]->staff()->key(tick)) + 7;
589             if (key[k] < 0 || key[k] > 14) {
590                   qDebug("illegal key at tick %d: %d, window %d-%d",
591                      tick.ticks(), key[k] - 7, start, end);
592                   return 0;
593                   // abort();
594                   }
595             ++k;
596             ++i;
597             }
598 
599       for (; k < 10; ++k) {
600             pitch[k] = pitch[k-1];
601             key[k]   = key[k-1];
602             }
603 
604       for (i = 0; i < 512; ++i) {
605             int pa    = 0;
606             int pb    = 0;
607             int l     = pitch[0] * 2 + (i & 1);
608             Q_ASSERT(l >= 0 && l <= static_cast<int>(sizeof(tab1)/sizeof(*tab1)));
609             int lof1a = tab1[l];
610             int lof1b = tab2[l];
611 
612             for (k = 1; k < 10; ++k) {
613                   int l1 = pitch[k] * 2 + ((i & (1 << k)) >> k);
614                   Q_ASSERT(l1 >= 0 && l1 <= static_cast<int>(sizeof(tab1)/sizeof(*tab1)));
615                   int lof2a = tab1[l1];
616                   int lof2b = tab2[l1];
617                   pa += penalty(lof1a, lof2a, key[k]);
618                   pb += penalty(lof1b, lof2b, key[k]);
619                   lof1a = lof2a;
620                   lof1b = lof2b;
621                   }
622             if (pa < pb) {
623                   if (pa < p) {
624                         p   = pa;
625                         idx = i;
626                         }
627                   }
628             else {
629                   if (pb < p) {
630                         p   = pb;
631                         idx = i * -1;
632                         }
633                   }
634             }
635 /*      qDebug("compute window\n   ");
636       for (int i = 0; i < 10; ++i)
637             qDebug("%2d ", pitch[i]);
638       qDebug("\n   ");
639       for (int i = 0; i < 10; ++i)
640             qDebug("%2d ", key[i]);
641       qDebug("\n   ");
642       for (int i = 0; i < 10; ++i)
643             qDebug("%2d ", tpc(i, pitch[i], idx));
644 */
645       return idx;
646       }
647 
648 //---------------------------------------------------------
649 //   changeAllTpcs
650 //---------------------------------------------------------
651 
changeAllTpcs(Note * n,int tpc1)652 void changeAllTpcs(Note* n, int tpc1)
653       {
654       if (!n)
655             return;
656       Interval v;
657       Fraction tick = n->chord() ? n->chord()->tick() : Fraction(-1,1);
658       if (n->part() && n->part()->instrument(tick)) {
659             v = n->part()->instrument(tick)->transpose();
660             v.flip();
661             }
662       int tpc2 = Ms::transposeTpc(tpc1, v, true);
663       n->undoChangeProperty(Pid::TPC1, tpc1);
664       n->undoChangeProperty(Pid::TPC2, tpc2);
665       }
666 
667 //---------------------------------------------------------
668 //   spell
669 //---------------------------------------------------------
670 
spellNotelist(std::vector<Note * > & notes)671 void Score::spellNotelist(std::vector<Note*>& notes)
672       {
673       int n = int(notes.size());
674 
675       int start = 0;
676       while (start < n) {
677             int end = start + WINDOW;
678             if (end > n)
679                   end = n;
680             int opt = computeWindow(notes, start, end);
681             const int* tab;
682             if (opt < 0) {
683                   tab = tab2;
684                   opt *= -1;
685                   }
686             else
687                   tab = tab1;
688 
689             if (start == 0) {
690                   changeAllTpcs(notes[0], tab[(notes[0]->pitch() % 12) * 2 + (opt & 1)]);
691                   if (n > 1)
692                         changeAllTpcs(notes[1], tab[(notes[1]->pitch() % 12) * 2 + ((opt & 2)>>1)]);
693                   if (n > 2)
694                         changeAllTpcs(notes[2], tab[(notes[2]->pitch() % 12) * 2 + ((opt & 4)>>2)]);
695                   }
696             if ((end - start) >= 6) {
697                   changeAllTpcs(notes[start+3], tab[(notes[start+3]->pitch() % 12) * 2 + ((opt &  8) >> 3)]);
698                   changeAllTpcs(notes[start+4], tab[(notes[start+4]->pitch() % 12) * 2 + ((opt & 16) >> 4)]);
699                   changeAllTpcs(notes[start+5], tab[(notes[start+5]->pitch() % 12) * 2 + ((opt & 32) >> 5)]);
700                   }
701             if (end == n) {
702                   int n1 = end - start;
703                   int k;
704                   switch(n1 - 6) {
705                         case 3:
706                               k = end - start - 3;
707                               changeAllTpcs(notes[end-3], tab[(notes[end-3]->pitch() % 12) * 2 + ((opt & (1<<k)) >> k)]);
708                               Q_FALLTHROUGH();
709                         case 2:
710                               k = end - start - 2;
711                               changeAllTpcs(notes[end-2], tab[(notes[end-2]->pitch() % 12) * 2 + ((opt & (1<<k)) >> k)]);
712                               Q_FALLTHROUGH();
713                         case 1:
714                               k = end - start - 1;
715                               changeAllTpcs(notes[end-1], tab[(notes[end-1]->pitch() % 12) * 2 + ((opt & (1<<k)) >> k)]);
716                         }
717                   break;
718                   }
719             // advance to next window
720             start += 3;
721             }
722       }
723 
724 //---------------------------------------------------------
725 //   pitch2tpc2
726 //---------------------------------------------------------
727 
728 // pitch2tpc2(pitch, false) replaced by pitch2tpc(pitch, Key::C, Prefer::FLATS)
729 // pitch2tpc2(pitch, true) replaced by pitch2tpc(pitch, Key::C, Prefer::SHARPS)
730 
731 //---------------------------------------------------------
732 //   pitch2tpc
733 //    preferred pitch spelling depending on key
734 //    key -7 to +7
735 //
736 // The value of prefer sets the preferred mix of flats and sharps
737 // for pitches that are non-diatonic in the key specified, by
738 // positioning the window along the tpc sequence.
739 //
740 // Scale tones are the range shown in [ ].
741 // A value of 8 (Prefer::FLATS) specifies 5b 2b 6b 3b 7b [4 1 5 2 6 3 7]
742 // A value of 11 (Prefer::NEAREST) specifies 3b 7b [4 1 5 2 6 3 7] 4# 1# 5#
743 // A value of 13 (Prefer::SHARPS) specifies [4 1 5 2 6 3 7] 4# 1# 5# 2# 6#
744 //
745 // Examples for Prefer::NEAREST (n indicates explicit natural):
746 // C major will use Eb Bb [F C G D A E B] F# C# G#.
747 // E major will use Gn Dn [A E B F# C# G# D#] A# E# B#.
748 // F# major will use An En [B F# C# G# D# A# E#] B# Fx Cx.
749 // Eb major will use Gb Db [Ab Eb Bb F C G D] An En Bn.
750 // Gb major will use Bbb Fb [Cb Gb Db Ab Eb Bb F] Cn Gn Dn.
751 //---------------------------------------------------------
752 
pitch2tpc(int pitch,Key key,Prefer prefer)753 int pitch2tpc(int pitch, Key key, Prefer prefer)
754       {
755       return (pitch * 7 + 26 - (int(prefer) + int(key))) % 12 + (int(prefer) + int(key));
756       }
757 
758 //---------------------------------------------------------
759 //   pitch2absStepByKey
760 //    absolute step (C0 = 0, D0 = 1, ... C1 = 7, D2 = 8, ...) for a pitch/tpc according to key
761 //    if pAlter not null, returns in it the alteration with respect to the corresponding key degree (-3 to 3)
762 //    (for instance, an F in GMaj yields alteration -1 i.e. 1 semitone below corresp. deg. of GMaj which is F#)
763 //    key: between Key::MIN and Key::MAX
764 //---------------------------------------------------------
765 
pitch2absStepByKey(int pitch,int tpc,Key key,int & alter)766 int pitch2absStepByKey(int pitch, int tpc, Key key, int& alter)
767       {
768       // sanitize input data
769       if (pitch < 0)
770             pitch += PITCH_DELTA_OCTAVE;
771       if (pitch > 127)
772             pitch -= PITCH_DELTA_OCTAVE;
773       if (tpc < Tpc::TPC_MIN)
774             tpc   += TPC_DELTA_ENHARMONIC;
775       if (tpc > Tpc::TPC_MAX)
776             tpc   -= TPC_DELTA_ENHARMONIC;
777       if (key < Key::MIN)
778             key   += Key::DELTA_ENHARMONIC;
779       if (key > Key::MAX)
780             key   -= Key::DELTA_ENHARMONIC;
781 
782       int octave = (pitch - int(tpc2alter(tpc))) / PITCH_DELTA_OCTAVE;
783       int step = tpc2step(tpc);
784       alter = tpc2alterByKey(tpc, key);
785       return octave * STEP_DELTA_OCTAVE + step;
786       }
787 
788 //---------------------------------------------------------
789 //   absStep2pitchByKey
790 //    the default pitch for the given absolute step in the given key
791 //---------------------------------------------------------
792 
absStep2pitchByKey(int step,Key key)793 int absStep2pitchByKey(int step, Key key)
794       {
795       // sanitize input data
796       if (step < 0)
797             step += STEP_DELTA_OCTAVE;
798       if (step > 74)
799             step -= STEP_DELTA_OCTAVE;
800       if (key < Key::MIN)
801             key  += Key::DELTA_ENHARMONIC;
802       if (key > Key::MAX)
803             key  -= Key::DELTA_ENHARMONIC;
804 
805       int octave = step / STEP_DELTA_OCTAVE;
806       int deltaPitch = step2deltaPitchByKey(step % STEP_DELTA_OCTAVE, key);
807       return octave * PITCH_DELTA_OCTAVE + deltaPitch;
808       }
809 
810 //---------------------------------------------------------
811 //   tpc2degree
812 //    the scale degree of a TPC for a given Key
813 //---------------------------------------------------------
814 
tpc2degree(int tpc,Key key)815 int tpc2degree(int tpc, Key key)
816       {
817       const QString names("CDEFGAB");
818       const QString scales("CGDAEBFCGDAEBFC");
819       QString scale = scales[int(key)+7];
820       QString stepName = tpc2stepName(tpc);
821       return (names.indexOf(stepName) - names.indexOf(scale) +28) % 7;
822       }
823 
824 //---------------------------------------------------------
825 //   tpcInterval
826 ///   Finds tpc of a note based on an altered interval
827 ///   from a starting note
828 //---------------------------------------------------------
829 
tpcInterval(int startTpc,int interval,int alter)830 int tpcInterval(int startTpc, int interval, int alter)
831       {
832       Q_ASSERT(interval > 0);
833       static const int intervals[7] = {
834 //          1  2  3   4  5  6  7
835             0, 2, 4, -1, 1, 3, 5
836       };
837 
838       int result = startTpc + intervals[(interval - 1) % 7] + alter * TPC_DELTA_SEMITONE;
839       //ensure that we don't have anything more than double sharp or double flat
840       //(I know, breaking some convention, but it's the best we can do for now)
841       while (result > Tpc::TPC_MAX)
842             result -= TPC_DELTA_ENHARMONIC;
843       while (result < Tpc::TPC_MIN)
844             result += TPC_DELTA_ENHARMONIC;
845 
846       return result;
847       }
848 
849 //---------------------------------------------------------
850 //   step2pitchInterval
851 ///   Finds pitch between notes a specified altered interval away
852 ///
853 ///   For example:
854 ///         step = 3, alter = 0 means major 3rd
855 ///         step = 5, alter = -1 means diminished 5
856 ///         step = 6, alter = 2 means augmented sixth
857 //---------------------------------------------------------
858 
step2pitchInterval(int step,int alter)859 int step2pitchInterval(int step, int alter)
860       {
861       Q_ASSERT(step > 0);
862       static const int intervals[7] = {
863 //          1  2  3  4  5  6  7
864             0, 2, 4, 5, 7, 9, 11
865       };
866 
867       return intervals[(step - 1) % 7] + alter;
868       }
869 
870 //----------------------------------------------
871 //   function2Tpc
872 ///   might be temporary, just used to parse nashville notation now
873 ///
874 //----------------------------------------------
function2Tpc(const QString & s,Key key)875 int function2Tpc(const QString& s, Key key) {
876       //TODO - PHV: allow for alternate spellings
877       int alter = 0;
878       int step;
879       if (!s.isEmpty() && s[0].isDigit()) {
880             step = s[0].digitValue();
881             }
882       else if (s.size() > 1 && s[1].isDigit()) {
883             step = s[1].digitValue();
884             if (s[0] == 'b')
885                   alter = -1;
886             else if (s[0] == '#')
887                   alter = 1;
888             }
889       else
890             return Tpc::TPC_INVALID;
891 
892       int keyTpc = int(key) + 14; //tpc of key (ex. F# major would be Tpc::F_S)
893       return tpcInterval(keyTpc, step, alter);
894       }
895 
896 }
897 
898