/** * composer.java * * Creates a musical composition in the form of a standard MIDI file. * * This base abtract class has methods to create a MIDI Sequence * write the Sequence to a standard MIDI file * and set some global variables common to all compositions. * * The abstract "composer ()" method which organizes the actual musical MIDI events * is to be implemented by specific types of composer * * This module is part of Karl Brown's MIDI programming project. * */ package MidiApps; import java.io.*; import java.util.*; import javax.sound.midi.*; /** * * @author Karl Brown * @version 1.0 * last updated 2/16/2003 */ public abstract class composer { tracer tr; String filename; String fileNameFinal = ""; String dirname; Sequence s; File f; int res = 24; byte baseMidiPitch; int numOctaves; long beatLength; // in ticks static byte MY_REED_ORGAN = 0x14; static byte SYNTH_SQUARE = 0x4F; static byte STRING_BASS = 0x20; static byte MY_TRUMPET = 0x39; static byte JAZZ_GUITAR = 0x1A; static byte PIANO = 0x00; static byte C_DOWN_4 = 0x0C; static byte C_DOWN_3 = 0x18; static byte C_DOWN_2 = 0x24; static byte C_DOWN_1 = 0x30; static byte MIDDLE_C = 0x3C; static byte C_UP_1 = 0x48; static byte C_UP_2 = 0x54; static byte C_UP_3 = 0x60; static byte C_UP_4 = 0x6C; public void setTracer(tracer trc) { tr = trc; // System.out.println("setTracer -- System.out.println"); // this.out.println("setTracer -- this.out.println"); // trc.trace("setTracer -- trc.trace"); // tr.trace("setTracer -- tr.trace"); } public void setFileName(String nameIn) { filename = new String(nameIn); } public String getFileNameFinal() { return fileNameFinal; } public void setDirectory(String dirIn) { dirname = new String(dirIn); } public byte getBaseMidiPitch() { return baseMidiPitch; } public int getNumOctaves() { return numOctaves; } public void setBaseMidiPitch(byte pitchIn) { if ((short)pitchIn < 127) { baseMidiPitch = pitchIn; } } public void setNumOctaves(int num) { if (num > 0 && num <= 8) { numOctaves = num; } } public void setBeatLength(long len) { if (len > 0) { beatLength = len; } } public long getBeatLength() { return beatLength; } /** * * Writes the MIDI sequence which has been built to a standard MIDI file * with the specified file name and directory path. * */ public void writeMidiFile () { try { String fname = filename + ".mid"; //prod // tr.trace("filename is " + fname); String pathname = dirname + "/" + fname; File f = new File(pathname); if (f.exists()) { // tr.trace(fname + " already exists
"); String ts = new timeStamp().getTimeStamp(); String fname2 = filename + ts +".mid"; //prod // tr.trace("new filename is " + fname2); String pathname2 = dirname + "/" + fname2; f = new File(pathname2); fileNameFinal = fname2; } else { // tr.trace(path + " does NOT exist
"); fileNameFinal = fname; } String path = f.getAbsolutePath(); MidiSystem.write(s,1,f); } catch (Exception e) { tr.trace("composer::writeMidiFile: Exception caught:"); tr.trace(e.toString()); } } /** * * sets number of ticks per beat - before creating sequence. * (Length of beat is set by tempo events AFTER creating sequence.) * */ public void setResolution (int resIn) { res = resIn; } public void createSequence () { try { s = new Sequence(0, res); } catch (Exception e) { tr.trace("createSequence exception caught: " + e); } } /** * * Abtract class method to generate the musical composition * for the Sequence * The implemented method must: * Create all Track objects fot the sequence * Generate all MIDI events, meta and sysex events * Add the events to the Tracks * */ public abstract void compose(); }