view src/samer/midi/MidiRecorderBase.java @ 5:b67a33c44de7

Remove some crap, etc
author samer
date Fri, 05 Apr 2019 21:34:25 +0100
parents bf79fb79ee13
children
line wrap: on
line source
/*
 *	Copyright (c) 2000, Samer Abdallah, King's College London.
 *	All rights reserved.
 *
 *	This software is provided AS iS and WITHOUT ANY WARRANTY; 
 *	without even the implied warranty of MERCHANTABILITY or 
 *	FITNESS FOR A PARTICULAR PURPOSE.
 */

package samer.midi;
import samer.core.*;
import samer.core.types.*;
import samer.tools.*;
import java.util.*;
import java.io.*;
import javax.sound.midi.*;


public abstract class MidiRecorderBase extends NamedTask implements Agent
{
    Sequence	sequence;
	Track		track;
	int			currentTime;
	public 		VInteger	T;
	boolean	recording=false;

	public MidiRecorderBase() throws Exception
	{
		super("midi");
		sequence = new Sequence(Sequence.PPQ, 10);
		track = sequence.createTrack();
		currentTime=0;
		T = new VInteger("tickTime",100);
	}

	public void getCommands(Agent.Registry r) {
		r.add("record").add("stop").add("save").add("clear");
	}

	public void execute(String cmd, Environment env) throws Exception
	{
		if (cmd.equals("save")) {
			saveMidiFile(new File(X.string(env.datum("filename"),"synth.mid")));
		} else if (cmd.equals("clear")) {
			sequence = new Sequence(Sequence.PPQ, 10);
			track = sequence.createTrack();
			currentTime=0;
		} else if (cmd.equals("record")) {
			recording=true;
		} else if (cmd.equals("stop")) {
			recording=false;
		}
	}

    /**
     * given 120 bpm:
     *   (120 bpm) / (60 seconds per minute) = 2 beats per second
     *   2 / 1000 beats per millisecond
     *   (2 * resolution) ticks per second
     *   (2 * resolution)/1000 ticks per millisecond, or 
     *      (resolution / 500) ticks per millisecond
     *   ticks = milliseconds * resolution / 500
     */
    public void noteOn(int ch, int num,int vel) 
	{
		if (!recording) return;
        try {
		    ShortMessage message = new ShortMessage();
            long tick = currentTime * sequence.getResolution() / 500;
            message.setMessage(ShortMessage.NOTE_ON+ch, num, vel); 
            track.add(new MidiEvent(message, tick));
        } catch (Exception ex) { ex.printStackTrace(); }
    }

    public void noteOff(int ch, int num)
	{
		if (!recording) return;
        try {
		    ShortMessage message = new ShortMessage();
            long tick = currentTime * sequence.getResolution() / 500;
            message.setMessage(ShortMessage.NOTE_OFF+ch, num, 0);
            track.add(new MidiEvent(message, tick));
        } catch (Exception ex) { ex.printStackTrace(); }
    }

	public void tick() { if (recording) currentTime+=T.value; }

    public void saveMidiFile(File file) throws Exception
	{
        int[] fileTypes = MidiSystem.getMidiFileTypes(sequence);
        if (fileTypes.length == 0) {
            System.out.println("Can't save sequence");
        } else {
            if (MidiSystem.write(sequence, fileTypes[0], file) == -1) {
                throw new IOException("Problems writing to file");
            } 
        }
    }
}