void
Midi_chunk::add( String str )
{
- data_str_ += str;
+ data_str_ += str;
}
void
Midi_chunk::set( String header_str, String data_str, String footer_str )
{
- data_str_ = data_str;
- footer_str_ = footer_str;
- header_str_ = header_str;
+ data_str_ = data_str;
+ footer_str_ = footer_str;
+ header_str_ = header_str;
}
String
Midi_chunk::str()
{
- String str = header_str_;
- String length_str = StringConversion::int2hex_str( data_str_.length_i() + footer_str_.length_i(), 8, '0' );
- length_str = StringConversion::hex2bin_str( length_str );
- str += length_str;
- str += data_str_;
- str += footer_str_;
- return str;
+ String str = header_str_;
+ String length_str = StringConversion::int2hex_str( data_str_.length_i() + footer_str_.length_i(), 8, '0' );
+ length_str = StringConversion::hex2bin_str( length_str );
+ str += length_str;
+ str += data_str_;
+ str += footer_str_;
+ return str;
}
Midi_duration::Midi_duration( Real seconds_f )
{
- seconds_f_ = seconds_f;
+ seconds_f_ = seconds_f;
}
String
Midi_duration::str()
{
- return String( "<duration: " ) + String( seconds_f_ ) + ">";
+ return String( "<duration: " ) + String( seconds_f_ ) + ">";
}
Midi_header::Midi_header( int format_i, int tracks_i, int tempo_i )
{
- String str;
+ String str;
- String format_str = StringConversion::int2hex_str( format_i, 4, '0' );
- str += StringConversion::hex2bin_str( format_str );
+ String format_str = StringConversion::int2hex_str( format_i, 4, '0' );
+ str += StringConversion::hex2bin_str( format_str );
- String tracks_str = StringConversion::int2hex_str( tracks_i, 4, '0' );
- str += StringConversion::hex2bin_str( tracks_str );
+ String tracks_str = StringConversion::int2hex_str( tracks_i, 4, '0' );
+ str += StringConversion::hex2bin_str( tracks_str );
- String tempo_str = StringConversion::int2hex_str( tempo_i, 4, '0' );
- str += StringConversion::hex2bin_str( tempo_str );
+ String tempo_str = StringConversion::int2hex_str( tempo_i, 4, '0' );
+ str += StringConversion::hex2bin_str( tempo_str );
- set( "MThd", str, "" );
+ set( "MThd", str, "" );
}
String
Midi_item::int2varlength_str( int i )
{
- int buffer_i = i & 0x7f;
- while ( (i >>= 7) > 0 ) {
- buffer_i <<= 8;
- buffer_i |= 0x80;
- buffer_i += (i & 0x7f);
- }
-
- String str;
- while ( 1 ) {
- str += (char)buffer_i;
- if ( buffer_i & 0x80 )
- buffer_i >>= 8;
- else
- break;
- }
- return str;
+ int buffer_i = i & 0x7f;
+ while ( (i >>= 7) > 0 ) {
+ buffer_i <<= 8;
+ buffer_i |= 0x80;
+ buffer_i += (i & 0x7f);
+ }
+
+ String str;
+ while ( 1 ) {
+ str += (char)buffer_i;
+ if ( buffer_i & 0x80 )
+ buffer_i >>= 8;
+ else
+ break;
+ }
+ return str;
}
void
Midi_item::output_midi( Midi_stream& midi_stream_r )
{
- midi_stream_r << str();
+ midi_stream_r << str();
}
Midi_note::Midi_note( Melodic_req* melreq_l, int channel_i, bool on_bo )
{
- pitch_i_ = melreq_l->pitch() + c0_pitch_i_c_;
- channel_i_ = channel_i;
- on_bo_ = on_bo;
+
+ if (!melreq_l )
+ pitch_i_ = INT_MAX-1; // any pitch.
+ else
+ pitch_i_ = melreq_l->pitch() + c0_pitch_i_c_;
+
+ channel_i_ = channel_i;
+
+ // poor man-s staff dynamics:
+ dynamic_byte_ = (melreq_l)? 0x64 - 0x10 * channel_i_:0;
+ on_b_ = on_bo;
}
String
Midi_note::str()
{
- if ( pitch_i_ != INT_MAX ) {
- Byte status_by = ( on_bo_ ? 0x90 : 0x80 ) + channel_i_;
- String str = String( (char)status_by );
- str += (char)pitch_i_;
- // poor man-s staff dynamics:
- Byte dynamic_by = 0x64 - 0x10 * channel_i_;
- str += (char)dynamic_by;
- return str;
- }
- return String( "" );
+ if ( pitch_i_ != INT_MAX ) {
+ Byte status_byte = ( on_b_ ? 0x90 : 0x80 ) + channel_i_;
+ String str = String( (char)status_byte );
+ str += (char)pitch_i_;
+ // poor man-s staff dynamics:
+ str += (char)dynamic_byte_;
+ return str;
+ }
+ return String( "" );
}
Midi_track::Midi_track( int number_i )
// mi = 0: major key
// mi = 1: minor key
- number_i_ = number_i;
+ number_i_ = number_i;
- char const* data_ch_c_l = "00" "ff58" "0404" "0218" "08"
- "00" "ff51" "0307" "a120"
+ char const* data_ch_c_l = "00" "ff58" "0404" "0218" "08"
+ "00" "ff51" "0307" "a120"
// why a key at all, in midi?
// key: C
- "00" "ff59" "02" "00" "00"
+ "00" "ff59" "02" "00" "00"
// key: F (scsii-menuetto)
// "00" "ff59" "02" "ff" "00"
- ;
+ ;
- String data_str;
- // only for format 0 (currently using format 1)?
- data_str += StringConversion::hex2bin_str( data_ch_c_l );
+ String data_str;
+ // only for format 0 (currently using format 1)?
+ data_str += StringConversion::hex2bin_str( data_ch_c_l );
- char const* footer_ch_c_l = "00" "ff2f" "00";
- String footer_str = StringConversion::hex2bin_str( footer_ch_c_l );
+ char const* footer_ch_c_l = "00" "ff2f" "00";
+ String footer_str = StringConversion::hex2bin_str( footer_ch_c_l );
- set( "MTrk", data_str, footer_str );
+ set( "MTrk", data_str, footer_str );
}
void
Midi_track::add( int delta_time_i, String event_str )
{
- Midi_chunk::add( int2varlength_str( delta_time_i ) + event_str );
+ assert(delta_time_i >= 0);
+ Midi_chunk::add( int2varlength_str( delta_time_i ) + event_str );
}
void
Midi_track::add( Moment delta_time_moment, Midi_item* mitem_l )
{
- // silly guess: 24 midi clocks per 4 note
- // huh?
+ // silly guess: 24 midi clocks per 4 note
+ // huh?
// int delta_time_i = delta_time_moment / Moment( 1, 4 ) * Moment( 24 );
- int delta_time_i = delta_time_moment / Moment( 1, 4 ) * Moment( 96 );
- add( delta_time_i, mitem_l->str() );
+ int delta_time_i = delta_time_moment / Moment( 1, 4 ) * Moment( 96 );
+ add( delta_time_i, mitem_l->str() );
}
--- /dev/null
+/*
+ midioutput.cc -- implement Midi_output
+
+ source file of the LilyPond music typesetter
+
+ (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>, Jan Nieuwehuizen <jan@digicash.com>
+*/
+#include "plist.hh"
+#include "debug.hh"
+#include "score.hh"
+#include "staff.hh"
+#include "midistream.hh"
+#include "mididef.hh"
+#include "midioutput.hh"
+#include "midiwalker.hh"
+#include "midiitem.hh"
+#include "stcol.hh"
+#include "musicalrequest.hh"
+
+
+Midi_output:: Midi_output(Score* score_l, Midi_def* midi_l )
+{
+ Midi_stream midi_stream(midi_l->outfile_str_,
+ score_l->staffs_.size(),
+ midi_l->get_tempo_i(Moment(1, 4)));
+
+ midi_stream_l_ = &midi_stream;
+ int track_i=0;
+
+ for (iter_top(score_l->staffs_,i); i.ok(); i++) {
+ do_staff(i, track_i++);
+ }
+
+}
+
+void
+Midi_output::do_staff(Staff*st_l,int track_i)
+{
+ Midi_track midi_track( track_i );
+ for (Midi_walker w (st_l, &midi_track); w.ok(); w++)
+ w.process_requests();
+
+ *midi_stream_l_ << midi_track;
+}
(c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>, Jan Nieuwenhuizen <jan@digicash.com>
*/
-#include "misc.hh"
#include "musicalrequest.hh"
-#include "voice.hh"
#include "pscore.hh"
#include "staff.hh"
-#include "midicolumn.hh"
-#include "midistaff.hh"
+#include "stcol.hh"
#include "midiwalker.hh"
-#include "debug.hh"
#include "midiitem.hh"
#include "midistream.hh"
+#include "debug.hh"
-Midi_walker::Midi_walker( Midi_staff* mstaff_l )
- : Staff_walker( mstaff_l, 0 )
-{
-}
-
-Midi_column*
-Midi_walker::mcol_l()
+Midi_walker::Midi_walker(Staff *st_l, Midi_track* track_l)
+ : PCursor<Staff_column*>(st_l->cols_)
{
- return (Midi_column*) *(*this);
+ track_l_ = track_l;
+ last_moment_= 0;
}
-Midi_staff*
-Midi_walker::mstaff_l()
+void
+Midi_walker::do_stop_notes(Moment max_moment)
{
- return (Midi_staff*)staff_l_;
+ while (stop_notes.size() && stop_notes.front_idx() <= max_moment) {
+ Moment stop_moment = stop_notes.front_idx();
+ Melodic_req * req_l = stop_notes.get();
+
+ Midi_note note(req_l, track_l_->number_i_, false);
+
+ Moment delta_t = stop_moment-last_moment_ ;
+ last_moment_ += delta_t;
+ track_l_->add(delta_t, ¬e );
+ }
}
void
Midi_walker::process_requests()
{
- allow_break();
+ do_stop_notes(ptr()->when());
+ for ( int i = 0; i < ptr()->musicalreq_l_arr_.size(); i++ ) {
+
+ Rhythmic_req *n = ptr()->musicalreq_l_arr_[i]->rhythmic();
+ if ( !n || !(n->note() || n->rest()) )
+ continue;
+
+ Midi_note note(n->melodic(), track_l_->number_i_, true);
+ stop_notes.enter(n->melodic(), n->duration() + ptr()->when() );
+ Moment dt = 0;
+ track_l_->add(dt, ¬e);
+ }
}
+Midi_walker::~Midi_walker()
+{
+ do_stop_notes( last_moment_ + Moment(10,1)); // ugh
+}