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 
39 package com.portaudio;
40 
41 import junit.framework.TestCase;
42 
49 public 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 }
static native int hostApiTypeIdToHostApiIndex(int hostApiType)
boolean read(float[] buffer, int numFrames)
static native void initialize()
static native int isFormatSupported(StreamParameters inputStreamParameters, StreamParameters outputStreamParameters, int sampleRate)
static native int getDeviceCount()
static native String getVersionText()
static native int hostApiDeviceIndexToDeviceIndex(int hostApiIndex, int apiDeviceIndex)
static native void terminate()
static final int FORMAT_FLOAT_32
Definition: PortAudio.java:75
static native int getVersion()
static native int getHostApiCount()
boolean write(float[] buffer, int numFrames)

Generated for PortAudio by  doxygen1.8.15