Подключение устройства Midi и задержка

В настоящее время я программирую простое приложение, которое принимает данные с устройства midi и выводит соответствующий звук. Я получил все для работы сейчас, но есть две проблемы: во-первых, когда я подключаю MIDI-устройство ПОСЛЕ запуска программы или отключаю его во время работы программы, она не будет распознана. Во-вторых, задержка очень высока как для OSX, так и для Linux (Raspbian) и Windows. Кто-нибудь знает решение любой из этих проблем? Вот что у меня есть:

Класс MidiHandler читает входные данные и синтезирует звук

public class MidiHandler {
MidiDevice device;
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
List<Transmitter> transmitters;
MidiInputReceiver reciever;

public MidiHandler() {

    for (int i = 0; i < infos.length; i++) {
        try {
            this.device = MidiSystem.getMidiDevice(this.infos[i]);
            // does the device have any transmitters?
            // if it does, add it to the device list
            System.out.println(this.infos[i]);

            // get all transmitters
            this.transmitters = this.device.getTransmitters();

            // using my own MidiInputReceiver
            this.reciever = new MidiInputReceiver(this.device
                    .getDeviceInfo().toString());
            // and for each transmitter
            for (int j = 0; j < this.transmitters.size(); j++) {
                // create a new receiver
                this.transmitters.get(j).setReceiver(this.reciever);
            }

            Transmitter trans = this.device.getTransmitter();
            trans.setReceiver(new MidiInputReceiver(this.device
                    .getDeviceInfo().toString()));
            this.device.open();
        } catch (MidiUnavailableException e) {
        }
    }

}

public void playNote(byte b) {
    reciever.playNote(b);
}

public void stopNote(byte b) {
    reciever.stopNote(b);
}

public void close() {
    for (int i = 0; i < this.transmitters.size(); ++i) {
        this.transmitters.get(i).close();
    }
    this.reciever.close();
    this.device.close();
}

public String getInfos() {
    String infos = "";
    for (int i = 0; i < this.infos.length; i++) {
        infos += "\n" + this.infos[i] + " ";
    }
    return infos;
}

// tried to write my own class. I thought the send method handles an
// MidiEvents sent to it
public class MidiInputReceiver implements Receiver {
    Synthesizer synth;
    MidiChannel[] mc;
    Instrument[] instr;
    int instrument;
    int channel;

    public MidiInputReceiver(String name) {
        try {
            patcher p = new patcher();
            this.instrument = p.getInstrument();
            this.channel = p.getChannel();
            this.synth = MidiSystem.getSynthesizer();
            this.synth.open();
            this.mc = synth.getChannels();
            instr = synth.getDefaultSoundbank().getInstruments();
            this.synth.loadInstrument(instr[1]);
            mc[this.channel].programChange(0, this.instrument);
        } catch (MidiUnavailableException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    public void send(MidiMessage msg, long timeStamp) {
        /*
         * Use to display midi message
        for (int i = 0; i < msg.getMessage().length; i++) {
            System.out.print("[" + msg.getMessage()[i] + "] ");

        }

        System.out.println();
        */

        if (msg.getMessage()[0] == -112) {
            mc[this.channel].noteOn(msg.getMessage()[1],
                    msg.getMessage()[2] + 1000);
        }

        if (msg.getMessage()[0] == -128) {
            mc[this.channel].noteOff(msg.getMessage()[1],
                    msg.getMessage()[2] + 1000);
        }

    }

    public void playNote(byte b) {
        mc[this.channel].noteOn(b, 1000);
    }

    public void stopNote(byte b) {
        mc[this.channel].noteOff(b);
    }

    public void close() {
    }

}

Класс Shell содержит метод main

public class Shell {
private static MidiHandler midi;
AudioServer server;

private Shell() {
}

/**
 * The main method. Executes via BufferedReader, to communicate with the
 * user
 * 
 * @param args
 *            Command line parameter
 * @throws IOException
 *             IOExeption can occur
 */
public static void main(String[] args) throws IOException {

    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    execute(in);
}

/**
 * Method used for general interaction with the user. Utilizes a
 * BufferedReader to read inputs, then proceeds to analyze the input for
 * predefined commands
 * 
 * @param in
 *            The BufferedReader in use
 * @throws IOException
 * @throws ParseException
 */
private static void execute(BufferedReader in) throws IOException {

    boolean quit = false;
    while (!quit) {

        midi = new MidiHandler();
        System.out.print("midi> ");
        String input;
        input = in.readLine(); // read line
        if (input == null | input.isEmpty()) {
            break;
        } // No command given?

        // First character is always the command.
        char command = Character.toLowerCase(input.charAt(0));

        try {

            switch (command) {

            case 'n':
                midi = new MidiHandler();
                break;

            case 'c':
                midi.close();
                break;

            case 'p':
                midi.playNote((byte) 60);
                break;

            case 's':
                midi.stopNote((byte) 60);

            case 'q':
                midi.close();
                quit = true;
                System.exit(0);
                break;

            default:
                System.out.println("Unknown command");
                break;
            }

        } catch (NumberFormatException e) {
            System.out.println("Invalid parameter");
        }

    }

}

Любая помощь будет принята с благодарностью. Заранее спасибо.

0 ответов

Другие вопросы по тегам