1 /*
2 * exportmidi.c
3 *
4 * Functions for exporting a Standard Midi file
5 *
6 * for Denemo, a gtk+ frontend to GNU Lilypond
7 * (C) 2001, 2002 Per Andersson, 2009, 2010, 2011, 2012 Richard Shann
8 *
9 * License: this file may be used under the FSF GPL version 3 or later
10 */
11
12 #define EXPORTMIDI_VERSION "1.2"
13
14 /*
15 * The function exportmidi() writes a "Standard MIDI file" to disk.
16 * The file can then be played by programs like playmidi
17 * or TiMidity, externally or by the denemo playback command.
18 *
19 * See www.wotsit.org for some info on midi and the standard file format
20 *
21 * The ambition is to honour as many musical directives (tempo, slurs, ties,
22 * dynamics, staccato ...) as possible, and to make the output as musical
23 * as possible. Efforts have been made to try to handle empty or incomplete
24 * measures, unbalanced slurs and other strange input.
25 *
26 * Exportmidi() has a velocity modulation feature to make the sound
27 * less mechanical, but this is still under development.
28 * Timing modulation is planned.
29 *
30 * Call exportmidi() from some file menu or as a part of the playback command.
31 * It has the same parameters as exportmudela().
32 * There is a code fragment for this in the file fragment.c.
33 * The makefile needs the four files exportmidi.[ch] and instrumentname.[ch].
34 *
35 * Environment variable is used for user preferences. This should be replaced
36 * by some musical "style sheet" in the future, since the values depend on
37 * the genre (and tempo) of the piece, as well as personal taste.
38 * Information should be stored in the mudela file, somehow.
39 * Values may change within the piece, and ...
40 * There are many issues to resolve here!
41 *
42 * This software is tested with denemo 0.5.5.
43 *
44 *
45 *
46 * Per Andersson
47 * Artifex consulting
48 *
49 * email to: artifex@europe.com
50 */
51
52 #include <stdlib.h>
53 #include <string.h>
54 #include <stdio.h>
55 #include <time.h>
56 #include <ctype.h>
57 #include <errno.h>
58
59 #include <denemo/denemo.h>
60 #include "export/exportmidi.h"
61 #include "audio/instrumentname.h"
62 #include "audio/audiointerface.h"
63 #include "core/view.h"
64 #include "printview/svgview.h"
65 #include "smf.h"
66 /*
67 * only for developers
68 */
69
70 static int debug = 0;
71
72 /****************************************************************/
73
74
75 /**
76 * some important midi command bytes
77 */
78
79 #define MIDI_NOTE_OFF 0x80
80 #define MIDI_NOTE_ON 0x90
81 #define MIDI_PROG_CHANGE 0xc0
82 #define MAX_TRACKS 16
83
84
85 /*
86 * support macros for exportmidi()
87 */
88
89 /* length, in ticks, of a quarter note */
90 #define MIDI_RESOLUTION 384
91
92 /* tick conversion */
93 #define ticks2bars(t,u,l) (t/(MIDI_RESOLUTION*4*u/l))
94 #define bars2ticks(t,u,l) (t*(MIDI_RESOLUTION*4*u/l))
95 #define ticks2beats(t,u,l) (t/(MIDI_RESOLUTION*4/l))
96 #define beats2ticks(t,u,l) (t*(MIDI_RESOLUTION*4/l))
97
98 /****************************************************************/
99
100 /**
101 * dynamic request handling
102 */
103
104 enum dynamics
105 {
106 DYN_TACET = 0,
107 DYN_PPP,
108 DYN_PP,
109 DYN_P,
110 DYN_MP,
111 DYN_MF,
112 DYN_F,
113 DYN_FF,
114 DYN_FFF,
115 DYN_MAX
116 };
117
118 static char *dyn_strings[DYN_MAX] = {
119 "tacet",
120 "ppp",
121 "pp",
122 "p",
123 "mp",
124 "mf",
125 "f",
126 "ff",
127 "fff",
128 };
129
130 static int dyn_vol[DYN_MAX] = { 1, 16, 32, 48, 64, 80, 96, 112, 127 };
131
132 /**
133 * convert dynamic string to midi velocity 0 .. 127
134 */
135
136 static int
string_to_vol(char * dynamic,int default_vol)137 string_to_vol (char *dynamic, int default_vol)
138 {
139 int i;
140
141 for (i = 0; i < DYN_MAX; i++)
142 {
143 if (!strcmp (dynamic, dyn_strings[i]))
144 {
145 return dyn_vol[i];
146 }
147 }
148 return default_vol;
149 }
150
151 /****************************************************************/
152
153 /**
154 * unbiased random generator,
155 *
156 * returns a value within +- maxdev
157 */
158 /* UNUSED
159 static int
160 i_random (int *accumulate, int maxdev)
161 {
162 int rnd;
163
164 rnd = maxdev - 2 * maxdev * (rand () >> 4) / (RAND_MAX >> 4) - *accumulate;
165
166 *accumulate += rnd / 2;
167
168 if (debug >= 10)
169 {
170 fprintf (stderr, "random=%d\n", rnd / 2);
171 }
172
173 return rnd / 2;
174 }
175 */
176 /****************************************************************/
177
178 /**
179 * limit a value to be within limits
180 * (simple first approach)
181 */
182 /* UNUSED
183 static int
184 compress (int range, int invalue)
185 {
186 int outvalue;
187
188 outvalue = invalue;
189
190 if (invalue >= range)
191 {
192 outvalue = range - 1;
193 }
194
195 if (invalue != outvalue)
196 {
197 fprintf (stderr, "compress %d %d\n", invalue, outvalue);
198 }
199
200 return outvalue & 0x7F;
201 }
202 */
203 /****************************************************************/
204
205 /**
206 * integer base 2 logarithm used in time-sig code
207 */
208
209 static int
twolog(int x)210 twolog (int x)
211 {
212 int answer = 0;
213
214 /* should not happen! */
215 if (x < 1)
216 return 0;
217
218 while (x > 1)
219 {
220 x >>= 1;
221 answer++;
222 }
223
224 return answer;
225 }
226
227
228 #define midi_meta_text(a,b) smf_event_new_textual(a,b)
229
230
231 /**
232 * almost only used for program change
233 */
234
235 static smf_event_t *
midi_change_event(int type,int chan,int val)236 midi_change_event (int type, int chan, int val)
237 {
238 smf_event_t *event = smf_event_new ();
239 guchar *buf = malloc (2);
240 event->midi_buffer = buf;
241 event->midi_buffer_length = 2;
242 *buf++ = type | chan;
243 *buf++ = val;
244 return event;
245 }
246
247 /**
248 * meta event: set time signature, time scale and metronome FF 58 04 nn dd cc bb Time Signature
249 */
250
251 static smf_event_t *
midi_timesig(int upper,int lower)252 midi_timesig (int upper, int lower)
253 {
254 smf_event_t *event = smf_event_new ();
255 guchar *buf = malloc (7);
256 event->midi_buffer = buf;
257 event->midi_buffer_length = 7;
258 div_t n;
259 int click = 24;
260
261 if (lower != 0)
262 {
263 n = div (4, lower);
264 click = 24 * ((float) n.quot + (float) n.rem);
265 }
266
267 *buf++ = 0xff, *buf++ = 0x58, *buf++ = 4;
268 *buf++ = upper, *buf++ = twolog (lower), *buf++ = click, *buf++ = 8;
269 return event;
270 }
271
272 /**
273 * meta event: set key signature
274 */
275
276 static smf_event_t *
midi_keysig(gint key,gint isminor)277 midi_keysig (gint key, gint isminor)
278 {
279 smf_event_t *event = smf_event_new ();
280 guchar *buf = malloc (5);
281 event->midi_buffer = buf;
282 event->midi_buffer_length = 5;
283 *buf++ = 0xff;
284 *buf++ = 0x59;
285 *buf++ = 2;
286 *buf++ = key;
287 *buf++ = isminor;
288 return event;
289 }
290
291 /**
292 * meta event: set system clock speed
293 */
294
295 static smf_event_t *
midi_tempo(long tempo)296 midi_tempo (long tempo)
297 {
298 long midi_tempo;
299 smf_event_t *event = smf_event_new ();
300 guchar *buf = malloc (6);
301 event->midi_buffer = buf;
302 event->midi_buffer_length = 6;
303 if (tempo == 0)
304 {
305 tempo = 1;
306 }
307 *buf++ = 0xff;
308 *buf++ = 0x51;
309 *buf++ = 3;
310 midi_tempo = 60000000 / tempo;
311 *buf++ = (midi_tempo >> 16) & 255;
312 *buf++ = (midi_tempo >> 8) & 255/*, (midi_tempo >> 0) & 255*/;
313 return event;
314 }
315
316 /**
317 * compute midi chromatic note number from diatonic offset
318 */
319
320 int
dia_to_midinote(int offs)321 dia_to_midinote (int offs)
322 {
323 int table[] = { -10, -8, -7, -5, -3, -1, 0, 2, 4, 5, 7, 9, 11 };
324
325 int tone, octave;
326 int midinum;
327
328 octave = offs / 7;
329 tone = offs % 7;
330 midinum = 60 + 12 * octave + table[tone + 6];
331 return midinum;
332 }
333
334 /****************************************************************/
335
336 /**
337 * slur handling code:
338 *
339 * decide what to do about slurs and things, using a note status table
340 * describing each note and a status variable for the general situation
341 */
342
343 /*
344 * constants used in note status table
345 */
346
347 #define FLG_CONNECT_B 0x01
348 #define FLG_CONNECT_F 0x02
349 #define FLG_SLUR_BEGIN 0x04
350 #define FLG_SLUR_END 0x08
351
352 #define FLG_NOTE_ON 0x10
353 #define FLG_NOTE_OFF 0x20
354 #define FLG_STACCATO 0x40
355 #define FLG_STACCATISSIMO 0x80
356
357 #define FLG_TIED_F 0x100
358 #define FLG_TIED_B 0x200
359
360 /**
361 * debug print-out of slur table
362 */
363
364 static char *
fmt_ticks(long t)365 fmt_ticks (long t)
366 {
367 static char answer[12];
368 long sig = 4;
369 long res = 4;
370 long count;
371
372 count = t * res / MIDI_RESOLUTION / sig;
373
374 sprintf (answer, "%ld = %ld+%ld/%ld", t, count / res, count % res, res);
375 return answer;
376 }
377
378 #if slurdebug
379 /**
380 * Output slur descriptions to the given file
381 *
382 */
383 static int
print_slurs(FILE * fd,int * tab,int status,int t_read,int t_written,char * txt)384 print_slurs (FILE * fd, int *tab, int status, int t_read, int t_written, char *txt)
385 {
386 int i;
387
388 fprintf (fd, "=== slurs: (state=%d) %s @ ", status, txt);
389 fprintf (fd, "r=%s ", fmt_ticks (t_read));
390 fprintf (fd, "w=%s\n", fmt_ticks (t_written));
391
392 for (i = 0; i < 128; i++)
393 {
394 if (tab[i])
395 {
396 fprintf (fd, "%2d: %3x %s%s%s%s%s%s%s%s%s%s\n",
397 i, tab[i], tab[i] & FLG_CONNECT_B ? "connect-backward " : "", tab[i] & FLG_CONNECT_F ? "connect-forward " : "", tab[i] & FLG_SLUR_BEGIN ? "begin " : "", tab[i] & FLG_SLUR_END ? "end " : "", tab[i] & FLG_STACCATO ? "staccato " : "", tab[i] & FLG_STACCATISSIMO ? "staccatissimo " : "", tab[i] & FLG_NOTE_ON ? "note_is_on " : "", tab[i] & FLG_NOTE_OFF ? "note_is_off " : "", tab[i] & FLG_TIED_B ? "tied_backward " : "", tab[i] & FLG_TIED_F ? "tied_forward " : "");
398 }
399 }
400
401 /* not used */
402 return 0;
403 }
404 #endif
405
406 #define STATE_NONE 0
407 #define STATE_FIRST 1
408 #define STATE_LAST 2
409 #define STATE_THROUGH 3
410
411 /**
412 * reset note status table and slur status
413 *
414 * called once before each track
415 */
416
417 static void
slur_erase(int * table,int * state)418 slur_erase (int *table, int *state)
419 {
420 int i;
421
422 for (i = 0; i < 128; i++)
423 {
424 table[i] = 0;
425 }
426 *state = STATE_NONE;
427 }
428
429 /**
430 * prepare note status table for next chord
431 *
432 * only keep notes that are still playing
433 *
434 * called once after each chord
435 */
436
437 static void
slur_shift(int * table)438 slur_shift (int *table)
439 {
440 int i;
441
442 for (i = 0; i < 128; i++)
443 {
444 if (table[i] & FLG_CONNECT_F)
445 {
446 table[i] |= FLG_CONNECT_B;
447 }
448 else
449 {
450 table[i] &= ~FLG_CONNECT_B;
451 }
452 if (table[i] & FLG_TIED_F)
453 {
454 table[i] |= FLG_TIED_B;
455 }
456 else
457 {
458 table[i] &= ~FLG_TIED_B;
459 }
460 table[i] &= (FLG_TIED_B | FLG_CONNECT_B);
461 }
462 }
463
464 /**
465 * update slur status (begin/middle/end of slurs, or no slur)
466 */
467
468 static void
slur_update(int * state,int begin,int end)469 slur_update (int *state, int begin, int end)
470 {
471 /* prepare flag bits */
472 begin = begin ? FLG_SLUR_BEGIN : 0;
473 end = end ? FLG_SLUR_END : 0;
474
475 /* look at: previous state, begin and end, then set new state */
476 switch (*state)
477 {
478 case STATE_FIRST:
479 switch (begin + end)
480 {
481 case FLG_SLUR_BEGIN:
482 fprintf (stderr, "warning: strange slur: extra begin\n");
483 *state = STATE_THROUGH;
484 break;
485 case 0:
486 case FLG_SLUR_BEGIN + FLG_SLUR_END:
487 *state = STATE_THROUGH;
488 break;
489 case FLG_SLUR_END:
490 *state = STATE_LAST;
491 break;
492 }
493 break;
494 case STATE_LAST:
495 switch (begin + end)
496 {
497 case FLG_SLUR_BEGIN:
498 *state = STATE_FIRST;
499 break;
500 case FLG_SLUR_BEGIN + FLG_SLUR_END:
501 *state = STATE_THROUGH;
502 fprintf (stderr, "strange slur: extra end\n");
503 break;
504 case 0:
505 *state = STATE_NONE;
506 break;
507 case FLG_SLUR_END:
508 fprintf (stderr, "strange slur: extra end\n");
509 *state = STATE_LAST;
510 break;
511 }
512 break;
513 case STATE_NONE:
514 switch (begin + end)
515 {
516 case FLG_SLUR_BEGIN:
517 *state = STATE_FIRST;
518 break;
519 case 0:
520 *state = STATE_NONE;
521 break;
522 case FLG_SLUR_BEGIN + FLG_SLUR_END:
523 fprintf (stderr, "strange slur: missing begin\n");
524 *state = STATE_THROUGH;
525 break;
526 case FLG_SLUR_END:
527 *state = STATE_LAST;
528 break;
529 }
530 break;
531 case STATE_THROUGH:
532 switch (begin + end)
533 {
534 case FLG_SLUR_BEGIN:
535 fprintf (stderr, "strange slur: extra begin\n");
536 *state = STATE_THROUGH;
537 break;
538 case 0:
539 case FLG_SLUR_BEGIN + FLG_SLUR_END:
540 *state = STATE_THROUGH;
541 break;
542 case FLG_SLUR_END:
543 *state = STATE_LAST;
544 break;
545 }
546 break;
547 }
548 }
549
550 /**
551 * insert a note and its properties in the table
552 */
553
554 static void
slur_note(int * table,int state,int notenum,int staccato,int staccatissimo,int tied)555 slur_note (int *table, int state, int notenum, int staccato, int staccatissimo, int tied)
556 {
557 int running;
558
559 /* see if note is already playing */
560 running = table[notenum] & FLG_CONNECT_B;
561
562 /* set flags for directives */
563 staccato = staccato ? FLG_STACCATO : 0;
564 staccatissimo = (staccatissimo ? FLG_STACCATISSIMO : 0);
565
566 table[notenum] &= FLG_TIED_B;
567
568 /* set note on/off according to the slur state */
569 switch (state)
570 {
571 case STATE_LAST:
572 if (!running)
573 {
574 table[notenum] |= FLG_NOTE_ON + FLG_NOTE_OFF;
575 }
576 else
577 {
578 table[notenum] |= FLG_NOTE_OFF;
579 }
580 break;
581 case STATE_NONE:
582 /* normal note, no slur */
583 if (running)
584 {
585 fprintf (stderr, "warning: note should not be on (0)\n");
586 }
587 table[notenum] |= FLG_NOTE_ON + FLG_NOTE_OFF;
588 break;
589 case STATE_THROUGH:
590 /* note may be started before */
591 if (!running)
592 {
593 table[notenum] |= FLG_NOTE_ON + FLG_CONNECT_F;
594 }
595 else
596 {
597 table[notenum] |= FLG_CONNECT_F;
598 }
599 break;
600 case STATE_FIRST:
601 /* first note of slur */
602 if (running)
603 {
604 fprintf (stderr, "warning: note should not be on (1)\n");
605 table[notenum] |= FLG_CONNECT_F;
606 }
607 else
608 {
609 table[notenum] |= FLG_NOTE_ON + FLG_CONNECT_F;
610 }
611 break;
612 default:
613 fprintf (stderr, "this shouldn't happen!\n");
614 exit (3);
615 }
616
617 if (tied)
618 {
619 table[notenum] |= FLG_TIED_F;
620 table[notenum] &= ~FLG_NOTE_OFF;
621 }
622
623 /* only relevant in normal notes or at end of slur */
624 table[notenum] += staccato + staccatissimo;
625 }
626
627 /*
628 * some predicates used in exportmidi
629 */
630
631 static int
slur_on_p(int * table,int notenum)632 slur_on_p (int *table, int notenum)
633 {
634 return (table[notenum] & FLG_NOTE_ON) && !(table[notenum] & FLG_TIED_B);
635 }
636
637 static int
slur_kill_p(int * table,int notenum)638 slur_kill_p (int *table, int notenum)
639 {
640 return ((table[notenum] & FLG_CONNECT_B) && !(table[notenum] & FLG_NOTE_ON)) || ((table[notenum] & FLG_TIED_B) && !(table[notenum] & FLG_NOTE_ON));
641 }
642
643 static int
slur_off_p(int * table,int notenum)644 slur_off_p (int *table, int notenum)
645 {
646 return (table[notenum] & FLG_NOTE_OFF);
647 }
648 /* UNUSED
649 static int
650 slur_staccato_p (int *table, int notenum)
651 {
652 return !(table[notenum] & FLG_STACCATO);
653 }
654
655 static int
656 slur_staccatissimo_p (int *table, int notenum)
657 {
658 return !(table[notenum] & FLG_STACCATISSIMO);
659 }
660 */
661 /****************************************************************/
662
663 /**
664 * compute the amount of extra velocity to be added to a note
665 */
666 /* UNUSED
667 static int
668 compute_beat (long ticks, long ticks_in_a_beat, long ticks_in_a_measure, int length, int factor)
669 {
670 // give extra beat only to short notes
671 if (length < ticks_in_a_measure / 2)
672 {
673 if (ticks == 0)
674 {
675 // put more emphasis on the first beat
676 return factor;
677 }
678 else if (ticks % ticks_in_a_beat)
679 {
680 // put less emphasis on off beat notes
681 return -factor;
682 }
683 else
684 {
685 // leave the rest alone
686 return 0;
687 }
688 }
689 else
690 {
691 return 0;
692 }
693 }
694 */
695 /****************************************************************/
696
697
698 /* convert denemo time values to ticks */
699
700 #define internaltoticks(i) ((MIDI_RESOLUTION*4)>>i)
701
702
703 /* this is a real high-tech macro */
704
705 #define percent(t,p) ((t*p)/100)
706
707 static int
is_status_byte(const unsigned char status)708 is_status_byte(const unsigned char status)
709 {
710 return (status & 0x80);
711 }
712
713 /* puts an event into track if buffer contains valid midi message.
714 and frees buffer. Returns the event, or NULL if invalid buffer.
715 */
716 static smf_event_t *
put_event(gchar * buffer,gint numbytes,smf_track_t * track)717 put_event (gchar * buffer, gint numbytes, smf_track_t * track)
718 {
719 smf_event_t *event = NULL;
720 if (numbytes && is_status_byte (buffer[0]))
721 event = smf_event_new_from_pointer (buffer, numbytes);
722 if (event && smf_event_is_valid (event))
723 {
724 smf_track_add_event_delta_pulses (track, event, 0);
725 }
726 g_free (buffer);
727 return event;
728 }
729
730 static gint
directive_get_midi_override(DenemoDirective * directive)731 directive_get_midi_override (DenemoDirective * directive)
732 {
733 return (directive->override & DENEMO_OVERRIDE_HIDDEN) | (directive->override & DENEMO_MIDI_MASK);
734 }
735
736 static gint
directive_get_midi_interpretation(DenemoDirective * directive)737 directive_get_midi_interpretation (DenemoDirective * directive)
738 {
739 return directive->override & DENEMO_MIDI_INTERPRETATION_MASK;
740 }
741
742 static gint
directive_get_midi_action(DenemoDirective * directive)743 directive_get_midi_action (DenemoDirective * directive)
744 {
745 return directive->override & DENEMO_MIDI_ACTION_MASK;
746 }
747
748 gchar *
substitute_midi_values(gchar * str,gint channel,gint volume)749 substitute_midi_values (gchar * str, gint channel, gint volume)
750 {
751 gchar *bytes = g_strdup (str);
752 gchar *c;
753 for (c = bytes; *c; c++)
754 {
755 if (*c == '$')
756 *c = '0' + channel;
757 if (*c == '%' && *(c + 1) == '%' && *(c + 2) == '%')
758 sprintf (c, "%3d", volume); //*c = itoa(volume);
759 }
760 // g_debug("We have transformed %s to %s\n", str, bytes);
761 return bytes;
762 }
763
764 static gchar *
directive_get_midi_buffer(DenemoDirective * directive,gint * pnumbytes,gint channel,gint volume)765 directive_get_midi_buffer (DenemoDirective * directive, gint * pnumbytes, gint channel, gint volume)
766 {
767 errno = 0;
768 *pnumbytes = 0;
769 if (directive->midibytes)
770 {
771 gchar *bytes;
772 bytes = substitute_midi_values (directive->midibytes->str, channel, volume);
773 //g_print("Got %s as midi bytes\n", bytes);
774 char *next;
775 gint i, numbytes;
776 for (i = 0, next = bytes; *next; i++)
777 {
778 gchar *last = next;
779 strtol (next, &next, 0);
780 if(errno || (last==next))
781 {
782 g_free(bytes);
783 return NULL;
784 }
785 }
786 gchar *buf = (gchar *) g_malloc0 (i);
787 for (i=0, next = bytes; *next; i++)
788 {
789 buf[i] = (char) strtol (next, &next, 0);
790 //g_print("byte %x\n", buf[i]);
791 }
792 *pnumbytes = i;
793 g_free (bytes);
794 return buf;
795 }
796 return NULL;
797 }
798
799 static gint
directive_get_midi_val(DenemoDirective * directive)800 directive_get_midi_val (DenemoDirective * directive)
801 {
802 gint val = 0;
803 if (directive->midibytes)
804 {
805 gchar *bytes;
806 bytes = directive->midibytes->str;
807 errno = 0;
808 val = strtol (bytes, NULL, 0);
809 if (errno)
810 {
811 g_warning ("String %s is bad format for MIDI value", bytes);
812 return 0;
813 }
814 }
815 return val;
816 }
817
818 /* change the volume according to the values passed in */
819 static void
change_volume(gint * volume,gint midi_val,gint midi_interpretation,gint midi_action)820 change_volume (gint * volume, gint midi_val, gint midi_interpretation, gint midi_action)
821 {
822 gdouble val;
823 // g_debug("midi_val %d cur_volume %d\n", midi_val, cur_volume);
824 val = (gdouble) midi_val;
825 if (midi_interpretation & DENEMO_OVERRIDE_PERCENT)
826 val = *volume * (midi_val / 100.0);
827 if (midi_action == DENEMO_OVERRIDE_ONCE)
828 g_warning ("Scripting error, ONCE for standalone directive is meaningless");
829 if (midi_action == DENEMO_OVERRIDE_RAMP)
830 g_warning ("Not implemented ramp yet");
831 if (midi_action == DENEMO_OVERRIDE_STEP)
832 {
833 if (midi_interpretation & DENEMO_OVERRIDE_RELATIVE)
834 *volume += val;
835 else
836 *volume = val;
837 }
838 if (*volume > 127)
839 *volume = 127;
840 if (*volume < 0)
841 *volume = 0;
842 }
843
844
845 /* change the channel according to the values passed in */
846 static void
change_channel(gint * channel,gint midi_val,gint midi_interpretation,gint midi_action)847 change_channel (gint * channel, gint midi_val, gint midi_interpretation, gint midi_action)
848 {
849 gdouble val;
850 //g_debug("midi_val %d cur_channel %d\n", midi_val, cur_channel);
851 val = (gdouble) midi_val;
852 if (midi_interpretation & DENEMO_OVERRIDE_PERCENT)
853 g_warning ("Percent meaningless with channel change");
854 if (midi_action == DENEMO_OVERRIDE_ONCE)
855 g_warning ("Scripting error, ONCE for standalone directive is meaningless");
856 if (midi_action == DENEMO_OVERRIDE_RAMP)
857 g_warning ("Ramp meaningless with channel change");
858 if (midi_action == DENEMO_OVERRIDE_STEP)
859 {
860 *channel = val;
861 }
862 if (*channel > 127)
863 *channel = 127;
864 if (*channel < 0)
865 *channel = 0;
866 g_message ("After channel change channel = %d", *channel);
867 }
868
869
870
871
872 /* change the tempo according to the values passed in */
873 static void
change_tempo(gint * tempo,gint midi_val,gint midi_interpretation,gint midi_action)874 change_tempo (gint * tempo, gint midi_val, gint midi_interpretation, gint midi_action)
875 {
876 gdouble val;
877 val = (gdouble) midi_val;
878 if (midi_interpretation & DENEMO_OVERRIDE_PERCENT)
879 val = *tempo * (midi_val / 100.0);
880 if (midi_action == DENEMO_OVERRIDE_ONCE)
881 g_warning ("Not implemented change of tempo for one chord");
882 if (midi_action == DENEMO_OVERRIDE_RAMP)
883 g_warning ("Not implemented ramp yet");
884 if (midi_action == DENEMO_OVERRIDE_STEP)
885 {
886 if (midi_interpretation & DENEMO_OVERRIDE_RELATIVE)
887 *tempo += val;
888 else
889 *tempo = val;
890 }
891 }
892
load_smf(DenemoMovement * si,smf_t * smf)893 static void load_smf ( DenemoMovement *si, smf_t *smf)
894 {
895 if (si->smf==smf)
896 return;
897 gboolean midi_track = FALSE;
898
899
900 g_static_mutex_lock (&smfmutex);
901 if (Denemo.project->movement->recorded_midi_track)
902 {
903 if (si->smf && (((smf_track_t *) Denemo.project->movement->recorded_midi_track)->smf == si->smf))
904 {
905 smf_track_remove_from_smf (Denemo.project->movement->recorded_midi_track);
906 midi_track = TRUE;
907 }
908 }
909 free_midi_data (si);
910 si->smf = smf;
911 if (midi_track)
912 smf_add_track (smf, Denemo.project->movement->recorded_midi_track);
913
914
915 si->smfsync = si->changecount;
916 g_static_mutex_unlock (&smfmutex);
917 }
918
919
save_smf_to_file(smf_t * smf,gchar * thefilename)920 static void save_smf_to_file (smf_t *smf, gchar *thefilename)
921 {
922 if (thefilename)
923 {
924 if (Denemo.project->movement->recorded_midi_track)
925 smf_add_track (smf, Denemo.project->movement->recorded_midi_track);
926 if(smf_save (smf, (const char *) thefilename))
927 g_debug("smf_save failed");
928 if (Denemo.project->movement->recorded_midi_track)
929 smf_track_remove_from_smf (Denemo.project->movement->recorded_midi_track);
930 }
931 }
932
load_lilypond_midi(gchar * outfile,gboolean keep)933 gdouble load_lilypond_midi (gchar * outfile, gboolean keep) {
934 smf_t *saved = NULL;
935 gchar *midi_file = Denemo.printstatus->printname_midi[Denemo.printstatus->cycle];
936 smf_t *smf = smf_load (midi_file);
937 if (smf)
938 {
939 if (!attach_timings ())
940 g_warning ("Attaching timings to objects failed\n");
941 if (outfile)
942 save_smf_to_file (smf, outfile);
943 if (!keep )
944 load_smf (Denemo.project->movement, smf);
945 else
946 smf_delete (smf);
947 return smf_get_length_seconds (Denemo.project->movement->smf);
948 } else
949 {
950 g_warning ("midi file %s not loaded", midi_file);
951 }
952 return 0.0;
953 }
954
955 /*
956 * the main midi output system (somewhat large)
957 */
958
959 /****************************************************************/
960 /****************************************************************/
961 /****************************************************************/
962
963 /**
964 * the main midi output system (somewhat large)
965 * return the duration in seconds of the music stored
966 */
967 gdouble
exportmidi(gchar * thefilename,DenemoMovement * si)968 exportmidi (gchar * thefilename, DenemoMovement * si)
969 {
970 /* variables for reading and decoding the object list */
971 smf_event_t *event = NULL;
972 staffnode *curstaff;
973 DenemoStaff *curstaffstruct;
974 measurenode *curmeasure;
975 objnode *curobjnode;
976 DenemoObject *curobj;
977 gint curmeasurenum;
978 chord chordval;
979 gint duration, numdots;
980 gint enshift;
981 gint mid_c_offset;
982 GList *curtone;
983 //gdouble fraction;
984
985 gint measurenum, last = 0;
986
987 /* variables for generating music */
988 //int i;
989 int d, n;
990
991 long ticks_read;
992 long ticks_written;
993 long ticks_at_bar = 0;
994 int cur_volume;
995 gdouble master_volume;
996 gboolean override_volume;
997 int cur_transposition;
998
999 int midi_channel = (-1);
1000 int tracknumber = 0;
1001 int timesigupper = 4;
1002 int timesiglower = 4;
1003 int notenumber;
1004 int prognum;
1005
1006 int width = 0;
1007 int notes_in_chord = 0;
1008 int note_status[128];
1009 int slur_status;
1010 int measure_is_empty;
1011 int measure_has_odd_tuplet;
1012 int measurewidth;
1013
1014 /* output velocity and timing modulation */
1015 //int rand_sigma = 0;
1016 //int rand_delta;
1017 //int beat = 0;
1018
1019 /* to handle user preferences */
1020 char *envp;
1021 int vel_randfact = 5;
1022 int vel_beatfact = 10;
1023 int pref_width = 100;
1024 int pref_staccato = 25;
1025 int pref_staccatissimo = 10;
1026
1027 /* tuplets */
1028 int tuplet = 0; //level of tuplet nesting only 0 and 1 are supported
1029 tupopen tupletnums;
1030 tupopen savedtuplet;
1031
1032 /* used to insert track sizes in the midi file */
1033 //long track_start_pos[MAX_TRACKS];
1034 //long track_end_pos[MAX_TRACKS];
1035
1036 /* statistics */
1037 time_t starttime;
1038 //time_t endtime;
1039
1040 call_out_to_guile ("(InitializeMidiGeneration)");
1041
1042 /* get user preferences, if any */
1043 envp = getenv ("EXP_MIDI_VEL");
1044 if (envp)
1045 {
1046 sscanf (envp, "%d %d", &vel_randfact, &vel_beatfact);
1047 fprintf (stderr, "VELOCITY parameters are: %d %d\n", vel_randfact, vel_beatfact);
1048 }
1049
1050 envp = getenv ("EXP_MIDI_PERCENT");
1051 if (envp)
1052 {
1053 sscanf (envp, "%d %d %d", &pref_width, &pref_staccato, &pref_staccatissimo);
1054
1055 fprintf (stderr, "PERCENT parameters are: normal=%d staccato=%d %d\n", pref_width, pref_staccato, pref_staccatissimo);
1056 }
1057
1058 /* just curious */
1059 time (&starttime);
1060
1061 smf_t *smf = smf_new ();
1062 if(smf_set_ppqn (smf, MIDI_RESOLUTION))
1063 g_debug("smf_set_ppqn failed");
1064
1065 /*
1066 * end of headers and meta events, now for some real actions
1067 */
1068
1069 //fraction = 1 / g_list_length (si->thescore);
1070
1071 /* iterate over all tracks in file */
1072 printf ("\nsi->stafftoplay in exportmidi = %i", si->stafftoplay);
1073 curstaff = si->thescore;
1074 if (si->stafftoplay > 0)
1075 {
1076 int z = si->stafftoplay;
1077 while (--z)
1078 curstaff = curstaff->next;
1079 }
1080 //for (curstaff = si->thescore; curstaff; curstaff = curstaff->next)
1081 while (curstaff)
1082 {
1083 /* handle one track */
1084 curstaffstruct = (DenemoStaff *) curstaff->data;
1085
1086 /* select a suitable track number */
1087 tracknumber++;
1088 smf_track_t *track = smf_track_new ();
1089 smf_add_track (smf, track);
1090
1091 /* track name */
1092 event = midi_meta_text (3, curstaffstruct->lily_name->str);
1093 smf_track_add_event_delta_pulses (track, event, 0);
1094
1095 /* tempo */
1096 gint cur_tempo = si->tempo;
1097
1098 if (tracknumber == 1)
1099 { //Do not set the tempo for later tracks as there may be tempo directives at the start of the first measure which libsmf will muddle up with any done here
1100 event = midi_tempo (cur_tempo);
1101 smf_track_add_event_delta_pulses (track, event, 0);
1102 }
1103 /* Midi Client/Port */
1104 // track->user_pointer = (DevicePort *) device_manager_get_DevicePort(curstaffstruct->device_port->str);
1105
1106 /* The midi instrument */
1107 if (curstaffstruct->midi_instrument && curstaffstruct->midi_instrument->len)
1108 {
1109 event = midi_meta_text (4, curstaffstruct->midi_instrument->str);
1110 smf_track_add_event_delta_pulses (track, event, 0);
1111 }
1112 midi_channel = curstaffstruct->midi_channel;
1113 prognum = curstaffstruct->midi_prognum;
1114
1115 /* set selected midi program */
1116 g_message ("Using channel %d prognum %d", midi_channel, prognum);
1117 event = midi_change_event (MIDI_PROG_CHANGE, midi_channel, prognum);
1118 smf_track_add_event_delta_pulses (track, event, 0);
1119
1120 /*key signature */
1121
1122 event = midi_keysig (curstaffstruct->keysig.number, curstaffstruct->keysig.isminor);
1123 smf_track_add_event_delta_pulses (track, event, 0);
1124
1125 /* Time signature */
1126 timesigupper = curstaffstruct->timesig.time1;
1127 //printf("\nstime1 = %i\n", timesigupper);
1128
1129 timesiglower = curstaffstruct->timesig.time2;
1130 //printf("\nstime2 = %i\n", timesiglower);
1131
1132 event = midi_timesig (timesigupper, timesiglower);
1133 smf_track_add_event_delta_pulses (track, event, 0);
1134
1135 /* set a default velocity value */
1136 cur_volume = curstaffstruct->volume;
1137
1138 master_volume = curstaffstruct->volume / 127.0; /* new semantic for staff volume as fractional master volume */
1139 override_volume = curstaffstruct->override_volume; /* force full volume output if set */
1140 cur_transposition = curstaffstruct->transposition;
1141
1142
1143 if (tuplet > 0)
1144 g_warning ("Unterminated tuplet at end of voice %d", tracknumber - 1);
1145 //Reset to tuplets nesting level 0, in case unbalanced tuplet start end in last staff
1146 tuplet = 0;
1147 //Now that we have the channel and volume we can interpret any score and staff-wide directives for midi
1148 if (curstaffstruct->staff_directives)
1149 {
1150 GList *g = curstaffstruct->staff_directives;
1151 DenemoDirective *directive = NULL;
1152 for (; g; g = g->next)
1153 {
1154 gint numbytes;
1155 directive = (DenemoDirective *) g->data;
1156 gint midi_override = directive_get_midi_override (directive);
1157 gchar *buf = directive_get_midi_buffer (directive, &numbytes, midi_channel, cur_volume);
1158 if (!(midi_override & DENEMO_OVERRIDE_HIDDEN))
1159 if (buf)
1160 if (NULL == put_event (buf, numbytes, track))
1161 g_warning ("Invalid midi bytes in staff directive");
1162 }
1163 }
1164
1165 if (tracknumber == 1)
1166 {
1167 if (Denemo.project->lilycontrol.directives)
1168 {
1169 //FIXME repeated code
1170 GList *g = Denemo.project->lilycontrol.directives;
1171 DenemoDirective *directive = NULL;
1172
1173 for (; g; g = g->next)
1174 {
1175 gint numbytes;
1176 directive = (DenemoDirective *) g->data;
1177 gint midi_override = directive_get_midi_override (directive);
1178 gchar *buf = directive_get_midi_buffer (directive, &numbytes, midi_channel, cur_volume);
1179 if (!(midi_override & DENEMO_OVERRIDE_HIDDEN))
1180 if (buf)
1181 if (NULL == put_event (buf, numbytes, track))
1182 g_warning ("Invalid midi bytes in score directive");
1183 }
1184 }
1185
1186 if (Denemo.project->movement->movementcontrol.directives)
1187 {
1188 GList *g = Denemo.project->movement->movementcontrol.directives;
1189 DenemoDirective *directive = NULL;
1190 for (; g; g = g->next)
1191 {
1192 gint numbytes;
1193 directive = (DenemoDirective *) g->data;
1194 gint midi_override = directive_get_midi_override (directive);
1195 gchar *buf = directive_get_midi_buffer (directive, &numbytes, midi_channel, cur_volume);
1196 if (!(midi_override & DENEMO_OVERRIDE_HIDDEN))
1197 if (buf)
1198 if (NULL == put_event (buf, numbytes, track))
1199 g_warning ("Invalid midi bytes in movement directive");
1200 }
1201 }
1202
1203 }
1204
1205
1206
1207
1208
1209 /* reset measure */
1210 curmeasurenum = 0;
1211 curmeasure = curstaffstruct->themeasures;
1212
1213 /* reset tick counters */
1214 ticks_read = 0;
1215 ticks_written = 0;
1216
1217 /* reset slur system */
1218 slur_erase (note_status, &slur_status);
1219
1220 /* set boundries */
1221
1222 last = g_list_length (curmeasure);
1223
1224
1225 /* iterate for over measures in track */
1226 for (measurenum = 1; curmeasure && measurenum <= last; curmeasure = curmeasure->next, measurenum++)
1227 {
1228 /* start of measure */
1229 curmeasurenum++;
1230 measure_is_empty = 1;
1231 measure_has_odd_tuplet = 0;
1232 ticks_at_bar = ticks_read;
1233
1234 /* iterate over objects in measure */
1235 for (curobjnode = (objnode *) ((DenemoMeasure*)curmeasure->data)->objects; curobjnode; curobjnode = curobjnode->next)
1236 {
1237 curobj = (DenemoObject *) curobjnode->data;
1238 curobj->earliest_time = ticks_read * 60.0 / (cur_tempo * MIDI_RESOLUTION); //smf_get_length_seconds(smf);
1239
1240
1241 /*******************************************
1242 * huge switch:
1243 * here we handle every kind of object
1244 * that seems relevant to us
1245 *******************************************/
1246 int tmpstaccato = 0, tmpstaccatissimo = 0;
1247 gboolean skip_midi = FALSE;
1248
1249 switch (curobj->type)
1250 {
1251 case CHORD:
1252 /********************
1253 * one or more notes
1254 ********************/
1255
1256
1257 measure_is_empty = 0;
1258 if (debug)
1259 fprintf (stderr, "=============================== chord at %s\n", fmt_ticks (ticks_read));
1260 chordval = *(chord *) curobj->object;
1261 if (chordval.directives)
1262 {
1263 GList *g = chordval.directives;
1264 DenemoDirective *directive = NULL;
1265 for (; g; g = g->next)
1266 {
1267 gint numbytes;
1268 directive = (DenemoDirective *) g->data;
1269 gchar *buf = directive_get_midi_buffer (directive, &numbytes, midi_channel, cur_volume);
1270 gint midi_override = directive_get_midi_override (directive);
1271 gint midi_interpretation = directive_get_midi_interpretation (directive);
1272 gint midi_action = directive_get_midi_action (directive);
1273 gint midi_val = directive_get_midi_val (directive);
1274 /* handle all types of MIDI overrides attached to chord here */
1275 switch (midi_override)
1276 {
1277 case DENEMO_OVERRIDE_VOLUME:
1278 if (midi_val)
1279 change_volume (&cur_volume, midi_val, midi_interpretation, midi_action);
1280 else
1281 skip_midi = TRUE;
1282 break;
1283 case DENEMO_OVERRIDE_TRANSPOSITION:
1284 cur_transposition = midi_val;
1285 break;
1286
1287 case DENEMO_OVERRIDE_CHANNEL:
1288 change_channel (&midi_channel, midi_val, midi_interpretation, midi_action);
1289 break;
1290 case DENEMO_OVERRIDE_TEMPO:
1291 change_tempo (&cur_tempo, midi_val, midi_interpretation, midi_action);
1292 if (cur_tempo)
1293 {
1294 event = midi_tempo (cur_tempo);
1295 smf_track_add_event_delta_pulses (track, event, 0);
1296 }
1297 else
1298 g_warning ("Tempo change to 0 bpm is illegal");
1299 break;
1300 //etc
1301 default:
1302 if (!(midi_override & DENEMO_OVERRIDE_HIDDEN))
1303 if (buf)
1304 {
1305 if (NULL == put_event (buf, numbytes, track))
1306 g_warning ("Invalid midi bytes in chord directive");
1307 }
1308 break;
1309 }
1310 } //for each directive attached to the chord
1311 } //if there are directives
1312 /* FIXME sound grace notes either simultaneously for shorter duration or steal time .... */
1313 if (chordval.is_grace)
1314 {
1315 curobj->latest_time = curobj->earliest_time;
1316 break;
1317 }
1318
1319 /***********************************
1320 * compute nominal duration of note
1321 ***********************************/
1322
1323 numdots = chordval.numdots;
1324 duration = 0;
1325 if (chordval.baseduration >= 0)
1326 {
1327 for (d = 0; d <= numdots; d++)
1328 {
1329
1330
1331 duration += internaltoticks (chordval.baseduration) >> d;
1332 }
1333 if (tuplet >= 1)
1334 {
1335 duration *= tupletnums.numerator;
1336 duration /= tupletnums.denominator;
1337 if (MIDI_RESOLUTION % tupletnums.denominator)
1338 {
1339 measure_has_odd_tuplet = 1;
1340 }
1341 }
1342
1343 if (tuplet >= 2)
1344 {
1345 if (MIDI_RESOLUTION % tupletnums.denominator * savedtuplet.denominator)
1346 {
1347 measure_has_odd_tuplet = 1;
1348 }
1349 duration *= savedtuplet.numerator;
1350 duration /= savedtuplet.denominator;
1351 }
1352 }
1353 else
1354 duration = curobj->durinticks;
1355
1356 /********************************
1357 * compute real duration of note
1358 ********************************/
1359 #if 0
1360 //this is not working - it causes the delta to be -ve later
1361 for (tmp = chordval.ornamentlist; tmp; tmp = tmp->next)
1362 {
1363 if (*(enum ornament *) tmp->data == (enum ornament) STACCATISSIMO)
1364 {
1365 tmpstaccatissimo = 1;
1366 width = percent (duration, pref_staccatissimo);
1367 }
1368 else if (*(enum ornament *) tmp->data == (enum ornament) STACCATO)
1369 {
1370 width = percent (duration, pref_staccato);
1371 tmpstaccato = 1;
1372 }
1373
1374 else
1375 {
1376 width = percent (duration, pref_width);
1377 }
1378
1379 }
1380 if (debug)
1381 fprintf (stderr, "duration is %s\n", fmt_ticks (duration));
1382 #else
1383 width = 0;
1384 #endif
1385
1386 if (!chordval.notes)
1387 {
1388 //MUST GIVE OFF TIME FOR RESTS HERE
1389 curobj->latest_time = curobj->earliest_time + duration * 60.0 / (cur_tempo * MIDI_RESOLUTION);
1390 //g_debug("Adding Dummy event for rest %d %d %d\n", duration, ticks_read, ticks_written);
1391 event = midi_meta_text (1 /* comment */ , "rest");
1392 smf_track_add_event_delta_pulses (track, event, duration);
1393
1394 ticks_written += duration;
1395 event->user_pointer = curobj;
1396 //g_debug("rest of %f seconds at %f\n", duration/(double)MIDI_RESOLUTION, curobj->latest_time);
1397 }
1398
1399 if (chordval.notes)
1400 {
1401
1402 gint tmp_channel = midi_channel;
1403 if (curobj->isinvisible)
1404 midi_channel = 9;
1405
1406 /**************************
1407 * prepare for note output
1408 **************************/
1409
1410 notes_in_chord = 0;
1411 if (debug)
1412 fprintf (stderr, "this is a chord\n");
1413
1414 // slur_update (&slur_status, chordval.slur_begin_p, chordval.slur_end_p);
1415 slur_update (&slur_status, 0, 0);
1416
1417 /* compute beat to add to note velocity */
1418 //beat = compute_beat (ticks_read - ticks_at_bar, beats2ticks (1, timesigupper, timesiglower), bars2ticks (1, timesigupper, timesiglower), duration, vel_beatfact);
1419
1420 /************************
1421 * begin chord read loop
1422 ************************/
1423
1424 for (curtone = chordval.notes; curtone; curtone = curtone->next)
1425 {
1426 note *thenote = (note *) curtone->data;
1427
1428 #ifdef NOTE_MIDI_OVERRIDES_IMPLEMENTED
1429 for (g = thenote->directives; g; g = g->next)
1430 {
1431 DenemoDirective *directive = g->data;
1432 gint midi_override = directive_get_midi_override (directive);
1433 if (midi_override)
1434 skip_midi = TRUE; //TODO if it *is* overriden take action e.g. increase volume etc. For now we just drop it
1435 }
1436 #endif
1437 if (!skip_midi)
1438 {
1439 if (chordval.has_dynamic)
1440 {
1441 //g_debug ("\nThis chord has a dynamic marking attatched\n");
1442 GList *dynamic = g_list_first (chordval.dynamics);
1443 cur_volume = string_to_vol (((GString *) dynamic->data)->str, cur_volume);
1444 }
1445 mid_c_offset = thenote->mid_c_offset;
1446 enshift = thenote->enshift;
1447 notenumber = dia_to_midinote (mid_c_offset) + enshift;
1448 notenumber += cur_transposition;
1449
1450 if (notenumber > 127)
1451 {
1452 g_warning ("Note out of range: %d", notenumber = 60);
1453 }
1454 slur_note (note_status, slur_status, notenumber, tmpstaccato, tmpstaccatissimo, chordval.is_tied);
1455 }
1456
1457 }
1458 /* End chord read loop */
1459 #if slurdebug
1460 print_slurs (stderr, note_status, slur_status, ticks_read, ticks_written, "after chord read");
1461 #endif
1462 /****************************
1463 * start note-on output loop
1464 ****************************/
1465
1466 /* kill old slurs and ties */
1467 /* start new notes */
1468
1469 notes_in_chord = 0;
1470 /* write delta */
1471 for (n = 0; n < 128; n++)
1472 {
1473 gint mididelta;
1474 if (slur_on_p (note_status, n) || slur_kill_p (note_status, n))
1475 {
1476 if (notes_in_chord++ == 0)
1477 {
1478 mididelta = ticks_read - ticks_written;
1479 ticks_written = ticks_read;
1480 }
1481 else
1482 {
1483 mididelta = 0;
1484 }
1485 }
1486
1487 /* compute velocity delta */
1488 //rand_delta = i_random (&rand_sigma, vel_randfact);
1489 /* write note on/off */
1490 if (slur_on_p (note_status, n))
1491 {
1492 // int mix = cur_volume? compress(128, cur_volume + rand_delta + beat) : 0;
1493 // FIXME the function compress is returning large values.
1494 event = smf_event_new_from_bytes (MIDI_NOTE_ON | midi_channel, n,(curstaffstruct->mute)? 0: (override_volume ? 127 : (gint) (master_volume * cur_volume /*FIXME as above, mix */ )));
1495 smf_track_add_event_delta_pulses (track, event, mididelta);
1496 event->user_pointer = curobj;
1497
1498 curobj->earliest_time = event->time_seconds;
1499 curobj->latest_time = curobj->earliest_time + duration * 60.0 / (cur_tempo * MIDI_RESOLUTION);
1500
1501 //g_debug ("'%d len %d'", event->event_number, event->midi_buffer_length);
1502 //printf ("volume = %i\n", (override_volume ? 0:mix));
1503 }
1504 else if (slur_kill_p (note_status, n))
1505 {
1506 event = smf_event_new_from_bytes (MIDI_NOTE_OFF | midi_channel, n, 0);
1507 //g_debug("{%d}", event->event_number);
1508 smf_track_add_event_delta_pulses (track, event, mididelta);
1509 //g_debug("Note off for track %x at delta (%d) %.1f for cur_tempo %d\n", track, mididelta, event->time_seconds, cur_tempo);
1510 event->user_pointer = curobj;
1511
1512 curobj->latest_time = event->time_seconds;
1513 curobj->earliest_time = curobj->latest_time - duration * 60.0 / (cur_tempo * MIDI_RESOLUTION);
1514 //g_debug("event off lur kill %f\n", event->time_seconds);
1515 }
1516 }
1517 /* end of first chord output loop */
1518
1519 #if slurdebug
1520 print_slurs (stderr, note_status, slur_status, ticks_read, ticks_written, "after loop1");
1521 #endif
1522 /*****************************
1523 * start note-off output loop
1524 *****************************/
1525
1526 /* kill untied notes */
1527
1528 notes_in_chord = 0;
1529
1530 /* start second chord output loop */
1531
1532 /* write delta */
1533 for (n = 0; n < 128; n++)
1534 {
1535 if (slur_off_p (note_status, n))
1536 {
1537 gint mididelta;
1538 if (notes_in_chord++ == 0)
1539 {
1540 width += ticks_read - ticks_written;
1541 mididelta = duration + width;
1542 ticks_written += duration + width;
1543 if (ticks_written > ticks_read + duration)
1544 {
1545 fprintf (stderr, "BAD WIDTH %d so delta %d\n" "(should not happen!)", width, mididelta);
1546 mididelta = 0;
1547 }
1548 }
1549 else
1550 {
1551 mididelta = 0;
1552 }
1553 /* write note off */
1554 event = smf_event_new_from_bytes (MIDI_NOTE_OFF | midi_channel, n, 60);
1555 //g_debug("smf length before %d %f mididelta %d",smf_get_length_pulses(smf), smf_get_length_seconds(smf),mididelta);
1556 smf_track_add_event_delta_pulses (track, event, mididelta);
1557 //g_debug("Note off for track %x at delta (%d) %.1f for cur_tempo %d\n", track, mididelta, event->time_seconds, cur_tempo);
1558 //g_debug("smf length after %d %f mididelta %d", smf_get_length_pulses(smf), smf_get_length_seconds(smf),mididelta);
1559 event->user_pointer = curobj;
1560
1561 curobj->latest_time = event->time_seconds;
1562 curobj->earliest_time = curobj->latest_time - duration * 60.0 / (cur_tempo * MIDI_RESOLUTION);
1563 //g_debug("event off %f mididelta %d duration %d for curobj->type = %d\n", event->time_seconds, mididelta, duration, curobj->type);
1564
1565 }
1566 }
1567 /* end of second chord output loop */
1568 midi_channel = tmp_channel;
1569 } //end of for notes in chord. Note that rests have no MIDI representation, of course.
1570 width = 0;
1571 #if slurdebug
1572 print_slurs (stderr, note_status, slur_status, ticks_read, ticks_written, "after loop2");
1573 #endif
1574 /* prepare for next event */
1575
1576 ticks_read += duration;
1577 slur_shift (note_status);
1578 #if slurdebug
1579 print_slurs (stderr, note_status, slur_status, ticks_read, ticks_written, "after shift");
1580 #endif
1581 if (debug)
1582 fprintf (stderr, "chord end\n");
1583 break;
1584
1585 case TIMESIG:
1586
1587 /************************
1588 * time signature change
1589 ************************/
1590
1591 if (ticks_read != ticks_at_bar)
1592 {
1593 fprintf (stderr, "error: can only change time" " signature at beginning of a measure\n");
1594 }
1595 timesigupper = ((timesig *) curobj->object)->time1;
1596 timesiglower = ((timesig *) curobj->object)->time2;
1597 if (debug)
1598 {
1599 fprintf (stderr, "timesig change to %d:%d\n", timesigupper, timesiglower);
1600 }
1601
1602 event = midi_timesig (timesigupper, timesiglower);
1603 smf_track_add_event_delta_pulses (track, event, 0);
1604 event->user_pointer = curobj;
1605
1606 curobj->earliest_time = curobj->latest_time = event->time_seconds; //= smf_get_length_seconds(smf);
1607 break;
1608
1609 case TUPOPEN:
1610
1611 /***************
1612 * tuplet begin
1613 ***************/
1614
1615 switch (tuplet)
1616 {
1617 default:
1618 fprintf (stderr, "too complicated tuplets\n");
1619 break;
1620 case 1:
1621 savedtuplet.numerator = tupletnums.numerator;
1622 savedtuplet.denominator = tupletnums.denominator;
1623 tupletnums.numerator = ((tupopen *) curobj->object)->numerator;
1624 tupletnums.denominator = ((tupopen *) curobj->object)->denominator;
1625 break;
1626 case 0:
1627 tupletnums.numerator = ((tupopen *) curobj->object)->numerator;
1628 tupletnums.denominator = ((tupopen *) curobj->object)->denominator;
1629 break;
1630 }
1631 tuplet++;
1632 curobj->earliest_time = curobj->latest_time = event->time_seconds; //the last event
1633 break;
1634 case TUPCLOSE:
1635
1636 /*************
1637 * tuplet end
1638 *************/
1639
1640 tuplet--;
1641 switch (tuplet)
1642 {
1643 case 2:
1644 case 3:
1645 case 4:
1646 case 5:
1647 case 6:
1648 case -1:
1649 fprintf (stderr, "too complicated tuplets\n");
1650 break;
1651 case 1:
1652 tupletnums.numerator = savedtuplet.numerator;
1653 tupletnums.denominator = savedtuplet.denominator;
1654 break;
1655 case 0:
1656 break;
1657 }
1658 curobj->earliest_time = curobj->latest_time = event->time_seconds; //the last event
1659 break;
1660
1661 case DYNAMIC:
1662
1663 /********************
1664 * dynamic directive
1665 ********************/
1666
1667 cur_volume = string_to_vol (((dynamic *) curobj->object)->type->str, cur_volume);
1668 curobj->earliest_time = curobj->latest_time = event->time_seconds; //the last event
1669 break;
1670
1671 case KEYSIG:
1672 // curobj->object
1673 // ((keysig *) theobj->object)->number; referenced in src/measure.cpp
1674 //printf("\nKEYSIG type = %d\n", ((keysig *) curobj->object)->number);
1675 event = midi_keysig ((((keysig *) curobj->object)->number), curstaffstruct->keysig.isminor);
1676 smf_track_add_event_delta_pulses (track, event, 0);
1677 event->user_pointer = curobj;
1678
1679 curobj->earliest_time = curobj->latest_time = event->time_seconds; //= smf_get_length_seconds(smf);
1680 break;
1681
1682 case CLEF:
1683
1684 /***********
1685 * ignored!
1686 ***********/
1687
1688 break;
1689
1690 case LILYDIRECTIVE:
1691 {
1692 gint theduration = curobj->durinticks;
1693 if (!(((DenemoDirective *) curobj->object)->override & DENEMO_OVERRIDE_HIDDEN))
1694 {
1695 gint numbytes;
1696 gchar *buf = directive_get_midi_buffer (curobj->object, &numbytes, midi_channel, cur_volume);
1697 gint midi_override = directive_get_midi_override (curobj->object);
1698 gint midi_interpretation = directive_get_midi_interpretation (curobj->object);
1699 gint midi_action = directive_get_midi_action (curobj->object);
1700 gint midi_val = directive_get_midi_val (curobj->object);
1701 switch (midi_override)
1702 {
1703 case DENEMO_OVERRIDE_VOLUME:
1704 change_volume (&cur_volume, midi_val, midi_interpretation, midi_action);
1705 break;
1706 case DENEMO_OVERRIDE_TRANSPOSITION:
1707 cur_transposition = midi_val;
1708 break;
1709
1710 case DENEMO_OVERRIDE_CHANNEL:
1711 change_channel (&midi_channel, midi_val, midi_interpretation, midi_action);
1712 break;
1713 case DENEMO_OVERRIDE_TEMPO:
1714 change_tempo (&cur_tempo, midi_val, midi_interpretation, midi_action);
1715 if (cur_tempo)
1716 {
1717 event = midi_tempo (cur_tempo);
1718 smf_track_add_event_delta_pulses (track, event, 0); //!!!!!!!!!! if rests precede this it is not at the right time...
1719 }
1720 else
1721 {
1722 g_warning ("Tempo change to 0 bpm is illegal - re-setting.");
1723 cur_tempo = 120;
1724 }
1725 break;
1726 case DENEMO_OVERRIDE_DURATION:
1727 theduration = midi_interpretation;
1728 //g_debug ("Duration is %d", theduration);
1729 break;
1730 default:
1731 if (!(midi_override & DENEMO_OVERRIDE_HIDDEN))
1732 if (buf)
1733 {g_print ("putting numbytes %d", numbytes);
1734 if (NULL == put_event (buf, numbytes, track))
1735 g_warning ("Directive has invalid MIDI bytes");
1736 }
1737 break;
1738 }
1739 }
1740
1741
1742
1743 curobj->earliest_time = event->time_seconds; // taking the last one...
1744 curobj->latest_time = curobj->earliest_time + theduration * 60.0 / (cur_tempo * MIDI_RESOLUTION);
1745 ticks_read += theduration;
1746 }
1747 break;
1748 default:
1749 #if DEBUG
1750 fprintf (stderr, "midi ignoring type %d\n", curobj->type);
1751 #endif
1752 break;
1753 }
1754
1755 //g_debug("Object type 0x%x Starts at %f Finishes %f\n",curobj->type, curobj->earliest_time, curobj->latest_time);
1756 } // end of objects
1757
1758 /*******************
1759 * Do some checking
1760 *******************/
1761
1762
1763 measurewidth = bars2ticks (1, timesigupper, timesiglower);
1764
1765 if (((DenemoMeasure*)curmeasure->data)->objects == NULL) //An empty measure - treat as whole measure silence
1766 ticks_read = ticks_at_bar + measurewidth;
1767 if (ticks_at_bar + measurewidth != ticks_read)
1768 {
1769 if ((!measure_is_empty) && curmeasure->next)
1770 {
1771 g_warning ("warning: overfull measure in %s " "measure %d from %ld to %ld " "\n%sdifference is %ld, measure began at %ld)", curstaffstruct->lily_name->str, measurenum, ticks_read, ticks_at_bar + measurewidth, measure_has_odd_tuplet ? "(after unusual tuplet: " : "(", ticks_at_bar + measurewidth - ticks_read, ticks_at_bar);
1772 }
1773 if (debug)
1774 {
1775 printf ("\nmeasure is empty = %d", measure_is_empty);
1776 printf ("\nticks_at_bar %ld + measurewidth %d != ticks_read %ld\n", ticks_at_bar, measurewidth, ticks_read);
1777 printf ("\ninternal ticks = %d\n", internaltoticks (0));
1778 }
1779
1780 //ticks_read = ticks_at_bar + measurewidth;//+ internaltoticks (0);
1781 }
1782 else
1783 {
1784 ; //fprintf (stderr, "[%d]", measurenum);
1785 }
1786 fflush (stdout);
1787
1788 /*************************
1789 * Done with this measure
1790 *************************/
1791
1792
1793 } /* Done with this staff */
1794
1795 /***********************
1796 * Done with this track
1797 ***********************/
1798
1799 //fprintf (stderr, "[%s done]\n", curstaffstruct->lily_name->str);
1800 fflush (stdout);
1801 /*gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(si->progressbar), fraction +
1802 gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(si->progressbar))); */
1803 if (si->stafftoplay == 0)
1804 curstaff = curstaff->next;
1805 else
1806 break;
1807 }
1808 #if 0
1809 {
1810 smf_event_t *event;
1811 while ((event=smf_get_next_event (smf)))
1812 g_print ("generated 0x%hhX 0x%hhX 0x%hhX\n", *(event->midi_buffer+0), *(event->midi_buffer+1), *(event->midi_buffer+2));
1813 }
1814 #endif
1815
1816
1817 /********
1818 * Done!
1819 ********/
1820 save_smf_to_file (smf, thefilename);
1821
1822
1823 load_smf (si, smf);
1824
1825
1826
1827 if (si->start_time < 0.0)
1828 si->start_time = 0.0;
1829 if (si->end_time < 0.0)
1830 si->end_time = smf_get_length_seconds (smf);
1831 g_debug ("Start time %f end time %f\n", si->start_time, si->end_time);
1832
1833 call_out_to_guile ("(FinalizeMidiGeneration)");
1834 return smf_get_length_seconds (smf);
1835 }
1836
1837 void
free_midi_data(DenemoMovement * si)1838 free_midi_data (DenemoMovement * si)
1839 {
1840 if (si->smf)
1841 {
1842 smf_t *temp = si->smf;
1843 si->smf = NULL;
1844 smf_delete (temp);
1845 }
1846 }
1847
1848
1849 /*
1850 * That's all, folks!
1851 *
1852 * End of exportmidi.c
1853 */
1854