首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java midi SysEx消息,流卡住,可能的错误?

Java midi SysEx消息,流卡住,可能的错误?
EN

Stack Overflow用户
提问于 2017-07-31 03:59:30
回答 1查看 184关注 0票数 0

当我一个接一个地发送具有不同字节长度的sysex消息时,midi流被卡住了。如果我坚持只有一个字节的长度,它工作得很好,但我有两个不同的sysex消息要传递:一个用于实时参数更改,另一个用于完整的补丁(备份)。

我已经通过javaFX编写了一个示例测试用例来演示此行为。

代码语言:javascript
复制
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Slider;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.SysexMessage;
import static javax.sound.midi.SysexMessage.SYSTEM_EXCLUSIVE;


public class MidiTestEnvironment extends Application {

    public static MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
    public static MidiDevice outputDevice;
    public static Receiver outputReceiver;
    public static final byte DEVICE_NUMBER = 76;

    @Override
    public void start(Stage primaryStage) {

        // Show output devices only. Replace the DEVICE_NUMBER constant with a working
        // output midi device number.
        printOutputDevices();

        // Set the output device and open it first, then set the receiver. 
        try {
            outputDevice = MidiSystem.getMidiDevice(MidiSystem.getMidiDeviceInfo()[DEVICE_NUMBER]);
            if (!(outputDevice.isOpen())){
                outputDevice.open();
            }
            outputReceiver = outputDevice.getReceiver();
            System.out.println("outputreciever: " + outputDevice.getDeviceInfo().getName());
        } catch (MidiUnavailableException ex) {
            Logger.getLogger(MidiTestEnvironment.class.getName()).log(Level.SEVERE, null, ex);
        }

        // Create a Button and send a Message to the defined Midi Out
        Button btn1 = new Button("Send Message 82 bytes !");
        btn1.setOnAction((ActionEvent event) -> {
            try {
                // sendControlMessage(7,50);
                sendSysexMessage(SysexJX8P_APN(), SysexJX8P_APN().length);
                System.out.println("Hello World!");
            } catch (InvalidMidiDataException ex) {
                Logger.getLogger(MidiTestEnvironment.class.getName()).log(Level.SEVERE, null, ex);
            }
        });

        // Create a Slider and send a Message to the defined Midi Out
        Slider sysexSlider = new Slider(0,127,0);
        sysexSlider.setMaxHeight(200);
        sysexSlider.setOrientation(Orientation.VERTICAL);

        sysexSlider.valueProperty().addListener((value,oldValue,newValue)->{
            try {
                sendSysexMessage(SysexJX8P_L1(20,newValue.byteValue()),10);
            } catch (InvalidMidiDataException ex) {
                Logger.getLogger(MidiTestEnvironment.class.getName()).log(Level.SEVERE, null, ex);
            }
        });

        // Cobble the gui together
        HBox root = new HBox();
        root.setSpacing(20);
        root.getChildren().addAll(btn1,sysexSlider);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

    //-------------------------------------------------------------------------------------------------------------------------------
    //-- SETUP MIDI MESSAGES
    //-------------------------------------------------------------------------------------------------------------------------------

    public static void sendControlMessage(int controller, int value) throws MidiUnavailableException {
        ShortMessage controlMessage = new ShortMessage();
        try {
            controlMessage.setMessage(ShortMessage.CONTROL_CHANGE, controller, value);
        } catch (InvalidMidiDataException ex) {
           Logger.getLogger(MidiTestEnvironment.class.getName()).log(Level.SEVERE, null, ex);
        }
        outputReceiver.send(controlMessage, -1);
    }



    public static void sendSysexMessage(byte[] data, int length) throws InvalidMidiDataException {
        SysexMessage sysexMessage = new SysexMessage();
        try {
            sysexMessage.setMessage(data, length);
            outputReceiver.send(sysexMessage, -1);
        } catch (InvalidMidiDataException ex) {
            Logger.getLogger(MidiTestEnvironment.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    //-------------------------------------------------------------------------------------------------------------------------------
    // DISPLAY OUTPUT DEVICES ONLY
    public static void printOutputDevices() {
        for (int i = 0; i < MidiSystem.getMidiDeviceInfo().length; i++) {
            try {
                if (MidiSystem.getMidiDevice(infos[i]).getMaxReceivers() == -1
                        && !MidiSystem.getMidiDevice(infos[i]).getDeviceInfo().getName().equals("Gervill")) 
                {
                    System.out.println(infos[i].getName() + " - " + infos[i].getDescription() + " | device Number: " + i);
                }
            } catch (MidiUnavailableException ex) {
                Logger.getLogger(MidiTestEnvironment.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    //-------------------------------------------------------------------------------------------------------------------------------
    //-- TEST SYSEX MESSAGES
    //-------------------------------------------------------------------------------------------------------------------------------
    public static final byte[] SysexJX8P_L1(int p_byteEight, byte v_byteNine) {
        byte[] sysexStringL1 = new byte[10];
        sysexStringL1[0] = (byte) (SYSTEM_EXCLUSIVE & 0xFF);
        sysexStringL1[1] = 0x41;
        sysexStringL1[2] = 0x36;
        sysexStringL1[3] = 0x00;
        sysexStringL1[4] = 0x21;
        sysexStringL1[5] = 0x20;
        sysexStringL1[6] = 0x01;
        sysexStringL1[7] = (byte) p_byteEight;
        sysexStringL1[8] = v_byteNine;
        sysexStringL1[9] = (byte) (ShortMessage.END_OF_EXCLUSIVE & 0xFF);
        return sysexStringL1;
    }

    public static final byte[] SysexJX8P_APN() {
        byte[] sysExStringAP = {(byte) (SYSTEM_EXCLUSIVE & 0xFF), 0x41, 0x35, 0x00, 0x21, 0x20, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,
            0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,
            0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,
            0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,
            0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, (byte) (ShortMessage.END_OF_EXCLUSIVE & 0xFF)};
        return sysExStringAP;
    }


}
EN

回答 1

Stack Overflow用户

发布于 2020-01-02 17:02:21

我也遇到过类似的问题,jdk 8和jdk 13都有类似的问题。通过关闭和打开sysex传输周围的MIDI设备解决了这个问题:

代码语言:javascript
复制
midiout.open();
midiout.getReceiver().send(outMsg, timeStamp);
midiout.close();
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45404129

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档