]> git.donarmstrong.com Git - lilypond.git/blob - lily/dynamic-performer.cc
(class Phrasing_slur_engraver):
[lilypond.git] / lily / dynamic-performer.cc
1 /*
2   dynamic-performer.cc -- implement Dynamic_performer
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2000--2005 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
8
9 #include "performer.hh"
10
11 #include "audio-item.hh"
12 #include "music.hh"
13 #include "translator.icc"
14
15
16 /*
17   TODO:
18
19   handle multiple events
20
21   perform absolute (text) dynamics
22 */
23 class Dynamic_performer : public Performer
24 {
25 public:
26   TRANSLATOR_DECLARATIONS (Dynamic_performer);
27 protected:
28   virtual bool try_music (Music *event);
29   void stop_translation_timestep ();
30   virtual void create_audio_elements ();
31
32 private:
33   Music *script_event_;
34   Audio_dynamic *audio_;
35 };
36
37 Dynamic_performer::Dynamic_performer ()
38 {
39   script_event_ = 0;
40   audio_ = 0;
41 }
42
43 void
44 Dynamic_performer::create_audio_elements ()
45 {
46   if (script_event_)
47     {
48       SCM proc = get_property ("dynamicAbsoluteVolumeFunction");
49
50       SCM svolume = SCM_EOL;
51       if (ly_is_procedure (proc))
52         {
53           // urg
54           svolume = scm_call_1 (proc, script_event_->get_property ("text"));
55         }
56
57       Real volume = robust_scm2double (svolume, 0.5);
58
59       /*
60         properties override default equaliser setting
61       */
62       SCM min = get_property ("midiMinimumVolume");
63       SCM max = get_property ("midiMaximumVolume");
64       if (scm_is_number (min) || scm_is_number (max))
65         {
66           Interval iv (0, 1);
67           if (scm_is_number (min))
68             iv[MIN] = scm_to_double (min);
69           if (scm_is_number (max))
70             iv[MAX] = scm_to_double (max);
71           volume = iv[MIN] + iv.length () * volume;
72         }
73       else
74         {
75           /*
76             urg, code duplication:: staff_performer
77           */
78           SCM s = get_property ("midiInstrument");
79
80           if (!scm_is_string (s))
81             s = get_property ("instrument");
82
83           if (!scm_is_string (s))
84             s = scm_makfrom0str ("piano");
85
86           SCM eq = get_property ("instrumentEqualizer");
87           if (ly_is_procedure (eq))
88             {
89               s = scm_call_1 (eq, s);
90             }
91
92           if (is_number_pair (s))
93             {
94               Interval iv = ly_scm2interval (s);
95               volume = iv[MIN] + iv.length () * volume;
96             }
97         }
98
99       audio_ = new Audio_dynamic (volume);
100       Audio_element_info info (audio_, script_event_);
101       announce_element (info);
102       script_event_ = 0;
103     }
104 }
105
106 void
107 Dynamic_performer::stop_translation_timestep ()
108 {
109   if (audio_)
110     {
111       play_element (audio_);
112       audio_ = 0;
113     }
114 }
115
116 bool
117 Dynamic_performer::try_music (Music *r)
118 {
119   if (!script_event_)
120     {
121       if (r->is_mus_type ("absolute-dynamic-event")) // fixme.
122         {
123           script_event_ = r;
124           return true;
125         }
126     }
127   return false;
128 }
129
130 ADD_TRANSLATOR (Dynamic_performer,
131                 /* doc */                "",
132                 /* create */ "",
133                 /* accept */ "absolute-dynamic-event",
134                 /* read */ "dynamicAbsoluteVolumeFunction midiMaximumVolume midiMinimumVolume midiInstrument instrumentEqualizer",
135                 /*writes*/"");