home *** CD-ROM | disk | FTP | other *** search
- #include <osbind.h>
-
- struct {
- unsigned char ident[10];
- unsigned char ainam[15][10];
- unsigned char aiset[15][8];
- unsigned char cinam[15][10];
- unsigned char ciset1[15];
- unsigned char ciset2[15];
- long fptr[5];
- unsigned char title[32];
- } mushdr;
-
- unsigned char tmpbuf[16384];
-
- char *keys[] = { "none","C","G","D","A","E","B","F#","C#","F","Bb","Eb","Ab",
- "Db","Gb","Cb" };
- char *beat[] = { "none","2/2","3/2","2/4","3/4","4/4","5/4","6/8" };
-
- /* sharping and flatting for key:
- c d e f g a b */
- int keyfix[16][12] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
- 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0,
- 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0,
- 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0,
- 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
- 0, 0, 0, 0,-1, 0, 0, 0, 0, 0, 0,-1,
- 0, 0, 0, 0,-1, 0, 0, 0, 0,-1, 0,-1,
- 0, 0,-1, 0,-1, 0, 0, 0, 0,-1, 0,-1,
- 0, 0,-1, 0,-1, 0, 0,-1, 0,-1, 0,-1,
- -1, 0,-1, 0,-1, 0, 0,-1, 0,-1, 0,-1,
- -1, 0,-1, 0,-1,-1, 0,-1, 0,-1, 0,-1
- };
-
- /* 96 pulses per quarter note timing */
- int ppq[] = {
- /* 1/32 1/16 1/8 (3)---1/4-----(.) 1/2 1 2*/
- 6,8,9, 12,16,18, 24,32,36, 48,64,72, 96,128,144, 192,256,288, 384,512,576, 768,
- 1024,1152, 1536,2048,2304, 3072,4096,4608, 6144,8192
- };
-
- /*************************/
- main( argc , argv )
- int argc;
- char *argv[];
- {
- int handl;
- int i,j,k;
- int tempo;
- long tmpo,tmpo1;
- int keyf,pitch;
- int tonecnt;
-
- printf( "\033v" ); /* screen wrap just in case */
- handl = Fopen( argv[1] , 0 );
- if( handl < 0 ) return;
- Fread( handl , 512L , &mushdr );
-
- /* title */
- printf( "song:%s\n\n" , mushdr.title );
- /* inst. names, noise, tone, octave, ADSR (vert,horiz) 0-15 ,
- Casio octave,(midi?)channel(0=16),preset */
- printf( "Atari Casio NTO A A D D S S R R O C \n" );
- printf( "instrument instrument ZNV | - | - | - | - v h PR\n\n" );
- for( i = 0 ; i < 15 ; i++ ) {
- printf( "%-10s %-10s " , mushdr.ainam[i] , mushdr.cinam[i] );
- if( mushdr.aiset[i][0] & 0x80 )
- printf( " " );
- else
- printf( "N" );
- if( mushdr.aiset[i][0] & 0x10 )
- printf( " " );
- else
- printf( "T" );
- printf( "%01d" , mushdr.aiset[i][1] >> 4 );
-
- for( j=0 ; j < 8 ; j++ )
- printf( "%3d" , mushdr.aiset[i][j] & 0x0f );
-
-
- printf( " %2d%3d%3d\n" , mushdr.ciset1[i] >> 4 ,
- mushdr.ciset1[i] & 0x0f , mushdr.ciset2[i] );
- }
-
- /* displacement to 4(?) lines of lyrics */
- for( i = 0 ; i < 5 ; i++ ) {
- printf( "%08X\n" , mushdr.fptr[i] );
- }
-
- /* NOTES **********************/
- for( i = 0 ; i < 16384 ; i++ ) tmpbuf[i] = 0;
- if( mushdr.fptr[0] )
- Fread( handl , (unsigned long)(mushdr.fptr[0] - 512L) , tmpbuf );
- else
- Fread( handl , 16384L , tmpbuf );
-
- /* music */
- /* track info - 4 words, lsb enables track, rest select instruments */
- for( i = 0 ; i < 4 ; i++ ) {
- if( tmpbuf[i+i + 1 ] )
- printf( "Track %d enabled for " , i+1 );
- else
- printf( "Track %d disabled, " , i+1 );
- for( j = 1 ; j < 8 ; j++ )
- if( ( tmpbuf[ i+i + 1 ] >> j ) & 1 )
- printf( "%d " , j );
- for( j = 0 ; j < 8 ; j++ )
- if( ( tmpbuf[ i+i ] >> j ) & 1 )
- printf( "%d " , j+8 );
- printf( "\n" );
- }
-
- /* NOW, FOR THE SOUNDS */
- tempo = 60;
- tmpo1 = 0;
- initsnd();
-
- /* for each byte, but may jump for variable record lengths */
- for( i = 8 ; tmpbuf[i] != 0xff ; i++ ) {
- switch( tmpbuf[i] ) {
- case 0x00: /* begin/end record delimiter */
-
- p_pause( (long)(tmpo1 >> 6) ); /* actually should be for each channel */
- quiet();
- tonecnt = 0;
- tmpo1 = 0;
-
- printf( "\n" );
- break;
- case 0x80: /* grand staff and key signature, what does [1] do? */
- printf( " (%d)key:%s," , tmpbuf[i+1] , keys[tmpbuf[i+2]] );
- keyf = tmpbuf[i+2];
- i += 2;
- break;
- case 0x81: /* tempo (MM) */
- printf( " tempo, quarter note = %d," , tmpbuf[i+1] );
- tempo = tmpbuf[i+1];
- i++;
- break;
- case 0x82: /* vertical bar across grand staff */
- printf( "|" );
- break;
- case 0x83: /* time signature */
- printf( " time:%s," , beat[tmpbuf[i+1]] );
- i++;
- break;
- case 0x84: /* loudness */
- printf( " loud(%d)=%d," , tmpbuf[i+1] , tmpbuf[i+2] );
- i+=2;
- break;
- case 0x85: /* repeat (n times) marker ||: */
- printf( " %d*[" , tmpbuf[i+1] );
- i++;
- break;
- case 0x86: /* repeat ends here :|| */
- printf( "]" );
- break;
- default: /* note subrecord, 3 bytes, instr:note */
- printf( "{%d:%d" , tmpbuf[i] & 15 , tmpbuf[i+2] );
- /* the printed value is the base note, pitch is the actual to play */
- pitch = tmpbuf[i+2];
- /* should be +/-12 per octave (oct2=0) offset for instrument */
-
- if( tmpbuf[i] & 0x40 ) /* begin tie */
- printf( "(" );
-
- if( tmpbuf[i] & 0x20 ) /* end tie (valid to begin too */
- printf( ")" );
-
- if( ( tmpbuf[i+1] & 0xc0 ) == 0xc0 ) /* flat */
- pitch--, printf( "b" );
- if( ( tmpbuf[i+1] & 0xc0 ) == 0x80 ) /* sharp */
- pitch++, printf( "#" );
- if( ( tmpbuf[i+1] & 0xc0 ) == 0x40 ) /* natural */
- printf( "(nat)" );
-
- if( !( tmpbuf[i+1] & 0xc0 ) ) /* adjust note value for key */
- pitch += keyfix[keyf][pitch%12]; /* only if no accidental */
-
- if( tmpbuf[i] & 0x10 )
- printf( "-" );
- else if ( tonecnt < 3 ) /* play it sam (tramiel?:) */
- play( tonecnt++ , pitch );
-
- if( tmpbuf[i+1] & 0x20 ) /* accent */
- printf( ">" );
- k = tmpbuf[i+1] & 31;
-
- /* Note duration */
- j = 64;
-
- /* the player does not yet do differing lengths,
- should be minimum between 00 records */
- tmpo = 37500L; /* for milliseconds, 7500 for 200Hz tics */
- tmpo *= ppq[k];
- tmpo /= tempo;
- if( !tmpo1 || tmpo < tmpo1 )
- tmpo1 = tmpo;
-
- while( k > 2 ) /* type of note */
- j >>= 1, k -= 3; /* tempo is period not freq */
- if( !(k&1) )
- printf( " 1/%d" , j ); /* normal and dotted */
- if( k == 1 )
- printf( " 1/%d(3)" , j >> 1 ); /* triplet */
- if( k == 2 )
- printf( "." ); /* dotted */
- printf( "}" );
- i+=2;
- break;
- }
-
- }
-
- printf( "\n" );
-
- quiet();
-
- /* LYRICS - using the pointers - room for a fourth line? ********************/
- if( mushdr.fptr[0] ) {
- for( i = 0 ; i < 16384 ; i++ ) tmpbuf[i] = 0;
- Fread( handl , mushdr.fptr[1]-mushdr.fptr[0] , tmpbuf );
- printf( "verse 1:\n" );
- for( i = 0 ; tmpbuf[i] ; i++ ) {
- if( !(i & 63 ) ) printf( "\n" );
- printf( "%c" , tmpbuf[i] );
- }
- printf( "\n" );
- for( i = 0 ; i < 16384 ; i++ ) tmpbuf[i] = 0;
- Fread( handl , mushdr.fptr[2]-mushdr.fptr[1] , tmpbuf );
- printf( "verse 2:\n" );
- for( i = 0 ; tmpbuf[i] ; i++ ) {
- if( !(i & 63 ) ) printf( "\n" );
- printf( "%c" , tmpbuf[i] );
- }
- printf( "\n" );
-
- for( i = 0 ; i < 16384 ; i++ ) tmpbuf[i] = 0;
- Fread( handl , mushdr.fptr[3]-mushdr.fptr[2] , tmpbuf );
- printf( "verse 3:\n" );
- for( i = 0 ; tmpbuf[i] ; i++ ) {
- if( !(i & 63 ) ) printf( "\n" );
- printf( "%c" , tmpbuf[i] );
- }
- printf( "\n" );
-
- for( i = 0 ; i < 16384 ; i++ ) tmpbuf[i] = 0;
- Fread( handl , mushdr.fptr[4]-mushdr.fptr[3] , tmpbuf );
- /*?*/
- }
-
- Fclose( handl );
-
- }
-
- /*** HOW TO PLAY NOTES ***/
-
- int notedivs[12] = { 3822, 3608, 3405, 3214, 3034, 2863,
- 2703, 2551, 2408, 2273, 2145, 2025 };
- /*****/
- initsnd()
- {
- int val;
-
- Giaccess( 0 , 8+128 );
- Giaccess( 0 , 9+128 );
- Giaccess( 0 , 10+128 );
-
- val = Giaccess( 0 , 7 );
- val &= 0xc0;
- val |= 0x38;
- Giaccess( val , 7+128 );
- }
-
- /*****/
- quiet()
- {
-
- Giaccess( 0 , 8+128 );
- Giaccess( 0 , 9+128 );
- Giaccess( 0 , 10+128 );
- }
-
- /*****/
- play( channel , note )
- register int channel,note;
- {
- register int val;
- note -= 24;
-
- if( note < 0 )
- return;
-
- val = notedivs[ note % 12 ] >> (note / 12);
-
- Giaccess( 0x08 , channel + 8+128 );
- Giaccess( val & 0xff , channel + channel + 0+128 );
- Giaccess( val >> 8 , channel + channel + 1+128 );
-
- }
-