/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