home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / music / songdump / songtran.c < prev    next >
C/C++ Source or Header  |  1987-07-03  |  7KB  |  320 lines

  1. #include <osbind.h>
  2.  
  3. struct {
  4.     unsigned char    ident[10];
  5.     unsigned char    ainam[15][10];
  6.     unsigned char    aiset[15][8];
  7.     unsigned char    cinam[15][10];
  8.     unsigned char    ciset1[15];
  9.     unsigned char    ciset2[15];
  10.     long    fptr[5];
  11.     unsigned char    title[32];
  12. } mushdr;
  13.  
  14. struct muevnt {
  15.     long    rltime;
  16.     long    deltime;
  17.     char    etype;
  18.     char    inst;
  19.     char    frq;
  20.     char    fill;
  21. } evnt[2500];
  22.  
  23. unsigned char tmpbuf[16384];
  24.  
  25. char *keys[] = { "none","C","G","D","A","E","B","F#","C#","F","Bb","Eb","Ab",
  26.         "Db","Gb","Cb" };
  27. char *beat[] = { "none","2/2","3/2","2/4","3/4","4/4","5/4","6/8" };
  28.  
  29. /* sharping and flatting for key:
  30.  c     d     e  f     g     a     b  */
  31. int    keyfix[16][12] = {
  32.  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  33.  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  34.  0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
  35.  1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
  36.  1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
  37.  1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0,
  38.  1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0,
  39.  1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0,
  40.  1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1,
  41.  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
  42.  0, 0, 0, 0,-1, 0, 0, 0, 0, 0, 0,-1,
  43.  0, 0, 0, 0,-1, 0, 0, 0, 0,-1, 0,-1,
  44.  0, 0,-1, 0,-1, 0, 0, 0, 0,-1, 0,-1,
  45.  0, 0,-1, 0,-1, 0, 0,-1, 0,-1, 0,-1,
  46. -1, 0,-1, 0,-1, 0, 0,-1, 0,-1, 0,-1,
  47. -1, 0,-1, 0,-1,-1, 0,-1, 0,-1, 0,-1
  48. };
  49.  
  50. /* 96 pulses per quarter note timing */
  51. int ppq[] = {
  52. /*    1/32      1/16      1/8 (3)---1/4-----(.)  1/2           1            2*/
  53. 6,8,9, 12,16,18, 24,32,36, 48,64,72, 96,128,144, 192,256,288, 384,512,576, 768,
  54. 1024,1152, 1536,2048,2304, 3072,4096,4608, 6144,8192
  55. };
  56.  
  57. /*************************/
  58. main( argc , argv )
  59. int    argc;
  60. char    *argv[];
  61. {
  62. int    handl;
  63. int    i,j,k;
  64. int    tempo;
  65. int    evntptr;
  66. long    tmpo,tmpo1;
  67. register int    keyf,pitch;
  68. register long    realtime;
  69. int    noteplay[3];
  70.  
  71. handl = Fopen( argv[1] , 0 );
  72. if( handl < 0 ) return;
  73. Fread( handl , 512L , &mushdr );
  74.  
  75. /* NOTES **********************/
  76. for( i = 0 ; i < 16384 ; i++ ) tmpbuf[i] = 0;
  77. if( mushdr.fptr[0] )
  78.     Fread( handl , (unsigned long)(mushdr.fptr[0] - 512L) , tmpbuf );
  79. else
  80.     Fread( handl , 16384L , tmpbuf );
  81.  
  82. /* NOW, FOR THE SOUNDS */
  83. tempo = 60;
  84. tmpo1 = 0;
  85. realtime = 0;
  86. evntptr = 0;
  87.  
  88. printf( "PROCESSING\n" );
  89.  
  90. /* for each byte, but may jump for variable record lengths */
  91. for( i = 8 ; tmpbuf[i] != 0xff ; i++ ) {
  92.     switch( tmpbuf[i] ) {
  93.     case 0x00:    /* begin/end record delimiter */
  94. realtime += tmpo1;
  95. tmpo1 = 0;
  96.         break;
  97.     case 0x80:    /* grand staff and key signature, what does [1] do? */
  98. keyf = tmpbuf[i+2];
  99.         i += 2;
  100.         break;
  101.     case 0x81:    /* tempo (MM) */
  102. tempo = tmpbuf[i+1];
  103.         i++;
  104.         break;
  105.     case 0x82:    /* vertical bar across grand staff */
  106.         break;
  107.     case 0x83:    /* time signature */
  108.         i++;
  109.         break;
  110.     case 0x84:    /* loudness */
  111.         i+=2;
  112.         break;
  113.     case 0x85:    /* repeat (n times) marker ||: */
  114. /*        printf( " %d*[" , tmpbuf[i+1] );
  115. */        i++;
  116.         break;
  117.     case 0x86:    /* repeat ends here :|| */
  118. /*        printf( "]" );
  119. */        break;
  120.     default:    /* note subrecord, 3 bytes, instr:note */
  121. /* the printed value is the base note, pitch is the actual to play */
  122. pitch = tmpbuf[i+2];
  123. /* should be +/-12 per octave (oct2=0) offset for instrument */
  124.  
  125.  
  126.         if( ( tmpbuf[i+1] & 0xc0 ) == 0xc0 )    /* flat */
  127.             pitch--;
  128.         if( ( tmpbuf[i+1] & 0xc0 ) == 0x80 )    /* sharp */
  129.             pitch++;
  130.  
  131. /*        if( ( tmpbuf[i+1] & 0xc0 ) == 0x40 )       natural */
  132.  
  133. if( !( tmpbuf[i+1] & 0xc0 ) )        /* adjust note value for key */
  134.     pitch += keyfix[keyf][pitch%12];    /* only if no accidental */
  135.  
  136. /* Note duration */
  137.  
  138. /* the player does not yet do differing lengths,
  139.     should be minimum between 00 records */
  140. tmpo = 1250L;        /* for .5 milliseconds, 125 for 200Hz tics */
  141. tmpo = ppq[ tmpbuf[i+1] & 31 ];        /* *= */
  142. /* tmpo /= tempo; */
  143. if( !tmpo1 || tmpo < tmpo1 )
  144.     tmpo1 = tmpo;
  145.  
  146. k = 0;
  147. if( tmpbuf[i] & 0x40 )    /* begin tie */
  148.     k |= 4;
  149. if( tmpbuf[i] & 0x20 )    /* end tie (valid to begin too */
  150.     k |= 2;
  151. if( tmpbuf[i+1] & 0x20 )    /* accent */
  152.     k |= 8;
  153.  
  154. if( !( tmpbuf[i] & 0x10 ) ) {    /* rest */
  155.     evnt[ evntptr ].rltime = realtime;
  156.     evnt[ evntptr+1 ].rltime = realtime + tmpo;
  157.     evnt[ evntptr ].deltime = tmpo;
  158.     evnt[ evntptr+1 ].deltime = tmpo;
  159.     evnt[ evntptr ].etype = k;
  160.     evnt[ evntptr+1 ].etype = k|1;
  161.     evnt[ evntptr ].inst = tmpbuf[i]&15;
  162.     evnt[ evntptr+1 ].inst = tmpbuf[i]&15;
  163.     evnt[ evntptr ].frq = pitch;
  164.     evnt[ evntptr+1 ].frq = pitch;
  165.     evntptr += 2;
  166.     }
  167.  
  168.         i+=2;
  169.         break;
  170.         }
  171.  
  172.     }
  173. /* unfold event table */
  174. printf( "SORTING\n" );
  175. heapsort( evnt , evntptr );
  176.  
  177. evnt[ evntptr ].rltime = 0x7fffffffL;
  178.  
  179. printf( "UNFOLDING-\n" );
  180. /* look for end of tie/beginning of tie pairs, and expand first note */
  181.  
  182. printf( "RESULTS:\n" );
  183. initsnd();
  184. tmpo1 = 0;
  185. k = 0;
  186. noteplay[0]=0;
  187. noteplay[1]=0;
  188. noteplay[2]=0;
  189. for( i = 0 ; i < evntptr ; i++ ) {
  190.     if( tmpo1 < evnt[i].rltime ) {
  191. printf( "%10D\n" , evnt[i].rltime );
  192.  
  193.     while( k < i ) {
  194.         if( !( evnt[k].etype & 1 ) ) {
  195. if( !noteplay[0] )play(0,evnt[k].frq),noteplay[0]=evnt[k].frq;
  196. else if( !noteplay[1] )play(1,evnt[k].frq),noteplay[1]=evnt[k].frq;
  197. else if( !noteplay[2] )play(2,evnt[k].frq),noteplay[2]=evnt[k].frq;
  198.             }
  199.         k++;
  200.         }
  201.  
  202.         p_pause( (long)( (evnt[i].rltime - tmpo1) * 625L / tempo ) );
  203.         tmpo1 = evnt[i].rltime;
  204.         }
  205.  
  206. /*    printf( "%10D %6D %2d %2d %3d\n" ,
  207. evnt[i].rltime, evnt[i].deltime, evnt[i].etype, evnt[i].inst, evnt[i].frq );
  208. */
  209.     if( evnt[i].etype & 1 ) {
  210. /*        if( !( evnt[i].etype & 4 ) ) {        only if matching &2*/
  211. if( noteplay[0] == evnt[i].frq )quiet(0),noteplay[0]=0;
  212. else if( noteplay[1] == evnt[i].frq )quiet(1),noteplay[1]=0;
  213. else if( noteplay[2] == evnt[i].frq )quiet(2),noteplay[2]=0;
  214. /*            }*/
  215.         }
  216.  
  217.     }
  218.  
  219. printf( "\n" );
  220. Fclose( handl );
  221.  
  222. }
  223.  
  224. /*** HOW TO PLAY NOTES ***/
  225.  
  226. int    notedivs[12] = {    3822, 3608, 3405, 3214, 3034, 2863,
  227.                 2703, 2551, 2408, 2273, 2145, 2025 };
  228. /*****/
  229. initsnd()
  230. {
  231. int    val;
  232.  
  233. Giaccess( 0 , 8+128 );
  234. Giaccess( 0 , 9+128 );
  235. Giaccess( 0 , 10+128 );
  236.  
  237. val = Giaccess( 0 , 7 );
  238. val &= 0xc0;
  239. val |= 0x38;
  240. Giaccess( val , 7+128 );
  241. }
  242.  
  243. /*****/
  244. quiet( channel )
  245. register int    channel;
  246. {
  247. Giaccess( 0 , channel + 8+128 );
  248. }
  249.  
  250. /*****/
  251. play( channel , note )
  252. register int    channel,note;
  253. {
  254. register int val;
  255. note -= 24;
  256.  
  257. if( note < 0 )
  258.     return;
  259.  
  260. val = notedivs[ note % 12 ] >> (note / 12);
  261.  
  262. Giaccess( 0x08 ,    channel + 8+128 );
  263. Giaccess( val & 0xff ,    channel + channel + 0+128 );
  264. Giaccess( val >> 8 ,    channel + channel + 1+128 );
  265.  
  266. }
  267.  
  268. /*************************/
  269. heapsort( tbl , len )
  270. struct muevnt    *tbl;
  271. int    len;
  272. {
  273. int    l;
  274. int    r;
  275. int    i,j;
  276.  
  277. struct muevnt    ktbl;
  278.  
  279. /*1*/
  280. l = len/2 + 1;
  281. r = len;
  282.  
  283. while( 1 ) {
  284. /*2*/
  285.     if( l > 1 ) {
  286.         l--;
  287.         ktbl = tbl[ l ];
  288.         }
  289.     else    {
  290.         ktbl = tbl[ r ];
  291.         tbl[ r ] = tbl[ 1 ];
  292.         r--;
  293.         if( r == 1 ) {
  294.             tbl[ 1 ] = ktbl;
  295.             break;
  296.             }
  297.         }
  298. /*3*/
  299.     j = l;
  300.  
  301.     while( 1 ) {
  302. /*4*/
  303.         i = j;
  304.         j = j+j;
  305.         if( j > r )
  306.             break;
  307.         if( j < r && tbl[ j ].rltime < tbl[ j+1 ].rltime )
  308.             j++;
  309. /*6*/
  310.         if( ktbl.rltime >= tbl[ j ].rltime )
  311.             break;
  312. /*7*/
  313.         tbl[i] = tbl[j];
  314.         }
  315. /*8*/
  316.     tbl[i] = ktbl;
  317.     }
  318.  
  319. }
  320.