home *** CD-ROM | disk | FTP | other *** search
/ Da Capo / da_capo_vol1.bin / programs / amiga / midi / smusmidi / smusmidi.c < prev    next >
C/C++ Source or Header  |  1992-07-10  |  46KB  |  1,232 lines

  1. /*
  2. ** SMUSMIDI.C Copyright © 1991 Thomas E. Janzen
  3. ** Converts a DMCS .SMUS file to a standard MIDI file.
  4. ** Don't expect it to work on SMUS files from programs other than DMCS.
  5. ** 7-7-91 resumed work on it.
  6. ** 25 July 91 works pretty well
  7. ** 27 July remove double math to avoid linking math lib.
  8. ** 15 Aug 91
  9. ** 17 August 1991 Works well enough for me. Version 1.0
  10. */
  11. /* Copyright (c) 1990 by Thomas E. Janzen
  12.    All Rights Reserved
  13.  
  14.    THIS SOFTWARE IS FURNISHED FREE OF CHARGE FOR STUDY AND USE AND MAY
  15.    BE COPIED ONLY FOR PERSONAL USE OR COMPLETELY AS OFFERED WITH NO
  16.    CHANGES FOR FREE DISTRIBUTION.  NO TITLE TO AND OWNERSHIP OF THE
  17.    SOFTWARE IS HEREBY TRANSFERRED.  THOMAS E. JANZEN ASSUMES NO 
  18.    RESPONSBILITY FOR THE USE OR RELIABILITY OF THIS SOFTWARE.
  19.    
  20.    THOMAS E. JANZEN ASSUMES NO RESPONSIBILITY FOR THE USE OF THIS
  21.    SOFTWARE TO COPY MUSICAL SCORE FILES PROTECTED BY COPYRIGHT LAWS.
  22.    THIS SOFTWARE IS FOR USE ONLY WITHIN ANY AND ALL APPLICABLE LAWS.
  23.  
  24.    Thomas E. Janzen
  25.    58A School St. Apt. 2-L
  26.    Hudson, MA 01749
  27.    (508)562-1295
  28. */
  29. /*
  30. **  FACILITY:
  31. **
  32. **    SMUSMIDI file format convertor on Commodore (TM) Amiga (TM)
  33. **    compiled with SAS/C (TM) 5.10a
  34. **
  35. **  ABSTRACT:
  36. **
  37. **  SMUSMIDI.c converts SMUS files from DMCS (TM Electronic Arts)
  38. **             into standard MIDI file format files. 
  39. **
  40. **  AUTHOR: Thomas E. Janzen
  41. **
  42. **  CREATION DATE:    17-AUG-1991
  43. **
  44. **  MODIFICATION HISTORY:
  45. **    DATE    NAME    DESCRIPTION
  46. **--
  47. */
  48. #include <stdlib.h>
  49. #include <stdio.h>
  50. #include <ctype.h>
  51. #include <string.h>
  52. #include <proto/exec.h>
  53. #include "iff/iff.h"
  54. #include "iff/smus.h"
  55.  
  56. #define MIDI_FILE_TYPE ".MID"
  57. #define IDLEN         4
  58. #define TRUE          1
  59. #define FALSE         0
  60. #define SINGLMULTTRAK 0
  61. #define MULTITRACK    1
  62. #define MIDIHDRLEN   14
  63. #define MIDITRKHDRLEN 8
  64. #define SYSEXLEN      4
  65. #define NTRK_POS    12
  66. #define TICKS_PER_QUARTER 240
  67. #define NOTEON       0X90
  68. #define NOTEOFF      0X80
  69. #define META_EVENT   0XFF
  70. #define SEQ_NUM      0X00
  71.  
  72. #define TEXT_EVENT   0X01
  73. #define COPY_EVENT   0X02
  74. #define TRACK_NAME   0X03
  75. #define INST_NAME    0X04
  76. #define LYRIC_EVENT  0X05
  77. #define MARKER_EVENT 0X06
  78. #define CUE_POINT    0X07
  79. #define CHAN_PREFIX  0X20
  80. #define EOT_EVENT    0X2F
  81. #define TEMPO_EVENT  0X51
  82. #define TIME_SIG_EVENT 0X58
  83. #define KEY_EVENT    0X59
  84. #define MAX_TIES     32
  85. #define MAX_CHORDS   32
  86. #define NOT_OLD_CHORD 0x40000000
  87.  
  88. struct MIDI_Note_struct {
  89.    unsigned char  Status_Channel,
  90.                   Note_Number,
  91.                   Velocity;
  92. };
  93. typedef struct MIDI_Note_struct MIDI_NOTE_TYPE;
  94.  
  95. struct MIDI_Header {
  96.    unsigned int Chunk_Type;
  97.    unsigned int Chunk_Len;
  98.    unsigned short int Format;
  99.    unsigned short int Num_Tracks;
  100.    unsigned short int Division; /* of time, usu. 24 MIDI ticks or SMPTE */
  101. };
  102. typedef struct MIDI_Header MIDI_HEADER_TYPE;
  103.  
  104. struct MIDI_Track {
  105.    unsigned int Chunk_Type;
  106.    unsigned int Chunk_Len;
  107. };
  108. typedef struct MIDI_Track MIDI_TRACK_TYPE;
  109.  
  110. struct Chord_Struct {
  111.    unsigned char  Pitch, 
  112.                   Tied,
  113.                   Tied_Back,
  114.                   Delete;
  115. };
  116. typedef struct Chord_Struct CHORD_TYPE;
  117.  
  118. static char *MIDItoPitchName (int NoteNum, char *PitchName);
  119. static int SMUS_Len_to_MIDI_Delay (SEvent *Note);
  120. static int Variable_Length_Values (int Number, unsigned char *Array);
  121. static int Search_Tied_Array (char Pitch, char *Tied_Array, 
  122.                               int Tied_Index);
  123. static int Remove_Tied_Note (int Pitch, char *Tied_Array, int Tied_Index);
  124. static void Insert_Null (unsigned int *MIDI_Index, 
  125.                                  unsigned char *MIDI_Score);
  126. static void Insert_Meta_Event (unsigned int *MIDI_Index,
  127.                                        unsigned char *MIDI_Score,
  128.                                        unsigned char Event_Type,
  129.                                        unsigned int Event_Len);
  130. static void Send_a_Note (  unsigned int *MIDI_Index,
  131.                            unsigned char *MIDI_Score,
  132.                            unsigned char Current_Channel,
  133.                            unsigned char Current_Dynamic,
  134.                            unsigned char Pitch,
  135.                            unsigned char *Running_Status);
  136. static void Shutdown (void);
  137. static int Remove_Chord_Notes ( CHORD_TYPE *Chord_Array, 
  138.                                int Chord_Array_Len);
  139. static int Check_Tie (char *SMUS_Score, int SMUS_Index, SEvent Note, 
  140.                      int FORM_Size);
  141. static int Search_Chord_Array (  char Pitch, 
  142.                                  CHORD_TYPE *Chord_Array, 
  143.                                  int Chord_Index,
  144.                                  int Tied);
  145. static int Add_Chord_Array (CHORD_TYPE *Chord_Array, unsigned char Pitch,
  146.                               int Tie, int Tie_Back, int Chord_Index);
  147.  
  148. static unsigned char *SMUS_Score = NULL,
  149.                      *MIDI_Score = NULL;
  150. static FILE *SMUS_File = NULL,
  151.             *MIDI_File = NULL;
  152. static unsigned int Just_Did_a_Delay = FALSE;
  153.  
  154. void main (int argc, char *argv[])
  155. {
  156.    static unsigned char 
  157.                Track_String[32],
  158.                Current_Channel,
  159.                Current_Dynamic = 127,
  160.                Tied_Array[MAX_TIES],
  161.                key;
  162.    static CHORD_TYPE Chord_Array[MAX_CHORDS];
  163.    static MIDI_HEADER_TYPE MIDI_FileHdr = 
  164.                            {MakeID('M','T','h','d'), 6, 
  165.                               MULTITRACK, 1, TICKS_PER_QUARTER};
  166.    auto MIDI_TRACK_TYPE  *MIDI_Track_ptr;
  167.    auto unsigned char Score_Name[128],
  168.                       Running_Status = 0;
  169.    static char SMUS_File_Name[128] = "Score.smus",
  170.                MIDI_File_Name[128] = "ram:Score",
  171.                filemode[2] = "r";
  172.    static SScoreHeader Header;
  173.    auto unsigned int FORM_Size = 0,
  174.                      Instrument_Index,
  175.                      Track,
  176.                      Temp_ID,
  177.                      MIDI_Track_Index,
  178.                      status,
  179.                      tempint,
  180.                      ID_int,
  181.                      MIDI_Delay = 0,
  182.                      len,
  183.                      Real_Tie;
  184. #ifdef DEBUG
  185.    auto int          debug_stopper = 62;                     
  186. #endif
  187.    auto int          Chord_Index = 0,
  188.                      Chord_Counter = 0,
  189.                      Tied_Index = 0,
  190.                      Notes_per_Track,
  191.                      Chord_Note;
  192.    static unsigned int  Start_of_Tracks_Index,
  193.                         SMUS_Index = 0,
  194.                         MIDI_Index = 0,
  195.                         Caesura = TICKS_PER_QUARTER / 24;
  196.    static RefInstrument Instruments[32];
  197.    static SEvent Note;
  198.    static int Note_Counter;
  199.    union {
  200.       unsigned int Tempo_int;
  201.       unsigned char Tempo_char[4];
  202.    } MIDI_Tempo;
  203.  
  204.    if (argc != 3) 
  205.    {
  206.        printf ("usage: SMUSMIDI {SMUS_file} {MIDI_file(no type)}\n");
  207.        exit (1);
  208.    }
  209.    strcpy (SMUS_File_Name, argv[1]);
  210.    if  ((SMUS_File = fopen (SMUS_File_Name, filemode)) == NULL) 
  211.    {
  212.         printf ("Can't open SMUS input file.\n");
  213.         exit (1);
  214.    }
  215.    strcpy (filemode, "w");
  216.    strcpy (MIDI_File_Name, argv[2]);
  217.    strcat (MIDI_File_Name, MIDI_FILE_TYPE);
  218.    if  ((MIDI_File = fopen (MIDI_File_Name, filemode)) == NULL) 
  219.    {
  220.          printf ("Can't open MIDI output file.\n");
  221.          Shutdown ();
  222.    }
  223.    status = fread ((char *)&ID_int, sizeof (int), 1, SMUS_File);
  224.    if (ID_int != FORM)
  225.    {
  226.       printf ("Not a FORM file\n");
  227.       Shutdown ();
  228.    }
  229.    status = fread ((char *)&FORM_Size, sizeof (int), 1, SMUS_File);
  230.    printf ("FORM is: %d bytes.\n", FORM_Size);
  231.  
  232.    SMUS_Score = malloc (FORM_Size);
  233.    if (SMUS_Score == NULL)
  234.    {
  235.       printf ("Insufficient memory for SMUS Score\n");
  236.       Shutdown ();
  237.       exit (0);
  238.    }
  239.    MIDI_Score = malloc (4 * FORM_Size);
  240.    memset (MIDI_Score, '\0', 4 * FORM_Size);
  241.    if (MIDI_Score == NULL)
  242.    {
  243.       printf ("Insufficient memory for MIDI Score\n");
  244.       Shutdown ();
  245.    }
  246.    /* Copy whole file into RAM */
  247.    fread (SMUS_Score, FORM_Size, 1, SMUS_File);
  248.    fclose (SMUS_File);
  249.    SMUS_File = NULL;
  250.    
  251.    /* check for SMUS */
  252.    SMUS_Index = 0;
  253.    memcpy ((char *)&ID_int, &SMUS_Score[SMUS_Index], 4);
  254.    if (ID_int != ID_SMUS)
  255.    {
  256.       printf ("Input file was not an SMUS file!?\n");
  257.       Shutdown ();
  258.    }
  259.    SMUS_Index +=