home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Da Capo
/
da_capo_vol1.bin
/
programs
/
amiga
/
midi
/
smusmidi
/
smusmidi.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-10
|
46KB
|
1,232 lines
/*
** SMUSMIDI.C Copyright © 1991 Thomas E. Janzen
** Converts a DMCS .SMUS file to a standard MIDI file.
** Don't expect it to work on SMUS files from programs other than DMCS.
** 7-7-91 resumed work on it.
** 25 July 91 works pretty well
** 27 July remove double math to avoid linking math lib.
** 15 Aug 91
** 17 August 1991 Works well enough for me. Version 1.0
*/
/* Copyright (c) 1990 by Thomas E. Janzen
All Rights Reserved
THIS SOFTWARE IS FURNISHED FREE OF CHARGE FOR STUDY AND USE AND MAY
BE COPIED ONLY FOR PERSONAL USE OR COMPLETELY AS OFFERED WITH NO
CHANGES FOR FREE DISTRIBUTION. NO TITLE TO AND OWNERSHIP OF THE
SOFTWARE IS HEREBY TRANSFERRED. THOMAS E. JANZEN ASSUMES NO
RESPONSBILITY FOR THE USE OR RELIABILITY OF THIS SOFTWARE.
THOMAS E. JANZEN ASSUMES NO RESPONSIBILITY FOR THE USE OF THIS
SOFTWARE TO COPY MUSICAL SCORE FILES PROTECTED BY COPYRIGHT LAWS.
THIS SOFTWARE IS FOR USE ONLY WITHIN ANY AND ALL APPLICABLE LAWS.
Thomas E. Janzen
58A School St. Apt. 2-L
Hudson, MA 01749
(508)562-1295
*/
/*
** FACILITY:
**
** SMUSMIDI file format convertor on Commodore (TM) Amiga (TM)
** compiled with SAS/C (TM) 5.10a
**
** ABSTRACT:
**
** SMUSMIDI.c converts SMUS files from DMCS (TM Electronic Arts)
** into standard MIDI file format files.
**
** AUTHOR: Thomas E. Janzen
**
** CREATION DATE: 17-AUG-1991
**
** MODIFICATION HISTORY:
** DATE NAME DESCRIPTION
**--
*/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <proto/exec.h>
#include "iff/iff.h"
#include "iff/smus.h"
#define MIDI_FILE_TYPE ".MID"
#define IDLEN 4
#define TRUE 1
#define FALSE 0
#define SINGLMULTTRAK 0
#define MULTITRACK 1
#define MIDIHDRLEN 14
#define MIDITRKHDRLEN 8
#define SYSEXLEN 4
#define NTRK_POS 12
#define TICKS_PER_QUARTER 240
#define NOTEON 0X90
#define NOTEOFF 0X80
#define META_EVENT 0XFF
#define SEQ_NUM 0X00
#define TEXT_EVENT 0X01
#define COPY_EVENT 0X02
#define TRACK_NAME 0X03
#define INST_NAME 0X04
#define LYRIC_EVENT 0X05
#define MARKER_EVENT 0X06
#define CUE_POINT 0X07
#define CHAN_PREFIX 0X20
#define EOT_EVENT 0X2F
#define TEMPO_EVENT 0X51
#define TIME_SIG_EVENT 0X58
#define KEY_EVENT 0X59
#define MAX_TIES 32
#define MAX_CHORDS 32
#define NOT_OLD_CHORD 0x40000000
struct MIDI_Note_struct {
unsigned char Status_Channel,
Note_Number,
Velocity;
};
typedef struct MIDI_Note_struct MIDI_NOTE_TYPE;
struct MIDI_Header {
unsigned int Chunk_Type;
unsigned int Chunk_Len;
unsigned short int Format;
unsigned short int Num_Tracks;
unsigned short int Division; /* of time, usu. 24 MIDI ticks or SMPTE */
};
typedef struct MIDI_Header MIDI_HEADER_TYPE;
struct MIDI_Track {
unsigned int Chunk_Type;
unsigned int Chunk_Len;
};
typedef struct MIDI_Track MIDI_TRACK_TYPE;
struct Chord_Struct {
unsigned char Pitch,
Tied,
Tied_Back,
Delete;
};
typedef struct Chord_Struct CHORD_TYPE;
static char *MIDItoPitchName (int NoteNum, char *PitchName);
static int SMUS_Len_to_MIDI_Delay (SEvent *Note);
static int Variable_Length_Values (int Number, unsigned char *Array);
static int Search_Tied_Array (char Pitch, char *Tied_Array,
int Tied_Index);
static int Remove_Tied_Note (int Pitch, char *Tied_Array, int Tied_Index);
static void Insert_Null (unsigned int *MIDI_Index,
unsigned char *MIDI_Score);
static void Insert_Meta_Event (unsigned int *MIDI_Index,
unsigned char *MIDI_Score,
unsigned char Event_Type,
unsigned int Event_Len);
static void Send_a_Note ( unsigned int *MIDI_Index,
unsigned char *MIDI_Score,
unsigned char Current_Channel,
unsigned char Current_Dynamic,
unsigned char Pitch,
unsigned char *Running_Status);
static void Shutdown (void);
static int Remove_Chord_Notes ( CHORD_TYPE *Chord_Array,
int Chord_Array_Len);
static int Check_Tie (char *SMUS_Score, int SMUS_Index, SEvent Note,
int FORM_Size);
static int Search_Chord_Array ( char Pitch,
CHORD_TYPE *Chord_Array,
int Chord_Index,
int Tied);
static int Add_Chord_Array (CHORD_TYPE *Chord_Array, unsigned char Pitch,
int Tie, int Tie_Back, int Chord_Index);
static unsigned char *SMUS_Score = NULL,
*MIDI_Score = NULL;
static FILE *SMUS_File = NULL,
*MIDI_File = NULL;
static unsigned int Just_Did_a_Delay = FALSE;
void main (int argc, char *argv[])
{
static unsigned char
Track_String[32],
Current_Channel,
Current_Dynamic = 127,
Tied_Array[MAX_TIES],
key;
static CHORD_TYPE Chord_Array[MAX_CHORDS];
static MIDI_HEADER_TYPE MIDI_FileHdr =
{MakeID('M','T','h','d'), 6,
MULTITRACK, 1, TICKS_PER_QUARTER};
auto MIDI_TRACK_TYPE *MIDI_Track_ptr;
auto unsigned char Score_Name[128],
Running_Status = 0;
static char SMUS_File_Name[128] = "Score.smus",
MIDI_File_Name[128] = "ram:Score",
filemode[2] = "r";
static SScoreHeader Header;
auto unsigned int FORM_Size = 0,
Instrument_Index,
Track,
Temp_ID,
MIDI_Track_Index,
status,
tempint,
ID_int,
MIDI_Delay = 0,
len,
Real_Tie;
#ifdef DEBUG
auto int debug_stopper = 62;
#endif
auto int Chord_Index = 0,
Chord_Counter = 0,
Tied_Index = 0,
Notes_per_Track,
Chord_Note;
static unsigned int Start_of_Tracks_Index,
SMUS_Index = 0,
MIDI_Index = 0,
Caesura = TICKS_PER_QUARTER / 24;
static RefInstrument Instruments[32];
static SEvent Note;
static int Note_Counter;
union {
unsigned int Tempo_int;
unsigned char Tempo_char[4];
} MIDI_Tempo;
if (argc != 3)
{
printf ("usage: SMUSMIDI {SMUS_file} {MIDI_file(no type)}\n");
exit (1);
}
strcpy (SMUS_File_Name, argv[1]);
if ((SMUS_File = fopen (SMUS_File_Name, filemode)) == NULL)
{
printf ("Can't open SMUS input file.\n");
exit (1);
}
strcpy (filemode, "w");
strcpy (MIDI_File_Name, argv[2]);
strcat (MIDI_File_Name, MIDI_FILE_TYPE);
if ((MIDI_File = fopen (MIDI_File_Name, filemode)) == NULL)
{
printf ("Can't open MIDI output file.\n");
Shutdown ();
}
status = fread ((char *)&ID_int, sizeof (int), 1, SMUS_File);
if (ID_int != FORM)
{
printf ("Not a FORM file\n");
Shutdown ();
}
status = fread ((char *)&FORM_Size, sizeof (int), 1, SMUS_File);
printf ("FORM is: %d bytes.\n", FORM_Size);
SMUS_Score = malloc (FORM_Size);
if (SMUS_Score == NULL)
{
printf ("Insufficient memory for SMUS Score\n");
Shutdown ();
exit (0);
}
MIDI_Score = malloc (4 * FORM_Size);
memset (MIDI_Score, '\0', 4 * FORM_Size);
if (MIDI_Score == NULL)
{
printf ("Insufficient memory for MIDI Score\n");
Shutdown ();
}
/* Copy whole file into RAM */
fread (SMUS_Score, FORM_Size, 1, SMUS_File);
fclose (SMUS_File);
SMUS_File = NULL;
/* check for SMUS */
SMUS_Index = 0;
memcpy ((char *)&ID_int, &SMUS_Score[SMUS_Index], 4);
if (ID_int != ID_SMUS)
{
printf ("Input file was not an SMUS file!?\n");
Shutdown ();
}
SMUS_Index +=