Michael Welsh Duggan <[EMAIL PROTECTED]> writes: > Mats Bengtsson <[EMAIL PROTECTED]> writes: > >> Michael Welsh Duggan wrote: >>> In the following fragment: >>> << e1 \\ { c4 d e f } >> >>> When played by a pianist (which I should emphasize, I am not), the >>> e4 >>> should interrupt the e1 so that it sounds like: >>> << e2 \\ { c4 d e f } >> >>> What the midi output currently does is this: >>> << e1 \\ { c4 d s f } >> >>> I would like to change Midi_walker::do_start_note to do the former >>> (fairly easy). The question is, should there be an option to do the >>> latter? >> >> Probably! Imagine, for example, that you are typesetting an >> orchestral piece and this particular music is played by two >> flutes, for example. It's common to typeset two flute parts on >> a common stave in a printed score and because of the limitation to >> 16 channels in MIDI, you will typically keep them in the same >> stave also in the LilyPond \score{} for the MIDI output (each >> Staff context is translated into a MIDI channel, by default). > > How about a patch like the following? (Untested. I can't test until > I get home.) There are some things that could be moved around, but > this should provide a general idea. >
Now that I have had a chance to go home and do some testing, I have the following patch. Some things could probably be cleaned up, and I welcome comments and criticisms. Here is an example score which demonstrates the change: \score{ \notes << e'1 \\ { c'4 c' e' f' } >> \midi { \context { \StaffContext midiSimultaneousInterrupt = ##t } } } And here is the patch: Index: lily/audio-staff.cc =================================================================== RCS file: /cvsroot/lilypond/lilypond/lily/audio-staff.cc,v retrieving revision 1.19 diff -u -p -u -p -r1.19 audio-staff.cc --- lily/audio-staff.cc 5 Feb 2004 14:55:17 -0000 1.19 +++ lily/audio-staff.cc 20 Apr 2004 03:46:51 -0000 @@ -12,6 +12,17 @@ #include "midi-stream.hh" #include "midi-walker.hh" +Audio_staff::Audio_staff (const Performer *performer) +{ + performer_ = performer; +} + +SCM +Audio_staff::internal_get_property (SCM sym) const +{ + return performer_->internal_get_property (sym); +} + void Audio_staff::add_audio_item (Audio_item* l) { Index: lily/midi-item.cc =================================================================== RCS file: /cvsroot/lilypond/lilypond/lily/midi-item.cc,v retrieving revision 1.75 diff -u -p -u -p -r1.75 midi-item.cc --- lily/midi-item.cc 7 Apr 2004 13:40:30 -0000 1.75 +++ lily/midi-item.cc 20 Apr 2004 03:46:52 -0000 @@ -239,6 +239,12 @@ Midi_note::get_length () const return m; } +void +Midi_note::set_length (Moment m) +{ + audio_->length_mom_ = m; +} + int Midi_note::get_fine_tuning () const { Index: lily/midi-walker.cc =================================================================== RCS file: /cvsroot/lilypond/lilypond/lily/midi-walker.cc,v retrieving revision 1.43 diff -u -p -u -p -r1.43 midi-walker.cc --- lily/midi-walker.cc 8 Mar 2004 16:17:40 -0000 1.43 +++ lily/midi-walker.cc 20 Apr 2004 03:46:52 -0000 @@ -38,6 +38,7 @@ Midi_walker::Midi_walker (Audio_staff* a track_ = track; index_= 0; items_ = &audio_staff->audio_items_; + staff_ = audio_staff; last_mom_ = 0; } @@ -60,13 +61,44 @@ Midi_walker::do_start_note (Midi_note* n bool play_start = true; for (int i=0; i < stop_note_queue.size (); i++) { - /* if this pith already in queue */ + /* if this pitch already in queue */ if (stop_note_queue[i].val->get_pitch () == note->get_pitch ()) { - if (stop_note_queue[i].key < stop_mom) + /* If the two notes do not start simultanously, but + intersect, and midiSimultaneousInterrupt is set, then the + later note should interrupt the first. */ + if ((note->audio_->audio_column_->at_mom () + != stop_note_queue[i].val->audio_->audio_column_->at_mom ()) + && ly_scm2bool (staff_->internal_get_property + (ly_symbol2scm ("midiSimultaneousInterrupt")))) + { + /* Simultanous notes are handled by interruption */ + if (stop_note_queue[i].key > ptr->audio_column_->at_mom ()) + { + /* Change length of original note */ + Moment new_length = stop_note_queue[i].val->get_length () - + (stop_note_queue[i].key - + ptr->audio_column_->at_mom ()); + if (new_length == 0) + { + /* simultaneous notes. + don't play the start note */ + delete note; + note = 0; + break; + } + + stop_note_queue[i].val->set_length (new_length); + /* stop here instead */ + output_event (ptr->audio_column_->at_mom (), + stop_note_queue[i].val); + break; + } + } + else if (stop_note_queue[i].key < stop_mom) { /* let stopnote in queue be ignored, - new stop note wins */ + new stop note wins */ stop_note_queue[i].ignore_b_ = true; /* don't replay start note, */ play_start = false; Index: lily/staff-performer.cc =================================================================== RCS file: /cvsroot/lilypond/lilypond/lily/staff-performer.cc,v retrieving revision 1.61 diff -u -p -u -p -r1.61 staff-performer.cc --- lily/staff-performer.cc 12 Apr 2004 14:52:21 -0000 1.61 +++ lily/staff-performer.cc 20 Apr 2004 03:46:52 -0000 @@ -62,7 +62,7 @@ Staff_performer::~Staff_performer () void Staff_performer::initialize () { - audio_staff_ = new Audio_staff; + audio_staff_ = new Audio_staff (this); announce_element (Audio_element_info (audio_staff_, 0)); name_ = new Audio_text (Audio_text::TRACK_NAME, context ()->id_string ()); Index: lily/include/audio-staff.hh =================================================================== RCS file: /cvsroot/lilypond/lilypond/lily/include/audio-staff.hh,v retrieving revision 1.18 diff -u -p -u -p -r1.18 audio-staff.hh --- lily/include/audio-staff.hh 25 Mar 2004 01:45:15 -0000 1.18 +++ lily/include/audio-staff.hh 20 Apr 2004 03:46:52 -0000 @@ -9,15 +9,22 @@ #include "parray.hh" #include "lily-proto.hh" +#include "lily-guile.hh" #include "audio-element.hh" +#include "performer.hh" struct Audio_staff : public Audio_element { + Audio_staff (const Performer *performer); + + SCM internal_get_property (SCM sym) const; + void add_audio_item (Audio_item* l); void output (Midi_stream& midi_stream_r, int track_i); Link_array<Audio_item> audio_items_; int channel_; + const Performer *performer_; }; #endif // AUDIO_STAFF_HH Index: lily/include/midi-item.hh =================================================================== RCS file: /cvsroot/lilypond/lilypond/lily/include/midi-item.hh,v retrieving revision 1.34 diff -u -p -u -p -r1.34 midi-item.hh --- lily/include/midi-item.hh 5 Feb 2004 14:55:37 -0000 1.34 +++ lily/include/midi-item.hh 20 Apr 2004 03:46:52 -0000 @@ -122,6 +122,7 @@ public: Midi_note (Audio_note*); Moment get_length () const; + void set_length (Moment m); int get_pitch () const; int get_fine_tuning () const; virtual String to_string () const; Index: ly/performer-init.ly =================================================================== RCS file: /cvsroot/lilypond/lilypond/ly/performer-init.ly,v retrieving revision 1.41 diff -u -p -u -p -r1.41 performer-init.ly --- ly/performer-init.ly 11 Apr 2004 15:54:45 -0000 1.41 +++ ly/performer-init.ly 20 Apr 2004 03:46:52 -0000 @@ -109,6 +109,7 @@ dynamicAbsoluteVolumeFunction = #default-dynamic-absolute-volume instrumentEqualizer = #default-instrument-equalizer drumPitchTable = #(alist->hash-table midiDrumPitches) + midiSimultaneousInterrupt = ##f } -- Michael Welsh Duggan ([EMAIL PROTECTED]) _______________________________________________ Lilypond-user mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/lilypond-user