1 /* DSSISynthesizer.java -- DSSI Synthesizer Provider
2 Copyright (C) 2005, 2006, 2012 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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)
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.
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
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
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. */
39 package gnu
.javax
.sound
.midi
.dssi
;
41 import java
.util
.ArrayList
;
42 import java
.util
.Iterator
;
43 import java
.util
.List
;
45 import javax
.sound
.midi
.Instrument
;
46 import javax
.sound
.midi
.MidiChannel
;
47 import javax
.sound
.midi
.MidiMessage
;
48 import javax
.sound
.midi
.MidiUnavailableException
;
49 import javax
.sound
.midi
.Patch
;
50 import javax
.sound
.midi
.Receiver
;
51 import javax
.sound
.midi
.ShortMessage
;
52 import javax
.sound
.midi
.Soundbank
;
53 import javax
.sound
.midi
.SoundbankResource
;
54 import javax
.sound
.midi
.Synthesizer
;
55 import javax
.sound
.midi
.Transmitter
;
56 import javax
.sound
.midi
.VoiceStatus
;
59 * DSSI soft-synth support.
61 * All DSSI soft-synths are expected to be installed in /usr/lib/dssi.
63 * @author Anthony Green (green@redhat.com)
66 public class DSSISynthesizer
implements Synthesizer
69 * The DSSI Instrument class.
71 * @author Anthony Green (green@redhat.com)
74 class DSSIInstrument
extends Instrument
76 DSSIInstrument (Soundbank soundbank
, Patch patch
, String name
)
78 super (soundbank
, patch
, name
, null);
81 /* @see javax.sound.midi.SoundbankResource#getData()
83 public Object
getData()
91 * DSSISoundbank holds all instruments.
93 * @author Anthony Green (green@redhat.com)
96 class DSSISoundbank
implements Soundbank
99 private String description
;
100 private List
<Instrument
> instruments
= new ArrayList
<Instrument
>();
101 private List
<SoundbankResource
> resources
= new ArrayList
<SoundbankResource
>();
102 private String vendor
;
103 private String version
;
105 public DSSISoundbank(String name
, String description
, String vendor
, String version
)
108 this.description
= description
;
109 this.vendor
= vendor
;
110 this.version
= version
;
113 void add(Instrument instrument
)
115 instruments
.add(instrument
);
118 /* @see javax.sound.midi.Soundbank#getName()
120 public String
getName()
125 /* @see javax.sound.midi.Soundbank#getVersion()
127 public String
getVersion()
132 /* @see javax.sound.midi.Soundbank#getVendor()
134 public String
getVendor()
139 /* @see javax.sound.midi.Soundbank#getDescription()
141 public String
getDescription()
146 /* @see javax.sound.midi.Soundbank#getResources()
148 public SoundbankResource
[] getResources()
150 return resources
.toArray(new SoundbankResource
[resources
.size()]);
153 /* @see javax.sound.midi.Soundbank#getInstruments()
155 public Instrument
[] getInstruments()
157 return instruments
.toArray(new Instrument
[instruments
.size()]);
160 /* @see javax.sound.midi.Soundbank#getInstrument(javax.sound.midi.Patch)
162 public Instrument
getInstrument(Patch patch
)
164 Iterator
<Instrument
> itr
= instruments
.iterator();
166 while (itr
.hasNext())
168 Instrument i
= itr
.next();
169 if (i
.getPatch().equals(patch
))
178 * The Receiver class receives all MIDI messages from a connected
181 * @author Anthony Green (green@redhat.com)
184 class DSSIReceiver
implements Receiver
187 * @see javax.sound.midi.Receiver#send(javax.sound.midi.MidiMessage, long)
189 public void send(MidiMessage message
, long timeStamp
)
190 throws IllegalStateException
192 if (message
instanceof ShortMessage
)
194 ShortMessage smessage
= (ShortMessage
) message
;
196 switch (message
.getStatus())
198 case ShortMessage
.NOTE_ON
:
199 int velocity
= smessage
.getData2();
201 channels
[smessage
.getChannel()].noteOn(smessage
.getData1(),
202 smessage
.getData2());
204 channels
[smessage
.getChannel()].noteOff(smessage
.getData1());
206 case ShortMessage
.CONTROL_CHANGE
:
207 channels
[smessage
.getChannel()].controlChange(smessage
.getData1(),
208 smessage
.getData2());
211 System
.out
.println ("Unhandled message: " + message
.getStatus());
218 * @see javax.sound.midi.Receiver#close()
222 // TODO Auto-generated method stub
227 static native void noteOn_(long handle
, int channel
, int noteNumber
, int velocity
);
228 static native void noteOff_(long handle
, int channel
, int noteNumber
, int velocity
);
229 static native void setPolyPressure_(long handle
, int channel
, int noteNumber
, int pressure
);
230 static native int getPolyPressure_(long handle
, int channel
, int noteNumber
);
231 static native void controlChange_(long handle
, int channel
, int control
, int value
);
232 static native void open_(long handle
);
233 static native void close_(long handle
);
234 static native String
getProgramName_(long handle
, int index
);
235 static native int getProgramBank_(long handle
, int index
);
236 static native int getProgramProgram_(long handle
, int index
);
237 static native void selectProgram_(long handle
, int bank
, int program
);
240 * @author Anthony Green (green@redhat.com)
243 public class DSSIMidiChannel
implements MidiChannel
248 * Default contructor.
250 public DSSIMidiChannel(int channel
)
253 this.channel
= channel
;
257 * @see javax.sound.midi.MidiChannel#noteOn(int, int)
259 public void noteOn(int noteNumber
, int velocity
)
261 noteOn_(sohandle
, channel
, noteNumber
, velocity
);
265 * @see javax.sound.midi.MidiChannel#noteOff(int, int)
267 public void noteOff(int noteNumber
, int velocity
)
269 noteOff_(sohandle
, channel
, noteNumber
, velocity
);
273 * @see javax.sound.midi.MidiChannel#noteOff(int)
275 public void noteOff(int noteNumber
)
277 noteOff_(sohandle
, channel
, noteNumber
, -1);
281 * @see javax.sound.midi.MidiChannel#setPolyPressure(int, int)
283 public void setPolyPressure(int noteNumber
, int pressure
)
285 setPolyPressure_(sohandle
, channel
, noteNumber
, pressure
);
289 * @see javax.sound.midi.MidiChannel#getPolyPressure(int)
291 public int getPolyPressure(int noteNumber
)
293 return getPolyPressure_(sohandle
, channel
, noteNumber
);
297 * @see javax.sound.midi.MidiChannel#setChannelPressure(int)
299 public void setChannelPressure(int pressure
)
301 // TODO Auto-generated method stub
306 * @see javax.sound.midi.MidiChannel#getChannelPressure()
308 public int getChannelPressure()
310 // TODO Auto-generated method stub
314 /* @see javax.sound.midi.MidiChannel#controlChange(int, int) */
315 public void controlChange(int controller
, int value
)
317 controlChange_(sohandle
, channel
, controller
, value
);
321 * @see javax.sound.midi.MidiChannel#getController(int)
323 public int getController(int controller
)
325 // TODO Auto-generated method stub
330 * @see javax.sound.midi.MidiChannel#programChange(int)
332 public void programChange(int program
)
334 // TODO Auto-generated method stub
339 * @see javax.sound.midi.MidiChannel#programChange(int, int)
341 public void programChange(int bank
, int program
)
343 // TODO Auto-generated method stub
348 * @see javax.sound.midi.MidiChannel#getProgram()
350 public int getProgram()
352 // TODO Auto-generated method stub
357 * @see javax.sound.midi.MidiChannel#setPitchBend(int)
359 public void setPitchBend(int bend
)
361 // TODO Auto-generated method stub
366 * @see javax.sound.midi.MidiChannel#getPitchBend()
368 public int getPitchBend()
370 // TODO Auto-generated method stub
375 * @see javax.sound.midi.MidiChannel#resetAllControllers()
377 public void resetAllControllers()
379 // TODO Auto-generated method stub
384 * @see javax.sound.midi.MidiChannel#allNotesOff()
386 public void allNotesOff()
388 // TODO Auto-generated method stub
393 * @see javax.sound.midi.MidiChannel#allSoundOff()
395 public void allSoundOff()
397 // TODO Auto-generated method stub
402 * @see javax.sound.midi.MidiChannel#localControl(boolean)
404 public boolean localControl(boolean on
)
406 // TODO Auto-generated method stub
411 * @see javax.sound.midi.MidiChannel#setMono(boolean)
413 public void setMono(boolean on
)
415 // TODO Auto-generated method stub
420 * @see javax.sound.midi.MidiChannel#getMono()
422 public boolean getMono()
424 // TODO Auto-generated method stub
429 * @see javax.sound.midi.MidiChannel#setOmni(boolean)
431 public void setOmni(boolean on
)
433 // TODO Auto-generated method stub
438 * @see javax.sound.midi.MidiChannel#getOmni()
440 public boolean getOmni()
442 // TODO Auto-generated method stub
447 * @see javax.sound.midi.MidiChannel#setMute(boolean)
449 public void setMute(boolean mute
)
451 // TODO Auto-generated method stub
456 * @see javax.sound.midi.MidiChannel#getMute()
458 public boolean getMute()
460 // TODO Auto-generated method stub
465 * @see javax.sound.midi.MidiChannel#setSolo(boolean)
467 public void setSolo(boolean solo
)
469 // TODO Auto-generated method stub
474 * @see javax.sound.midi.MidiChannel#getSolo()
476 public boolean getSolo()
478 // TODO Auto-generated method stub
488 MidiChannel channels
[] = new MidiChannel
[16];
490 // The list of known soundbanks, and the default one.
491 List
<Soundbank
> soundbanks
= new ArrayList
<Soundbank
>();
492 DSSISoundbank defaultSoundbank
;
495 * Create a DSSI Synthesizer.
497 * @param info the DSSIInfo for this soft-synth
498 * @param soname the name of the .so file for this DSSI synth
499 * @param index the DSSI index for this soft-synth
501 public DSSISynthesizer(Info info
, String soname
, long index
)
505 sohandle
= DSSIMidiDeviceProvider
.dlopen_(soname
);
506 handle
= DSSIMidiDeviceProvider
.getDSSIHandle_(sohandle
, index
);
507 channels
[0] = new DSSIMidiChannel(0);
508 defaultSoundbank
= new DSSISoundbank("name", "description",
509 "vendor", "version");
510 soundbanks
.add(defaultSoundbank
);
516 name
= getProgramName_(sohandle
, i
);
520 add(new DSSIInstrument(defaultSoundbank
,
521 new Patch(getProgramBank_(sohandle
, i
),
522 getProgramProgram_(sohandle
, i
)),
526 } while (name
!= null);
530 * @see javax.sound.midi.Synthesizer#getMaxPolyphony()
532 public int getMaxPolyphony()
534 // TODO Auto-generated method stub
539 * @see javax.sound.midi.Synthesizer#getLatency()
541 public long getLatency()
543 // DSSI and LADSPA provide no way to determine the latency.
544 // Let's just return 0 for now.
549 * @see javax.sound.midi.Synthesizer#getChannels()
551 public MidiChannel
[] getChannels()
557 * @see javax.sound.midi.Synthesizer#getVoiceStatus()
559 public VoiceStatus
[] getVoiceStatus()
561 // TODO Auto-generated method stub
566 * @see javax.sound.midi.Synthesizer#isSoundbankSupported(javax.sound.midi.Soundbank)
568 public boolean isSoundbankSupported(Soundbank soundbank
)
570 // TODO Auto-generated method stub
574 /* @see javax.sound.midi.Synthesizer#loadInstrument(javax.sound.midi.Instrument)
576 public boolean loadInstrument(Instrument instrument
)
578 // FIXME: perhaps this isn't quite right. It can probably
579 // be in any soundbank.
580 if (instrument
.getSoundbank() != defaultSoundbank
)
581 throw new IllegalArgumentException ("Synthesizer doesn't support this instrument's soundbank");
583 Patch patch
= instrument
.getPatch();
584 selectProgram_(sohandle
, patch
.getBank(), patch
.getProgram());
589 * @see javax.sound.midi.Synthesizer#unloadInstrument(javax.sound.midi.Instrument)
591 public void unloadInstrument(Instrument instrument
)
593 // TODO Auto-generated method stub
598 * @see javax.sound.midi.Synthesizer#remapInstrument(javax.sound.midi.Instrument, javax.sound.midi.Instrument)
600 public boolean remapInstrument(Instrument from
, Instrument to
)
602 // TODO Auto-generated method stub
606 /* @see javax.sound.midi.Synthesizer#getDefaultSoundbank()
608 public Soundbank
getDefaultSoundbank()
610 return defaultSoundbank
;
613 /* @see javax.sound.midi.Synthesizer#getAvailableInstruments()
615 public Instrument
[] getAvailableInstruments()
617 List
<Instrument
> instruments
= new ArrayList
<Instrument
>();
618 Iterator
<Soundbank
> itr
= soundbanks
.iterator();
619 while (itr
.hasNext())
621 Soundbank sb
= itr
.next();
622 Instrument ins
[] = sb
.getInstruments();
623 for (int i
= 0; i
< ins
.length
; i
++)
624 instruments
.add(ins
[i
]);
626 return instruments
.toArray(new Instrument
[instruments
.size()]);
630 * @see javax.sound.midi.Synthesizer#getLoadedInstruments()
632 public Instrument
[] getLoadedInstruments()
634 // TODO Auto-generated method stub
639 * @see javax.sound.midi.Synthesizer#loadAllInstruments(javax.sound.midi.Soundbank)
641 public boolean loadAllInstruments(Soundbank soundbank
)
643 // TODO Auto-generated method stub
648 * @see javax.sound.midi.Synthesizer#unloadAllInstruments(javax.sound.midi.Soundbank)
650 public void unloadAllInstruments(Soundbank soundbank
)
652 // TODO Auto-generated method stub
656 * @see javax.sound.midi.Synthesizer#loadInstruments(javax.sound.midi.Soundbank, javax.sound.midi.Patch[])
658 public boolean loadInstruments(Soundbank soundbank
, Patch
[] patchList
)
660 // TODO Auto-generated method stub
665 * @see javax.sound.midi.Synthesizer#unloadInstruments(javax.sound.midi.Soundbank, javax.sound.midi.Patch[])
667 public void unloadInstruments(Soundbank soundbank
, Patch
[] patchList
)
669 // TODO Auto-generated method stub
673 /* @see javax.sound.midi.MidiDevice#getDeviceInfo()
675 public Info
getDeviceInfo()
680 /* @see javax.sound.midi.MidiDevice#open()
682 public void open() throws MidiUnavailableException
687 /* @see javax.sound.midi.MidiDevice#close()
695 * @see javax.sound.midi.MidiDevice#isOpen()
697 public boolean isOpen()
699 // TODO Auto-generated method stub
704 * @see javax.sound.midi.MidiDevice#getMicrosecondPosition()
706 public long getMicrosecondPosition()
708 // TODO Auto-generated method stub
712 /* @see javax.sound.midi.MidiDevice#getMaxReceivers()
714 public int getMaxReceivers()
719 /* @see javax.sound.midi.MidiDevice#getMaxTransmitters()
721 public int getMaxTransmitters()
726 /* @see javax.sound.midi.MidiDevice#getReceiver()
728 public Receiver
getReceiver() throws MidiUnavailableException
730 return new DSSIReceiver();
733 /* @see javax.sound.midi.MidiDevice#getTransmitter()
735 public Transmitter
getTransmitter() throws MidiUnavailableException