1 /*
2  * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package javax.sound.midi;
27 
28 import javax.sound.sampled.Control;
29 
30 
31 /**
32  * A <code>Synthesizer</code> generates sound.  This usually happens when one of
33  * the <code>Synthesizer</code>'s {@link MidiChannel} objects receives a
34  * {@link MidiChannel#noteOn(int, int) noteOn} message, either
35  * directly or via the <code>Synthesizer</code> object.
36  * Many <code>Synthesizer</code>s support <code>Receivers</code>, through which
37  * MIDI events can be delivered to the <code>Synthesizer</code>.
38  * In such cases, the <code>Synthesizer</code> typically responds by sending
39  * a corresponding message to the appropriate <code>MidiChannel</code>, or by
40  * processing the event itself if the event isn't one of the MIDI channel
41  * messages.
42  * <p>
43  * The <code>Synthesizer</code> interface includes methods for loading and
44  * unloading instruments from soundbanks.  An instrument is a specification for synthesizing a
45  * certain type of sound, whether that sound emulates a traditional instrument or is
46  * some kind of sound effect or other imaginary sound. A soundbank is a collection of instruments, organized
47  * by bank and program number (via the instrument's <code>Patch</code> object).
48  * Different <code>Synthesizer</code> classes might implement different sound-synthesis
49  * techniques, meaning that some instruments and not others might be compatible with a
50  * given synthesizer.
51  * Also, synthesizers may have a limited amount of memory for instruments, meaning
52  * that not every soundbank and instrument can be used by every synthesizer, even if
53  * the synthesis technique is compatible.
54  * To see whether the instruments from
55  * a certain soundbank can be played by a given synthesizer, invoke the
56  * {@link #isSoundbankSupported(Soundbank) isSoundbankSupported} method of
57  * <code>Synthesizer</code>.
58  * <p>
59  * "Loading" an instrument means that that instrument becomes available for
60  * synthesizing notes.  The instrument is loaded into the bank and
61  * program location specified by its <code>Patch</code> object.  Loading does
62  * not necessarily mean that subsequently played notes will immediately have
63  * the sound of this newly loaded instrument.  For the instrument to play notes,
64  * one of the synthesizer's <code>MidiChannel</code> objects must receive (or have received)
65  * a program-change message that causes that particular instrument's
66  * bank and program number to be selected.
67  *
68  * @see MidiSystem#getSynthesizer
69  * @see Soundbank
70  * @see Instrument
71  * @see MidiChannel#programChange(int, int)
72  * @see Receiver
73  * @see Transmitter
74  * @see MidiDevice
75  *
76  * @author Kara Kytle
77  */
78 public interface Synthesizer extends MidiDevice {
79 
80 
81     // SYNTHESIZER METHODS
82 
83 
84     /**
85      * Obtains the maximum number of notes that this synthesizer can sound simultaneously.
86      * @return the maximum number of simultaneous notes
87      * @see #getVoiceStatus
88      */
getMaxPolyphony()89     public int getMaxPolyphony();
90 
91 
92     /**
93      * Obtains the processing latency incurred by this synthesizer, expressed in
94      * microseconds.  This latency measures the worst-case delay between the
95      * time a MIDI message is delivered to the synthesizer and the time that the
96      * synthesizer actually produces the corresponding result.
97      * <p>
98      * Although the latency is expressed in microseconds, a synthesizer's actual measured
99      * delay may vary over a wider range than this resolution suggests.  For example,
100      * a synthesizer might have a worst-case delay of a few milliseconds or more.
101      *
102      * @return the worst-case delay, in microseconds
103      */
getLatency()104     public long getLatency();
105 
106 
107     /**
108      * Obtains the set of MIDI channels controlled by this synthesizer.  Each
109      * non-null element in the returned array is a <code>MidiChannel</code> that
110      * receives the MIDI messages sent on that channel number.
111      * <p>
112      * The MIDI 1.0 specification provides for 16 channels, so this
113      * method returns an array of at least 16 elements.  However, if this synthesizer
114      * doesn't make use of all 16 channels, some of the elements of the array
115      * might be <code>null</code>, so you should check each element
116      * before using it.
117      * @return an array of the <code>MidiChannel</code> objects managed by this
118      * <code>Synthesizer</code>.  Some of the array elements may be <code>null</code>.
119      */
getChannels()120     public MidiChannel[] getChannels();
121 
122 
123     /**
124      * Obtains the current status of the voices produced by this synthesizer.
125      * If this class of <code>Synthesizer</code> does not provide voice
126      * information, the returned array will always be of length 0.  Otherwise,
127      * its length is always equal to the total number of voices, as returned by
128      * <code>getMaxPolyphony()</code>.  (See the <code>VoiceStatus</code> class
129      * description for an explanation of synthesizer voices.)
130      *
131      * @return an array of <code>VoiceStatus</code> objects that supply
132      * information about the corresponding synthesizer voices
133      * @see #getMaxPolyphony
134      * @see VoiceStatus
135      */
getVoiceStatus()136     public VoiceStatus[] getVoiceStatus();
137 
138 
139     /**
140      * Informs the caller whether this synthesizer is capable of loading
141      * instruments from the specified soundbank.
142      * If the soundbank is unsupported, any attempts to load instruments from
143      * it will result in an <code>IllegalArgumentException</code>.
144      * @param soundbank soundbank for which support is queried
145      * @return <code>true</code> if the soundbank is supported, otherwise <code>false</code>
146      * @see #loadInstruments
147      * @see #loadAllInstruments
148      * @see #unloadInstruments
149      * @see #unloadAllInstruments
150      * @see #getDefaultSoundbank
151      */
isSoundbankSupported(Soundbank soundbank)152     public boolean isSoundbankSupported(Soundbank soundbank);
153 
154 
155     /**
156      * Makes a particular instrument available for synthesis.  This instrument
157      * is loaded into the patch location specified by its <code>Patch</code>
158      * object, so that if a program-change message is
159      * received (or has been received) that causes that patch to be selected,
160      * subsequent notes will be played using the sound of
161      * <code>instrument</code>.  If the specified instrument is already loaded,
162      * this method does nothing and returns <code>true</code>.
163      * <p>
164      * The instrument must be part of a soundbank
165      * that this <code>Synthesizer</code> supports.  (To make sure, you can use
166      * the <code>getSoundbank</code> method of <code>Instrument</code> and the
167      * <code>isSoundbankSupported</code> method of <code>Synthesizer</code>.)
168      * @param instrument instrument to load
169      * @return <code>true</code> if the instrument is successfully loaded (or
170      * already had been), <code>false</code> if the instrument could not be
171      * loaded (for example, if the synthesizer has insufficient
172      * memory to load it)
173      * @throws IllegalArgumentException if this
174      * <code>Synthesizer</code> doesn't support the specified instrument's
175      * soundbank
176      * @see #unloadInstrument
177      * @see #loadInstruments
178      * @see #loadAllInstruments
179      * @see #remapInstrument
180      * @see SoundbankResource#getSoundbank
181      * @see MidiChannel#programChange(int, int)
182      */
loadInstrument(Instrument instrument)183     public boolean loadInstrument(Instrument instrument);
184 
185 
186     /**
187      * Unloads a particular instrument.
188      * @param instrument instrument to unload
189      * @throws IllegalArgumentException if this
190      * <code>Synthesizer</code> doesn't support the specified instrument's
191      * soundbank
192      * @see #loadInstrument
193      * @see #unloadInstruments
194      * @see #unloadAllInstruments
195      * @see #getLoadedInstruments
196      * @see #remapInstrument
197      */
unloadInstrument(Instrument instrument)198     public void unloadInstrument(Instrument instrument);
199 
200 
201     /**
202      * Remaps an instrument. Instrument <code>to</code> takes the
203      * place of instrument <code>from</code>.<br>
204      * For example, if <code>from</code> was located at bank number 2,
205      * program number 11, remapping causes that bank and program location
206      * to be occupied instead by <code>to</code>.<br>
207      * If the function succeeds,  instrument <code>from</code> is unloaded.
208      * <p>To cancel the remapping reload instrument <code>from</code> by
209      * invoking one of {@link #loadInstrument}, {@link #loadInstruments}
210      * or {@link #loadAllInstruments}.
211      *
212      * @param from the <code>Instrument</code> object to be replaced
213      * @param to the <code>Instrument</code> object to be used in place
214      * of the old instrument, it should be loaded into the synthesizer
215      * @return <code>true</code> if the instrument successfully remapped,
216      * <code>false</code> if feature is not implemented by synthesizer
217      * @throws IllegalArgumentException if instrument
218      * <code>from</code> or instrument <code>to</code> aren't supported by
219      * synthesizer or if instrument <code>to</code> is not loaded
220      * @throws NullPointerException if <code>from</code> or
221      * <code>to</code> parameters have null value
222      * @see #loadInstrument
223      * @see #loadInstruments
224      * @see #loadAllInstruments
225      */
remapInstrument(Instrument from, Instrument to)226     public boolean remapInstrument(Instrument from, Instrument to);
227 
228 
229     /**
230      * Obtains the default soundbank for the synthesizer, if one exists.
231      * (Some synthesizers provide a default or built-in soundbank.)
232      * If a synthesizer doesn't have a default soundbank, instruments must
233      * be loaded explicitly from an external soundbank.
234      * @return default soundbank, or <code>null</code> if one does not exist.
235      * @see #isSoundbankSupported
236      */
getDefaultSoundbank()237     public Soundbank getDefaultSoundbank();
238 
239 
240     /**
241      * Obtains a list of instruments that come with the synthesizer.  These
242      * instruments might be built into the synthesizer, or they might be
243      * part of a default soundbank provided with the synthesizer, etc.
244      * <p>
245      * Note that you don't use this method  to find out which instruments are
246      * currently loaded onto the synthesizer; for that purpose, you use
247      * <code>getLoadedInstruments()</code>.
248      * Nor does the method indicate all the instruments that can be loaded onto
249      * the synthesizer; it only indicates the subset that come with the synthesizer.
250      * To learn whether another instrument can be loaded, you can invoke
251      * <code>isSoundbankSupported()</code>, and if the instrument's
252      * <code>Soundbank</code> is supported, you can try loading the instrument.
253      *
254      * @return list of available instruments. If the synthesizer
255      * has no instruments coming with it, an array of length 0 is returned.
256      * @see #getLoadedInstruments
257      * @see #isSoundbankSupported(Soundbank)
258      * @see #loadInstrument
259      */
getAvailableInstruments()260     public Instrument[] getAvailableInstruments();
261 
262 
263     /**
264      * Obtains a list of the instruments that are currently loaded onto this
265      * <code>Synthesizer</code>.
266      * @return a list of currently loaded instruments
267      * @see #loadInstrument
268      * @see #getAvailableInstruments
269      * @see Soundbank#getInstruments
270      */
getLoadedInstruments()271     public Instrument[] getLoadedInstruments();
272 
273 
274     /**
275      * Loads onto the <code>Synthesizer</code> all instruments contained
276      * in the specified <code>Soundbank</code>.
277      * @param soundbank the <code>Soundbank</code> whose are instruments are
278      * to be loaded
279      * @return <code>true</code> if the instruments are all successfully loaded (or
280      * already had been), <code>false</code> if any instrument could not be
281      * loaded (for example, if the <code>Synthesizer</code> had insufficient memory)
282      * @throws IllegalArgumentException if the requested soundbank is
283      * incompatible with this synthesizer.
284      * @see #isSoundbankSupported
285      * @see #loadInstrument
286      * @see #loadInstruments
287      */
loadAllInstruments(Soundbank soundbank)288     public boolean loadAllInstruments(Soundbank soundbank);
289 
290 
291 
292     /**
293      * Unloads all instruments contained in the specified <code>Soundbank</code>.
294      * @param soundbank soundbank containing instruments to unload
295      * @throws IllegalArgumentException thrown if the soundbank is not supported.
296      * @see #isSoundbankSupported
297      * @see #unloadInstrument
298      * @see #unloadInstruments
299      */
unloadAllInstruments(Soundbank soundbank)300     public void unloadAllInstruments(Soundbank soundbank);
301 
302 
303     /**
304      * Loads the instruments referenced by the specified patches, from the
305      * specified <code>Soundbank</code>.  Each of the <code>Patch</code> objects
306      * indicates a bank and program number; the <code>Instrument</code> that
307      * has the matching <code>Patch</code> is loaded into that bank and program
308      * location.
309      * @param soundbank the <code>Soundbank</code> containing the instruments to load
310      * @param patchList list of patches for which instruments should be loaded
311      * @return <code>true</code> if the instruments are all successfully loaded (or
312      * already had been), <code>false</code> if any instrument could not be
313      * loaded (for example, if the <code>Synthesizer</code> had insufficient memory)
314      * @throws IllegalArgumentException thrown if the soundbank is not supported.
315      * @see #isSoundbankSupported
316      * @see Instrument#getPatch
317      * @see #loadAllInstruments
318      * @see #loadInstrument
319      * @see Soundbank#getInstrument(Patch)
320      * @see Sequence#getPatchList()
321      */
loadInstruments(Soundbank soundbank, Patch[] patchList)322     public boolean loadInstruments(Soundbank soundbank, Patch[] patchList);
323 
324     /**
325      * Unloads the instruments referenced by the specified patches, from the MIDI sound bank specified.
326      * @param soundbank soundbank containing instruments to unload
327      * @param patchList list of patches for which instruments should be unloaded
328      * @throws IllegalArgumentException thrown if the soundbank is not supported.
329      *
330      * @see #unloadInstrument
331      * @see #unloadAllInstruments
332      * @see #isSoundbankSupported
333      * @see Instrument#getPatch
334      * @see #loadInstruments
335      */
unloadInstruments(Soundbank soundbank, Patch[] patchList)336     public void unloadInstruments(Soundbank soundbank, Patch[] patchList);
337 
338 
339     // RECEIVER METHODS
340 
341     /**
342      * Obtains the name of the receiver.
343      * @return receiver name
344      */
345     //  public abstract String getName();
346 
347 
348     /**
349      * Opens the receiver.
350      * @throws MidiUnavailableException if the receiver is cannot be opened,
351      * usually because the MIDI device is in use by another application.
352      * @throws SecurityException if the receiver cannot be opened due to security
353      * restrictions.
354      */
355     //  public abstract void open() throws MidiUnavailableException, SecurityException;
356 
357 
358     /**
359      * Closes the receiver.
360      */
361     //  public abstract void close();
362 
363 
364     /**
365      * Sends a MIDI event to the receiver.
366      * @param event event to send.
367      * @throws IllegalStateException if the receiver is not open.
368      */
369     //  public void send(MidiEvent event) throws IllegalStateException {
370     //
371     //  }
372 
373 
374     /**
375      * Obtains the set of controls supported by the
376      * element.  If no controls are supported, returns an
377      * array of length 0.
378      * @return set of controls
379      */
380     // $$kk: 03.04.99: josh bloch recommends getting rid of this:
381     // what can you really do with a set of untyped controls??
382     // $$kk: 03.05.99: i am putting this back in.  for one thing,
383     // you can check the length and know whether you should keep
384     // looking....
385     // public Control[] getControls();
386 
387     /**
388      * Obtains the specified control.
389      * @param controlClass class of the requested control
390      * @return requested control object, or null if the
391      * control is not supported.
392      */
393     // public Control getControl(Class controlClass);
394 }
395