PortAudio  2.0
jpa_tools.c
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 }
void PaStream
Definition: portaudio.h:584
const PaHostErrorInfo * Pa_GetLastHostErrorInfo(void)
void * hostApiSpecificStreamInfo
Definition: portaudio.h:528
The portable PortAudio API.
PaSampleFormat sampleFormat
Definition: portaudio.h:508
const char * errorText
Definition: portaudio.h:341
int PaError
Definition: portaudio.h:70
PaTime suggestedLatency
Definition: portaudio.h:521
PaDeviceIndex device
Definition: portaudio.h:495
const char * Pa_GetErrorText(PaError errorCode)