Just return true if a Java blocking IO stream underflows or overflows on read or write.

Only throw an exception if something truly nasty occurs.
This commit is contained in:
philburk 2012-09-04 18:25:58 +00:00
commit d693c3c583
4 changed files with 88 additions and 40 deletions

View file

@ -40,6 +40,13 @@
#include "portaudio.h" #include "portaudio.h"
#include "jpa_tools.h" #include "jpa_tools.h"
#ifndef FALSE
#define FALSE (0)
#endif
#ifndef TRUE
#define TRUE (!FALSE)
#endif
/* /*
* Class: com_portaudio_BlockingStream * Class: com_portaudio_BlockingStream
* Method: getReadAvailable * Method: getReadAvailable
@ -70,9 +77,9 @@ JNIEXPORT jint JNICALL Java_com_portaudio_BlockingStream_getWriteAvailable
/* /*
* Class: com_portaudio_BlockingStream * Class: com_portaudio_BlockingStream
* Method: writeFloats * Method: writeFloats
* Signature: ([FI)V * Signature: ([FI)Z
*/ */
JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_writeFloats JNIEXPORT jboolean JNICALL Java_com_portaudio_BlockingStream_writeFloats
(JNIEnv *env, jobject blockingStream, jfloatArray buffer, jint numFrames) (JNIEnv *env, jobject blockingStream, jfloatArray buffer, jint numFrames)
{ {
jfloat *carr; jfloat *carr;
@ -82,26 +89,34 @@ JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_writeFloats
{ {
(*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"), (*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"),
"null stream buffer"); "null stream buffer");
return; return FALSE;
} }
carr = (*env)->GetFloatArrayElements(env, buffer, NULL); carr = (*env)->GetFloatArrayElements(env, buffer, NULL);
if (carr == NULL) if (carr == NULL)
{ {
(*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"), (*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"),
"invalid stream buffer"); "invalid stream buffer");
return; return FALSE;
} }
err = Pa_WriteStream( stream, carr, numFrames ); err = Pa_WriteStream( stream, carr, numFrames );
(*env)->ReleaseFloatArrayElements(env, buffer, carr, 0); (*env)->ReleaseFloatArrayElements(env, buffer, carr, 0);
jpa_CheckError( env, err ); if( err == paOutputUnderflowed )
{
return TRUE;
}
else
{
jpa_CheckError( env, err );
return FALSE;
}
} }
/* /*
* Class: com_portaudio_BlockingStream * Class: com_portaudio_BlockingStream
* Method: readFloats * Method: readFloats
* Signature: ([FI)V * Signature: ([FI)Z
*/ */
JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_readFloats JNIEXPORT jboolean JNICALL Java_com_portaudio_BlockingStream_readFloats
(JNIEnv *env, jobject blockingStream, jfloatArray buffer, jint numFrames) (JNIEnv *env, jobject blockingStream, jfloatArray buffer, jint numFrames)
{ {
jfloat *carr; jfloat *carr;
@ -111,25 +126,34 @@ JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_readFloats
{ {
(*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"), (*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"),
"null stream buffer"); "null stream buffer");
return; return FALSE;
} }
carr = (*env)->GetFloatArrayElements(env, buffer, NULL); carr = (*env)->GetFloatArrayElements(env, buffer, NULL);
if (carr == NULL) if (carr == NULL)
{ {
(*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"), (*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"),
"invalid stream buffer"); "invalid stream buffer");
return; return FALSE;
} }
err = Pa_ReadStream( stream, carr, numFrames ); err = Pa_ReadStream( stream, carr, numFrames );
(*env)->ReleaseFloatArrayElements(env, buffer, carr, 0); (*env)->ReleaseFloatArrayElements(env, buffer, carr, 0);
jpa_CheckError( env, err ); if( err == paInputOverflowed )
{
return TRUE;
}
else
{
jpa_CheckError( env, err );
return FALSE;
}
} }
/* /*
* Class: com_portaudio_BlockingStream * Class: com_portaudio_BlockingStream
* Method: writeShorts * Method: writeShorts
* Signature: ([FI)V * Signature: ([SI)Z
*/ */
JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_writeShorts JNIEXPORT jboolean JNICALL Java_com_portaudio_BlockingStream_writeShorts
(JNIEnv *env, jobject blockingStream, jfloatArray buffer, jint numFrames) (JNIEnv *env, jobject blockingStream, jfloatArray buffer, jint numFrames)
{ {
jshort *carr; jshort *carr;
@ -139,26 +163,34 @@ JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_writeShorts
{ {
(*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"), (*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"),
"null stream buffer"); "null stream buffer");
return; return FALSE;
} }
carr = (*env)->GetShortArrayElements(env, buffer, NULL); carr = (*env)->GetShortArrayElements(env, buffer, NULL);
if (carr == NULL) if (carr == NULL)
{ {
(*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"), (*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"),
"invalid stream buffer"); "invalid stream buffer");
return; return FALSE;
} }
err = Pa_WriteStream( stream, carr, numFrames ); err = Pa_WriteStream( stream, carr, numFrames );
(*env)->ReleaseShortArrayElements(env, buffer, carr, 0); (*env)->ReleaseShortArrayElements(env, buffer, carr, 0);
jpa_CheckError( env, err ); if( err == paOutputUnderflowed )
{
return TRUE;
}
else
{
jpa_CheckError( env, err );
return FALSE;
}
} }
/* /*
* Class: com_portaudio_BlockingStream * Class: com_portaudio_BlockingStream
* Method: readShorts * Method: readShorts
* Signature: ([FI)V * Signature: ([SI)Z
*/ */
JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_readShorts JNIEXPORT jboolean JNICALL Java_com_portaudio_BlockingStream_readShorts
(JNIEnv *env, jobject blockingStream, jfloatArray buffer, jint numFrames) (JNIEnv *env, jobject blockingStream, jfloatArray buffer, jint numFrames)
{ {
jshort *carr; jshort *carr;
@ -168,18 +200,26 @@ JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_readShorts
{ {
(*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"), (*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"),
"null stream buffer"); "null stream buffer");
return; return FALSE;
} }
carr = (*env)->GetShortArrayElements(env, buffer, NULL); carr = (*env)->GetShortArrayElements(env, buffer, NULL);
if (carr == NULL) if (carr == NULL)
{ {
(*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"), (*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"),
"invalid stream buffer"); "invalid stream buffer");
return; return FALSE;
} }
err = Pa_ReadStream( stream, carr, numFrames ); err = Pa_ReadStream( stream, carr, numFrames );
(*env)->ReleaseShortArrayElements(env, buffer, carr, 0); (*env)->ReleaseShortArrayElements(env, buffer, carr, 0);
jpa_CheckError( env, err ); if( err == paInputOverflowed )
{
return TRUE;
}
else
{
jpa_CheckError( env, err );
return FALSE;
}
} }
/* /*

View file

@ -31,33 +31,33 @@ JNIEXPORT jint JNICALL Java_com_portaudio_BlockingStream_getWriteAvailable
/* /*
* Class: com_portaudio_BlockingStream * Class: com_portaudio_BlockingStream
* Method: readFloats * Method: readFloats
* Signature: ([FI)V * Signature: ([FI)Z
*/ */
JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_readFloats JNIEXPORT jboolean JNICALL Java_com_portaudio_BlockingStream_readFloats
(JNIEnv *, jobject, jfloatArray, jint); (JNIEnv *, jobject, jfloatArray, jint);
/* /*
* Class: com_portaudio_BlockingStream * Class: com_portaudio_BlockingStream
* Method: writeFloats * Method: writeFloats
* Signature: ([FI)V * Signature: ([FI)Z
*/ */
JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_writeFloats JNIEXPORT jboolean JNICALL Java_com_portaudio_BlockingStream_writeFloats
(JNIEnv *, jobject, jfloatArray, jint); (JNIEnv *, jobject, jfloatArray, jint);
/* /*
* Class: com_portaudio_BlockingStream * Class: com_portaudio_BlockingStream
* Method: readShorts * Method: readShorts
* Signature: ([SI)V * Signature: ([SI)Z
*/ */
JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_readShorts JNIEXPORT jboolean JNICALL Java_com_portaudio_BlockingStream_readShorts
(JNIEnv *, jobject, jshortArray, jint); (JNIEnv *, jobject, jshortArray, jint);
/* /*
* Class: com_portaudio_BlockingStream * Class: com_portaudio_BlockingStream
* Method: writeShorts * Method: writeShorts
* Signature: ([SI)V * Signature: ([SI)Z
*/ */
JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_writeShorts JNIEXPORT jboolean JNICALL Java_com_portaudio_BlockingStream_writeShorts
(JNIEnv *, jobject, jshortArray, jint); (JNIEnv *, jobject, jshortArray, jint);
/* /*

View file

@ -1,5 +1,9 @@
/* DO NOT EDIT THIS FILE - it is machine generated */ /* DO NOT EDIT THIS FILE - it is machine generated */
#if defined(__APPLE__)
#include <JavaVM/jni.h> #include <JavaVM/jni.h>
#else
#include <jni.h>
#endif
/* Header for class com_portaudio_PortAudio */ /* Header for class com_portaudio_PortAudio */
#ifndef _Included_com_portaudio_PortAudio #ifndef _Included_com_portaudio_PortAudio

