gpt4 book ai didi

Java MIDI Track 播放重复的音符

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:17:49 24 4
gpt4 key购买 nike

我正在创建一个应用程序,用户可以在其中将多个 MIDI 音符添加到一个集合中,他们可以从这里按下“播放”按钮,应用程序将遍历每个音符并通过扬声器播放它们。

我创建了一个 MIDIMessage 类,它包含用户选择添加到列表中的音符的详细信息,存储的详细信息是 Pitch、Velocity、Delay 和 Channel。

这些消息中的每一个都被保存到类型为 MIDIMessage 的 ArrayList。

然后我继续将集合的迭代器附加到迭代器对象,并在集合中仍有未使用的元素时播放声音。

出于某种原因,即使我只将一个音符添加到集合中,也总是有两个音符以完全相同的音高、长度和力度演奏。

此外,无论集合中有多少个音符,每个音符都会同时播放,我认为它们之间会有某种延迟。

以下是我目前使用的代码:

MIDI消息:

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);
}

最佳答案

我不确定为什么音符会被演奏两次,但这绝对是错误的:

            track.add(new MidiEvent(noteOnMsg,0));
track.add(new MidiEvent(noteOffMsg,1));

如你所见here , MidiEvent 由消息和 MIDI 节拍组成。您总是在 tick 0 上添加一个 noteOnMsg 并在 tick 1 上添加一个 noteOffMsg,这解释了为什么多个音符会同时播放。你想做这样的事情:

startTick = 0;

while(itr.hasNext()) {
[...]
track.add(new MidiEvent(noteOnMsg,startTick));
track.add(new MidiEvent(noteOffMsg,startTick + how_long_the_note_is_played));
startTick += difference_between_this_note_and_the_next;
[...]
}

我不确定你的 delay 是什么意思,也不确定你是否可以在这里使用它,所以我改用描述性变量名称。

请注意,您必须在此处使用 MIDI 节拍 - 如果您想将秒转换为 MIDI 节拍,请参阅 this SO question (或者更确切地说是它的答案):

[一个 MIDI 节拍有多长?]

The formula is 60000 / (BPM * PPQ) (milliseconds).

关于Java MIDI Track 播放重复的音符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4680883/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com