}
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)
#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 ();
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 ();
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_item*> audio_items_;
- int channel_;
};
#endif // AUDIO_STAFF_HH
class Midi_item
{
public:
- DECLARE_CLASSNAME(Midi_item);
+ DECLARE_CLASSNAME (Midi_item);
Midi_item ();
virtual ~Midi_item ();
virtual char const *name () const;
{
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
public:
Midi_instrument (Audio_instrument *);
- DECLARE_CLASSNAME(Midi_instrument);
+ DECLARE_CLASSNAME (Midi_instrument);
virtual string to_string () const;
Audio_instrument *audio_;
{
public:
Midi_key (Audio_key *);
- DECLARE_CLASSNAME(Midi_key);
+ DECLARE_CLASSNAME (Midi_key);
virtual string to_string () const;
{
public:
Midi_time_signature (Audio_time_signature *);
- DECLARE_CLASSNAME(Midi_time_signature);
+ DECLARE_CLASSNAME (Midi_time_signature);
virtual string to_string () const;
{
public:
Midi_note (Audio_note *);
- DECLARE_CLASSNAME(Midi_note);
+ DECLARE_CLASSNAME (Midi_note);
int get_semitone_pitch () const;
int get_fine_tuning () const;
{
public:
Midi_note_off (Midi_note *);
- DECLARE_CLASSNAME(Midi_note_off);
+ DECLARE_CLASSNAME (Midi_note_off);
virtual string to_string () const;
TEXT = 1, COPYRIGHT, TRACK_NAME, INSTRUMENT_NAME, LYRIC,
MARKER, CUE_POINT
};
- DECLARE_CLASSNAME(Midi_text);
+ DECLARE_CLASSNAME (Midi_text);
Midi_text (Audio_text *);
{
public:
Midi_dynamic (Audio_dynamic *);
- DECLARE_CLASSNAME(Midi_dynamic);
+ DECLARE_CLASSNAME (Midi_dynamic);
virtual string to_string () const;
{
public:
Midi_piano_pedal (Audio_piano_pedal *);
- DECLARE_CLASSNAME(Midi_piano_pedal);
+ DECLARE_CLASSNAME (Midi_piano_pedal);
virtual string to_string () const;
{
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
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<Audio_item*> items_;
PQueue<Midi_note_event> stop_note_queue;
}
Midi_instrument::Midi_instrument (Audio_instrument *a)
+ : Midi_channel_item (a)
+ , audio_ (a)
{
- audio_ = a;
audio_->str_ = String_convert::to_lower (audio_->str_);
}
{
}
-Midi_channel_item::Midi_channel_item ()
+Midi_channel_item::Midi_channel_item (Audio_item *ai)
+ : channel_ (ai->channel_)
{
- channel_ = 0;
}
Midi_item::~Midi_item ()
}
Midi_key::Midi_key (Audio_key *a)
+ : audio_ (a)
{
- audio_ = a;
}
string
}
Midi_time_signature::Midi_time_signature (Audio_time_signature *a)
+ : audio_ (a)
+ , clocks_per_1_ (18)
{
- audio_ = a;
- clocks_per_1_ = 18;
}
string
}
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
{
}
Midi_dynamic::Midi_dynamic (Audio_dynamic *a)
+ : Midi_channel_item (a)
+ , audio_ (a)
{
- audio_ = a;
}
string
}
Midi_piano_pedal::Midi_piano_pedal (Audio_piano_pedal *a)
+ : Midi_channel_item (a)
+ , audio_ (a)
{
- audio_ = a;
}
string
}
Midi_tempo::Midi_tempo (Audio_tempo *a)
+ : audio_ (a)
{
- audio_ = a;
}
string
}
Midi_text::Midi_text (Audio_text *a)
+ : audio_ (a)
{
- audio_ = a;
}
string
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 ()
if (Midi_item *midi = get_midi (audio))
{
- if (Midi_channel_item *mci = dynamic_cast<Midi_channel_item*> (midi))
- mci->channel_ = channel_;
-
if (Midi_note *note = dynamic_cast<Midi_note *> (midi))
{
if (note->audio_->length_mom_.to_bool ())
Midi_walker::get_midi (Audio_item *i)
{
Midi_item *mi = Midi_item::get_midi (i);
+
+ if (percussion_)
+ if (Midi_channel_item *mci = dynamic_cast<Midi_channel_item*> (mi))
+ mci->channel_ = 9;
+
midi_events_.push_back (mi);
return mi;
}
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)
{
along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <map>
+
#include "warn.hh"
#include "audio-column.hh"
#include "audio-item.hh"
Audio_text *instrument_name_;
Audio_text *name_;
Audio_tempo *tempo_;
+ map<string, int> channel_map_;
};
#include "translator.icc"
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;
}
Staff_performer::acknowledge_audio_element (Audio_element_info inf)
{
if (Audio_item *ai = dynamic_cast<Audio_item *> (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<string, int>::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);
+ }
}