]> git.donarmstrong.com Git - lilypond.git/blob - lily/midi-item.cc
release: 0.1.7
[lilypond.git] / lily / midi-item.cc
1 /*
2   midi-item.cc -- implement Midi items.
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997 Jan Nieuwenhuizen <jan@digicash.com>
7  */
8
9 #include "proto.hh"
10 #include "plist.hh"
11 #include "debug.hh"
12 #include "misc.hh"
13 #include "string.hh"
14 #include "string-convert.hh"
15 #include "command-request.hh"
16 #include "musical-request.hh"
17 #include "midi-item.hh"
18 #include "midi-stream.hh"
19 #include "audio-item.hh"
20
21 IMPLEMENT_IS_TYPE_B(Midi_item);
22 IMPLEMENT_IS_TYPE_B1(Midi_chunk, Midi_item);
23 IMPLEMENT_IS_TYPE_B1(Midi_duration, Midi_item);
24 IMPLEMENT_IS_TYPE_B1(Midi_header, Midi_chunk);
25 IMPLEMENT_IS_TYPE_B1(Midi_instrument, Midi_item);
26 IMPLEMENT_IS_TYPE_B1(Midi_key,Midi_item);
27 IMPLEMENT_IS_TYPE_B1(Midi_meter, Midi_item);
28 IMPLEMENT_IS_TYPE_B1(Midi_note, Midi_item);
29 IMPLEMENT_IS_TYPE_B1(Midi_note_off, Midi_item);
30 IMPLEMENT_IS_TYPE_B1(Midi_tempo, Midi_item);
31 IMPLEMENT_IS_TYPE_B1(Midi_text, Midi_item);
32 IMPLEMENT_IS_TYPE_B1(Midi_track, Midi_chunk);
33
34 Midi_chunk::Midi_chunk()
35     : Midi_item( 0 )
36 {
37 }
38
39 void
40 Midi_chunk::add( String str )
41 {
42     data_str_ += str;
43 }
44
45 void
46 Midi_chunk::set( String header_str, String data_str, String footer_str )
47 {
48     data_str_ = data_str;
49     footer_str_ = footer_str;
50     header_str_ = header_str;
51 }
52   
53 String
54 Midi_chunk::str() const
55 {
56     String str = header_str_;
57     String length_str = String_convert::i2hex_str( data_str_.length_i() + footer_str_.length_i(), 8, '0' );
58     length_str = String_convert::hex2bin_str( length_str );
59     str += length_str;
60     str += data_str_;
61     str += footer_str_;
62     return str;
63 }
64
65 Midi_duration::Midi_duration( Real seconds_f )
66     : Midi_item( 0 )
67 {
68     seconds_f_ = seconds_f;
69 }
70
71 String
72 Midi_duration::str() const
73 {
74     return String( "<duration: " ) + String( seconds_f_ ) + ">";
75 }
76
77 Midi_header::Midi_header( int format_i, int tracks_i, int clocks_per_4_i )
78     : Midi_chunk()
79 {
80     String str;
81         
82     String format_str = String_convert::i2hex_str( format_i, 4, '0' );
83     str += String_convert::hex2bin_str( format_str );
84         
85     String tracks_str = String_convert::i2hex_str( tracks_i, 4, '0' );
86     str += String_convert::hex2bin_str( tracks_str );
87
88     String tempo_str = String_convert::i2hex_str( clocks_per_4_i, 4, '0' );
89     str += String_convert::hex2bin_str( tempo_str );
90
91     set( "MThd", str, "" );
92 }
93
94 char const* const instrument_name_sz_a_[ ] = {
95
96  /* default is usually piano */
97  /* 0 */ "piano",
98
99  /* (1-8 piano) */
100  /* 1 */ "acoustic grand",
101  /* 2 */ "bright acoustic",
102  /* 3 */ "electric grand",
103  /* 4 */ "honky-tonk",
104  /* 5 */ "electric piano 1",
105  /* 6 */ "electric piano 2",
106  /* 7 */ "harpsichord",
107  /* 8 */ "clav",
108
109  /* (9-16 chrom percussion) */
110  /* 9 */ "celesta",
111  /* 10 */ "glockenspiel",
112  /* 11 */ "music box",
113  /* 12 */ "vibraphone",
114  /* 13 */ "marimba",
115  /* 14 */ "xylophone",
116  /* 15 */ "tubular bells",
117  /* 16 */ "dulcimer",
118
119  /* (17-24 organ) */
120  /* 17 */ "drawbar organ",
121  /* 18 */ "percussive organ",
122  /* 19 */ "rock organ",
123  /* 20 */ "church organ",
124  /* 21 */ "reed organ",
125  /* 22 */ "accoridan",
126  /* 23 */ "harmonica",
127  /* 24 */ "tango accordian",
128
129  /* (25-32 guitar) */
130  /* 25 */ "acoustic guitar(nylon)",
131  /* 26 */ "acoustic guitar(steel)",
132  /* 27 */ "electric guitar(jazz)",
133  /* 28 */ "electric guitar(clean)",
134  /* 29 */ "electric guitar(muted)",
135  /* 30 */ "overdriven guitar",
136  /* 31 */ "distortion guitar",
137  /* 32 */ "guitar harmonics",
138
139  /* (33-40 bass) */
140  /* 33 */ "acoustic bass",
141  /* 34 */ "electric bass(finger)",
142  /* 35 */ "electric bass(pick)",
143  /* 36 */ "fretless bass",
144  /* 37 */ "slap bass 1",
145  /* 38 */ "slap bass 2",
146  /* 39 */ "synth bass 1",
147  /* 40 */ "synth bass 2",
148
149  /* (41-48 strings) */
150  /* 41 */ "violin",
151  /* 42 */ "viola",
152  /* 43 */ "cello",
153  /* 44 */ "contrabass",
154  /* 45 */ "tremolo strings",
155  /* 46 */ "pizzicato strings",
156  /* 47 */ "orchestral strings",
157  /* 48 */ "timpani",
158
159  /* (49-56 ensemble) */
160  /* 49 */ "string ensemble 1",
161  /* 50 */ "string ensemble 2",
162  /* 51 */ "synthstrings 1",
163  /* 52 */ "synthstrings 2",
164  /* 53 */ "choir aahs",
165  /* 54 */ "voice oohs",
166  /* 55 */ "synth voice",
167  /* 56 */ "orchestra hit",
168
169  /* (57-64 brass) */
170  /* 57 */ "trumpet",
171  /* 58 */ "trombone",
172  /* 59 */ "tuba",
173  /* 60 */ "muted trumpet",
174  /* 61 */ "french horn",
175  /* 62 */ "brass section",
176  /* 63 */ "synthbrass 1",
177  /* 64 */ "synthbrass 2",
178
179  /* (65-72 reed) */
180  /* 65 */ "soprano sax",
181  /* 66 */ "alto sax",
182  /* 67 */ "tenor sax",
183  /* 68 */ "baritone sax",
184  /* 69 */ "oboe",
185  /* 70 */ "english horn",
186  /* 71 */ "bassoon",
187  /* 72 */ "clarinet",
188
189  /* (73-80 pipe) */
190  /* 73 */ "piccolo",
191  /* 74 */ "flute",
192  /* 75 */ "recorder",
193  /* 76 */ "pan flute",
194  /* 77 */ "blown bottle",
195  /* 78 */ "skakuhachi",
196  /* 79 */ "whistle",
197  /* 80 */ "ocarina",
198
199  /* (81-88 synth lead) */
200  /* 81 */ "lead 1 (square)",
201  /* 82 */ "lead 2 (sawtooth)",
202  /* 83 */ "lead 3 (calliope)",
203  /* 84 */ "lead 4 (chiff)",
204  /* 85 */ "lead 5 (charang)",
205  /* 86 */ "lead 6 (voice)",
206  /* 87 */ "lead 7 (fifths)",
207  /* 88 */ "lead 8 (bass+lead)",
208
209  /* (89-96 synth pad) */
210  /* 89 */ "pad 1 (new age)",
211  /* 90 */ "pad 2 (warm)",
212  /* 91 */ "pad 3 (polysynth)",
213  /* 92 */ "pad 4 (choir)",
214  /* 93 */ "pad 5 (bowed)",
215  /* 94 */ "pad 6 (metallic)",
216  /* 95 */ "pad 7 (halo)",
217  /* 96 */ "pad 8 (sweep)",
218
219  /* (97-104 synth effects) */
220  /* 97 */ "fx 1 (rain)",
221  /* 98 */ "fx 2 (soundtrack)",
222  /* 99 */ "fx 3 (crystal)",
223  /* 100 */ "fx 4 (atmosphere)",
224  /* 101 */ "fx 5 (brightness)",
225  /* 102 */ "fx 6 (goblins)",
226  /* 103 */ "fx 7 (echoes)",
227  /* 104 */ "fx 8 (sci-fi)",
228
229  /* (105-112 ethnic) */
230  /* 105 */ "sitar",
231  /* 106 */ "banjo",
232  /* 107 */ "shamisen",
233  /* 108 */ "koto",
234  /* 109 */ "kalimba",
235  /* 110 */ "bagpipe",
236  /* 111 */ "fiddle",
237  /* 112 */ "shanai",
238
239  /* (113-120 percussive) */
240  /* 113 */ "tinkle bell",
241  /* 114 */ "agogo",
242  /* 115 */ "steel drums",
243  /* 116 */ "woodblock",
244  /* 117 */ "taiko drum",
245  /* 118 */ "melodic tom",
246  /* 119 */ "synth drum",
247  /* 120 */ "reverse cymbal",
248
249  /* (121-128 sound effects) */
250  /* 121 */ "guitar fret noise",
251  /* 122 */ "breath noise",
252  /* 123 */ "seashore",
253  /* 124 */ "bird tweet",
254  /* 125 */ "telephone ring",
255  /* 126 */ "helicopter",
256  /* 127 */ "applause",
257  /* 128 */ "gunshot",
258          0
259 }; 
260
261 Midi_instrument::Midi_instrument( int channel_i, String instrument_str )
262     : Midi_item( 0 )
263 {
264     instrument_str_ = instrument_str;
265     instrument_str_.to_lower();
266     channel_i_ = channel_i;
267 }
268                                       
269 String
270 Midi_instrument::str() const
271 {
272     Byte program_byte = 0;
273     for ( int i = 0; instrument_name_sz_a_[i]; i++ )
274         if ( instrument_str_ == String(instrument_name_sz_a_[ i ] )) { 
275             program_byte = (Byte)i;
276             break;
277         }
278
279     if ( !program_byte )
280         return String( "" );
281
282     String str = String( (char)( 0xc0 + channel_i_ ) );
283     str += String( (char)program_byte );
284     return str;
285 }
286
287 Midi_item::Midi_item( Audio_item* audio_item_l )
288 {
289     audio_item_l_ = audio_item_l;
290     channel_i_ = 0;
291 }
292
293 void
294 Midi_item::output( Midi_stream* midi_stream_l ) const
295 {
296     *midi_stream_l << str();
297 }
298
299 String
300 Midi_item::i2varint_str( int i )
301 {
302     int buffer_i = i & 0x7f;
303     while ( (i >>= 7) > 0 ) {
304         buffer_i <<= 8;
305         buffer_i |= 0x80;
306         buffer_i += (i & 0x7f);
307     }
308
309     String str;
310     while ( 1 ) {
311         str += (char)buffer_i;
312         if ( buffer_i & 0x80 )
313             buffer_i >>= 8;
314         else
315             break;
316     }
317     return str;
318 }
319
320 Midi_key::Midi_key( Audio_item* audio_item_l )
321     : Midi_item( audio_item_l )
322 {
323 }
324
325 String
326 Midi_key::str() const
327 {
328     Key_change_req* k = audio_item_l_->req_l_->command()->keychange();
329     int sharps_i = k->sharps_i();
330     int flats_i = k->flats_i();
331
332     // midi cannot handle non-conventional keys
333     if ( flats_i && sharps_i )
334         return "";
335     int accidentals_i = sharps_i - flats_i;
336
337     String str = "ff5902";
338     str += String_convert::i2hex_str( accidentals_i, 2, '0' );
339     int minor_i = k->minor_b();
340     str += String_convert::i2hex_str( minor_i, 2, '0' );
341     return String_convert::hex2bin_str( str );
342 }
343
344 Midi_meter::Midi_meter( Audio_item* audio_item_l )
345     : Midi_item( audio_item_l )
346 {
347     clocks_per_1_i_ = 18;
348 }
349
350 String
351 Midi_meter::str() const
352 {
353     Meter_change_req* m = audio_item_l_->req_l_->command()->meterchange();
354     int num_i = m->beats_i_;
355     int den_i = m->one_beat_i_;
356
357     String str = "ff5804";
358     str += String_convert::i2hex_str( num_i, 2, '0' );
359     str += String_convert::i2hex_str( intlog2( den_i ) , 2, '0' );
360     str += String_convert::i2hex_str( clocks_per_1_i_, 2, '0' );
361     str += String_convert::i2hex_str( 8, 2, '0' );
362     return String_convert::hex2bin_str( str );
363 }
364
365 Midi_note::Midi_note( Audio_item* audio_item_l )
366     : Midi_item( audio_item_l )
367 {
368     dynamic_byte_ = 0x7f;
369 }
370
371 Moment
372 Midi_note::duration() const
373 {
374     return audio_item_l_->req_l_->musical()->rhythmic()->duration();
375 }
376
377 int
378 Midi_note::pitch_i() const
379 {
380     return audio_item_l_->req_l_->musical()->melodic()->pitch();
381 }
382
383 String
384 Midi_note::str() const
385 {
386     if ( pitch_i() == INT_MAX )
387         return String( "" );
388
389     Byte status_byte = (char)( 0x90 + channel_i_ );
390
391     String str = String( (char)status_byte );
392     str += (char)( pitch_i() + c0_pitch_i_c_ );
393
394     // poor man's staff dynamics:
395     str += (char)( dynamic_byte_ - 0x10 * channel_i_ );
396
397     return str;
398 }
399
400 Midi_note_off::Midi_note_off( Midi_note* midi_note_l )
401     : Midi_item( midi_note_l->audio_item_l_ )
402 {
403     // 0x64 is supposed to be neutral, but let's try
404     aftertouch_byte_ = 0x64;
405     channel_i_ = midi_note_l->channel_i_;
406 }
407
408 int
409 Midi_note_off::pitch_i() const
410 {
411     return audio_item_l_->req_l_->musical()->melodic()->pitch();
412 }
413
414 String
415 Midi_note_off::str() const
416 {
417     if ( pitch_i() == INT_MAX )
418         return String( "" );
419
420     Byte status_byte = (char)( 0x80 + channel_i_ );
421
422     String str = String( (char)status_byte );
423     str += (char)( pitch_i() + Midi_note::c0_pitch_i_c_ );
424     str += (char)aftertouch_byte_;
425     return str;
426 }
427
428 Midi_tempo::Midi_tempo( Audio_item* audio_item_l )
429     : Midi_item( audio_item_l )
430 {
431     per_minute_4_i_ = ( (Audio_tempo*)audio_item_l_ )->per_minute_4_i_;
432 }
433
434 Midi_tempo::Midi_tempo( int per_minute_4_i )
435     : Midi_item( 0 )
436 {
437     per_minute_4_i_ = per_minute_4_i;
438 }
439
440 String
441 Midi_tempo::str() const
442 {
443     int useconds_per_4_i = 60 * (int)1e6 / per_minute_4_i_;
444     String str = "ff5103";
445     str += String_convert::i2hex_str( useconds_per_4_i, 6, '0' );
446     return String_convert::hex2bin_str( str );
447 }
448
449 Midi_text::Midi_text( Audio_item* audio_item_l )
450     : Midi_item( audio_item_l )
451 {
452     text_str_ = ( (Audio_text*)audio_item_l_ )->text_str_;
453     type_ = (Type)( (Audio_text*)audio_item_l_ )->type_;
454 }
455
456 Midi_text::Midi_text( Midi_text::Type type, String text_str )
457     : Midi_item( 0 )
458 {
459     text_str_ = text_str;
460     type_ = type;
461 }
462
463 String
464 Midi_text::str() const
465 {
466     String str = "ff" + String_convert::i2hex_str( type_, 2, '0' );
467     str = String_convert::hex2bin_str( str );
468     str += i2varint_str( text_str_.length_i() );
469     str += text_str_;
470     return str;
471 }
472
473 Midi_track::Midi_track()
474     : Midi_chunk()
475 {
476 //                4D 54 72 6B     MTrk
477 //                00 00 00 3B     chunk length (59)
478 //        00      FF 58 04 04 02 18 08    time signature
479 //        00      FF 51 03 07 A1 20       tempo
480  
481 // FF 59 02 sf mi  Key Signature
482 //         sf = -7:  7 flats
483 //         sf = -1:  1 flat
484 //         sf = 0:  key of C
485 //         sf = 1:  1 sharp
486 //         sf = 7: 7 sharps
487 //         mi = 0:  major key
488 //         mi = 1:  minor key
489
490     number_i_ = 0;
491         
492     char const* data_ch_C = ""
493 //        "00" "ff58" "0404" "0218" "08"
494 //      "00" "ff51" "0307" "a120"
495 // why a key at all, in midi?
496 // key: C
497 //      "00" "ff59" "02" "00" "00"
498 // key: F (scsii-menuetto)
499 //                                "00" "ff59" "02" "ff" "00"
500         ;
501
502     String data_str;
503     // only for format 0 (currently using format 1)?
504     data_str += String_convert::hex2bin_str( data_ch_C );
505
506     char const* footer_ch_C = "00" "ff2f" "00";
507     String footer_str = String_convert::hex2bin_str( footer_ch_C );
508
509     set( "MTrk", data_str, footer_str );
510 }
511
512 void 
513 Midi_track::add( int delta_time_i, String event_str )
514 {
515     if ( delta_time_i < 0 ) {
516         cout << String_convert::bin2hex_str( i2varint_str( delta_time_i ) ) << endl;
517         cout << String_convert::bin2hex_str( event_str ) << endl;
518     }
519     assert(delta_time_i >= 0);
520     Midi_chunk::add( i2varint_str( delta_time_i ) + event_str );
521 }
522
523 void 
524 Midi_track::add( Moment delta_time_moment, Midi_item* mitem_l )
525 {
526     // use convention of 384 clocks per 4
527     // use Duration_convert
528     int delta_time_i = delta_time_moment * Moment( 384 ) / Moment( 1, 4 );
529     // ? int ( delta_time_moment * 4 * 384) 
530     add( delta_time_i, mitem_l->str() );
531 }
532