00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 package com.portaudio;
00040
00041 import junit.framework.TestCase;
00042
00049 public class TestBasic extends TestCase
00050 {
00051
00052 public void testDeviceCount()
00053 {
00054 PortAudio.initialize();
00055 assertTrue( "version invalid", (PortAudio.getVersion() > 0) );
00056 System.out.println( "getVersion = " + PortAudio.getVersion() );
00057 System.out.println( "getVersionText = " + PortAudio.getVersionText() );
00058 System.out.println( "getDeviceCount = " + PortAudio.getDeviceCount() );
00059 assertTrue( "getDeviceCount", (PortAudio.getDeviceCount() > 0) );
00060 PortAudio.terminate();
00061 }
00062
00063 public void testListDevices()
00064 {
00065 PortAudio.initialize();
00066 int count = PortAudio.getDeviceCount();
00067 assertTrue( "getDeviceCount", (count > 0) );
00068 for( int i = 0; i < count; i++ )
00069 {
00070 DeviceInfo info = PortAudio.getDeviceInfo( i );
00071 System.out.println( "------------------ #" + i );
00072 System.out.println( " name = " + info.name );
00073 System.out.println( " hostApi = " + info.hostApi );
00074 System.out.println( " maxOutputChannels = "
00075 + info.maxOutputChannels );
00076 System.out.println( " maxInputChannels = "
00077 + info.maxInputChannels );
00078 System.out.println( " defaultSampleRate = "
00079 + info.defaultSampleRate );
00080 System.out.printf( " defaultLowInputLatency = %3d msec\n",
00081 ((int) (info.defaultLowInputLatency * 1000)) );
00082 System.out.printf( " defaultHighInputLatency = %3d msec\n",
00083 ((int) (info.defaultHighInputLatency * 1000)) );
00084 System.out.printf( " defaultLowOutputLatency = %3d msec\n",
00085 ((int) (info.defaultLowOutputLatency * 1000)) );
00086 System.out.printf( " defaultHighOutputLatency = %3d msec\n",
00087 ((int) (info.defaultHighOutputLatency * 1000)) );
00088
00089 assertTrue( "some channels",
00090 (info.maxOutputChannels + info.maxInputChannels) > 0 );
00091 assertTrue( "not too many channels", (info.maxInputChannels < 64) );
00092 assertTrue( "not too many channels", (info.maxOutputChannels < 64) );
00093 }
00094
00095 System.out.println( "defaultInput = "
00096 + PortAudio.getDefaultInputDevice() );
00097 System.out.println( "defaultOutput = "
00098 + PortAudio.getDefaultOutputDevice() );
00099
00100 PortAudio.terminate();
00101 }
00102
00103 public void testHostApis()
00104 {
00105 PortAudio.initialize();
00106 int validApiCount = 0;
00107 for( int hostApiType = 0; hostApiType < PortAudio.HOST_API_TYPE_COUNT; hostApiType++ )
00108 {
00109 int hostApiIndex = PortAudio
00110 .hostApiTypeIdToHostApiIndex( hostApiType );
00111 if( hostApiIndex >= 0 )
00112 {
00113 HostApiInfo info = PortAudio.getHostApiInfo( hostApiIndex );
00114 System.out.println( "Checking Host API: " + info.name );
00115 for( int apiDeviceIndex = 0; apiDeviceIndex < info.deviceCount; apiDeviceIndex++ )
00116 {
00117 int deviceIndex = PortAudio
00118 .hostApiDeviceIndexToDeviceIndex( hostApiIndex,
00119 apiDeviceIndex );
00120 DeviceInfo deviceInfo = PortAudio
00121 .getDeviceInfo( deviceIndex );
00122 assertEquals( "host api must match up", hostApiIndex,
00123 deviceInfo.hostApi );
00124 }
00125 validApiCount++;
00126 }
00127 }
00128
00129 assertEquals( "host api counts", PortAudio.getHostApiCount(),
00130 validApiCount );
00131 }
00132
00133 public void testListHostApis()
00134 {
00135 PortAudio.initialize();
00136 int count = PortAudio.getHostApiCount();
00137 assertTrue( "getHostApiCount", (count > 0) );
00138 for( int i = 0; i < count; i++ )
00139 {
00140 HostApiInfo info = PortAudio.getHostApiInfo( i );
00141 System.out.println( "------------------ #" + i );
00142 System.out.println( " version = " + info.version );
00143 System.out.println( " name = " + info.name );
00144 System.out.println( " type = " + info.type );
00145 System.out.println( " deviceCount = " + info.deviceCount );
00146 System.out.println( " defaultInputDevice = "
00147 + info.defaultInputDevice );
00148 System.out.println( " defaultOutputDevice = "
00149 + info.defaultOutputDevice );
00150 assertTrue( "some devices", info.deviceCount > 0 );
00151 }
00152
00153 System.out.println( "------\ndefaultHostApi = "
00154 + PortAudio.getDefaultHostApi() );
00155 PortAudio.terminate();
00156 }
00157
00158 public void testCheckFormat()
00159 {
00160 PortAudio.initialize();
00161 StreamParameters streamParameters = new StreamParameters();
00162 streamParameters.device = PortAudio.getDefaultOutputDevice();
00163 int result = PortAudio
00164 .isFormatSupported( null, streamParameters, 44100 );
00165 System.out.println( "isFormatSupported returns " + result );
00166 assertEquals( "default output format", 0, result );
00167
00168 streamParameters.channelCount = 8765;
00169 result = PortAudio.isFormatSupported( null, streamParameters, 44100 );
00170 System.out.println( "crazy isFormatSupported returns " + result );
00171 assertTrue( "default output format", (result < 0) );
00172 PortAudio.terminate();
00173 }
00174
00175 static class SineOscillator
00176 {
00177 double phase = 0.0;
00178 double phaseIncrement = 0.01;
00179
00180 SineOscillator(double freq, int sampleRate)
00181 {
00182 phaseIncrement = freq * Math.PI * 2.0 / sampleRate;
00183 }
00184
00185 double next()
00186 {
00187 double value = Math.sin( phase );
00188 phase += phaseIncrement;
00189 if( phase > Math.PI )
00190 {
00191 phase -= Math.PI * 2.0;
00192 }
00193 return value;
00194 }
00195 }
00196
00197 public void testStreamError()
00198 {
00199 PortAudio.initialize();
00200 StreamParameters streamParameters = new StreamParameters();
00201 streamParameters.sampleFormat = PortAudio.FORMAT_FLOAT_32;
00202 streamParameters.channelCount = 2;
00203 streamParameters.device = PortAudio.getDefaultOutputDevice();
00204 int framesPerBuffer = 256;
00205 int flags = 0;
00206 BlockingStream stream = PortAudio.openStream( null, streamParameters,
00207 44100, framesPerBuffer, flags );
00208
00209
00210 Throwable caught = null;
00211 try
00212 {
00213 float[] buffer = new float[framesPerBuffer
00214 * streamParameters.channelCount];
00215 stream.write( buffer, framesPerBuffer );
00216 } catch( Throwable e )
00217 {
00218 caught = e;
00219 e.printStackTrace();
00220 }
00221
00222 assertTrue( "caught no expection", (caught != null) );
00223 assertTrue( "exception should say stream is stopped", caught
00224 .getMessage().contains( "stopped" ) );
00225
00226
00227 caught = null;
00228 try
00229 {
00230 stream.write( (float[]) null, framesPerBuffer );
00231 } catch( Throwable e )
00232 {
00233 caught = e;
00234 e.printStackTrace();
00235 }
00236 assertTrue( "caught no expection", (caught != null) );
00237 assertTrue( "exception should say stream is stopped", caught
00238 .getMessage().contains( "null" ) );
00239
00240
00241 stream.start();
00242 caught = null;
00243 try
00244 {
00245 short[] buffer = new short[framesPerBuffer
00246 * streamParameters.channelCount];
00247 stream.write( buffer, framesPerBuffer );
00248 } catch( Throwable e )
00249 {
00250 caught = e;
00251 e.printStackTrace();
00252 }
00253
00254 assertTrue( "caught no expection", (caught != null) );
00255 assertTrue( "exception should say tried to", caught.getMessage()
00256 .contains( "Tried to write short" ) );
00257
00258 stream.close();
00259
00260 PortAudio.terminate();
00261 }
00262
00263 public void checkBlockingWriteFloat( int deviceId, double sampleRate )
00264 {
00265 StreamParameters streamParameters = new StreamParameters();
00266 streamParameters.channelCount = 2;
00267 streamParameters.device = deviceId;
00268 streamParameters.suggestedLatency = PortAudio
00269 .getDeviceInfo( streamParameters.device ).defaultLowOutputLatency;
00270 System.out.println( "suggestedLatency = "
00271 + streamParameters.suggestedLatency );
00272
00273 int framesPerBuffer = 256;
00274 int flags = 0;
00275 BlockingStream stream = PortAudio.openStream( null, streamParameters,
00276 (int) sampleRate, framesPerBuffer, flags );
00277 assertTrue( "got default stream", stream != null );
00278
00279 assertEquals( "stream isStopped", true, stream.isStopped() );
00280 assertEquals( "stream isActive", false, stream.isActive() );
00281
00282 int numFrames = 80000;
00283 double expected = ((double)numFrames) / sampleRate;
00284 stream.start();
00285 long startTime = System.currentTimeMillis();
00286 double startStreamTime = stream.getTime();
00287 assertEquals( "stream isStopped", false, stream.isStopped() );
00288 assertEquals( "stream isActive", true, stream.isActive() );
00289
00290 writeSineData( stream, framesPerBuffer, numFrames, (int) sampleRate );
00291
00292 StreamInfo streamInfo = stream.getInfo();
00293 System.out.println( "inputLatency of a stream = "+ streamInfo.inputLatency );
00294 System.out.println( "outputLatency of a stream = "+streamInfo.outputLatency );
00295 System.out.println( "sampleRate of a stream = "+ streamInfo.sampleRate );
00296
00297 assertEquals( "inputLatency of a stream ", 0.0, streamInfo.inputLatency, 0.000001 );
00298 assertTrue( "outputLatency of a stream ",(streamInfo.outputLatency > 0) );
00299 assertEquals( "sampleRate of a stream ", sampleRate, streamInfo.sampleRate, 3 );
00300
00301 double endStreamTime = stream.getTime();
00302 stream.stop();
00303 long stopTime = System.currentTimeMillis();
00304
00305 System.out.println( "startStreamTime = " + startStreamTime );
00306 System.out.println( "endStreamTime = " + endStreamTime );
00307 double elapsedStreamTime = endStreamTime - startStreamTime;
00308 System.out.println( "elapsedStreamTime = " + elapsedStreamTime );
00309 assertTrue( "elapsedStreamTime: " + elapsedStreamTime,
00310 (elapsedStreamTime > 0.0) );
00311 assertEquals( "elapsedStreamTime: ", expected, elapsedStreamTime, 0.10 );
00312
00313 assertEquals( "stream isStopped", true, stream.isStopped() );
00314 assertEquals( "stream isActive", false, stream.isActive() );
00315 stream.close();
00316
00317 double elapsed = (stopTime - startTime) / 1000.0;
00318 assertEquals( "elapsed time to play", expected, elapsed, 0.20 );
00319 }
00320
00321 public void testBlockingWriteFloat()
00322 {
00323 PortAudio.initialize();
00324 checkBlockingWriteFloat( PortAudio.getDefaultOutputDevice(), 44100 );
00325 PortAudio.terminate();
00326 }
00327
00328 public void ZtestWriteEachHostAPI()
00329 {
00330 PortAudio.initialize();
00331 for( int hostApiIndex = 0; hostApiIndex < PortAudio.getHostApiCount(); hostApiIndex++ )
00332 {
00333 HostApiInfo hostInfo = PortAudio.getHostApiInfo( hostApiIndex );
00334 System.out.println( "-------------\nWriting using Host API: " + hostInfo.name );
00335 int deviceId = hostInfo.defaultOutputDevice;
00336 System.out.println( " Device ID =" + deviceId );
00337 DeviceInfo deviceInfo = PortAudio.getDeviceInfo( deviceId );
00338 System.out.println( " sampleRate =" + deviceInfo.defaultSampleRate );
00339 checkBlockingWriteFloat( deviceId,
00340 (int) deviceInfo.defaultSampleRate );
00341 System.out.println( "Finished with " + hostInfo.name );
00342 }
00343 PortAudio.terminate();
00344 }
00345
00346 private void writeSineData( BlockingStream stream, int framesPerBuffer,
00347 int numFrames, int sampleRate )
00348 {
00349 float[] buffer = new float[framesPerBuffer * 2];
00350 SineOscillator osc1 = new SineOscillator( 200.0, sampleRate );
00351 SineOscillator osc2 = new SineOscillator( 300.0, sampleRate );
00352 int framesLeft = numFrames;
00353 while( framesLeft > 0 )
00354 {
00355 int index = 0;
00356 int framesToWrite = (framesLeft > framesPerBuffer) ? framesPerBuffer
00357 : framesLeft;
00358 for( int j = 0; j < framesToWrite; j++ )
00359 {
00360 buffer[index++] = (float) osc1.next();
00361 buffer[index++] = (float) osc2.next();
00362 }
00363 stream.write( buffer, framesToWrite );
00364 framesLeft -= framesToWrite;
00365 }
00366 }
00367
00368 private void writeSineDataShort( BlockingStream stream,
00369 int framesPerBuffer, int numFrames )
00370 {
00371 short[] buffer = new short[framesPerBuffer * 2];
00372 SineOscillator osc1 = new SineOscillator( 200.0, 44100 );
00373 SineOscillator osc2 = new SineOscillator( 300.0, 44100 );
00374 int framesLeft = numFrames;
00375 while( framesLeft > 0 )
00376 {
00377 int index = 0;
00378 int framesToWrite = (framesLeft > framesPerBuffer) ? framesPerBuffer
00379 : framesLeft;
00380 for( int j = 0; j < framesToWrite; j++ )
00381 {
00382 buffer[index++] = (short) (osc1.next() * 32767);
00383 buffer[index++] = (short) (osc2.next() * 32767);
00384 }
00385 stream.write( buffer, framesToWrite );
00386 framesLeft -= framesToWrite;
00387 }
00388 }
00389
00390 public void testBlockingWriteShort()
00391 {
00392 PortAudio.initialize();
00393
00394 StreamParameters streamParameters = new StreamParameters();
00395 streamParameters.sampleFormat = PortAudio.FORMAT_INT_16;
00396 streamParameters.channelCount = 2;
00397 streamParameters.device = PortAudio.getDefaultOutputDevice();
00398 streamParameters.suggestedLatency = PortAudio
00399 .getDeviceInfo( streamParameters.device ).defaultLowOutputLatency;
00400 System.out.println( "suggestedLatency = "
00401 + streamParameters.suggestedLatency );
00402
00403 int framesPerBuffer = 256;
00404 int flags = 0;
00405 BlockingStream stream = PortAudio.openStream( null, streamParameters,
00406 44100, framesPerBuffer, flags );
00407 assertTrue( "got default stream", stream != null );
00408
00409 int numFrames = 80000;
00410 stream.start();
00411 long startTime = System.currentTimeMillis();
00412 writeSineDataShort( stream, framesPerBuffer, numFrames );
00413 stream.stop();
00414 long stopTime = System.currentTimeMillis();
00415 stream.close();
00416
00417 double elapsed = (stopTime - startTime) / 1000.0;
00418 double expected = numFrames / 44100.0;
00419 assertEquals( "elapsed time to play", expected, elapsed, 0.20 );
00420 PortAudio.terminate();
00421 }
00422
00423 public void testRecordPlayFloat() throws InterruptedException
00424 {
00425 checkRecordPlay( PortAudio.FORMAT_FLOAT_32 );
00426 }
00427
00428 public void testRecordPlayShort() throws InterruptedException
00429 {
00430 checkRecordPlay( PortAudio.FORMAT_INT_16 );
00431 }
00432
00433 public void checkRecordPlay( int sampleFormat ) throws InterruptedException
00434 {
00435 int framesPerBuffer = 256;
00436 int flags = 0;
00437 int sampleRate = 44100;
00438 int numFrames = sampleRate * 3;
00439 float[] floatBuffer = null;
00440 short[] shortBuffer = null;
00441
00442 PortAudio.initialize();
00443 StreamParameters inParameters = new StreamParameters();
00444 inParameters.sampleFormat = sampleFormat;
00445 inParameters.device = PortAudio.getDefaultInputDevice();
00446
00447 DeviceInfo info = PortAudio.getDeviceInfo( inParameters.device );
00448 inParameters.channelCount = (info.maxInputChannels > 2) ? 2
00449 : info.maxInputChannels;
00450 System.out.println( "channelCount = " + inParameters.channelCount );
00451 inParameters.suggestedLatency = PortAudio
00452 .getDeviceInfo( inParameters.device ).defaultLowInputLatency;
00453
00454 if( sampleFormat == PortAudio.FORMAT_FLOAT_32 )
00455 {
00456 floatBuffer = new float[numFrames * inParameters.channelCount];
00457 }
00458 else if( sampleFormat == PortAudio.FORMAT_INT_16 )
00459 {
00460 shortBuffer = new short[numFrames * inParameters.channelCount];
00461 }
00462
00463 BlockingStream inStream = PortAudio.openStream( inParameters, null,
00464 sampleRate, framesPerBuffer, flags );
00465
00466 System.out.println( "RECORDING - say something like testing 1,2,3..." );
00467 inStream.start();
00468
00469 if( sampleFormat == PortAudio.FORMAT_FLOAT_32 )
00470 {
00471 inStream.read( floatBuffer, numFrames );
00472 }
00473 else if( sampleFormat == PortAudio.FORMAT_INT_16 )
00474 {
00475 inStream.read( shortBuffer, numFrames );
00476 }
00477 Thread.sleep( 100 );
00478 int availableToRead = inStream.getReadAvailable();
00479 System.out.println( "availableToRead = " + availableToRead );
00480 assertTrue( "getReadAvailable ", availableToRead > 0 );
00481
00482 inStream.stop();
00483 inStream.close();
00484 System.out.println( "Finished recording. Begin Playback." );
00485
00486
00487 StreamParameters outParameters = new StreamParameters();
00488 outParameters.sampleFormat = sampleFormat;
00489 outParameters.channelCount = inParameters.channelCount;
00490 outParameters.device = PortAudio.getDefaultOutputDevice();
00491 outParameters.suggestedLatency = PortAudio
00492 .getDeviceInfo( outParameters.device ).defaultLowOutputLatency;
00493
00494 BlockingStream outStream = PortAudio.openStream( null, outParameters,
00495 sampleRate, framesPerBuffer, flags );
00496 assertTrue( "got default stream", outStream != null );
00497
00498 assertEquals( "inStream isActive", false, inStream.isActive() );
00499
00500 outStream.start();
00501 Thread.sleep( 100 );
00502 int availableToWrite = outStream.getWriteAvailable();
00503 System.out.println( "availableToWrite = " + availableToWrite );
00504 assertTrue( "getWriteAvailable ", availableToWrite > 0 );
00505
00506 System.out.println( "inStream = " + inStream );
00507 System.out.println( "outStream = " + outStream );
00508 assertEquals( "inStream isActive", false, inStream.isActive() );
00509 assertEquals( "outStream isActive", true, outStream.isActive() );
00510 if( sampleFormat == PortAudio.FORMAT_FLOAT_32 )
00511 {
00512 outStream.write( floatBuffer, numFrames );
00513 }
00514 else if( sampleFormat == PortAudio.FORMAT_INT_16 )
00515 {
00516 outStream.write( shortBuffer, numFrames );
00517 }
00518 outStream.stop();
00519
00520 outStream.close();
00521 PortAudio.terminate();
00522 }
00523 }