[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[cp-patches] FYI: dssi control handling, midi demo, INSTALL and LICENSE
From: |
Anthony Green |
Subject: |
[cp-patches] FYI: dssi control handling, midi demo, INSTALL and LICENSE additions |
Date: |
Thu, 06 Oct 2005 20:18:02 -0700 |
I'm about to check in the following patch collection, most of which I've
already posted to the list for comment.
Thanks,
AG
2005-10-06 Anthony Green <address@hidden>
* INSTALL: Describe midi provider dependencies.
* native/jni/midi-dssi/README: New file.
* LICENSE (terms): Add notice about code copied from the DSSI
distribution.
* examples/gnu/classpath/examples/midi/Demo.java: New file.
* native/jni/midi-dssi/dssi_data.h (dssi_data): Add control_count,
control_port_map, control_value_map, sample_rate, and
control_values fields.
* native/jni/midi-dssi/gnu_javax_sound_midi_dssi_DSSISynthesizer.c
(DEBUG_DSSI_PROVIDER): New macro.
(get_port_default): New function.
(set_control): New function.
(Java_gnu_javax_sound_midi_dssi_DSSISynthesizer_open_1): Remove
debug output. Reformat. Allocate the control ports and assign
proper default values.
(Java_gnu_javax_sound_midi_dssi_DSSISynthesizer_noteOn_1): Use
JLONG_TO_PTR.
(Java_gnu_javax_sound_midi_dssi_DSSISynthesizer_noteOff_1): Ditto.
* gnu/javax/sound/midi/dssi/DSSISynthesizer.java
(Channel.controlChange): Implement.
(controlChange_): New native method.
* include/gnu_javax_sound_midi_dssi_DSSISynthesizer.h: Rebuilt.
* gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java: Make
instance final.
Index: LICENSE
===================================================================
RCS file: /cvsroot/classpath/classpath/LICENSE,v
retrieving revision 1.7
diff -u -r1.7 LICENSE
--- LICENSE 2 Jul 2005 20:32:07 -0000 1.7
+++ LICENSE 7 Oct 2005 02:47:11 -0000
@@ -284,3 +284,17 @@
shall not be used in advertising or otherwise to promote the sale, use
or other dealings in these Data Files or Software without prior
written authorization of the copyright holder.
+
+
+The file native/jni/midi-dssi/gnu_javax_sound_midi_dssi_DSSISynthesizer.c
+contains two functions (get_port_default and set_control) derived from
+example code in the DSSI distribution (http://dssi.sourceforge.net).
+The original DSSI example code is distributed under the following
+terms:
+
+ Copyright 2004 Chris Cannam, Steve Harris and Sean Bolton.
+
+ Permission to use, copy, modify, distribute, and sell this software
+ for any purpose is hereby granted without fee, provided that the
+ above copyright notice and this permission notice are included in
+ all copies or substantial portions of the software.
Index: gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java
===================================================================
RCS file:
/cvsroot/classpath/classpath/gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java,v
retrieving revision 1.1
diff -u -r1.1 AlsaMidiSequencerDevice.java
--- gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java 3 Oct 2005
01:53:12 -0000 1.1
+++ gnu/javax/sound/midi/alsa/AlsaMidiSequencerDevice.java 7 Oct 2005
02:47:12 -0000
@@ -64,7 +64,7 @@
public class AlsaMidiSequencerDevice implements Sequencer
{
// The singleton instance.
- public static AlsaMidiSequencerDevice instance = new
AlsaMidiSequencerDevice();
+ public final static AlsaMidiSequencerDevice instance = new
AlsaMidiSequencerDevice();
// A pointer to a native chunk of memory
private long nativeState;
Index: gnu/javax/sound/midi/dssi/DSSISynthesizer.java
===================================================================
RCS file:
/cvsroot/classpath/classpath/gnu/javax/sound/midi/dssi/DSSISynthesizer.java,v
retrieving revision 1.1
diff -u -r1.1 DSSISynthesizer.java
--- gnu/javax/sound/midi/dssi/DSSISynthesizer.java 3 Oct 2005 01:53:12
-0000 1.1
+++ gnu/javax/sound/midi/dssi/DSSISynthesizer.java 7 Oct 2005 02:47:12
-0000
@@ -85,6 +85,10 @@
else
channels[smessage.getChannel()].noteOff(smessage.getData1());
break;
+ case ShortMessage.CONTROL_CHANGE:
+ channels[smessage.getChannel()].controlChange(smessage.getData1(),
+ smessage.getData2());
+ break;
default:
System.out.println ("Unhandled message: " + message.getStatus());
break;
@@ -106,6 +110,7 @@
static native void noteOff_(long handle, int channel, int noteNumber, int
velocity);
static native void setPolyPressure_(long handle, int channel, int
noteNumber, int pressure);
static native int getPolyPressure_(long handle, int channel, int noteNumber);
+ static native void controlChange_(long handle, int channel, int control, int
value);
static native void open_(long handle);
static native void close_(long handle);
@@ -184,13 +189,10 @@
return 0;
}
- /* (non-Javadoc)
- * @see javax.sound.midi.MidiChannel#controlChange(int, int)
- */
+ /* @see javax.sound.midi.MidiChannel#controlChange(int, int) */
public void controlChange(int controller, int value)
{
- // TODO Auto-generated method stub
-
+ controlChange_(sohandle, channel, controller, value);
}
/* (non-Javadoc)
Index: include/gnu_javax_sound_midi_dssi_DSSISynthesizer.h
===================================================================
RCS file:
/cvsroot/classpath/classpath/include/gnu_javax_sound_midi_dssi_DSSISynthesizer.h,v
retrieving revision 1.1
diff -u -r1.1 gnu_javax_sound_midi_dssi_DSSISynthesizer.h
--- include/gnu_javax_sound_midi_dssi_DSSISynthesizer.h 3 Oct 2005 01:53:12
-0000 1.1
+++ include/gnu_javax_sound_midi_dssi_DSSISynthesizer.h 7 Oct 2005 02:47:12
-0000
@@ -14,6 +14,7 @@
JNIEXPORT void JNICALL
Java_gnu_javax_sound_midi_dssi_DSSISynthesizer_noteOff_1 (JNIEnv *env, jclass,
jlong, jint, jint, jint);
JNIEXPORT void JNICALL
Java_gnu_javax_sound_midi_dssi_DSSISynthesizer_setPolyPressure_1 (JNIEnv *env,
jclass, jlong, jint, jint, jint);
JNIEXPORT jint JNICALL
Java_gnu_javax_sound_midi_dssi_DSSISynthesizer_getPolyPressure_1 (JNIEnv *env,
jclass, jlong, jint, jint);
+JNIEXPORT void JNICALL
Java_gnu_javax_sound_midi_dssi_DSSISynthesizer_controlChange_1 (JNIEnv *env,
jclass, jlong, jint, jint, jint);
JNIEXPORT void JNICALL Java_gnu_javax_sound_midi_dssi_DSSISynthesizer_open_1
(JNIEnv *env, jclass, jlong);
JNIEXPORT void JNICALL Java_gnu_javax_sound_midi_dssi_DSSISynthesizer_close_1
(JNIEnv *env, jclass, jlong);
Index: native/jni/midi-dssi/dssi_data.h
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/midi-dssi/dssi_data.h,v
retrieving revision 1.2
diff -u -r1.2 dssi_data.h
--- native/jni/midi-dssi/dssi_data.h 4 Oct 2005 12:24:08 -0000 1.2
+++ native/jni/midi-dssi/dssi_data.h 7 Oct 2005 02:47:14 -0000
@@ -100,5 +100,22 @@
float *left_buffer;
float *right_buffer;
+ /* The number of input controls for this synth. */
+ unsigned control_count;
+
+ /* An array of control values, control_count in length. */
+ LADSPA_Data *control_values;
+
+ /* A mapping of MIDI controllers to control values. There are a
+ maximum of 128 MIDI controllers. */
+ unsigned control_value_map[128];
+
+ /* A mapping of MIDI controllers to LADSPA ports. There are a
+ maximum of 128 MIDI controllers. */
+ unsigned control_port_map[128];
+
+ /* The sample rate. */
+ jack_nframes_t sample_rate;
+
} dssi_data;
Index: native/jni/midi-dssi/gnu_javax_sound_midi_dssi_DSSISynthesizer.c
===================================================================
RCS file:
/cvsroot/classpath/classpath/native/jni/midi-dssi/gnu_javax_sound_midi_dssi_DSSISynthesizer.c,v
retrieving revision 1.2
diff -u -r1.2 gnu_javax_sound_midi_dssi_DSSISynthesizer.c
--- native/jni/midi-dssi/gnu_javax_sound_midi_dssi_DSSISynthesizer.c 4 Oct
2005 12:24:08 -0000 1.2
+++ native/jni/midi-dssi/gnu_javax_sound_midi_dssi_DSSISynthesizer.c 7 Oct
2005 02:47:14 -0000
@@ -35,11 +35,30 @@
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
+/* The original get_port_default() and set_control() routines were
+ * copied from the DSSI source distribution and are covered by the
+ * following copyright and license...
+ *
+ * Copyright 2004 Chris Cannam, Steve Harris and Sean Bolton.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * for any purpose is hereby granted without fee, provided that the
+ * above copyright notice and this permission notice are included in
+ * all copies or substantial portions of the software.
+ */
+
#include <config.h>
#include <gnu_javax_sound_midi_dssi_DSSISynthesizer.h>
+#include <math.h>
#include "dssi_data.h"
+/* Define this for debug output. */
+#undef DEBUG_DSSI_PROVIDER
+
+static void set_control (dssi_data *data, snd_seq_event_t *event);
+
+
/**
* The jack callback routine.
*
@@ -50,15 +69,19 @@
static int
process (jack_nframes_t nframes, void *arg)
{
- struct timeval tv;
dssi_data *data = (dssi_data *) arg;
int index;
jack_default_audio_sample_t *buffer;
- /* Look through the event buffer to see if anything needs doing. */
+ /* Look through the event buffer to see if any control values
+ need changing. */
for ( index = data->midiEventReadIndex;
index != data->midiEventWriteIndex;
- index = (index + 1) % EVENT_BUFFER_SIZE);
+ index = (index + 1) % EVENT_BUFFER_SIZE)
+ {
+ if (data->midiEventBuffer[index].type == SND_SEQ_EVENT_CONTROLLER)
+ set_control (data, & data->midiEventBuffer[index]);
+ }
/* Call the synth audio processing routine. */
data->desc->run_synth(data->plugin_handle,
@@ -84,8 +107,151 @@
return 0;
}
-/* FIXME: Temporary hack. */
-float mctrl = 0.9f;
+
+/**
+ * Calculate a reasonable default value for a specific control port.
+ * This is mostly copied from the DSSI example code. Copyright info
+ * is found at the top of this file.
+ *
+ */
+static LADSPA_Data
+get_port_default (const LADSPA_Descriptor *plugin,
+ int port, jack_nframes_t sample_rate)
+{
+ LADSPA_PortRangeHint hint = plugin->PortRangeHints[port];
+ float lower = hint.LowerBound *
+ (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor) ? sample_rate : 1.0f);
+ float upper = hint.UpperBound *
+ (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor) ? sample_rate : 1.0f);
+
+ if (!LADSPA_IS_HINT_HAS_DEFAULT(hint.HintDescriptor))
+ {
+ if (!LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) ||
+ !LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor))
+ {
+ /* No hint, its not bounded, wild guess */
+ return 0.0f;
+ }
+
+ if (lower <= 0.0f && upper >= 0.0f)
+ {
+ /* It spans 0.0, 0.0 is often a good guess */
+ return 0.0f;
+ }
+
+ /* No clues, return minimum */
+ return lower;
+ }
+
+ /* Try all the easy ones */
+
+ if (LADSPA_IS_HINT_DEFAULT_0(hint.HintDescriptor))
+ return 0.0f;
+ else if (LADSPA_IS_HINT_DEFAULT_1(hint.HintDescriptor))
+ return 1.0f;
+ else if (LADSPA_IS_HINT_DEFAULT_100(hint.HintDescriptor))
+ return 100.0f;
+ else if (LADSPA_IS_HINT_DEFAULT_440(hint.HintDescriptor))
+ return 440.0f;
+
+ /* All the others require some bounds */
+
+ if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)
+ && (LADSPA_IS_HINT_DEFAULT_MINIMUM(hint.HintDescriptor)))
+ return lower;
+
+ if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor))
+ {
+ if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hint.HintDescriptor))
+ return upper;
+
+ if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor))
+ {
+ if (LADSPA_IS_HINT_DEFAULT_LOW(hint.HintDescriptor))
+ return lower * 0.75f + upper * 0.25f;
+ else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint.HintDescriptor))
+ return lower * 0.5f + upper * 0.5f;
+ else if (LADSPA_IS_HINT_DEFAULT_HIGH(hint.HintDescriptor))
+ return lower * 0.25f + upper * 0.75f;
+ }
+ }
+
+ /* fallback */
+ return 0.0f;
+}
+
+/**
+ * Set a control value by mapping the MIDI event to a suitable value
+ * for this control.
+ * This is mostly copied from the DSSI example code. Copyright info
+ * is found at the top of this file.
+ *
+ */
+static void
+set_control(dssi_data *data, snd_seq_event_t *event)
+{
+ unsigned control = event->data.control.param;
+ unsigned port = data->control_port_map[control];
+
+ const LADSPA_Descriptor *p = data->desc->LADSPA_Plugin;
+
+ LADSPA_PortRangeHintDescriptor d = p->PortRangeHints[port].HintDescriptor;
+
+ LADSPA_Data lb = p->PortRangeHints[port].LowerBound *
+ (LADSPA_IS_HINT_SAMPLE_RATE(p->PortRangeHints[port].HintDescriptor) ?
+ data->sample_rate : 1.0f);
+
+ LADSPA_Data ub = p->PortRangeHints[port].UpperBound *
+ (LADSPA_IS_HINT_SAMPLE_RATE(p->PortRangeHints[port].HintDescriptor) ?
+ data->sample_rate : 1.0f);
+
+ float value = (float)event->data.control.value;
+
+ if (!LADSPA_IS_HINT_BOUNDED_BELOW(d))
+ {
+ if (!LADSPA_IS_HINT_BOUNDED_ABOVE(d))
+ {
+ /* unbounded: might as well leave the value alone. */
+ }
+ else
+ {
+ /* bounded above only. just shift the range. */
+ value = ub - 127.0f + value;
+ }
+ }
+ else
+ {
+ if (!LADSPA_IS_HINT_BOUNDED_ABOVE(d))
+ {
+ /* bounded below only. just shift the range. */
+ value = lb + value;
+ }
+ else
+ {
+ /* bounded both ends. more interesting. */
+ if (LADSPA_IS_HINT_LOGARITHMIC(d))
+ {
+ const float llb = logf(lb);
+ const float lub = logf(ub);
+
+ value = expf(llb + ((lub - llb) * value / 127.0f));
+ }
+ else
+ {
+ value = lb + ((ub - lb) * value / 127.0f);
+ }
+ }
+ }
+
+#ifdef DEBUG_DSSI_PROVIDER
+ printf("MIDI controller %d=%d -> control in %u=%f\n",
+ event->data.control.param,
+ event->data.control.value,
+ data->control_value_map[control], value);
+#endif
+
+ data->control_values[data->control_value_map[control]] = value;
+}
/**
* Open a new synthesizer. This currently involves instantiating a
@@ -97,7 +263,7 @@
Java_gnu_javax_sound_midi_dssi_DSSISynthesizer_open_1
(JNIEnv *env, jclass clazz __attribute__((unused)), jlong handle)
{
- unsigned int port_count, j;
+ unsigned int port_count, j, cindex, controller = 0;
dssi_data *data = (dssi_data *) (long) handle;
if ((data->jack_client = jack_client_new (data->desc->LADSPA_Plugin->Label))
== 0)
{
@@ -106,9 +272,14 @@
"can't create jack client");
return;
}
+
+ /* Get the jack sample rate, which may be used in default control port
+ value calculations. */
+ data->sample_rate = jack_get_sample_rate (data->jack_client);
- data->plugin_handle =
(data->desc->LADSPA_Plugin->instantiate)(data->desc->LADSPA_Plugin,
-
jack_get_sample_rate (data->jack_client));
+ data->plugin_handle =
+ (data->desc->LADSPA_Plugin->instantiate)(data->desc->LADSPA_Plugin,
+ data->sample_rate);
if (jack_set_process_callback (data->jack_client, process, data) != 0)
{
@@ -123,9 +294,9 @@
data->jack_right_output_port =
jack_port_register (data->jack_client, "output_right",
JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
-
- /* Count the number of output audio ports. */
- port_count = 0;
+
+ /* Count the number of controls and audio ouput ports. */
+ port_count = data->control_count = 0;
for (j = 0; j < data->desc->LADSPA_Plugin->PortCount; j++)
{
LADSPA_PortDescriptor pod =
@@ -133,11 +304,20 @@
if (LADSPA_IS_PORT_AUDIO(pod) && LADSPA_IS_PORT_OUTPUT(pod))
port_count++;
+ else if (LADSPA_IS_PORT_CONTROL(pod) && LADSPA_IS_PORT_INPUT(pod))
+ data->control_count++;
}
- printf ("LADSPA output ports = %d\n", port_count);
+
+ /* Allocate the array of control values. */
+ data->control_values =
+ (LADSPA_Data *) JCL_malloc (env,
+ data->control_count * sizeof (LADSPA_Data));
+
+ /* Initialize the MIDI control map. */
+ memset (data->control_value_map, 0, data->control_count * sizeof(unsigned));
/* Create buffers for each port. */
- for (j = 0; j < data->desc->LADSPA_Plugin->PortCount; j++)
+ for (cindex = 0, j = 0; j < data->desc->LADSPA_Plugin->PortCount; j++)
{
LADSPA_PortDescriptor pod =
data->desc->LADSPA_Plugin->PortDescriptors[j];
@@ -152,11 +332,39 @@
else
if (LADSPA_IS_PORT_CONTROL(pod) && LADSPA_IS_PORT_INPUT(pod))
{
+ /* This is an input control port. Connect it to a properly
+ initialized value in our controller value array. */
(data->desc->LADSPA_Plugin->connect_port)
- (data->plugin_handle, j, &mctrl);
+ (data->plugin_handle, j, &(data->control_values[cindex]));
+ data->control_values[cindex] =
+ get_port_default (data->desc->LADSPA_Plugin,
+ j, data->sample_rate);
+
+ /* Set up the mapping between MIDI controllers and this
+ contoller value. */
+ if (data->desc->get_midi_controller_for_port)
+ {
+ controller = data->desc->
+ get_midi_controller_for_port(data->plugin_handle, j);
+
+ if (DSSI_IS_CC(controller))
+ {
+ data->control_value_map[DSSI_CC_NUMBER(controller)] =
cindex;
+ data->control_port_map[DSSI_CC_NUMBER(controller)] = j;
+ }
+ }
+
+#ifdef DEBUG_DSSI_PROVIDER
+ printf ("MIDI Controller 0x%x [%s] = %g\n",
+ DSSI_CC_NUMBER(controller),
+ data->desc->LADSPA_Plugin->PortNames[j],
+ data->control_values[cindex]);
+#endif
+
+ cindex++;
}
}
-
+
(data->desc->LADSPA_Plugin->activate)(data->plugin_handle);
if (jack_activate (data->jack_client))
@@ -165,6 +373,28 @@
}
/**
+ * This is called when we receive a new MIDI CONTROL CHANGE message.
+ * Simply stick an appropriate event in the event buffer. This will
+ * get processed in the jack callback function.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_javax_sound_midi_dssi_DSSISynthesizer_controlChange_1
+ (JNIEnv *env __attribute__((unused)), jclass clazz __attribute__((unused)),
+ jlong handle, jint channel, jint control, jint value)
+{
+ dssi_data *data = JLONG_TO_PTR(dssi_data,handle);
+
+ /* Insert this event in the event buffer. */
+ snd_seq_event_t *ev = & data->midiEventBuffer[data->midiEventWriteIndex];
+
+ /* Set the event value. */
+ snd_seq_ev_set_controller (ev, channel, control, value);
+
+ data->midiEventWriteIndex =
+ (data->midiEventWriteIndex + 1) % EVENT_BUFFER_SIZE;
+}
+
+/**
* This is called when we receive a new MIDI NOTE ON message. Simply
* stick an appropriate event in the event buffer. This will get
* processed in the jack callback function.
@@ -174,7 +404,7 @@
(JNIEnv *env __attribute__((unused)), jclass clazz __attribute__((unused)),
jlong handle, jint channel, jint note, jint velocity)
{
- dssi_data *data = (dssi_data *) (long) handle;
+ dssi_data *data = JLONG_TO_PTR(dssi_data,handle);
/* Insert this event in the event buffer. */
snd_seq_event_t *ev = & data->midiEventBuffer[data->midiEventWriteIndex];
@@ -199,7 +429,7 @@
jclass clazz __attribute__((unused)),
jlong handle, jint channel, jint note, jint velocity)
{
- dssi_data *data = (dssi_data *) (long) handle;
+ dssi_data *data = JLONG_TO_PTR(dssi_data,handle);
/* Insert this event in the event buffer. */
snd_seq_event_t *ev = & data->midiEventBuffer[data->midiEventWriteIndex];
Index: examples/gnu/classpath/examples/midi/Demo.java
===================================================================
RCS file: examples/gnu/classpath/examples/midi/Demo.java
diff -N examples/gnu/classpath/examples/midi/Demo.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ examples/gnu/classpath/examples/midi/Demo.java 7 Oct 2005 02:52:07
-0000
@@ -0,0 +1,137 @@
+/* Demo.java -- And example of MIDI support
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath examples.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA. */
+
+package gnu.classpath.examples.midi;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import javax.sound.midi.*;
+
+/**
+ * An example how javax.sound.midi facilities work.
+ */
+public class Demo extends Frame implements ItemListener
+{
+ Choice midiInChoice = new Choice();
+ Choice midiOutChoice = new Choice();
+
+ MidiDevice inDevice = null;
+ MidiDevice outDevice = null;
+
+ ArrayList inDevices = new ArrayList();
+ ArrayList outDevices = new ArrayList();
+
+ public Demo () throws Exception
+ {
+ MenuBar mb = new MenuBar ();
+ Menu menu = new Menu ("File");
+ MenuItem quit = new MenuItem("Quit", new MenuShortcut('Q'));
+ quit.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ System.exit(0);
+ }
+ });
+ menu.add (quit);
+ mb.add(menu);
+
+ setTitle("synthcity: the GNU Classpath MIDI Demo");
+ setLayout(new FlowLayout());
+
+ MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
+
+ for (int i = 0; i < infos.length; i++)
+ {
+ MidiDevice device = MidiSystem.getMidiDevice(infos[i]);
+ if (device.getMaxReceivers() > 0)
+ {
+ midiOutChoice.addItem(infos[i].getDescription());
+ outDevices.add(device);
+ }
+ if (device.getMaxTransmitters() > 0)
+ {
+ midiInChoice.addItem(infos[i].getDescription());
+ inDevices.add(device);
+ }
+ }
+
+ setMenuBar (mb);
+ add(new Label("MIDI IN: "));
+ add(midiInChoice);
+ add(new Label(" MIDI OUT: "));
+ add(midiOutChoice);
+
+ midiInChoice.addItemListener(this);
+ midiOutChoice.addItemListener(this);
+
+ pack();
+ show();
+ }
+
+ public void itemStateChanged (ItemEvent e)
+ {
+ try
+ {
+ if (e.getItemSelectable() == midiInChoice)
+ {
+ if (inDevice != null)
+ inDevice.close();
+ inDevice = (MidiDevice)
+ inDevices.get(midiInChoice.getSelectedIndex());
+ }
+
+ if (e.getItemSelectable() == midiOutChoice)
+ {
+ if (outDevice != null)
+ outDevice.close();
+ outDevice = (MidiDevice)
+ outDevices.get(midiOutChoice.getSelectedIndex());
+ }
+
+ if (inDevice != null && outDevice != null)
+ {
+ if (! inDevice.isOpen())
+ inDevice.open();
+ if (! outDevice.isOpen())
+ outDevice.open();
+ Transmitter t = inDevice.getTransmitter();
+ if (t == null)
+ System.err.println (inDevice + ".getTransmitter() == null");
+ Receiver r = outDevice.getReceiver();
+ if (r == null)
+ System.err.println (outDevice + ".getReceiver() == null");
+
+ if (t != null && r != null)
+ t.setReceiver (r);
+ }
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ public static void main (String args[]) throws Exception
+ {
+ new Demo();
+ }
+}
Index: native/jni/midi-dssi/README
===================================================================
RCS file: native/jni/midi-dssi/README
diff -N native/jni/midi-dssi/README
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ native/jni/midi-dssi/README 7 Oct 2005 02:52:07 -0000
@@ -0,0 +1,134 @@
+The file native/jni/midi-dssi/gnu_javax_sound_midi_dssi_DSSISynthesizer.c
+contains two functions (get_port_default and set_control) derived from
+example code in the DSSI distribution (http://dssi.sourceforge.net).
+The original DSSI example code is distributed under the following
+terms:
+
+ Copyright 2004 Chris Cannam, Steve Harris and Sean Bolton.
+
+ Permission to use, copy, modify, distribute, and sell this software
+ for any purpose is hereby granted without fee, provided that the
+ above copyright notice and this permission notice are included in
+ all copies or substantial portions of the software.
+
+
+The rest of this file contain the original versions of these
+functions.
+
+
+LADSPA_Data get_port_default(const LADSPA_Descriptor *plugin, int port)
+{
+ LADSPA_PortRangeHint hint = plugin->PortRangeHints[port];
+ float lower = hint.LowerBound *
+ (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor) ? sample_rate : 1.0f);
+ float upper = hint.UpperBound *
+ (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor) ? sample_rate : 1.0f);
+
+ if (!LADSPA_IS_HINT_HAS_DEFAULT(hint.HintDescriptor)) {
+ if (!LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) ||
+ !LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) {
+ /* No hint, its not bounded, wild guess */
+ return 0.0f;
+ }
+
+ if (lower <= 0.0f && upper >= 0.0f) {
+ /* It spans 0.0, 0.0 is often a good guess */
+ return 0.0f;
+ }
+
+ /* No clues, return minimum */
+ return lower;
+ }
+
+ /* Try all the easy ones */
+
+ if (LADSPA_IS_HINT_DEFAULT_0(hint.HintDescriptor)) {
+ return 0.0f;
+ } else if (LADSPA_IS_HINT_DEFAULT_1(hint.HintDescriptor)) {
+ return 1.0f;
+ } else if (LADSPA_IS_HINT_DEFAULT_100(hint.HintDescriptor)) {
+ return 100.0f;
+ } else if (LADSPA_IS_HINT_DEFAULT_440(hint.HintDescriptor)) {
+ return 440.0f;
+ }
+
+ /* All the others require some bounds */
+
+ if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) {
+ if (LADSPA_IS_HINT_DEFAULT_MINIMUM(hint.HintDescriptor)) {
+ return lower;
+ }
+ }
+ if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) {
+ if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hint.HintDescriptor)) {
+ return upper;
+ }
+ if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) {
+ if (LADSPA_IS_HINT_DEFAULT_LOW(hint.HintDescriptor)) {
+ return lower * 0.75f + upper * 0.25f;
+ } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint.HintDescriptor)) {
+ return lower * 0.5f + upper * 0.5f;
+ } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hint.HintDescriptor)) {
+ return lower * 0.25f + upper * 0.75f;
+ }
+ }
+ }
+
+ /* fallback */
+ return 0.0f;
+}
+
+
+void
+setControl(d3h_instance_t *instance, long controlIn, snd_seq_event_t *event)
+{
+ long port = pluginControlInPortNumbers[controlIn];
+
+ const LADSPA_Descriptor *p = instance->plugin->descriptor->LADSPA_Plugin;
+
+ LADSPA_PortRangeHintDescriptor d = p->PortRangeHints[port].HintDescriptor;
+
+ LADSPA_Data lb = p->PortRangeHints[port].LowerBound *
+ (LADSPA_IS_HINT_SAMPLE_RATE(p->PortRangeHints[port].HintDescriptor) ?
+ sample_rate : 1.0f);
+
+ LADSPA_Data ub = p->PortRangeHints[port].UpperBound *
+ (LADSPA_IS_HINT_SAMPLE_RATE(p->PortRangeHints[port].HintDescriptor) ?
+ sample_rate : 1.0f);
+
+ float value = (float)event->data.control.value;
+
+ if (!LADSPA_IS_HINT_BOUNDED_BELOW(d)) {
+ if (!LADSPA_IS_HINT_BOUNDED_ABOVE(d)) {
+ /* unbounded: might as well leave the value alone. */
+ } else {
+ /* bounded above only. just shift the range. */
+ value = ub - 127.0f + value;
+ }
+ } else {
+ if (!LADSPA_IS_HINT_BOUNDED_ABOVE(d)) {
+ /* bounded below only. just shift the range. */
+ value = lb + value;
+ } else {
+ /* bounded both ends. more interesting. */
+ if (LADSPA_IS_HINT_LOGARITHMIC(d)) {
+ const float llb = logf(lb);
+ const float lub = logf(ub);
+
+ value = expf(llb + ((lub - llb) * value / 127.0f));
+ } else {
+ value = lb + ((ub - lb) * value / 127.0f);
+ }
+ }
+ }
+
+ if (verbose) {
+ printf("%s: %s MIDI controller %d=%d -> control in %ld=%f\n", myName,
+ instance->friendly_name, event->data.control.param,
+ event->data.control.value, controlIn, value);
+ }
+
+ pluginControlIns[controlIn] = value;
+ pluginPortUpdated[controlIn] = 1;
+}
+
Index: INSTALL
===================================================================
RCS file: /cvsroot/classpath/classpath/INSTALL,v
retrieving revision 1.32
diff -u -r1.32 INSTALL
--- INSTALL 6 Sep 2005 23:01:55 -0000 1.32
+++ INSTALL 7 Oct 2005 03:14:06 -0000
@@ -79,6 +79,29 @@
- texinfo 4.2 or higher.
+ For building the ALSA midi provider code you will need
+ ALSA. http://www.alsa-project.org.
+
+ For building the DSSI midi synthesizer provider code you will
+ need DSSI from http://dssi.sourceforge.net. This, in turn,
+ introduces many dependencies, including:
+
+ - liblo: the Lightweight OSC implementation
+ http://plugin.org.uk/liblo/
+
+ - LADSPA: Linux Audio Developer's Simple Plugin API
+ http://www.ladspa.org
+
+ - the JACK Audio Connection Kit: A low latency audio server
+ http://jackit.sourceforge.net
+
+ - libsndfile: an audio file I/O library
+ http://www.mega-nerd.com/libsndfile/
+
+ - fluidsynth: a real-time SoundFont 2 based soft-synth
+ http://www.fluidsynth.org/
+
+
This package was designed to use the GNU standard for configuration
and makefiles. To build and install do the following:
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [cp-patches] FYI: dssi control handling, midi demo, INSTALL and LICENSE additions,
Anthony Green <=