1
1
package com .darkprograms .speech .microphone ;
2
2
3
3
import javax .sound .sampled .*;
4
+
4
5
import java .io .File ;
5
6
6
7
/**
@@ -91,6 +92,22 @@ public void setTargetDataLine(TargetDataLine targetDataLine) {
91
92
public Microphone (AudioFileFormat .Type fileType ) {
92
93
setState (CaptureState .CLOSED );
93
94
setFileType (fileType );
95
+ initTargetDataLine ();
96
+ }
97
+
98
+ /**
99
+ * Initializes the target data line.
100
+ */
101
+ private void initTargetDataLine (){
102
+ DataLine .Info dataLineInfo = new DataLine .Info (TargetDataLine .class , getAudioFormat ());
103
+ try {
104
+ setTargetDataLine ((TargetDataLine ) AudioSystem .getLine (dataLineInfo ));
105
+ } catch (LineUnavailableException e ) {
106
+ // TODO Auto-generated catch block
107
+ e .printStackTrace ();
108
+ return ;
109
+ }
110
+
94
111
}
95
112
96
113
@@ -135,84 +152,13 @@ public void captureAudioToFile(String audioFile) throws Exception {
135
152
136
153
}
137
154
138
- /**
139
- * Gets the volume of the microphone input
140
- * Interval is 100ms so allow 100ms for this method to run in your code or specify smaller interval.
141
- * @return The volume of the microphone input or -1 if data-line is not available
142
- */
143
- public int getAudioVolume (){
144
- return getAudioVolume (100 );
145
- }
146
-
147
- /**
148
- * Gets the volume of the microphone input
149
- * @param interval: The length of time you would like to calculate the volume over in milliseconds.
150
- * @return The volume of the microphone input or -1 if data-line is not available.
151
- */
152
- public int getAudioVolume (int interval ){
153
- return calculateAudioVolume (this .getNumOfBytes (interval /1000d ));
154
- }
155
-
156
- /**
157
- * Gets the volume of microphone input
158
- * @param numOfBytes The number of bytes you want for volume interpretation
159
- * @return The volume over the specified number of bytes or -1 if data-line is unavailable.
160
- */
161
- private int calculateAudioVolume (int numOfBytes ){
162
- if (getTargetDataLine ()!=null ){
163
- byte [] data = new byte [numOfBytes ];
164
- this .getTargetDataLine ().read (data , 0 , numOfBytes );
165
- return calculateRMSLevel (data );
166
- }
167
- else {
168
- return -1 ;
169
- }
170
- }
171
-
172
- /**
173
- * Calculates the volume of AudioData which may be buffered data from a data-line
174
- * @param audioData The byte[] you want to determine the volume of
175
- * @return the calculated volume of audioData
176
- */
177
- private int calculateRMSLevel (byte [] audioData ){
178
- long lSum = 0 ;
179
- for (int i =0 ; i <audioData .length ; i ++)
180
- lSum = lSum + audioData [i ];
181
-
182
- double dAvg = lSum / audioData .length ;
183
-
184
- double sumMeanSquare = 0d ;
185
- for (int j =0 ; j <audioData .length ; j ++)
186
- sumMeanSquare = sumMeanSquare + Math .pow (audioData [j ] - dAvg , 2d );
187
-
188
- double averageMeanSquare = sumMeanSquare / audioData .length ;
189
- return (int )(Math .pow (averageMeanSquare ,0.5d ) + 0.5 );
190
- }
191
-
192
- /**
193
- * Returns the number of bytes over interval for useful when figuring out how long to record.
194
- * @param seconds The length in seconds
195
- * @return the number of bytes the microphone will save.
196
- */
197
- public int getNumOfBytes (int seconds ){
198
- return getNumOfBytes ((double )seconds );
199
- }
200
-
201
- /**
202
- * Returns the number of bytes over interval for useful when figuring out how long to record.
203
- * @param seconds The length in seconds
204
- * @return the number of bytes the microphone will output over the specified time.
205
- */
206
- public int getNumOfBytes (double seconds ){
207
- return (int )(seconds *getAudioFormat ().getSampleRate ()*getAudioFormat ().getFrameSize ()+.5 );
208
- }
209
155
210
156
/**
211
157
* The audio format to save in
212
158
*
213
159
* @return Returns AudioFormat to be used later when capturing audio from microphone
214
160
*/
215
- private AudioFormat getAudioFormat () {
161
+ public AudioFormat getAudioFormat () {
216
162
float sampleRate = 8000.0F ;
217
163
//8000,11025,16000,22050,44100
218
164
int sampleSizeInBits = 16 ;
@@ -226,6 +172,28 @@ private AudioFormat getAudioFormat() {
226
172
return new AudioFormat (sampleRate , sampleSizeInBits , channels , signed , bigEndian );
227
173
}
228
174
175
+ /**
176
+ * Opens the microphone, starting the targetDataLine.
177
+ * If it's already open, it does nothing.
178
+ */
179
+ public void open (){
180
+ if (getTargetDataLine ()==null ){
181
+ initTargetDataLine ();
182
+ }
183
+ if (!getTargetDataLine ().isOpen () && getState ()==CaptureState .CLOSED ){
184
+ try {
185
+ setState (CaptureState .PROCESSING_AUDIO );
186
+ getTargetDataLine ().open (getAudioFormat ());
187
+ getTargetDataLine ().start ();
188
+ } catch (LineUnavailableException e ) {
189
+ // TODO Auto-generated catch block
190
+ e .printStackTrace ();
191
+ return ;
192
+ }
193
+ }
194
+
195
+ }
196
+
229
197
/**
230
198
* Close the microphone capture, saving all processed audio to the specified file.<br>
231
199
* If already closed, this does nothing
@@ -235,6 +203,7 @@ public void close() {
235
203
} else {
236
204
getTargetDataLine ().stop ();
237
205
getTargetDataLine ().close ();
206
+ setState (CaptureState .CLOSED );
238
207
}
239
208
}
240
209
@@ -248,13 +217,11 @@ private class CaptureThread implements Runnable {
248
217
*/
249
218
public void run () {
250
219
try {
251
- setState (CaptureState .PROCESSING_AUDIO );
252
220
AudioFileFormat .Type fileType = getFileType ();
253
221
File audioFile = getAudioFile ();
254
- getTargetDataLine ().open (getAudioFormat ());
255
- getTargetDataLine ().start ();
222
+ open ();
256
223
AudioSystem .write (new AudioInputStream (getTargetDataLine ()), fileType , audioFile );
257
- setState ( CaptureState . CLOSED );
224
+ //Will write to File until it's closed.
258
225
} catch (Exception ex ) {
259
226
ex .printStackTrace ();
260
227
}
0 commit comments