/Users/lyon/j4p/src/sound/recorder/AudioCommon.java
|
1 package sound.recorder;
2
3 /**
4 * DocJava, Inc.
5 * http://www.docjava.com
6 * Programmer: dlyon
7 * Date: Nov 22, 2004
8 * Time: 3:42:48 PM
9 */
10 /*
11 * AudioCommon.java
12 *
13 * This file is part of jsresources.org
14 */
15
16 /*
17 * Copyright (c) 1999 - 2001 by Matthias Pfisterer
18 * All rights reserved.
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
22 * are met:
23 *
24 * - Redistributions of source code must retain the above copyright notice,
25 * this list of conditions and the following disclaimer.
26 * - Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
41 * OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 /*
45 |<--- this code is formatted to fit into 80 columns --->|
46 */
47
48 import javax.sound.sampled.AudioFileFormat;
49 import javax.sound.sampled.AudioFormat;
50 import javax.sound.sampled.AudioSystem;
51 import javax.sound.sampled.DataLine;
52 import javax.sound.sampled.Line;
53 import javax.sound.sampled.LineUnavailableException;
54 import javax.sound.sampled.Mixer;
55 import javax.sound.sampled.SourceDataLine;
56 import javax.sound.sampled.TargetDataLine;
57
58 /**
59 * Common methods for audio examples.
60 */
61 public class AudioCommon {
62 private static boolean DEBUG = true;
63
64
65 /**
66 * TODO:
67 */
68 public static void listSupportedTargetTypes() {
69 String strMessage = "Supported target types:";
70 AudioFileFormat.Type[] aTypes = AudioSystem.getAudioFileTypes();
71 for (int i = 0; i < aTypes.length; i++) {
72 strMessage += " " + aTypes[i].getExtension();
73 }
74 out(strMessage);
75 }
76
77 /**
78 * Trying to get an audio file type for the passed extension.
79 * This works by examining all available file types. For each
80 * type, if the extension this type promisses to handle matches
81 * the extension we are trying to find a type for, this type is
82 * returned.
83 * If no appropriate type is found, null is returned.
84 */
85 public static AudioFileFormat.Type findTargetType(String strExtension) {
86 AudioFileFormat.Type[] aTypes = AudioSystem.getAudioFileTypes();
87 for (int i = 0; i < aTypes.length; i++) {
88 if (aTypes[i].getExtension().equals(strExtension)) {
89 return aTypes[i];
90 }
91 }
92 return null;
93 }
94
95 /**
96 * TODO:
97 */
98 public static void listMixersAndExit() {
99 out("Available Mixers:");
100 Mixer.Info[] aInfos = AudioSystem.getMixerInfo();
101 for (int i = 0; i < aInfos.length; i++) {
102 out(aInfos[i].getName());
103 }
104 if (aInfos.length == 0) {
105 out("[No mixers available]");
106 }
107 System.exit(0);
108 }
109
110 /**
111 * List Mixers.
112 * Only Mixers that support either TargetDataLines or SourceDataLines
113 * are listed, depending on the value of bPlayback.
114 */
115 public static void listMixersAndExit(boolean bPlayback) {
116 out("Available Mixers:");
117 Mixer.Info[] aInfos = AudioSystem.getMixerInfo();
118 for (int i = 0; i < aInfos.length; i++) {
119 Mixer mixer = AudioSystem.getMixer(aInfos[i]);
120 Line.Info lineInfo = new Line.Info(bPlayback ?
121 SourceDataLine.class :
122 TargetDataLine.class);
123 if (mixer.isLineSupported(lineInfo)) {
124 out(aInfos[i].getName());
125 }
126 }
127 if (aInfos.length == 0) {
128 out("[No mixers available]");
129 }
130 System.exit(0);
131 }
132
133 /**
134 * TODO:
135 * This method tries to return a Mixer.Info whose name
136 * matches the passed name. If no matching Mixer.Info is
137 * found, null is returned.
138 */
139 public static Mixer.Info getMixerInfo(String strMixerName) {
140 Mixer.Info[] aInfos = AudioSystem.getMixerInfo();
141 for (int i = 0; i < aInfos.length; i++) {
142 if (aInfos[i].getName().equals(strMixerName)) {
143 return aInfos[i];
144 }
145 }
146 return null;
147 }
148
149 /**
150 * TODO:
151 */
152 public static TargetDataLine getTargetDataLine(String strMixerName,
153 AudioFormat audioFormat,
154 int nBufferSize) {
155 /*
156 Asking for a line is a rather tricky thing.
157 We have to construct an Info object that specifies
158 the desired properties for the line.
159 First, we have to say which kind of line we want. The
160 possibilities are: SourceDataLine (for playback), Clip
161 (for repeated playback) and TargetDataLine (for
162 recording).
163 Here, we want to do normal capture, so we ask for
164 a TargetDataLine.
165 Then, we have to pass an AudioFormat object, so that
166 the Line knows which format the data passed to it
167 will have.
168 Furthermore, we can give Java Sound a hint about how
169 big the internal buffer for the line should be. This
170 isn't used here, signaling that we
171 don't care about the exact size. Java Sound will use
172 some default value for the buffer size.
173 */
174 TargetDataLine targetDataLine = null;
175 DataLine.Info info = new DataLine.Info(TargetDataLine.class,
176 audioFormat, nBufferSize);
177 try {
178 if (strMixerName != null) {
179 Mixer.Info mixerInfo = getMixerInfo(strMixerName);
180 if (mixerInfo == null) {
181 out("AudioCommon.getTargetDataLine(): mixer not found: " + strMixerName);
182 return null;
183 }
184 Mixer mixer = AudioSystem.getMixer(mixerInfo);
185 targetDataLine = (TargetDataLine) mixer.getLine(info);
186 } else {
187 if (DEBUG) {
188 out("AudioCommon.getTargetDataLine(): using default mixer");
189 }
190 targetDataLine = (TargetDataLine) AudioSystem.getLine(info);
191 }
192
193 /*
194 * The line is there, but it is not yet ready to
195 * receive audio data. We have to open the line.
196 */
197 if (DEBUG) {
198 out("AudioCommon.getTargetDataLine(): opening line...");
199 }
200 targetDataLine.open(audioFormat, nBufferSize);
201 if (DEBUG) {
202 out("AudioCommon.getTargetDataLine(): opened line");
203 }
204 } catch (LineUnavailableException e) {
205 if (DEBUG) {
206 e.printStackTrace();
207 }
208 } catch (Exception e) {
209 if (DEBUG) {
210 e.printStackTrace();
211 }
212 }
213 if (DEBUG) {
214 out("AudioCommon.getTargetDataLine(): returning line: " + targetDataLine);
215 }
216 return targetDataLine;
217 }
218
219 /**
220 * Checks if the encoding is PCM.
221 */
222 public static boolean isPcm(AudioFormat.Encoding encoding) {
223 return encoding.equals(AudioFormat.Encoding.PCM_SIGNED)
224 || encoding.equals(AudioFormat.Encoding.PCM_UNSIGNED);
225 }
226
227 /**
228 * TODO:
229 */
230 private static void out(String strMessage) {
231 System.out.println(strMessage);
232 }
233 }
234
235 /*** AudioCommon.java ***/
236
237