【问题标题】:Java Midi Sequencer doesn't play after recordingJava Midi Sequencer 录制后不播放
【发布时间】:2016-01-09 21:18:17
【问题描述】:

我写了一个小midi录音机,之后应该可以播放曲目:

Sequencer seqr=MidiSystem.getSequencer();

//Transmitters and receivers here

seqr.startRecording();

//Some Stuff (basically waiting)

seqr.stopRecording();
seqr.setTickPosition(0);
seqr.setLoopStartPoint(0);
seqr.setLoopEndPoint(seqr.getTickLength());
seqr.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
seqr.start();

它没有,但是 - 这让我很困惑 - 如果我添加:

File midFile=new File("MyMidiFile.mid");
MidiSystem.write(seqr.getSequence(), 1, midFile);
seqr.setSequence(MidiSystem.getSequence(midFile));

stopRecoding()之后播放,

这告诉我,录音和播放工作正常。

//问题结束

编辑

我的整个 midi 代码按要求

发射器和接收器

public static MidiDevice inputDevice;
public static MidiDevice outputDevice;
public static Transmitter usbTransmitter;
public static Receiver usbReciever;

public static Sequencer seqr;
public static Transmitter seqTransmitter;
public static Receiver seqReciever;

初始化:

try{
    seqr = MidiSystem.getSequencer();

    Info[] midiDeviceInfo = MidiSystem.getMidiDeviceInfo();

    inputDevice = MidiSystem.getMidiDevice(midiDeviceInfo[1]);
    outputDevice = MidiSystem.getMidiDevice(midiDeviceInfo[4]);
    seqr = MidiSystem.getSequencer();
    inputDevice.open();
    outputDevice.open();
    seqr.open();

    seqReciever = seqr.getReceiver();
    seqTransmitter = seqr.getTransmitters().get(0);

    usbTransmitter = inputDevice.getTransmitter();
    usbReciever = outputDevice.getReceiver();
    usbTransmitter.setReceiver(seqReciever);
    seqTransmitter.setReceiver(usbReciever);

    Sequence seq = new Sequence(Sequence.PPQ, 24);

    seqr.setSequence(seq);
    seqr.setTickPosition(0);
} catch (MidiUnavailableException | InvalidMidiDataException e) {
    e.printStackTrace();
}

录音:

Track track;
Sequencer seqr;
Sequence seq;

public TrackControler(Sequencer seqr) {
    this.seqr = seqr;
    this.seq = seqr.getSequence();
    this.track = seq.createTrack();
}

private void startRecordNow() {
    seqr.recordEnable(track, -1);
    seqr.startRecording();
}

private void endRecordNow() {
    seqr.stopRecording();

    seqr.setTickPosition(0);
    seqr.setLoopStartPoint(0);
    seqr.setLoopEndPoint(seqr.getTickLength());
    seqr.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
    seqr.start();
}

【问题讨论】:

    标签: java midi


    【解决方案1】:

    如果没有看到您的 MIDI 录音或播放代码,我不得不猜测 MidiSystem.write()Sequencer.setSequence() 正在做一些您忽略的初始化。我的第二个猜测是Sequencer.stopRecording() 没有让游戏处于正确的状态。

    这是我能做的最好的事情,没有更多信息。

    更新(因此您不必查看 cmets):

    Java 似乎做了一些缓存,需要seqr.setSequence(seqr.getSequence() 之类的东西来提交缓存。我一直在寻找更直接的方法来做到这一点,但没有找到任何东西。

    【讨论】:

    • 这是我的代码的 midi 部分。这有什么线索吗?
    • 你在停止录制时尝试过seqr.recordingDisable(track);吗?另外,我会为序列的长度添加一个调试检查(seq. getMicrosecondLength() 会这样做),以确保记录一些内容。
    • 我不知道禁用,但它不能解决我的问题。我的代码和其他一些调试打印中有System.out.println(track.size() - 1 + " events");。所以我可以肯定地告诉你,轨道不是空的
    • 如果通读RealTimeSequnecer源代码。 setSequence() 做了一些缓存刷新,如果我做seqr.setSequence(seqr.getSequence()); 也会调用它,它神奇地工作......
    • 如果你插入seqr.setSequence(seqr.getSequence());而不是写一个文件然后读回的语句会发生什么?我知道这不应该有任何意义,但我猜想在设置序列时会发生一些事情,如果它有效,至少你有一个不涉及写入文件的解决方法。 ;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-07
    • 1970-01-01
    • 2019-02-17
    • 1970-01-01
    相关资源
    最近更新 更多