--- /dev/null
+/*
+ grace-performer-group.cc -- implement Grace_performer_group
+
+ source file of the GNU LilyPond music playter
+
+ (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
+
+ */
+#include "grace-performer-group.hh"
+#include "lily-guile.hh"
+#include "ly-symbols.hh"
+#include "audio-element.hh"
+
+ADD_THIS_TRANSLATOR (Grace_performer_group);
+
+void
+Grace_performer_group::start ()
+{
+}
+/*
+ We're really finished with this context. Get rid of everything.
+ */
+void
+Grace_performer_group::finish ()
+{
+ calling_self_b_ = true;
+ removal_processing (); // ugr. We'd want to have this done by our parents.g
+ for (int i=0; i < announce_to_top_.size (); i++)
+ {
+ Performer::announce_element (announce_to_top_[i]);
+ }
+
+ for (int i=0; i < play_us_.size (); i++)
+ {
+ Performer::play_element (play_us_[i]);
+ }
+ play_us_.clear ();
+ calling_self_b_ = false;
+}
+
+void
+Grace_performer_group::do_removal_processing ()
+{
+ Performer_group_performer::do_removal_processing ();
+}
+
+void
+Grace_performer_group::announce_element (Audio_element_info inf)
+{
+ announce_info_arr_.push (inf);
+ // do not propagate to top
+ announce_to_top_.push (inf);
+
+ //inf.elem_l_->set_elt_property (grace_scm_sym, SCM_BOOL_T);
+}
+
+void
+Grace_performer_group::play_element (Audio_element*e)
+{
+ play_us_.push (e);
+}
+
+
+Grace_performer_group::Grace_performer_group()
+{
+ calling_self_b_ = false;
+}
+
+void
+Grace_performer_group::process ()
+{
+ calling_self_b_ = true;
+ process_requests ();
+ do_announces();
+ pre_move_processing();
+ check_removal();
+ calling_self_b_ = false;
+}
+
+
+void
+Grace_performer_group::each (Method_pointer method)
+{
+ if (calling_self_b_)
+ Performer_group_performer::each (method);
+}
+
+
+void
+Grace_performer_group::each (Const_method_pointer method) const
+{
+ if (calling_self_b_)
+ Performer_group_performer::each (method);
+}
+
+/*
+ don't let the commands trickle up.
+ */
+bool
+Grace_performer_group::do_try_music (Music *m)
+{
+ bool hebbes_b =false;
+
+ Link_array<Translator> nongroups (nongroup_l_arr ());
+
+ for (int i =0; !hebbes_b && i < nongroups.size() ; i++)
+ hebbes_b =nongroups[i]->try_music (m);
+
+ return hebbes_b;
+}
--- /dev/null
+/*
+ grace-performer-group.hh -- declare
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
+
+ */
+
+#ifndef GRACE_PERFORMER_GROUP_HH
+#define GRACE_PERFORMER_GROUP_HH
+
+#include "performer-group-performer.hh"
+#include "global-translator.hh"
+
+class Grace_performer_group : public Performer_group_performer, public Global_translator
+{
+ Link_array<Audio_element> play_us_;
+ Array<Audio_element_info> announce_to_top_;
+ bool calling_self_b_;
+public:
+ VIRTUAL_COPY_CONS(Translator);
+ Grace_performer_group ();
+protected:
+ virtual void announce_element (Audio_element_info);
+ virtual void start ();
+ virtual void finish ();
+ virtual void process ();
+ virtual void each (Method_pointer);
+ virtual void each (Const_method_pointer) const;
+ virtual void do_removal_processing () ;
+ virtual void play_element (Audio_element*);
+ virtual bool do_try_music (Music *m);
+};
+
+
+#endif /* GRACE_PERFORMER_GROUP_HH */
--- /dev/null
+/*
+ key-def.hh -- declare
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
+
+ */
+
+#ifndef KEY_DEF_HH
+#define KEY_DEF_HH
+
+#include "array.hh"
+#include "musical-pitch.hh"
+
+/**
+ Universal key definition (Should rename class Key to 'Accidentals'?)
+ */
+class Key_def
+{
+public:
+ Key_def ();
+
+ Array<Musical_pitch> pitch_arr_;
+ int modality_i_;
+ bool ordinary_key_b_;
+
+ /// squash the octaves to 1
+ void squash_octaves ();
+
+ /// return number accidentals in key; ordinary key only
+ int ordinary_accidentals_i () const;
+
+ /// return number of flats in key
+ int flats_i () const;
+
+ /// return number of sharps in key
+ int sharps_i () const;
+
+ /// modality == 3
+ bool minor_b () const;
+
+ void transpose (Musical_pitch d);
+};
+
+#endif /* KEY_DEF_HH */
--- /dev/null
+/*
+ tie-performer.hh -- declare
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
+
+ */
+
+#ifndef TIE_PERFORMER_HH
+#define TIE_PERFORMER_HH
+
+#include "pqueue.hh"
+#include "performer.hh"
+
+struct CNote_melodic_tuple {
+ Melodic_req *req_l_ ;
+ Audio_note *note_l_;
+ Moment end_;
+ CNote_melodic_tuple ();
+ CNote_melodic_tuple (Audio_note*, Melodic_req*, Moment);
+ static int pitch_compare (CNote_melodic_tuple const &, CNote_melodic_tuple const &);
+ static int time_compare (CNote_melodic_tuple const &, CNote_melodic_tuple const &);
+};
+
+inline int compare (CNote_melodic_tuple const &a, CNote_melodic_tuple const &b)
+{
+ return CNote_melodic_tuple::time_compare (a,b);
+}
+
+
+/**
+ Manufacture ties. Acknowledge notes, and put them into a
+ priority queue. If we have a Tie_req, connect the notes that finish
+ just at this time, and note that start at this time.
+
+ TODO: should share code with Tie_engraver ?
+ */
+class Tie_performer : public Performer
+{
+public:
+ VIRTUAL_COPY_CONS(Translator);
+ Tie_performer ();
+
+private:
+ PQueue<CNote_melodic_tuple> past_notes_pq_;
+ Tie_req *req_l_;
+ Array<CNote_melodic_tuple> now_notes_;
+ Array<CNote_melodic_tuple> stopped_notes_;
+ Link_array<Audio_tie> tie_p_arr_;
+
+protected:
+ virtual void do_post_move_processing ();
+ virtual void do_pre_move_processing ();
+ virtual void acknowledge_element (Audio_element_info);
+ virtual bool do_try_music (Music*);
+ virtual void do_process_requests ();
+ virtual void process_acknowledged ();
+
+};
+
+
+#endif /* TIE_PERFORMER_HH */
+
--- /dev/null
+/*
+ key-def.cc -- implement
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
+
+ */
+
+#include "key-def.hh"
+#include "debug.hh"
+
+Key_def::Key_def ()
+{
+ modality_i_ = 0;
+ ordinary_key_b_ = false;
+}
+
+int
+Key_def::ordinary_accidentals_i () const
+{
+ if (!ordinary_key_b_)
+ {
+ programming_error ("Accidentals requested for non-conventional key");
+ return 0;
+ }
+
+ int p;
+ if (pitch_arr_.size () < 1)
+ {
+ warning (_ ("No key name: assuming `C'"));
+ p = 0;
+ }
+ else
+ {
+ p = pitch_arr_[0].semitone_pitch ();
+ p += modality_i_;
+ }
+ /* Solve the equation 7*accidentals_i mod 12 = p, -6 <= accidentals_i <= 5 */
+ int accidentals_i = (7*p) % 12;
+ accidentals_i = (accidentals_i + 18) % 12 -6;
+
+ /* Correct from flats to sharps or vice versa */
+ if (accidentals_i * pitch_arr_[0].accidental_i_ < 0)
+ accidentals_i += 12 * sign (pitch_arr_[0].accidental_i_);
+ return accidentals_i;
+}
+
+int
+Key_def::flats_i () const
+{
+ if (ordinary_key_b_)
+ return 0 >? -ordinary_accidentals_i ();
+ int flats_i = 0;
+ for (int i = 0; i < pitch_arr_.size (); i++)
+ {
+ if (pitch_arr_[i].accidental_i_ < 0)
+ flats_i -= pitch_arr_[i].accidental_i_;
+ }
+ return flats_i;
+}
+
+bool
+Key_def::minor_b () const
+{
+ return modality_i_ == 3;
+}
+
+int
+Key_def::sharps_i () const
+{
+ if (ordinary_key_b_)
+ return 0 >? ordinary_accidentals_i ();
+ int sharps_i = 0;
+ for (int i = 0; i < pitch_arr_.size (); i++)
+ {
+ if (pitch_arr_[i].accidental_i_ > 0)
+ sharps_i += pitch_arr_[i].accidental_i_;
+ }
+ return sharps_i;
+}
+
+void
+Key_def::transpose (Musical_pitch d)
+{
+ if (ordinary_key_b_ )
+ {
+ if (pitch_arr_.size () > 0)
+ pitch_arr_[0].transpose (d);
+ else
+ {
+ warning (_ ("don't know how handle empty keys")); // TODO
+ }
+ }
+ else
+ {
+ Array<Musical_pitch> old_pitch_arr_;
+ for (int i = 0; i < pitch_arr_.size (); i++)
+ {
+ old_pitch_arr_.push (pitch_arr_[i]);
+ }
+ // set accidentals for \key d (as in Key_engraver::read_req)
+ // (later called "new accidentals")
+ int p = d.semitone_pitch ();
+ /* Solve the equation 7*accidentals_i mod 12 = p, -6 <= accidentals_i <= 5 */
+ int accidentals_i = (7*p) % 12;
+ accidentals_i = (accidentals_i + 18) % 12 -6;
+
+ /* Correct from flats to sharps or vice versa */
+ if (accidentals_i * d.accidental_i_ < 0)
+ accidentals_i += 12 * sign (d.accidental_i_);
+
+ pitch_arr_.clear ();
+ if (accidentals_i < 0)
+ {
+ int accidental = 6 ; // First accidental: bes
+ for ( ; accidentals_i < 0 ; accidentals_i++ )
+ {
+ Musical_pitch m;
+ m.accidental_i_ = -1;
+ m.notename_i_ = accidental;
+ pitch_arr_.push (m);
+
+ accidental = (accidental + 3) % 7 ;
+ }
+ }
+ else
+ {
+ int accidental = 3 ; // First accidental: fis
+ for ( ; accidentals_i > 0 ; accidentals_i-- )
+ {
+ Musical_pitch m;
+ m.accidental_i_ = 1;
+ m.notename_i_ = accidental;
+ pitch_arr_.push (m);
+
+ accidental = (accidental + 4) % 7 ;
+ }
+ }
+ // Check if transposed old accidentals and the new ones coincide
+ accidentals_i = pitch_arr_.size ();
+ int acc_found;
+ Musical_pitch mm;
+ for (int i=0; i < old_pitch_arr_.size (); i++)
+ {
+ acc_found = 0;
+ mm = old_pitch_arr_[i];
+ mm.transpose (d);
+ for (int j=0; ( (j < accidentals_i) && (acc_found == 0)); j++)
+ {
+ if (pitch_arr_[j].notename_i_ == mm.notename_i_)
+ {
+ if (mm.accidental_i_ == 0)
+ {
+ // remove new accidental
+ pitch_arr_.del (j);
+ accidentals_i--;
+ acc_found = 1;
+ }
+ else
+ {
+ // change new accidental
+ pitch_arr_[j].accidental_i_ = mm.accidental_i_;
+ acc_found = 1;
+ }
+ }
+ }
+ if (acc_found == 0)
+ {
+ // add transposed old accidental
+ pitch_arr_.push (mm);
+ }
+ }
+ }
+}
+
+void
+Key_def::squash_octaves ()
+{
+ for (int i=0; i < pitch_arr_.size (); i++)
+ {
+ pitch_arr_[i].octave_i_ = 0;
+ }
+}
--- /dev/null
+/*
+ tie-performer.cc -- implement
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1999 Jan Nieuwenhuizen <janneke@gnu.org>
+
+ */
+
+#include "tie-performer.hh"
+#include "command-request.hh"
+#include "audio-item.hh"
+#include "musical-request.hh"
+
+
+ADD_THIS_TRANSLATOR (Tie_performer);
+
+Tie_performer::Tie_performer()
+{
+ req_l_ = 0;
+}
+
+bool
+Tie_performer::do_try_music (Music *m)
+{
+ if (Tie_req * c = dynamic_cast<Tie_req*> (m))
+ {
+ req_l_ = c;
+ return true;
+ }
+ return false;
+}
+
+void
+Tie_performer::acknowledge_element (Audio_element_info i)
+{
+ if (Audio_note *nh = dynamic_cast<Audio_note *> (i.elem_l_))
+ {
+ Note_req * m = dynamic_cast<Note_req* > (i.req_l_);
+ if (!m)
+ return;
+ now_notes_.push (CNote_melodic_tuple (nh, m, now_mom()+ m->length_mom ()));
+ }
+}
+
+void
+Tie_performer::do_process_requests ()
+{
+ if (req_l_)
+ {
+ Moment now = now_mom ();
+ Link_array<Audio_note> nharr;
+
+ stopped_notes_.clear ();
+ while (past_notes_pq_.size ()
+ && past_notes_pq_.front ().end_ == now)
+ stopped_notes_.push (past_notes_pq_.get ());
+ }
+}
+
+void
+Tie_performer::process_acknowledged ()
+{
+ if (req_l_)
+ {
+ now_notes_.sort (CNote_melodic_tuple::pitch_compare);
+ stopped_notes_.sort(CNote_melodic_tuple::pitch_compare);
+ int i=0;
+ int j=0;
+ int tie_count=0;
+ while ( i < now_notes_.size () && j < stopped_notes_.size ())
+ {
+ int comp
+ = Musical_pitch::compare (now_notes_[i].req_l_->pitch_ ,
+ stopped_notes_[j].req_l_->pitch_);
+
+ if (comp)
+ {
+ (comp < 0) ? i ++ : j++;
+ continue;
+ }
+ else
+ {
+ tie_count ++;
+
+ /* don't go around recreating ties that were already
+ made. Not infallible. Due to reordering in sort (),
+ we will make the wrong ties when notenotes are
+ added. */
+ if (tie_count > tie_p_arr_.size ())
+ {
+ Audio_tie * p = new Audio_tie;
+ p->set_note (LEFT, stopped_notes_[j].note_l_);
+ p->set_note (RIGHT, now_notes_[i].note_l_);
+ tie_p_arr_.push (p);
+ announce_element (Audio_element_info (p, req_l_));
+ }
+ i++;
+ j++;
+
+ }
+ }
+
+ if (!tie_p_arr_.size ())
+ {
+ req_l_->warning (_("No ties were created!"));
+ }
+
+ }
+}
+
+void
+Tie_performer::do_pre_move_processing ()
+{
+ for (int i=0; i < now_notes_.size (); i++)
+ {
+ past_notes_pq_.insert (now_notes_[i]);
+ }
+ now_notes_.clear ();
+
+ for (int i=0; i< tie_p_arr_.size (); i++)
+ {
+ //play_element (tie_p_arr_[i]);
+ /*
+ urg.
+ doesn't work for c ~ c ~ c
+ */
+ tie_p_arr_[i]->note_l_drul_[LEFT]->length_mom_ +=
+ tie_p_arr_[i]->note_l_drul_[RIGHT]->length_mom_;
+ tie_p_arr_[i]->note_l_drul_[RIGHT]->length_mom_ = 0;
+ }
+ tie_p_arr_.clear ();
+}
+
+void
+Tie_performer::do_post_move_processing ()
+{
+ req_l_ =0;
+ Moment now = now_mom ();
+ while (past_notes_pq_.size () && past_notes_pq_.front ().end_ < now)
+ past_notes_pq_.delmin ();
+}
+
+
+CNote_melodic_tuple::CNote_melodic_tuple ()
+{
+ note_l_ =0;
+ req_l_ =0;
+ end_ = 0;
+}
+
+CNote_melodic_tuple::CNote_melodic_tuple (Audio_note *h, Melodic_req*m, Moment mom)
+{
+ note_l_ = h;
+ req_l_ = m;
+ end_ = mom;
+}
+
+int
+CNote_melodic_tuple::pitch_compare (CNote_melodic_tuple const&h1,
+ CNote_melodic_tuple const &h2)
+{
+ return Melodic_req::compare (*h1.req_l_, *h2.req_l_);
+}
+
+int
+CNote_melodic_tuple::time_compare (CNote_melodic_tuple const&h1,
+ CNote_melodic_tuple const &h2)
+{
+ return (h1.end_ - h2.end_ ).sign ();
+}