Я создаю приложение, в котором пользователь может добавить несколько заметок MIDI в коллекцию, отсюда они могут нажать кнопку «Воспроизвести», и приложение будет проходить через каждую ноту и воспроизводить их через динамики ,Java MIDI Трек, воспроизводящий повторяющиеся заметки
Я создал класс MIDIMessage, в котором хранятся сведения о примечании, которое пользователь выбрал для добавления в список, причем данные хранятся в виде Pitch, Velocity, Delay и Channel.
Каждое из этих сообщений сохраняется в ArrayList с типом как MIDIMessage.
Затем я перехожу к итератору коллекции к объекту итератора и воспроизвожу звук, пока в коллекции еще нет элемента.
По какой-то причине, даже если я добавляю только одну ноту в коллекцию, всегда есть две ноты, играющие с одинаковой высотой, длиной и скоростью.
Также каждая нота играет одновременно, независимо от того, сколько из них присутствует в коллекции, я предположил, что между ними будет какая-то задержка.
Ниже приводится код, я использую в данный момент:
MIDIMessage:
package javatest;
public class MIDIMessage
{
private int pitch;
private int velocity;
private int channel;
public MIDIMessage(int p, int v, int c)
{
pitch = p;
velocity = v;
channel = c;
}
public int GetPitch()
{
return this.pitch;
}
public int GetVelocity()
{
return this.velocity;
}
public int GetChannel()
{
return this.channel;
}
}
Добавление заметки к коллекции:
public void AddToList()
{
int channel = jComboBoxChannels.getSelectedIndex();
int pitch = jComboBoxPitch.getSelectedIndex();
int velocity = ((Integer)jSpinnerVelocity.getValue());
collection.add(new MIDIMessage(pitch,velocity,channel));
}
Игра ноты :
try
{
jButton1.setEnabled(false);
Sequencer sequencer = MidiSystem.getSequencer();
sequencer.open();
Sequence sequence = new Sequence(Sequence.PPQ,1);
Track track = sequence.createTrack();
Iterator itr = collection.iterator();
int i = 0;
while(itr.hasNext())
{
MIDIMessage msg = (MIDIMessage)itr.next();
ShortMessage noteOnMsg = new ShortMessage();
//Signal/Channel/Pitch/Velocity
noteOnMsg.setMessage(ShortMessage.NOTE_ON, msg.GetChannel(),msg.GetPitch(),msg.GetVelocity());
ShortMessage noteOffMsg = new ShortMessage();
//Signal/Channel/Pitch/Velocity
noteOffMsg.setMessage(ShortMessage.NOTE_OFF,msg.GetChannel(),msg.GetPitch(),msg.GetVelocity());
track.add(new MidiEvent(noteOnMsg,0));
track.add(new MidiEvent(noteOffMsg,1));
//i = i+1;
}
sequencer.setSequence(sequence);
sequencer.setTempoInBPM(120);
sequencer.setLoopCount(1);
sequencer.start();
Thread.sleep(1000);
}
Прошу прощения, я не понимаю, как узнать, как долго играла нота, а другая между текущей записью и следующей? Также задержка была ошибкой, я был C/P-кодом из старого исходного файла. –
Вы * определяете *, как долго воспроизводится нота и какая разница между текущей записью и следующей. Если вы хотите просто воспроизвести заметку каждый «бит», попробуйте использовать «Sequence.PPQ» для обеих переменных. – schnaader
Что я пытаюсь сказать, я не понимаю, как бы я определил длину заметки, есть ли какой-то метод, который я могу использовать для получения длины одного ?. В качестве примера я заметил, что вы можете назвать новый MidiEvent (noteOnMsg, 1) .getTick); но я чувствую, что для его использования мне нужно будет создать MidiEvent отдельно, а затем добавить его на дорожку после, что позволит мне установить Tick на переменную. –