home *** CD-ROM | disk | FTP | other *** search
/ Da Capo / da_capo_vol1.bin / programs / amiga / midi / mod2midi / mod2midi.c < prev    next >
C/C++ Source or Header  |  1994-06-12  |  43KB  |  1,989 lines

  1. /*    .MOD to MID file converter ©1993 Andrew Scott
  2.  
  3.         Amiga conversion © 1994 by Paul Huxham
  4. */
  5.  
  6. #include <ctype.h>
  7. #include <math.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11.  
  12. #include <exec/types.h>
  13.  
  14. #include <clib/dos_protos.h>
  15.  
  16. #include <pragmas/dos_pragmas.h>
  17.  
  18. #include "mod2midi.h"
  19. #include "text.h"
  20.  
  21. /* CLI parameters */
  22. #define OPT_TEMPLATE "MOD,MIDI,ABOUT/S,MAPSAMPLES/S,SAVEINFO/S,TRANSPOSE/S,DRUM/N,TEMPO/N,VOLUMESHIFT/S"
  23. #define OPT_MODFILE 0
  24. #define OPT_MIDIFILE 1
  25. #define OPT_ABOUT 2
  26. #define OPT_MAPSAMPLES 3
  27. #define OPT_SAVEINFO 4
  28. #define OPT_TRANSPOSE 5
  29. #define OPT_DRUMCHANNEL 6
  30. #define OPT_TEMPOTYPE 7
  31. #define OPT_VOLUMESHIFT 8
  32. #define OPT_NUMBEROF 9
  33.  
  34. /* Function Prototypes */
  35. int Instrument( void );
  36. void OutByte( bfile f, char b );
  37. void FlushOut( bfile f );
  38. void CloseOut( bfile f );
  39. int OpenOut( bfile f, string fn );
  40. unsigned long Beatle( bfile f );
  41. unsigned char InByte( bfile f );
  42. void CloseIn( bfile f );
  43. int OpenIn( bfile f, string fn );
  44. void Inskipp( bfile f, unsigned long n );
  45. struct bpos FPos( bfile f );
  46. void FGoto( bfile f, struct bpos x );
  47. int WriteVLQ( bfile f, unsigned long i );
  48. int MKTest( bfile f );
  49. string SimplifyName( string s );
  50. string GetLine( FILE *f );
  51. int ReadModSpecs( bfile f, string n, samps s );
  52. void ScanSamples( samps s );
  53. int SetDefaults( samps s, string fn );
  54. void SaveDefaults( samps s, string fn );
  55. void NullArryFree( string *sp );
  56. int Instrument();
  57. string MIDIVal( samp *sam );
  58. string TransVal( samp *sam );
  59. string VolumeVal( samp *sam );
  60. string NullVal( samp *sam );
  61. int Sample( samps s, string (*MIDIVal)(samp *x), int w );
  62. int ChooseChannels( samps s );
  63. void MapSamples( samps s );
  64. void SaveSamp( samp sam );
  65. void SaveSamples( samps s );
  66. void Transpositions( samps s );
  67. void VolumeShifts( samps s );
  68. unsigned char NoteValue( unsigned int n );
  69. unsigned long NoteLength( unsigned char n, unsigned int l, unsigned int b );
  70. void WriteHeader( bfile mf, unsigned char n );
  71. unsigned int Trk0Info( bfile mf, string s );
  72. void AddToLog( unsigned long a, unsigned long b );
  73. void WriteLog( FILE *f );
  74. unsigned char RestrictVol( int v );
  75. void ConvertMOD( bfile f1, bfile f2, string tn, samps smp );
  76. extern int ScrollChoice( string title, string *sp, int w );
  77. extern string DialogBox( string *sp, string def );
  78.  
  79. char *version = "$VER: Mod2Midi 1.0 (12.6.94)";
  80. long __stack = 20000; // Code allocates everything off the stack ;-)
  81.  
  82. bfile MidFile, ModFile;
  83. char SongName[21];
  84. samps Samples;
  85. unsigned long PosLog[64];
  86. int DrumChann = 9, TempoType = 1, PosI = 0;
  87. string MidFN, ModFN;
  88.  
  89. char *TempoTypes[] = { "NORMAL", "EXTENDED" };
  90.  
  91. extern struct Library *DOSBase;
  92.  
  93. int main( int argc, char *argv[] )
  94. {
  95.     int r;
  96.     UBYTE Mode = MODE_CONVERT;
  97.  
  98.     MidFile->f = ModFile->f = NULL;
  99.     MidFN = ModFN = NULL;
  100.  
  101.     /* Only work if launched from shell */
  102.     if ( argc != 0 )
  103.     {
  104.         struct RDArgs *RDArgs;
  105.         LONG opts[OPT_NUMBEROF];
  106.  
  107.         opts[OPT_MODFILE] = 0;
  108.         opts[OPT_MIDIFILE] = 0;
  109.         opts[OPT_ABOUT] = 0;
  110.         opts[OPT_MAPSAMPLES] = 0;
  111.         opts[OPT_SAVEINFO] = 0;
  112.         opts[OPT_TRANSPOSE] = 0;
  113.         opts[OPT_DRUMCHANNEL] = 0;
  114.         opts[OPT_TEMPOTYPE] = 0;
  115.         opts[OPT_VOLUMESHIFT] = 0;
  116.  
  117.         RDArgs = ReadArgs( OPT_TEMPLATE, opts, NULL );
  118.         if ( RDArgs != NULL )
  119.         {
  120.             /* Grab all set cli parameters */
  121.             if ( opts[OPT_MODFILE] != 0 )
  122.             {
  123.                 ModFN = malloc( strlen( (char *)opts[OPT_MODFILE] ) + 1 );
  124.                 if ( ModFN != NULL ) strcpy( ModFN, (char *)opts[OPT_MODFILE] );
  125.             }
  126.  
  127.             if ( opts[OPT_MIDIFILE] != 0 )
  128.             {
  129.                 MidFN = malloc( strlen( (char *)opts[OPT_MIDIFILE] ) + 1 );
  130.                 if ( MidFN != NULL ) strcpy( MidFN, (char *)opts[OPT_MIDIFILE] );
  131.             }
  132.  
  133.             if ( opts[OPT_ABOUT] != 0 )    Mode |= MODE_ABOUT;
  134.  
  135.             if ( opts[OPT_MAPSAMPLES] != 0 ) Mode |= MODE_MAPSAMPLES;
  136.  
  137.             if ( opts[OPT_SAVEINFO] != 0 ) Mode |= MODE_SAVEINFO;
  138.  
  139.             if ( opts[OPT_TRANSPOSE] != 0 ) Mode |= MODE_TRANSPOSE;
  140.  
  141.             if ( opts[OPT_VOLUMESHIFT] != 0 ) Mode |= MODE_VOLUMESHIFT;
  142.  
  143.             if ( opts[OPT_DRUMCHANNEL] != 0 )
  144.             {
  145.                 /* Drum channel is stored as value - 1 */
  146.                 DrumChann = *( (ULONG *)opts[OPT_DRUMCHANNEL] ) - 1;
  147.                 printf( "Drum channel set to: %d\n", DrumChann + 1 );
  148.             }
  149.  
  150.             if ( opts[OPT_TEMPOTYPE] != 0 )
  151.             {
  152.                 int value;
  153.  
  154.                 value = *( (ULONG *)opts[OPT_TEMPOTYPE] );
  155.  
  156.                 if ( value >= 0 && value <= 1 )
  157.                 {
  158.                     TempoType = value;
  159.                     printf( "Tempo type set to: %s\n", TempoTypes[TempoType] );
  160.                 }
  161.                 else printf( "Illegal value for TEMPO, using default of NORMAL\n" );
  162.             }
  163.  
  164.             FreeArgs ( RDArgs );
  165.  
  166.             /* Open the MID file */
  167.             if ( MidFN != NULL )
  168.             {
  169.                 r = OpenOut( MidFile, MidFN );
  170.             }
  171.  
  172.             /* Open the MOD file */
  173.             if ( r != NULL && ModFN != NULL )
  174.             {
  175.                 if ( ModFile->f != NULL ) SaveDefaults( Samples, ModFN ); // Save defaults
  176.  
  177.                 r = OpenIn( ModFile, ModFN );
  178.                 if ( r != NULL )
  179.                 {
  180.                     if ( !ReadModSpecs( ModFile, SongName, Samples ) )
  181.                         printf( "%s is not a .mod file\n", ModFN );
  182.                     else
  183.                     if ( !SetDefaults( Samples, ModFN ) ) CloseIn( ModFile );
  184.                 }
  185.             }
  186.  
  187.             if ( ( Mode & MODE_ABOUT ) == MODE_ABOUT )
  188.             {
  189.                 int i = 0;
  190.                 while ( MSG_ABOUT[i] != NULL ) printf( "%s\n", MSG_ABOUT[ i++ ] );
  191.  
  192.                 Mode = NULL; //Dont allow futher processing
  193.             }
  194.  
  195.             if ( ( Mode & MODE_MAPSAMPLES ) == MODE_MAPSAMPLES )
  196.             {
  197.                 if ( ModFile->f != NULL ) MapSamples( Samples );
  198.                 else
  199.                 printf( "%s", MSG_ERR_NO_MOD_FILENAME );
  200.             }
  201.  
  202.             if ( ( Mode & MODE_SAVEINFO ) == MODE_SAVEINFO )
  203.             {
  204.                 if ( ModFile->f != NULL ) SaveSamples( Samples );
  205.                 else
  206.                 printf( "%s", MSG_ERR_NO_MOD_FILENAME );
  207.             }
  208.  
  209.             if ( ( Mode & MODE_TRANSPOSE ) == MODE_TRANSPOSE )
  210.             {
  211.                 if ( ModFile->f != NULL ) Transpositions( Samples );
  212.                 else
  213.                 printf( "%s", MSG_ERR_NO_MOD_FILENAME );
  214.             }
  215.  
  216.             if ( ( Mode & MODE_VOLUMESHIFT ) == MODE_VOLUMESHIFT )
  217.             {
  218.                 if ( ModFile->f != NULL ) VolumeShifts( Samples );
  219.                 else
  220.                 printf( "%s", MSG_ERR_NO_MOD_FILENAME );
  221.             }
  222.  
  223.             /* Do the conversion */
  224.             if ( MidFile->f != NULL && ModFile->f != NULL && Mode != NULL )
  225.             {
  226.                 if ( ChooseChannels( Samples ) <= 16 )
  227.                 {
  228.                     ConvertMOD( ModFile, MidFile, SongName, Samples );
  229.                 }
  230.                 else
  231.                 printf( "Too many instruments, there is a maximum of 16 allowed\n" );
  232.             }
  233.             else
  234.             printf( "Both a source .MOD and a destination .MID file must be supplied\n" );
  235.  
  236.             /* If the file is open, close it */
  237.             if ( ModFile->f != NULL )
  238.             {
  239.                 CloseIn( ModFile );
  240.                 SaveDefaults( Samples, ModFN );
  241.             }
  242.  
  243.             /* If a filename has been allocated, free it */
  244.             if ( ModFN != NULL ) free( ModFN );
  245.  
  246.             /* If the file is open, close it */
  247.             if ( MidFile->f != NULL ) CloseOut( MidFile );
  248.  
  249.             /* If a filename has been allocated, free it */
  250.             if ( MidFN != NULL ) free( MidFN );
  251.         }
  252.         else printf( "Illegal parameters!\n" );
  253.     }
  254. }
  255.  
  256. /* Post: The byte b has been written to the buffer of the file f */
  257. void OutByte( bfile f, char b )
  258. {
  259.     if ( f->o == BUFFSIZE )
  260.     {
  261.         fwrite( f->b, 1, BUFFSIZE, f->f );
  262.         f->o = 0;
  263.   }
  264.  
  265.     f->b[ f->o++ ] = b;
  266. }
  267.  
  268. /* Pre: f was opened for writing */
  269. /* Post: The file f has has its buffer flushed */
  270. void FlushOut( bfile f )
  271. {
  272.     if ( f->o > 0 ) fwrite( f->b, 1, f->o, f->f );
  273.  
  274.     f->o = 0;
  275. }
  276.  
  277. /* Pre: f was opened for writing */
  278. /* Post: The file f has been flushed and is now closed */
  279. void CloseOut( bfile f )
  280. {
  281.     FlushOut( f );
  282.  
  283.     fclose( f->f );
  284.     f->f = NULL;
  285. }
  286.  
  287. /* Returns: NZ if the file f has been opened for writing with the name fn */
  288. int OpenOut( bfile f, string fn )
  289. {
  290.     if ( f->f != NULL ) CloseOut( f );
  291.  
  292.     f->f = fopen( fn, "wb" );
  293.     f->o = 0;
  294.  
  295.     return f->f != NULL;
  296. }
  297.  
  298. /* Returns: bfile-tell; the offset from the start */
  299. unsigned long Beatle( bfile f )
  300. {
  301.     return ftell( f->f ) + f->o;
  302. }
  303.  
  304. /* Pre: f was opened for reading */
  305. /* Returns: The next byte from the file f */
  306. unsigned char InByte( bfile f )
  307. {
  308.     if ( f->o == BUFFSIZE && !feof( f->f ) )
  309.     {
  310.         f->r = fread( f->b, 1, BUFFSIZE, f->f );
  311.         if ( f->r < BUFFSIZE ) f->b[ f->r ] = 0;
  312.  
  313.         f->o = 0;
  314.     }
  315.  
  316.     if ( f->o < f->r ) return f->b[ f->o++ ];
  317.  
  318.     return f->b[ f->o ];
  319. }
  320.  
  321. /* Post: The file f is now closed */
  322. void CloseIn( bfile f )
  323. {
  324.     fclose( f->f );
  325.     f->f = NULL;
  326. }
  327.  
  328. /* Returns: NZ if the file f has been opened for reading with the name fn */
  329. int OpenIn( bfile f, string fn )
  330. {
  331.     if ( f->f != NULL ) CloseIn( f );
  332.  
  333.     f->f = fopen( fn, "rb" );
  334.  
  335.     f->o = f->r = BUFFSIZE;
  336.  
  337.     re