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