1 /* DSSIMidiDeviceProvider.java -- DSSI Device Provider
2    Copyright (C) 2005, 2012 Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 
39 package gnu.javax.sound.midi.dssi;
40 
41 import java.util.ArrayList;
42 import java.util.List;
43 import java.io.File;
44 import java.io.FilenameFilter;
45 
46 import gnu.classpath.Configuration;
47 import javax.sound.midi.MidiDevice;
48 import javax.sound.midi.MidiDevice.Info;
49 import javax.sound.midi.spi.MidiDeviceProvider;
50 
51 /**
52  * A DSSI MIDI device provider.
53  *
54  * DSSI (pronounced "dizzy") is an API for audio plugins, with particular
55  * application for software synthesis plugins with native user interfaces.
56  *
57  * Read about DSSI at http://dssi.sourceforge.net
58  *
59  * @author Anthony Green (green@redhat.com)
60  *
61  */
62 public class DSSIMidiDeviceProvider extends MidiDeviceProvider
63 {
64   /**
65    * The MidiDevice.Info specialized for DSSI synthesizers.
66    *
67    * @author Anthony Green (green@redhat.com)
68    *
69    */
70   private static class DSSIInfo extends Info
71   {
72     String copyright;
73     String soname;
74     long index;
75 
DSSIInfo(String name, String vendor, String label, String copyright, String version, String soname, long index)76     public DSSIInfo(String name, String vendor, String label,
77                     String copyright, String version,
78                     String soname, long index)
79     {
80       super(name, vendor, label, version);
81       this.copyright = copyright;
82       this.soname = soname;
83       this.index = index;
84     }
85   }
86 
dlopen_(String soname)87   static native long dlopen_(String soname);
dlclose_(long sohandle)88   static native void dlclose_(long sohandle);
getDSSIHandle_(long sohandle, long index)89   static native long getDSSIHandle_(long sohandle, long index);
getDSSIName_(long handle)90   static native String getDSSIName_(long handle);
getDSSICopyright_(long handle)91   static native String getDSSICopyright_(long handle);
getDSSIVendor_(long handle)92   static native String getDSSIVendor_(long handle);
getDSSILabel_(long handle)93   static native String getDSSILabel_(long handle);
94 
examineLibrary(String soname)95   private static List<DSSIInfo> examineLibrary(String soname)
96   {
97      List<DSSIInfo> list = new ArrayList<DSSIInfo>();
98      long index = 0;
99      long handle;
100 
101      long sohandle = dlopen_(soname);
102      if (sohandle == 0)
103        return list;
104      do
105      {
106        handle = getDSSIHandle_(sohandle, index);
107        if (handle == 0)
108          break;
109        String name = getDSSILabel_(handle);
110        String copyright = getDSSICopyright_(handle);
111        String label = getDSSIName_(handle);
112        String vendor = getDSSIVendor_(handle);
113        list.add(new DSSIInfo(name, vendor, label, copyright,
114                              "DSSI-1", soname, index));
115        index++;
116      } while (true);
117 
118      // Close the library and free memory
119      dlclose_(sohandle);
120 
121      return list;
122   }
123 
124   private static DSSIInfo[] infos;
125 
126   static
127   {
128     if (Configuration.INIT_LOAD_LIBRARY)
129       System.loadLibrary("gjsmdssi");
130 
131     File dssidir = new File("/usr/lib/dssi/");
132     String sofiles[] = dssidir.list(new FilenameFilter()
133                                     {
134                                       public boolean accept(File dir, String n)
135                                       {
136                                         return n.endsWith(".so");
137                                       }
138                                     });
139     List<DSSIInfo> ilist = new ArrayList<DSSIInfo>();
140     for (int i = 0; i < sofiles.length; i++)
examineLibrary(new File(dssidir, sofiles[i]).getAbsolutePath())141       ilist.addAll(examineLibrary(new File(dssidir, sofiles[i]).getAbsolutePath()));
142     infos = ilist.toArray(new DSSIInfo[ilist.size()]);
143   }
144 
DSSIMidiDeviceProvider()145   public DSSIMidiDeviceProvider()
146   {
147     // Empty.
148   }
149 
150   /* Return the Info array.
151    * @see javax.sound.midi.spi.MidiDeviceProvider#getDeviceInfo()
152    */
getDeviceInfo()153   public Info[] getDeviceInfo()
154   {
155     return infos;
156   }
157 
158   /* Get a MIDI Device for info.
159    * @see javax.sound.midi.spi.MidiDeviceProvider#getDevice(javax.sound.midi.MidiDevice.Info)
160    */
getDevice(Info info)161   public MidiDevice getDevice(Info info)
162   {
163     for (int i = 0; i < infos.length; i++)
164     {
165       if (info.equals(infos[i]))
166       {
167           return new DSSISynthesizer(infos[i],
168                                      infos[i].soname,
169                                      infos[i].index);
170       }
171     }
172     throw new IllegalArgumentException("Don't recognize MIDI device " + info);
173   }
174 }
175