PortAudio 2.0
TestBasic.java
1/*
2 * Portable Audio I/O Library
3 * Java Binding for PortAudio
4 *
5 * Based on the Open Source API proposed by Ross Bencina
6 * Copyright (c) 2008 Ross Bencina
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining
9 * a copy of this software and associated documentation files
10 * (the "Software"), to deal in the Software without restriction,
11 * including without limitation the rights to use, copy, modify, merge,
12 * publish, distribute, sublicense, and/or sell copies of the Software,
13 * and to permit persons to whom the Software is furnished to do so,
14 * subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be
17 * included in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
24 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 */
27
28/*
29 * The text above constitutes the entire PortAudio license; however,
30 * the PortAudio community also makes the following non-binding requests:
31 *
32 * Any person wishing to distribute modifications to the Software is
33 * requested to send the modifications to the original developer so that
34 * they can be incorporated into the canonical version. It is also
35 * requested that these non-binding requests be included along with the
36 * license above.
37 */
38
39package com.portaudio;
40
41import junit.framework.TestCase;
42
49public class TestBasic extends TestCase
50{
51
52 public void testDeviceCount()
53 {
55 assertTrue( "version invalid", (PortAudio.getVersion() > 0) );
56 System.out.println( "getVersion = " + PortAudio.getVersion() );
57 System.out.println( "getVersionText = " + PortAudio.getVersionText() );
58 System.out.println( "getDeviceCount = " + PortAudio.getDeviceCount() );
59 assertTrue( "getDeviceCount", (PortAudio.getDeviceCount() > 0) );
61 }
62
63 public void testListDevices()
64 {
66 int count = PortAudio.getDeviceCount();
67 assertTrue( "getDeviceCount", (count > 0) );
68 for( int i = 0; i < count; i++ )
69 {
70 DeviceInfo info = PortAudio.getDeviceInfo( i );
71 System.out.println( "------------------ #" + i );
72 System.out.println( " name = " + info.name );
73 System.out.println( " hostApi = " + info.hostApi );
74 System.out.println( " maxOutputChannels = "
75 + info.maxOutputChannels );
76 System.out.println( " maxInputChannels = "
77 + info.maxInputChannels );
78 System.out.println( " defaultSampleRate = "
79 + info.defaultSampleRate );
80 System.out.printf( " defaultLowInputLatency = %3d msec\n",
81 ((int) (info.defaultLowInputLatency * 1000)) );
82 System.out.printf( " defaultHighInputLatency = %3d msec\n",
83 ((int) (info.defaultHighInputLatency * 1000)) );
84 System.out.printf( " defaultLowOutputLatency = %3d msec\n",
85 ((int) (info.defaultLowOutputLatency * 1000)) );
86 System.out.printf( " defaultHighOutputLatency = %3d msec\n",
87 ((int) (info.defaultHighOutputLatency * 1000)) );
88
89 assertTrue( "some channels",
90 (info.maxOutputChannels + info.maxInputChannels) > 0 );
91 assertTrue( "not too many channels", (info.maxInputChannels < 64) );
92 assertTrue( "not too many channels", (info.maxOutputChannels < 64) );
93 }
94
95 System.out.println( "defaultInput = "
96 + PortAudio.getDefaultInputDevice() );
97 System.out.println( "defaultOutput = "
98 + PortAudio.getDefaultOutputDevice() );
99
101 }
102
103 public void testHostApis()
104 {
106 int validApiCount = 0;
107 for( int hostApiType = 0; hostApiType < PortAudio.HOST_API_TYPE_COUNT; hostApiType++ )
108 {
109 int hostApiIndex = PortAudio
110 .hostApiTypeIdToHostApiIndex( hostApiType );
111 if( hostApiIndex >= 0 )
112 {
113 HostApiInfo info = PortAudio.getHostApiInfo( hostApiIndex );
114 System.out.println( "Checking Host API: " + info.name );
115 for( int apiDeviceIndex = 0; apiDeviceIndex < info.deviceCount; apiDeviceIndex++ )
116 {
117 int deviceIndex = PortAudio
118 .hostApiDeviceIndexToDeviceIndex( hostApiIndex,
119 apiDeviceIndex );
120 DeviceInfo deviceInfo = PortAudio
121 .getDeviceInfo( deviceIndex );
122 assertEquals( "host api must match up", hostApiIndex,
123 deviceInfo.hostApi );
124 }
125 validApiCount++;
126 }
127 }
128
129 assertEquals( "host api counts", PortAudio.getHostApiCount(),
130 validApiCount );
131 }
132
133 public void testListHostApis()
134 {
136 int count = PortAudio.getHostApiCount();
137 assertTrue( "getHostApiCount", (count > 0) );
138 for( int i = 0; i < count; i++ )
139 {
140 HostApiInfo info = PortAudio.getHostApiInfo( i );
141 System.out.println( "------------------ #" + i );
142 System.out.println( " version = " + info.version );
143 System.out.println( " name = " + info.name );
144 System.out.println( " type = " + info.type );
145 System.out.println( " deviceCount = " + info.deviceCount );
146 System.out.println( " defaultInputDevice = "
147 + info.defaultInputDevice );
148 System.out.println( " defaultOutputDevice = "
149 + info.defaultOutputDevice );
150 assertTrue( "some devices", info.deviceCount > 0 );
151 }
152
153 System.out.println( "------\ndefaultHostApi = "
154 + PortAudio.getDefaultHostApi() );
156 }
157
158 public void testCheckFormat()
159 {
161 StreamParameters streamParameters = new StreamParameters();
162 streamParameters.device = PortAudio.getDefaultOutputDevice();
163 int result = PortAudio
164 .isFormatSupported( null, streamParameters, 44100 );
165 System.out.println( "isFormatSupported returns " + result );
166 assertEquals( "default output format", 0, result );
167 // Try crazy channelCount
168 streamParameters.channelCount = 8765;
169 result = PortAudio.isFormatSupported( null, streamParameters, 44100 );
170 System.out.println( "crazy isFormatSupported returns " + result );
171 assertTrue( "default output format", (result < 0) );
173 }
174
175 static class SineOscillator
176 {
177 double phase = 0.0;
178 double phaseIncrement = 0.01;
179
180 SineOscillator(double freq, int sampleRate)
181 {
182 phaseIncrement = freq * Math.PI * 2.0 / sampleRate;
183 }
184
185 double next()
186 {
187 double value = Math.sin( phase );
188 phase += phaseIncrement;
189 if( phase > Math.PI )
190 {
191 phase -= Math.PI * 2.0;
192 }
193 return value;
194 }
195 }
196
197 public void testStreamError()
198 {
200 StreamParameters streamParameters = new StreamParameters();
201 streamParameters.sampleFormat = PortAudio.FORMAT_FLOAT_32;
202 streamParameters.channelCount = 2;
203 streamParameters.device = PortAudio.getDefaultOutputDevice();
204 int framesPerBuffer = 256;
205 int flags = 0;
206 BlockingStream stream = PortAudio.openStream( null, streamParameters,
207 44100, framesPerBuffer, flags );
208
209 // Try to write data to a stopped stream.
210 Throwable caught = null;
211 try
212 {
213 float[] buffer = new float[framesPerBuffer
214 * streamParameters.channelCount];
215 stream.write( buffer, framesPerBuffer );
216 } catch( Throwable e )
217 {
218 caught = e;
219 e.printStackTrace();
220 }
221
222 assertTrue( "caught no expection", (caught != null) );
223 assertTrue( "exception should say stream is stopped", caught
224 .getMessage().contains( "stopped" ) );
225
226 // Try to write null data.
227 caught = null;
228 try
229 {
230 stream.write( (float[]) null, framesPerBuffer );
231 } catch( Throwable e )
232 {
233 caught = e;
234 e.printStackTrace();
235 }
236 assertTrue( "caught no expection", (caught != null) );
237 assertTrue( "exception should say stream is stopped", caught
238 .getMessage().contains( "null" ) );
239
240 // Try to write short data to a float stream.
241 stream.start();
242 caught = null;
243 try
244 {
245 short[] buffer = new short[framesPerBuffer
246 * streamParameters.channelCount];
247 stream.write( buffer, framesPerBuffer );
248 } catch( Throwable e )
249 {
250 caught = e;
251 e.printStackTrace();
252 }
253
254 assertTrue( "caught no expection", (caught != null) );
255 assertTrue( "exception should say tried to", caught.getMessage()
256 .contains( "Tried to write short" ) );
257
258 stream.close();
259
261 }
262
263 public void checkBlockingWriteFloat( int deviceId, double sampleRate )
264 {
265 StreamParameters streamParameters = new StreamParameters();
266 streamParameters.channelCount = 2;
267 streamParameters.device = deviceId;
268 streamParameters.suggestedLatency = PortAudio
269 .getDeviceInfo( streamParameters.device ).defaultLowOutputLatency;
270 System.out.println( "suggestedLatency = "
271 + streamParameters.suggestedLatency );
272
273 int framesPerBuffer = 256;
274 int flags = 0;
275 BlockingStream stream = PortAudio.openStream( null, streamParameters,
276 (int) sampleRate, framesPerBuffer, flags );
277 assertTrue( "got default stream", stream != null );
278
279 assertEquals( "stream isStopped", true, stream.isStopped() );
280 assertEquals( "stream isActive", false, stream.isActive() );
281
282 int numFrames = 80000;
283 double expected = ((double)numFrames) / sampleRate;
284 stream.start();
285 long startTime = System.currentTimeMillis();
286 double startStreamTime = stream.getTime();
287 assertEquals( "stream isStopped", false, stream.isStopped() );
288 assertEquals( "stream isActive", true, stream.isActive() );
289
290 writeSineData( stream, framesPerBuffer, numFrames, (int) sampleRate );
291
292 StreamInfo streamInfo = stream.getInfo();
293 System.out.println( "inputLatency of a stream = "+ streamInfo.inputLatency );
294 System.out.println( "outputLatency of a stream = "+streamInfo.outputLatency );
295 System.out.println( "sampleRate of a stream = "+ streamInfo.sampleRate );
296
297 assertEquals( "inputLatency of a stream ", 0.0, streamInfo.inputLatency, 0.000001 );
298 assertTrue( "outputLatency of a stream ",(streamInfo.outputLatency > 0) );
299 assertEquals( "sampleRate of a stream ", sampleRate, streamInfo.sampleRate, 3 );
300
301 double endStreamTime = stream.getTime();
302 stream.stop();
303 long stopTime = System.currentTimeMillis();
304
305 System.out.println( "startStreamTime = " + startStreamTime );
306 System.out.println( "endStreamTime = " + endStreamTime );
307 double elapsedStreamTime = endStreamTime - startStreamTime;
308 System.out.println( "elapsedStreamTime = " + elapsedStreamTime );
309 assertTrue( "elapsedStreamTime: " + elapsedStreamTime,
310 (elapsedStreamTime > 0.0) );
311 assertEquals( "elapsedStreamTime: ", expected, elapsedStreamTime, 0.10 );
312
313 assertEquals( "stream isStopped", true, stream.isStopped() );
314 assertEquals( "stream isActive", false, stream.isActive() );
315 stream.close();
316
317 double elapsed = (stopTime - startTime) / 1000.0;
318 assertEquals( "elapsed time to play", expected, elapsed, 0.20 );
319 }
320
321 public void testBlockingWriteFloat()
322 {
324 checkBlockingWriteFloat( PortAudio.getDefaultOutputDevice(), 44100 );
326 }
327
328 public void ZtestWriteEachHostAPI()
329 {
331 for( int hostApiIndex = 0; hostApiIndex < PortAudio.getHostApiCount(); hostApiIndex++ )
332 {
333 HostApiInfo hostInfo = PortAudio.getHostApiInfo( hostApiIndex );
334 System.out.println( "-------------\nWriting using Host API: " + hostInfo.name );
335 int deviceId = hostInfo.defaultOutputDevice;
336 System.out.println( " Device ID =" + deviceId );
337 DeviceInfo deviceInfo = PortAudio.getDeviceInfo( deviceId );
338 System.out.println( " sampleRate =" + deviceInfo.defaultSampleRate );
339 checkBlockingWriteFloat( deviceId,
340 (int) deviceInfo.defaultSampleRate );
341 System.out.println( "Finished with " + hostInfo.name );
342 }
344 }
345
346 private void writeSineData( BlockingStream stream, int framesPerBuffer,
347 int numFrames, int sampleRate )
348 {
349 float[] buffer = new float[framesPerBuffer * 2];
350 SineOscillator osc1 = new SineOscillator( 200.0, sampleRate );
351 SineOscillator osc2 = new SineOscillator( 300.0, sampleRate );
352 int framesLeft = numFrames;
353 while( framesLeft > 0 )
354 {
355 int index = 0;
356 int framesToWrite = (framesLeft > framesPerBuffer) ? framesPerBuffer
357 : framesLeft;
358 for( int j = 0; j < framesToWrite; j++ )
359 {
360 buffer[index++] = (float) osc1.next();
361 buffer[index++] = (float) osc2.next();
362 }
363 stream.write( buffer, framesToWrite );
364 framesLeft -= framesToWrite;
365 }
366 }
367
368 private void writeSineDataShort( BlockingStream stream,
369 int framesPerBuffer, int numFrames )
370 {
371 short[] buffer = new short[framesPerBuffer * 2];
372 SineOscillator osc1 = new SineOscillator( 200.0, 44100 );
373 SineOscillator osc2 = new SineOscillator( 300.0, 44100 );
374 int framesLeft = numFrames;
375 while( framesLeft > 0 )
376 {
377 int index = 0;
378 int framesToWrite = (framesLeft > framesPerBuffer) ? framesPerBuffer
379 : framesLeft;
380 for( int j = 0; j < framesToWrite; j++ )
381 {
382 buffer[index++] = (short) (osc1.next() * 32767);
383 buffer[index++] = (short) (osc2.next() * 32767);
384 }
385 stream.write( buffer, framesToWrite );
386 framesLeft -= framesToWrite;
387 }
388 }
389
390 public void testBlockingWriteShort()
391 {
393
394 StreamParameters streamParameters = new StreamParameters();
395 streamParameters.sampleFormat = PortAudio.FORMAT_INT_16;
396 streamParameters.channelCount = 2;
397 streamParameters.device = PortAudio.getDefaultOutputDevice();
398 streamParameters.suggestedLatency = PortAudio
399 .getDeviceInfo( streamParameters.device ).defaultLowOutputLatency;
400 System.out.println( "suggestedLatency = "
401 + streamParameters.suggestedLatency );
402
403 int framesPerBuffer = 256;
404 int flags = 0;
405 BlockingStream stream = PortAudio.openStream( null, streamParameters,
406 44100, framesPerBuffer, flags );
407 assertTrue( "got default stream", stream != null );
408
409 int numFrames = 80000;
410 stream.start();
411 long startTime = System.currentTimeMillis();
412 writeSineDataShort( stream, framesPerBuffer, numFrames );
413 stream.stop();
414 long stopTime = System.currentTimeMillis();
415 stream.close();
416
417 double elapsed = (stopTime - startTime) / 1000.0;
418 double expected = numFrames / 44100.0;
419 assertEquals( "elapsed time to play", expected, elapsed, 0.20 );
421 }
422
423 public void testRecordPlayFloat() throws InterruptedException
424 {
425 checkRecordPlay( PortAudio.FORMAT_FLOAT_32 );
426 }
427
428 public void testRecordPlayShort() throws InterruptedException
429 {
430 checkRecordPlay( PortAudio.FORMAT_INT_16 );
431 }
432
433 public void checkRecordPlay( int sampleFormat ) throws InterruptedException
434 {
435 int framesPerBuffer = 256;
436 int flags = 0;
437 int sampleRate = 44100;
438 int numFrames = sampleRate * 3;
439 float[] floatBuffer = null;
440 short[] shortBuffer = null;
441
443 StreamParameters inParameters = new StreamParameters();
444 inParameters.sampleFormat = sampleFormat;
445 inParameters.device = PortAudio.getDefaultInputDevice();
446
447 DeviceInfo info = PortAudio.getDeviceInfo( inParameters.device );
448 inParameters.channelCount = (info.maxInputChannels > 2) ? 2
449 : info.maxInputChannels;
450 System.out.println( "channelCount = " + inParameters.channelCount );
451 inParameters.suggestedLatency = PortAudio
452 .getDeviceInfo( inParameters.device ).defaultLowInputLatency;
453
454 if( sampleFormat == PortAudio.FORMAT_FLOAT_32 )
455 {
456 floatBuffer = new float[numFrames * inParameters.channelCount];
457 }
458 else if( sampleFormat == PortAudio.FORMAT_INT_16 )
459 {
460 shortBuffer = new short[numFrames * inParameters.channelCount];
461 }
462 // Record a few seconds of audio.
463 BlockingStream inStream = PortAudio.openStream( inParameters, null,
464 sampleRate, framesPerBuffer, flags );
465
466 System.out.println( "RECORDING - say something like testing 1,2,3..." );
467 inStream.start();
468
469 if( sampleFormat == PortAudio.FORMAT_FLOAT_32 )
470 {
471 inStream.read( floatBuffer, numFrames );
472 }
473 else if( sampleFormat == PortAudio.FORMAT_INT_16 )
474 {
475 inStream.read( shortBuffer, numFrames );
476 }
477 Thread.sleep( 100 );
478 int availableToRead = inStream.getReadAvailable();
479 System.out.println( "availableToRead = " + availableToRead );
480 assertTrue( "getReadAvailable ", availableToRead > 0 );
481
482 inStream.stop();
483 inStream.close();
484 System.out.println( "Finished recording. Begin Playback." );
485
486 // Play back what we recorded.
487 StreamParameters outParameters = new StreamParameters();
488 outParameters.sampleFormat = sampleFormat;
489 outParameters.channelCount = inParameters.channelCount;
490 outParameters.device = PortAudio.getDefaultOutputDevice();
491 outParameters.suggestedLatency = PortAudio
492 .getDeviceInfo( outParameters.device ).defaultLowOutputLatency;
493
494 BlockingStream outStream = PortAudio.openStream( null, outParameters,
495 sampleRate, framesPerBuffer, flags );
496 assertTrue( "got default stream", outStream != null );
497
498 assertEquals( "inStream isActive", false, inStream.isActive() );
499
500 outStream.start();
501 Thread.sleep( 100 );
502 int availableToWrite = outStream.getWriteAvailable();
503 System.out.println( "availableToWrite = " + availableToWrite );
504 assertTrue( "getWriteAvailable ", availableToWrite > 0 );
505
506 System.out.println( "inStream = " + inStream );
507 System.out.println( "outStream = " + outStream );
508 assertEquals( "inStream isActive", false, inStream.isActive() );
509 assertEquals( "outStream isActive", true, outStream.isActive() );
510 if( sampleFormat == PortAudio.FORMAT_FLOAT_32 )
511 {
512 outStream.write( floatBuffer, numFrames );
513 }
514 else if( sampleFormat == PortAudio.FORMAT_INT_16 )
515 {
516 outStream.write( shortBuffer, numFrames );
517 }
518 outStream.stop();
519
520 outStream.close();
522 }
523}
boolean write(float[] buffer, int numFrames)
boolean read(float[] buffer, int numFrames)
static native void initialize()
static native void terminate()
static final int FORMAT_FLOAT_32
Definition: PortAudio.java:75
static native int getVersion()
static native int hostApiTypeIdToHostApiIndex(int hostApiType)
static native int getHostApiCount()
static native int hostApiDeviceIndexToDeviceIndex(int hostApiIndex, int apiDeviceIndex)
static native int getDeviceCount()
static native int isFormatSupported(StreamParameters inputStreamParameters, StreamParameters outputStreamParameters, int sampleRate)
static native String getVersionText()

Generated for PortAudio by  doxygen1.9.2