The following code is a Java program that will turn the letters of your computer's keyboard into a "piano-like" keyboard. Similar to an organ, from left to right and from bottom to top the pitch of the keys will increase. The frequency of each note is selected based on the user's input key, the logic for which can be found in the code labeled "Tone.java."

Download the code and play Beethoven's Fur Elise with "hghghafsn" or hot cross buns with "gdagdaaaaaddddgda."

// Keyboard.java

import java.awt.EventQueue; import javax.swing.JFrame;

public class Keyboard extends JFrame {

private static final long serialVersionUID = 1L;

public Keyboard() {

       add(new Tone());
       setTitle("Keyboard");
       setDefaultCloseOperation(EXIT_ON_CLOSE);
       setSize(500, 50);
       setLocationRelativeTo(null);
       setResizable(true);
   }
   public static void main(String[] args) {
       
       EventQueue.invokeLater(() -> {
           Keyboard ex = new Keyboard();
           ex.setVisible(true);
       });
   }

}

// Tone.java import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; import javax.swing.JPanel;

public class Tone extends JPanel {

private static final long serialVersionUID = 1L;

   public Tone() {
       addKeyListener(new TAdapter());
       setFocusable(true);
   }
   private class TAdapter extends KeyAdapter {
       public void keyReleased(KeyEvent e) {
       }
       
       public void keyPressed(KeyEvent e) {
       	int key = e.getKeyCode();
           int rate = 16 * 1024; // ~16KHz
       	final AudioFormat af = new AudioFormat(rate, 8, 1, true, true);
           SourceDataLine line = null;

try { line = AudioSystem.getSourceDataLine(af); } catch (LineUnavailableException e1) { e1.printStackTrace(); }

           try {

line.open(af, rate); } catch (LineUnavailableException e1) { e1.printStackTrace(); }

           line.start();
           int seconds = 2;
           double f = convert(key);
           byte[] sin = new byte[seconds * rate];
           for (int i = 0; i < sin.length; i++) {
               double period = (double)rate / f;
               double angle = 2.0 * Math.PI * i / period;
               sin[i] = (byte)(Math.sin(angle) * 127.0);
           }
           int length = rate * 150 / 1000;
           @SuppressWarnings("unused")

int unused = line.write(sin, 0, length);

           line.drain();
           line.close();
       }
   }
   
   public double convert(int key) {
   	double frequency = 440.0;
   	switch (key) {
   	case KeyEvent.VK_Z:
   		frequency = 440.0; // A4
   		break;
   	case KeyEvent.VK_X:
   		frequency = 466.16; // A#4 Bb4
   		break;
   	case KeyEvent.VK_C:
   		frequency = 493.88; // B4
   		break;
   	case KeyEvent.VK_V:
   		frequency = 523.25; // C5
   		break;
   	case KeyEvent.VK_B:
   		frequency = 554.37; // C#5 Db5
   		break;
   	case KeyEvent.VK_N:
   		frequency = 587.33; // D5
   		break;
   	case KeyEvent.VK_M:
   		frequency = 622.25; // D#5 Eb5
   		break;
   	case KeyEvent.VK_A:
   		frequency = 659.25; // E5
   		break;
   	case KeyEvent.VK_S:
   		frequency = 698.46; // F5
   		break;
   	case KeyEvent.VK_D:
   		frequency = 739.99; // F#5 Gb5
   		break;
   	case KeyEvent.VK_F:
   		frequency = 783.99; // G5
   		break;
   	case KeyEvent.VK_G:
   		frequency = 830.61; // G#5 Ab5
   		break;
   	case KeyEvent.VK_H:
   		frequency = 880.00; // A5
   		break;
   	case KeyEvent.VK_J:
   		frequency = 932.33; // A#5 Bb5
   		break;
   	case KeyEvent.VK_K:
   		frequency = 987.77; // B5
   		break;
   	case KeyEvent.VK_L:
   		frequency = 1046.50; // C6
   		break;
   	case KeyEvent.VK_Q:
   		frequency = 1108.73; // C#6 Db6
   		break;
   	case KeyEvent.VK_W:
   		frequency = 1174.66; // D6
   		break;
   	case KeyEvent.VK_E:
   		frequency = 1244.51; // D#6 Eb6
   		break;
   	case KeyEvent.VK_R:
   		frequency = 1318.51; // E6
   		break;
   	case KeyEvent.VK_T:
   		frequency = 1396.91; // F6
   		break;
   	case KeyEvent.VK_Y:
   		frequency = 1479.98;  // F#6 Gb6
   		break;
   	case KeyEvent.VK_U:
   		frequency = 1567.98; // G6
   		break;
   	case KeyEvent.VK_I:
   		frequency = 1661.22; // G#6 Ab6
   		break;
   	case KeyEvent.VK_O:
   		frequency = 1760.00; // A6
   		break;
   	case KeyEvent.VK_P:
   		frequency = 1864.66; // A#6 Bb6
   		break;
   	}
   	return frequency;
   }

}

Alumni Liaison

Ph.D. on Applied Mathematics in Aug 2007. Involved on applications of image super-resolution to electron microscopy

Francisco Blanco-Silva