OSDN Git Service

最初のコミット
[winaudioj/stedx.git] / itor.cpp
1 /*************************************/
2 /* STD MIDI file converter / player  */
3 /*************************************/
4
5 /*
6   This code is brought from Takayuki Toda's 'rc_converters'.
7
8   Modified 2000 by Daisuke Nagano <breeze.nagano@nifty.ne.jp>
9  */
10 //#include "stdafx.h"
11
12 #ifdef HAVE_CONFIG_H
13 #include "config.h"
14 #endif /* HAVE_CONFIG_H */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 #include "rcpfile.h"
21 #include "rcpdef.h"
22 #include "rcddef.h"
23
24 #if STDC_HEADERS
25 # include <string.h>
26 #else
27 # ifndef HAVE_MEMCPY
28 #  define memcpy(d, s, n) bcopy ((s), (d), (n))
29 #  define memmove(d, s, n) bcopy ((s), (d), (n))
30 # endif
31 #endif
32
33 #define TRACK_LEN 65536
34
35 static struct head {
36   char chunk[4];
37   long length;
38   short format;
39   short ntrks;
40   short division;
41 } std_head;
42
43 static struct track {
44   char chunk[4];
45   long length;
46 } std_trk;
47
48 static int opt, comment;
49 static int sameflag;
50
51 static unsigned char *rcpptr, *lastptr;
52 static unsigned char *inptr, *buf;
53 static unsigned char *note, *note_data;
54 static int incount;
55 static int tc;
56 static int fmt;
57 static int pt;
58 static int midi_ch;
59 static int tb_mode,tb_max, ratio,rcp_base;
60 static int step, stepx;
61 static int barlen, barunit, stepsum;
62 static int fixflag;
63 static char std_name[256];
64
65 static const char memoinit[] = "                                    ";
66 static const char ttlinit[] = "                                                                ";
67 static int memoflag;
68 static int beatflag;
69 static int tempoflag;
70 static int chfixflag,chbport;
71
72 static int tempofix;
73 static int exc_no,exc_id,barno,devno_fix,notoff,chport;
74
75 static int trk;
76 static int len;
77 static int cmd;
78 static int d_byte;
79
80 static int nbuf[16], vbuf[16], gbuf[16], cbuf[16];
81
82 const static int beat[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
83 static int      barlenb[2048];
84
85 static char     rc_path[256];
86 static char     exc_buf[32*1024+4];
87
88 static int tai_compres(int);
89 static int same_compres(int);
90 static int add_set(int, int *);
91 static int meas_len(int, int);
92
93 static unsigned char * strncpy0( unsigned char *dst, unsigned char *src, int n )
94 {
95   int i;
96
97   for( i = 0; i < n; i++ ) {
98     dst[i] = src[i];
99   }
100   dst[n] = 0;
101   return( dst );
102 }
103
104 static int alloc_mem( void )
105 {
106   void *work;
107
108   if( ( work = (void *)malloc( TRACK_LEN * 8 ) ) < 0 ) {
109     fprintf( stderr, "Memory exhausted\n" );
110     return 1;
111   }
112
113   note_data = ( unsigned char * )work;
114   buf = ( unsigned char * )( (unsigned char *)work + TRACK_LEN * 4 );
115
116   return 0;
117 }
118
119 static void destroy_mem( void )
120 {
121   if ( note_data != NULL )
122     free(note_data);
123
124   return;
125 }
126
127 static void get_data( unsigned char *s, int bc )
128 {
129   memmove( ( char * )s, ( char *)( inptr + incount ), bc );
130   incount += bc;
131
132   return;
133 }
134
135 static void put_data( unsigned char *s, int bc )
136 {
137   if( lastptr <= rcpptr + bc ) {
138     fprintf( stderr, "Buffer exhausted\n" );
139     return;
140   }
141   memmove( ( char * )rcpptr, ( char * )s, bc );
142   rcpptr += bc;
143
144   return;
145 }
146
147 static void strpaste( unsigned char *dst, unsigned char *src )
148 {
149   while( *src ) {
150     *dst++ = *src++;
151   }
152 }
153
154 static void strnpaste( unsigned char *dst, unsigned char *src, int n )
155 {
156   while( n-- ) {
157     *dst++ = *src++;
158   }
159 }
160
161 static void ctrlcut( char *s )
162 {
163   while(*s) {
164     if( *s == 13 ) { *s = 32; }
165     if( *s == 27 ) { *s = 32; }
166     s++;
167   }
168 }
169
170 /**/
171
172 static int get_delta( int p )
173 {
174   register int val, i, d;
175   
176   val = 0;
177   d_byte = 0;
178   
179   for( i = 0; i < 4; i++ ) {
180     d = buf[p++];
181     d_byte++;
182     val = ( val << 7 ) + ( d & 0x7f );
183     if( d < 0x80 ) {
184       return( val );
185     }
186   }
187   
188   fprintf( stderr, "Invalid delta time.\n" );
189   return(0); /**//*warning*//**/
190 }
191 /**/
192
193 static void proc_beat( int high, int low )
194 {
195   /*
196     if( beatflag ) {
197     return;
198     }
199     */
200   if( !beatflag ) {
201     RCP_HEAD.Beathigh = high;
202     RCP_HEAD.Beatlow = low;
203   }
204
205   barlen = (RCP_HEAD.Timebase+RCP_HEAD.Timebaseh*256) * 4 * high / low;
206   if(trk==0 && barno<2048){barlenb[barno]=barlen;}
207 }
208
209 static int proc_header( void )
210 {
211   int   i;
212   uint8 b[14];
213   
214   get_data( b, 14 );
215   
216   if( strncmp( (char*)b, "MThd", 4 ) ) {
217     unsigned char tmp[128];
218     get_data( tmp, 128-14 ); /* Mac binary */
219     
220     get_data( b, 14 );
221     
222     if( strncmp( (char*)b, "MThd", 4 ) ) {
223       /*fprintf( stderr, "This file is not SMF file (MThd).\n" );*/
224       return 1;
225     }
226   }
227   
228   std_head.length = b[4]*256*256*256 + b[5]*65536 + b[6]*256 + b[7];
229   std_head.format = b[8]*256 + b[9];
230   std_head.ntrks  = b[10]*256 + b[11];
231   std_head.division = b[12]*256 + b[13];
232
233   if( !comment ) {
234     printf( "format =%3d    ntrk =%3d    division =%4d\n",
235             std_head.format, std_head.ntrks, std_head.division );
236   }
237   
238   if( ( fmt = std_head.format ) != 0 && fmt != 1 ) {
239     fprintf( stderr, "Cannot treat format %d.\n", fmt );
240     return 1;
241   }
242   
243   if(std_head.ntrks>18){
244     RCP_HEAD.trkmax = 36;
245   }else{
246     RCP_HEAD.trkmax = 18;
247   }
248   
249   /*
250   strpaste( RCP_HEAD.memo +  28, ( unsigned char * )"  ¤³¤Î¥Ç¡¼¥¿¤Ï¡¢" );
251   strpaste( RCP_HEAD.memo +  84, ( unsigned char * )"  É¸½àMIDI¥Õ¥©¡¼¥Þ¥Ã¥È¤«¤\81E );
252   strpaste( RCP_HEAD.memo + 140, ( unsigned char * )"  ItoR.x (v1.00)¤Ë¤è¤\81E );
253   strpaste( RCP_HEAD.memo + 151, ( unsigned char * )version );
254   strpaste( RCP_HEAD.memo + 196, ( unsigned char * )"  ÊÑ´¹¤µ¤\81EÞ¤·¤¿¡£" );
255   strpaste( RCP_HEAD.memo + 252, ( unsigned char * )"  Copyright 1990-97" );
256   strpaste( RCP_HEAD.memo + 280, ( unsigned char * )"           HARPOON,TURBO" );
257   */
258   
259   if( !tb_mode || std_head.division > tb_max ) {
260     rcp_base=48;if( tb_mode ) {rcp_base=tb_max;}
261     
262     RCP_HEAD.Timebase = rcp_base;
263     RCP_HEAD.Timebaseh = rcp_base>>8;
264     tb_mode = 0;
265     ratio = std_head.division;
266     
267     if( !comment ) {
268       if( std_head.division > tb_max ) {
269         printf( "¥¿¥¤¥à¥Ù¡¼¥¹¤\81Ed¤ËÊѹ¹¤·¤Þ¤¹¡£\n\n",tb_max );
270       }
271     }
272     
273   } else {
274     RCP_HEAD.Timebase = std_head.division;
275     RCP_HEAD.Timebaseh = std_head.division>>8;
276     
277     if( !comment ) {
278       printf( "¥¿¥¤¥à¥Ù¡¼¥¹¤òÊѹ¹¤·¤Þ¤»¤ó¡£\n\n" );
279     }
280     
281   }
282   
283   RCP_HEAD.Tempo = 120;
284   beatflag = 0;
285   proc_beat( 4, 4 );
286   RCP_HEAD.Key = 0;
287   RCP_HEAD.Playbias = 0;
288   
289   tempoflag = 0;
290   
291   tc = 0x0586;
292   
293   for(i=0;i<2048;i++){barlenb[i]=0;}
294   
295   return 0;
296 }
297
298 static void entry( int d0, int d1, int d2, int d3 )
299 {
300
301   /*if(len && d0==0xe6 && note[len-4]==0xe6){len-=4;d1=note[len+1];}*//**/
302
303   note[ len++ ] = d0;
304   note[ len++ ] = d1;
305   note[ len++ ] = d2;
306   note[ len++ ] = d3;
307   
308   if( len >= 65492+65536*3 ) {
309     fprintf( stderr, "Track buffer overflow\n" );
310     len-=4;
311     return;
312   }
313
314   return;
315 }
316
317 static void flash( int dt )
318 {
319   int dx, i, j;
320   
321   while( dt > 0 ) {
322     
323     if( dt <= 0xf0 ) {
324       dx = dt;
325     } else {
326       dx = 0xf0;
327     }
328     
329     if( dx + barunit > barlen ) {
330       dx = barlen - barunit;
331     }
332     
333     for( i = 0; i < 16; i++ ) {
334       if( gbuf[i] ) {
335         
336         if(fmt!=0 && !chfixflag && midi_ch!=cbuf[i]){
337           if( midi_ch == -1 ) {
338             TRACK.MIDI_CH = cbuf[i];
339           }else{
340             entry( 0xe6, 0x00, cbuf[i]+1, 0x00 );
341           }
342           midi_ch=cbuf[i];
343         }
344         
345         /*if( gbuf[i] <= dx ) {*/
346         if( gbuf[i] <= 0xf0 ) {/**/
347           entry( nbuf[i], 0, gbuf[i], vbuf[i] );
348           for( j = i; j < 15; j++ ) {
349             nbuf[j] = nbuf[j+1];
350             vbuf[j] = vbuf[j+1];
351             gbuf[j] = gbuf[j+1];
352             cbuf[j] = cbuf[j+1];
353           }
354           nbuf[15] = vbuf[15] = gbuf[15] = cbuf[15] = 0;
355           i--;
356         } else {
357           entry( nbuf[i], 0, dx + 1, vbuf[i] );
358           gbuf[i] -= dx;
359         }
360       } else {
361         break;
362       }
363     }
364     
365     if( note[ len - 4 ] !=0xde &&
366         note[ len - 4 ] < 0xf0 && ( note[ len - 3 ] + dx ) <= 0xf0 ) {
367       note[ len - 3 ] += dx ;
368     } else {
369       if(note[len-4]==0xf7){
370         int ll=len-4;
371         while(note[ll]==0xf7){ll-=4;}
372         if(note[ll]==0x98 && ( note[ ll + 1 ] + dx ) <= 0xf0 ) {
373           note[ ll + 1 ] += dx ;
374         } else {
375           entry( 0x00, dx, 0, 0 );
376         }
377       }else{
378         entry( 0x00, dx, 0, 0 );
379       }
380     }
381     
382     dt -= dx;
383     
384     if( ( barunit += dx ) == barlen ) {
385       entry( 0xfd, 0x00, 0x00, 0x00 );
386       barunit = 0;
387       if(barlenb[barno]>0 && trk>0){barlen=barlenb[barno];}
388       barno++;
389     }
390     
391   }
392   
393   stepsum = 0;
394 }
395
396 static void proc_dummy( int dt )
397   {
398     if( !tb_mode ) {
399       step += dt;
400       dt = ( step * rcp_base / ratio ) - stepx;
401       stepx += dt;
402     }
403
404     if( fmt == 0 ) {
405       stepsum += dt;
406     } else {
407       flash( dt );
408     }
409   }
410
411 static void check( int data )
412   {
413     cmd = data & 0xf0;
414
415     /*  if(cmd==0x80){return;}*/
416
417     if( !fixflag ) {
418       data &= 0x0f;data+=chport;
419       if( midi_ch != data ) {
420         if( fmt == 1 ) {
421           flash(stepsum);/**/
422           if( midi_ch == -1 ) {
423             TRACK.MIDI_CH = data;
424           }else{
425             if(!chfixflag){
426               entry( 0xe6, 0x00, data+1, 0x00 );
427             }
428           }
429         }
430         midi_ch = data;
431       }
432     }
433   }
434
435 static int search( int pp )
436   {
437     /*  int n, dt, cc, ch, ccmd, last, i,ocmd;*/
438     int dt, last, i;
439     short n,cc, ch, ccmd,ocmd;
440
441     n = buf[pp];
442     ccmd = cmd;
443     ocmd = cmd;
444     last = std_trk.length;
445     pp += 2;
446     dt = 0;
447     ch = midi_ch&15;/**/
448
449     while( pp < last ) {
450       if(notoff!=0 && dt>255){return( 1 );}
451
452       dt += get_delta( pp );
453       pp += d_byte;
454       if( ( cc = buf[pp] ) < 0x80 ) {
455         if( ccmd == 0x80 && cc == n && ( fixflag || ch+chport == midi_ch ) ) {
456           return( dt );
457         } else {
458           if( ccmd == 0x90 && cc == n &&
459               buf[pp+1] == 0x00 && ( fixflag || ch+chport == midi_ch ) ) {
460             return( dt );
461           } else {
462             pp += 2;
463             if(ccmd>=0xc0 && ccmd<=0xdf){pp--;}
464           }
465         }
466       } else {
467         ocmd=cc;
468         switch( cc & 0xf0 ) {
469         case 0x80 :
470           if( buf[pp+1] == n &&
471               ( fixflag || cc == ( 0x80 + (midi_ch&15) ) ) ) {
472             return( dt );
473           }
474           pp += 3;
475           ch = cc & 0x0f;
476           break;
477         case 0x90 :
478           if( buf[pp+1] == n && buf[pp+2] == 0x00 &&
479               ( fixflag || cc == ( 0x90 + (midi_ch&15) ) ) ) { 
480             return( dt );
481           }
482           pp += 3;
483           ch = cc & 0x0f;
484           break;
485         case 0xa0 :
486         case 0xb0 :
487         case 0xe0 :
488           pp += 3;
489           ch = cc & 0x0f;
490           break;
491         case 0xc0 :
492         case 0xd0 :
493           pp += 2;
494           ch = cc & 0x0f;
495           break;
496         case 0xf0 :
497           switch( cc ) {
498           case 0xf0 :
499           case 0xf7 :
500             pp += 1;
501             i = get_delta( pp );
502             pp += d_byte;
503             pp += i;
504             break;
505           case 0xff :
506             pp += 2;
507             i = get_delta( pp );
508             pp += d_byte;
509             pp += i;
510             break;
511           default :
512             fprintf( stderr, "Invalid format\n" );
513             /*exit(18);*/
514             return 1;
515             break;
516           }
517           break;
518         }
519         ccmd = cc & 0xf0;
520       }
521     }
522     notoff=1;
523     return( 1 );
524   }
525
526 static void ent_buf( int nt, int vl, int gt )
527   {
528     int i;
529
530     /*
531       if( !comment ) {
532       printf( "<nt=%d vl=%d gt=%d>\n", nt, vl, gt );
533       }
534       */
535
536     if( gt <= 0xf0 ) {
537       entry( nt, 0, gt,vl );return;
538     } else {
539       entry( nt, 0, 255,vl );
540     }
541
542     for( i = 0; i < 16; i++ ) {
543       if( !gbuf[i] || (nbuf[i] == nt && cbuf[i] == midi_ch) ) {
544         nbuf[i] = nt;
545         vbuf[i] = vl;
546         gbuf[i] = gt;
547         cbuf[i] = midi_ch;
548         return;
549       }
550     }
551
552     for( i = 0; i < 15; i++ ) {
553       nbuf[i] = nbuf[i+1];
554       vbuf[i] = vbuf[i+1];
555       gbuf[i] = gbuf[i+1];
556       cbuf[i] = cbuf[i+1];
557     }
558
559     nbuf[15] = nt;
560     vbuf[15] = vl;
561     gbuf[15] = gt;
562     cbuf[15] = midi_ch;
563
564     /*
565       fprintf( stderr, "¥Î¡¼¥È¥ª¡¼¥Ð¥Õ¥ú½¼\n" );        exit(18);
566       */
567   }
568
569 static void note_off( int p )
570   {
571     /* do nothing */
572   }
573
574 static void note_on( int p )
575   {
576     int gt;
577
578     if( fmt == 0  ) {
579       if( midi_ch != TRACK.MIDI_CH  ) {
580         return;
581       }
582       flash( stepsum );
583     }
584
585     if( buf[p+1] ) {
586       if( !( gt = search( p ) ) ) {
587         return;
588       }
589       if( !tb_mode ) {
590         if( !( gt = gt * rcp_base / ratio ) ) {
591           /*                    if( !( gt = (gt * rcp_base+(ratio>>1)) / ratio ) ) {*/
592           gt = 1;
593         }
594       }
595       ent_buf( buf[p], buf[p+1], gt );
596     }
597   }
598
599 static void aft_key( int p )
600   {
601     if( fmt == 0  ) {
602       if( midi_ch != TRACK.MIDI_CH  ) {
603         return;
604       }
605       flash( stepsum );
606     }
607
608     entry( 0xed, 0x00, buf[p], buf[p+1] );
609   }
610
611 static void ctl_chg( int p )
612   {
613     if( fmt == 0  ) {
614       if( midi_ch != TRACK.MIDI_CH  ) {
615         return;
616       }
617       flash( stepsum );
618     }
619
620     entry( 0xeb, 0x00, buf[p], buf[p+1] );
621   }
622
623 static void prg_chg( int p )
624   {
625     if( fmt == 0  ) {
626       if( midi_ch != TRACK.MIDI_CH  ) {
627         return;
628       }
629       flash( stepsum );
630     }
631
632     entry( 0xec, 0x00, buf[p], 0x00 );
633   }
634
635 static void aft_tch( int p )
636   {
637     if( fmt == 0  ) {
638       if( midi_ch != TRACK.MIDI_CH  ) {
639         return;
640       }
641       flash( stepsum );
642     }
643
644     entry( 0xea, 0x00, buf[p], 0x00 );
645   }
646
647 static void pt_bend( int p )
648   {
649     if( fmt == 0  ) {
650       if( midi_ch != TRACK.MIDI_CH  ) {
651         return;
652       }
653       flash( stepsum );
654     }
655
656     entry( 0xee, 0x00, buf[p], buf[p+1] );
657   }
658
659 static void run_sts( int p )
660   {
661     if( fmt == 0  ) {
662       if( midi_ch != TRACK.MIDI_CH  ) {
663         return;
664       }
665       flash( stepsum );
666     }
667
668     switch( cmd ) {
669     case 0x80 : note_off(p); break;
670     case 0x90 : note_on(p);  break;
671     case 0xa0 : aft_key(p);  break;
672     case 0xb0 : ctl_chg(p);  break;
673     case 0xc0 : prg_chg(p);  break;
674     case 0xd0 : aft_tch(p);  break;
675     case 0xe0 : pt_bend(p);  break;
676     }
677   }
678
679 static int num_check( int num, int limit )
680   {
681     if( num > limit ) {
682       return( limit );
683     } else {
684       return( num );
685     }
686   }
687
688 static void clr_ttl( void )
689   {
690     strpaste( ( unsigned char * )RCP_HEAD.title, ( unsigned char * )ttlinit );
691   }
692
693 static void proc_meta( int meta, unsigned char *text, int length )
694   {
695     int i;
696     unsigned char work[128];
697
698     if( fmt == 0 /*&& trk*/ ) {
699       flash( stepsum );
700     }
701
702     switch( meta ) {
703     case 0x03:
704       if( !memoflag ) {
705         ctrlcut((char*)text);
706         memoflag = 1;
707         if(trk){
708           if((127<text[35] && 161>text[35]) || 224<text[35]){
709             text[35]=0;}
710           strnpaste( TRACK.Memo, text, num_check( length, 36 ) );
711           if(strncmp((char*)text,"PartA",5)==0){chport=0;}
712           if(strncmp((char*)text,"PartB",5)==0){chport=16;}
713         }
714         if( trk == 0 ) {
715           clr_ttl();
716           if((127<text[63] && 161>text[63]) || 224<text[63]){
717             text[63]=0;}
718           strnpaste( RCP_HEAD.title, text, num_check( length, 64 ) );
719         }
720       }
721       break;
722     case 0x01:
723       /*if( !step ) {*/
724       if( step<barlen ) {
725         if( !memoflag ) {
726           ctrlcut((char*)text);
727           memoflag = 1;
728           if(trk){
729             if((127<text[35] && 161>text[35]) || 224<text[35]){
730               text[35]=0;}
731             strnpaste( TRACK.Memo, text, num_check( length, 36 ) );
732             if(strncmp((char*)text,"PartA",5)==0){chport=0;}
733             if(strncmp((char*)text,"PartB",5)==0){chport=16;}
734           }
735           if( trk == 0 ) {
736             clr_ttl();
737             if((127<text[63] && 161>text[63]) || 224<text[63]){
738               text[63]=0;}
739             strnpaste( RCP_HEAD.title, text, num_check( length, 64 ) );
740           }
741           if(!step){break;}
742         }
743       } /* no break */
744     case 0x04:
745     case 0x05:
746     case 0x06:
747     case 0x07:
748     case 0x02:/*turbo*/
749       ctrlcut((char*)text);
750     next:
751       strcpy( ( char * )work, ( char * )memoinit );
752       strnpaste( work, text, num_check( length, 64 ) );
753       if(length<20){length=20;}
754       entry( 0xf6, 0x00, work[0], work[1] );
755       for( i = 2; i < 20; i += 2 ) {
756         entry( 0xf7, 0x00, work[i], work[i+1] );
757       }
758       if(length>20){strcpy((char*)text,(char*)&text[20]);length-=20;goto next;}
759
760       /*                for( i = 2; i < length; i += 2 ) {
761                         entry( 0xf7, 0x00, work[i], work[i+1] );
762                         }
763                         */
764       break;
765     case 0x20:
766       midi_ch = 0;
767       /*fixflag = 1;*/
768       if(!chfixflag || fmt==0){entry( 0xe6, 0x00, (text[0]+1)+chport, 0x00 );}
769       break;
770     case 0x51:
771       if( !tempoflag && trk == 0 && tempofix==0) {
772         i = 60000000 / ( ( text[0] << 16 ) + ( text[1] << 8 ) + text[2] );
773         /*
774           if( i > 255 ) {
775           i = 255;
776           } else */{
777           if( i == 0 ) {
778             i = 1;
779           }
780         }
781
782           RCP_HEAD.Tempo = i;
783           tempoflag = 1;
784
785           if( i > 255 ) {
786             RCP_HEAD.Tempo = 255;goto skip;}
787
788       } else {
789       skip:
790         if( !tempoflag && trk == 0 ) {
791           i = 60000000 / ( ( text[0] << 16 ) + ( text[1] << 8 ) + text[2] );
792           RCP_HEAD.Tempo = i>>1;
793           tempoflag = 1;
794         }
795
796         i = 60000000 / ( ( text[0] << 16 ) + ( text[1] << 8 ) + text[2] );
797         i = 64 * i / RCP_HEAD.Tempo;
798         /*ÀßÄꤷ¤¿¤¤¥Æ¥ó¥Ý¡à½é´\81EßÄ\81EÆ¥ó¥Ý¡ß64*/
799         if( i > 255 ) {
800           i = 255;
801         } else {
802           if( i == 0 ) {
803             i = 1;
804           }
805         }
806         entry( 0xe7, 0x00, i, 0x00 );
807         tempoflag = 1;
808       }
809       break;
810     case 0x58:
811       proc_beat( text[0], beat[ text[1] ] );
812       beatflag = 1;
813       break;
814     case 0x21:
815       if((text[0])==1){chport=16;}else{chport=0;}
816       /*entry( 0xe6, 0x00, (midi_ch+1)+chport, 0x00 );*/
817       break;
818     case 0x00:
819       /*        case 0x02:*/
820     case 0x2f:
821     case 0x54:
822     case 0x59:
823     case 0x7f:
824       break;
825     default :
826       if( !comment ) {
827         printf( "FF %02X (Unknown meta event)\n", meta );
828       }
829       break;
830     }
831   }
832
833 static void proc_excl( unsigned char *text, int length ,int code)
834   {
835     int h, m, l;
836     int hh, mm, ll;
837     int i;
838
839     if( fmt == 0 /*&& trk*/ ) {
840       flash( stepsum );
841     }
842
843     text[ length ] = 0xf7 ;
844
845     if( devno_fix !=0 && text[0] == 0x41 && text[3] == 0x12){
846       text[1]=0x10;}
847
848     if( length < 9 || length > 15 ||
849         text[0] != 0x41 || text[3] != 0x12 ||
850         text[ length-1 ] != 0xf7 ) {
851
852       if( text[0] == 0x41 && text[3] == 0x12 && length<9 ){return;}
853
854       if(code==0xf0){
855       nor:
856         i=0;
857         entry( 0x98, 0, 0, 0 );
858         while(i<length){
859           entry( 0xf7, 0, text[i], text[i+1] );
860           if( text[i] == 0xf7 || text[ i+1 ] == 0xf7 ) {break;}
861           i=i+2;
862         }
863       }else{
864         if(len==0 || note[len-4]!=0xf7){goto nor;}
865         i=0;
866
867         if(note[len-2]==0xf7){note[len-2]=text[i++];}
868         if(note[len-1]==0xf7){note[len-1]=text[i++];}
869
870         while(i<length){
871           entry( 0xf7, 0, text[i], text[i+1] );
872           if( text[i] == 0xf7 || text[ i+1 ] == 0xf7 ) {break;}
873           i=i+2;
874         }
875       }
876
877       /*fprintf( stderr, "ÉÔÀµEXCLUSIVE¥á¥Ã¥»¡¼¥¸ \n" );
878         exit(18);*/
879
880       return;
881     }
882
883     if( exc_no != text[1] || exc_id != text[2] ) {
884       exc_no = text[1];exc_id = text[2];
885       entry( 0xdf, 0, exc_no, exc_id );
886     }
887
888     h = text[4]; m = text[5]; l = text[6];
889     hh = mm = ll = -1;
890
891     for( i = 7; i < length - 2; i++ ) {
892       if( hh != h || mm != m  ) {
893         entry( 0xdd, 0x00, h, m );
894         hh = h; mm = m; ll = l;
895       }
896       entry( 0xde, 0x00, l, text[i] );
897       if( l++ == 0x7f ) {
898         l = 0;
899         m++;
900       }
901     }
902   }
903
904 static int proc_next( void )
905   {
906     int meta, code, length,last;
907     unsigned char text[4096];
908
909     last = std_trk.length;
910     cmd = 0x00;
911     step = stepx = 0;
912
913     while(pt<last) {
914
915       proc_dummy( get_delta(pt) );
916       pt += d_byte;
917
918       if( ( code = buf[pt] ) == 0xff ) {
919         pt++;
920         meta = buf[pt++];
921         length = get_delta(pt);
922         pt += d_byte;
923         strncpy0( text, buf + pt, length );
924         if( fmt == 1 || trk == 0 ) {
925           proc_meta( meta, text, length );
926         }
927         pt += length;
928         if( meta == 0x2f ) {
929           return 0;
930         }
931       } else {
932         switch( code & 0xf0 ) {
933         case 0x80: /*check( buf[pt] ); note_off(pt+1);*/
934           cmd = buf[pt] & 0xf0;
935           pt += 3; break;
936         case 0x90: check( buf[pt] ); note_on(pt+1);  pt += 3; break;
937         case 0xa0: check( buf[pt] ); aft_key(pt+1);  pt += 3; break;
938         case 0xb0: check( buf[pt] ); ctl_chg(pt+1);  pt += 3; break;
939         case 0xc0: check( buf[pt] ); prg_chg(pt+1);  pt += 2; break;
940         case 0xd0: check( buf[pt] ); aft_tch(pt+1);  pt += 2; break;
941         case 0xe0: check( buf[pt] ); pt_bend(pt+1);  pt += 3; break;
942         case 0xf0:
943           if( code != 0xf0 && code != 0xf7 ) {
944             fprintf( stderr, "Invalid MIDI message (%02X)\n", code );
945             return 1;
946           }
947           pt++;
948           length = get_delta(pt);
949           pt += d_byte;
950           if( fmt == 1 || trk == 0 ) {
951             if(length<32*1024){
952               strncpy0( (uint8*)exc_buf, buf + pt, length );
953               proc_excl( (uint8*)exc_buf, length ,code);
954             }
955           }
956           pt += length;
957           break;
958         default :  run_sts(pt); pt += 2;
959           if(cmd>=0xc0 && cmd<=0xdf){pt--;}
960           break;
961         }
962       }
963     }
964   }
965
966 static void track_end( void )
967 {
968   if( fmt == 0 ) {
969     flash( stepsum );
970   }
971   
972   if(trk){
973     while(len>0) {
974       if( ( note[ len - 4 ] == 0x00 && note[ len - 2 ] == 0x00 ) ||
975           note[ len - 4 ] == 0xfd ) {
976         len -= 4;
977       } else {
978         break;
979       }
980     }
981   }
982   
983   entry( 0xfe, 0, 0, 0 );
984   len=tai_compres(len);
985   if(sameflag){len=same_compres(len);}
986   
987   if( len > 65488 ) {
988     fprintf( stderr, "Track overflow.\n" );
989     /*          len=65488-4;
990                 entry( 0xfe, 0, 0, 0 );*/
991   }
992   
993   TRACK.len_high = ( len + 44 ) >> 8;
994   TRACK.len_low = (( len + 44 ) >> 16 ) + ( len + 44 ) & 0xff;
995 }
996
997 static int proc_track( void )
998 {
999   int i;
1000   unsigned char b[8];
1001   
1002   exc_no=0x10;exc_id=0x16;chport=0;
1003   
1004   if( fmt == 1 || trk == 0 ) {
1005     get_data( b, 8 );
1006     strncpy(std_trk.chunk, (char*)b, 4);
1007     std_trk.length = b[4]*256*256*256 + b[5]*65536 + b[6]*256 + b[7];
1008     if( strncmp( std_trk.chunk, "MTrk", 4 ) ) {
1009       fprintf( stderr, "Invalid SMF file (MTrk)\n" );
1010       return 1;
1011     }
1012     get_data( buf, std_trk.length );
1013   }
1014
1015   for( i = 0; i < 16; i++ ) {
1016     nbuf[i] = vbuf[i] = gbuf[i] = cbuf[i] = 0;
1017   }
1018   
1019   pt = 0;
1020   len = 0;
1021   
1022   barunit = 0; stepsum = 0;
1023   fixflag = 0;
1024   
1025   TRACK.track_no = trk;
1026   TRACK.rhythm_flag = 0x00;
1027   
1028   if( fmt == 0 ) {
1029     TRACK.MIDI_CH = midi_ch = trk ;
1030   } else {
1031     TRACK.MIDI_CH = 0 ;
1032     midi_ch = -1;
1033   }
1034   
1035   TRACK.Play_bias = 0x00;
1036   TRACK.ST_offset = 0x00;
1037   TRACK.Mode = 0x00;
1038   
1039   strpaste( TRACK.Memo, ( unsigned char * )memoinit );
1040   memoflag = 0;
1041   barno=0;
1042   if(barlenb[0]>0 && trk>0){barlen=barlenb[barno++];}
1043   
1044   if( !comment ) {
1045     printf( "Track= %2d  %04X\n", trk, std_trk.length );
1046   }
1047   
1048   if(chbport!=0 && trk>16 ){chport=16;}
1049   
1050   notoff=0;
1051   if ( proc_next() != 0 ) return 1;
1052
1053   track_end();
1054   
1055   if( trk == 0 ) {
1056     put_data( RCP_HEAD.mark, 0x0586 );
1057   }
1058   
1059   if(chfixflag){
1060     if( std_head.format==0 ){
1061       TRACK.MIDI_CH = trk ;
1062     }else{
1063       if(trk){TRACK.MIDI_CH = trk-1 ;}
1064     }
1065   }
1066   
1067   put_data( ( unsigned char * )&TRACK.len_low, 44 );
1068   put_data( ( unsigned char * )note, len );
1069   tc += len + 44;
1070
1071   return 0;
1072 }
1073
1074 static void dummy_track( void )
1075   {
1076     len = 0;
1077
1078     TRACK.track_no = trk;
1079     TRACK.rhythm_flag = 0x00;
1080     TRACK.MIDI_CH = 255;
1081     TRACK.Play_bias = 0x00;
1082     TRACK.ST_offset = 0x00;
1083     TRACK.Mode = 0x00;
1084     strpaste( TRACK.Memo, ( unsigned char * )memoinit );
1085
1086     if( !comment ) {
1087       printf( "Track= %2d  dummy\n", trk );
1088     }
1089
1090     track_end();
1091
1092     put_data( ( unsigned char * )&TRACK.len_low, 44 );
1093     put_data( ( unsigned char * )note, len );
1094     tc += len + 44;
1095   }
1096
1097 #if 0
1098 static void option( char *s )
1099   {
1100     char c;
1101
1102     opt = 0;
1103     comment = 0;
1104     tb_mode = 0;
1105     tb_max = 48;
1106     sameflag = 0;
1107     chfixflag = 0;
1108     tempofix = 0;
1109     devno_fix = 0;
1110     chbport=0;
1111
1112     if( !*s ) {
1113       usage();
1114     }
1115
1116     while( c = *s++ ) {
1117       switch( c ) {
1118       case 'C' :
1119       case 'c' :
1120         opt = 0;
1121         break;
1122       case 'B' :
1123       case 'b' :
1124         opt = 1;
1125         break;
1126       case 'P' :
1127       case 'p' :
1128         opt = 2;
1129         break;
1130       case 'K' :
1131       case 'k'  :
1132         opt = 2;
1133         break;
1134       case 'R' :
1135       case 'r'  :
1136         opt = 3;
1137         break;
1138       case 'X' :
1139       case 'x' :
1140         opt = 4;
1141         break;
1142       case 'T' :
1143       case 't' :
1144         tb_mode = 1;
1145         tb_max = 0;
1146         while(*s>='0' && *s<='9'){
1147           tb_max=tb_max*10+((*s++)-'0');
1148         }
1149         if(tb_max<48){tb_max=240;}
1150         break;
1151       case 'N' :
1152       case 'n' :
1153         comment = 1;
1154         break;
1155       case ' ' :
1156         opt = 0;
1157         break;
1158       case 'S' :
1159       case 's' :
1160         sameflag = 1;
1161         break;
1162       case 'F' :
1163       case 'f' :
1164         chfixflag = 1;
1165         break;
1166       case 'G' :
1167       case 'g' :
1168         chbport = 1;
1169         break;
1170       case 'E' :
1171       case 'e' :
1172         tempofix = 1;
1173         break;
1174       case 'D' :
1175       case 'd' :
1176         devno_fix = 1;
1177         break;
1178       default :
1179         usage();
1180         break;
1181       }
1182     }
1183
1184   }
1185 #endif
1186
1187 int itor(  char *smf_data,  char *rcp_buf )
1188 {
1189   int i;
1190
1191   /* Initialize all configurable valuables */
1192   
1193   opt = 0;
1194   chfixflag = 0;
1195   devno_fix = 0;
1196
1197   tb_mode =  1; /* 0:time base is converted into 48 */
1198   tb_max = 480; /* Max number of time base */
1199   chbport =  1; /* translate all tracks > 16 into port B */
1200   tempofix = 1; /* fixes errors of tempo change */
1201   sameflag = 1; /* unifies all tracks with SAME MEAS */
1202   comment  = 1; /* suppress all comments */
1203   
1204
1205   /* allocate internal work memory */
1206   
1207   note_data = NULL;
1208
1209   if ( alloc_mem() != 0 ) return 0;
1210   
1211   inptr   = (uint8 *)smf_data;
1212   rcpptr  = (uint8 *)rcp_buf;
1213   incount = 0;
1214   lastptr = rcpptr + 512*1024; /* DATA_ADR_SIZE */
1215   
1216   for( i = 0; i < 16; i++ ) {
1217     note_data[i] = 0xff;
1218   }
1219   
1220   note = note_data + 16;
1221   
1222
1223   /* process all tracks */
1224   
1225   if ( proc_header() != 0 ) {
1226     destroy_mem();
1227     return 0;
1228   }
1229   
1230   if( fmt == 0 ) {
1231     for( trk = 0; trk < 16; trk++ ) {
1232       if ( proc_track() != 0 ) {
1233         destroy_mem();
1234         return 0;
1235       }
1236     }
1237     
1238     for( trk = 16; trk < 18; trk++ ) {
1239       dummy_track();
1240     }
1241     
1242   } else {
1243     for( trk = 0; trk < std_head.ntrks; trk++ ) {
1244       if ( proc_track()!= 0 ) {
1245         destroy_mem();
1246         return 0;
1247       }
1248     }
1249     
1250     if( std_head.ntrks>18){
1251       for( trk = std_head.ntrks; trk < 36; trk++ ) {
1252         dummy_track();
1253       }
1254     }else{
1255       for( trk = std_head.ntrks; trk < 18; trk++ ) {
1256         dummy_track();
1257       }
1258     }
1259     
1260   }
1261   
1262   /* free all minternal work memory */
1263
1264   destroy_mem();
1265   
1266   /* all works finished */
1267   
1268   return (int)(rcpptr - (uint8*)rcp_buf);
1269 }
1270
1271 /***************************/
1272
1273 static int tai_compres(int ln)
1274   {
1275     int i,ad,ch,rbh=-1,rbm=-1;
1276     unsigned char       a,b,c,d;
1277     /*base dd dev df*/
1278     ch=(TRACK.MIDI_CH+1)&0xff;
1279     ad=0;
1280
1281     for(i=0;i<ln;i+=4){
1282       a=note[i];b=note[i+1];c=note[i+2];d=note[i+3];
1283
1284       if(a<128 && c>b && d>0){
1285         int cc=ch,ad2,sum;
1286         ad2=i;sum=0;
1287
1288         while(ad2<ln){
1289           unsigned char da=note[ad2];
1290           if(da==0xe6){cc=note[ad2+2];}
1291
1292           if(ad2>i && cc==ch && a==da && note[ad2+2]!=0 && note[ad2+3]!=0 ){
1293             if(sum+note[ad2+2]<=255){
1294               c=note[ad2+2]+sum;
1295               note[i+2]=c;
1296               note[ad2+2]=0;
1297               note[ad2+3]=0;
1298             }else{
1299               break;
1300             }
1301           }
1302
1303           if(da<0xf0){sum+=note[ad2+1];if(sum>255 || sum>=c){break;}}
1304
1305           if(da>=0xfc||da==0xf8||da==0xf9||da==0xe2||da==0xec){break;}
1306           ad2+=4;
1307         }
1308       }
1309
1310       /*                if(note[i]>=0xfc){ch=-1;}*/
1311
1312       if(note[i]>=0xfc){rbh=-1;rbm=-1;}
1313
1314       if(note[i]==0xdd){
1315         if(note[i+2]==rbh && note[i+3]==rbm){
1316           note[i]=0;note[i+2]=0;note[i+3]=0;
1317         }else{
1318           rbh=note[i+2];
1319           rbm=note[i+3];
1320
1321           if(ad && note[ad-4]==0xdd){
1322             note[ad-2]=note[i+2];
1323             note[ad-1]=note[i+3];
1324             note[i]=0;note[i+2]=0;note[i+3]=0;
1325           }
1326         }
1327       }
1328
1329       /*                if(note[i]==0xe6){
1330                         if(note[i+2]==ch){
1331                         note[i]=0;note[i+2]=0;note[i+3]=0;
1332                         }else{
1333                         ch=note[i+2];
1334
1335                         if(ad && note[ad-4]==0xe6){
1336                         note[ad-2]=note[i+2];
1337                         note[i]=0;note[i+2]=0;note[i+3]=0;
1338                         }
1339                         }
1340                         }
1341                         */
1342       /*
1343         if(note[i]==0xee){
1344         if(ad && note[ad-4]==note[i] && note[ad-3]==0){
1345         note[ad-2]=note[i+2];
1346         note[i]=0;note[i+2]=0;note[i+3]=0;
1347         }
1348         }
1349         */
1350       if((note[i]<0x80 &&(note[i+2]==0||note[i+3]==0))&&
1351          ad>0 && note[ad-4]<0xf0 && note[ad-3]+note[i+1]<=240){
1352         note[ad-3]+=note[i+1];
1353       }else{
1354         note[ad++]=note[i];note[ad++]=note[i+1];
1355         note[ad++]=note[i+2];note[ad++]=note[i+3];
1356       }
1357     }
1358
1359     return ad;
1360   }
1361
1362 /***************************/
1363 static int same_compres(int size)
1364   {
1365     int i,j=0,k,match,count=0;
1366     int po=0,m_max,ln,co=0,me=0,ad;
1367     int add[1024],add2[1024],leng[1024];
1368
1369     m_max=add_set(size,add);if(m_max<2 || m_max>1024){return(size);}
1370
1371     for(i=0;i<m_max;i++){
1372       po=add[i];ln=meas_len(size,po);match=0;
1373       if(ln>4 && note[po+ln-4]==0xfc){ln=ln-4;}
1374
1375       if(note[po]<0xfc && me>0){
1376         j=0;while(j<me ){
1377           if(ln==leng[j] && note[add2[j]]<0xfc){
1378             match=1;ad=add2[j];
1379             k=0;while(k<ln){
1380               if(note[po+k]!=note[ad]){match=0;break;}
1381               k++;ad++;
1382             }
1383           }
1384           if(match!=0){break;}
1385           j++;
1386         }
1387       }
1388
1389       if(match!=0 && j<1024 && add2[j]<65536-44){
1390         int ad=add2[j]+44;
1391         if(me<1024){add2[me]=co;leng[me]=4;me++;}
1392         note[co]=0xfc;
1393         note[co+1]=j&0xff;note[co+2]=(j>>8)+(ad&0xfc);note[co+3]=ad>>8;
1394         co=co+4;count++;
1395       }else{
1396         if(me<1024){add2[me]=co;leng[me]=ln;me++;}
1397         for(k=0;k<ln;k++){note[co]=note[po];po++;co++;}
1398       }
1399     }
1400     note[co]=0xfe;co=co+4;
1401     return(co);
1402   }
1403
1404 static int add_set(int size,int *add)
1405   {
1406     int co=0,i=0;
1407
1408     add[0]=0;
1409     while(i<size){
1410       if(note[i]>=0xfc||note[i+4]==0xfc){
1411         co++;if(co<1024){add[co]=i+4;}
1412       }
1413
1414       if(note[i]<128){
1415         if(note[i+2]==0 || note[i+3]==0){note[i]=0;note[i+2]=0;note[i+3]=0;}
1416       }
1417       i=i+4;
1418     }
1419
1420     return(co);
1421   }
1422
1423 static int meas_len(int size,int j)
1424   {
1425     int co=0,d;
1426
1427     while(j<size ){
1428       d=note[j];
1429       if( d==0xfe ){break;}
1430       co++;
1431       if( d>0xfb ){break;}
1432       j=j+4;
1433     }
1434     return(co*4);
1435   }
1436
1437 /***************************/