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