From: Jan Nieuwenhuizen Date: Mon, 5 Jul 1999 10:56:28 +0000 (+0200) Subject: partial: 1.1.53.jcn X-Git-Tag: release/1.1.53~1 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=0ac652bb955a79fcb1655a5fade88bc6e1e551c3;p=lilypond.git partial: 1.1.53.jcn --- diff --git a/lily/grace-performer-group.cc b/lily/grace-performer-group.cc new file mode 100644 index 0000000000..65d4cdef7f --- /dev/null +++ b/lily/grace-performer-group.cc @@ -0,0 +1,110 @@ +/* + grace-performer-group.cc -- implement Grace_performer_group + + source file of the GNU LilyPond music playter + + (c) 1999 Jan Nieuwenhuizen + + */ +#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 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 index 0000000000..515015e106 --- /dev/null +++ b/lily/include/grace-performer-group.hh @@ -0,0 +1,37 @@ +/* + grace-performer-group.hh -- declare + + source file of the GNU LilyPond music typesetter + + (c) 1999 Jan Nieuwenhuizen + + */ + +#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 play_us_; + Array 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 index 0000000000..0303fb4e84 --- /dev/null +++ b/lily/include/key-def.hh @@ -0,0 +1,46 @@ +/* + key-def.hh -- declare + + source file of the GNU LilyPond music typesetter + + (c) 1999 Jan Nieuwenhuizen + + */ + +#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 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 index 0000000000..08fe1b98f9 --- /dev/null +++ b/lily/include/tie-performer.hh @@ -0,0 +1,64 @@ +/* + tie-performer.hh -- declare + + source file of the GNU LilyPond music typesetter + + (c) 1999 Jan Nieuwenhuizen + + */ + +#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 past_notes_pq_; + Tie_req *req_l_; + Array now_notes_; + Array stopped_notes_; + Link_array 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 index 0000000000..7c492b23f3 --- /dev/null +++ b/lily/key-def.cc @@ -0,0 +1,184 @@ +/* + key-def.cc -- implement + + source file of the GNU LilyPond music typesetter + + (c) 1999 Jan Nieuwenhuizen + + */ + +#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 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 index 0000000000..0d7d5a0257 --- /dev/null +++ b/lily/tie-performer.cc @@ -0,0 +1,171 @@ +/* + tie-performer.cc -- implement + + source file of the GNU LilyPond music typesetter + + (c) 1999 Jan Nieuwenhuizen + + */ + +#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 (m)) + { + req_l_ = c; + return true; + } + return false; +} + +void +Tie_performer::acknowledge_element (Audio_element_info i) +{ + if (Audio_note *nh = dynamic_cast (i.elem_l_)) + { + Note_req * m = dynamic_cast (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 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 (); +}