First version, development moved to 5110-connected machine
[gnokii.git] / common / files / midifile.c
1 /* a little modified code from http://iki.fi/too/sw/xring/ */
2
3 /* embedding modified midifile.h and midifile.c into this file */
4
5 #include "config.h"
6
7 /***** midifile.h ******/
8
9 struct MF {
10 /* definitions for MIDI file parsing code */
11   int (*Mf_getc)(struct MF *);
12   void (*Mf_header)(struct MF *, int, int, int);
13   void (*Mf_trackstart)(struct MF *);
14   void (*Mf_trackend)(struct MF *);
15   void (*Mf_noteon)(struct MF *, int, int, int);
16   void (*Mf_noteoff)(struct MF *, int, int, int);
17   void (*Mf_pressure)(struct MF *, int, int, int);
18   void (*Mf_parameter)(struct MF *, int, int, int);
19   void (*Mf_pitchbend)(struct MF *, int, int, int);
20   void (*Mf_program)(struct MF *, int, int);
21   void (*Mf_chanpressure)(struct MF *, int, int);
22   void (*Mf_sysex)(struct MF *, int, char *);
23   void (*Mf_metamisc)(struct MF *, int, int, char * );
24   void (*Mf_seqspecific)(struct MF *, int, int, char *);
25   void (*Mf_seqnum)(struct MF *, int);
26   void (*Mf_text)(struct MF *, int, int, char *);
27   void (*Mf_eot)(struct MF *);
28   void (*Mf_timesig)(struct MF *, int, int, int, int);
29   void (*Mf_smpte)(struct MF *, int, int, int, int, int);
30   void (*Mf_tempo)(struct MF *, long);
31   void (*Mf_keysig)(struct MF *, int, int);
32   void (*Mf_arbitrary)(struct MF *, int, char *);
33   void (*Mf_error)(struct MF *, char * );
34 #if 0
35 /* definitions for MIDI file writing code */
36   void (*Mf_putc)(struct MF *);
37   void (*Mf_writetrack)(struct MF *);
38   void (*Mf_writetempotrack)(struct MF *);
39 #endif
40   /* variables */
41   int Mf_nomerge;             /* 1 => continue'ed system exclusives are */
42                                         /* not collapsed. */
43   long Mf_currtime;          /* current time in delta-time units */
44
45 /* private stuff */
46   long Mf_toberead;
47   long Mf_numbyteswritten;
48
49   char *Msgbuff;        /* message buffer */
50   int Msgsize;          /* Size of currently allocated Msg */
51   int Msgindex;         /* index of next available location in Msg */
52
53 };
54
55 float mf_ticks2sec(unsigned long ticks,int division,unsigned int tempo);
56 unsigned long mf_sec2ticks(float secs,int division, unsigned int tempo);
57
58 void mferror(struct MF * mf, char * s);
59
60 /*void mfwrite(); */
61
62
63 /* MIDI status commands most significant bit is 1 */
64 #define note_off                0x80
65 #define note_on                 0x90
66 #define poly_aftertouch         0xa0
67 #define control_change          0xb0
68 #define program_chng            0xc0
69 #define channel_aftertouch      0xd0
70 #define pitch_wheel             0xe0
71 #define system_exclusive        0xf0
72 #define delay_packet            (1111)
73
74 /* 7 bit controllers */
75 #define damper_pedal            0x40
76 #define portamento              0x41    
77 #define sostenuto               0x42
78 #define soft_pedal              0x43
79 #define general_4               0x44
80 #define hold_2                  0x45
81 #define general_5               0x50
82 #define general_6               0x51
83 #define general_7               0x52
84 #define general_8               0x53
85 #define tremolo_depth           0x5c
86 #define chorus_depth            0x5d
87 #define detune                  0x5e
88 #define phaser_depth            0x5f
89
90 /* parameter values */
91 #define data_inc                0x60
92 #define data_dec                0x61
93
94 /* parameter selection */
95 #define non_reg_lsb             0x62
96 #define non_reg_msb             0x63
97 #define reg_lsb                 0x64
98 #define reg_msb                 0x65
99
100 /* Standard MIDI Files meta event definitions */
101 #define meta_event              0xFF
102 #define sequence_number         0x00
103 #define text_event              0x01
104 #define copyright_notice        0x02
105 #define sequence_name           0x03
106 #define instrument_name         0x04
107 #define lyric                   0x05
108 #define marker                  0x06
109 #define cue_point               0x07
110 #define channel_prefix          0x20
111 #define end_of_track            0x2f
112 #define set_tempo               0x51
113 #define smpte_offset            0x54
114 #define time_signature          0x58
115 #define key_signature           0x59
116 #define sequencer_specific      0x74
117
118 /* Manufacturer's ID number */
119 #define Seq_Circuits (0x01) /* Sequential Circuits Inc. */
120 #define Big_Briar    (0x02) /* Big Briar Inc.           */
121 #define Octave       (0x03) /* Octave/Plateau           */
122 #define Moog         (0x04) /* Moog Music               */
123 #define Passport     (0x05) /* Passport Designs         */
124 #define Lexicon      (0x06) /* Lexicon                  */
125 #define Tempi        (0x20) /* Bon Tempi                */
126 #define Siel         (0x21) /* S.I.E.L.                 */
127 #define Kawai        (0x41) 
128 #define Roland       (0x42)
129 #define Korg         (0x42)
130 #define Yamaha       (0x43)
131
132 /* miscellaneous definitions */
133 #define MThd 0x4d546864
134 #define MTrk 0x4d54726b
135 #define lowerbyte(x) ((unsigned char)(x & 0xff))
136 #define upperbyte(x) ((unsigned char)((x & 0xff00)>>8))
137
138 /* the midifile interface */
139 void midifile(struct MF * mf);
140
141 /***** midifile.c ******/
142
143 /*
144  * midifile 1.11
145  * 
146  * Read and write a MIDI file.  Externally-assigned function pointers are 
147  * called upon recognizing things in the file.
148  *
149  * Original release ?
150  * June 1989 - Added writing capability, M. Czeiszperger.
151  *
152  *          The file format implemented here is called
153  *          Standard MIDI Files, and is part of the Musical
154  *          instrument Digital Interface specification.
155  *          The spec is avaiable from:
156  *
157  *               International MIDI Association
158  *               5316 West 57th Street
159  *               Los Angeles, CA 90056
160  *
161  *          An in-depth description of the spec can also be found
162  *          in the article "Introducing Standard MIDI Files", published
163  *          in Electronic Musician magazine, April, 1989.
164  * 
165  */
166
167 #include <stdio.h>
168 #include <stdlib.h>
169 #include <string.h>
170 #include <fcntl.h>
171
172 #ifdef WIN32\r
173 \r
174   #include <windows.h>\r
175 \r
176 #else\r
177 \r
178   #include <unistd.h>\r
179 #endif\r
180
181 #include "gsm-common.h"
182 #include "gsm-ringtones.h"
183
184 #define NULLFUNC NULL
185
186 static void readheader(struct MF * mf);
187 static int readtrack(struct MF * mf);
188 static void chanmessage(struct MF * mf,int status,int c1,int c2);
189 static void msginit(struct MF * mf);
190 static void msgadd(struct MF * mf,int c);
191 static void metaevent(struct MF * mf, int type);
192 static void sysex(struct MF * mf);
193 static int msgleng(struct MF * mf);
194 static void badbyte(struct MF * mf,int c);
195 static void biggermsg(struct MF * mf);
196
197
198 static long readvarinum(struct MF * mf);
199 static long read32bit(struct MF * mf);
200 static long to32bit(int, int, int, int);
201 static int read16bit(struct MF * mf);
202 static int to16bit(int, int);
203 static char * msg(struct MF * mf);
204
205 /* The only non-static function in this file. */
206 void mfread(struct MF * mf)
207 {
208         if ( mf->Mf_getc == NULLFUNC )
209                 mferror(mf, "mfread() called without setting Mf_getc"); 
210
211         readheader(mf);
212         while ( readtrack(mf) )
213                 ;
214 }
215
216 /* for backward compatibility with the original lib */
217 void midifile(struct MF * mf)
218 {
219     mfread(mf);
220 }
221
222 /* read through the "MThd" or "MTrk" header string */
223 static int readmt(struct MF * mf, char * s)
224 {
225         int n = 0;
226         char *p = s;
227         int c=0;
228
229         while ( n++<4 && (c=mf->Mf_getc(mf)) != EOF ) {
230                 if ( c != *p++ ) {
231                         char buff[32];
232                         (void) strcpy(buff, "expecting ");
233                         (void) strcat(buff, s);
234                         mferror(mf, buff);
235                 }
236         }
237         return c;
238 }
239
240 /* read a single character and abort on EOF */
241 static int egetc(struct MF * mf)
242 {
243         int c = mf->Mf_getc(mf);
244
245         if ( c == EOF )
246                 mferror(mf, "premature EOF");
247         mf->Mf_toberead--;
248         return c;
249 }
250
251 /* read a header chunk */
252 static void readheader(struct MF * mf)
253 {
254         int format, ntrks, division;
255
256         if ( readmt(mf, "MThd") == EOF )
257                 return;
258
259         mf->Mf_toberead = read32bit(mf);
260         format = read16bit(mf);
261         ntrks = read16bit(mf);
262         division = read16bit(mf);
263
264         if ( mf->Mf_header )
265                 (*mf->Mf_header)(mf, format,ntrks,division);
266
267         /* flush any extra stuff, in case the length of header is not 6 */
268         while ( mf->Mf_toberead > 0 )
269                 (void) egetc(mf);
270 }
271
272 static int readtrack(struct MF * mf)             /* read a track chunk */
273 {
274         /* This array is indexed by the high half of a status byte.  It's */
275         /* value is either the number of bytes needed (1 or 2) for a channel */
276         /* message, or 0 (meaning it's not  a channel message). */
277         static int chantype[] = {
278                 0, 0, 0, 0, 0, 0, 0, 0,         /* 0x00 through 0x70 */
279                 2, 2, 2, 2, 1, 1, 2, 0          /* 0x80 through 0xf0 */
280         };
281         long lookfor;
282         int c, c1, type;
283         int sysexcontinue = 0;  /* 1 if last message was an unfinished sysex */
284         int running = 0;        /* 1 when running status used */
285         int status = 0;         /* status value (e.g. 0x90==note-on) */
286         int needed;
287
288         if ( readmt(mf, "MTrk") == EOF )
289                 return(0);
290
291         mf->Mf_toberead = read32bit(mf);
292         mf->Mf_currtime = 0;
293
294         if ( mf->Mf_trackstart )
295                 (*mf->Mf_trackstart)(mf);
296
297         while ( mf->Mf_toberead > 0 ) {
298
299                 mf->Mf_currtime += readvarinum(mf);     /* delta time */
300
301                 c = egetc(mf);
302
303                 if ( sysexcontinue && c != 0xf7 )
304                         mferror(mf, "didn't find expected continuation of a sysex");
305
306                 if ( (c & 0x80) == 0 ) {         /* running status? */
307                         if ( status == 0 )
308                                 mferror(mf, "unexpected running status");
309                         running = 1;
310                 }
311                 else {
312                         status = c;
313                         running = 0;
314                 }
315
316                 needed = chantype[ (status>>4) & 0xf ];
317
318                 if ( needed ) {         /* ie. is it a channel message? */
319
320                         if ( running )
321                                 c1 = c;
322                         else
323                                 c1 = egetc(mf);
324                         chanmessage(mf, status, c1, (needed>1)? egetc(mf): 0);
325                         continue;;
326                 }
327
328                 switch ( c ) {
329
330                 case 0xff:                      /* meta event */
331
332                         type = egetc(mf);
333                         lookfor = mf->Mf_toberead - readvarinum(mf);
334                         msginit(mf);
335
336                         while ( mf->Mf_toberead > lookfor )
337                                 msgadd(mf, egetc(mf));
338
339                         metaevent(mf, type);
340                         break;
341
342                 case 0xf0:              /* start of system exclusive */
343
344                         lookfor = mf->Mf_toberead - readvarinum(mf);
345                         msginit(mf);
346                         msgadd(mf, 0xf0);
347
348                         while ( mf->Mf_toberead > lookfor )
349                                 msgadd(mf, c=egetc(mf));
350
351                         if ( c==0xf7 || mf->Mf_nomerge==0 )
352                                 sysex(mf);
353                         else
354                                 sysexcontinue = 1;  /* merge into next msg */
355                         break;
356
357                 case 0xf7:      /* sysex continuation or arbitrary stuff */
358
359                         lookfor = mf->Mf_toberead - readvarinum(mf);
360
361                         if ( ! sysexcontinue )
362                                 msginit(mf);
363
364                         while ( mf->Mf_toberead > lookfor )
365                                 msgadd(mf, c=egetc(mf));
366
367                         if ( ! sysexcontinue ) {
368                                 if ( mf->Mf_arbitrary )
369                                         (*mf->Mf_arbitrary)(mf, msgleng(mf),msg(mf));
370                         }
371                         else if ( c == 0xf7 ) {
372                                 sysex(mf);
373                                 sysexcontinue = 0;
374                         }
375                         break;
376                 default:
377                         badbyte(mf, c);
378                         break;
379                 }
380         }
381         if ( mf->Mf_trackend )
382                 (*mf->Mf_trackend)(mf);
383         return(1);
384 }
385
386 static void badbyte(struct MF * mf,int c)
387 {
388         char buff[32];
389
390         (void) sprintf(buff,"unexpected byte: 0x%02x",c);
391         mferror(mf, buff);
392 }
393
394 static void metaevent(struct MF * mf, int type)
395 {
396         int leng = msgleng(mf);
397         char *m = msg(mf);
398
399         switch  ( type ) {
400         case 0x00:
401                 if ( mf->Mf_seqnum )
402                         (*mf->Mf_seqnum)(mf, to16bit(m[0],m[1]));
403                 break;
404         case 0x01:      /* Text event */
405         case 0x02:      /* Copyright notice */
406         case 0x03:      /* Sequence/Track name */
407         case 0x04:      /* Instrument name */
408         case 0x05:      /* Lyric */
409         case 0x06:      /* Marker */
410         case 0x07:      /* Cue point */
411         case 0x08:
412         case 0x09:
413         case 0x0a:
414         case 0x0b:
415         case 0x0c:
416         case 0x0d:
417         case 0x0e:
418         case 0x0f:
419                 /* These are all text events */
420                 if ( mf->Mf_text )
421                         (*mf->Mf_text)(mf, type,leng,m);
422                 break;
423         case 0x2f:      /* End of Track */
424                 if ( mf->Mf_eot )
425                         (*mf->Mf_eot)(mf);
426                 break;
427         case 0x51:      /* Set tempo */
428                 if ( mf->Mf_tempo )
429                         (*mf->Mf_tempo)(mf, to32bit(0,m[0],m[1],m[2]));
430                 break;
431         case 0x54:
432                 if ( mf->Mf_smpte )
433                         (*mf->Mf_smpte)(mf, m[0],m[1],m[2],m[3],m[4]);
434                 break;
435         case 0x58:
436                 if ( mf->Mf_timesig )
437                         (*mf->Mf_timesig)(mf, m[0],m[1],m[2],m[3]);
438                 break;
439         case 0x59:
440                 if ( mf->Mf_keysig )
441                         (*mf->Mf_keysig)(mf, m[0],m[1]);
442                 break;
443         case 0x7f:
444                 if ( mf->Mf_seqspecific )
445                         (*mf->Mf_seqspecific)(mf, type, leng, m);
446                 break;
447         default:
448                 if ( mf->Mf_metamisc )
449                         (*mf->Mf_metamisc)(mf, type,leng,m);
450         }
451 }
452
453 static void sysex(struct MF * mf)
454 {
455         if ( mf->Mf_sysex )
456                 (*mf->Mf_sysex)(mf, msgleng(mf),msg(mf));
457 }
458
459 static void chanmessage(struct MF * mf,int status,int c1,int c2)
460 {
461         int chan = status & 0xf;
462
463         switch ( status & 0xf0 ) {
464         case 0x80:
465                 if ( mf->Mf_noteoff )
466                         (*mf->Mf_noteoff)(mf, chan,c1,c2);
467                 break;
468         case 0x90:
469                 if ( mf->Mf_noteon )
470                         (*mf->Mf_noteon)(mf, chan,c1,c2);
471                 break;
472         case 0xa0:
473                 if ( mf->Mf_pressure )
474                         (*mf->Mf_pressure)(mf, chan,c1,c2);
475                 break;
476         case 0xb0:
477                 if ( mf->Mf_parameter )
478                         (*mf->Mf_parameter)(mf, chan,c1,c2);
479                 break;
480         case 0xe0:
481                 if ( mf->Mf_pitchbend )
482                         (*mf->Mf_pitchbend)(mf, chan,c1,c2);
483                 break;
484         case 0xc0:
485                 if ( mf->Mf_program )
486                         (*mf->Mf_program)(mf, chan,c1);
487                 break;
488         case 0xd0:
489                 if ( mf->Mf_chanpressure )
490                         (*mf->Mf_chanpressure)(mf, chan,c1);
491                 break;
492         }
493 }
494
495 /* readvarinum - read a varying-length number, and return the */
496 /* number of characters it took. */
497
498 static long readvarinum(struct MF * mf)
499 {
500         long value;
501         int c;
502
503         c = egetc(mf);
504         value = c;
505         if ( c & 0x80 ) {
506                 value &= 0x7f;
507                 do {
508                         c = egetc(mf);
509                         value = (value << 7) + (c & 0x7f);
510                 } while (c & 0x80);
511         }
512         return (value);
513 }
514
515 static long to32bit(int c1,int c2,int c3,int c4)
516 {
517         long value = 0L;
518
519         value = (c1 & 0xff);
520         value = (value<<8) + (c2 & 0xff);
521         value = (value<<8) + (c3 & 0xff);
522         value = (value<<8) + (c4 & 0xff);
523         return (value);
524 }
525
526 static int to16bit(int c1,int c2)
527 {
528         return ((c1 & 0xff ) << 8) + (c2 & 0xff);
529 }
530
531 static long read32bit(struct MF * mf)
532 {
533         int c1, c2, c3, c4;
534
535         c1 = egetc(mf);
536         c2 = egetc(mf);
537         c3 = egetc(mf);
538         c4 = egetc(mf);
539         return to32bit(c1,c2,c3,c4);
540 }
541
542 static int read16bit(struct MF * mf)
543 {
544         int c1, c2;
545         c1 = egetc(mf);
546         c2 = egetc(mf);
547         return to16bit(c1,c2);
548 }
549
550 /* static */
551 void mferror(struct MF * mf, char * s)
552 {
553         if ( mf->Mf_error )
554                 (*mf->Mf_error)(mf, s);
555         exit(1);
556 }
557
558 /* The code below allows collection of a system exclusive message of */
559 /* arbitrary length.  The Msgbuff is expanded as necessary.  The only */
560 /* visible data/routines are msginit(), msgadd(), msg(), msgleng(). */
561
562 #define MSGINCREMENT 128
563
564 static void msginit(struct MF * mf)
565 {
566         mf->Msgindex = 0;
567 }
568
569 static char * msg(struct MF * mf)
570 {
571         return(mf->Msgbuff);
572 }
573
574 static int msgleng(struct MF * mf)
575 {
576         return(mf->Msgindex);
577 }
578
579 static void msgadd(struct MF * mf,int c)
580 {
581         /* If necessary, allocate larger message buffer. */
582         if ( mf->Msgindex >= mf->Msgsize )
583                 biggermsg(mf);
584         mf->Msgbuff[mf->Msgindex++] = c;
585 }
586
587 static void biggermsg(struct MF * mf)
588 {
589         char *newmess;
590         char *oldmess = mf->Msgbuff;
591         int oldleng = mf->Msgsize;
592
593         mf->Msgsize += MSGINCREMENT;
594         newmess = (char *) malloc( (unsigned)(sizeof(char) * mf->Msgsize) );
595
596         if(newmess == NULL)
597                 mferror(mf, "malloc error!");
598                 
599         /* copy old message into larger new one */
600         if ( oldmess != NULL ) {
601                 register char *p = newmess;
602                 register char *q = oldmess;
603                 register char *endq = &oldmess[oldleng];
604
605                 for ( ; q!=endq ; p++,q++ )
606                         *p = *q;
607                 free(oldmess);
608         }
609         mf->Msgbuff = newmess;
610 }
611
612 #if 0 /* saving time not converting write function at this time
613        */
614 /*
615  * mfwrite() - The only fuction you'll need to call to write out
616  *             a midi file.
617  *
618  * format      0 - Single multi-channel track
619  *             1 - Multiple simultaneous tracks
620  *             2 - One or more sequentially independent
621  *                 single track patterns                
622  * ntracks     The number of tracks in the file.
623  * division    This is kind of tricky, it can represent two
624  *             things, depending on whether it is positive or negative
625  *             (bit 15 set or not).  If  bit  15  of division  is zero,
626  *             bits 14 through 0 represent the number of delta-time
627  *             "ticks" which make up a quarter note.  If bit  15 of
628  *             division  is  a one, delta-times in a file correspond to
629  *             subdivisions of a second similiar to  SMPTE  and  MIDI
630  *             time code.  In  this format bits 14 through 8 contain
631  *             one of four values - 24, -25, -29, or -30,
632  *             corresponding  to  the  four standard  SMPTE and MIDI
633  *             time code frame per second formats, where  -29
634  *             represents  30  drop  frame.   The  second  byte
635  *             consisting  of  bits 7 through 0 corresponds the the
636  *             resolution within a frame.  Refer the Standard MIDI
637  *             Files 1.0 spec for more details.
638  * fp          This should be the open file pointer to the file you
639  *             want to write.  It will have be a global in order
640  *             to work with Mf_putc.  
641  */ 
642 void 
643 mfwrite(format,ntracks,division,fp) 
644 int format,ntracks,division; 
645 FILE *fp; 
646 {
647     int i; void mf_write_track_chunk(), mf_write_header_chunk();
648
649     if ( mf->Mf_putc == NULLFUNC )
650             mferror(mf, "mfmf_write() called without setting Mf_putc");
651
652     if ( mf->Mf_writetrack == NULLFUNC )
653             mferror(mf, "mfmf_write() called without setting Mf_mf_writetrack"); 
654
655     /* every MIDI file starts with a header */
656     mf_write_header_chunk(format,ntracks,division);
657
658     /* In format 1 files, the first track is a tempo map */
659     if(format == 1 && ( mf->Mf_writetempotrack ))
660     {
661         (*mf->Mf_writetempotrack)();
662     }
663
664     /* The rest of the file is a series of tracks */
665     for(i = 0; i < ntracks; i++)
666         mf_write_track_chunk(i,fp);
667 }
668
669 void 
670 mf_write_track_chunk(which_track,fp)
671 int which_track;
672 FILE *fp;
673 {
674         unsigned long trkhdr,trklength;
675         long offset, place_marker;
676         void write16bit(),write32bit();
677         
678         
679         trkhdr = MTrk;
680         trklength = 0;
681
682         /* Remember where the length was written, because we don't
683            know how long it will be until we've finished writing */
684         offset = ftell(fp); 
685
686 #ifdef DEBUG
687         printf("offset = %d\n",(int) offset);
688 #endif
689
690         /* Write the track chunk header */
691         write32bit(trkhdr);
692         write32bit(trklength);
693
694         mf->Mf_numbyteswritten = 0L; /* the header's length doesn't count */
695
696         if( mf->Mf_writetrack )
697         {
698             (*mf->Mf_writetrack)(which_track);
699         }
700
701         /* mf_write End of track meta event */
702         eputc(mf, 0);
703         eputc(mf, meta_event);
704         eputc(mf, end_of_track);
705
706         eputc(mf, 0);
707          
708         /* It's impossible to know how long the track chunk will be beforehand,
709            so the position of the track length data is kept so that it can
710            be written after the chunk has been generated */
711         place_marker = ftell(fp);
712         
713         /* This method turned out not to be portable because the
714            parameter returned from ftell is not guaranteed to be
715            in bytes on every machine */
716         /* track.length = place_marker - offset - (long) sizeof(track); */
717
718 #ifdef DEBUG
719 printf("length = %d\n",(int) trklength);
720 #endif
721
722         if(fseek(fp,offset,0) < 0)
723             mferror(mf, "error seeking during final stage of write");
724
725         trklength = mf->Mf_numbyteswritten;
726
727         /* Re-mf_write the track chunk header with right length */
728         write32bit(trkhdr);
729         write32bit(trklength);
730
731         fseek(fp,place_marker,0);
732 } /* End gen_track_chunk() */
733
734
735 void 
736 mf_write_header_chunk(format,ntracks,division)
737 int format,ntracks,division;
738 {
739     unsigned long ident,length;
740     void write16bit(),write32bit();
741     
742     ident = MThd;           /* Head chunk identifier                    */
743     length = 6;             /* Chunk length                             */
744
745     /* individual bytes of the header must be written separately
746        to preserve byte order across cpu types :-( */
747     write32bit(ident);
748     write32bit(length);
749     write16bit(format);
750     write16bit(ntracks);
751     write16bit(division);
752 } /* end gen_header_chunk() */
753
754
755 #ifdef WHENISTHISNEEDED
756 /*
757  * mf_write_midi_event()
758  * 
759  * Library routine to mf_write a single MIDI track event in the standard MIDI
760  * file format. The format is:
761  *
762  *                    <delta-time><event>
763  *
764  * In this case, event can be any multi-byte midi message, such as
765  * "note on", "note off", etc.      
766  *
767  * delta_time - the time in ticks since the last event.
768  * type - the type of meta event.
769  * chan - The midi channel.
770  * data - A pointer to a block of chars containing the META EVENT,
771  *        data.
772  * size - The length of the meta-event data.
773  */
774 int 
775 mf_write_midi_event(delta_time, type, chan, data, size)
776 unsigned long delta_time;
777 unsigned int chan,type;
778 unsigned long size;
779 unsigned char *data;
780 {
781     int i;
782     void WriteVarLen();
783     unsigned char c;
784
785     WriteVarLen(delta_time);
786
787     /* all MIDI events start with the type in the first four bits,
788        and the channel in the lower four bits */
789     c = type | chan;
790
791     if(chan > 15)
792         perror("error: MIDI channel greater than 16\n");
793
794     eputc(mf, c);
795
796     /* write out the data bytes */
797     for(i = 0; i < size; i++)
798         eputc(mf, data[i]);
799
800     return(size);
801 } /* end mf_write MIDI event */
802
803 /*
804  * mf_write_meta_event()
805  *
806  * Library routine to mf_write a single meta event in the standard MIDI
807  * file format. The format of a meta event is:
808  *
809  *          <delta-time><FF><type><length><bytes>
810  *
811  * delta_time - the time in ticks since the last event.
812  * type - the type of meta event.
813  * data - A pointer to a block of chars containing the META EVENT,
814  *        data.
815  * size - The length of the meta-event data.
816  */
817 int
818 mf_write_meta_event(delta_time, type, data, size)
819 unsigned long delta_time;
820 unsigned char *data,type;
821 unsigned long size;
822 {
823     int i;
824
825     WriteVarLen(delta_time);
826     
827     /* This marks the fact we're writing a meta-event */
828     eputc(mf, meta_event);
829
830     /* The type of meta event */
831     eputc(mf, type);
832
833     /* The length of the data bytes to follow */
834     WriteVarLen(size); 
835
836     for(i = 0; i < size; i++)
837     {
838         if(eputc(mf, data[i]) != data[i])
839             return(-1); 
840     }
841     return(size);
842 } /* end mf_write_meta_event */
843
844 void 
845 mf_write_tempo(tempo)
846 unsigned long tempo;
847 {
848     /* Write tempo */
849     /* all tempos are written as 120 beats/minute, */
850     /* expressed in microseconds/quarter note     */
851     eputc(mf, 0);
852     eputc(mf, meta_event);
853     eputc(mf, set_tempo);
854
855     eputc(mf, 3);
856     eputc(mf, (unsigned)(0xff & (tempo >> 16)));
857     eputc(mf, (unsigned)(0xff & (tempo >> 8)));
858     eputc(mf, (unsigned)(0xff & tempo));
859 }
860
861 #endif
862 /*
863  * Write multi-length bytes to MIDI format files
864  */
865 void 
866 WriteVarLen(value)
867 unsigned long value;
868 {
869   unsigned long buffer;
870
871   buffer = value & 0x7f;
872   while((value >>= 7) > 0)
873   {
874         buffer <<= 8;
875         buffer |= 0x80;
876         buffer += (value & 0x7f);
877   }
878   while(1){
879        eputc(mf, (unsigned)(buffer & 0xff));
880        
881         if(buffer & 0x80)
882                 buffer >>= 8;
883         else
884                 return;
885         }
886 }/* end of WriteVarLen */
887
888
889 /*
890  * write32bit()
891  * write16bit()
892  *
893  * These routines are used to make sure that the byte order of
894  * the various data types remains constant between machines. This
895  * helps make sure that the code will be portable from one system
896  * to the next.  It is slightly dangerous that it assumes that longs
897  * have at least 32 bits and ints have at least 16 bits, but this
898  * has been true at least on PCs, UNIX machines, and Macintosh's.
899  *
900  */
901 void 
902 write32bit(data)
903 unsigned long data;
904 {
905     eputc(mf, x(unsigned)((data >> 24) & 0xff));
906     eputc(mf, (unsigned)((data >> 16) & 0xff));
907     eputc(mf, (unsigned)((data >> 8 ) & 0xff));
908     eputc(mf, (unsigned)(data & 0xff));
909 }
910
911 void 
912 write16bit(data)
913 int data;
914 {
915     eputc(mf, (unsigned)((data & 0xff00) >> 8));
916     eputc(mf, (unsigned)(data & 0xff));
917 }
918
919 /* write a single character and abort on error */
920 eputc(mf, c)                    
921 unsigned char c;
922 {
923         int return_val;
924         
925         if((mf->Mf_putc) == NULLFUNC)
926         {
927                 mferror(mf, "Mf_putc undefined");
928                 return(-1);
929         }
930         
931         return_val = (mf->Mf_putc)(mf, c);
932
933         if ( return_val == EOF )
934                 mferror(mf, "error writing");
935                 
936         mf->Mf_numbyteswritten++;
937         return(return_val);
938 }
939
940 #endif
941
942 unsigned long mf_sec2ticks(float secs,int division, unsigned int tempo)
943 {    
944      return (long)(((secs * 1000.0) / 4.0 * division) / tempo);
945 }
946
947
948 /* 
949  * This routine converts delta times in ticks into seconds. The
950  * else statement is needed because the formula is different for tracks
951  * based on notes and tracks based on SMPTE times.
952  *
953  */
954 float mf_ticks2sec(unsigned long ticks,int division,unsigned int tempo)
955 {
956     float smpte_format, smpte_resolution;
957
958     if(division > 0)
959         return ((float) (((float)(ticks) * (float)(tempo)) / ((float)(division) * 1000000.0)));
960     else
961     {
962        smpte_format = upperbyte(division);
963        smpte_resolution = lowerbyte(division);
964        return (float) ((float) ticks / (smpte_format * smpte_resolution * 1000000.0));
965     }
966 } /* end of ticks2sec() */
967
968 /* code to utilize the interface */
969
970 #define TRACE(x, y) do { if (x) printf y; } while (0)
971
972
973 typedef unsigned long ulg;
974 typedef unsigned char uch;
975 typedef unsigned int  ui;
976
977 struct NoteInfo
978 {
979   int beats;
980   int nrnotes;
981   struct Notes {
982     ui note : 4;
983     ui scale : 4;
984     ui length : 4;
985     ui lextra : 4;
986   } note[1];
987 };
988
989 #define IBUFSIZE 1024
990 struct MFX
991 {
992   struct MF mfi;
993   struct NoteInfo * ni;
994   int allocated;
995
996   int division;
997   int trackstate;
998
999   int prevnoteonpitch; /* -1, nothing, 0 pause, 1-x note. */
1000   ulg prevnoteontime;
1001
1002   struct {
1003     int fd;
1004     uch buf[IBUFSIZE];
1005     int len;
1006     int p;
1007   } istrm;
1008 };
1009
1010 enum { TRK_NONE, TRK_READING, TRK_FINISHED };
1011
1012 #define ALLOCSIZE 256
1013
1014 #define NIALLOC(size) (struct NoteInfo *)malloc(sizeof (struct NoteInfo) + ((size) - 1) * sizeof (struct Notes))
1015
1016 #define NIREALLOC(ni, size) (struct NoteInfo *)realloc((ni), sizeof (struct NoteInfo) + ((size) - 1) * sizeof (struct Notes))
1017
1018
1019 static void lm_error(struct MF * mf, char * s);
1020
1021 static int  lm_getc(struct MF * mf);
1022 static void lm_header(struct MF * mf, int, int, int);
1023 static void lm_trackstart(struct MF * mf);
1024 static void lm_trackend(struct MF * mf);
1025 static void lm_tempo(struct MF *, long);
1026 static void lm_noteon(struct MF *, int, int, int);
1027 static void lm_noteoff(struct MF *, int, int, int);
1028
1029
1030 struct NoteInfo * readmidi(int fd)
1031 {
1032   struct MFX mfxi = { { 0 } };
1033   struct MF * mf = (struct MF *)&mfxi;
1034   
1035   mfxi.ni = NIALLOC(ALLOCSIZE);
1036   mfxi.allocated = ALLOCSIZE;
1037
1038   /* set variables to their initial values */
1039   mfxi.division = 0;
1040   mfxi.trackstate = TRK_NONE;
1041   mfxi.prevnoteonpitch = -1;
1042   mfxi.ni->nrnotes = 0;
1043   mfxi.ni->beats = 120; 
1044
1045   mfxi.istrm.fd = fd;
1046   mfxi.istrm.p = mfxi.istrm.len = 0;
1047   mf->Mf_getc = lm_getc;
1048   
1049   mf->Mf_header = lm_header;
1050   mf->Mf_tempo = lm_tempo;
1051   mf->Mf_trackstart = lm_trackstart;
1052   mf->Mf_trackend = lm_trackend;
1053   mf->Mf_noteon = lm_noteon;
1054   mf->Mf_noteoff = lm_noteoff;
1055
1056   mf->Mf_error = lm_error;
1057
1058   midifile(mf);
1059
1060   return mfxi.ni;
1061 }
1062
1063 static void lm_error(struct MF * mf, char * s)
1064 {
1065   fprintf(stderr, "%s\n", s);
1066 }
1067
1068 static int lm_getc(struct MF * mf)
1069 {
1070   struct MFX * mfx = (struct MFX *)mf;
1071
1072   /* printf("p %d, len %d\n", mfx->istrm.p, mfx->istrm.len); */
1073   if (mfx->istrm.p == mfx->istrm.len)
1074   {
1075     mfx->istrm.len = read(mfx->istrm.fd, mfx->istrm.buf, IBUFSIZE);
1076     /* printf("readlen %d\n", mfx->istrm.len); */
1077     if (mfx->istrm.len <= 0)
1078       return -1;
1079
1080     mfx->istrm.p = 1;
1081     return mfx->istrm.buf[0];
1082   }
1083   /* else */
1084   return mfx->istrm.buf[mfx->istrm.p++];
1085 }
1086
1087 static void lm_header(struct MF * mf, int format, int ntrks, int division)
1088 {
1089   struct MFX * mfx = (struct MFX *)mf;
1090
1091   TRACE(0, ("lm_header(%p, %d, %d, %d)\n", mf, format, ntrks, division));
1092
1093   mfx->division = division;
1094 }
1095
1096 /* this is just a quess */
1097 static void lm_tempo(struct MF * mf, long tempo)
1098 {
1099   struct MFX * mfx = (struct MFX *)mf;
1100
1101   TRACE(0, ("lm_tempo(%p, %ld)\n", mf, tempo));
1102
1103   if (mfx->trackstate != TRK_FINISHED)
1104     mfx->ni->beats = 60000000 / tempo;
1105 }
1106
1107
1108 static void addnote(struct MFX * mfx, int pitch, int duration, int special)
1109 {
1110   int nr, p, s;
1111   struct NoteInfo * ni;
1112   
1113   if (mfx->ni->nrnotes == mfx->allocated)
1114   {
1115     mfx->allocated += ALLOCSIZE;
1116     mfx->ni = NIREALLOC(mfx->ni, mfx->allocated);
1117     if (mfx->ni == NULL)
1118       exit(1);
1119   }
1120   ni = mfx->ni; /* mfx->ni pointer value may have changed above */
1121   nr = ni->nrnotes++;
1122
1123   
1124   if (pitch == 0)  { p = 0; s = 0; }
1125   else  { pitch--; p = (pitch % 12) + 1; s = pitch / 12; }
1126   
1127   ni->note[nr].note = p;
1128   ni->note[nr].scale = s;
1129
1130   ni->note[nr].length = duration;
1131   ni->note[nr].lextra = special;
1132 }
1133   
1134 /* currently supported */
1135 static /*     N  32  32.  16  16.   8    8.   4    4.   2    2.   1     1.  */
1136 int vals[] = { 15, 38,  54, 78,  109, 156, 218, 312, 437, 625, 875, 1250 };
1137
1138 static void writenote(struct MFX * mfx, int delta)
1139 {
1140   ulg millinotetime = delta * 250 / mfx->division;
1141   int i;
1142   int duration;
1143   int special;
1144   
1145   for(i = 0; i < sizeof vals / sizeof vals[0]; i++)
1146   {
1147     if (millinotetime < vals[i])
1148       break;
1149   }
1150
1151   if (i == 0)
1152     return;
1153
1154   i--;
1155   duration = i / 2;
1156   special = i & 1;
1157
1158   addnote(mfx, mfx->prevnoteonpitch, duration, special); /* XXX think this */
1159 }
1160   
1161
1162 static void lm_trackstart(struct MF * mf)
1163 {
1164   struct MFX * mfx = (struct MFX *)mf;
1165
1166   TRACE(0, ("lm_trackstart(%p)\n", mf));
1167
1168   if (mfx->trackstate == TRK_NONE)
1169     mfx->trackstate = TRK_READING;
1170
1171   mfx->prevnoteonpitch = -1;
1172 }
1173
1174 static void lm_trackend(struct MF * mf)
1175 {
1176   struct MFX * mfx = (struct MFX *)mf;
1177   long time = mf->Mf_currtime;
1178
1179   TRACE(0, ("lm_trackend(%p)\n", mf));
1180
1181   if (mfx->trackstate == TRK_READING && mfx->ni->nrnotes > 0)
1182     mfx->trackstate = TRK_FINISHED;
1183
1184   if (mfx->prevnoteonpitch >= 0)
1185     writenote(mfx, time - mfx->prevnoteontime);
1186   
1187   mfx->prevnoteonpitch = -1;
1188 }
1189
1190 static void lm_noteon(struct MF * mf, int chan, int pitch, int vol)
1191 {
1192   struct MFX * mfx = (struct MFX *)mf;
1193   long time = mf->Mf_currtime;
1194
1195   TRACE(0, ("lm_noteon(%p, %d, %d, %d)\n", mf, chan, pitch, vol));
1196
1197   if (vol == 0) /* kludge? to handle some (format 1? midi files) */
1198     return; 
1199   
1200   if (mfx->trackstate != TRK_READING)
1201     return;
1202   
1203   if (mfx->prevnoteonpitch >= 0)
1204     writenote(mfx, time - mfx->prevnoteontime);
1205
1206   if (vol == 0)
1207     mfx->prevnoteonpitch = 0;
1208   else
1209     mfx->prevnoteonpitch = pitch + 1;
1210   
1211   mfx->prevnoteontime = time;
1212 }
1213
1214 static void lm_noteoff(struct MF * mf, int chan, int pitch, int vol)
1215 {
1216   struct MFX * mfx = (struct MFX *)mf;
1217   long time = mf->Mf_currtime;
1218   
1219   TRACE(0, ("lm_noteoff(%p, %d, %d, %d)\n", mf, chan, pitch, vol));
1220
1221   if (mfx->prevnoteonpitch >= 0)
1222   {
1223     writenote(mfx, time - mfx->prevnoteontime);
1224     mfx->prevnoteonpitch = -1;
1225   }
1226   mfx->prevnoteonpitch = 0;
1227   mfx->prevnoteontime = time;
1228 }
1229
1230 //{ "p", "c", "c#", "d", "d#", "e", "f", "f#", "g", "g#", "a", "a#", "h" };
1231 char notes[] =
1232   { 255,  0,   1,   2,    3,   4,    6,   7,    8,   9,   10,  11 ,   12 };
1233
1234 u8 lengths[] =  { 4, 8, 16, 32, 64, 128 };
1235
1236 static void countdefaults(struct NoteInfo * ni, int * length_p, int * scale_p)
1237 {
1238   int lengths[15] = { 0 };
1239   int scales[15] = { 0 };
1240   int maxlenval = 0; /* (*) */
1241   int maxscaleval = 0;
1242   int i;
1243
1244   for (i = 0; i < ni->nrnotes; i++)
1245   {
1246     struct Notes * note = &ni->note[i];
1247
1248     lengths[note->length]++;
1249     scales[note->scale]++;
1250   }
1251
1252   maxlenval = lengths[0]; /* (*) smart compiler eliminates dead code */
1253   *length_p = 0;
1254   
1255   for (i = 1; i < 15; i++) /* `p' incremented scales[0], therefore ignored */
1256   {
1257     TRACE(0, ("%d - len: %d, scale: %d\n", i, lengths[i], scales[i]));
1258     
1259     if (lengths[i] > maxlenval) {
1260       *length_p = i;
1261       maxlenval = lengths[i];
1262     }
1263     if (scales[i] > maxscaleval) {
1264       *scale_p = i;
1265       maxscaleval = scales[i];
1266     }
1267   }
1268 }
1269
1270 GSM_Error loadmid(char *filename, GSM_Ringtone *ringtone)
1271 {
1272   int fd;
1273   struct NoteInfo * ni;
1274   int i;
1275   int deflen, defscale;
1276
1277 #ifdef WIN32
1278   if ((fd = open(filename, O_RDONLY | O_BINARY)) < 0)
1279   {
1280     perror("open");
1281     return GE_CANTOPENFILE;
1282   }
1283 #else
1284   if ((fd = open(filename, O_RDONLY)) < 0)
1285   {
1286     perror("open");
1287     return GE_CANTOPENFILE;
1288   }
1289 #endif
1290   
1291   ni = readmidi(fd);
1292
1293   if (ni == NULL)
1294     return 0;
1295
1296   countdefaults(ni, &deflen, &defscale);
1297
1298   strcpy(ringtone->name,"GNOKII");
1299
1300   if (ni->nrnotes<MAX_RINGTONE_NOTES)
1301     ringtone->NrNotes=ni->nrnotes;
1302   else
1303     ringtone->NrNotes=MAX_RINGTONE_NOTES;
1304     
1305   for (i = 0; i < ringtone->NrNotes; i++)
1306   {
1307     struct Notes * note = &ni->note[i];
1308
1309     ringtone->notes[i].note=notes[note->note];
1310     ringtone->notes[i].note=notes[note->note]+(note->scale%4)*14;    
1311     
1312     ringtone->notes[i].duration=lengths[note->length];
1313     if (note->lextra)
1314       ringtone->notes[i].duration=ringtone->notes[i].duration*1.5;
1315
1316     ringtone->notes[i].tempo=ni->beats;
1317
1318   }
1319
1320   ringtone->Loop=15;
1321   
1322   return 0;
1323 }