summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/portmidi/pm_java/pmdefaults/PmDefaultsFrame.java
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2015-01-10 16:58:11 +0100
committer Miodrag Milanovic <mmicko@gmail.com>2015-01-10 16:58:11 +0100
commit1273e97e73d7856a668b4419aae27065c81b06be (patch)
tree49ef6f3811122b79ae93bad45756ab0a77f3a04e /3rdparty/portmidi/pm_java/pmdefaults/PmDefaultsFrame.java
parentd103debef2830bd0e28b54348c21492f89c269c4 (diff)
Placed full code of portmidi in 3rdparty folder (nw)
Diffstat (limited to '3rdparty/portmidi/pm_java/pmdefaults/PmDefaultsFrame.java')
-rw-r--r--3rdparty/portmidi/pm_java/pmdefaults/PmDefaultsFrame.java428
1 files changed, 428 insertions, 0 deletions
diff --git a/3rdparty/portmidi/pm_java/pmdefaults/PmDefaultsFrame.java b/3rdparty/portmidi/pm_java/pmdefaults/PmDefaultsFrame.java
new file mode 100644
index 00000000000..b38af1b0f70
--- /dev/null
+++ b/3rdparty/portmidi/pm_java/pmdefaults/PmDefaultsFrame.java
@@ -0,0 +1,428 @@
+// PmDefaults -- a small application to set PortMIDI default input/output
+
+/* Implementation notes:
+
+This program uses PortMidi to enumerate input and output devices and also
+to send output messages to test output devices and
+to receive input messages to test input devices.
+
+*/
+
+package pmdefaults;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.lang.Math.*;
+import jportmidi.*;
+import jportmidi.JPortMidiApi.*;
+import java.util.ArrayList;
+import java.util.prefs.*;
+import java.net.*;
+
+public class PmDefaultsFrame extends JFrame
+ implements ActionListener, ComponentListener {
+
+ // This class extends JPortMidi in order to override midi input handling
+ // In this case, midi input simply blinks the activity light
+ public class JPM extends JPortMidi {
+ ActivityLight light;
+ PmDefaultsFrame frame;
+ int lightTime;
+ boolean lightState;
+ int now; // current time in ms
+ final int HALF_BLINK_PERIOD = 250; // ms
+
+ public JPM(ActivityLight al, PmDefaultsFrame df)
+ throws JPortMidiException {
+ light = al;
+ frame = df;
+ lightTime = 0;
+ lightState = false; // meaning "off"
+ now = 0;
+ }
+
+ public void poll(int ms) throws JPortMidiException {
+ // blink the light. lightState is initially false (off).
+ // to blink the light, set lightState to true and lightTime
+ // to now + 0.25s; turn on light
+ // now > ligntTime && lightState => set lightTime = now + 0.25s;
+ // set lightState = false
+ // turn off light
+ // light can be blinked again when now > lightTime && !lightState
+ now = ms;
+ if (now > lightTime && lightState) {
+ lightTime = now + HALF_BLINK_PERIOD;
+ lightState = false;
+ light.setState(false);
+ }
+ super.poll();
+ }
+
+ public void handleMidiIn(PmEvent buffer) {
+ System.out.println("midi in: now " + now +
+ " lightTime " + lightTime +
+ " lightState " + lightState);
+ if (now > lightTime && !lightState) {
+ lightState = true;
+ lightTime = now + HALF_BLINK_PERIOD;
+ light.setState(true);
+ }
+ }
+ }
+
+ public class ActivityLight extends JPanel {
+ Color color;
+ final Color OFF_COLOR = Color.BLACK;
+ final Color ON_COLOR = Color.GREEN;
+
+ ActivityLight() {
+ super();
+ Dimension size = new Dimension(50, 25);
+ setMaximumSize(size);
+ setPreferredSize(size);
+ setMinimumSize(size);
+ color = OFF_COLOR;
+ System.out.println("ActivityLight " + getSize());
+ }
+
+ public void setState(boolean on) {
+ color = (on ? ON_COLOR : OFF_COLOR);
+ repaint();
+ }
+
+ public void paintComponent(Graphics g) {
+ super.paintComponent(g); // paint background
+ g.setColor(color);
+ int x = (getWidth() / 2) - 5;
+ int y = (getHeight() / 2) - 5;
+ g.fillOval(x, y, 10, 10);
+ g.setColor(OFF_COLOR);
+ g.drawOval(x, y, 10, 10);
+ }
+ }
+
+ private JLabel inputLabel;
+ private JComboBox inputSelection;
+ // inputIds maps from the index of an item in inputSelection to the
+ // device ID. Used to open the selected device.
+ private ArrayList<Integer> inputIds;
+ private ActivityLight inputActivity;
+ private JLabel outputLabel;
+ private JComboBox outputSelection;
+ // analogous to inputIds, outputIds maps selection index to device ID
+ private ArrayList<Integer> outputIds;
+ private JButton testButton;
+ private JButton refreshButton;
+ private JButton updateButton;
+ private JButton closeButton;
+ private JLabel logo;
+
+ private JPM jpm;
+ private Timer timer;
+
+ public void componentResized(ComponentEvent e) {
+ System.out.println(e);
+ if (e.getComponent() == this) {
+ Insets insets = getInsets();
+ Dimension dim = getSize();
+ layoutComponents(dim.width - insets.left - insets.right,
+ dim.height - insets.top - insets.bottom);
+ }
+ }
+ public void componentMoved(ComponentEvent e) {
+ System.out.println(e);
+ }
+ public void componentHidden(ComponentEvent e) {
+ System.out.println(e);
+ }
+ public void componentShown(ComponentEvent e) {
+ System.out.println(e);
+ }
+
+
+ PmDefaultsFrame(String title) {
+ super(title);
+ initComponents();
+ System.out.println("initComponents returned\n");
+ pack(); // necessary before calling getInsets();
+ // initially, only width matters to layout:
+ layoutComponents(550, 300);
+ System.out.println("after layout, pref " + getPreferredSize());
+ // now, based on layout-computed preferredSize, set the Frame size
+ Insets insets = getInsets();
+ Dimension dim = getPreferredSize();
+ dim.width += (insets.left + insets.right);
+ dim.height += (insets.top + insets.bottom);
+ setSize(dim);
+ System.out.println("size" + getPreferredSize());
+ addComponentListener(this);
+
+ timer = new Timer(50 /* ms */, this);
+ timer.addActionListener(this);
+ try {
+ jpm = new JPM(inputActivity, this);
+ jpm.setTrace(true);
+ loadDeviceChoices();
+ timer.start(); // don't start timer if there's an error
+ } catch(JPortMidiException e) {
+ System.out.println(e);
+ }
+ }
+
+ void openInputSelection() {
+ int id = inputSelection.getSelectedIndex();
+ if (id < 0) return; // nothing selected
+ id = (Integer) (inputIds.get(id)); // map to device ID
+ // openInput will close any previously open input stream
+ try {
+ jpm.openInput(id, 100); // buffer size hopes to avoid overflow
+ } catch(JPortMidiException e) {
+ System.out.println(e);
+ }
+ }
+
+ // make a string to put into preferences describing this device
+ String makePrefName(int id) {
+ String name = jpm.getDeviceName(id);
+ String interf = jpm.getDeviceInterf(id);
+ // the syntax requires comma-space separator (see portmidi.h)
+ return interf + ", " + name;
+ }
+
+
+ public void savePreferences() {
+ Preferences prefs = Preferences.userRoot().node("/PortMidi");
+ int id = outputSelection.getSelectedIndex();
+ if (id >= 0) {
+ String prefName = makePrefName(outputIds.get(id));
+ System.out.println("output pref: " + prefName);
+ prefs.put("PM_RECOMMENDED_OUTPUT_DEVICE", prefName);
+ }
+ id = inputSelection.getSelectedIndex();
+ if (id >= 0) {
+ String prefName = makePrefName(inputIds.get(id));
+ System.out.println("input pref: " + prefName);
+ prefs.put("PM_RECOMMENDED_INPUT_DEVICE", prefName);
+ }
+ try {
+ prefs.flush();
+ } catch(BackingStoreException e) {
+ System.out.println(e);
+ }
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ Object source = e.getSource();
+ try {
+ if (source == timer) {
+ jpm.poll(jpm.timeGet());
+ } else if (source == refreshButton) {
+ if (jpm.isOpenInput()) jpm.closeInput();
+ if (jpm.isOpenOutput()) jpm.closeOutput();
+ jpm.refreshDeviceLists();
+ loadDeviceChoices();
+ } else if (source == updateButton) {
+ savePreferences();
+ } else if (source == closeButton) {
+ if (jpm.isOpenInput()) jpm.closeInput();
+ if (jpm.isOpenOutput()) jpm.closeOutput();
+ } else if (source == testButton) {
+ sendTestMessages();
+ } else if (source == inputSelection) {
+ // close previous selection and open new one
+ openInputSelection();
+ } else if (source == outputSelection) {
+ jpm.closeOutput(); // remains closed until Test button reopens
+ }
+ } catch(JPortMidiException ex) {
+ System.out.println(ex);
+ }
+ };
+
+ private void layoutComponents(int width, int height) {
+ // I tried to do this with various layout managers, but failed
+ // It seems pretty straightforward to just compute locations and
+ // sizes.
+
+ int gap = 2; // pixel separation between components
+ int indent = 20;
+ int y = gap;
+
+ // inputLabel goes in upper left
+ inputLabel.setLocation(0, y);
+ inputLabel.setSize(inputLabel.getPreferredSize());
+
+ // inputSelection goes below and indented, width based on panel
+ y += inputLabel.getHeight() + gap;
+ inputSelection.setLocation(indent, y);
+ // size of inputSelection must leave room at right for inputButton
+ // (in fact, inputActivity goes there, but we'll make inputSelection
+ // and outputSelection the same size, based on leaving room for
+ // testButton, which is larger than inputActivity.)
+ Dimension dim = inputSelection.getPreferredSize();
+ Dimension dimButton = testButton.getPreferredSize();
+ // make button and selection the same height so they align
+ dim.height = dimButton.height = Math.max(dim.height, dimButton.height);
+ // make selection width as wide as possible
+ dim.width = width - indent - dimButton.width - gap;
+ inputSelection.setSize(dim);
+
+ // inputActivity goes to the right of inputSelection
+ inputActivity.setLocation(indent + dim.width + gap, y);
+ // square size to match the height of inputSelection
+ inputActivity.setSize(dim.height, dim.height);
+
+ // outputLabel goes below
+ y += dim.height + gap;
+ outputLabel.setLocation(0, y);
+ outputLabel.setSize(outputLabel.getPreferredSize());
+
+ // outputSelection is like inputSelection
+ y += outputLabel.getHeight() + gap;
+ outputSelection.setLocation(indent, y);
+ outputSelection.setSize(dim);
+
+ // testButton is like inputActivity
+ testButton.setLocation(indent + dim.width + gap, y);
+ testButton.setSize(dimButton);
+ System.out.println("button " + dimButton + " selection " + dim);
+
+ // refreshButton is below
+ y += dim.height + gap;
+ dim = refreshButton.getPreferredSize();
+ refreshButton.setLocation(indent, y);
+ refreshButton.setSize(dim);
+
+ // updateButton to right of refreshButton
+ int x = indent + dim.width + gap;
+ updateButton.setLocation(x, y);
+ dim = updateButton.getPreferredSize();
+ updateButton.setSize(dim);
+
+ // closeButton to right of updateButton
+ x += dim.width + gap;
+ closeButton.setLocation(x, y);
+ dim = closeButton.getPreferredSize();
+ closeButton.setSize(dim);
+
+ // place logo centered at bottom
+ y += dim.height + gap;
+ logo.setLocation((width - logo.getWidth()) / 2,
+ height - gap - logo.getHeight());
+
+ // set overall size
+ y += logo.getHeight() + gap;
+ System.out.println("computed best size " + width + ", " + y);
+ setPreferredSize(new Dimension(width, y));
+ }
+
+ private void initComponents() {
+ Container wholePanel = getContentPane();
+ wholePanel.setLayout(null);
+ setLayout(null);
+
+ inputLabel = new JLabel();
+ inputLabel.setText("Default Input");
+ wholePanel.add(inputLabel);
+
+ inputSelection = new JComboBox();
+ inputSelection.addActionListener(this);
+ inputSelection.setLocation(20, 30);
+ inputSelection.setSize(inputSelection.getPreferredSize());
+ System.out.println("Adding inputSelection to panel");
+ wholePanel.add(inputSelection);
+ inputIds = new ArrayList<Integer>();
+
+ inputActivity = new ActivityLight();
+ wholePanel.add(inputActivity);
+
+ outputLabel = new JLabel();
+ outputLabel.setText("Default Output");
+ wholePanel.add(outputLabel);
+
+ outputSelection = new JComboBox();
+ outputSelection.addActionListener(this);
+ wholePanel.add(outputSelection);
+ testButton = new JButton();
+ testButton.setText("Test");
+ testButton.addActionListener(this);
+ wholePanel.add(testButton);
+ outputIds = new ArrayList<Integer>();
+
+ refreshButton = new JButton();
+ refreshButton.setText("Refresh Device Lists");
+ System.out.println("refresh " + refreshButton.getPreferredSize());
+ System.out.println(getLayout());
+ refreshButton.addActionListener(this);
+ wholePanel.add(refreshButton);
+
+ updateButton = new JButton();
+ updateButton.setText("Update Preferences");
+ updateButton.setSize(refreshButton.getPreferredSize());
+ updateButton.addActionListener(this);
+ wholePanel.add(updateButton);
+
+ closeButton = new JButton();
+ closeButton.setText("Close/Release Ports");
+ closeButton.setSize(refreshButton.getPreferredSize());
+ closeButton.addActionListener(this);
+ wholePanel.add(closeButton);
+
+ // load the logo from the jar file (on Linux and Windows)
+ ClassLoader cldr = this.getClass().getClassLoader();
+ ImageIcon icon;
+ URL logoURL = cldr.getResource("portmusic_logo.png");
+ if (logoURL == null) {
+ // on Mac, load from bundle
+ icon = new ImageIcon("portmusic_logo.png");
+ } else {
+ icon = new ImageIcon(logoURL);
+ }
+ logo = new JLabel(icon);
+ logo.setSize(logo.getPreferredSize());
+ wholePanel.add(logo);
+
+ setVisible(true);
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ }
+
+ void loadDeviceChoices() throws JPortMidiException {
+ // initialize and load combo boxes with device descriptions
+ int n = jpm.countDevices();
+ inputSelection.removeAllItems();
+ inputIds.clear();
+ outputSelection.removeAllItems();
+ outputIds.clear();
+ for (int i = 0; i < n; i++) {
+ String interf = jpm.getDeviceInterf(i);
+ String name = jpm.getDeviceName(i);
+ System.out.println("name " + name);
+ String selection = name + " [" + interf + "]";
+ if (jpm.getDeviceInput(i)) {
+ inputIds.add(i);
+ inputSelection.addItem(selection);
+ } else {
+ outputIds.add(i);
+ outputSelection.addItem(selection);
+ }
+ }
+ }
+
+ void sendTestMessages() {
+ try {
+ if (!jpm.isOpenOutput()) {
+ int id = outputSelection.getSelectedIndex();
+ if (id < 0) return; // nothing selected
+ id = (Integer) (outputIds.get(id));
+ System.out.println("calling openOutput");
+ jpm.openOutput(id, 10, 10);
+ }
+ jpm.midiNote(0, 67, 100); // send an A (440)
+ jpm.midiNote(0, 67, 0, jpm.timeGet() + 500);
+ } catch(JPortMidiException e) {
+ System.out.println(e);
+ }
+ }
+}
+