]> git.donarmstrong.com Git - lilypond.git/blob - lily/musical-pitch.cc
release: 1.2.12
[lilypond.git] / lily / musical-pitch.cc
1 /*   
2   musical-pitch.cc --  implement Musical_pitch
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1998--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9 #include "musical-pitch.hh"
10 #include "debug.hh"
11 #include "main.hh"
12
13 Musical_pitch::Musical_pitch (int n, int a, int o)
14 {
15   notename_i_ = n;
16   accidental_i_ = a;
17   octave_i_ = o;
18 }
19
20 void
21 Musical_pitch::print () const
22 {
23 #ifndef NPRINT
24   DEBUG_OUT << str ();
25 #endif
26 }
27
28 int
29 Musical_pitch::compare (Musical_pitch const &m1, Musical_pitch const &m2)
30 {
31     int o=  m1.octave_i_ - m2.octave_i_;
32   int n = m1.notename_i_ - m2.notename_i_;
33   int a = m1.accidental_i_ - m2.accidental_i_;
34
35   if (o)
36         return o;
37   if (n)
38         return n;
39   if (a)
40         return a;
41   return 0;
42 }
43
44 int
45 Musical_pitch::steps () const
46 {
47   return  notename_i_ + octave_i_*7;
48 }
49
50 /*
51   should be settable from input to allow "viola"-mode
52  */
53 static Byte pitch_byte_a[  ] = { 0, 2, 4, 5, 7, 9, 11 };
54
55 int
56 Musical_pitch::semitone_pitch () const
57 {
58   return  pitch_byte_a[ notename_i_ % 7 ] + accidental_i_ + octave_i_ * 12;
59 }
60
61 void
62 Musical_pitch::transpose (Musical_pitch delta)
63 {
64   int old_pitch = semitone_pitch ();
65   int delta_pitch = delta.semitone_pitch ();
66   octave_i_ += delta.octave_i_;
67   notename_i_ += delta.notename_i_;
68
69   
70   while  (notename_i_ >= 7)
71     {
72       notename_i_ -= 7;
73       octave_i_ ++;
74     }
75
76   int new_pitch = semitone_pitch ();
77   int delta_acc = new_pitch - old_pitch - delta_pitch;
78   accidental_i_ -= delta_acc;
79 }
80
81
82 #if 0
83 // nice test for internationalisation strings
84 char const *accname[] = {"double flat", "flat", "natural",
85                          "sharp" , "double sharp"};
86 #else
87 char const *accname[] = {"eses", "es", "", "is" , "isis"};
88 #endif
89
90 String
91 Musical_pitch::str () const
92 {
93   int n = (notename_i_ + 2) % 7;
94   String s = to_str (char(n + 'a'));
95   if (accidental_i_)
96     s += String (accname[accidental_i_ + 2]);
97
98   if (octave_i_ > 0)
99     {
100       int o = octave_i_ + 1;
101       while (o--)
102         s += "'";
103     }
104   else if (octave_i_ <0)
105     {
106       int o = (-octave_i_) - 1;
107       while (o--)
108         s += to_str (',');
109     }
110 #if 0  
111   if (octave_i_)
112     s  += String ((octave_i_> 0)? "^": "_") + to_str (octave_i_);
113 #endif
114   
115   return s;
116 }
117
118 /*
119   change me to relative, counting from last pitch p
120   return copy of resulting pitch
121  */
122 Musical_pitch
123 Musical_pitch::to_relative_octave (Musical_pitch p)
124 {
125   int oct_mod = octave_i_  + 1; // account for c' = octave 1 iso. 0 4
126   Musical_pitch up_pitch (p);
127   Musical_pitch down_pitch (p);
128
129   up_pitch.accidental_i_ = accidental_i_;
130   down_pitch.accidental_i_ = accidental_i_;
131   
132   Musical_pitch n = *this;
133   up_pitch.up_to (notename_i_);
134   down_pitch.down_to (notename_i_);
135
136   int h = p.steps ();
137   if (abs (up_pitch.steps () - h) < abs (down_pitch.steps () - h))
138     n = up_pitch;
139   else
140     n = down_pitch;
141   
142   n.octave_i_ += oct_mod;
143
144   *this = n;
145   return *this;
146 }
147
148 void
149 Musical_pitch::up_to (int notename)
150 {
151   if (notename_i_  > notename)
152     {
153       octave_i_ ++;
154     }
155   notename_i_  = notename;
156 }
157
158 void
159 Musical_pitch::down_to (int notename)
160 {
161   if (notename_i_ < notename)
162     {
163       octave_i_ --;
164     }
165   notename_i_ = notename;
166 }
167