Quoting Janek Warcho? <[email protected]>:
As for the patches themselves, are you using Git? It would be slightly more convenient for us if you sent us "Git-formatted" patches (i.e. patches representing complete git commits), [...]
Here are the Git-formatted patches. -- Heikki Tauriainen
>From b50ccdc9e06acc1bd8a909e06f83b88fbf8cbc86 Mon Sep 17 00:00:00 2001 From: Heikki Tauriainen <[email protected]> Date: Sat, 21 Sep 2013 23:17:55 +0300 Subject: [PATCH 1/4] Fix definition of default MIDI instrument in performer-init.ly --- ly/performer-init.ly | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ly/performer-init.ly b/ly/performer-init.ly index 816bb2f..9fb4dff 100644 --- a/ly/performer-init.ly +++ b/ly/performer-init.ly @@ -193,7 +193,7 @@ \name Score melismaBusyProperties = #default-melisma-properties - instrumentName = #"bright acoustic" + midiInstrument = #"bright acoustic" midiChannelMapping = #'staff %% quarter = 60 -- 1.8.4.rc3
>From 10f023acfc259957586635dd06bc2c02fd491783 Mon Sep 17 00:00:00 2001 From: Heikki Tauriainen <[email protected]> Date: Sat, 21 Sep 2013 23:18:28 +0300 Subject: [PATCH 2/4] New data types for controlling pan position, reverb and chorus levels --- lily/audio-item.cc | 19 ++++++++++++++ lily/include/audio-item.hh | 26 +++++++++++++++++++ lily/include/lily-proto.hh | 8 ++++++ lily/include/midi-item.hh | 39 +++++++++++++++++++++++++++++ lily/midi-item.cc | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 154 insertions(+) diff --git a/lily/audio-item.cc b/lily/audio-item.cc index b7a5ef2..d7cbced 100644 --- a/lily/audio-item.cc +++ b/lily/audio-item.cc @@ -204,3 +204,22 @@ Audio_text::Audio_text (Audio_text::Type type, const string &text_string) type_ = type; } +Audio_controller_value_change::Audio_controller_value_change (int value) + : value_ (value) +{ +} + +Audio_pan_position::Audio_pan_position (int position) + : Audio_controller_value_change (position) +{ +} + +Audio_reverb_level::Audio_reverb_level (int level) + : Audio_controller_value_change (level) +{ +} + +Audio_chorus_level::Audio_chorus_level (int level) + : Audio_controller_value_change (level) +{ +} diff --git a/lily/include/audio-item.hh b/lily/include/audio-item.hh index 544dd83..ed594f9 100644 --- a/lily/include/audio-item.hh +++ b/lily/include/audio-item.hh @@ -137,6 +137,32 @@ public: int one_beat_; }; +class Audio_controller_value_change : public Audio_item +{ +public: + Audio_controller_value_change (int value); + + int value_; +}; + +class Audio_pan_position : public Audio_controller_value_change +{ +public: + Audio_pan_position (int position); +}; + +class Audio_reverb_level : public Audio_controller_value_change +{ +public: + Audio_reverb_level (int level); +}; + +class Audio_chorus_level : public Audio_controller_value_change +{ +public: + Audio_chorus_level (int level); +}; + int moment_to_ticks (Moment); Real moment_to_real (Moment); Moment remap_grace_duration (Moment); diff --git a/lily/include/lily-proto.hh b/lily/include/lily-proto.hh index 53e863c..8873677 100644 --- a/lily/include/lily-proto.hh +++ b/lily/include/lily-proto.hh @@ -23,14 +23,18 @@ #include "flower-proto.hh" class All_font_metrics; +class Audio_chorus_level; class Audio_column; +class Audio_controller_value_change; class Audio_dynamic; class Audio_element; class Audio_instrument; class Audio_item; class Audio_key; class Audio_note; +class Audio_pan_position; class Audio_piano_pedal; +class Audio_reverb_level; class Audio_staff; class Audio_tempo; class Audio_text; @@ -103,7 +107,9 @@ class Lyric_engraver; class Lyric_performer; class Lyric_phrasing_engraver; class Mensural_ligature_engraver; +class Midi_chorus_level; class Midi_chunk; +class Midi_controller_value_change; class Midi_duration; class Midi_dynamic; class Midi_event; @@ -114,7 +120,9 @@ class Midi_key; class Midi_note; class Midi_note_event; class Midi_note_off; +class Midi_pan_position; class Midi_piano_pedal; +class Midi_reverb_level; class Midi_stream; class Midi_tempo; class Midi_text; diff --git a/lily/include/midi-item.hh b/lily/include/midi-item.hh index c5a9cc9..89396dc 100644 --- a/lily/include/midi-item.hh +++ b/lily/include/midi-item.hh @@ -46,11 +46,23 @@ public: class Midi_channel_item : public Midi_item { public: + virtual ~Midi_channel_item (); int channel_; DECLARE_CLASSNAME (Midi_channel_item); Midi_channel_item (Audio_item *ai); }; +class Midi_controller_value_change : public Midi_channel_item +{ +public: + DECLARE_CLASSNAME (Midi_controller_value_change); + Midi_controller_value_change (Audio_controller_value_change *ai); + virtual ~Midi_controller_value_change (); + virtual int get_controller_number () const = 0; + virtual string to_string () const; + int value_; +}; + class Midi_duration : public Midi_item { public: @@ -175,4 +187,31 @@ public: Audio_tempo *audio_; }; +class Midi_pan_position : public Midi_controller_value_change +{ +public: + Midi_pan_position (Audio_pan_position *); + DECLARE_CLASSNAME (Midi_pan_position); + + virtual int get_controller_number () const; +}; + +class Midi_reverb_level : public Midi_controller_value_change +{ +public: + Midi_reverb_level (Audio_reverb_level *); + DECLARE_CLASSNAME (Midi_reverb_level); + + virtual int get_controller_number () const; +}; + +class Midi_chorus_level : public Midi_controller_value_change +{ +public: + Midi_chorus_level (Audio_chorus_level *); + DECLARE_CLASSNAME (Midi_chorus_level); + + virtual int get_controller_number () const; +}; + #endif // MIDI_ITEM_HH diff --git a/lily/midi-item.cc b/lily/midi-item.cc index 0d0edbb..c6bd6a4 100644 --- a/lily/midi-item.cc +++ b/lily/midi-item.cc @@ -50,6 +50,12 @@ Midi_item::get_midi (Audio_item *a) return new Midi_time_signature (i); else if (Audio_text *i = dynamic_cast<Audio_text *> (a)) return new Midi_text (i); + else if (Audio_pan_position *i = dynamic_cast<Audio_pan_position *> (a)) + return new Midi_pan_position (i); + else if (Audio_reverb_level *i = dynamic_cast<Audio_reverb_level *> (a)) + return new Midi_reverb_level (i); + else if (Audio_chorus_level *i = dynamic_cast<Audio_chorus_level *> (a)) + return new Midi_chorus_level (i); else assert (0); @@ -102,10 +108,23 @@ Midi_channel_item::Midi_channel_item (Audio_item *ai) { } +Midi_controller_value_change::Midi_controller_value_change (Audio_controller_value_change *ai) + : Midi_channel_item (ai), value_ (ai->value_) +{ +} + Midi_item::~Midi_item () { } +Midi_channel_item::~Midi_channel_item () +{ +} + +Midi_controller_value_change::~Midi_controller_value_change () +{ +} + string int2midi_varint_string (int i) { @@ -342,6 +361,49 @@ Midi_text::to_string () const return str; } +string +Midi_controller_value_change::to_string () const +{ + Byte status_byte = (char) (0xB0 + channel_); + string str = ::to_string ((char)status_byte); + str += ::to_string ((char)get_controller_number ()); + str += ::to_string ((char)value_); + return str; +} + +Midi_pan_position::Midi_pan_position (Audio_pan_position *a) + : Midi_controller_value_change (a) +{ +} + +int +Midi_pan_position::get_controller_number () const +{ + return 10; +} + +Midi_reverb_level::Midi_reverb_level (Audio_reverb_level *a) + : Midi_controller_value_change (a) +{ +} + +int +Midi_reverb_level::get_controller_number () const +{ + return 91; +} + +Midi_chorus_level::Midi_chorus_level (Audio_chorus_level *a) + : Midi_controller_value_change (a) +{ +} + +int +Midi_chorus_level::get_controller_number () const +{ + return 93; +} + char const * Midi_item::name () const { -- 1.8.4.rc3
>From 717647db9412c7c8c6ab37acc9194b7603253d2e Mon Sep 17 00:00:00 2001 From: Heikki Tauriainen <[email protected]> Date: Sat, 21 Sep 2013 23:18:54 +0300 Subject: [PATCH 3/4] Allow customizing implementations of Translator::connect_to_context and Translator::disconnect_from_context --- lily/include/translator.hh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lily/include/translator.hh b/lily/include/translator.hh index 41e2d97..be6781e 100644 --- a/lily/include/translator.hh +++ b/lily/include/translator.hh @@ -136,9 +136,8 @@ public: virtual void initialize (); virtual void finalize (); - /* should maybe be virtual */ - void connect_to_context (Context *c); - void disconnect_from_context (Context *c); + virtual void connect_to_context (Context *c); + virtual void disconnect_from_context (Context *c); void stop_translation_timestep (); void start_translation_timestep (); -- 1.8.4.rc3
>From 7e2690ebb69eeb16720a8322c46410d16939d45f Mon Sep 17 00:00:00 2001 From: Heikki Tauriainen <[email protected]> Date: Sat, 21 Sep 2013 23:20:33 +0300 Subject: [PATCH 4/4] Add support for setting MIDI pan position, and reverb and chorus levels --- lily/midi-effect-performer.cc | 139 ++++++++++++++++++++++++++++++++++++++ lily/staff-performer.cc | 75 ++++++++++++++++++++ ly/performer-init.ly | 7 ++ scm/define-context-properties.scm | 12 ++++ 4 files changed, 233 insertions(+) create mode 100644 lily/midi-effect-performer.cc diff --git a/lily/midi-effect-performer.cc b/lily/midi-effect-performer.cc new file mode 100644 index 0000000..8abc78a --- /dev/null +++ b/lily/midi-effect-performer.cc @@ -0,0 +1,139 @@ +/* + This file is part of LilyPond, the GNU music typesetter. + + Copyright (C) 2013 by Heikki Tauriainen <[email protected]>. + Adapted from performer implementations + Copyright (C) 1996--2012 Jan Nieuwenhuizen <[email protected]>, + Han-Wen Nienhyus <[email protected]> and others. + + LilyPond is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + LilyPond is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with LilyPond. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "performer.hh" + +#include "audio-item.hh" +#include "context.hh" +#include "dispatcher.hh" +#include "international.hh" +#include "listener.hh" +#include "stream-event.hh" + +#include "translator.icc" + +class Midi_effect_performer : public Performer +{ +public: + TRANSLATOR_DECLARATIONS (Midi_effect_performer); + DECLARE_LISTENER (apply_effect); + ~Midi_effect_performer (); + + void connect_to_context (Context *c); + void disconnect_from_context (Context *c); + + void stop_translation_timestep (); + +private: + template<typename T> + void announce_audio_item (T *&target, Stream_event *ev); + + Audio_pan_position *pan_position_; + Audio_reverb_level *reverb_level_; + Audio_chorus_level *chorus_level_; +}; + +Midi_effect_performer::Midi_effect_performer () + : pan_position_ (0), + reverb_level_ (0), + chorus_level_ (0) +{ +} + +Midi_effect_performer::~Midi_effect_performer () +{ +} + +void +Midi_effect_performer::connect_to_context (Context *c) +{ + c->events_below ()->add_listener (GET_LISTENER (apply_effect), + ly_symbol2scm ("SetProperty")); +} + +void +Midi_effect_performer::disconnect_from_context (Context *c) +{ + c->events_below ()->remove_listener (GET_LISTENER (apply_effect), + ly_symbol2scm ("SetProperty")); +} + +void +Midi_effect_performer::stop_translation_timestep () +{ + pan_position_ = 0; + reverb_level_ = 0; + chorus_level_ = 0; +} + +IMPLEMENT_LISTENER (Midi_effect_performer, apply_effect) +void +Midi_effect_performer::apply_effect (SCM sev) +{ + Stream_event *ev = unsmob_stream_event (sev); + SCM sym = ev->get_property ("symbol"); + if (scm_is_symbol (sym)) + { + string symbol = ly_symbol2string (sym); + if (symbol == "midiPanPosition") + announce_audio_item (pan_position_, ev); + else if (symbol == "midiReverbLevel") + announce_audio_item (reverb_level_, ev); + else if (symbol == "midiChorusLevel") + announce_audio_item (chorus_level_, ev); + } +} + +template<typename T> +void +Midi_effect_performer::announce_audio_item (T *&target, + Stream_event *ev) +{ + SCM value = ev->get_property ("value"); + if (scm_is_number (value)) + { + int val = scm_to_int (value); + if (val >= 0 && val <= 127) + { + target = new T (val); + announce_element (Audio_element_info (target, 0)); + } + else + ev->origin ()->warning (_ ("value out of range, setting not changed")); + } +} + +ADD_TRANSLATOR (Midi_effect_performer, + /* doc */ + "", + + /* create */ + "", + + /* read */ + "midiPanPosition " + "midiReverbLevel " + "midiChorusLevel ", + + /* write */ + "" + ); diff --git a/lily/staff-performer.cc b/lily/staff-performer.cc index c06ad9b..1abba88 100644 --- a/lily/staff-performer.cc +++ b/lily/staff-performer.cc @@ -48,9 +48,15 @@ private: string new_instrument_string (); void set_instrument_name (const string &voice); void set_instrument (int channel, const string &voice); + bool register_controller_value_change (int new_value, + map<int, int> &value_map); int get_channel (const string &instrument); Audio_staff *get_audio_staff (const string &voice); Audio_staff *new_audio_staff (const string &voice); + template<typename T> + void set_controller_for_new_staff (Audio_staff *audio_staff, + const char *property, + map<int, int> &value_map); Audio_dynamic *get_dynamic (const string &voice); string instrument_string_; @@ -59,6 +65,9 @@ private: Audio_text *instrument_name_; Audio_text *name_; Audio_tempo *tempo_; + map<int, int> pan_position_per_channel_; + map<int, int> reverb_level_per_channel_; + map<int, int> chorus_level_per_channel_; map<string, deque<Audio_note *> > note_map_; map<string, Audio_staff *> staff_map_; map<string, int> channel_map_; @@ -128,9 +137,36 @@ Staff_performer::new_audio_staff (const string &voice) staff_map_[voice] = audio_staff; if (!instrument_string_.empty ()) set_instrument (channel_, voice); + set_controller_for_new_staff<Audio_pan_position> (audio_staff, + "midiPanPosition", + pan_position_per_channel_); + set_controller_for_new_staff<Audio_reverb_level> (audio_staff, + "midiReverbLevel", + reverb_level_per_channel_); + set_controller_for_new_staff<Audio_chorus_level> (audio_staff, + "midiChorusLevel", + chorus_level_per_channel_); return audio_staff; } +template<typename T> +void +Staff_performer::set_controller_for_new_staff (Audio_staff *audio_staff, + const char *property, + map<int, int> &value_map) +{ + SCM value = get_property (property); + if (scm_is_integer (value)) + { + int val = scm_to_int (value); + Audio_controller_value_change *item = new T (val); + item->channel_ = channel_; + register_controller_value_change (val, value_map); + audio_staff->add_audio_item (item); + announce_element (Audio_element_info (item, 0)); + } +} + Audio_staff * Staff_performer::get_audio_staff (const string &voice) { @@ -187,6 +223,21 @@ Staff_performer::set_instrument_name (const string &voice) get_audio_staff (voice)->add_audio_item (instrument_name_); } +bool +Staff_performer::register_controller_value_change (int new_value, + map<int, int> &value_map) +{ + pair<map<int, int>::iterator, bool> ins + = value_map.insert (make_pair (channel_, new_value)); + int &value = ins.first->second; + if (!ins.second && new_value == value) + { + return false; + } + value = new_value; + return true; +} + void Staff_performer::stop_translation_timestep () { @@ -215,6 +266,9 @@ Staff_performer::stop_translation_timestep () void Staff_performer::finalize () { + pan_position_per_channel_.clear (); + reverb_level_per_channel_.clear (); + chorus_level_per_channel_.clear (); staff_map_.clear (); channel_map_.clear (); if (staff_performer_count_) @@ -322,6 +376,27 @@ Staff_performer::acknowledge_audio_element (Audio_element_info inf) d->silent_ = true; } } + if (Audio_pan_position *p + = dynamic_cast<Audio_pan_position *>(inf.elem_)) + { + if (!register_controller_value_change (p->value_, + pan_position_per_channel_)) + return; + } + if (Audio_reverb_level *l + = dynamic_cast<Audio_reverb_level *>(inf.elem_)) + { + if (!register_controller_value_change (l->value_, + reverb_level_per_channel_)) + return; + } + if (Audio_chorus_level *l + = dynamic_cast<Audio_chorus_level *>(inf.elem_)) + { + if (!register_controller_value_change (l->value_, + chorus_level_per_channel_)) + return; + } Audio_staff *audio_staff = get_audio_staff (voice); audio_staff->add_audio_item (ai); } diff --git a/ly/performer-init.ly b/ly/performer-init.ly index 9fb4dff..3595473 100644 --- a/ly/performer-init.ly +++ b/ly/performer-init.ly @@ -30,6 +30,7 @@ \consists "Staff_performer" \consists "Key_performer" + \consists "Midi_effect_performer" } \context { @@ -48,6 +49,7 @@ \alias Staff \consists "Staff_performer" \consists "Key_performer" + \consists "Midi_effect_performer" } \context { @@ -59,6 +61,7 @@ \defaultchild VaticanaVoice \consists "Staff_performer" \consists "Key_performer" + \consists "Midi_effect_performer" } \context { @@ -70,6 +73,7 @@ \alias Staff \consists "Staff_performer" \consists "Key_performer" + \consists "Midi_effect_performer" } \context { @@ -195,6 +199,9 @@ melismaBusyProperties = #default-melisma-properties midiInstrument = #"bright acoustic" midiChannelMapping = #'staff + midiPanPosition = #64 + midiReverbLevel = #64 + midiChorusLevel = #64 %% quarter = 60 tempoWholesPerMinute = #(ly:make-moment 15/1) diff --git a/scm/define-context-properties.scm b/scm/define-context-properties.scm index 1cbd9fb..2ff9d74 100644 --- a/scm/define-context-properties.scm +++ b/scm/define-context-properties.scm @@ -433,6 +433,18 @@ event when notes with the same pitch, in the same MIDI-file track, overlap.") (midiMinimumVolume ,number? "Set the minimum loudness for MIDI. Ranges from 0 to@tie{}1.") (midiChannelMapping ,symbol? "How to map MIDI channels: per @code{instrument} (default), @code{staff} or @code{voice}.") + (midiPanPosition ,integer? "Pan position for the MIDI channel +associated with the current context (where the MIDI channel depends on +midiChannelMapping). Ranges from 0 to@tie{}127 (0=hard +left,@tie{}64=center,@tie{}127=hard right).") + (midiReverbLevel ,integer? "Reverb effect level for the MIDI channel +associated with the current context (where the MIDI channel depends on +midiChannelMapping). Ranges from 0 to@tie{}127 (0=off,@tie{}127=full +effect).") + (midiChorusLevel ,integer? "Chorus effect level for the MIDI channel +associated with the current context (where the MIDI channel depends on +midiChannelMapping). Ranges from 0 to@tie{}127 (0=off,@tie{}127=full +effect).") (minimumFret ,number? "The tablature auto string-selecting mechanism selects the highest string with a fret at least @code{minimumFret}.") -- 1.8.4.rc3
_______________________________________________ lilypond-devel mailing list [email protected] https://lists.gnu.org/mailman/listinfo/lilypond-devel
