classpath-patches
[Top][All Lists]
Advanced

[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:
 






reply via email to

[Prev in Thread] Current Thread [Next in Thread]