]> git.donarmstrong.com Git - lilypond.git/blob - lily/grace-position-performer.cc
release: 1.3.0
[lilypond.git] / lily / grace-position-performer.cc
1 /*   
2   grace-position-performer.cc --  implement Grace_position_performer
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
7
8  */
9
10 #include "performer.hh"
11 #include "audio-item.hh"
12 #include "global-translator.hh"
13
14 class Grace_position_performer : public Performer
15 {
16 public:
17   Grace_position_performer ();
18
19 protected:
20   Link_array<Audio_note> graces_;
21   Link_array<Audio_note> notes_;
22
23   VIRTUAL_COPY_CONS (Translator);
24   virtual void acknowledge_element (Audio_element_info);
25   virtual void process_acknowledged ();
26   virtual void do_post_move_processing ();
27   Global_translator* global_translator_l ();
28 };
29
30 ADD_THIS_TRANSLATOR (Grace_position_performer);
31
32 Grace_position_performer::Grace_position_performer ()
33 {
34 }
35
36 void
37 Grace_position_performer::acknowledge_element (Audio_element_info i)
38 {
39   if (Audio_note * n = dynamic_cast <Audio_note*> (i.elem_l_))
40     {
41       if (i.elem_l_->grace_b_)
42         graces_.push (n);
43       else
44         notes_.push (n);
45     }
46 }
47
48 void
49 Grace_position_performer::process_acknowledged ()
50 {
51   if (graces_.size ())
52     {
53       // we're above grace-engraver-group, so we cannot tell
54       // grace-iterator.  note-performer should add moments.
55       //Global_translator* global_l = global_translator_l ();
56       Moment delay_mom = Moment (1, 8);
57       if (notes_.size ())
58         {
59           Moment shortest_mom = notes_[0]->length_mom_;
60           for (int i=1; i < notes_.size (); i++)
61             shortest_mom = shortest_mom <? notes_[i]->length_mom_;
62           
63           Rational grace_fraction_rat (1, 2);
64           SCM prop = get_property ("graceFraction", 0);
65           if (SMOB_IS_TYPE_B(Moment, prop))
66             grace_fraction_rat = *SMOB_TO_TYPE (Moment,prop);
67
68           delay_mom = shortest_mom * grace_fraction_rat;
69           for (int i=0; i < notes_.size (); i++)
70             {
71               Audio_note* n = notes_[i];
72               n->length_mom_ -= delay_mom;
73               n->delayed_mom_ = delay_mom;
74               n->delayed_until_mom_ = now_mom () + delay_mom;
75               //global_l->add_moment_to_process (n->delayed_until_mom_);
76             }
77           notes_.clear ();
78         }
79       
80       Moment grace_length_mom;
81       for (int i=0; i < graces_.size (); i++)
82         grace_length_mom += graces_[i]->length_mom_;
83
84       Rational grace_factor_rat = delay_mom / grace_length_mom;
85
86       for (int i=0; i < graces_.size (); i++)
87         {
88           Audio_note* n = graces_[i];
89           n->length_mom_ *= grace_factor_rat;
90           if (i)
91             {
92               Audio_note* p = graces_[i-1];
93               n->delayed_mom_ = p->delayed_mom_ + p->length_mom_;
94               n->delayed_until_mom_ = now_mom () + n->delayed_mom_;
95               //global_l->add_moment_to_process (n->delayed_until_mom_);
96             }
97         }
98       graces_.clear ();
99     }
100 }
101
102 Global_translator*
103 Grace_position_performer::global_translator_l ()
104 {
105   Translator *t = this;
106   Global_translator *global_l =0;
107   do
108     {
109       t = t->daddy_trans_l_ ;
110       global_l = dynamic_cast<Global_translator*> (t);
111     }
112   while (!global_l);
113
114   return global_l;
115 }
116
117
118 void
119 Grace_position_performer::do_post_move_processing ()
120 {
121   graces_.clear ();
122   notes_.clear ();
123 }
124