From: Jan Nieuwenhuizen Date: Thu, 3 Mar 2011 15:40:06 +0000 (+0100) Subject: Map voices to channels in MIDI output. X-Git-Tag: release/2.13.53-1~26 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=e5380f29f23e204a603f8398368d2a7dc0260aa0;p=lilypond.git Map voices to channels in MIDI output. This fixes a long standing weirdness in MIDI output, with voices being all merged into one channel with channel number equalling track number. With voices mapped to channels, midi2ly can neatly recreate voices without needing to do tricky guessing. --- diff --git a/lily/audio-item.cc b/lily/audio-item.cc index 0ed413bf67..8459aa8c54 100644 --- a/lily/audio-item.cc +++ b/lily/audio-item.cc @@ -39,8 +39,9 @@ Audio_item::get_column () const } Audio_item::Audio_item () + : audio_column_ (0) + , channel_ (0) { - audio_column_ = 0; } Audio_note::Audio_note (Pitch p, Moment m, bool tie_event, Pitch transposing) diff --git a/lily/audio-staff.cc b/lily/audio-staff.cc index 3ca1910abc..b827b8b377 100644 --- a/lily/audio-staff.cc +++ b/lily/audio-staff.cc @@ -24,23 +24,23 @@ #include "midi-walker.hh" void -Audio_staff::add_audio_item (Audio_item *l) +Audio_staff::add_audio_item (Audio_item *ai) { - audio_items_.push_back (l); + audio_items_.push_back (ai); } Audio_staff::Audio_staff () + : percussion_ (false) { - channel_ = -1; } void -Audio_staff::output (Midi_stream &midi_stream, int channel) +Audio_staff::output (Midi_stream &midi_stream, int track) { Midi_track midi_track; - midi_track.number_ = channel; + midi_track.number_ = track; - Midi_walker i (this, &midi_track, channel); + Midi_walker i (this, &midi_track); for (; i.ok (); i++) i.process (); diff --git a/lily/include/audio-item.hh b/lily/include/audio-item.hh index 6bf0cb4a6a..525544dc1d 100644 --- a/lily/include/audio-item.hh +++ b/lily/include/audio-item.hh @@ -27,8 +27,10 @@ class Audio_item : public Audio_element { public: - Audio_item (); Audio_column *audio_column_; + int channel_; + + Audio_item (); Audio_column *get_column () const; virtual void render (); diff --git a/lily/include/audio-staff.hh b/lily/include/audio-staff.hh index 47a58177b4..a76854ddb1 100644 --- a/lily/include/audio-staff.hh +++ b/lily/include/audio-staff.hh @@ -26,13 +26,13 @@ struct Audio_staff : public Audio_element { - void add_audio_item (Audio_item *l); + void add_audio_item (Audio_item *ai); void output (Midi_stream &midi_stream_r, int track); Audio_staff (); + bool percussion_; vector audio_items_; - int channel_; }; #endif // AUDIO_STAFF_HH diff --git a/lily/include/midi-item.hh b/lily/include/midi-item.hh index f77f9c8507..cc59ed0abe 100644 --- a/lily/include/midi-item.hh +++ b/lily/include/midi-item.hh @@ -33,7 +33,7 @@ string int2midi_varint_string (int i); class Midi_item { public: - DECLARE_CLASSNAME(Midi_item); + DECLARE_CLASSNAME (Midi_item); Midi_item (); virtual ~Midi_item (); virtual char const *name () const; @@ -48,8 +48,8 @@ class Midi_channel_item : public Midi_item { public: int channel_; - DECLARE_CLASSNAME(Midi_channel_item); - Midi_channel_item (); + DECLARE_CLASSNAME (Midi_channel_item); + Midi_channel_item (Audio_item *ai); }; class Midi_duration : public Midi_item @@ -70,7 +70,7 @@ class Midi_instrument : public Midi_channel_item public: Midi_instrument (Audio_instrument *); - DECLARE_CLASSNAME(Midi_instrument); + DECLARE_CLASSNAME (Midi_instrument); virtual string to_string () const; Audio_instrument *audio_; @@ -80,7 +80,7 @@ class Midi_key : public Midi_item { public: Midi_key (Audio_key *); - DECLARE_CLASSNAME(Midi_key); + DECLARE_CLASSNAME (Midi_key); virtual string to_string () const; @@ -91,7 +91,7 @@ class Midi_time_signature : public Midi_item { public: Midi_time_signature (Audio_time_signature *); - DECLARE_CLASSNAME(Midi_time_signature); + DECLARE_CLASSNAME (Midi_time_signature); virtual string to_string () const; @@ -103,7 +103,7 @@ class Midi_note : public Midi_channel_item { public: Midi_note (Audio_note *); - DECLARE_CLASSNAME(Midi_note); + DECLARE_CLASSNAME (Midi_note); int get_semitone_pitch () const; int get_fine_tuning () const; @@ -120,7 +120,7 @@ class Midi_note_off : public Midi_note { public: Midi_note_off (Midi_note *); - DECLARE_CLASSNAME(Midi_note_off); + DECLARE_CLASSNAME (Midi_note_off); virtual string to_string () const; @@ -136,7 +136,7 @@ public: TEXT = 1, COPYRIGHT, TRACK_NAME, INSTRUMENT_NAME, LYRIC, MARKER, CUE_POINT }; - DECLARE_CLASSNAME(Midi_text); + DECLARE_CLASSNAME (Midi_text); Midi_text (Audio_text *); @@ -149,7 +149,7 @@ class Midi_dynamic : public Midi_channel_item { public: Midi_dynamic (Audio_dynamic *); - DECLARE_CLASSNAME(Midi_dynamic); + DECLARE_CLASSNAME (Midi_dynamic); virtual string to_string () const; @@ -160,7 +160,7 @@ class Midi_piano_pedal : public Midi_channel_item { public: Midi_piano_pedal (Audio_piano_pedal *); - DECLARE_CLASSNAME(Midi_piano_pedal); + DECLARE_CLASSNAME (Midi_piano_pedal); virtual string to_string () const; @@ -171,13 +171,11 @@ class Midi_tempo : public Midi_item { public: Midi_tempo (Audio_tempo *); - DECLARE_CLASSNAME(Midi_tempo); + DECLARE_CLASSNAME (Midi_tempo); virtual string to_string () const; Audio_tempo *audio_; }; - - #endif // MIDI_ITEM_HH diff --git a/lily/include/midi-walker.hh b/lily/include/midi-walker.hh index 15f573cbac..4fd1ae39fc 100644 --- a/lily/include/midi-walker.hh +++ b/lily/include/midi-walker.hh @@ -39,22 +39,22 @@ int compare (Midi_note_event const &left, Midi_note_event const &right); class Midi_walker { public: - Midi_walker (Audio_staff *audio_staff, Midi_track *midi_track, - int channel); + Midi_walker (Audio_staff *audio_staff, Midi_track *midi_track); ~Midi_walker (); void process (); void operator ++ (int); bool ok () const; void finalize (); + private: void do_start_note (Midi_note *note); void do_stop_notes (int); void output_event (int, Midi_item *l); Midi_item *get_midi (Audio_item*); - int channel_; Midi_track *track_; Audio_staff *staff_; + bool percussion_; vsize index_; vector items_; PQueue stop_note_queue; diff --git a/lily/midi-item.cc b/lily/midi-item.cc index b3b064b67a..ab67947d55 100644 --- a/lily/midi-item.cc +++ b/lily/midi-item.cc @@ -72,8 +72,9 @@ Midi_duration::to_string () const } Midi_instrument::Midi_instrument (Audio_instrument *a) + : Midi_channel_item (a) + , audio_ (a) { - audio_ = a; audio_->str_ = String_convert::to_lower (audio_->str_); } @@ -100,9 +101,9 @@ Midi_item::Midi_item () { } -Midi_channel_item::Midi_channel_item () +Midi_channel_item::Midi_channel_item (Audio_item *ai) + : channel_ (ai->channel_) { - channel_ = 0; } Midi_item::~Midi_item () @@ -133,8 +134,8 @@ int2midi_varint_string (int i) } Midi_key::Midi_key (Audio_key *a) + : audio_ (a) { - audio_ = a; } string @@ -150,9 +151,9 @@ Midi_key::to_string () const } Midi_time_signature::Midi_time_signature (Audio_time_signature *a) + : audio_ (a) + , clocks_per_1_ (18) { - audio_ = a; - clocks_per_1_ = 18; } string @@ -178,12 +179,12 @@ Midi_time_signature::to_string () const } Midi_note::Midi_note (Audio_note *a) + : Midi_channel_item (a) + , audio_ (a) + , dynamic_byte_ (0x5a) { - audio_ = a; - dynamic_byte_ = 0x5a; } - int Midi_note::get_fine_tuning () const { @@ -262,8 +263,9 @@ Midi_note_off::to_string () const } Midi_dynamic::Midi_dynamic (Audio_dynamic *a) + : Midi_channel_item (a) + , audio_ (a) { - audio_ = a; } string @@ -291,8 +293,9 @@ Midi_dynamic::to_string () const } Midi_piano_pedal::Midi_piano_pedal (Audio_piano_pedal *a) + : Midi_channel_item (a) + , audio_ (a) { - audio_ = a; } string @@ -314,8 +317,8 @@ Midi_piano_pedal::to_string () const } Midi_tempo::Midi_tempo (Audio_tempo *a) + : audio_ (a) { - audio_ = a; } string @@ -328,8 +331,8 @@ Midi_tempo::to_string () const } Midi_text::Midi_text (Audio_text *a) + : audio_ (a) { - audio_ = a; } string diff --git a/lily/midi-walker.cc b/lily/midi-walker.cc index 6476220f7a..fdafd91b1d 100644 --- a/lily/midi-walker.cc +++ b/lily/midi-walker.cc @@ -52,15 +52,14 @@ audio_item_less (Audio_item * const a, return a->get_column ()->when_ < b->get_column ()->when_; } -Midi_walker::Midi_walker (Audio_staff *audio_staff, Midi_track *track, - int channel) +Midi_walker::Midi_walker (Audio_staff *audio_staff, Midi_track *track) { - channel_ = channel; track_ = track; index_ = 0; items_ = audio_staff->audio_items_; vector_sort (items_, audio_item_less); last_tick_ = 0; + percussion_ = audio_staff->percussion_; } Midi_walker::~Midi_walker () @@ -171,9 +170,6 @@ Midi_walker::process () if (Midi_item *midi = get_midi (audio)) { - if (Midi_channel_item *mci = dynamic_cast (midi)) - mci->channel_ = channel_; - if (Midi_note *note = dynamic_cast (midi)) { if (note->audio_->length_mom_.to_bool ()) @@ -188,6 +184,11 @@ Midi_item* Midi_walker::get_midi (Audio_item *i) { Midi_item *mi = Midi_item::get_midi (i); + + if (percussion_) + if (Midi_channel_item *mci = dynamic_cast (mi)) + mci->channel_ = 9; + midi_events_.push_back (mi); return mi; } diff --git a/lily/performance.cc b/lily/performance.cc index 33f6fb971e..b07c8604cf 100644 --- a/lily/performance.cc +++ b/lily/performance.cc @@ -53,44 +53,17 @@ Performance::output (Midi_stream &midi_stream) const if (be_verbose_global) progress_indication (_ ("Track...") + " "); - int channel = 0; for (vsize i = 0; i < audio_staffs_.size (); i++) { Audio_staff *s = audio_staffs_[i]; if (be_verbose_global) progress_indication ("[" + to_string (i)); - - int midi_channel = s->channel_; - - if (midi_channel < 0) - { - midi_channel = channel; - channel ++; - /* - MIDI players tend to ignore instrument settings on - channel 10, the percussion channel. - */ - if (channel % 16 == 9) - channel ++; - } - - /* - Huh? Why does each staff also have a separate channel? We - should map channels to voices, not staves. --hwn. - */ - if (midi_channel > 15) - { - warning (_ ("MIDI channel wrapped around")); - warning (_ ("remapping modulo 16")); - - midi_channel = midi_channel % 16; - } - - s->output (midi_stream, midi_channel); + s->output (midi_stream, i); if (be_verbose_global) progress_indication ("]"); } } + void Performance::add_element (Audio_element *p) { diff --git a/lily/staff-performer.cc b/lily/staff-performer.cc index daf00a1812..8d56541894 100644 --- a/lily/staff-performer.cc +++ b/lily/staff-performer.cc @@ -17,6 +17,8 @@ along with LilyPond. If not, see . */ +#include + #include "warn.hh" #include "audio-column.hh" #include "audio-item.hh" @@ -49,6 +51,7 @@ private: Audio_text *instrument_name_; Audio_text *name_; Audio_tempo *tempo_; + map channel_map_; }; #include "translator.icc" @@ -115,17 +118,13 @@ void Staff_performer::stop_translation_timestep () { SCM proc = ly_lily_module_constant ("percussion?"); - SCM drums = scm_call_1 (proc, ly_symbol2scm (instrument_string_.c_str ())); - audio_staff_->channel_ = (drums == SCM_BOOL_T ? 9 : -1); + audio_staff_->percussion_ = (drums == SCM_BOOL_T); + if (name_) - { name_ = 0; - } if (tempo_) - { tempo_ = 0; - } instrument_name_ = 0; instrument_ = 0; } @@ -155,6 +154,23 @@ void Staff_performer::acknowledge_audio_element (Audio_element_info inf) { if (Audio_item *ai = dynamic_cast (inf.elem_)) - audio_staff_->add_audio_item (ai); + { + /* map each context (voice) to its own channel */ + Context *c = inf.origin_contexts (this)[0]; + string id = c->id_string (); + int channel = channel_map_.size (); + /* MIDI players tend to ignore instrument settings on channel + 10, the percussion channel. */ + if (channel % 16 == 9) + channel_map_[""] = channel++; + + map::const_iterator i = channel_map_.find (id); + if (i != channel_map_.end ()) + channel = i->second; + else + channel_map_[id] = channel; + + audio_staff_->add_audio_item (ai); + } }