// Rhythmic_req * note_req_l_;
// Melodic_req* current_l_;
-// Moment off_mom_;
+ Moment off_mom_;
// Moment on_mom_;
};
virtual Translator* get_default_interpreter();
Translator * ancestor_l( int l = 1 );
- int depth_i() const;
+ virtual int depth_i() const;
- void process_requests();
+ virtual Moment get_mom() const;
+
+ virtual void midi_output( Midi_stream* midi_stream_l );
+ virtual void process_requests();
+ virtual void set_track( Midi_def* midi_l, int& track_i_r );
private:
Pointer_list<Performer*> perf_p_list_;
Performer();
virtual ~Performer();
+ virtual void midi_output( Midi_stream* midi_stream_l_ );
void print() const;
virtual void process_requests();
+
+ virtual void set( Moment mom );
+ virtual void set_track( Midi_def* midi_l, int& track_i_r );
+
virtual bool try_request( Request* req_l );
protected:
virtual void do_print() const;
+ virtual Moment get_mom() const;
virtual void play_event( Midi_item* l );
};
virtual Translator* ancestor_l( int l );
virtual int depth_i() const;
- virtual void play_event( Midi_item* l );
+ virtual void finish();
+ virtual Moment get_mom() const;
virtual void prepare( Moment mom );
virtual void process();
+ virtual void set_score( Score* score_l );
+ virtual void start();
private:
+ void header();
+
+ Midi_def* midi_l_;
Midi_stream* midi_stream_p_;
Moment prev_mom_;
Moment now_mom_;
String instrument_str();
protected:
+ virtual void midi_output( Midi_stream* midi_stream_l_ );
virtual void play_event( Midi_item* l );
+ virtual void set_track( Midi_def* midi_l, int& track_i_r );
private:
- int midi_track_i_;
+ void header();
+
+ Midi_def* midi_l_;
+ Moment midi_mom_;
+ int track_i_;
+ Midi_track* midi_track_p_;
};
#endif // STAFF_PERFORMER_HH
--- /dev/null
+/*
+ midi-walker.cc -- implement Midi_walker
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>, Jan Nieuwenhuizen <jan@digicash.com>
+
+ TODO
+
+ Ideally this should also use a register system, to process slurs,
+ dynamics, etc.
+
+*/
+
+/* reincluded for code jatting */
+#if 0
+
+#include "command-request.hh"
+#include "musical-request.hh"
+#include "p-score.hh"
+#include "staff.hh"
+#include "midi-walker.hh"
+#include "midi-item.hh"
+#include "midi-stream.hh"
+#include "debug.hh"
+#include "staff-column.hh"
+
+Midi_walker::Midi_walker(Staff *st_l, Midi_track* track_l)
+ : PCursor<Staff_column*>(st_l->cols_)
+{
+ track_l_ = track_l;
+ last_moment_= 0;
+}
+
+/**
+ output notestop events for all notes which end before #max_moment#
+ */
+void
+Midi_walker::do_stop_notes(Moment max_moment)
+{
+ while (stop_notes.size() && stop_notes.front().key <= max_moment) {
+ Note_event ent=stop_notes.get();
+ if (ent.ignore_b_)
+ continue;
+
+ Moment stop_moment = ent.key;
+ Melodic_req * req_l = ent.val;
+
+ Midi_note note(req_l, track_l_->number_i_, false);
+ output_event(note, stop_moment);
+ }
+}
+/**
+ Find out if start_note event is needed, and do it if needed.
+ */
+void
+Midi_walker::do_start_note(Note_req*note_l)
+{
+ Moment stop = note_l->duration() + ptr()->when();
+ for(int i=0; i < stop_notes.size(); i++) {
+ if (stop_notes[i].val->melodic()->pitch() ==
+ note_l->pitch()) {
+ if ( stop_notes[i].key < stop){
+ stop_notes[i].ignore_b_=true;
+ }
+ else
+ return; // skip the stop note
+ }
+ }
+ Note_event e;
+ e.val = note_l;
+ e.key = stop;
+
+ stop_notes.insert(e);
+
+ Midi_note note(note_l, track_l_->number_i_, true);
+ output_event(note, ptr()->when());
+}
+
+
+/** advance the track to #now#, output the item, and adjust current
+ "moment". */
+void
+Midi_walker::output_event(Midi_item &i, Moment now)
+{
+ Moment delta_t = now - last_moment_ ;
+ last_moment_ += delta_t;
+ track_l_->add(delta_t, &i );
+}
+
+void
+Midi_walker::process_requests()
+{
+ do_stop_notes(ptr()->when());
+
+ for ( int i = 0; i < ptr()->commandreq_l_arr_.size(); i++ ) {
+ Command_req *c_l = ptr()->commandreq_l_arr_[i]->command();
+ Meter_change_req* meter_l = c_l->meterchange();
+ if ( meter_l )
+ output_event( Midi_time( meter_l->beats_i_, meter_l->one_beat_i_, 18 ), ptr()->when() );
+ Key_change_req* key_l = c_l->keychange();
+ if ( key_l ) {
+ int sharps_i = key_l->sharps_i();
+ int flats_i = key_l->flats_i();
+ // midi cannot handle non-conventional keys
+ if ( !( flats_i && sharps_i ) )
+ output_event( Midi_key( sharps_i - flats_i, key_l->minor_b() ), ptr()->when() );
+ }
+ }
+
+ for ( int i = 0; i < ptr()->musicalreq_l_arr_.size(); i++ ) {
+ Musical_req *m = ptr()->musicalreq_l_arr_[i]->musical();
+ if (!m)
+ return;
+ Rhythmic_req *n = m->rhythmic();
+ if ( !n)
+ continue;
+ Note_req * note_l = n->note();
+ if (!note_l)
+ continue;
+ do_start_note(note_l);
+ }
+}
+
+Midi_walker::~Midi_walker()
+{
+ do_stop_notes( last_moment_ + Moment(10,1)); // ugh
+}
+
+
+int
+compare(Note_event const&e1, Note_event const&e2)
+{
+ return sign(e1.key - e2.key);
+}
+
+#endif
/*
note-performer.cc -- implement Note_performer
- (c) 1996, 1997 Han-Wen Nienhuys <hanwen@stack.nl>
- Jan Nieuwenhuizen <jan@digicash.com>
+ (c) 1996, 1997 Jan Nieuwenhuizen <jan@digicash.com>
*/
#include "note-performer.hh"
Note_performer::Note_performer()
{
- // is this what we want?
- // or do we need to cache/keep note until it has ended?
note_req_l_ = 0;
+ off_mom_ = 0;
}
Note_performer::~Note_performer()
//Midi_note( Melodic_req* melreq_l, int channel_i, bool on_bo )
// this is _really_ braindead, but it generates some output
- if ( note_req_l_ && note_req_l_->melodic() ) {
- Midi_note n( note_req_l_->melodic(), 0, true );
+ if ( !note_req_l_ || !note_req_l_->melodic() || !note_req_l_->rhythmic() )
+ return;
+
+ // ugh, need to know channel (===track===staff) too
+ int channel_i = 0;
+ Moment mom = get_mom();
+ if ( !off_mom_ ) { // start note
+ off_mom_ = mom + note_req_l_->duration();
+ Midi_note n( note_req_l_->melodic(), channel_i, true );
play_event( &n );
}
- note_req_l_ = 0;
+ else if ( mom == off_mom_ ) {
+ Midi_note n( note_req_l_->melodic(), channel_i, false );
+ play_event( &n );
+ note_req_l_ = 0;
+ off_mom_ = 0;
+ }
}
bool
// if (req_l->musical() && (req_l->musical()->note() || req_l->musical()->rest()))
// note_req_l_ = req_l->musical()->rhythmic();
if ( req_l->musical() && req_l->musical()->note() )
+// huh?
note_req_l_ = req_l->musical()->melodic();
else
return false;
return perf_p->get_default_interpreter();
}
+Moment
+Performer_group_performer::get_mom() const
+{
+ Moment mom = Performer::get_mom();
+
+ for ( int i = 0; i < nongroup_l_arr_.size(); i++ )
+ nongroup_l_arr_[ i ]->set( mom );
+
+ return mom;
+}
+
bool
Performer_group_performer::is_bottom_performer_b() const
{
return !itrans_l_->get_default_itrans_l();
}
+void
+Performer_group_performer::midi_output( Midi_stream* midi_stream_l )
+{
+ for ( PCursor<Performer*> i( perf_p_list_.top() ); i.ok(); i++ )
+ i->midi_output( midi_stream_l );
+}
+
void
Performer_group_performer::process_requests()
{
- PCursor<Performer*> i( perf_p_list_.top() );
- while( i.ok() ) {
- Performer* perf_l = i++;
- perf_l->process_requests();
- }
+ for ( PCursor<Performer*> i( perf_p_list_.top() ); i.ok(); i++ )
+ i->process_requests();
+}
+
+void
+Performer_group_performer::set_track( Midi_def* midi_l, int& track_i_r )
+{
+ for ( PCursor<Performer*> i( perf_p_list_.top() ); i.ok(); i++ )
+ i->set_track( midi_l, track_i_r );
}
bool
hebbes_b = daddy_perf_l_->try_request(req_l);
return hebbes_b ;
}
+
{
}
+Moment
+Performer::get_mom() const
+{
+ return daddy_perf_l_->get_mom();
+}
+
+void
+Performer::midi_output( Midi_stream* )
+{
+}
+
void
Performer::play_event( Midi_item* l )
{
{
}
+void
+Performer::set( Moment )
+{
+}
+
+void
+Performer::set_track( Midi_def*, int& )
+{
+}
+
bool
Performer::try_request( Request* req_l )
{
/*
staff-performer.cc -- implement Staff_performer
- (c) 1996, 1997 Han-Wen Nienhuys <hanwen@stack.nl>
- Jan Nieuwenhuizen <jan@digicash.com>
+ (c) 1996, 1997 Jan Nieuwenhuizen <jan@digicash.com>
*/
#include "translator.hh"
#include "input-translator.hh"
#include "debug.hh"
+#include "midi-def.hh"
+#include "midi-item.hh"
+#include "midi-stream.hh"
+#include "string.hh"
+#include "string-convert.hh"
IMPLEMENT_STATIC_NAME(Staff_performer);
IMPLEMENT_IS_TYPE_B1(Staff_performer,Performer_group_performer);
Staff_performer::Staff_performer()
{
+ midi_mom_ = 0;
+ track_i_ = 0;
+ midi_track_p_ = 0;
}
Staff_performer::~Staff_performer()
{
+ delete midi_track_p_;
+}
+
+void
+Staff_performer::header()
+{
+ // set track name
+ Midi_text track_name( Midi_text::TRACK_NAME, "Track " + String_convert::i2dec_str( track_i_, 0, '0' ) );
+ midi_track_p_->add( Moment( 0 ), &track_name );
+
+ // set instrument :-)
+ Midi_text instrument_name( Midi_text::INSTRUMENT_NAME, instrument_str() );
+ midi_track_p_->add( Moment( 0 ), &instrument_name );
+
+ Midi_tempo midi_tempo( midi_l_->get_tempo_i( Moment( 1, 4 ) ) );
+ midi_track_p_->add( Moment( 0 ), &midi_tempo );
}
String
return Translator::id_str_;
}
+void
+Staff_performer::midi_output( Midi_stream* midi_stream_l )
+{
+ *mlog << "[" << track_i_ << "]";
+ *midi_stream_l << *midi_track_p_;
+}
+
void
Staff_performer::play_event( Midi_item* l )
{
-// l.track_i_ = midi_track_i_;
- Performer::play_event( l );
+ Moment mom = get_mom();
+ Moment delta_t = mom - midi_mom_ ;
+ midi_mom_ += delta_t;
+ midi_track_p_->add( delta_t, l );
+}
+
+void
+Staff_performer::set_track( Midi_def* midi_l, int& track_i_r )
+{
+ midi_l_ = midi_l;
+ track_i_ = track_i_r++;
+ midi_track_p_ = new Midi_track( track_i_ );
+ header();
}
#endif
// arrays are 20% faster, but we have no Pointer_array yet
-#define MVOICE_LIST // does this work?
-#define MEVENT_LIST
+#define MEVENT_LIST // does this work?
+#define MVOICE_LIST
#define TCOL_LIST
#include "string.hh"
#include "plist.hh"
#include "plist.tcc"
-//IPL_instantiate(Midi_event);
+#ifdef MEVENT_LIST
+IPL_instantiate(Midi_event);
+#endif
+
IPL_instantiate(Midi_track);
-// PL_instantiate(Midi_voice);
+
+#ifdef MVOICE_LIST
+PL_instantiate(Midi_voice);
+#endif
+
IPL_instantiate(Midi_voice);
-//IPL_instantiate(Track_column);
+
+#ifdef TCOL_LIST
+IPL_instantiate(Track_column);
+#endif