MIDI Java生成混乱的声音
我一直在从事一个项目,在这个项目中,我需要用java操作MIDI文件中的每个乐器。 然后我决定从序列中的每个曲目中获取每个MIDI事件,并将其发送给接收器。在此之后,线程等待每个勾号持续的时间,然后使用下一个勾号再次执行该操作。 问题是:乐器的声音和顺序变得非常混乱。 我也试着单独演奏每一首曲子,但还是一团糟! 守则:MIDI Java生成混乱的声音,java,audio,midi,synthesizer,Java,Audio,Midi,Synthesizer,我一直在从事一个项目,在这个项目中,我需要用java操作MIDI文件中的每个乐器。 然后我决定从序列中的每个曲目中获取每个MIDI事件,并将其发送给接收器。在此之后,线程等待每个勾号持续的时间,然后使用下一个勾号再次执行该操作。 问题是:乐器的声音和顺序变得非常混乱。 我也试着单独演奏每一首曲子,但还是一团糟! 守则: Sequence sequence = MidiSystem.getSequence(new File(source)); Synthesiz
Sequence sequence = MidiSystem.getSequence(new File(source));
Synthesizer synth = MidiSystem.getSynthesizer();
//Gets a MidiMessage and send it to Synthesizer
Receiver rcv = synth.getReceiver();
//Contains all tracks and events from MIDI file
Track[] tracks = sequence.getTracks();
synth.open();
//If there are tracks
if(tracks != null)
{
//Verify the division type of the sequence (PPQ, SMPT)
if(sequence.getDivisionType() == Sequence.PPQ)
{
int ppq = sequence.getResolution();
//Do the math to get the time (in miliseconds) each tick takes
long tickTime = TicksToMiliseconds(BPM,ppq);
//Returns the number of ticks from the longest track
int longestTrackTicks = LongestTrackTicks(tracks);
//Each iteration sends a new message to 'receiver'
for(int tick = 0; tick < maiorTick ; tick++)
{
//Iteration of each track
for(int trackNumber = 0; trackNumber < tracks.length; trackNumber++)
{
//If the number of ticks from a track isn't already finished
//continue
if(tick < tracks[trackNumber].size())
{
MidiEvent ev = tracks[trackNumber].get(tick);
rcv.send(ev.getMessage(),-1);
}
}
Thread.sleep(tickTime);
}
}
}
synth.close();
Sequence-Sequence=MidiSystem.getSequence(新文件(源));
Synthesizer synth=MidiSystem.getSynthesizer();
//获取MIDI消息并将其发送到合成器
Receiver rcv=synth.getReceiver();
//包含MIDI文件中的所有曲目和事件
Track[]tracks=sequence.getTracks();
synth.open();
//如果有痕迹
如果(轨迹!=null)
{
//验证序列的划分类型(PPQ、SMPT)
if(sequence.getDivisionType()==sequence.PPQ)
{
int ppq=sequence.getResolution();
//计算每个刻度所用的时间(以毫秒为单位)
长滴答时间=滴答毫秒(BPM,ppq);
//返回最长轨迹的刻度数
int longestTrackTicks=longestTrackTicks(轨迹);
//每次迭代都会向“接收者”发送一条新消息
对于(int tick=0;tick
至少,您的代码看起来像是在每一个滴答声
毫秒打开/关闭某个东西。时期
track.get(tick)
只返回曲目中的tick
-第个事件,而不是tick
时刻的事件。
如果您的目标只是播放声音,Java为其提供了一个高级API,如ntabee所说,
Track.get(n)
返回曲目中的第n
个事件;要按时间获取事件,必须手动比较事件的时间
此外,Thread.sleep()
不是很精确,并且可以等待比预期更长的时间。
这些错误会累加起来的
要实时更改MIDI消息,请告诉音序器播放到您自己的
接收器
,然后对事件执行任何操作,并将它们传递到“真实的”接收器我决定使用音序器。我不知道,但是“start”方法在一个新线程中运行,当它仍在运行时,我可以使我想要的每个乐器静音,这正是我想要的。
谢谢你的回答 问题是我需要在音乐播放时操纵乐器。这就是我以前没有用音序器的原因。这个想法是改变一些乐器演奏时的音量。此外,track.get(tick)返回MIDI事件。Java文档说MIDI事件有MIDI消息,这一个包含关于该tick处声音的所有信息。