From: Han-Wen Nienhuys Date: Thu, 11 Jan 2007 14:47:47 +0000 (+0100) Subject: Fix #87. X-Git-Tag: release/2.10.11-1~3 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=52f9a12c13d296ddada847df46b4ddf5dabf81cb;p=lilypond.git Fix #87. Excise moments from midi backend completely, and move duration to grace_part_ field in grace notes. This fixes MIDI syncing problems with grace notes. Conflicts: input/regression/midi-grace.ly lily/include/midi-item.hh lily/midi-item.cc lily/note-performer.cc --- diff --git a/lily/audio-column.cc b/lily/audio-column.cc index 6365305675..3a3cc5f2f8 100644 --- a/lily/audio-column.cc +++ b/lily/audio-column.cc @@ -29,9 +29,16 @@ Audio_column::when () const return when_; } +int +Audio_column::ticks () const +{ + return int (moment_to_ticks (when_)); +} + void Audio_column::offset_when (Moment m) { when_ += m; } + diff --git a/lily/audio-item.cc b/lily/audio-item.cc index 5372aacafc..75dc5917b1 100644 --- a/lily/audio-item.cc +++ b/lily/audio-item.cc @@ -75,11 +75,23 @@ Audio_span_dynamic::add_absolute (Audio_dynamic *d) dynamics_.push_back (d); } -static Real -moment2real (Moment m) +Moment +remap_grace_duration (Moment m) { - return m.main_part_.to_double () - + 0.1 * m.grace_part_.to_double (); + return Moment (m.main_part_ + Rational (9,40) * m.grace_part_, + Rational (0)); +} + +Real +moment_to_real (Moment m) +{ + return remap_grace_duration (m).main_part_.to_double (); +} + +int +moment_to_ticks (Moment m) +{ + return int (moment_to_real (m) * 384 * 4); } @@ -114,14 +126,14 @@ Audio_span_dynamic::render () Moment start = dynamics_[0]->get_column ()->when (); - Real total_t = moment2real (dynamics_.back ()->get_column ()->when () - start); + Real total_t = moment_to_real (dynamics_.back ()->get_column ()->when () - start); for (vsize i = 1; i < dynamics_.size(); i ++) { Moment dt_moment = dynamics_[i]->get_column ()->when () - start; - Real dt = moment2real (dt_moment); + Real dt = moment_to_real (dt_moment); Real v = start_v + delta_v * (dt / total_t); diff --git a/lily/include/audio-column.hh b/lily/include/audio-column.hh index 239f3f941a..892c678a94 100644 --- a/lily/include/audio-column.hh +++ b/lily/include/audio-column.hh @@ -26,7 +26,7 @@ public: vector audio_items_; Moment when_; - + int ticks () const ; protected: void offset_when (Moment m); friend class Score_performer; diff --git a/lily/include/audio-item.hh b/lily/include/audio-item.hh index d26e567bff..69a0ae78d1 100644 --- a/lily/include/audio-item.hh +++ b/lily/include/audio-item.hh @@ -121,5 +121,9 @@ public: int one_beat_; }; +int moment_to_ticks (Moment); +Real moment_to_real (Moment); +Moment remap_grace_duration (Moment); + #endif // AUDIO_ITEM_HH diff --git a/lily/include/midi-item.hh b/lily/include/midi-item.hh index 6ec530f68c..b48049b952 100644 --- a/lily/include/midi-item.hh +++ b/lily/include/midi-item.hh @@ -47,9 +47,9 @@ public: class Midi_event { public: - Midi_event (Moment delta_mom, Midi_item *midi); + Midi_event (int delta, Midi_item *midi); - Moment delta_mom_; + int delta_ticks_; Midi_item *midi_; string to_string () const; }; @@ -134,7 +134,6 @@ public: Midi_note (Audio_note *); DECLARE_CLASSNAME(Midi_note); - Moment get_length () const; int get_pitch () const; int get_fine_tuning () const; virtual string to_string () const; @@ -225,7 +224,7 @@ public: Midi_track (); ~Midi_track (); - void add (Moment delta_time_mom, Midi_item *midi); + void add (int, Midi_item *midi); virtual string data_string () const; }; diff --git a/lily/include/midi-walker.hh b/lily/include/midi-walker.hh index 2d17efbc60..cb75744a92 100644 --- a/lily/include/midi-walker.hh +++ b/lily/include/midi-walker.hh @@ -12,7 +12,7 @@ #include "lily-proto.hh" #include "moment.hh" -struct Midi_note_event : PQueue_ent +struct Midi_note_event : PQueue_ent { bool ignore_b_; Midi_note_event (); @@ -36,16 +36,16 @@ public: private: void do_start_note (Midi_note *note); - void do_stop_notes (Moment now_mom); - void output_event (Moment now_mom, Midi_item *l); + void do_stop_notes (int); + void output_event (int, Midi_item *l); int channel_; Midi_track *track_; Audio_staff *staff_; vsize index_; - vector *items_; + vector items_; PQueue stop_note_queue; - Moment last_mom_; + int last_tick_; }; #endif // MIDI_WALKER_HH diff --git a/lily/midi-item.cc b/lily/midi-item.cc index 2f1aa5bce6..69916c74ce 100644 --- a/lily/midi-item.cc +++ b/lily/midi-item.cc @@ -90,21 +90,16 @@ Midi_duration::to_string () const return string (""; } -Midi_event::Midi_event (Moment delta_mom, Midi_item *midi) +Midi_event::Midi_event (int delta_ticks, Midi_item *midi) { - delta_mom_ = delta_mom; + delta_ticks_ = delta_ticks; midi_ = midi; } string Midi_event::to_string () const { - assert (delta_mom_.grace_part_ == Rational (0)); - - Rational rat_dt = delta_mom_.main_part_ * Rational (384) * Rational (4); - int delta = rat_dt.to_int (); - - string delta_string = Midi_item::i2varint_string (delta); + string delta_string = Midi_item::i2varint_string (delta_ticks_); string midi_string = midi_->to_string (); assert (midi_string.length ()); return delta_string + midi_string; @@ -246,12 +241,6 @@ Midi_note::Midi_note (Audio_note *a) dynamic_byte_ = 0x7f; } -Moment -Midi_note::get_length () const -{ - Moment m = audio_->end_column_->when () - audio_->audio_column_->when (); - return m; -} int Midi_note::get_fine_tuning () const @@ -460,11 +449,11 @@ Midi_track::Midi_track () } void -Midi_track::add (Moment delta_time_mom, Midi_item *midi) +Midi_track::add (int delta_ticks, Midi_item *midi) { - assert (delta_time_mom >= Moment (0)); + assert (delta_ticks >= 0); - Midi_event *e = new Midi_event (delta_time_mom, midi); + Midi_event *e = new Midi_event (delta_ticks, midi); events_.push_back (e); } diff --git a/lily/midi-walker.cc b/lily/midi-walker.cc index 20dfb45ef5..d87fb557a2 100644 --- a/lily/midi-walker.cc +++ b/lily/midi-walker.cc @@ -33,21 +33,27 @@ compare (Midi_note_event const &left, Midi_note_event const &right) return 0; } +bool +audio_item_less (Audio_item * const a, + Audio_item * const b) +{ + return a->get_column ()->when_ < b->get_column ()->when_; +} + Midi_walker::Midi_walker (Audio_staff *audio_staff, Midi_track *track, int channel) { channel_ = channel; track_ = track; index_ = 0; - items_ = &audio_staff->audio_items_; - - last_mom_ = 0; + items_ = audio_staff->audio_items_; + vector_sort (items_, audio_item_less); + last_tick_ = 0; } Midi_walker::~Midi_walker () { - // ugh - do_stop_notes (last_mom_ + Moment (Rational (10, 1))); + do_stop_notes (last_tick_ + 384); } /** @@ -56,8 +62,9 @@ Midi_walker::~Midi_walker () void Midi_walker::do_start_note (Midi_note *note) { - Audio_item *ptr = (*items_)[index_]; - Moment stop_mom = note->get_length () + ptr->audio_column_->when (); + Audio_item *ptr = items_[index_]; + int stop_ticks = int (moment_to_real (note->audio_->length_mom_) * Real (384 * 4)) + + ptr->audio_column_->ticks (); bool play_start = true; for (vsize i = 0; i < stop_note_queue.size (); i++) @@ -65,7 +72,7 @@ Midi_walker::do_start_note (Midi_note *note) /* if this pith already in queue */ if (stop_note_queue[i].val->get_pitch () == note->get_pitch ()) { - if (stop_note_queue[i].key < stop_mom) + if (stop_note_queue[i].key < stop_ticks) { /* let stopnote in queue be ignored, new stop note wins */ @@ -89,11 +96,11 @@ Midi_walker::do_start_note (Midi_note *note) { Midi_note_event e; e.val = new Midi_note_off (note); - e.key = stop_mom; + e.key = int (stop_ticks); stop_note_queue.insert (e); if (play_start) - output_event (ptr->audio_column_->when (), note); + output_event (ptr->audio_column_->ticks (), note); } } @@ -101,9 +108,9 @@ Midi_walker::do_start_note (Midi_note *note) Output note events for all notes which end before #max_mom# */ void -Midi_walker::do_stop_notes (Moment max_mom) +Midi_walker::do_stop_notes (int max_ticks) { - while (stop_note_queue.size () && stop_note_queue.front ().key <= max_mom) + while (stop_note_queue.size () && stop_note_queue.front ().key <= max_ticks) { Midi_note_event e = stop_note_queue.get (); if (e.ignore_b_) @@ -112,10 +119,10 @@ Midi_walker::do_stop_notes (Moment max_mom) continue; } - Moment stop_mom = e.key; + int stop_ticks = e.key; Midi_note *note = e.val; - output_event (stop_mom, note); + output_event (stop_ticks, note); } } @@ -123,26 +130,29 @@ Midi_walker::do_stop_notes (Moment max_mom) Advance the track to #now#, output the item, and adjust current "moment". */ void -Midi_walker::output_event (Moment now_mom, Midi_item *l) +Midi_walker::output_event (int now_ticks, Midi_item *l) { - Moment delta_t = now_mom - last_mom_; - last_mom_ = now_mom; + int delta_ticks = now_ticks - last_tick_; + last_tick_ = now_ticks; /* this is not correct, but at least it doesn't crash when you start with graces */ - if (delta_t < Moment (0)) - delta_t = Moment (0); + if (delta_ticks < 0) + { + programming_error ("Going back in MIDI time."); + delta_ticks = 0; + } - track_->add (delta_t, l); + track_->add (delta_ticks, l); } void Midi_walker::process () { - Audio_item *audio = (*items_)[index_]; - do_stop_notes (audio->audio_column_->when ()); + Audio_item *audio = items_[index_]; + do_stop_notes (audio->audio_column_->ticks ()); if (Midi_item *midi = Midi_item::get_midi (audio)) { @@ -152,18 +162,18 @@ Midi_walker::process () //midi->channel_ = track_->number_; if (Midi_note *note = dynamic_cast (midi)) { - if (note->get_length ().to_bool ()) + if (note->audio_->length_mom_.to_bool ()) do_start_note (note); } else - output_event (audio->audio_column_->when (), midi); + output_event (audio->audio_column_->ticks (), midi); } } bool Midi_walker::ok () const { - return index_ < items_->size (); + return index_ < items_.size (); } void diff --git a/lily/note-performer.cc b/lily/note-performer.cc index 8d9dfb44c1..b21d96935d 100644 --- a/lily/note-performer.cc +++ b/lily/note-performer.cc @@ -66,7 +66,14 @@ Note_performer::process_music () tie_event = ev; } - Audio_note *p = new Audio_note (*pitp, get_event_length (n), + Moment len = get_event_length (n); + if (now_mom().grace_part_) + { + len.grace_part_ = len.main_part_; + len.main_part_ = Rational (0); + } + + Audio_note *p = new Audio_note (*pitp, len, tie_event, - transposing); Audio_element_info info (p, n); announce_element (info); diff --git a/lily/performance.cc b/lily/performance.cc index 73a61767ce..c50c5a150d 100644 --- a/lily/performance.cc +++ b/lily/performance.cc @@ -38,11 +38,9 @@ Performance::output (Midi_stream &midi_stream) const { int tracks_ = audio_staffs_.size (); - // ugh - int clocks_per_4 = 384; - - midi_stream << Midi_header (1, tracks_, clocks_per_4); - message (_ ("Track...") + " "); + midi_stream << Midi_header (1, tracks_, 384); + if (be_verbose_global) + progress_indication (_ ("Track...") + " "); int channel = 0; for (vsize i = 0; i < audio_staffs_.size (); i++) @@ -107,21 +105,7 @@ Performance::write_output (string out) const } -void -Performance::remap_grace_durations () -{ - for (vsize i = 0; i < audio_elements_.size (); i++) - { - if (Audio_column * col = dynamic_cast (audio_elements_[i])) - { - col->when_.main_part_ = col->when_.main_part_ + Rational (1,4) * col->when_.grace_part_; - col->when_.grace_part_ = Rational (0); - } - } -} - void Performance::process () { - remap_grace_durations (); }