View file

@ -71,9 +71,9 @@ public class BlockingStream
*/ */
public native int getWriteAvailable(); public native int getWriteAvailable();
private native void readFloats( float[] buffer, int numFrames ); private native boolean readFloats( float[] buffer, int numFrames );
private native void writeFloats( float[] buffer, int numFrames ); private native boolean writeFloats( float[] buffer, int numFrames );
/** /**
* Read 32-bit floating point data from the stream into the array. * Read 32-bit floating point data from the stream into the array.
@ -81,15 +81,16 @@ public class BlockingStream
* @param buffer * @param buffer
* @param numFrames * @param numFrames
* number of frames to read * number of frames to read
* @return true if an input overflow occurred
*/ */
public void read( float[] buffer, int numFrames ) public boolean read( float[] buffer, int numFrames )
{ {
if( inputFormat != PortAudio.FORMAT_FLOAT_32 ) if( inputFormat != PortAudio.FORMAT_FLOAT_32 )
{ {
throw new RuntimeException( throw new RuntimeException(
"Tried to read float samples from a non float stream." ); "Tried to read float samples from a non float stream." );
} }
readFloats( buffer, numFrames ); return readFloats( buffer, numFrames );
} }
/** /**
@ -99,20 +100,21 @@ public class BlockingStream
* @param buffer * @param buffer
* @param numFrames * @param numFrames
* number of frames to write * number of frames to write
* @return true if an output underflow occurred
*/ */
public void write( float[] buffer, int numFrames ) public boolean write( float[] buffer, int numFrames )
{ {
if( outputFormat != PortAudio.FORMAT_FLOAT_32 ) if( outputFormat != PortAudio.FORMAT_FLOAT_32 )
{ {
throw new RuntimeException( throw new RuntimeException(
"Tried to write float samples to a non float stream." ); "Tried to write float samples to a non float stream." );
} }
writeFloats( buffer, numFrames ); return writeFloats( buffer, numFrames );
} }
private native void readShorts( short[] buffer, int numFrames ); private native boolean readShorts( short[] buffer, int numFrames );
private native void writeShorts( short[] buffer, int numFrames ); private native boolean writeShorts( short[] buffer, int numFrames );
/** /**
* Read 16-bit integer data to the stream from the array. * Read 16-bit integer data to the stream from the array.
@ -120,15 +122,16 @@ public class BlockingStream
* @param buffer * @param buffer
* @param numFrames * @param numFrames
* number of frames to write * number of frames to write
* @return true if an input overflow occurred
*/ */
public void read( short[] buffer, int numFrames ) public boolean read( short[] buffer, int numFrames )
{ {
if( inputFormat != PortAudio.FORMAT_INT_16 ) if( inputFormat != PortAudio.FORMAT_INT_16 )
{ {
throw new RuntimeException( throw new RuntimeException(
"Tried to read short samples from a non short stream." ); "Tried to read short samples from a non short stream." );
} }
readShorts( buffer, numFrames ); return readShorts( buffer, numFrames );
} }
/** /**
@ -137,15 +140,16 @@ public class BlockingStream
* @param buffer * @param buffer
* @param numFrames * @param numFrames
* number of frames to write * number of frames to write
* @return true if an output underflow occurred
*/ */
public void write( short[] buffer, int numFrames ) public boolean write( short[] buffer, int numFrames )
{ {
if( outputFormat != PortAudio.FORMAT_INT_16 ) if( outputFormat != PortAudio.FORMAT_INT_16 )
{ {
throw new RuntimeException( throw new RuntimeException(
"Tried to write short samples from a non short stream." ); "Tried to write short samples from a non short stream." );
} }
writeShorts( buffer, numFrames ); return writeShorts( buffer, numFrames );
} }
/** /**