4 // source file of the LilyPond music typesetter
6 // (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
14 #include "musicalrequest.hh"
16 #include "midiitem.hh"
17 #include "midistream.hh"
19 Midi_chunk::Midi_chunk()
24 Midi_chunk::add( String str
)
30 Midi_chunk::set( String header_str
, String data_str
, String footer_str
)
33 footer_str_
= footer_str
;
34 header_str_
= header_str
;
40 String str
= header_str_
;
41 String length_str
= StringConversion::int2hex_str( data_str_
.length_i() + footer_str_
.length_i(), 8, '0' );
42 length_str
= StringConversion::hex2bin_str( length_str
);
49 Midi_duration::Midi_duration( Real seconds_f
)
51 seconds_f_
= seconds_f
;
57 return String( "<duration: " ) + String( seconds_f_
) + ">";
60 Midi_header::Midi_header( int format_i
, int tracks_i
, int tempo_i
)
64 String format_str
= StringConversion::int2hex_str( format_i
, 4, '0' );
65 str
+= StringConversion::hex2bin_str( format_str
);
67 String tracks_str
= StringConversion::int2hex_str( tracks_i
, 4, '0' );
68 str
+= StringConversion::hex2bin_str( tracks_str
);
70 String tempo_str
= StringConversion::int2hex_str( tempo_i
, 4, '0' );
71 str
+= StringConversion::hex2bin_str( tempo_str
);
73 set( "MThd", str
, "" );
77 Midi_item::int2varlength_str( int i
)
79 int buffer_i
= i
& 0x7f;
80 while ( (i
>>= 7) > 0 ) {
83 buffer_i
+= (i
& 0x7f);
88 str
+= (char)buffer_i
;
89 if ( buffer_i
& 0x80 )
98 Midi_item::output_midi( Midi_stream
& midi_stream_r
)
100 midi_stream_r
<< str();
104 Midi_note::Midi_note( Melodic_req
* melreq_l
, int channel_i
, bool on_bo
)
106 pitch_i_
= melreq_l
->pitch() + c0_pitch_i_c_
;
107 channel_i_
= channel_i
;
114 if ( pitch_i_
!= INT_MAX
) {
115 Byte status_by
= ( on_bo_
? 0x90 : 0x80 ) + channel_i_
;
116 String str
= String( (char)status_by
);
117 str
+= (char)pitch_i_
;
118 // poor man-s staff dynamics:
119 Byte dynamic_by
= 0x64 - 0x10 * channel_i_
;
120 str
+= (char)dynamic_by
;
126 Midi_track::Midi_track( int number_i
)
129 // 00 00 00 3B chunk length (59)
130 // 00 FF 58 04 04 02 18 08 time signature
131 // 00 FF 51 03 07 A1 20 tempo
133 // FF 59 02 sf mi Key Signature
142 number_i_
= number_i
;
144 char const* data_ch_c_l
= "00" "ff58" "0404" "0218" "08"
145 "00" "ff51" "0307" "a120"
146 // why a key at all, in midi?
148 "00" "ff59" "02" "00" "00"
149 // key: F (scsii-menuetto)
150 // "00" "ff59" "02" "ff" "00"
154 // only for format 0 (currently using format 1)?
155 data_str
+= StringConversion::hex2bin_str( data_ch_c_l
);
157 char const* footer_ch_c_l
= "00" "ff2f" "00";
158 String footer_str
= StringConversion::hex2bin_str( footer_ch_c_l
);
160 set( "MTrk", data_str
, footer_str
);
164 Midi_track::add( int delta_time_i
, String event_str
)
166 Midi_chunk::add( int2varlength_str( delta_time_i
) + event_str
);
170 Midi_track::add( Moment delta_time_moment
, Midi_item
* mitem_l
)
172 // silly guess: 24 midi clocks per 4 note
174 // int delta_time_i = delta_time_moment / Moment( 1, 4 ) * Moment( 24 );
175 int delta_time_i
= delta_time_moment
/ Moment( 1, 4 ) * Moment( 96 );
176 add( delta_time_i
, mitem_l
->str() );