Advertisement
Guest User

Midi Keyboard

a guest
Dec 15th, 2016
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 19.23 KB | None | 0 0
  1. package midikeyboard;
  2.  
  3.  
  4. import java.awt.GridLayout;
  5. import java.awt.event.ActionEvent;
  6. import java.awt.event.ItemEvent;
  7. import java.awt.event.ItemListener;
  8. import java.awt.event.KeyEvent;
  9. import java.awt.event.KeyListener;
  10. import javax.sound.midi.MidiDevice.Info;
  11. import javax.sound.midi.MidiSystem;
  12. import javax.sound.midi.MidiUnavailableException;
  13. import javax.sound.midi.Receiver;
  14. import javax.sound.midi.Sequencer;
  15. import javax.sound.midi.Synthesizer;
  16. //import javax.sound.midi.Transmitter; //(Not needed.  No physical device)
  17. import javax.sound.midi.Instrument;
  18. import javax.sound.midi.InvalidMidiDataException;
  19. import javax.sound.midi.MidiChannel;
  20. import javax.sound.midi.MidiDevice;
  21. import javax.sound.midi.ShortMessage;
  22. import javax.sound.midi.Soundbank;
  23. import javax.swing.JComboBox;
  24. import javax.swing.JFrame;
  25. import javax.swing.JLabel;
  26. import javax.swing.JPanel;
  27. import javax.swing.Timer;
  28.  
  29.  
  30.  
  31. public class MidiKeyboard {
  32.     final static int
  33.             A_LOW=0, //-1 octave
  34.             B_LOW=1,
  35.             C_LOW=2,
  36.             D_LOW=3,
  37.             E_LOW=4,
  38.             F_LOW=5,
  39.             G_LOW=6,
  40.             A_MID=7, //center octave
  41.             B_MID=8,
  42.             C_MID=9,
  43.             D_MID=10,
  44.             E_MID=11,
  45.             F_MID=12,
  46.             G_MID=13,
  47.             A_HIGH=14,//+1 octave
  48.             B_HIGH=15,
  49.             C_HIGH=16,
  50.             D_HIGH=17,
  51.             E_HIGH=18,
  52.             F_HIGH=19,
  53.             G_HIGH=20,
  54.             A_HIGHER=21,//+2 octaves
  55.             B_HIGHER=22,
  56.             C_HIGHER=23,
  57.             D_HIGHER=24,
  58.             E_HIGHER=25,
  59.             F_HIGHER=26,
  60.             G_HIGHER=27;
  61.     final static int[] NOTES={45, 47, 48, 50, 52, 53, 55}; //abcdefg
  62.     static int sharpFlat=0; //+1 for sharp, -1 for flat
  63.     static boolean sharpOn, flatOn;
  64.     static Synthesizer synth;
  65.     static Sequencer mySequencer;
  66.     static Receiver myReceiver;
  67. //    static Transmitter myTransmitter;  //not needed since no physical device
  68.     static Info[] deviceInfo;
  69.     static Instrument[] orchestra;
  70.     static MidiDevice device;
  71.     static MidiChannel[] synthChannel;
  72.     static ShortMessage message;
  73.     static Soundbank defaultSoundbank;
  74.     static boolean[] noteOn, notePlaying;
  75.     static JFrame frame;
  76.     static JPanel panel;
  77.     static Timer t;
  78.    
  79.     public static void main(String[] args) {
  80.         noteOn = new boolean[G_HIGHER+1];
  81.         notePlaying = new boolean[G_HIGHER+1];
  82.        
  83.         //get info about installed midi devices
  84.         deviceInfo = MidiSystem.getMidiDeviceInfo();
  85.         if (deviceInfo.length > 0){
  86.             //output details
  87.             System.out.println(deviceInfo.length + " devices found");
  88.             for (int i = 0; i < deviceInfo.length; ++i){
  89.                 System.out.println(deviceInfo[i].getName() + " - " +
  90.                     deviceInfo[i].getDescription()+ "\n");
  91.             }
  92.                    
  93.         }
  94.        
  95.        
  96.         try {
  97.             // get device from list
  98.             device = MidiSystem.getMidiDevice(deviceInfo[0]);
  99.             //open device for use
  100.             if(!device.isOpen()) {
  101.                 device.open();
  102.             }
  103.            
  104.            
  105.             mySequencer = MidiSystem.getSequencer(true);
  106.             if (!mySequencer.isOpen()){
  107.                 mySequencer.open();
  108.             }
  109.             //note comes in...  (not needed, not dealing with physical device)
  110. //            myTransmitter = mySequencer.getTransmitter();
  111.            
  112.             synth = MidiSystem.getSynthesizer();
  113.             if (!synth.isOpen()) {
  114.                 synth.open();
  115.             }
  116.            
  117.             //send to here
  118.             myReceiver = synth.getReceiver();
  119.             //each transmitter only sends to one receiver at a time.
  120. //            myTransmitter.setReceiver(myReceiver);
  121.         } catch (MidiUnavailableException ex) {
  122.             System.err.println(ex.getMessage());
  123.         }
  124.        
  125.         System.out.println("Device details\n" +
  126.                 "Max receivers of device: " + device.getMaxReceivers() +
  127.                 "\nMax transmitters of device: " + device.getMaxTransmitters() +
  128.                 "\nMicrosecond timestamp: " + device.getMicrosecondPosition());
  129.        
  130.         synthChannel = synth.getChannels();
  131.         System.out.println("Synth Details\nChannels: " + synthChannel.length +
  132.                 " Latency: " + synth.getLatency() +
  133.                 "\nMax notes at once:" + synth.getMaxPolyphony());
  134.        
  135.         defaultSoundbank= synth.getDefaultSoundbank();
  136.         System.out.println("Default Soundbank:"+ defaultSoundbank.getName() +
  137.                 "\nVendor: " + defaultSoundbank.getVendor() + "\nVersion: " +
  138.                 defaultSoundbank.getVersion() + "\nDescription: " +
  139.                 defaultSoundbank.getDescription() + "\n");
  140.        
  141.         //what instruments are available?
  142.         orchestra = defaultSoundbank.getInstruments();
  143.         if (orchestra.length > 0){
  144.             System.out.println(orchestra.length + " instruments found.");
  145.            
  146.             //list them nicely
  147.             for (int i = 1; i <= orchestra.length; ++i){
  148.                 System.out.print(orchestra[i-1].getName() +
  149.                         ((i%10==0)?"\n" :"\t"));
  150.             }
  151.         }
  152.        
  153.        
  154.         initUI();
  155.         while (frame.isVisible()){}
  156.         //close all
  157.         myReceiver.close();
  158.         mySequencer.close();
  159. //        myTransmitter.close();
  160.         synth.close();
  161.     }
  162.    
  163.     /**
  164.      * Play the passed midi note value on the passed receiver
  165.      */
  166.     private static void playNote(int note, Receiver inst){
  167.        
  168.         ShortMessage n = new ShortMessage();
  169.         try {
  170.             //command, channel, Note, Volume
  171.             n.setMessage(ShortMessage.NOTE_ON, 0, note, 93);
  172.         } catch (InvalidMidiDataException ex) {
  173.             System.err.println(ex.getMessage());
  174.         }
  175.         inst.send(n, 0);
  176.     }
  177.    
  178.     /**
  179.      * Stop playing the passed midi note value on the passed receiver.
  180.      */
  181.     private static void stopNote(int note, Receiver inst){
  182.         ShortMessage n = new ShortMessage();
  183.         try {
  184.             //command, channel, Note, Volume
  185.             n.setMessage(ShortMessage.NOTE_OFF, 0, note, 93);
  186.         } catch (InvalidMidiDataException ex) {
  187.             System.err.println(ex.getMessage());
  188.         }
  189.         inst.send(n, 0);
  190.     }
  191.    
  192.     private static void initUI(){
  193.         frame = new JFrame("MidiKeyboard");
  194.         panel = new JPanel();
  195.         GridLayout grid =new GridLayout(3, 1, 5, 5);
  196.         panel.setLayout(grid);
  197.        
  198.         //instrument selection
  199.         JComboBox listInstruments = new JComboBox();
  200.         for (int i = 1; i <= orchestra.length; ++i){
  201.             listInstruments.addItem(orchestra[i-1].getName());
  202.         }
  203.         listInstruments.addItemListener(new ItemListener(){
  204.  
  205.             @Override
  206.             public void itemStateChanged(ItemEvent e) {
  207.                 //change selected channel's instrument to selected instrument
  208.                 synthChannel[0].programChange(
  209.                         //get the bank the instrument is in
  210.                         orchestra[listInstruments.getSelectedIndex()].
  211.                                 getPatch().getBank(),
  212.                         //get the instrument itself
  213.                         orchestra[listInstruments.getSelectedIndex()].
  214.                                 getPatch().getProgram());
  215.                 //switch to panel focus so playing can begin immediately.
  216.                 panel.requestFocus();
  217. //                listInstruments.getSelectedIndex();
  218.             }
  219.         });
  220.         panel.add(listInstruments);
  221.        
  222.         //Put instructions on window
  223.         JLabel info = new JLabel(
  224.                 "  -  \u266f - Shift for sharp, Ctrl for flat -  \u266f -");
  225.         panel.add(info);
  226.        
  227.         JLabel b = new JLabel("Type something!");
  228.         panel.add(b);
  229.        
  230.         //adding ability to play...
  231.         panel.setFocusable(true);
  232.         panel.addKeyListener(new KeyListener(){
  233.  
  234.             @Override
  235.             public void keyTyped(KeyEvent e) {
  236. //                throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
  237.             }
  238.  
  239.             @Override
  240.             public void keyPressed(KeyEvent e) {
  241.                 switch (e.getKeyCode()){
  242.                     //Home Row
  243.                     case KeyEvent.VK_A:
  244.                         noteOn[A_MID]=true;
  245.                         break;
  246.                     case KeyEvent.VK_S:
  247.                         noteOn[B_MID]=true;
  248.                         break;
  249.                     case KeyEvent.VK_D:
  250.                         noteOn[C_MID]=true;
  251.                         break;
  252.                     case KeyEvent.VK_F:
  253.                         noteOn[D_MID]=true;
  254.                         break;
  255.                     case KeyEvent.VK_G:
  256.                         noteOn[E_MID]=true;
  257.                         break;
  258.                     case KeyEvent.VK_H:
  259.                         noteOn[F_MID]=true;
  260.                         break;
  261.                     case KeyEvent.VK_J:
  262.                         noteOn[G_MID]=true;
  263.                         break;
  264.                     case KeyEvent.VK_K:
  265.                         noteOn[A_HIGH]=true;
  266.                         break;
  267.                     case KeyEvent.VK_L:
  268.                         noteOn[B_HIGH]=true;
  269.                         break;
  270.                     case KeyEvent.VK_SEMICOLON:
  271.                         noteOn[C_HIGH]=true;
  272.                         break;
  273.                     case KeyEvent.VK_QUOTE:
  274.                         noteOn[D_HIGH]= true;
  275.                         break;
  276.                    
  277.                     //Above home row
  278.                     case KeyEvent.VK_Q:
  279.                         noteOn[A_HIGH]=true;
  280.                         break;
  281.                     case KeyEvent.VK_W:
  282.                         noteOn[B_HIGH]=true;
  283.                         break;
  284.                     case KeyEvent.VK_E:
  285.                         noteOn[C_HIGH]=true;
  286.                         break;
  287.                     case KeyEvent.VK_R:
  288.                         noteOn[D_HIGH]=true;
  289.                         break;
  290.                     case KeyEvent.VK_T:
  291.                         noteOn[E_HIGH]=true;
  292.                         break;
  293.                     case KeyEvent.VK_Y:
  294.                         noteOn[F_HIGH]=true;
  295.                         break;
  296.                     case KeyEvent.VK_U:
  297.                         noteOn[G_HIGH]=true;
  298.                         break;
  299.                     case KeyEvent.VK_I:
  300.                         noteOn[A_HIGHER]=true;
  301.                         break;
  302.                     case KeyEvent.VK_O:
  303.                         noteOn[B_HIGHER]=true;
  304.                         break;
  305.                     case KeyEvent.VK_P:
  306.                         noteOn[C_HIGHER]=true;
  307.                         break;
  308.                     case KeyEvent.VK_OPEN_BRACKET:
  309.                         noteOn[D_HIGHER]=true;
  310.                         break;
  311.                     case KeyEvent.VK_CLOSE_BRACKET:
  312.                         noteOn[E_HIGHER]=true;
  313.                         break;
  314.                        
  315.                     //below home row
  316.                     case KeyEvent.VK_Z:
  317.                         noteOn[A_LOW]=true;
  318.                         break;
  319.                     case KeyEvent.VK_X:
  320.                         noteOn[B_LOW]=true;
  321.                         break;
  322.                     case KeyEvent.VK_C:
  323.                         noteOn[C_LOW]=true;
  324.                         break;
  325.                     case KeyEvent.VK_V:
  326.                         noteOn[D_LOW]=true;
  327.                         break;
  328.                     case KeyEvent.VK_B:
  329.                         noteOn[E_LOW]=true;
  330.                         break;
  331.                     case KeyEvent.VK_N:
  332.                         noteOn[F_LOW]=true;
  333.                         break;
  334.                     case KeyEvent.VK_M:
  335.                         noteOn[G_LOW]=true;
  336.                         break;
  337.                     case KeyEvent.VK_COMMA:
  338.                         noteOn[A_MID]=true;
  339.                         break;
  340.                     case KeyEvent.VK_PERIOD:
  341.                         noteOn[B_MID]=true;
  342.                         break;
  343.                     case KeyEvent.VK_SLASH:
  344.                         noteOn[C_MID]=true;
  345.                         break;
  346.                        
  347.                    
  348.                     //Shift and control
  349.                     case KeyEvent.VK_SHIFT:
  350.                         if (!sharpOn){
  351.                             ++sharpFlat;
  352.                             sharpOn=true;
  353.                         }
  354.                         break;
  355.                     case KeyEvent.VK_CONTROL:
  356.                         if (!flatOn){
  357.                             --sharpFlat;
  358.                             flatOn=true;
  359.                         }
  360.                         break;
  361.                     default:
  362.                         break;
  363.                 }
  364.             }
  365.  
  366.             @Override
  367.             public void keyReleased(KeyEvent e) {
  368.                 switch (e.getKeyCode()){
  369.                     //home row
  370.                     case KeyEvent.VK_A:
  371.                         noteOn[A_MID]=false;
  372.                         break;
  373.                     case KeyEvent.VK_S:
  374.                         noteOn[B_MID]=false;
  375.                         break;
  376.                     case KeyEvent.VK_D:
  377.                         noteOn[C_MID]=false;
  378.                         break;
  379.                     case KeyEvent.VK_F:
  380.                         noteOn[D_MID]=false;
  381.                         break;
  382.                     case KeyEvent.VK_G:
  383.                         noteOn[E_MID]=false;
  384.                         break;
  385.                     case KeyEvent.VK_H:
  386.                         noteOn[F_MID]=false;
  387.                         break;
  388.                     case KeyEvent.VK_J:
  389.                         noteOn[G_MID]=false;
  390.                         break;
  391.                     case KeyEvent.VK_K:
  392.                         noteOn[A_HIGH]=false;
  393.                         break;
  394.                     case KeyEvent.VK_L:
  395.                         noteOn[B_HIGH]=false;
  396.                         break;
  397.                     case KeyEvent.VK_SEMICOLON:
  398.                         noteOn[C_HIGH]=false;
  399.                         break;
  400.                     case KeyEvent.VK_QUOTE:
  401.                         noteOn[D_HIGH]=false;
  402.                         break;
  403.                    
  404.                     //Above home row
  405.                     case KeyEvent.VK_Q:
  406.                         noteOn[A_HIGH]=false;
  407.                         break;
  408.                     case KeyEvent.VK_W:
  409.                         noteOn[B_HIGH]=false;
  410.                         break;
  411.                     case KeyEvent.VK_E:
  412.                         noteOn[C_HIGH]=false;
  413.                         break;
  414.                     case KeyEvent.VK_R:
  415.                         noteOn[D_HIGH]=false;
  416.                         break;
  417.                     case KeyEvent.VK_T:
  418.                         noteOn[E_HIGH]=false;
  419.                         break;
  420.                     case KeyEvent.VK_Y:
  421.                         noteOn[F_HIGH]=false;
  422.                         break;
  423.                     case KeyEvent.VK_U:
  424.                         noteOn[G_HIGH]=false;
  425.                         break;
  426.                     case KeyEvent.VK_I:
  427.                         noteOn[A_HIGHER]=false;
  428.                         break;
  429.                     case KeyEvent.VK_O:
  430.                         noteOn[B_HIGHER]=false;
  431.                         break;
  432.                     case KeyEvent.VK_P:
  433.                         noteOn[C_HIGHER]=false;
  434.                         break;
  435.                     case KeyEvent.VK_OPEN_BRACKET:
  436.                         noteOn[D_HIGHER]=false;
  437.                         break;
  438.                     case KeyEvent.VK_CLOSE_BRACKET:
  439.                         noteOn[E_HIGHER]=false;
  440.                         break;
  441.                        
  442.                     //below home row
  443.                     case KeyEvent.VK_Z:
  444.                         noteOn[A_LOW]=false;
  445.                         break;
  446.                     case KeyEvent.VK_X:
  447.                         noteOn[B_LOW]=false;
  448.                         break;
  449.                     case KeyEvent.VK_C:
  450.                         noteOn[C_LOW]=false;
  451.                         break;
  452.                     case KeyEvent.VK_V:
  453.                         noteOn[D_LOW]=false;
  454.                         break;
  455.                     case KeyEvent.VK_B:
  456.                         noteOn[E_LOW]=false;
  457.                         break;
  458.                     case KeyEvent.VK_N:
  459.                         noteOn[F_LOW]=false;
  460.                         break;
  461.                     case KeyEvent.VK_M:
  462.                         noteOn[G_LOW]=false;
  463.                         break;
  464.                     case KeyEvent.VK_COMMA:
  465.                         noteOn[A_MID]=false;
  466.                         break;
  467.                     case KeyEvent.VK_PERIOD:
  468.                         noteOn[B_MID]=false;
  469.                         break;
  470.                     case KeyEvent.VK_SLASH:
  471.                         noteOn[C_MID]=false;
  472.                         break;
  473.                    
  474.                     //Shift and control
  475.                     case KeyEvent.VK_SHIFT:
  476.                         if (sharpOn){
  477.                             --sharpFlat;
  478.                             sharpOn=false;
  479.                         }
  480.                         break;
  481.                     case KeyEvent.VK_CONTROL:
  482.                         if (flatOn){
  483.                             ++sharpFlat;
  484.                             flatOn=false;
  485.                         }
  486.                         break;
  487.                     default:
  488.                         break;
  489.                 }
  490.             }
  491.         });
  492.        
  493.         //timer to check change of notes.
  494.         t = new Timer(1, (ActionEvent e) -> {
  495.            
  496. //            if (!panel.isFocusOwner()) {
  497. //                panel.requestFocus();
  498. //            }
  499.            
  500.             //iterate across notes, checking if it should play or stop
  501.             for (int i = 0; i < noteOn.length; ++i)
  502.                
  503.                 //if it should be playing and isn't already...
  504.                 if (noteOn[i] && !notePlaying[i]){
  505.                    
  506.                     //play (note) + (octave calculation) + (sharp or flat value)
  507.                     playNote(NOTES[i%NOTES.length] +
  508.                             (12 * (i/NOTES.length)) +
  509.                             sharpFlat, myReceiver);
  510.                    
  511.                     notePlaying[i]=true;
  512.                 }
  513.                
  514.                 else if (!noteOn[i]){
  515.                     stopNote(NOTES[i%NOTES.length] +
  516.                             (12 * (i/NOTES.length)) +
  517.                             sharpFlat, myReceiver);
  518.                     notePlaying[i]=false;
  519.                 }
  520.         });
  521.         t.start();
  522.        
  523.         frame.add(panel);
  524.         frame.setLocationRelativeTo(null);
  525.         frame.setSize(250, 100);
  526.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  527.         frame.setVisible(true);
  528.        
  529.     }
  530.    
  531. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement