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