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