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 >
Wrap
C/C++ Source or Header
|
1987-07-03
|
8KB
|
307 lines
#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 );
}