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:
parent
ac4bb571cb
commit
d693c3c583
4 changed files with 88 additions and 40 deletions
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue