001/* A class that supports live audio capture and playback.
002
003 Copyright (c) 2000-2018 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026
027 */
028package ptolemy.media.javasound;
029
030import java.io.IOException;
031
032import ptolemy.actor.injection.PtolemyInjector;
033
034///////////////////////////////////////////////////////////////////
035//// LiveSound
036
037/**
038 This class supports live capture and playback of audio
039 samples. For audio capture, audio samples are captured
040 from the audio input port of the computer. The audio input
041 port is typically associated with the line-in port,
042 microphone-in port, or cdrom audio-in port.
043 For audio playback, audio samples are written to
044 the audio output port. The audio output port is typically
045 associated with the headphones jack or the internal
046 speaker of the computer.
047 <p>
048 <b>Format of audio samples</b>
049 <p>
050 In this class, audio samples are double-valued and have a
051 valid range of [-1.0, 1.0]. Thus when this class is used
052 for audio capture, the returned samples will all range in
053 value from -1.0 to 1.0. When this class is used for audio
054 playback, the valid range of input samples is from -1.0 to
055 1.0. Any samples that are outside of this range will be
056 hard-clipped to fall within this range.
057 <p>
058 <b>Supported audio formats</b>
059 <p>
060 This class supports the subset of the hardware supported
061 audio formats that are also supported under Java. Provided
062 that the computer has a sound card that was manufactured
063 after 1998, the following formats are likely to be supported.
064 <ul>
065 <li><i>channels</i>: Mono (channels = 1) and stereo
066 (channels = 2) audio is supported. Note that some newer sound
067 cards support more than two channels, such as 4 input, 4 output
068 channels or better. Java does not support more than two
069 channels, however. The default value assumed by this class is
070 mono (1 channel). The number of channels may be set by the
071 setChannels() method and read by the getChannels method().
072 <li><i>sample rates</i>: 8000, 11025, 22050, 44100, and
073 48000 Hz are supported. Note that some newer sound cards
074 support 96000 Hz sample rates, but this is not supported under
075 Java. The default sample rate used by this class is 8000 Hz.
076 The sample rate may be set by the setSampleRate() method and
077 read by the getSampleRate() method.
078 <li><i>bit resolution</i>: 8 bit and 16 bit audio is supported.
079 Note that some newer sound cards support 20 bit, 24 bit, and 32
080 bit audio, but this is not supported under Java. The default
081 bit resolution used by this class is 16 bit audio. The bit
082 resolution may be set by the setBitsPerSample() method and
083 read by the getBitsPerSample() method.
084 </ul>
085 <p>
086 <b>Input/output latency</b>
087 <p>
088 When capturing audio samples, there will be some delay (latency)
089 from the time the sound arrives at the input port to the time
090 that the corresponding audio samples are available from this
091 class. Likewise, there will be some delay from the time sample
092 are written until the corresponding audio signal reaches the
093 output port (e.g., the speaker). This is because an internal
094 buffer is used to temporarily store audio samples when they are
095 captured or played. The size of this internal buffer affects
096 the latency in that a lower bound on the capture (playback)
097 latency is given by (<i>bufferSize</i> / <i>sampleRate</i>)
098 seconds. Here, <i>bufferSize</i> parameter is the size of the
099 buffer in samples per channel. This class provides a method,
100 setBufferSize(), to simultaneously set the size of internal
101 capture buffer and the internal playback buffer. The method
102 getBufferSize() may be used to read the buffer size. The default
103 size of the internal buffer is 4096 samples.
104 <p>
105 <b>Constraints</b>
106 <p>
107 This class requires that the sample rate, number of channels,
108 bit resolution, and internal buffer size be the same for both
109 capture and playback. The motivation for this constraint is to
110 simplify usage. Most audio hardware requires this anyway.
111 <p>
112 <b>Usage: audio capture</b>
113 <p>
114 First, call the appropriate methods to set the desired audio
115 format parameters such as sample rate, channels, bit resolution
116 if values other than the defaults are desired. The
117 setTransferSize() method should also be invoked to set the size
118 of the array (in samples per channel) that is returned when
119 audio samples are captured. The default value is 128 samples
120 per channel. Then invoke the startCapture(consumer) method to
121 start the audio capture process. This class will be ready to
122 capture audio immediately after startCapture() returns. Note
123 that startCapture() takes an Object parameter, <i>consumer</i>.
124 In addition to starting the audio capture process, startCapture()
125 also grants an object permission to capture audio.
126 <p>
127 After calling startCapture(consumer), the consumer object can
128 capture audio from the input port by calling getSamples(consumer).
129 The getSamples() method returns an array of samples from the input
130 port. The getSamples() blocks until the requested number of
131 samples (which is set by the setTransferSize method) are available.
132 Thus, it is not possible to call this method too frequently.
133 Note that if getSamples() is not called frequently enough,
134 the internal buffer will overflow and some audio data will
135 be lost, which is generally undesirable. After the consumer
136 object no longer wishes to capture audio, it should free up the
137 audio system resources by calling the stopCapture(consumer)
138 method. It should be noted that only one object may capture
139 audio simultaneously from the audio input port. A future
140 version of this class may support multiple objects capturing
141 from the input port simultaneously.
142 <p>
143 <b>Usage: audio Playback</b>
144 <p>
145 First, call the appropriate methods to set the desired audio
146 format parameters such as sample rate, channels, bit
147 resolution if values other than the defaults are desired.
148 The setTransferSize() method should also be invoked to set the
149 size of the array (in samples per channel) that is supplied
150 when audio samples are played. The default value is 128 samples
151 per channel. Then invoke the startPlayback(producer) method
152 to start the audio playback process. This class will be ready
153 to playback audio immediately after startPlayback() returns.
154 Note that startPlayback() takes an Object parameter,
155 <i>producer</i>. In addition to starting the audio playback
156 process, startPlayback() also grants an object permission to
157 playback audio.
158 <p>
159 After calling startPlayback(producer), the producer object can
160 playback audio to the output port by calling putSamples(producer).
161 The putSamples() method takes an array of samples and sends the
162 audio data to the output port. The putSamples() method blocks
163 until the requested number of samples (which is set by the
164 setTransferSize method) have been written to the output port.
165 Thus, it is not possible to call this method too frequently.
166 Note that if putSamples() is not called frequently enough,
167 the internal buffer will underflow, causing audible artifacts
168 in the output signal. After the producer object no longer wishes
169 to playback audio, it should free up the audio system resources
170 by calling the stopPlayback(producer) method. It should be noted
171 that only one object may playback audio simultaneously to the
172 audio output port. A future version of this class may support
173 multiple objects playing to the output port simultaneously.
174
175 @author Brian K. Vogel and Neil E. Turner and Steve Neuendorffer, Edward A. Lee, Contributor: Dennis Geurts
176 @version $Id$
177 @since Ptolemy II 1.0
178 @Pt.ProposedRating Yellow (net)
179 @Pt.AcceptedRating Red (cxh)
180 @see ptolemy.media.javasound.SoundReader
181 @see ptolemy.media.javasound.SoundWriter
182 */
183public class LiveSound {
184
185    /** Add a live sound listener. The listener will be notified
186     *  of all changes in live audio parameters. If the listener
187     *  is already listening, then do nothing.
188     *
189     *  @param listener The LiveSoundListener to add.
190     *  @see #removeLiveSoundListener(LiveSoundListener)
191     */
192    public static void addLiveSoundListener(LiveSoundListener listener) {
193        _implementation.addLiveSoundListener(listener);
194
195    }
196
197    /** Flush queued data from the capture buffer.  The flushed data is
198     *  discarded.  It is only legal to flush the capture buffer after
199     *  startCapture() is called.  Flushing an active audio buffer is likely to
200     *  cause a discontinuity in the data, resulting in a perceptible click.
201     *  <p>
202     *  Note that only the object with the exclusive lock on the capture audio
203     *  resources is allowed to invoke this method. An exception will occur if
204     *  the specified object does not have the lock on the playback audio
205     *  resources.
206     *
207     *  @param consumer The object that has an exclusive lock on
208     *   the capture audio resources.
209     *
210     *  @exception IllegalStateException If audio capture is currently
211     *  inactive. That is, if startCapture() has not yet been called
212     *  or if stopCapture() has already been called.
213     *
214     *  @exception IOException If the calling program does not have permission
215     *  to access the audio capture resources.
216     */
217    public static void flushCaptureBuffer(Object consumer)
218            throws IOException, IllegalStateException {
219        _implementation.flushCaptureBuffer(consumer);
220
221    }
222
223    /** Flush queued data from the playback buffer.  The flushed data is
224     *  discarded.  It is only legal to flush the playback buffer after
225     *  startPlayback() is called, and only makes sense to do so (but is
226     *  not required) after putSamples() is called.  Flushing an active audio
227     *  buffer is likely to cause a discontinuity in the data, resulting in a
228     *  perceptible click.
229     *  <p>
230     *  Note that only the object with the exclusive lock on the playback audio
231     *  resources is allowed to invoke this method. An exception will occur if
232     *  the specified object does not have the lock on the playback audio
233     *  resources.
234     *
235     *  @param producer The object that has an exclusive lock on
236     *   the playback audio resources.
237     *
238     *  @exception IllegalStateException If audio playback is currently
239     *  inactive. That is, if startPlayback() has not yet been called
240     *  or if stopPlayback() has already been called.
241     *
242     *  @exception IOException If the calling program does not have permission
243     *  to access the audio playback resources.
244     */
245    public static void flushPlaybackBuffer(Object producer)
246            throws IOException, IllegalStateException {
247        _implementation.flushPlaybackBuffer(producer);
248
249    }
250
251    /** Return the number of bits per audio sample, which is
252     *  set by the setBitsPerSample() method. The default
253     *  value of this parameter is 16 bits.
254     *
255     * @return The sample size in bits.
256     * @see #setBitsPerSample(int)
257     */
258    public static int getBitsPerSample() {
259        return _implementation.getBitsPerSample();
260
261    }
262
263    /** Return the suggested size of the internal capture and playback audio
264     *  buffers, in samples per channel. This parameter is set by the
265     *  setBufferSize() method.  There is no guarantee that the value returned
266     *  is the actual buffer size used for capture and playback.
267     *  Furthermore, the buffers used for capture and playback may have
268     *  different sizes.  The default value of this parameter is 4096.
269     *
270     *  @return The suggested internal buffer size in samples per
271     *   channel.
272     *  @see #setBufferSize(int)
273     */
274    public static int getBufferSize() {
275        return _implementation.getBufferSize();
276
277    }
278
279    /** Return the size of the internal capture audio buffer, in samples per
280     *  channel.
281     *
282     *  @return The internal buffer size in samples per channel.
283     *
284     *  @exception IllegalStateException If audio capture is inactive.
285     */
286    public static int getBufferSizeCapture() throws IllegalStateException {
287
288        return _implementation.getBufferSizeCapture();
289
290    }
291
292    /** Return the size of the internal playback audio buffer, in samples per
293     *  channel. This may differ from the requested buffer size if the hardware
294     *  does not support the requested buffer size. If playback has not
295     *  been started, then will simply return the requested buffer size.
296     *  @return The internal buffer size in samples per channel.
297     *  @exception IllegalStateException If audio playback is inactive.
298     */
299    public static int getBufferSizePlayback() {
300
301        return _implementation.getBufferSizePlayback();
302
303    }
304
305    /** Return the number of audio channels, which is set by
306     *  the setChannels() method. The default value of this
307     *  parameter is 1 (for mono audio).
308     *
309     *  @return The number of audio channels.
310     *  @see #setChannels(int)
311     */
312    public static int getChannels() {
313
314        return _implementation.getChannels();
315
316    }
317
318    /** Return the current sampling rate in Hz, which is set
319     *  by the setSampleRate() method. The default value of
320     *  this parameter is 8000 Hz.
321     *
322     *  @return The sample rate in Hz.
323     *  @see #setSampleRate(int)
324     */
325    public static int getSampleRate() {
326
327        return _implementation.getSampleRate();
328
329    }
330
331    /** Return an array of captured audio samples. This method
332     *  should be repeatedly called to obtain audio data.
333     *  The returned audio samples will have values in the range
334     *  [-1, 1], regardless of the audio bit resolution (bits per
335     *  sample).  This method should be called often enough to
336     *  prevent overflow of the internal audio buffer. If
337     *  overflow occurs, some audio data will be lost but no
338     *  exception or other error condition will occur. If
339     *  the audio data is not yet available, then this method
340     *  will block until the data is available.
341     *  <p>
342     *  The first index of the returned array
343     *  represents the channel number (0 for first channel, 1 for
344     *  second channel). The number of channels is set by the
345     *  setChannels() method. The second index represents the
346     *  sample index within a channel. For example,
347     *  <i>returned array</i>[n][m] contains the (m+1)th sample
348     *  of the (n+1)th channel. For each channel, n, the length of
349     *  <i>returned array</i>[n] is equal to the value returned by
350     *  the getTransferSize() method.
351     *  The size of the 2nd dimension of the returned array
352     *  is set by the setTransferSize() method.
353     *  <p>
354     *  Note that only the object with the exclusive lock on
355     *  the captured audio resources is allowed to invoked this
356     *  method. An exception will occur if the specified object
357     *  does not have the lock on the captured audio resources.
358     *
359     *  @param consumer The object that has an exclusive lock on
360     *   the capture audio resources.
361     *
362     *  @return Two dimensional array of captured audio samples.
363     *
364     *  @exception IllegalStateException If audio capture is currently
365     *   inactive.  That is, if startCapture() has not yet been called or if
366     *   stopCapture() has already been called.
367     *
368     *  @exception IOException If the calling program does not have permission
369     *   to access the audio capture resources.
370     */
371    public static double[][] getSamples(Object consumer)
372            throws IOException, IllegalStateException {
373
374        return _implementation.getSamples(consumer);
375
376    }
377
378    /** Get the array length (in samples per channel) to use
379     *  for capturing and playing samples via the putSamples()
380     *  and getSamples() methods. This method gets the size
381     *  of the 2nd dimension of the 2-dimensional array
382     *  used by the putSamples() and getSamples() methods. This
383     *  method returns the value that was set by the
384     *  setTransferSize(). If setTransferSize() was not invoked,
385     *  the default value of 128 is returned.
386     *
387     *  @return The size of the 2nd dimension of the 2-dimensional
388     *   array used by the putSamples() and getSamples() methods.
389     *  @see #setTransferSize(int)
390     */
391    public static int getTransferSize() {
392        return _implementation.getTransferSize();
393
394    }
395
396    /** Return true if audio capture is currently active.
397     *  Otherwise return false.
398     *
399     *  @return True If audio capture is currently active.
400     *  Otherwise return false.
401     */
402    public static boolean isCaptureActive() {
403        return _implementation.isCaptureActive();
404
405    }
406
407    /** Return true if audio playback is currently active.
408     *  Otherwise return false.
409     *
410     *  @return True If audio playback is currently active.
411     *  Otherwise return false.
412     */
413    public static boolean isPlaybackActive() {
414        return _implementation.isPlaybackActive();
415    }
416
417    /** Play an array of audio samples. There will be a
418     *  delay before the audio data is actually heard, since the
419     *  audio data in <i>samplesArray</i> is queued to an
420     *  internal audio buffer. The setBufferSize() method suggests a size
421     *  for the internal buffer. An upper bound
422     *  on the latency is given by (<i>bufferSize</i> /
423     *  <i>sampleRate</i>) seconds. This method should be invoked often
424     *  enough to prevent underflow of the internal audio buffer.
425     *  Underflow is undesirable since it will cause audible gaps
426     *  in audio playback, but no exception or error condition will
427     *  occur. If the caller attempts to write more data than can
428     *  be written, this method blocks until the data can be
429     *  written to the internal audio buffer.
430     *  <p>
431     *  The samples should be in the range (-1, 1). Samples that are
432     *  outside this range will be hard-clipped so that they fall
433     *  within this range.
434     *  <p>
435     *  The first index of the specified array
436     *  represents the channel number (0 for first channel, 1 for
437     *  second channel, etc.). The number of channels is set by the
438     *  setChannels() method. The second index represents the
439     *  sample index within a channel. For example,
440     *  putSamplesArray[n][m] contains the (m+1)th sample
441     *  of the (n+1)th channel.
442     *  <p>
443     *  Note that only the object with the exclusive lock on
444     *  the playback audio resources is allowed to invoke this
445     *  method. An exception will occur if the specified object
446     *  does not have the lock on the playback audio resources.
447     *
448     *  @param producer The object that has an exclusive lock on
449     *   the playback audio resources.
450     *
451     *  @param samplesArray A two dimensional array containing
452     *  the samples to play or write to a file.
453     *
454     *  @exception IOException If the calling program does not have permission
455     *  to access the audio playback resources.
456     *
457     *  @exception IllegalStateException If audio playback is currently
458     *  inactive. That is, If startPlayback() has not yet been called
459     *  or if stopPlayback() has already been called.
460     */
461    public static void putSamples(Object producer, double[][] samplesArray)
462            throws IOException, IllegalStateException {
463
464        _implementation.putSamples(producer, samplesArray);
465
466    }
467
468    /** Remove a live sound listener. If the listener is
469     *  is not listening, then do nothing.
470     *
471     *  @param listener The LiveSoundListener to remove.
472     *  @see #addLiveSoundListener(LiveSoundListener)
473     */
474    public static void removeLiveSoundListener(LiveSoundListener listener) {
475
476        _implementation.removeLiveSoundListener(listener);
477
478    }
479
480    /** Stop audio capture. If audio capture is already inactive,
481     *  then do nothing. This method should generally not be used,
482     *  but it may be needed to turn of audio capture for the
483     *  case where an ill-behaved application exits without calling
484     *  stopCapture(). The preferred way of stopping audio capture
485     *  is by calling the stopCapture() method.
486     *
487     */
488    public static void resetCapture() {
489
490        _implementation.resetCapture();
491
492    }
493
494    /** Stop audio playback. If audio playback is already inactive,
495     *  then do nothing. This method should generally not be used,
496     *  but it may be needed to turn of audio playback for the
497     *  case where an ill-behaved application exits without calling
498     *  stopPlayback(). The preferred way of stopping audio playback
499     *  is by calling the stopPlayback() method.
500     *
501     */
502    public static void resetPlayback() {
503
504        _implementation.resetPlayback();
505
506    }
507
508    /** Set the number of bits per sample to use for audio capture
509     *  and playback and notify any registered listeners of the change.
510     *  Allowable values include 8 and 16 bits. If
511     *  this method is not invoked, then the default value of 16
512     *  bits is used.
513     *  @param bitsPerSample The number of bits per sample.
514     *  @exception IOException If the specified bits per sample is
515     *   not supported by the audio hardware or by Java.
516     *  @see #getBitsPerSample()
517     */
518    public static void setBitsPerSample(int bitsPerSample) throws IOException {
519
520        _implementation.setBitsPerSample(bitsPerSample);
521
522    }
523
524    /** Request that the internal capture and playback
525     *  audio buffers have bufferSize samples per channel and notify the
526     *  registered listeners of the change. If this method
527     *  is not invoked, the default value of 1024 is used.
528     *
529     *  @param bufferSize The suggested size of the internal capture and
530     *   playback audio buffers, in samples per channel.
531     *  @exception IOException If the specified number of channels is
532     *   not supported by the audio hardware or by Java.
533     *  @see #getBufferSize()
534     */
535    public static void setBufferSize(int bufferSize) throws IOException {
536
537        _implementation.setBufferSize(bufferSize);
538
539    }
540
541    /** Set the number of audio channels to use for capture and
542     *  playback and notify any registered listeners of the change.
543     *  Allowable values are 1 (for mono) and 2 (for
544     *  stereo). If this method is not invoked, the default
545     *  value of 1 audio channel is used. Note that this method
546     *  sets the size of the first dimension of the
547     *  2-dimensional array used by the putSamples() and
548     *  getSamples() methods.
549     *
550     *  @param channels The number audio channels.
551     *
552     *  @exception IOException If the specified number of channels is
553     *   not supported by the audio hardware or by Java.
554     *  @see #getChannels()
555     */
556    public static void setChannels(int channels) throws IOException {
557
558        _implementation.setChannels(channels);
559
560    }
561
562    /** Set the sample rate to use for audio capture and playback
563     *  and notify an registered listeners of the change.
564     *  Allowable values for this parameter are 8000, 11025,
565     *  22050, 44100, and 48000 Hz. If this method is not invoked,
566     *  then the default value of 8000 Hz is used.
567     *
568     *  @param sampleRate Sample rate in Hz.
569     *
570     *  @exception IOException If the specified sample rate is
571     *   not supported by the audio hardware or by Java.
572     *  @see #getSampleRate()
573     */
574    public static void setSampleRate(int sampleRate) throws IOException {
575
576        _implementation.setSampleRate(sampleRate);
577
578    }
579
580    /** Set the array length (in samples per channel) to use
581     *  for capturing and playing samples via the putSamples()
582     *  and getSamples() methods. This method sets the size
583     *  of the 2nd dimension of the 2-dimensional array
584     *  used by the putSamples() and getSamples() methods. If
585     *  this method is not invoked, the default value of 128 is
586     *  used.
587     *  <p>
588     *  This method should only be called while audio capture and
589     *  playback are inactive. Otherwise an exception will occur.
590     *
591     *  @param transferSize The  size of the 2nd dimension of
592     *   the 2-dimensional array used by the putSamples() and
593     *   getSamples() methods
594     *
595     *  @exception IllegalStateException If this method is called
596     *   while audio capture or playback are active.
597     *  @see #getTransferSize()
598     */
599    public static void setTransferSize(int transferSize)
600            throws IllegalStateException {
601
602        _implementation.setTransferSize(transferSize);
603
604    }
605
606    /** Start audio capture. The specified object will be
607     *  given an exclusive lock on the audio capture resources
608     *  until the stopCapture() method is called with the
609     *  same object reference. After this method returns,
610     *  the getSamples() method may be repeatedly invoked
611     *  (using the object reference as a parameter) to
612     *  capture audio.
613     *  <p>
614     *  If audio capture is already active, then an
615     *  exception will occur.
616     *
617     *  @param consumer The object to be given exclusive access
618     *   to the captured audio resources.
619     *
620     *  @exception IOException If another object currently has access
621     *   to the audio capture resources or if starting the capture or
622     *   playback throws it.
623     *
624     *  @exception IllegalStateException If this method is called
625     *   while audio capture is already active.
626     */
627    public static void startCapture(Object consumer)
628            throws IOException, IllegalStateException {
629
630        _implementation.startCapture(consumer);
631
632    }
633
634    /** Start audio playback. The specified object will be
635     *  given an exclusive lock on the audio playback resources
636     *  until the stopPlayback() method is called with the
637     *  same object reference. After this method returns,
638     *  the putSamples() method may be repeatedly invoked
639     *  (using the object reference as a parameter) to
640     *  playback audio.
641     *  <p>
642     *  If audio playback is already active, then an
643     *  exception will occur.
644     *
645     *  @param producer The object to be given exclusive access
646     *   to the playback resources.
647     *
648     *  @exception IOException If another object currently has access
649     *   to the audio capture resources or if starting the playback throws it.
650     *
651     *  @exception IllegalStateException If this method is called
652     *   while audio playback is already active.
653     */
654    public static void startPlayback(Object producer)
655            throws IOException, IllegalStateException {
656
657        _implementation.startPlayback(producer);
658
659    }
660
661    /** Stop audio capture. If the specified object has
662     *  the lock on audio capture when this method is
663     *  invoked, then stop audio capture. Otherwise
664     *  an exception will occur.
665     *
666     *  @param consumer The object that held on exclusive
667     *   lock on the captured audio resources when this
668     *   method was invoked.
669     *
670     *  @exception IOException If another object currently has access
671     *   to the audio capture resources or if stopping the capture throws it.
672     *
673     *  @exception IllegalStateException If the specified
674     *   object did not hold an exclusive lock on the
675     *   captured audio resources when this method was invoked.
676     */
677    public static void stopCapture(Object consumer)
678            throws IOException, IllegalStateException {
679        _implementation.stopCapture(consumer);
680    }
681
682    /** Stop audio playback. If the specified object has
683     *  the lock on audio playback when this method is
684     *  invoked, then stop audio playback. Otherwise
685     *  an exception will occur.
686     *
687     *  @param producer The object that held on exclusive
688     *   lock on the playback audio resources when this
689     *   method was invoked.
690     *
691     *  @exception IOException If another object currently has access
692     *   to the audio capture resources or if stopping the playback throws it.
693
694     *  @exception IllegalStateException If the specified
695     *   object did not hold an exclusive lock on the
696     *   playback audio resources when this method was invoked.
697     *
698     */
699    public static void stopPlayback(Object producer)
700            throws IOException, IllegalStateException {
701        _implementation.stopPlayback(producer);
702    }
703
704    private static LiveSoundInterface _implementation = PtolemyInjector
705            .getInjector().getInstance(LiveSoundInterface.class);
706
707}