home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / music / songdump / songdump.c < prev    next >
C/C++ Source or Header  |  1987-07-03  |  8KB  |  307 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. unsigned char tmpbuf[16384];
  15.  
  16. char *keys[] = { "none","C","G","D","A","E","B","F#","C#","F","Bb","Eb","Ab",
  17.         "Db","Gb","Cb" };
  18. char *beat[] = { "none","2/2","3/2","2/4","3/4","4/4","5/4","6/8" };
  19.  
  20. /* sharping and flatting for key:
  21.  c     d     e  f     g     a     b  */
  22. int    keyfix[16][12] = {
  23.  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  24.  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  25.  0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
  26.  1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
  27.  1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
  28.  1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0,
  29.  1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0,
  30.  1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0,
  31.  1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1,
  32.  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
  33.  0, 0, 0, 0,-1, 0, 0, 0, 0, 0, 0,-1,
  34.  0, 0, 0, 0,-1, 0, 0, 0, 0,-1, 0,-1,
  35.  0, 0,-1, 0,-1, 0, 0, 0, 0,-1, 0,-1,
  36.  0, 0,-1, 0,-1, 0, 0,-1, 0,-1, 0,-1,
  37. -1, 0,-1, 0,-1, 0, 0,-1, 0,-1, 0,-1,
  38. -1, 0,-1, 0,-1,-1, 0,-1, 0,-1, 0,-1
  39. };
  40.  
  41. /* 96 pulses per quarter note timing */
  42. int ppq[] = {
  43. /*    1/32      1/16      1/8 (3)---1/4-----(.)  1/2           1            2*/
  44. 6,8,9, 12,16,18, 24,32,36, 48,64,72, 96,128,144, 192,256,288, 384,512,576, 768,
  45. 1024,1152, 1536,2048,2304, 3072,4096,4608, 6144,8192
  46. };
  47.  
  48. /*************************/
  49. main( argc , argv )
  50. int    argc;
  51. char    *argv[];
  52. {
  53. int    handl;
  54. int    i,j,k;
  55. int    tempo;
  56. long    tmpo,tmpo1;
  57. int    keyf,pitch;
  58. int    tonecnt;
  59.  
  60. printf( "\033v" );    /* screen wrap just in case */
  61. handl = Fopen( argv[1] , 0 );
  62. if( handl < 0 ) return;
  63. Fread( handl , 512L , &mushdr );
  64.  
  65. /* title */
  66. printf( "song:%s\n\n" , mushdr.title );
  67. /* inst. names, noise, tone, octave, ADSR (vert,horiz) 0-15 ,
  68.      Casio octave,(midi?)channel(0=16),preset */
  69. printf( "Atari      Casio      NTO  A  A  D  D  S  S  R  R  O  C  \n" );
  70. printf( "instrument instrument ZNV  |  -  |  -  |  -  |  -  v  h PR\n\n" );
  71. for( i = 0 ; i < 15 ; i++ ) {
  72.     printf( "%-10s %-10s " , mushdr.ainam[i] , mushdr.cinam[i] );
  73.     if( mushdr.aiset[i][0] & 0x80 )
  74.         printf( " " );
  75.     else
  76.         printf( "N" );
  77.     if( mushdr.aiset[i][0] & 0x10 )
  78.         printf( " " );
  79.     else
  80.         printf( "T" );
  81.     printf( "%01d" , mushdr.aiset[i][1] >> 4 );
  82.  
  83.     for( j=0 ; j < 8 ; j++ )
  84.         printf( "%3d" , mushdr.aiset[i][j] & 0x0f );
  85.  
  86.  
  87.     printf( " %2d%3d%3d\n" , mushdr.ciset1[i] >> 4 ,
  88.         mushdr.ciset1[i] & 0x0f , mushdr.ciset2[i] );
  89.     }
  90.  
  91. /* displacement to 4(?) lines of lyrics */
  92. for( i = 0 ; i < 5 ; i++ ) {
  93.     printf( "%08X\n" , mushdr.fptr[i] );
  94.     }
  95.  
  96. /* NOTES **********************/
  97. for( i = 0 ; i < 16384 ; i++ ) tmpbuf[i] = 0;
  98. if( mushdr.fptr[0] )
  99.     Fread( handl , (unsigned long)(mushdr.fptr[0] - 512L) , tmpbuf );
  100. else
  101.     Fread( handl , 16384L , tmpbuf );
  102.  
  103. /* music */
  104. /* track info - 4 words, lsb enables track, rest select instruments */
  105. for( i = 0 ; i < 4 ; i++ ) {
  106.     if( tmpbuf[i+i + 1 ] )
  107.         printf( "Track %d enabled for " , i+1 );
  108.     else
  109.         printf( "Track %d disabled, " , i+1 );
  110.     for( j = 1 ; j < 8 ; j++ )
  111.         if( ( tmpbuf[ i+i + 1 ] >> j ) & 1 )
  112.             printf( "%d " , j );
  113.     for( j = 0 ; j < 8 ; j++ )
  114.         if( ( tmpbuf[ i+i ] >> j ) & 1 )
  115.             printf( "%d " , j+8 );
  116.     printf( "\n" );
  117.     }
  118.  
  119. /* NOW, FOR THE SOUNDS */
  120. tempo = 60;
  121. tmpo1 = 0;
  122. initsnd();
  123.  
  124. /* for each byte, but may jump for variable record lengths */
  125. for( i = 8 ; tmpbuf[i] != 0xff ; i++ ) {
  126.     switch( tmpbuf[i] ) {
  127.     case 0x00:    /* begin/end record delimiter */
  128.  
  129. p_pause( (long)(tmpo1 >> 6) );    /* actually should be for each channel */
  130. quiet();
  131. tonecnt = 0;
  132. tmpo1 = 0;
  133.  
  134.         printf( "\n" );
  135.         break;
  136.     case 0x80:    /* grand staff and key signature, what does [1] do? */
  137.         printf( " (%d)key:%s," , tmpbuf[i+1] , keys[tmpbuf[i+2]] );
  138.         keyf = tmpbuf[i+2];
  139.         i += 2;
  140.         break;
  141.     case 0x81:    /* tempo (MM) */
  142.         printf( " tempo, quarter note = %d," , tmpbuf[i+1] );
  143. tempo = tmpbuf[i+1];
  144.         i++;
  145.         break;
  146.     case 0x82:    /* vertical bar across grand staff */
  147.         printf( "|" );
  148.         break;
  149.     case 0x83:    /* time signature */
  150.         printf( " time:%s," , beat[tmpbuf[i+1]] );
  151.         i++;
  152.         break;
  153.     case 0x84:    /* loudness */
  154.         printf( " loud(%d)=%d," , tmpbuf[i+1] , tmpbuf[i+2] );
  155.         i+=2;
  156.         break;
  157.     case 0x85:    /* repeat (n times) marker ||: */
  158.         printf( " %d*[" , tmpbuf[i+1] );
  159.         i++;
  160.         break;
  161.     case 0x86:    /* repeat ends here :|| */
  162.         printf( "]" );
  163.         break;
  164.     default:    /* note subrecord, 3 bytes, instr:note */
  165.         printf( "{%d:%d" , tmpbuf[i] & 15 , tmpbuf[i+2] );
  166. /* the printed value is the base note, pitch is the actual to play */
  167. pitch = tmpbuf[i+2];
  168. /* should be +/-12 per octave (oct2=0) offset for instrument */
  169.  
  170.         if( tmpbuf[i] & 0x40 )    /* begin tie */
  171.             printf( "(" );
  172.  
  173.         if( tmpbuf[i] & 0x20 )    /* end tie (valid to begin too */
  174.             printf( ")" );
  175.  
  176.         if( ( tmpbuf[i+1] & 0xc0 ) == 0xc0 )    /* flat */
  177. pitch--,        printf( "b" );
  178.         if( ( tmpbuf[i+1] & 0xc0 ) == 0x80 )    /* sharp */
  179. pitch++,        printf( "#" );
  180.         if( ( tmpbuf[i+1] & 0xc0 ) == 0x40 )    /* natural */
  181.             printf( "(nat)" );
  182.  
  183. if( !( tmpbuf[i+1] & 0xc0 ) )        /* adjust note value for key */
  184.     pitch += keyfix[keyf][pitch%12];    /* only if no accidental */
  185.  
  186.         if( tmpbuf[i] & 0x10 )
  187.             printf( "-" );
  188. else if ( tonecnt < 3 )            /* play it sam (tramiel?:) */
  189.     play( tonecnt++ , pitch );
  190.  
  191.         if( tmpbuf[i+1] & 0x20 )    /* accent */
  192.             printf( ">" );
  193.         k = tmpbuf[i+1] & 31;
  194.  
  195. /* Note duration */
  196.         j = 64;
  197.  
  198. /* the player does not yet do differing lengths,
  199.     should be minimum between 00 records */
  200. tmpo = 37500L;    /* for milliseconds, 7500 for 200Hz tics */
  201. tmpo *= ppq[k];
  202. tmpo /= tempo;
  203. if( !tmpo1 || tmpo < tmpo1 )
  204.     tmpo1 = tmpo;
  205.  
  206.         while( k > 2 )            /* type of note */
  207.             j >>= 1, k -= 3;    /* tempo is period not freq */
  208.         if( !(k&1) )
  209.             printf( " 1/%d" , j );    /* normal and dotted */
  210.         if( k == 1 )
  211.             printf( " 1/%d(3)" , j >> 1 );    /* triplet */
  212.         if( k == 2 )
  213.             printf( "." );        /* dotted */
  214.         printf( "}" );
  215.         i+=2;
  216.         break;
  217.         }
  218.  
  219.     }
  220.  
  221. printf( "\n" );
  222.  
  223. quiet();
  224.  
  225. /* LYRICS - using the pointers - room for a fourth line? ********************/
  226. if( mushdr.fptr[0] ) {
  227.     for( i = 0 ; i < 16384 ; i++ ) tmpbuf[i] = 0;
  228.     Fread( handl , mushdr.fptr[1]-mushdr.fptr[0] , tmpbuf );
  229.     printf( "verse 1:\n" );
  230.     for( i = 0 ; tmpbuf[i] ; i++ ) {
  231.         if( !(i & 63 ) ) printf( "\n" );
  232.         printf( "%c" , tmpbuf[i] );
  233.         }
  234.     printf( "\n" );
  235.     for( i = 0 ; i < 16384 ; i++ ) tmpbuf[i] = 0;
  236.     Fread( handl , mushdr.fptr[2]-mushdr.fptr[1] , tmpbuf );
  237.     printf( "verse 2:\n" );
  238.     for( i = 0 ; tmpbuf[i] ; i++ ) {
  239.         if( !(i & 63 ) ) printf( "\n" );
  240.         printf( "%c" , tmpbuf[i] );
  241.         }
  242.     printf( "\n" );
  243.  
  244.     for( i = 0 ; i < 16384 ; i++ ) tmpbuf[i] = 0;
  245.     Fread( handl , mushdr.fptr[3]-mushdr.fptr[2] , tmpbuf );
  246.     printf( "verse 3:\n" );
  247.     for( i = 0 ; tmpbuf[i] ; i++ ) {
  248.         if( !(i & 63 ) ) printf( "\n" );
  249.         printf( "%c" , tmpbuf[i] );
  250.         }
  251.     printf( "\n" );
  252.  
  253.     for( i = 0 ; i < 16384 ; i++ ) tmpbuf[i] = 0;
  254.     Fread( handl , mushdr.fptr[4]-mushdr.fptr[3] , tmpbuf );
  255.     /*?*/
  256.     }
  257.  
  258. Fclose( handl );
  259.  
  260. }
  261.  
  262. /*** HOW TO PLAY NOTES ***/
  263.  
  264. int    notedivs[12] = {    3822, 3608, 3405, 3214, 3034, 2863,
  265.                 2703, 2551, 2408, 2273, 2145, 2025 };
  266. /*****/
  267. initsnd()
  268. {
  269. int    val;
  270.  
  271. Giaccess( 0 , 8+128 );
  272. Giaccess( 0 , 9+128 );
  273. Giaccess( 0 , 10+128 );
  274.  
  275. val = Giaccess( 0 , 7 );
  276. val &= 0xc0;
  277. val |= 0x38;
  278. Giaccess( val , 7+128 );
  279. }
  280.  
  281. /*****/
  282. quiet()
  283. {
  284.  
  285. Giaccess( 0 , 8+128 );
  286. Giaccess( 0 , 9+128 );
  287. Giaccess( 0 , 10+128 );
  288. }
  289.  
  290. /*****/
  291. play( channel , note )
  292. register int    channel,note;
  293. {
  294. register int val;
  295. note -= 24;
  296.  
  297. if( note < 0 )
  298.     return;
  299.  
  300. val = notedivs[ note % 12 ] >> (note / 12);
  301.  
  302. Giaccess( 0x08 ,    channel + 8+128 );
  303. Giaccess( val & 0xff ,    channel + channel + 0+128 );
  304. Giaccess( val >> 8 ,    channel + channel + 1+128 );
  305.  
  306. }
  307.