jpa_tools.c (6342B)
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_PortAudio.h" 40 #include "portaudio.h" 41 #include "jpa_tools.h" 42 43 jint jpa_GetIntField( JNIEnv *env, jclass cls, jobject obj, const char *fieldName ) 44 { 45 /* Look for the instance field maxInputChannels in cls */ 46 jfieldID fid = (*env)->GetFieldID(env, cls, fieldName, "I"); 47 if (fid == NULL) 48 { 49 jpa_ThrowError( env, "Cannot find integer JNI field." ); 50 return 0; 51 } 52 else 53 { 54 return (*env)->GetIntField(env, obj, fid ); 55 } 56 } 57 58 void jpa_SetIntField( JNIEnv *env, jclass cls, jobject obj, const char *fieldName, jint value ) 59 { 60 /* Look for the instance field maxInputChannels in cls */ 61 jfieldID fid = (*env)->GetFieldID(env, cls, fieldName, "I"); 62 if (fid == NULL) 63 { 64 jpa_ThrowError( env, "Cannot find integer JNI field." ); 65 } 66 else 67 { 68 (*env)->SetIntField(env, obj, fid, value ); 69 } 70 } 71 72 jlong jpa_GetLongField( JNIEnv *env, jclass cls, jobject obj, const char *fieldName ) 73 { 74 /* Look for the instance field maxInputChannels in cls */ 75 jfieldID fid = (*env)->GetFieldID(env, cls, fieldName, "J"); 76 if (fid == NULL) 77 { 78 jpa_ThrowError( env, "Cannot find long JNI field." ); 79 return 0L; 80 } 81 else 82 { 83 return (*env)->GetLongField(env, obj, fid ); 84 } 85 } 86 87 void jpa_SetLongField( JNIEnv *env, jclass cls, jobject obj, const char *fieldName, jlong value ) 88 { 89 /* Look for the instance field maxInputChannels in cls */ 90 jfieldID fid = (*env)->GetFieldID(env, cls, fieldName, "J"); 91 if (fid == NULL) 92 { 93 jpa_ThrowError( env, "Cannot find long JNI field." ); 94 } 95 else 96 { 97 (*env)->SetLongField(env, obj, fid, value ); 98 } 99 } 100 101 102 void jpa_SetDoubleField( JNIEnv *env, jclass cls, jobject obj, const char *fieldName, jdouble value ) 103 { 104 /* Look for the instance field maxInputChannels in cls */ 105 jfieldID fid = (*env)->GetFieldID(env, cls, fieldName, "D"); 106 if (fid == NULL) 107 { 108 jpa_ThrowError( env, "Cannot find double JNI field." ); 109 } 110 else 111 { 112 (*env)->SetDoubleField(env, obj, fid, value ); 113 } 114 } 115 116 117 jdouble jpa_GetDoubleField( JNIEnv *env, jclass cls, jobject obj, const char *fieldName ) 118 { 119 /* Look for the instance field maxInputChannels in cls */ 120 jfieldID fid = (*env)->GetFieldID(env, cls, fieldName, "D"); 121 if (fid == NULL) 122 { 123 jpa_ThrowError( env, "Cannot find double JNI field." ); 124 return 0; 125 } 126 else 127 { 128 return (*env)->GetDoubleField(env, obj, fid ); 129 } 130 } 131 132 void jpa_SetStringField( JNIEnv *env, jclass cls, jobject obj, const char *fieldName, const char *value ) 133 { 134 /* Look for the instance field maxInputChannels in cls */ 135 jfieldID fid = (*env)->GetFieldID(env, cls, fieldName, "Ljava/lang/String;"); 136 if (fid == NULL) 137 { 138 jpa_ThrowError( env, "Cannot find String JNI field." ); 139 } 140 else 141 { 142 jstring jstr = (*env)->NewStringUTF(env, value); 143 if (jstr == NULL) 144 { 145 jpa_ThrowError( env, "Cannot create new String." ); 146 } 147 else 148 { 149 (*env)->SetObjectField(env, obj, fid, jstr ); 150 } 151 } 152 } 153 154 PaStreamParameters *jpa_FillStreamParameters( JNIEnv *env, jobject jstreamParam, PaStreamParameters *myParams ) 155 { 156 jclass cls; 157 158 if( jstreamParam == NULL ) return NULL; // OK, not an error 159 160 cls = (*env)->GetObjectClass(env, jstreamParam); 161 162 myParams->channelCount = jpa_GetIntField( env, cls, jstreamParam, "channelCount" ); 163 myParams->device = jpa_GetIntField( env, cls, jstreamParam, "device" ); 164 myParams->sampleFormat = jpa_GetIntField( env, cls, jstreamParam, "sampleFormat" ); 165 myParams->suggestedLatency = jpa_GetDoubleField( env, cls, jstreamParam, "suggestedLatency" ); 166 myParams->hostApiSpecificStreamInfo = NULL; 167 168 return myParams; 169 } 170 171 // Create an exception that will be thrown when we return from the JNI call. 172 jint jpa_ThrowError( JNIEnv *env, const char *message ) 173 { 174 return (*env)->ThrowNew(env, (*env)->FindClass( env, "java/lang/RuntimeException"), 175 message ); 176 } 177 178 // Throw an exception on error. 179 jint jpa_CheckError( JNIEnv *env, PaError err ) 180 { 181 if( err == -1 ) 182 { 183 return jpa_ThrowError( env, "-1, possibly no available default device" ); 184 } 185 else if( err < 0 ) 186 { 187 if( err == paUnanticipatedHostError ) 188 { 189 const PaHostErrorInfo *hostErrorInfo = Pa_GetLastHostErrorInfo(); 190 return jpa_ThrowError( env, hostErrorInfo->errorText ); 191 } 192 else 193 { 194 return jpa_ThrowError( env, Pa_GetErrorText( err ) ); 195 } 196 } 197 else 198 { 199 return err; 200 } 201 } 202 203 // Get the stream pointer from a BlockingStream long field. 204 PaStream *jpa_GetStreamPointer( JNIEnv *env, jobject blockingStream ) 205 { 206 jclass cls = (*env)->GetObjectClass(env, blockingStream); 207 return (PaStream *) jpa_GetLongField( env, cls, blockingStream, "nativeStream" ); 208 }