/* * MidiNote.java * * This file is part of jsresources.org */ /* * Copyright (c) 1999 - 2006 by Matthias Pfisterer * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /* |<--- this code is formatted to fit into 80 columns --->| */ import javax.sound.midi.InvalidMidiDataException; import javax.sound.midi.MidiDevice; import javax.sound.midi.MidiSystem; import javax.sound.midi.MidiUnavailableException; import javax.sound.midi.Receiver; import javax.sound.midi.MidiMessage; import javax.sound.midi.ShortMessage; import javax.sound.midi.SysexMessage; // TODO: an optional delay parameter that is added to getMicrosecondPosition to be used as timestamp for the event delivery. /** <titleabbrev>MidiNote</titleabbrev> <title>Playing a note on a MIDI device</title> <formalpara><title>Purpose</title> <para>Plays a single note on a MIDI device. The MIDI device can be a software synthesizer, an internal hardware synthesizer or any device connected to the MIDI OUT port.</para> </formalpara> <formalpara><title>Usage</title> <para> <cmdsynopsis><command>java MidiNote</command> <arg choice="opt"><replaceable class="parameter">devicename</replaceable></arg> <arg choice="plain"><replaceable class="parameter">keynumber</replaceable></arg> <arg choice="plain"><replaceable class="parameter">velocity</replaceable></arg> <arg choice="plain"><replaceable class="parameter">duration</replaceable></arg> </cmdsynopsis> </para></formalpara> <formalpara><title>Parameters</title> <variablelist> <varlistentry> <term><replaceable class="parameter">devicename</replaceable></term> <listitem><para>the name of the device to send the MIDI messages to</para></listitem> </varlistentry> <varlistentry> <term><replaceable class="parameter">keynumber</replaceable></term> <listitem><para>the MIDI key number</para></listitem> </varlistentry> <varlistentry> <term><replaceable class="parameter">velocity</replaceable></term> <listitem><para>the velocity</para></listitem> </varlistentry> <varlistentry> <term><replaceable class="parameter">duration</replaceable></term> <listitem><para>the duration in milliseconds</para></listitem> </varlistentry> </variablelist> </formalpara> <formalpara><title>Bugs, limitations</title> <para>Not well-tested.</para> </formalpara> <formalpara><title>Source code</title> <para> <ulink url="MidiNote.java.html">MidiNote.java</ulink>, <ulink url="MidiCommon.java.html">MidiCommon.java</ulink> </para> </formalpara> */ public class MidiNote { /** Flag for debugging messages. If true, some messages are dumped to the console during operation. */ private static boolean DEBUG = true; public static void main(String[] args) { // TODO: make settable via command line int nChannel = 0; int nKey = 0; // MIDI key number int nVelocity = 0; /* * Time between note on and note off event in * milliseconds. Note that on most systems, the * best resolution you can expect are 10 ms. */ int nDuration = 0; int nArgumentIndexOffset = 0; String strDeviceName = null; if (args.length == 4) { strDeviceName = args[0]; nArgumentIndexOffset = 1; } else if (args.length == 3) { nArgumentIndexOffset = 0; } else { printUsageAndExit(); } nKey = Integer.parseInt(args[0 + nArgumentIndexOffset]); nKey = Math.min(127, Math.max(0, nKey)); nVelocity = Integer.parseInt(args[1 + nArgumentIndexOffset]); nVelocity = Math.min(127, Math.max(0, nVelocity)); nDuration = Integer.parseInt(args[2 + nArgumentIndexOffset]); nDuration = Math.max(0, nDuration); MidiDevice outputDevice = null; Receiver receiver = null; if (strDeviceName != null) { MidiDevice.Info info = MidiCommon.getMidiDeviceInfo(strDeviceName, true); if (info == null) { out("no device info found for name " + strDeviceName); System.exit(1); } try { outputDevice = MidiSystem.getMidiDevice(info); if (DEBUG) out("MidiDevice: " + outputDevice); outputDevice.open(); } catch (MidiUnavailableException e) { if (DEBUG) out(e); } if (outputDevice == null) { out("wasn't able to retrieve MidiDevice"); System.exit(1); } try { receiver = outputDevice.getReceiver(); } catch (MidiUnavailableException e) { if (DEBUG) out(e); } } else { /* We retrieve a Receiver for the default MidiDevice. */ try { receiver = MidiSystem.getReceiver(); } catch (MidiUnavailableException e) { if (DEBUG) { out(e); } } } if (receiver == null) { out("wasn't able to retrieve Receiver"); System.exit(1); } if (DEBUG) out("Receiver: " + receiver); /* Here, we prepare the MIDI messages to send. Obviously, one is for turning the key on and one for turning it off. */ ShortMessage onMessage = null; ShortMessage offMessage = null; try { onMessage = new ShortMessage(); offMessage = new ShortMessage(); onMessage.setMessage(ShortMessage.NOTE_ON, nChannel, nKey, nVelocity); offMessage.setMessage(ShortMessage.NOTE_OFF, nChannel, nKey, 0); if (DEBUG) { out("On Msg: " + onMessage.getStatus() + " " + onMessage.getData1() + " " + onMessage.getData2()); out("Off Msg: " + offMessage.getStatus() + " " + offMessage.getData1() + " " + offMessage.getData2()); } } catch (InvalidMidiDataException e) { if (DEBUG) { out(e); } } /* * Turn the note on */ if (DEBUG) out("sending on message..."); receiver.send(onMessage, -1); if (DEBUG) out("...sent"); /* * Wait for the specified amount of time * (the duration of the note). */ try { Thread.sleep(nDuration); } catch (InterruptedException e) { if (DEBUG) out(e); } /* * Turn the note off. */ if (DEBUG) out("sending off message..."); receiver.send(offMessage, -1); if (DEBUG) out("...sent"); /* * Clean up. */ receiver.close(); if (outputDevice != null) { outputDevice.close(); } } private static void printUsageAndExit() { out("MidiNote: usage:"); out(" java MidiNote [<device name>] <note number> <velocity> <duration>"); out(" <device name>\toutput to named device"); System.exit(1); } private static void out(String strMessage) { System.out.println(strMessage); } private static void out(Throwable t) { t.printStackTrace(); } } /*** MidiNote.java ***/