我如何使用Java的MidiSystem.write()函数?

时间:2015-04-19 21:28:05

标签: java sequence midi filewriter out

Java Doc for Function

我似乎无法弄清楚如何使用此功能。我有一个Java.Midi.Sequence和我想写的文件,但我无法弄清楚“int fileType”是什么。在MidiSystem,Sequence或MidiFileWriter中没有要引用的静态int。 0也没有帮助。

使用零时得到的错误是这样的:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: seph.reed.effigy.MidiLoader$1 cannot be cast to javax.sound.midi.ShortMessage
at com.sun.media.sound.StandardMidiFileWriter.writeTrack(StandardMidiFileWriter.java:386)
at com.sun.media.sound.StandardMidiFileWriter.getFileStream(StandardMidiFileWriter.java:204)
at com.sun.media.sound.StandardMidiFileWriter.write(StandardMidiFileWriter.java:137)
at com.sun.media.sound.StandardMidiFileWriter.write(StandardMidiFileWriter.java:153)
at javax.sound.midi.MidiSystem.write(MidiSystem.java:1060)
at seph.reed.effigy.MidiLoader.saveClipAs(MidiLoader.java:197)
at seph.reed.effigy.EffigyMenuBar$2.onClick(EffigyMenuBar.java:47)

引用的个人功能是:

public void saveClipAs(File selectedFile) {
    try {
        Sequence out = new Sequence(Sequence.PPQ, 256);
        Track toMe = out.createTrack();

        Sequencer fromMe = ANCESTOR(Effigy.class).m_gui.getCurrentClip().m_sequencer;
//traverse linked list adding notes to track
        for(MidiEventEntity ptr = fromMe.m_head; ptr != null; ptr = ptr.m_next) {
            byte[] midiData = new byte[3];
            midiData[0] = MidiToolBox.NOTE_ON;
            midiData[1] = (byte)ptr.getNote();
            midiData[2] = (byte)127;

            long tick = (long) (256 * ptr.getBeat()); //256 ticks per 1/4 note
            MidiEvent addMe = new MidiEvent(new MidiMessage(midiData) {
                @Override
                public Object clone() {
                    return null;  }
            }, tick);
            toMe.add(addMe);
        }

  //THIS LINE BELOW
        MidiSystem.write(out, 0, selectedFile);
    }
    catch (InvalidMidiDataException e) {
        e.printStackTrace();  } 
    catch (IOException e) {
        e.printStackTrace();
    }
}

感谢您的帮助。我完全不知道int fileType究竟要求什么。

编辑:删除了一个愚蠢的次要问题。

编辑:功能代码:

for(MidiEventEntity ptr = fromMe.m_head; ptr != null; ptr = ptr.m_next) {
            byte status = MidiToolBox.NOTE_ON;
            byte note = (byte)ptr.getNote();
            byte velocity = (byte)127;

            long tick = (long) (256 * ptr.getBeat()); //256 ticks per 1/4 note
            ShortMessage msg = new ShortMessage(status, note, velocity);
            MidiEvent addMe = new MidiEvent(msg, tick);
            toMe.add(addMe);
        }

2 个答案:

答案 0 :(得分:1)

看起来int对应于Midi Type 0,Midi Type 1,Midi Type 2 (more details here)

就如何确定系统支持的midi类型而言,您可以调用MidiSystem.getMidiFileTypes(Sequence sequence)方法。

答案 1 :(得分:0)

根据https://docs.oracle.com/javase/tutorial/sound/SPI-providing-MIDI.html

  

有三种标准MIDI文件格式,所有这些格式都可以支持Java Sound API:Type 0,Type 1和Type 2.这些文件格式在文件中MIDI序列数据的内部表示方式不同,适用于不同种类的序列。如果实现本身不支持所有三种类型,则服务提供者可以为未实现的类型提供支持。还有标准MIDI文件格式的变体,其中一些是专有的,同样可以由第三方供应商支持。

因此fileType为0,1或2。 您可以通过MidiSystem.getMidiFileTypes()查看您的实现支持的文件类型。 可以通过识别midi文件的文件类型 MidiSystem.getMidiFileFormat()(见 http://docs.oracle.com/javase/7/docs/api/javax/sound/midi/MidiSystem.html#getMidiFileFormat%28java.io.File%29http://docs.oracle.com/javase/7/docs/api/javax/sound/midi/MidiFileFormat.html