]> git.donarmstrong.com Git - lilypond.git/blob - lily/key-performer.cc
Run `make grand-replace'.
[lilypond.git] / lily / key-performer.cc
1 /*
2   key-performer.cc -- implement Key_performer
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997--2008 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
8
9 #include "audio-item.hh"
10 #include "music-sequence.hh"
11 #include "performer.hh"
12 #include "stream-event.hh"
13 #include "warn.hh"
14
15 #include "translator.icc"
16
17 class Key_performer : public Performer
18 {
19 public:
20   TRANSLATOR_DECLARATIONS (Key_performer);
21   ~Key_performer ();
22
23 protected:
24   void process_music ();
25   void stop_translation_timestep ();
26
27   DECLARE_TRANSLATOR_LISTENER (key_change);
28 private:
29   Stream_event *key_ev_;
30   Audio_key *audio_;
31 };
32
33 Key_performer::Key_performer ()
34 {
35   key_ev_ = 0;
36   audio_ = 0;
37 }
38
39 Key_performer::~Key_performer ()
40 {
41 }
42
43 void
44 Key_performer::process_music ()
45 {
46   if (key_ev_)
47     {
48       SCM pitchlist = key_ev_->get_property ("pitch-alist");
49       SCM proc = ly_lily_module_constant ("alterations-in-key");
50
51       SCM acc = scm_call_1 (proc, pitchlist);
52
53       Pitch key_do (0,
54                     scm_to_int (scm_caar (pitchlist)),
55                     ly_scm2rational (scm_cdar (pitchlist)));
56
57       Pitch c_do (0, 0, 0);
58
59       SCM c_pitchlist
60         = ly_transpose_key_alist (pitchlist,
61                                   pitch_interval (key_do, c_do).smobbed_copy ());
62
63       /* MIDI keys are too limited for lilypond scales.
64          We check for minor scale and assume major otherwise.  */
65
66       SCM third = scm_assoc (scm_from_int (2),
67                              c_pitchlist);
68       bool minor = (scm_is_pair (third)
69                     && scm_is_number (scm_cdr (third))
70                     && ly_scm2rational (scm_cdr (third)) == FLAT_ALTERATION);
71
72       audio_ = new Audio_key (scm_to_int (acc),
73                               !minor);
74
75       Audio_element_info info (audio_, key_ev_);
76       announce_element (info);
77       key_ev_ = 0;
78     }
79 }
80
81 void
82 Key_performer::stop_translation_timestep ()
83 {
84   if (audio_)
85     {
86       audio_ = 0;
87     }
88 }
89
90 IMPLEMENT_TRANSLATOR_LISTENER (Key_performer, key_change);
91 void
92 Key_performer::listen_key_change (Stream_event *ev)
93 {
94   if (!key_ev_)
95     key_ev_ = ev;
96 }
97
98 ADD_TRANSLATOR (Key_performer,
99                 /* doc */
100                 "",
101
102                 /* create */
103                 "",
104
105                 /* read */
106                 "",
107
108                 /* write */
109                 ""
110                 );