com_portaudio_BlockingStream.c (9843B)
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 #include "com_portaudio_BlockingStream.h" 40 #include "portaudio.h" 41 #include "jpa_tools.h" 42 43 #ifndef FALSE 44 #define FALSE (0) 45 #endif 46 #ifndef TRUE 47 #define TRUE (!FALSE) 48 #endif 49 50 /* 51 * Class: com_portaudio_BlockingStream 52 * Method: getReadAvailable 53 * Signature: ()I 54 */ 55 JNIEXPORT jint JNICALL Java_com_portaudio_BlockingStream_getReadAvailable 56 (JNIEnv *env, jobject blockingStream) 57 { 58 PaStream *stream =jpa_GetStreamPointer( env, blockingStream ); 59 if( stream == NULL ) return 0; 60 return Pa_GetStreamReadAvailable( stream ); 61 } 62 63 /* 64 * Class: com_portaudio_BlockingStream 65 * Method: getWriteAvailable 66 * Signature: ()I 67 */ 68 JNIEXPORT jint JNICALL Java_com_portaudio_BlockingStream_getWriteAvailable 69 (JNIEnv *env, jobject blockingStream) 70 { 71 PaStream *stream =jpa_GetStreamPointer( env, blockingStream ); 72 if( stream == NULL ) return 0; 73 return Pa_GetStreamWriteAvailable( stream ); 74 } 75 76 77 /* 78 * Class: com_portaudio_BlockingStream 79 * Method: writeFloats 80 * Signature: ([FI)Z 81 */ 82 JNIEXPORT jboolean JNICALL Java_com_portaudio_BlockingStream_writeFloats 83 (JNIEnv *env, jobject blockingStream, jfloatArray buffer, jint numFrames) 84 { 85 jfloat *carr; 86 jint err; 87 PaStream *stream =jpa_GetStreamPointer( env, blockingStream ); 88 if( buffer == NULL ) 89 { 90 (*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"), 91 "null stream buffer"); 92 return FALSE; 93 } 94 carr = (*env)->GetFloatArrayElements(env, buffer, NULL); 95 if (carr == NULL) 96 { 97 (*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"), 98 "invalid stream buffer"); 99 return FALSE; 100 } 101 err = Pa_WriteStream( stream, carr, numFrames ); 102 (*env)->ReleaseFloatArrayElements(env, buffer, carr, 0); 103 if( err == paOutputUnderflowed ) 104 { 105 return TRUE; 106 } 107 else 108 { 109 jpa_CheckError( env, err ); 110 return FALSE; 111 } 112 } 113 114 /* 115 * Class: com_portaudio_BlockingStream 116 * Method: readFloats 117 * Signature: ([FI)Z 118 */ 119 JNIEXPORT jboolean JNICALL Java_com_portaudio_BlockingStream_readFloats 120 (JNIEnv *env, jobject blockingStream, jfloatArray buffer, jint numFrames) 121 { 122 jfloat *carr; 123 jint err; 124 PaStream *stream =jpa_GetStreamPointer( env, blockingStream ); 125 if( buffer == NULL ) 126 { 127 (*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"), 128 "null stream buffer"); 129 return FALSE; 130 } 131 carr = (*env)->GetFloatArrayElements(env, buffer, NULL); 132 if (carr == NULL) 133 { 134 (*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"), 135 "invalid stream buffer"); 136 return FALSE; 137 } 138 err = Pa_ReadStream( stream, carr, numFrames ); 139 (*env)->ReleaseFloatArrayElements(env, buffer, carr, 0); 140 if( err == paInputOverflowed ) 141 { 142 return TRUE; 143 } 144 else 145 { 146 jpa_CheckError( env, err ); 147 return FALSE; 148 } 149 } 150 151 /* 152 * Class: com_portaudio_BlockingStream 153 * Method: writeShorts 154 * Signature: ([SI)Z 155 */ 156 JNIEXPORT jboolean JNICALL Java_com_portaudio_BlockingStream_writeShorts 157 (JNIEnv *env, jobject blockingStream, jfloatArray buffer, jint numFrames) 158 { 159 jshort *carr; 160 jint err; 161 PaStream *stream =jpa_GetStreamPointer( env, blockingStream ); 162 if( buffer == NULL ) 163 { 164 (*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"), 165 "null stream buffer"); 166 return FALSE; 167 } 168 carr = (*env)->GetShortArrayElements(env, buffer, NULL); 169 if (carr == NULL) 170 { 171 (*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"), 172 "invalid stream buffer"); 173 return FALSE; 174 } 175 err = Pa_WriteStream( stream, carr, numFrames ); 176 (*env)->ReleaseShortArrayElements(env, buffer, carr, 0); 177 if( err == paOutputUnderflowed ) 178 { 179 return TRUE; 180 } 181 else 182 { 183 jpa_CheckError( env, err ); 184 return FALSE; 185 } 186 } 187 188 /* 189 * Class: com_portaudio_BlockingStream 190 * Method: readShorts 191 * Signature: ([SI)Z 192 */ 193 JNIEXPORT jboolean JNICALL Java_com_portaudio_BlockingStream_readShorts 194 (JNIEnv *env, jobject blockingStream, jfloatArray buffer, jint numFrames) 195 { 196 jshort *carr; 197 jint err; 198 PaStream *stream =jpa_GetStreamPointer( env, blockingStream ); 199 if( buffer == NULL ) 200 { 201 (*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"), 202 "null stream buffer"); 203 return FALSE; 204 } 205 carr = (*env)->GetShortArrayElements(env, buffer, NULL); 206 if (carr == NULL) 207 { 208 (*env)->ThrowNew( env, (*env)->FindClass(env,"java/lang/RuntimeException"), 209 "invalid stream buffer"); 210 return FALSE; 211 } 212 err = Pa_ReadStream( stream, carr, numFrames ); 213 (*env)->ReleaseShortArrayElements(env, buffer, carr, 0); 214 if( err == paInputOverflowed ) 215 { 216 return TRUE; 217 } 218 else 219 { 220 jpa_CheckError( env, err ); 221 return FALSE; 222 } 223 } 224 225 /* 226 * Class: com_portaudio_BlockingStream 227 * Method: start 228 * Signature: ()V 229 */ 230 JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_start 231 (JNIEnv *env, jobject blockingStream ) 232 { 233 PaStream *stream = jpa_GetStreamPointer( env, blockingStream ); 234 int err = Pa_StartStream( stream ); 235 jpa_CheckError( env, err ); 236 } 237 238 /* 239 * Class: com_portaudio_BlockingStream 240 * Method: stop 241 * Signature: ()V 242 */ 243 JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_stop 244 (JNIEnv *env, jobject blockingStream ) 245 { 246 PaStream *stream =jpa_GetStreamPointer( env, blockingStream ); 247 int err = Pa_StopStream( stream ); 248 jpa_CheckError( env, err ); 249 } 250 /* 251 * Class: com_portaudio_BlockingStream 252 * Method: abort 253 * Signature: ()V 254 */ 255 JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_abort 256 (JNIEnv *env, jobject blockingStream ) 257 { 258 PaStream *stream =jpa_GetStreamPointer( env, blockingStream ); 259 int err = Pa_AbortStream( stream ); 260 jpa_CheckError( env, err ); 261 } 262 263 /* 264 * Class: com_portaudio_BlockingStream 265 * Method: close 266 * Signature: ()V 267 */ 268 JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_close 269 (JNIEnv *env, jobject blockingStream ) 270 { 271 jclass cls; 272 PaStream *stream =jpa_GetStreamPointer( env, blockingStream ); 273 if( stream != NULL ) 274 { 275 int err = Pa_CloseStream( stream ); 276 jpa_CheckError( env, err ); 277 cls = (*env)->GetObjectClass(env, blockingStream); 278 jpa_SetLongField( env, cls, blockingStream, "nativeStream", (jlong) 0 ); 279 } 280 } 281 282 /* 283 * Class: com_portaudio_BlockingStream 284 * Method: isStopped 285 * Signature: ()V 286 */ 287 JNIEXPORT jboolean JNICALL Java_com_portaudio_BlockingStream_isStopped 288 (JNIEnv *env, jobject blockingStream ) 289 { 290 int err; 291 PaStream *stream =jpa_GetStreamPointer( env, blockingStream ); 292 if( stream == NULL ) return 1; 293 err = Pa_IsStreamStopped( stream ); 294 return (jpa_CheckError( env, err ) > 0); 295 } 296 /* 297 * Class: com_portaudio_BlockingStream 298 * Method: isActive 299 * Signature: ()V 300 */ 301 JNIEXPORT jboolean JNICALL Java_com_portaudio_BlockingStream_isActive 302 (JNIEnv *env, jobject blockingStream ) 303 { 304 int err; 305 PaStream *stream =jpa_GetStreamPointer( env, blockingStream ); 306 if( stream == NULL ) return 0; 307 err = Pa_IsStreamActive( stream ); 308 return (jpa_CheckError( env, err ) > 0); 309 } 310 311 312 /* 313 * Class: com_portaudio_BlockingStream 314 * Method: getTime 315 * Signature: ()D 316 */ 317 JNIEXPORT jdouble JNICALL Java_com_portaudio_BlockingStream_getTime 318 (JNIEnv *env, jobject blockingStream ) 319 { 320 PaStream *stream =jpa_GetStreamPointer( env, blockingStream ); 321 if( stream == NULL ) return 0.0; 322 return Pa_GetStreamTime( stream ); 323 } 324 325 326 /* 327 * Class: com_portaudio_BlockingStream 328 * Method: getInfo 329 * Signature: ()Lcom/portaudio/StreamInfo; 330 */ 331 JNIEXPORT void JNICALL Java_com_portaudio_BlockingStream_getInfo 332 (JNIEnv *env, jobject blockingStream, jobject streamInfo) 333 { 334 335 PaStream *stream =jpa_GetStreamPointer( env, blockingStream ); 336 const PaStreamInfo *info = Pa_GetStreamInfo( stream ); 337 if( streamInfo == NULL ) 338 { 339 jpa_ThrowError( env, "Invalid stream." ); 340 } 341 else 342 { 343 /* Get a reference to obj's class */ 344 jclass cls = (*env)->GetObjectClass(env, streamInfo); 345 346 jpa_SetIntField( env, cls, streamInfo, "structVersion", info->structVersion ); 347 jpa_SetDoubleField( env, cls, streamInfo, "inputLatency", info->inputLatency ); 348 jpa_SetDoubleField( env, cls, streamInfo, "outputLatency", info->outputLatency ); 349 jpa_SetDoubleField( env, cls, streamInfo, "sampleRate", info->sampleRate ); 350 } 351 } 352