home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Da Capo
/
da_capo_vol1.bin
/
programs
/
amiga
/
midi
/
mod2midi
/
mod2midi.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-12
|
43KB
|
1,989 lines
/* .MOD to MID file converter ©1993 Andrew Scott
Amiga conversion © 1994 by Paul Huxham
*/
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <exec/types.h>
#include <clib/dos_protos.h>
#include <pragmas/dos_pragmas.h>
#include "mod2midi.h"
#include "text.h"
/* CLI parameters */
#define OPT_TEMPLATE "MOD,MIDI,ABOUT/S,MAPSAMPLES/S,SAVEINFO/S,TRANSPOSE/S,DRUM/N,TEMPO/N,VOLUMESHIFT/S"
#define OPT_MODFILE 0
#define OPT_MIDIFILE 1
#define OPT_ABOUT 2
#define OPT_MAPSAMPLES 3
#define OPT_SAVEINFO 4
#define OPT_TRANSPOSE 5
#define OPT_DRUMCHANNEL 6
#define OPT_TEMPOTYPE 7
#define OPT_VOLUMESHIFT 8
#define OPT_NUMBEROF 9
/* Function Prototypes */
int Instrument( void );
void OutByte( bfile f, char b );
void FlushOut( bfile f );
void CloseOut( bfile f );
int OpenOut( bfile f, string fn );
unsigned long Beatle( bfile f );
unsigned char InByte( bfile f );
void CloseIn( bfile f );
int OpenIn( bfile f, string fn );
void Inskipp( bfile f, unsigned long n );
struct bpos FPos( bfile f );
void FGoto( bfile f, struct bpos x );
int WriteVLQ( bfile f, unsigned long i );
int MKTest( bfile f );
string SimplifyName( string s );
string GetLine( FILE *f );
int ReadModSpecs( bfile f, string n, samps s );
void ScanSamples( samps s );
int SetDefaults( samps s, string fn );
void SaveDefaults( samps s, string fn );
void NullArryFree( string *sp );
int Instrument();
string MIDIVal( samp *sam );
string TransVal( samp *sam );
string VolumeVal( samp *sam );
string NullVal( samp *sam );
int Sample( samps s, string (*MIDIVal)(samp *x), int w );
int ChooseChannels( samps s );
void MapSamples( samps s );
void SaveSamp( samp sam );
void SaveSamples( samps s );
void Transpositions( samps s );
void VolumeShifts( samps s );
unsigned char NoteValue( unsigned int n );
unsigned long NoteLength( unsigned char n, unsigned int l, unsigned int b );
void WriteHeader( bfile mf, unsigned char n );
unsigned int Trk0Info( bfile mf, string s );
void AddToLog( unsigned long a, unsigned long b );
void WriteLog( FILE *f );
unsigned char RestrictVol( int v );
void ConvertMOD( bfile f1, bfile f2, string tn, samps smp );
extern int ScrollChoice( string title, string *sp, int w );
extern string DialogBox( string *sp, string def );
char *version = "$VER: Mod2Midi 1.0 (12.6.94)";
long __stack = 20000; // Code allocates everything off the stack ;-)
bfile MidFile, ModFile;
char SongName[21];
samps Samples;
unsigned long PosLog[64];
int DrumChann = 9, TempoType = 1, PosI = 0;
string MidFN, ModFN;
char *TempoTypes[] = { "NORMAL", "EXTENDED" };
extern struct Library *DOSBase;
int main( int argc, char *argv[] )
{
int r;
UBYTE Mode = MODE_CONVERT;
MidFile->f = ModFile->f = NULL;
MidFN = ModFN = NULL;
/* Only work if launched from shell */
if ( argc != 0 )
{
struct RDArgs *RDArgs;
LONG opts[OPT_NUMBEROF];
opts[OPT_MODFILE] = 0;
opts[OPT_MIDIFILE] = 0;
opts[OPT_ABOUT] = 0;
opts[OPT_MAPSAMPLES] = 0;
opts[OPT_SAVEINFO] = 0;
opts[OPT_TRANSPOSE] = 0;
opts[OPT_DRUMCHANNEL] = 0;
opts[OPT_TEMPOTYPE] = 0;
opts[OPT_VOLUMESHIFT] = 0;
RDArgs = ReadArgs( OPT_TEMPLATE, opts, NULL );
if ( RDArgs != NULL )
{
/* Grab all set cli parameters */
if ( opts[OPT_MODFILE] != 0 )
{
ModFN = malloc( strlen( (char *)opts[OPT_MODFILE] ) + 1 );
if ( ModFN != NULL ) strcpy( ModFN, (char *)opts[OPT_MODFILE] );
}
if ( opts[OPT_MIDIFILE] != 0 )
{
MidFN = malloc( strlen( (char *)opts[OPT_MIDIFILE] ) + 1 );
if ( MidFN != NULL ) strcpy( MidFN, (char *)opts[OPT_MIDIFILE] );
}
if ( opts[OPT_ABOUT] != 0 ) Mode |= MODE_ABOUT;
if ( opts[OPT_MAPSAMPLES] != 0 ) Mode |= MODE_MAPSAMPLES;
if ( opts[OPT_SAVEINFO] != 0 ) Mode |= MODE_SAVEINFO;
if ( opts[OPT_TRANSPOSE] != 0 ) Mode |= MODE_TRANSPOSE;
if ( opts[OPT_VOLUMESHIFT] != 0 ) Mode |= MODE_VOLUMESHIFT;
if ( opts[OPT_DRUMCHANNEL] != 0 )
{
/* Drum channel is stored as value - 1 */
DrumChann = *( (ULONG *)opts[OPT_DRUMCHANNEL] ) - 1;
printf( "Drum channel set to: %d\n", DrumChann + 1 );
}
if ( opts[OPT_TEMPOTYPE] != 0 )
{
int value;
value = *( (ULONG *)opts[OPT_TEMPOTYPE] );
if ( value >= 0 && value <= 1 )
{
TempoType = value;
printf( "Tempo type set to: %s\n", TempoTypes[TempoType] );
}
else printf( "Illegal value for TEMPO, using default of NORMAL\n" );
}
FreeArgs ( RDArgs );
/* Open the MID file */
if ( MidFN != NULL )
{
r = OpenOut( MidFile, MidFN );
}
/* Open the MOD file */
if ( r != NULL && ModFN != NULL )
{
if ( ModFile->f != NULL ) SaveDefaults( Samples, ModFN ); // Save defaults
r = OpenIn( ModFile, ModFN );
if ( r != NULL )
{
if ( !ReadModSpecs( ModFile, SongName, Samples ) )
printf( "%s is not a .mod file\n", ModFN );
else
if ( !SetDefaults( Samples, ModFN ) ) CloseIn( ModFile );
}
}
if ( ( Mode & MODE_ABOUT ) == MODE_ABOUT )
{
int i = 0;
while ( MSG_ABOUT[i] != NULL ) printf( "%s\n", MSG_ABOUT[ i++ ] );
Mode = NULL; //Dont allow futher processing
}
if ( ( Mode & MODE_MAPSAMPLES ) == MODE_MAPSAMPLES )
{
if ( ModFile->f != NULL ) MapSamples( Samples );
else
printf( "%s", MSG_ERR_NO_MOD_FILENAME );
}
if ( ( Mode & MODE_SAVEINFO ) == MODE_SAVEINFO )
{
if ( ModFile->f != NULL ) SaveSamples( Samples );
else
printf( "%s", MSG_ERR_NO_MOD_FILENAME );
}
if ( ( Mode & MODE_TRANSPOSE ) == MODE_TRANSPOSE )
{
if ( ModFile->f != NULL ) Transpositions( Samples );
else
printf( "%s", MSG_ERR_NO_MOD_FILENAME );
}
if ( ( Mode & MODE_VOLUMESHIFT ) == MODE_VOLUMESHIFT )
{
if ( ModFile->f != NULL ) VolumeShifts( Samples );
else
printf( "%s", MSG_ERR_NO_MOD_FILENAME );
}
/* Do the conversion */
if ( MidFile->f != NULL && ModFile->f != NULL && Mode != NULL )
{
if ( ChooseChannels( Samples ) <= 16 )
{
ConvertMOD( ModFile, MidFile, SongName, Samples );
}
else
printf( "Too many instruments, there is a maximum of 16 allowed\n" );
}
else
printf( "Both a source .MOD and a destination .MID file must be supplied\n" );
/* If the file is open, close it */
if ( ModFile->f != NULL )
{
CloseIn( ModFile );
SaveDefaults( Samples, ModFN );
}
/* If a filename has been allocated, free it */
if ( ModFN != NULL ) free( ModFN );
/* If the file is open, close it */
if ( MidFile->f != NULL ) CloseOut( MidFile );
/* If a filename has been allocated, free it */
if ( MidFN != NULL ) free( MidFN );
}
else printf( "Illegal parameters!\n" );
}
}
/* Post: The byte b has been written to the buffer of the file f */
void OutByte( bfile f, char b )
{
if ( f->o == BUFFSIZE )
{
fwrite( f->b, 1, BUFFSIZE, f->f );
f->o = 0;
}
f->b[ f->o++ ] = b;
}
/* Pre: f was opened for writing */
/* Post: The file f has has its buffer flushed */
void FlushOut( bfile f )
{
if ( f->o > 0 ) fwrite( f->b, 1, f->o, f->f );
f->o = 0;
}
/* Pre: f was opened for writing */
/* Post: The file f has been flushed and is now closed */
void CloseOut( bfile f )
{
FlushOut( f );
fclose( f->f );
f->f = NULL;
}
/* Returns: NZ if the file f has been opened for writing with the name fn */
int OpenOut( bfile f, string fn )
{
if ( f->f != NULL ) CloseOut( f );
f->f = fopen( fn, "wb" );
f->o = 0;
return f->f != NULL;
}
/* Returns: bfile-tell; the offset from the start */
unsigned long Beatle( bfile f )
{
return ftell( f->f ) + f->o;
}
/* Pre: f was opened for reading */
/* Returns: The next byte from the file f */
unsigned char InByte( bfile f )
{
if ( f->o == BUFFSIZE && !feof( f->f ) )
{
f->r = fread( f->b, 1, BUFFSIZE, f->f );
if ( f->r < BUFFSIZE ) f->b[ f->r ] = 0;
f->o = 0;
}
if ( f->o < f->r ) return f->b[ f->o++ ];
return f->b[ f->o ];
}
/* Post: The file f is now closed */
void CloseIn( bfile f )
{
fclose( f->f );
f->f = NULL;
}
/* Returns: NZ if the file f has been opened for reading with the name fn */
int OpenIn( bfile f, string fn )
{
if ( f->f != NULL ) CloseIn( f );
f->f = fopen( fn, "rb" );
f->o = f->r = BUFFSIZE;
re