0

こんにちは: MIDI シーケンサーのインスタンスを外部クロックに同期させようとしています。やった:

S_p = MidiSystem.getSequencer(false);
D2 = MidiSystem.getMidiDevice(MidiSystem.getMidiDeviceInfo()[1]);
S_p.open();
D2.open();
R2=S_p.getReceiver();
T2=D2.getTransmitter();
T2.setReceiver(R2);

しかし

for(int i=0;i<S_p.getMasterSyncModes().length;i++)
{System.out.println("Available modes are "+i+ " "+S_p.getMasterSyncModes()[i].toString());}

戻り値

 Available modes are 0 Internal Clock

つまり、これは役に立たなくなります。

S_p.setMasterSyncMode(Sequencer.SyncMode.MIDI_SYNC);

私は何を間違っていますか?もちろん、D2 から送信されて、system.out に通知するようにカスタム作成された別のレシーバーに送信されるメッセージの確認があり、シーケンサーは正常に再生されますが、SyncModes ドキュメントをサポートしていないようです。具体的には、このフレーズは私を混乱させます(MIDI_SYNCから:「このモードは、MIDIレシーバーでもあるシーケンサーのマスター同期モードとしてのみ適用されます。」

シーケンサーが受信機であることの意味は何ですか。getReceiver() の私のアプローチで十分だと思いました

よろしくお願いします!

4

2 に答える 2

1

将来の世代のために:

自作で、自分に合った、MIDI クロック シーケンサー。(シーケンサーが受信機であることについて、それが何を言っているのかが明確になったと思います): (受信機が異なる MIDI チャンネルでリッスンし、それに応じてトラックが作成されると仮定します。閉じるときにすべてのノートを送信します。Track_Master は私の実装からのもので、チャンネルを追跡します。受信者はリッスンしています)

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.Sequence;

/**
 * @author claudio
 *
 */

public class MIDI_Clocked_Sequencer implements Receiver {

private Sequence S;
private int[] playheads;
private long counter=0;
private Receiver[] receivers;
private long counter_reset;

/**
 * @throws MidiUnavailableException 
 * 
 */
public MIDI_Clocked_Sequencer(Sequence S,long counter_reset,int[]  where_to_get_receivers) throws MidiUnavailableException {
    this.setSequence(S);
    this.counter_reset=counter_reset;
    playheads=new int[S.getTracks().length];
    receivers=new Receiver[where_to_get_receivers.length];
    for(int i=0;i<where_to_get_receivers.length;i++){
        this.receivers[i]=MidiSystem.getMidiDevice(MidiSystem.getMidiDeviceInfo()[where_to_get_receivers[i]]).getReceiver();
        MidiSystem.getMidiDevice(MidiSystem.getMidiDeviceInfo()[where_to_get_receivers[i]]).open();
    }
}

@Override
public void close() {
    for(int j=0;j<receivers.length;j++){
        try {
            receivers[j].send(new ShortMessage(ShortMessage.CONTROL_CHANGE+Track_Master.channel_map.get(Track_Master.gui_map.get(j)),123,0), 0);
        } catch (InvalidMidiDataException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }           
receivers[j].close();}
}

@Override
public void send(MidiMessage msg, long arg1) {
    Set<MidiMessage> message_buffer = new HashSet<MidiMessage>();
    if(msg.getMessage()[0]==-8){
        if(counter==counter_reset){counter=0;}
            for(int j=0;j<S.getTracks().length;j++){
                if(playheads[j]==S.getTracks()[j].size()){playheads[j]=0;};
                while(playheads[j]<S.getTracks()[j].size() &&   S.getTracks()[j].get(playheads[j]).getTick()==counter){
                message_buffer.add(S.getTracks()[j].get(playheads[j]).getMessage());
                playheads[j]=playheads[j]+1;
                }
            }
            for(Iterator<MidiMessage> it=message_buffer.iterator();it.hasNext();){
            MidiMessage f=it.next();
                for(int j=0;j<receivers.length;j++)
                {
                    receivers[j].send(f, -1);}
            }
            counter=counter+1;
      }
}

public Sequence getSequence() {
    return S;
}

public void setSequence(Sequence s) {
    this.S = s;
  }

}
于 2015-11-02T04:40:01.240 に答える