]> git.donarmstrong.com Git - lilypond.git/commitdiff
partial: 1.1.53.jcn
authorJan Nieuwenhuizen <janneke@gnu.org>
Mon, 5 Jul 1999 10:56:28 +0000 (12:56 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Mon, 5 Jul 1999 10:56:28 +0000 (12:56 +0200)
lily/grace-performer-group.cc [new file with mode: 0644]
lily/include/grace-performer-group.hh [new file with mode: 0644]
lily/include/key-def.hh [new file with mode: 0644]
lily/include/tie-performer.hh [new file with mode: 0644]
lily/key-def.cc [new file with mode: 0644]
lily/tie-performer.cc [new file with mode: 0644]

diff --git a/lily/grace-performer-group.cc b/lily/grace-performer-group.cc
new file mode 100644 (file)
index 0000000..65d4cde
--- /dev/null
@@ -0,0 +1,110 @@
+/*   
+  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;
+}
diff --git a/lily/include/grace-performer-group.hh b/lily/include/grace-performer-group.hh
new file mode 100644 (file)
index 0000000..515015e
--- /dev/null
@@ -0,0 +1,37 @@
+/*   
+  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 */
diff --git a/lily/include/key-def.hh b/lily/include/key-def.hh
new file mode 100644 (file)
index 0000000..0303fb4
--- /dev/null
@@ -0,0 +1,46 @@
+/*   
+  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 */
diff --git a/lily/include/tie-performer.hh b/lily/include/tie-performer.hh
new file mode 100644 (file)
index 0000000..08fe1b9
--- /dev/null
@@ -0,0 +1,64 @@
+/*   
+  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 */
+
diff --git a/lily/key-def.cc b/lily/key-def.cc
new file mode 100644 (file)
index 0000000..7c492b2
--- /dev/null
@@ -0,0 +1,184 @@
+/*   
+  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;
+    }
+}
diff --git a/lily/tie-performer.cc b/lily/tie-performer.cc
new file mode 100644 (file)
index 0000000..0d7d5a0
--- /dev/null
@@ -0,0 +1,171 @@
+/*   
+  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 ();
+}