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

Reply via email to