1 /* a little modified code from http://iki.fi/too/sw/xring/ */
3 /* embedding modified midifile.h and midifile.c into this file */
5 /***** midifile.h ******/
8 /* definitions for MIDI file parsing code */
9 int (*Mf_getc)(struct MF *);
10 void (*Mf_header)(struct MF *, int, int, int);
11 void (*Mf_trackstart)(struct MF *);
12 void (*Mf_trackend)(struct MF *);
13 void (*Mf_noteon)(struct MF *, int, int, int);
14 void (*Mf_noteoff)(struct MF *, int, int, int);
15 void (*Mf_pressure)(struct MF *, int, int, int);
16 void (*Mf_parameter)(struct MF *, int, int, int);
17 void (*Mf_pitchbend)(struct MF *, int, int, int);
18 void (*Mf_program)(struct MF *, int, int);
19 void (*Mf_chanpressure)(struct MF *, int, int);
20 void (*Mf_sysex)(struct MF *, int, char *);
21 void (*Mf_metamisc)(struct MF *, int, int, char * );
22 void (*Mf_seqspecific)(struct MF *, int, int, char *);
23 void (*Mf_seqnum)(struct MF *, int);
24 void (*Mf_text)(struct MF *, int, int, char *);
25 void (*Mf_eot)(struct MF *);
26 void (*Mf_timesig)(struct MF *, int, int, int, int);
27 void (*Mf_smpte)(struct MF *, int, int, int, int, int);
28 void (*Mf_tempo)(struct MF *, long);
29 void (*Mf_keysig)(struct MF *, int, int);
30 void (*Mf_arbitrary)(struct MF *, int, char *);
31 void (*Mf_error)(struct MF *, char * );
33 /* definitions for MIDI file writing code */
34 void (*Mf_putc)(struct MF *);
35 void (*Mf_writetrack)(struct MF *);
36 void (*Mf_writetempotrack)(struct MF *);
39 int Mf_nomerge; /* 1 => continue'ed system exclusives are */
41 long Mf_currtime; /* current time in delta-time units */
45 long Mf_numbyteswritten;
47 char *Msgbuff; /* message buffer */
48 int Msgsize; /* Size of currently allocated Msg */
49 int Msgindex; /* index of next available location in Msg */
53 float mf_ticks2sec(unsigned long ticks,int division,unsigned int tempo);
54 unsigned long mf_sec2ticks(float secs,int division, unsigned int tempo);
56 void mferror(struct MF * mf, char * s);
61 /* MIDI status commands most significant bit is 1 */
64 #define poly_aftertouch 0xa0
65 #define control_change 0xb0
66 #define program_chng 0xc0
67 #define channel_aftertouch 0xd0
68 #define pitch_wheel 0xe0
69 #define system_exclusive 0xf0
70 #define delay_packet (1111)
72 /* 7 bit controllers */
73 #define damper_pedal 0x40
74 #define portamento 0x41
75 #define sostenuto 0x42
76 #define soft_pedal 0x43
77 #define general_4 0x44
79 #define general_5 0x50
80 #define general_6 0x51
81 #define general_7 0x52
82 #define general_8 0x53
83 #define tremolo_depth 0x5c
84 #define chorus_depth 0x5d
86 #define phaser_depth 0x5f
88 /* parameter values */
92 /* parameter selection */
93 #define non_reg_lsb 0x62
94 #define non_reg_msb 0x63
98 /* Standard MIDI Files meta event definitions */
99 #define meta_event 0xFF
100 #define sequence_number 0x00
101 #define text_event 0x01
102 #define copyright_notice 0x02
103 #define sequence_name 0x03
104 #define instrument_name 0x04
107 #define cue_point 0x07
108 #define channel_prefix 0x20
109 #define end_of_track 0x2f
110 #define set_tempo 0x51
111 #define smpte_offset 0x54
112 #define time_signature 0x58
113 #define key_signature 0x59
114 #define sequencer_specific 0x74
116 /* Manufacturer's ID number */
117 #define Seq_Circuits (0x01) /* Sequential Circuits Inc. */
118 #define Big_Briar (0x02) /* Big Briar Inc. */
119 #define Octave (0x03) /* Octave/Plateau */
120 #define Moog (0x04) /* Moog Music */
121 #define Passport (0x05) /* Passport Designs */
122 #define Lexicon (0x06) /* Lexicon */
123 #define Tempi (0x20) /* Bon Tempi */
124 #define Siel (0x21) /* S.I.E.L. */
126 #define Roland (0x42)
128 #define Yamaha (0x43)
130 /* miscellaneous definitions */
131 #define MThd 0x4d546864
132 #define MTrk 0x4d54726b
133 #define lowerbyte(x) ((unsigned char)(x & 0xff))
134 #define upperbyte(x) ((unsigned char)((x & 0xff00)>>8))
136 /* the midifile interface */
137 void midifile(struct MF * mf);
139 /***** midifile.c ******/
144 * Read and write a MIDI file. Externally-assigned function pointers are
145 * called upon recognizing things in the file.
148 * June 1989 - Added writing capability, M. Czeiszperger.
150 * The file format implemented here is called
151 * Standard MIDI Files, and is part of the Musical
152 * instrument Digital Interface specification.
153 * The spec is avaiable from:
155 * International MIDI Association
156 * 5316 West 57th Street
157 * Los Angeles, CA 90056
159 * An in-depth description of the spec can also be found
160 * in the article "Introducing Standard MIDI Files", published
161 * in Electronic Musician magazine, April, 1989.
172 #include <windows.h>
\r
176 #include <unistd.h>
\r
179 #include "gsm-common.h"
180 #include "gsm-ringtones.h"
182 #define NULLFUNC NULL
184 static void readheader(struct MF * mf);
185 static int readtrack(struct MF * mf);
186 static void chanmessage(struct MF * mf,int status,int c1,int c2);
187 static void msginit(struct MF * mf);
188 static void msgadd(struct MF * mf,int c);
189 static void metaevent(struct MF * mf, int type);
190 static void sysex(struct MF * mf);
191 static int msgleng(struct MF * mf);
192 static void badbyte(struct MF * mf,int c);
193 static void biggermsg(struct MF * mf);
196 static long readvarinum(struct MF * mf);
197 static long read32bit(struct MF * mf);
198 static long to32bit(int, int, int, int);
199 static int read16bit(struct MF * mf);
200 static int to16bit(int, int);
201 static char * msg(struct MF * mf);
203 /* The only non-static function in this file. */
204 void mfread(struct MF * mf)
206 if ( mf->Mf_getc == NULLFUNC )
207 mferror(mf, "mfread() called without setting Mf_getc");
210 while ( readtrack(mf) )
214 /* for backward compatibility with the original lib */
215 void midifile(struct MF * mf)
220 /* read through the "MThd" or "MTrk" header string */
221 static int readmt(struct MF * mf, char * s)
227 while ( n++<4 && (c=mf->Mf_getc(mf)) != EOF ) {
230 (void) strcpy(buff, "expecting ");
231 (void) strcat(buff, s);
238 /* read a single character and abort on EOF */
239 static int egetc(struct MF * mf)
241 int c = mf->Mf_getc(mf);
244 mferror(mf, "premature EOF");
249 /* read a header chunk */
250 static void readheader(struct MF * mf)
252 int format, ntrks, division;
254 if ( readmt(mf, "MThd") == EOF )
257 mf->Mf_toberead = read32bit(mf);
258 format = read16bit(mf);
259 ntrks = read16bit(mf);
260 division = read16bit(mf);
263 (*mf->Mf_header)(mf, format,ntrks,division);
265 /* flush any extra stuff, in case the length of header is not 6 */
266 while ( mf->Mf_toberead > 0 )
270 static int readtrack(struct MF * mf) /* read a track chunk */
272 /* This array is indexed by the high half of a status byte. It's */
273 /* value is either the number of bytes needed (1 or 2) for a channel */
274 /* message, or 0 (meaning it's not a channel message). */
275 static int chantype[] = {
276 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 through 0x70 */
277 2, 2, 2, 2, 1, 1, 2, 0 /* 0x80 through 0xf0 */
281 int sysexcontinue = 0; /* 1 if last message was an unfinished sysex */
282 int running = 0; /* 1 when running status used */
283 int status = 0; /* status value (e.g. 0x90==note-on) */
286 if ( readmt(mf, "MTrk") == EOF )
289 mf->Mf_toberead = read32bit(mf);
292 if ( mf->Mf_trackstart )
293 (*mf->Mf_trackstart)(mf);
295 while ( mf->Mf_toberead > 0 ) {
297 mf->Mf_currtime += readvarinum(mf); /* delta time */
301 if ( sysexcontinue && c != 0xf7 )
302 mferror(mf, "didn't find expected continuation of a sysex");
304 if ( (c & 0x80) == 0 ) { /* running status? */
306 mferror(mf, "unexpected running status");
314 needed = chantype[ (status>>4) & 0xf ];
316 if ( needed ) { /* ie. is it a channel message? */
322 chanmessage(mf, status, c1, (needed>1)? egetc(mf): 0);
328 case 0xff: /* meta event */
331 lookfor = mf->Mf_toberead - readvarinum(mf);
334 while ( mf->Mf_toberead > lookfor )
335 msgadd(mf, egetc(mf));
340 case 0xf0: /* start of system exclusive */
342 lookfor = mf->Mf_toberead - readvarinum(mf);
346 while ( mf->Mf_toberead > lookfor )
347 msgadd(mf, c=egetc(mf));
349 if ( c==0xf7 || mf->Mf_nomerge==0 )
352 sysexcontinue = 1; /* merge into next msg */
355 case 0xf7: /* sysex continuation or arbitrary stuff */
357 lookfor = mf->Mf_toberead - readvarinum(mf);
359 if ( ! sysexcontinue )
362 while ( mf->Mf_toberead > lookfor )
363 msgadd(mf, c=egetc(mf));
365 if ( ! sysexcontinue ) {
366 if ( mf->Mf_arbitrary )
367 (*mf->Mf_arbitrary)(mf, msgleng(mf),msg(mf));
369 else if ( c == 0xf7 ) {
379 if ( mf->Mf_trackend )
380 (*mf->Mf_trackend)(mf);
384 static void badbyte(struct MF * mf,int c)
388 (void) sprintf(buff,"unexpected byte: 0x%02x",c);
392 static void metaevent(struct MF * mf, int type)
394 int leng = msgleng(mf);
400 (*mf->Mf_seqnum)(mf, to16bit(m[0],m[1]));
402 case 0x01: /* Text event */
403 case 0x02: /* Copyright notice */
404 case 0x03: /* Sequence/Track name */
405 case 0x04: /* Instrument name */
406 case 0x05: /* Lyric */
407 case 0x06: /* Marker */
408 case 0x07: /* Cue point */
417 /* These are all text events */
419 (*mf->Mf_text)(mf, type,leng,m);
421 case 0x2f: /* End of Track */
425 case 0x51: /* Set tempo */
427 (*mf->Mf_tempo)(mf, to32bit(0,m[0],m[1],m[2]));
431 (*mf->Mf_smpte)(mf, m[0],m[1],m[2],m[3],m[4]);
434 if ( mf->Mf_timesig )
435 (*mf->Mf_timesig)(mf, m[0],m[1],m[2],m[3]);
439 (*mf->Mf_keysig)(mf, m[0],m[1]);
442 if ( mf->Mf_seqspecific )
443 (*mf->Mf_seqspecific)(mf, type, leng, m);
446 if ( mf->Mf_metamisc )
447 (*mf->Mf_metamisc)(mf, type,leng,m);
451 static void sysex(struct MF * mf)
454 (*mf->Mf_sysex)(mf, msgleng(mf),msg(mf));
457 static void chanmessage(struct MF * mf,int status,int c1,int c2)
459 int chan = status & 0xf;
461 switch ( status & 0xf0 ) {
463 if ( mf->Mf_noteoff )
464 (*mf->Mf_noteoff)(mf, chan,c1,c2);
468 (*mf->Mf_noteon)(mf, chan,c1,c2);
471 if ( mf->Mf_pressure )
472 (*mf->Mf_pressure)(mf, chan,c1,c2);
475 if ( mf->Mf_parameter )
476 (*mf->Mf_parameter)(mf, chan,c1,c2);
479 if ( mf->Mf_pitchbend )
480 (*mf->Mf_pitchbend)(mf, chan,c1,c2);
483 if ( mf->Mf_program )
484 (*mf->Mf_program)(mf, chan,c1);
487 if ( mf->Mf_chanpressure )
488 (*mf->Mf_chanpressure)(mf, chan,c1);
493 /* readvarinum - read a varying-length number, and return the */
494 /* number of characters it took. */
496 static long readvarinum(struct MF * mf)
507 value = (value << 7) + (c & 0x7f);
513 static long to32bit(int c1,int c2,int c3,int c4)
518 value = (value<<8) + (c2 & 0xff);
519 value = (value<<8) + (c3 & 0xff);
520 value = (value<<8) + (c4 & 0xff);
524 static int to16bit(int c1,int c2)
526 return ((c1 & 0xff ) << 8) + (c2 & 0xff);
529 static long read32bit(struct MF * mf)
537 return to32bit(c1,c2,c3,c4);
540 static int read16bit(struct MF * mf)
545 return to16bit(c1,c2);
549 void mferror(struct MF * mf, char * s)
552 (*mf->Mf_error)(mf, s);
556 /* The code below allows collection of a system exclusive message of */
557 /* arbitrary length. The Msgbuff is expanded as necessary. The only */
558 /* visible data/routines are msginit(), msgadd(), msg(), msgleng(). */
560 #define MSGINCREMENT 128
562 static void msginit(struct MF * mf)
567 static char * msg(struct MF * mf)
572 static int msgleng(struct MF * mf)
574 return(mf->Msgindex);
577 static void msgadd(struct MF * mf,int c)
579 /* If necessary, allocate larger message buffer. */
580 if ( mf->Msgindex >= mf->Msgsize )
582 mf->Msgbuff[mf->Msgindex++] = c;
585 static void biggermsg(struct MF * mf)
588 char *oldmess = mf->Msgbuff;
589 int oldleng = mf->Msgsize;
591 mf->Msgsize += MSGINCREMENT;
592 newmess = (char *) malloc( (unsigned)(sizeof(char) * mf->Msgsize) );
595 mferror(mf, "malloc error!");
597 /* copy old message into larger new one */
598 if ( oldmess != NULL ) {
599 register char *p = newmess;
600 register char *q = oldmess;
601 register char *endq = &oldmess[oldleng];
603 for ( ; q!=endq ; p++,q++ )
607 mf->Msgbuff = newmess;
610 #if 0 /* saving time not converting write function at this time
613 * mfwrite() - The only fuction you'll need to call to write out
616 * format 0 - Single multi-channel track
617 * 1 - Multiple simultaneous tracks
618 * 2 - One or more sequentially independent
619 * single track patterns
620 * ntracks The number of tracks in the file.
621 * division This is kind of tricky, it can represent two
622 * things, depending on whether it is positive or negative
623 * (bit 15 set or not). If bit 15 of division is zero,
624 * bits 14 through 0 represent the number of delta-time
625 * "ticks" which make up a quarter note. If bit 15 of
626 * division is a one, delta-times in a file correspond to
627 * subdivisions of a second similiar to SMPTE and MIDI
628 * time code. In this format bits 14 through 8 contain
629 * one of four values - 24, -25, -29, or -30,
630 * corresponding to the four standard SMPTE and MIDI
631 * time code frame per second formats, where -29
632 * represents 30 drop frame. The second byte
633 * consisting of bits 7 through 0 corresponds the the
634 * resolution within a frame. Refer the Standard MIDI
635 * Files 1.0 spec for more details.
636 * fp This should be the open file pointer to the file you
637 * want to write. It will have be a global in order
638 * to work with Mf_putc.
641 mfwrite(format,ntracks,division,fp)
642 int format,ntracks,division;
645 int i; void mf_write_track_chunk(), mf_write_header_chunk();
647 if ( mf->Mf_putc == NULLFUNC )
648 mferror(mf, "mfmf_write() called without setting Mf_putc");
650 if ( mf->Mf_writetrack == NULLFUNC )
651 mferror(mf, "mfmf_write() called without setting Mf_mf_writetrack");
653 /* every MIDI file starts with a header */
654 mf_write_header_chunk(format,ntracks,division);
656 /* In format 1 files, the first track is a tempo map */
657 if(format == 1 && ( mf->Mf_writetempotrack ))
659 (*mf->Mf_writetempotrack)();
662 /* The rest of the file is a series of tracks */
663 for(i = 0; i < ntracks; i++)
664 mf_write_track_chunk(i,fp);
668 mf_write_track_chunk(which_track,fp)
672 unsigned long trkhdr,trklength;
673 long offset, place_marker;
674 void write16bit(),write32bit();
680 /* Remember where the length was written, because we don't
681 know how long it will be until we've finished writing */
685 printf("offset = %d\n",(int) offset);
688 /* Write the track chunk header */
690 write32bit(trklength);
692 mf->Mf_numbyteswritten = 0L; /* the header's length doesn't count */
694 if( mf->Mf_writetrack )
696 (*mf->Mf_writetrack)(which_track);
699 /* mf_write End of track meta event */
701 eputc(mf, meta_event);
702 eputc(mf, end_of_track);
706 /* It's impossible to know how long the track chunk will be beforehand,
707 so the position of the track length data is kept so that it can
708 be written after the chunk has been generated */
709 place_marker = ftell(fp);
711 /* This method turned out not to be portable because the
712 parameter returned from ftell is not guaranteed to be
713 in bytes on every machine */
714 /* track.length = place_marker - offset - (long) sizeof(track); */
717 printf("length = %d\n",(int) trklength);
720 if(fseek(fp,offset,0) < 0)
721 mferror(mf, "error seeking during final stage of write");
723 trklength = mf->Mf_numbyteswritten;
725 /* Re-mf_write the track chunk header with right length */
727 write32bit(trklength);
729 fseek(fp,place_marker,0);
730 } /* End gen_track_chunk() */
734 mf_write_header_chunk(format,ntracks,division)
735 int format,ntracks,division;
737 unsigned long ident,length;
738 void write16bit(),write32bit();
740 ident = MThd; /* Head chunk identifier */
741 length = 6; /* Chunk length */
743 /* individual bytes of the header must be written separately
744 to preserve byte order across cpu types :-( */
749 write16bit(division);
750 } /* end gen_header_chunk() */
753 #ifdef WHENISTHISNEEDED
755 * mf_write_midi_event()
757 * Library routine to mf_write a single MIDI track event in the standard MIDI
758 * file format. The format is:
760 * <delta-time><event>
762 * In this case, event can be any multi-byte midi message, such as
763 * "note on", "note off", etc.
765 * delta_time - the time in ticks since the last event.
766 * type - the type of meta event.
767 * chan - The midi channel.
768 * data - A pointer to a block of chars containing the META EVENT,
770 * size - The length of the meta-event data.
773 mf_write_midi_event(delta_time, type, chan, data, size)
774 unsigned long delta_time;
775 unsigned int chan,type;
783 WriteVarLen(delta_time);
785 /* all MIDI events start with the type in the first four bits,
786 and the channel in the lower four bits */
790 perror("error: MIDI channel greater than 16\n");
794 /* write out the data bytes */
795 for(i = 0; i < size; i++)
799 } /* end mf_write MIDI event */
802 * mf_write_meta_event()
804 * Library routine to mf_write a single meta event in the standard MIDI
805 * file format. The format of a meta event is:
807 * <delta-time><FF><type><length><bytes>
809 * delta_time - the time in ticks since the last event.
810 * type - the type of meta event.
811 * data - A pointer to a block of chars containing the META EVENT,
813 * size - The length of the meta-event data.
816 mf_write_meta_event(delta_time, type, data, size)
817 unsigned long delta_time;
818 unsigned char *data,type;
823 WriteVarLen(delta_time);
825 /* This marks the fact we're writing a meta-event */
826 eputc(mf, meta_event);
828 /* The type of meta event */
831 /* The length of the data bytes to follow */
834 for(i = 0; i < size; i++)
836 if(eputc(mf, data[i]) != data[i])
840 } /* end mf_write_meta_event */
843 mf_write_tempo(tempo)
847 /* all tempos are written as 120 beats/minute, */
848 /* expressed in microseconds/quarter note */
850 eputc(mf, meta_event);
851 eputc(mf, set_tempo);
854 eputc(mf, (unsigned)(0xff & (tempo >> 16)));
855 eputc(mf, (unsigned)(0xff & (tempo >> 8)));
856 eputc(mf, (unsigned)(0xff & tempo));
861 * Write multi-length bytes to MIDI format files
867 unsigned long buffer;
869 buffer = value & 0x7f;
870 while((value >>= 7) > 0)
874 buffer += (value & 0x7f);
877 eputc(mf, (unsigned)(buffer & 0xff));
884 }/* end of WriteVarLen */
891 * These routines are used to make sure that the byte order of
892 * the various data types remains constant between machines. This
893 * helps make sure that the code will be portable from one system
894 * to the next. It is slightly dangerous that it assumes that longs
895 * have at least 32 bits and ints have at least 16 bits, but this
896 * has been true at least on PCs, UNIX machines, and Macintosh's.
903 eputc(mf, x(unsigned)((data >> 24) & 0xff));
904 eputc(mf, (unsigned)((data >> 16) & 0xff));
905 eputc(mf, (unsigned)((data >> 8 ) & 0xff));
906 eputc(mf, (unsigned)(data & 0xff));
913 eputc(mf, (unsigned)((data & 0xff00) >> 8));
914 eputc(mf, (unsigned)(data & 0xff));
917 /* write a single character and abort on error */
923 if((mf->Mf_putc) == NULLFUNC)
925 mferror(mf, "Mf_putc undefined");
929 return_val = (mf->Mf_putc)(mf, c);
931 if ( return_val == EOF )
932 mferror(mf, "error writing");
934 mf->Mf_numbyteswritten++;
940 unsigned long mf_sec2ticks(float secs,int division, unsigned int tempo)
942 return (long)(((secs * 1000.0) / 4.0 * division) / tempo);
947 * This routine converts delta times in ticks into seconds. The
948 * else statement is needed because the formula is different for tracks
949 * based on notes and tracks based on SMPTE times.
952 float mf_ticks2sec(unsigned long ticks,int division,unsigned int tempo)
954 float smpte_format, smpte_resolution;
957 return ((float) (((float)(ticks) * (float)(tempo)) / ((float)(division) * 1000000.0)));
960 smpte_format = upperbyte(division);
961 smpte_resolution = lowerbyte(division);
962 return (float) ((float) ticks / (smpte_format * smpte_resolution * 1000000.0));
964 } /* end of ticks2sec() */
966 /* code to utilize the interface */
968 #define TRACE(x, y) do { if (x) printf y; } while (0)
971 typedef unsigned long ulg;
972 typedef unsigned char uch;
973 typedef unsigned int ui;
987 #define IBUFSIZE 1024
991 struct NoteInfo * ni;
997 int prevnoteonpitch; /* -1, nothing, 0 pause, 1-x note. */
1008 enum { TRK_NONE, TRK_READING, TRK_FINISHED };
1010 #define ALLOCSIZE 256
1012 #define NIALLOC(size) (struct NoteInfo *)malloc(sizeof (struct NoteInfo) + ((size) - 1) * sizeof (struct Notes))
1014 #define NIREALLOC(ni, size) (struct NoteInfo *)realloc((ni), sizeof (struct NoteInfo) + ((size) - 1) * sizeof (struct Notes))
1017 static void lm_error(struct MF * mf, char * s);
1019 static int lm_getc(struct MF * mf);
1020 static void lm_header(struct MF * mf, int, int, int);
1021 static void lm_trackstart(struct MF * mf);
1022 static void lm_trackend(struct MF * mf);
1023 static void lm_tempo(struct MF *, long);
1024 static void lm_noteon(struct MF *, int, int, int);
1025 static void lm_noteoff(struct MF *, int, int, int);
1028 struct NoteInfo * readmidi(int fd)
1030 struct MFX mfxi = { { 0 } };
1031 struct MF * mf = (struct MF *)&mfxi;
1033 mfxi.ni = NIALLOC(ALLOCSIZE);
1034 mfxi.allocated = ALLOCSIZE;
1036 /* set variables to their initial values */
1038 mfxi.trackstate = TRK_NONE;
1039 mfxi.prevnoteonpitch = -1;
1040 mfxi.ni->nrnotes = 0;
1041 mfxi.ni->beats = 120;
1044 mfxi.istrm.p = mfxi.istrm.len = 0;
1045 mf->Mf_getc = lm_getc;
1047 mf->Mf_header = lm_header;
1048 mf->Mf_tempo = lm_tempo;
1049 mf->Mf_trackstart = lm_trackstart;
1050 mf->Mf_trackend = lm_trackend;
1051 mf->Mf_noteon = lm_noteon;
1052 mf->Mf_noteoff = lm_noteoff;
1054 mf->Mf_error = lm_error;
1061 static void lm_error(struct MF * mf, char * s)
1063 fprintf(stderr, "%s\n", s);
1066 static int lm_getc(struct MF * mf)
1068 struct MFX * mfx = (struct MFX *)mf;
1070 /* printf("p %d, len %d\n", mfx->istrm.p, mfx->istrm.len); */
1071 if (mfx->istrm.p == mfx->istrm.len)
1073 mfx->istrm.len = read(mfx->istrm.fd, mfx->istrm.buf, IBUFSIZE);
1074 /* printf("readlen %d\n", mfx->istrm.len); */
1075 if (mfx->istrm.len <= 0)
1079 return mfx->istrm.buf[0];
1082 return mfx->istrm.buf[mfx->istrm.p++];
1085 static void lm_header(struct MF * mf, int format, int ntrks, int division)
1087 struct MFX * mfx = (struct MFX *)mf;
1089 TRACE(0, ("lm_header(%p, %d, %d, %d)\n", mf, format, ntrks, division));
1091 mfx->division = division;
1094 /* this is just a quess */
1095 static void lm_tempo(struct MF * mf, long tempo)
1097 struct MFX * mfx = (struct MFX *)mf;
1099 TRACE(0, ("lm_tempo(%p, %ld)\n", mf, tempo));
1101 if (mfx->trackstate != TRK_FINISHED)
1102 mfx->ni->beats = 60000000 / tempo;
1106 static void addnote(struct MFX * mfx, int pitch, int duration, int special)
1109 struct NoteInfo * ni;
1111 if (mfx->ni->nrnotes == mfx->allocated)
1113 mfx->allocated += ALLOCSIZE;
1114 mfx->ni = NIREALLOC(mfx->ni, mfx->allocated);
1115 if (mfx->ni == NULL)
1118 ni = mfx->ni; /* mfx->ni pointer value may have changed above */
1122 if (pitch == 0) { p = 0; s = 0; }
1123 else { pitch--; p = (pitch % 12) + 1; s = pitch / 12; }
1125 ni->note[nr].note = p;
1126 ni->note[nr].scale = s;
1128 ni->note[nr].length = duration;
1129 ni->note[nr].lextra = special;
1132 /* currently supported */
1133 static /* N 32 32. 16 16. 8 8. 4 4. 2 2. 1 1. */
1134 int vals[] = { 15, 38, 54, 78, 109, 156, 218, 312, 437, 625, 875, 1250 };
1136 static void writenote(struct MFX * mfx, int delta)
1138 ulg millinotetime = delta * 250 / mfx->division;
1143 for(i = 0; i < sizeof vals / sizeof vals[0]; i++)
1145 if (millinotetime < vals[i])
1156 addnote(mfx, mfx->prevnoteonpitch, duration, special); /* XXX think this */
1160 static void lm_trackstart(struct MF * mf)
1162 struct MFX * mfx = (struct MFX *)mf;
1164 TRACE(0, ("lm_trackstart(%p)\n", mf));
1166 if (mfx->trackstate == TRK_NONE)
1167 mfx->trackstate = TRK_READING;
1169 mfx->prevnoteonpitch = -1;
1172 static void lm_trackend(struct MF * mf)
1174 struct MFX * mfx = (struct MFX *)mf;
1175 long time = mf->Mf_currtime;
1177 TRACE(0, ("lm_trackend(%p)\n", mf));
1179 if (mfx->trackstate == TRK_READING && mfx->ni->nrnotes > 0)
1180 mfx->trackstate = TRK_FINISHED;
1182 if (mfx->prevnoteonpitch >= 0)
1183 writenote(mfx, time - mfx->prevnoteontime);
1185 mfx->prevnoteonpitch = -1;
1188 static void lm_noteon(struct MF * mf, int chan, int pitch, int vol)
1190 struct MFX * mfx = (struct MFX *)mf;
1191 long time = mf->Mf_currtime;
1193 TRACE(0, ("lm_noteon(%p, %d, %d, %d)\n", mf, chan, pitch, vol));
1195 if (vol == 0) /* kludge? to handle some (format 1? midi files) */
1198 if (mfx->trackstate != TRK_READING)
1201 if (mfx->prevnoteonpitch >= 0)
1202 writenote(mfx, time - mfx->prevnoteontime);
1205 mfx->prevnoteonpitch = 0;
1207 mfx->prevnoteonpitch = pitch + 1;
1209 mfx->prevnoteontime = time;
1212 static void lm_noteoff(struct MF * mf, int chan, int pitch, int vol)
1214 struct MFX * mfx = (struct MFX *)mf;
1215 long time = mf->Mf_currtime;
1217 TRACE(0, ("lm_noteoff(%p, %d, %d, %d)\n", mf, chan, pitch, vol));
1219 if (mfx->prevnoteonpitch >= 0)
1221 writenote(mfx, time - mfx->prevnoteontime);
1222 mfx->prevnoteonpitch = -1;
1224 mfx->prevnoteonpitch = 0;
1225 mfx->prevnoteontime = time;
1228 //{ "p", "c", "c#", "d", "d#", "e", "f", "f#", "g", "g#", "a", "a#", "h" };
1230 { 255, 0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11 , 12 };
1232 u8 lengths[] = { 4, 8, 16, 32, 64, 128 };
1234 static void countdefaults(struct NoteInfo * ni, int * length_p, int * scale_p)
1236 int lengths[15] = { 0 };
1237 int scales[15] = { 0 };
1238 int maxlenval = 0; /* (*) */
1239 int maxscaleval = 0;
1242 for (i = 0; i < ni->nrnotes; i++)
1244 struct Notes * note = &ni->note[i];
1246 lengths[note->length]++;
1247 scales[note->scale]++;
1250 maxlenval = lengths[0]; /* (*) smart compiler eliminates dead code */
1253 for (i = 1; i < 15; i++) /* `p' incremented scales[0], therefore ignored */
1255 TRACE(0, ("%d - len: %d, scale: %d\n", i, lengths[i], scales[i]));
1257 if (lengths[i] > maxlenval) {
1259 maxlenval = lengths[i];
1261 if (scales[i] > maxscaleval) {
1263 maxscaleval = scales[i];
1268 GSM_Error loadmid(char *filename, GSM_Ringtone *ringtone)
1271 struct NoteInfo * ni;
1273 int deflen, defscale;
1276 if ((fd = open(filename, O_RDONLY | O_BINARY)) < 0)
1279 return GE_CANTOPENFILE;
1282 if ((fd = open(filename, O_RDONLY)) < 0)
1285 return GE_CANTOPENFILE;
1294 countdefaults(ni, &deflen, &defscale);
1296 strcpy(ringtone->name,"GNOKII");
1298 if (ni->nrnotes<MAX_RINGTONE_NOTES)
1299 ringtone->NrNotes=ni->nrnotes;
1301 ringtone->NrNotes=MAX_RINGTONE_NOTES;
1303 for (i = 0; i < ringtone->NrNotes; i++)
1305 struct Notes * note = &ni->note[i];
1307 ringtone->notes[i].note=notes[note->note];
1308 ringtone->notes[i].note=notes[note->note]+(note->scale%4)*14;
1310 ringtone->notes[i].duration=lengths[note->length];
1312 ringtone->notes[i].duration=ringtone->notes[i].duration*1.5;
1314 ringtone->notes[i].tempo=ni->beats;