java - MIDI Java 生成困惑的声音

标签 java audio midi synthesizer

我一直在一个项目中工作,我需要在 Java 中操作 MIDI 文件中的每个乐器。 然后我决定从序列中的每条轨道获取每个 MIDI 事件并将其发送到接收器。之后,线程等待每个滴答持续的时间,然后在下一个滴答中再次执行。 问题是:乐器的声音以及它们的顺序变得非常困惑。 我也试着单独执行每首轨道,但它仍然一团糟! 代码:

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

最佳答案

正如 ntabee 所说,Track.get(n) 返回轨道中的第 n 个事件;要按时间获取事件,您必须手动比较事件的时间。

此外,Thread.sleep() 不是很精确,可以等待比预期更长的时间。 这些错误会累积起来。


要实时更改 MIDI 消息,请告诉音序器播放您自己的 Receiver,然后对事件做任何您想做的事并将它们传递给“真正的”Receiver.

关于java - MIDI Java 生成困惑的声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25859950/

相关文章:

java - 如何在 Java 中检查 LinkedHashMap 的相等性——还要考虑插入顺序?

java - Spring 匿名/回调类用于数据持久化的困难时期

audio - 使用ffmpeg将音频文件转换为mp3

android - 将带有 amr_nb 音频编解码器的 .mov 包装器转换为 aac/mp4a 编解码器

c# - 什么样的定时器最适合MIDI定时?

java - 如何向 jMusic 添加 "Arabian"或 "Microtone"或 "Quarter-tone"支持?

java - 为什么我的java程序每次都打印零?

java - 在 Hashmap 中重新散列

javascript - 在 html5 javascript 中同步音频和视频

c++ - 编写一个程序,帮助工作室将 MIDI 音符编号转换为名称和 Octave