]> git.donarmstrong.com Git - lilypond.git/blob - lily/staff-performer.cc
Merge branch 'master' into lilypond/translation
[lilypond.git] / lily / staff-performer.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1997--2011 Jan Nieuwenhuizen <janneke@gnu.org>
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <map>
21
22 #include "warn.hh"
23 #include "audio-column.hh"
24 #include "audio-item.hh"
25 #include "audio-staff.hh"
26 #include "performer-group.hh"
27 #include "context.hh"
28
29 /* Perform a staff. Individual notes should have their instrument
30   (staff-wide) set, so we override play_element ()
31 */
32 class Staff_performer : public Performer
33 {
34 public:
35   TRANSLATOR_DECLARATIONS (Staff_performer);
36   ~Staff_performer ();
37
38   string new_instrument_string ();
39   string instrument_string_;
40
41 protected:
42   virtual void acknowledge_audio_element (Audio_element_info info);
43   virtual void finalize ();
44   virtual void initialize ();
45   void process_music ();
46   void stop_translation_timestep ();
47
48 private:
49   Audio_staff *audio_staff_;
50   Audio_instrument *instrument_;
51   Audio_text *instrument_name_;
52   Audio_text *name_;
53   Audio_tempo *tempo_;
54   map<string, int> channel_map_;
55 };
56
57 #include "translator.icc"
58
59 ADD_TRANSLATOR (Staff_performer,
60                 /* doc */
61                 "",
62
63                 /* create */
64                 "",
65
66                 /* read */
67                 "",
68
69                 /* write */
70                 "");
71
72 Staff_performer::Staff_performer ()
73 {
74   audio_staff_ = 0;
75   instrument_ = 0;
76   instrument_name_ = 0;
77   name_ = 0;
78   tempo_ = 0;
79 }
80
81 Staff_performer::~Staff_performer ()
82 {
83 }
84
85 void
86 Staff_performer::initialize ()
87 {
88   audio_staff_ = new Audio_staff;
89   name_ = new Audio_text (Audio_text::TRACK_NAME, context ()->id_string ());
90
91   audio_staff_->add_audio_item (name_);
92   
93   announce_element (Audio_element_info (audio_staff_, 0));
94   announce_element (Audio_element_info (name_, 0));
95 }
96
97 void
98 Staff_performer::process_music ()
99 {
100   string str = new_instrument_string ();
101   if (str.length ())
102     {
103       instrument_name_ = new Audio_text (Audio_text::INSTRUMENT_NAME, str);
104       announce_element (Audio_element_info (instrument_name_, 0));
105       instrument_ = new Audio_instrument (str);
106       announce_element (Audio_element_info (instrument_, 0));
107
108       audio_staff_->add_audio_item (instrument_);
109       audio_staff_->add_audio_item (instrument_name_);
110      
111       /*
112         Have to be here before notes arrive into the staff.
113       */
114     }
115 }
116
117 void
118 Staff_performer::stop_translation_timestep ()
119 {
120   SCM proc = ly_lily_module_constant ("percussion?");
121   SCM drums = scm_call_1 (proc, ly_symbol2scm (instrument_string_.c_str ()));
122   audio_staff_->percussion_ = (drums == SCM_BOOL_T);
123
124   if (name_)
125       name_ = 0;
126   if (tempo_)
127       tempo_ = 0;
128   instrument_name_ = 0;
129   instrument_ = 0;
130 }
131
132 void
133 Staff_performer::finalize ()
134 {
135   audio_staff_ = 0;
136 }
137
138 string
139 Staff_performer::new_instrument_string ()
140 {
141   // mustn't ask Score for instrument: it will return piano!
142   SCM minstr = get_property ("midiInstrument");
143
144   if (!scm_is_string (minstr)
145       || ly_scm2string (minstr) == instrument_string_)
146     return "";
147
148   instrument_string_ = ly_scm2string (minstr);
149
150   return instrument_string_;
151 }
152
153 void
154 Staff_performer::acknowledge_audio_element (Audio_element_info inf)
155 {
156   if (Audio_item *ai = dynamic_cast<Audio_item *> (inf.elem_))
157     {
158       /* map each context (voice) to its own channel */
159       Context *c = inf.origin_contexts (this)[0];
160       string id = c->id_string ();
161       int channel = channel_map_.size ();
162       /* MIDI players tend to ignore instrument settings on channel
163          10, the percussion channel.  */
164       if (channel % 16 == 9)
165         channel_map_[""] = channel++;
166
167       map<string, int>::const_iterator i = channel_map_.find (id);
168       if (i != channel_map_.end ())
169         channel = i->second;
170       else
171         channel_map_[id] = channel;
172
173       ai->channel_ = channel;
174       audio_staff_->add_audio_item (ai);
175     }
176 }
177