/*
* Copyright (C) 2012 Klaus Reimer <k@ailis.de>
* See LICENSE.txt for licensing information.
*/
package de.ailis.midi4js;
import javax.sound.midi.MetaMessage;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.Receiver;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.SysexMessage;
import org.json.JSONException;
import org.json.JSONStringer;
/**
* Message receiver which encapsulates the received message into a JSON
* object and then sends it to the JavaScript part of Midi4JS.
*
* @author Klaus Reimer (k@ailis.de)
*/
public final class MessageReceiver implements Receiver
{
/** The Midi4JS applet. */
private final Midi4JS applet;
/**
* Constructor.
*
* @param applet
* The Midi4JS applet.
*/
MessageReceiver(final Midi4JS applet)
{
this.applet = applet;
}
/**
* @see javax.sound.midi.Receiver#send(javax.sound.midi.MidiMessage, long)
*/
@Override
public void send(final MidiMessage message, final long timeStamp)
{
try
{
final JSONStringer json = new JSONStringer();
json.object();
json.key("status").value(message.getStatus());
json.key("message");
json.array();
final byte[] data = message.getMessage();
final int max = Math.min(data.length, message.getLength());
for (int i = 0; i < max; i++)
json.value(data[i] & 0xff);
json.endArray();
if (message instanceof ShortMessage)
processShortMessage((ShortMessage) message, json);
else if (message instanceof MetaMessage)
processMetaMessage((MetaMessage) message, json);
else if (message instanceof SysexMessage)
processSysexMessage((SysexMessage) message, json);
json.endObject();
this.applet.execJSMethod("messageReceived",
System.identityHashCode(this),
json.toString(), timeStamp);
}
catch (final JSONException e)
{
throw new RuntimeException(e.toString(), e);
}
}
/**
* Processes a short message.
*
* @param message
* The message to process.
* @param json
* The JSON stringer.
* @throws JSONException
* When JSON output fails.
*/
private void processShortMessage(final ShortMessage message, final JSONStringer json) throws JSONException
{
json.key("class").value("ShortMessage");
json.key("channel").value(message.getChannel());
json.key("command").value(message.getCommand());
json.key("data1").value(message.getData1());
json.key("data2").value(message.getData2());
}
/**
* Processes a meta message.
*
* @param message
* The message to process.
* @param json
* The JSON stringer.
* @throws JSONException
* When JSON output fails.
*/
private void processMetaMessage(final MetaMessage message, final JSONStringer json) throws JSONException
{
json.key("class").value("MetaMessage");
json.key("type").value(message.getType());
json.key("data");
json.array();
final byte[] data = message.getMessage();
final int max = Math.min(data.length, message.getLength());
for (int i = 0; i < max; i++)
json.value(data[i] & 0xff);
json.endArray();
}
/**
* Processes a sysex message.
*
* @param message
* The message to process.
* @param json
* The JSON stringer.
* @throws JSONException
* When JSON output fails.
*/
private void processSysexMessage(final SysexMessage message,
final JSONStringer json) throws JSONException
{
json.key("class").value("SysexMessage");
json.key("data");
json.array();
final byte[] data = message.getMessage();
final int max = Math.min(data.length, message.getLength());
for (int i = 0; i < max; i++)
json.value(data[i] & 0xff);
json.endArray();
}
/**
* @see javax.sound.midi.Receiver#close()
*/
@Override
public void close()
{
// Nothing to do here.
}
}