【问题标题】:Cannot change the MIDI instrument in Java无法在 Java 中更改 MIDI 乐器
【发布时间】:2016-04-05 13:11:00
【问题描述】:

我已经粘贴了这个小的 Java 程序:我有 8 个音调(C、D、E、...、A、B、C),因此我可以使用一个穷人的钢琴。

package net.coderodde.music;

import java.awt.Canvas;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.sound.midi.Instrument;
import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Soundbank;
import javax.sound.midi.Synthesizer;
import javax.swing.JFrame;

public class KeyboardPiano {

    private static final String APP_TITLE = "Keyboard Piano";

    private final JFrame frame = new JFrame(APP_TITLE);
    private final Canvas canvas = new Canvas();
    private Synthesizer synthesizer;
    private final MidiChannel[] midiChannels;
    private final Instrument[] instruments;
    private int instrumentIndex = 40;

    KeyboardPiano() {
        try {
            synthesizer = MidiSystem.getSynthesizer();
            synthesizer.open();
        } catch (MidiUnavailableException ex) {
            ex.printStackTrace();
            System.exit(1);
        }   

        this.midiChannels = synthesizer.getChannels();

        Soundbank bank = synthesizer.getDefaultSoundbank();

        synthesizer.loadAllInstruments(bank);

        System.out.println("[STATE] MIDI channels: " + midiChannels.length);

        this.instruments = synthesizer.getAvailableInstruments();

        System.out.println("[STATE] Instruments: " + instruments.length);

        synthesizer.loadAllInstruments(synthesizer.getDefaultSoundbank());
        boolean b = synthesizer.loadInstrument(instruments[53]);

        System.out.println(b);
    }

    private void init() {   
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(canvas);
        frame.setSize(100, 100);
        frame.setResizable(false);
        canvas.addKeyListener(new KeyboardPianoListener());
        canvas.setFocusable(true);
        canvas.requestFocus();
    }

    private void show() {
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        KeyboardPiano keyboardPiano = new KeyboardPiano();
        keyboardPiano.init();
        keyboardPiano.show();
    }

    private final class KeyboardPianoListener implements KeyListener {

        @Override
        public void keyTyped(KeyEvent e) {
            int keyCode = e.getExtendedKeyCode();
            int noteNumber = -1;

            switch (keyCode) {
                case KeyEvent.VK_1: {
                    noteNumber = 60;
                    break;
                }

                case KeyEvent.VK_2: {
                    noteNumber = 62;
                    break;
                }

                case KeyEvent.VK_3: {
                    noteNumber = 64;
                    break;
                }

                case KeyEvent.VK_4: {
                    noteNumber = 65;
                    break;
                }

                case KeyEvent.VK_5: {
                    noteNumber = 67;
                    break;
                }

                case KeyEvent.VK_6: {
                    noteNumber = 69;
                    break;
                }

                case KeyEvent.VK_7: {
                    noteNumber = 71;
                    break;
                }

                case KeyEvent.VK_8: {
                    noteNumber = 72;
                    break;
                }

                case KeyEvent.VK_A: {
                    System.out.println("dec");
                    instrumentIndex = Math.max(0, instrumentIndex - 1);
                    synthesizer.loadInstrument(instruments[instrumentIndex]);
                    break;
                }

                case KeyEvent.VK_S: {
                    System.out.println("inc");
                    instrumentIndex = Math.min(instruments.length - 1,
                                               instrumentIndex + 1);
                    synthesizer.loadInstrument(instruments[instrumentIndex]);
                    break;
                }
            }

            if (noteNumber != -1) {
                midiChannels[0].noteOn(noteNumber, 600);
            }
        }

        @Override
        public void keyPressed(KeyEvent e) {

        }

        @Override
        public void keyReleased(KeyEvent e) {

        }
    }
}

在按键监听器中,每当用户键入 A 或 S 时,程序都应该更改乐器,而这不会发生。那么,我在这里缺少什么?

【问题讨论】:

    标签: java midi


    【解决方案1】:

    当输入一个字符时触发事件KEY_TYPED

    您可以在keyTyped() 中检索输入的带有e.getKeyChar() 的字符,或者您将代码移动到keyPressed().1 中

    【讨论】:

      【解决方案2】:

      loadInstrument() 没有做你想做的事。

      要更换仪器,需要发送programChange()消息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-10
        相关资源
        最近更新 更多