如何使用JavaSound减少/消除滞后

时间:2015-04-18 18:36:35

标签: java javasound

我有一个简单的MIDI程序,当你点击那个音符时会弹奏一个音符。但是,单击音符和音符播放之间会有短暂的暂停。我知道延迟是因为我必须打开音序器,添加音符开启和关闭事件,然后播放它。

我的问题是:有没有办法消除滞后?或者至少减少它?我想不出任何办法。提前致谢!代码发布在下面。

import java.awt.*;
import java.awt.event.*;
import javax.sound.midi.*;
import javax.swing.*;
import java.io.IOException;
import javax.imageio.ImageIO;

public class HandyKeyboard {
    private JFrame mainFrame;

    private JButton lowCKey;
    private JButton dKey;
    private JButton eKey;
    private JButton fKey;
    private JButton gKey;
    private JButton aKey;
    private JButton bKey;
    private JButton highCKey;

    private JLabel title;
    private ContentPanel contentPanel;

    public static void main(String[] args){
        HandyKeyboard keyboardApp = new HandyKeyboard();
        keyboardApp.go();
    }
    public void go(){
        mainFrame = new JFrame("Handy Keyboard");
        lowCKey = new JButton("C");
        dKey = new JButton("D");
        eKey = new JButton("E");
        fKey = new JButton("F");
        gKey = new JButton("G");
        aKey = new JButton("A");
        bKey = new JButton("B");
        highCKey = new JButton("C");
        contentPanel = new ContentPanel("pianoKeysBG.png");

        lowCKey.addActionListener(new NoteListener(60));
        dKey.addActionListener(new NoteListener(62));
        eKey.addActionListener(new NoteListener(64));
        fKey.addActionListener(new NoteListener(65));
        gKey.addActionListener(new NoteListener(67));
        aKey.addActionListener(new NoteListener(69));
        bKey.addActionListener(new NoteListener(71));
        highCKey.addActionListener(new NoteListener(72));

        title = new JLabel("Options");
        Font largeFont  = new Font("Times New Roman", Font.BOLD, 30);
        title.setFont(largeFont);

        contentPanel.add(lowCKey);
        contentPanel.add(dKey);
        contentPanel.add(eKey);
        contentPanel.add(fKey);
        contentPanel.add(gKey);
        contentPanel.add(aKey);
        contentPanel.add(bKey);
        contentPanel.add(highCKey);

        mainFrame.setContentPane(contentPanel);
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.setSize(400, 400);
        mainFrame.setVisible(true);
    }
    private class ContentPanel extends JPanel {
        private final Image backgroundImg;
        public ContentPanel(String imgURL) {
            Image backgroundPic = null;
            try {backgroundPic = ImageIO.read(this.getClass().getResource(imgURL));}catch(IOException ex){ex.printStackTrace();}
            Image improvedPic = backgroundPic.getScaledInstance(385, 180, Image.SCALE_SMOOTH);
            this.backgroundImg = improvedPic;
        }
        protected void paintComponent(Graphics g){
            super.paintComponent(g);
            g.drawImage(backgroundImg, 0, 0, 400, 400, this);
        }
    }
    private class NoteListener implements ActionListener {
        private int noteInt;
        private Sequencer player;
        private Sequence seq;
        private Track track;

        public NoteListener(int i) {
            this.noteInt = i;
            try {
                player = MidiSystem.getSequencer();
                player.addMetaEventListener(new MetaEventListener() {

            @Override
            public void meta(MetaMessage metaMsg) {
                if (metaMsg.getType() == 0x2F) {
                    player.close();
                }
            }
        });
                seq = new Sequence(Sequence.PPQ, 1);
                track = seq.createTrack();
            }
            catch (MidiUnavailableException | InvalidMidiDataException e){
                e.printStackTrace();
            }
        }
        public void actionPerformed(ActionEvent e) {
            try {
                player.open();

                MidiEvent noteOn = new MidiEvent(new ShortMessage(144, 1, noteInt, 100), 1);
                track.add(noteOn);

                MidiEvent noteOff = new MidiEvent(new ShortMessage(128, 1, noteInt, 100), 2);
                track.add(noteOff);

                player.setSequence(seq);
                player.setTempoInBPM(80);
                player.start();

            }
            catch (Exception ex) {
                ex.printStackTrace();
            }
        }

    }
}

0 个答案:

没有答案