1 /* DSSISynthesizer.java -- DSSI Synthesizer Provider
2 Copyright (C) 2005 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
;
58 // FIXME: This import in only required for gcj it seems.
59 import javax
.sound
.midi
.MidiDevice
.Info
;
62 * DSSI soft-synth support.
64 * All DSSI soft-synths are expected to be installed in /usr/lib/dssi.
66 * @author Anthony Green (green@redhat.com)
69 public class DSSISynthesizer
implements Synthesizer
72 * The DSSI Instrument class.
74 * @author Anthony Green (green@redhat.com)
77 class DSSIInstrument
extends Instrument
79 DSSIInstrument (Soundbank soundbank
, Patch patch
, String name
)
81 super (soundbank
, patch
, name
, null);
84 /* @see javax.sound.midi.SoundbankResource#getData()
86 public Object
getData()
94 * DSSISoundbank holds all instruments.
96 * @author Anthony Green (green@redhat.com)
99 class DSSISoundbank
implements Soundbank
102 private String description
;
103 private List instruments
= new ArrayList();
104 private List resources
= new ArrayList();
105 private String vendor
;
106 private String version
;
108 public DSSISoundbank(String name
, String description
, String vendor
, String version
)
111 this.description
= description
;
112 this.vendor
= vendor
;
113 this.version
= version
;
116 void add(Instrument instrument
)
118 instruments
.add(instrument
);
121 /* @see javax.sound.midi.Soundbank#getName()
123 public String
getName()
128 /* @see javax.sound.midi.Soundbank#getVersion()
130 public String
getVersion()
135 /* @see javax.sound.midi.Soundbank#getVendor()
137 public String
getVendor()
142 /* @see javax.sound.midi.Soundbank#getDescription()
144 public String
getDescription()
149 /* @see javax.sound.midi.Soundbank#getResources()
151 public SoundbankResource
[] getResources()
153 return (SoundbankResource
[])
154 resources
.toArray(new SoundbankResource
[resources
.size()]);
157 /* @see javax.sound.midi.Soundbank#getInstruments()
159 public Instrument
[] getInstruments()
161 return (Instrument
[])
162 instruments
.toArray(new Instrument
[instruments
.size()]);
165 /* @see javax.sound.midi.Soundbank#getInstrument(javax.sound.midi.Patch)
167 public Instrument
getInstrument(Patch patch
)
169 Iterator itr
= instruments
.iterator();
171 while (itr
.hasNext())
173 Instrument i
= (Instrument
) itr
.next();
174 if (i
.getPatch().equals(patch
))
183 * The Receiver class receives all MIDI messages from a connected
186 * @author Anthony Green (green@redhat.com)
189 class DSSIReceiver
implements Receiver
192 * @see javax.sound.midi.Receiver#send(javax.sound.midi.MidiMessage, long)
194 public void send(MidiMessage message
, long timeStamp
)
195 throws IllegalStateException
197 if (message
instanceof ShortMessage
)
199 ShortMessage smessage
= (ShortMessage
) message
;
201 switch (message
.getStatus())
203 case ShortMessage
.NOTE_ON
:
204 int velocity
= smessage
.getData2();
206 channels
[smessage
.getChannel()].noteOn(smessage
.getData1(),
207 smessage
.getData2());
209 channels
[smessage
.getChannel()].noteOff(smessage
.getData1());
211 case ShortMessage
.CONTROL_CHANGE
:
212 channels
[smessage
.getChannel()].controlChange(smessage
.getData1(),
213 smessage
.getData2());
216 System
.out
.println ("Unhandled message: " + message
.getStatus());
223 * @see javax.sound.midi.Receiver#close()
227 // TODO Auto-generated method stub
232 static native void noteOn_(long handle
, int channel
, int noteNumber
, int velocity
);
233 static native void noteOff_(long handle
, int channel
, int noteNumber
, int velocity
);
234 static native void setPolyPressure_(long handle
, int channel
, int noteNumber
, int pressure
);
235 static native int getPolyPressure_(long handle
, int channel
, int noteNumber
);
236 static native void controlChange_(long handle
, int channel
, int control
, int value
);
237 static native void open_(long handle
);
238 static native void close_(long handle
);
239 static native String
getProgramName_(long handle
, int index
);
240 static native int getProgramBank_(long handle
, int index
);
241 static native int getProgramProgram_(long handle
, int index
);
242 static native void selectProgram_(long handle
, int bank
, int program
);
245 * @author Anthony Green (green@redhat.com)
248 public class DSSIMidiChannel
implements MidiChannel
253 * Default contructor.
255 public DSSIMidiChannel(int channel
)
258 this.channel
= channel
;
262 * @see javax.sound.midi.MidiChannel#noteOn(int, int)
264 public void noteOn(int noteNumber
, int velocity
)
266 noteOn_(sohandle
, channel
, noteNumber
, velocity
);
270 * @see javax.sound.midi.MidiChannel#noteOff(int, int)
272 public void noteOff(int noteNumber
, int velocity
)
274 noteOff_(sohandle
, channel
, noteNumber
, velocity
);
278 * @see javax.sound.midi.MidiChannel#noteOff(int)
280 public void noteOff(int noteNumber
)
282 noteOff_(sohandle
, channel
, noteNumber
, -1);
286 * @see javax.sound.midi.MidiChannel#setPolyPressure(int, int)
288 public void setPolyPressure(int noteNumber
, int pressure
)
290 setPolyPressure_(sohandle
, channel
, noteNumber
, pressure
);
294 * @see javax.sound.midi.MidiChannel#getPolyPressure(int)
296 public int getPolyPressure(int noteNumber
)
298 return getPolyPressure_(sohandle
, channel
, noteNumber
);
302 * @see javax.sound.midi.MidiChannel#setChannelPressure(int)
304 public void setChannelPressure(int pressure
)
306 // TODO Auto-generated method stub
311 * @see javax.sound.midi.MidiChannel#getChannelPressure()
313 public int getChannelPressure()
315 // TODO Auto-generated method stub
319 /* @see javax.sound.midi.MidiChannel#controlChange(int, int) */
320 public void controlChange(int controller
, int value
)
322 controlChange_(sohandle
, channel
, controller
, value
);
326 * @see javax.sound.midi.MidiChannel#getController(int)
328 public int getController(int controller
)
330 // TODO Auto-generated method stub
335 * @see javax.sound.midi.MidiChannel#programChange(int)
337 public void programChange(int program
)
339 // TODO Auto-generated method stub
344 * @see javax.sound.midi.MidiChannel#programChange(int, int)
346 public void programChange(int bank
, int program
)
348 // TODO Auto-generated method stub
353 * @see javax.sound.midi.MidiChannel#getProgram()
355 public int getProgram()
357 // TODO Auto-generated method stub
362 * @see javax.sound.midi.MidiChannel#setPitchBend(int)
364 public void setPitchBend(int bend
)
366 // TODO Auto-generated method stub
371 * @see javax.sound.midi.MidiChannel#getPitchBend()
373 public int getPitchBend()
375 // TODO Auto-generated method stub
380 * @see javax.sound.midi.MidiChannel#resetAllControllers()
382 public void resetAllControllers()
384 // TODO Auto-generated method stub
389 * @see javax.sound.midi.MidiChannel#allNotesOff()
391 public void allNotesOff()
393 // TODO Auto-generated method stub
398 * @see javax.sound.midi.MidiChannel#allSoundOff()
400 public void allSoundOff()
402 // TODO Auto-generated method stub
407 * @see javax.sound.midi.MidiChannel#localControl(boolean)
409 public boolean localControl(boolean on
)
411 // TODO Auto-generated method stub
416 * @see javax.sound.midi.MidiChannel#setMono(boolean)
418 public void setMono(boolean on
)
420 // TODO Auto-generated method stub
425 * @see javax.sound.midi.MidiChannel#getMono()
427 public boolean getMono()
429 // TODO Auto-generated method stub
434 * @see javax.sound.midi.MidiChannel#setOmni(boolean)
436 public void setOmni(boolean on
)
438 // TODO Auto-generated method stub
443 * @see javax.sound.midi.MidiChannel#getOmni()
445 public boolean getOmni()
447 // TODO Auto-generated method stub
452 * @see javax.sound.midi.MidiChannel#setMute(boolean)
454 public void setMute(boolean mute
)
456 // TODO Auto-generated method stub
461 * @see javax.sound.midi.MidiChannel#getMute()
463 public boolean getMute()
465 // TODO Auto-generated method stub
470 * @see javax.sound.midi.MidiChannel#setSolo(boolean)
472 public void setSolo(boolean solo
)
474 // TODO Auto-generated method stub
479 * @see javax.sound.midi.MidiChannel#getSolo()
481 public boolean getSolo()
483 // TODO Auto-generated method stub
493 MidiChannel channels
[] = new MidiChannel
[16];
495 // The list of known soundbanks, and the default one.
496 List soundbanks
= new ArrayList();
497 DSSISoundbank defaultSoundbank
;
500 * Create a DSSI Synthesizer.
502 * @param info the DSSIInfo for this soft-synth
503 * @param soname the name of the .so file for this DSSI synth
504 * @param index the DSSI index for this soft-synth
506 public DSSISynthesizer(Info info
, String soname
, long index
)
510 sohandle
= DSSIMidiDeviceProvider
.dlopen_(soname
);
511 handle
= DSSIMidiDeviceProvider
.getDSSIHandle_(sohandle
, index
);
512 channels
[0] = new DSSIMidiChannel(0);
513 defaultSoundbank
= new DSSISoundbank("name", "description",
514 "vendor", "version");
515 soundbanks
.add(defaultSoundbank
);
521 name
= getProgramName_(sohandle
, i
);
525 add(new DSSIInstrument(defaultSoundbank
,
526 new Patch(getProgramBank_(sohandle
, i
),
527 getProgramProgram_(sohandle
, i
)),
531 } while (name
!= null);
535 * @see javax.sound.midi.Synthesizer#getMaxPolyphony()
537 public int getMaxPolyphony()
539 // TODO Auto-generated method stub
544 * @see javax.sound.midi.Synthesizer#getLatency()
546 public long getLatency()
548 // DSSI and LADSPA provide no way to determine the latency.
549 // Let's just return 0 for now.
554 * @see javax.sound.midi.Synthesizer#getChannels()
556 public MidiChannel
[] getChannels()
562 * @see javax.sound.midi.Synthesizer#getVoiceStatus()
564 public VoiceStatus
[] getVoiceStatus()
566 // TODO Auto-generated method stub
571 * @see javax.sound.midi.Synthesizer#isSoundbankSupported(javax.sound.midi.Soundbank)
573 public boolean isSoundbankSupported(Soundbank soundbank
)
575 // TODO Auto-generated method stub
579 /* @see javax.sound.midi.Synthesizer#loadInstrument(javax.sound.midi.Instrument)
581 public boolean loadInstrument(Instrument instrument
)
583 // FIXME: perhaps this isn't quite right. It can probably
584 // be in any soundbank.
585 if (instrument
.getSoundbank() != defaultSoundbank
)
586 throw new IllegalArgumentException ("Synthesizer doesn't support this instrument's soundbank");
588 Patch patch
= instrument
.getPatch();
589 selectProgram_(sohandle
, patch
.getBank(), patch
.getProgram());
594 * @see javax.sound.midi.Synthesizer#unloadInstrument(javax.sound.midi.Instrument)
596 public void unloadInstrument(Instrument instrument
)
598 // TODO Auto-generated method stub
603 * @see javax.sound.midi.Synthesizer#remapInstrument(javax.sound.midi.Instrument, javax.sound.midi.Instrument)
605 public boolean remapInstrument(Instrument from
, Instrument to
)
607 // TODO Auto-generated method stub
611 /* @see javax.sound.midi.Synthesizer#getDefaultSoundbank()
613 public Soundbank
getDefaultSoundbank()
615 return defaultSoundbank
;
618 /* @see javax.sound.midi.Synthesizer#getAvailableInstruments()
620 public Instrument
[] getAvailableInstruments()
622 List instruments
= new ArrayList();
623 Iterator itr
= soundbanks
.iterator();
624 while (itr
.hasNext())
626 Soundbank sb
= (Soundbank
) itr
.next();
627 Instrument ins
[] = sb
.getInstruments();
628 for (int i
= 0; i
< ins
.length
; i
++)
629 instruments
.add(ins
[i
]);
631 return (Instrument
[])
632 instruments
.toArray(new Instrument
[instruments
.size()]);
636 * @see javax.sound.midi.Synthesizer#getLoadedInstruments()
638 public Instrument
[] getLoadedInstruments()
640 // TODO Auto-generated method stub
645 * @see javax.sound.midi.Synthesizer#loadAllInstruments(javax.sound.midi.Soundbank)
647 public boolean loadAllInstruments(Soundbank soundbank
)
649 // TODO Auto-generated method stub
654 * @see javax.sound.midi.Synthesizer#unloadAllInstruments(javax.sound.midi.Soundbank)
656 public void unloadAllInstruments(Soundbank soundbank
)
658 // TODO Auto-generated method stub
662 * @see javax.sound.midi.Synthesizer#loadInstruments(javax.sound.midi.Soundbank, javax.sound.midi.Patch[])
664 public boolean loadInstruments(Soundbank soundbank
, Patch
[] patchList
)
666 // TODO Auto-generated method stub
671 * @see javax.sound.midi.Synthesizer#unloadInstruments(javax.sound.midi.Soundbank, javax.sound.midi.Patch[])
673 public void unloadInstruments(Soundbank soundbank
, Patch
[] patchList
)
675 // TODO Auto-generated method stub
679 /* @see javax.sound.midi.MidiDevice#getDeviceInfo()
681 public Info
getDeviceInfo()
686 /* @see javax.sound.midi.MidiDevice#open()
688 public void open() throws MidiUnavailableException
693 /* @see javax.sound.midi.MidiDevice#close()
701 * @see javax.sound.midi.MidiDevice#isOpen()
703 public boolean isOpen()
705 // TODO Auto-generated method stub
710 * @see javax.sound.midi.MidiDevice#getMicrosecondPosition()
712 public long getMicrosecondPosition()
714 // TODO Auto-generated method stub
718 /* @see javax.sound.midi.MidiDevice#getMaxReceivers()
720 public int getMaxReceivers()
725 /* @see javax.sound.midi.MidiDevice#getMaxTransmitters()
727 public int getMaxTransmitters()
732 /* @see javax.sound.midi.MidiDevice#getReceiver()
734 public Receiver
getReceiver() throws MidiUnavailableException
736 return new DSSIReceiver();
739 /* @see javax.sound.midi.MidiDevice#getTransmitter()
741 public Transmitter
getTransmitter() throws MidiUnavailableException