~ubuntu-branches/ubuntu/oneiric/openjdk-7/oneiric-security

« back to all changes in this revision

Viewing changes to pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2012-10-17 16:22:48 UTC
  • mfrom: (1.3.11) (8.1.25 quantal)
  • Revision ID: package-import@ubuntu.com-20121017162248-steblyv2lnk2t951
Tags: 7u9-2.3.3-0ubuntu1~11.10.1
Build IcedTea7 2.3.3 for oneiric.

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
#define CONTEXT_POINTER "contextPointer"
9
9
 
10
10
typedef struct java_context {
11
 
        JNIEnv* env;
12
 
        jobject obj;
 
11
    JNIEnv* env;
 
12
    jobject obj;
13
13
} java_context;
14
14
 
15
15
extern JNIEnv* pulse_thread_env;
16
16
 
17
17
static void set_sink_input_volume_callback(pa_context* context, int success,
18
 
                void* userdata) {
19
 
        notifyWaitingOperations(pulse_thread_env);
 
18
        void* userdata) {
 
19
    notifyWaitingOperations(pulse_thread_env);
20
20
 
21
21
}
22
22
 
23
23
const char* getStringFromFormat(pa_sample_format_t format) {
24
24
 
25
 
        const char* value;
26
 
 
27
 
        if (format == PA_SAMPLE_U8) {
28
 
                value = "PA_SAMPLE_U8";
29
 
        } else if (format == PA_SAMPLE_ALAW) {
30
 
                value = "PA_SAMPLE_ALAW";
31
 
        } else if (format == PA_SAMPLE_ULAW) {
32
 
                value = "PA_SAMPLE_ULAW";
33
 
        } else if (format == PA_SAMPLE_S16BE) {
34
 
                value = "PA_SAMPLE_S16BE";
35
 
        } else if (format == PA_SAMPLE_S16LE) {
36
 
                value = "PA_SAMPLE_S16LE";
37
 
        } else if (format == PA_SAMPLE_S32BE) {
38
 
                value = "PA_SAMPLE_S32BE";
39
 
        } else if (format == PA_SAMPLE_S32LE) {
40
 
                value = "PA_SAMPLE_S32LE";
41
 
        } else {
42
 
                value = "PA_SAMPLE_INVALID";
43
 
        }
44
 
 
45
 
        return value;
 
25
    const char* value;
 
26
 
 
27
    if (format == PA_SAMPLE_U8) {
 
28
        value = "PA_SAMPLE_U8";
 
29
    } else if (format == PA_SAMPLE_ALAW) {
 
30
        value = "PA_SAMPLE_ALAW";
 
31
    } else if (format == PA_SAMPLE_ULAW) {
 
32
        value = "PA_SAMPLE_ULAW";
 
33
    } else if (format == PA_SAMPLE_S16BE) {
 
34
        value = "PA_SAMPLE_S16BE";
 
35
    } else if (format == PA_SAMPLE_S16LE) {
 
36
        value = "PA_SAMPLE_S16LE";
 
37
    } else if (format == PA_SAMPLE_S32BE) {
 
38
        value = "PA_SAMPLE_S32BE";
 
39
    } else if (format == PA_SAMPLE_S32LE) {
 
40
        value = "PA_SAMPLE_S32LE";
 
41
    } else {
 
42
        value = "PA_SAMPLE_INVALID";
 
43
    }
 
44
 
 
45
    return value;
46
46
}
47
47
 
48
48
pa_sample_format_t getFormatFromString(const char* encoding) {
49
49
 
50
 
        pa_sample_format_t format;
51
 
 
52
 
        if (strcmp(encoding, "PA_SAMPLE_U8") == 0) {
53
 
                format = PA_SAMPLE_U8;
54
 
        } else if (strcmp(encoding, "PA_SAMPLE_ALAW") == 0) {
55
 
                format = PA_SAMPLE_ALAW;
56
 
        } else if (strcmp(encoding, "PA_SAMPLE_ULAW;") == 0) {
57
 
                format = PA_SAMPLE_ULAW;
58
 
        } else if (strcmp(encoding, "PA_SAMPLE_S16BE") == 0) {
59
 
                format = PA_SAMPLE_S16BE;
60
 
        } else if (strcmp(encoding, "PA_SAMPLE_S16LE") == 0) {
61
 
                format = PA_SAMPLE_S16LE;
62
 
        } else if (strcmp(encoding, "PA_SAMPLE_S32BE") == 0) {
63
 
                format = PA_SAMPLE_S32BE;
64
 
        } else if (strcmp(encoding, "PA_SAMPLE_S32LE") == 0) {
65
 
                format = PA_SAMPLE_S32LE;
66
 
        } else {
67
 
                format = PA_SAMPLE_INVALID;
68
 
        }
69
 
 
70
 
        return format;
 
50
    pa_sample_format_t format;
 
51
 
 
52
    if (strcmp(encoding, "PA_SAMPLE_U8") == 0) {
 
53
        format = PA_SAMPLE_U8;
 
54
    } else if (strcmp(encoding, "PA_SAMPLE_ALAW") == 0) {
 
55
        format = PA_SAMPLE_ALAW;
 
56
    } else if (strcmp(encoding, "PA_SAMPLE_ULAW;") == 0) {
 
57
        format = PA_SAMPLE_ULAW;
 
58
    } else if (strcmp(encoding, "PA_SAMPLE_S16BE") == 0) {
 
59
        format = PA_SAMPLE_S16BE;
 
60
    } else if (strcmp(encoding, "PA_SAMPLE_S16LE") == 0) {
 
61
        format = PA_SAMPLE_S16LE;
 
62
    } else if (strcmp(encoding, "PA_SAMPLE_S32BE") == 0) {
 
63
        format = PA_SAMPLE_S32BE;
 
64
    } else if (strcmp(encoding, "PA_SAMPLE_S32LE") == 0) {
 
65
        format = PA_SAMPLE_S32LE;
 
66
    } else {
 
67
        format = PA_SAMPLE_INVALID;
 
68
    }
 
69
 
 
70
    return format;
71
71
}
72
72
 
73
73
static void stream_state_callback(pa_stream* stream, void *userdata) {
74
 
        //printf("stream_state_callback called\n");
75
 
 
76
 
        java_context* context = userdata;
77
 
        assert(stream);
78
 
        assert(context);
79
 
        assert(context->env);
80
 
        assert(context->obj);
81
 
 
82
 
        if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
83
 
                callJavaVoidMethod(context->env, context->obj, "stateCallback");
84
 
        } else {
85
 
                callJavaVoidMethod(pulse_thread_env, context->obj, "stateCallback");
86
 
        }
 
74
    //printf("stream_state_callback called\n");
 
75
 
 
76
    java_context* context = userdata;
 
77
    assert(stream);
 
78
    assert(context);
 
79
    assert(context->env);
 
80
    assert(context->obj);
 
81
 
 
82
    if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
 
83
        callJavaVoidMethod(context->env, context->obj, "stateCallback");
 
84
    } else {
 
85
        callJavaVoidMethod(pulse_thread_env, context->obj, "stateCallback");
 
86
    }
87
87
 
88
88
}
89
89
 
90
90
static void stream_write_callback(pa_stream *stream, size_t length,
91
 
                void *userdata) {
92
 
        //      printf("stream_write_callback called\n");
93
 
 
94
 
        java_context* context = userdata;
95
 
        assert(stream);
96
 
        assert(context);
97
 
        assert(context->env);
98
 
        assert(context->obj);
99
 
 
100
 
        if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
101
 
                callJavaVoidMethod(context->env, context->obj, "writeCallback");
102
 
        } else {
103
 
                callJavaVoidMethod(pulse_thread_env, context->obj, "writeCallback");
104
 
        }
 
91
        void *userdata) {
 
92
    //    printf("stream_write_callback called\n");
 
93
 
 
94
    java_context* context = userdata;
 
95
    assert(stream);
 
96
    assert(context);
 
97
    assert(context->env);
 
98
    assert(context->obj);
 
99
 
 
100
    if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
 
101
        callJavaVoidMethod(context->env, context->obj, "writeCallback");
 
102
    } else {
 
103
        callJavaVoidMethod(pulse_thread_env, context->obj, "writeCallback");
 
104
    }
105
105
}
106
106
 
107
107
static void stream_read_callback(pa_stream *stream, size_t length,
108
 
                void *userdata) {
109
 
        //      printf("stream_read_callback called\n");
110
 
 
111
 
        java_context* context = userdata;
112
 
        assert(stream);
113
 
        assert(context);
114
 
        assert(context->env);
115
 
        assert(context->obj);
116
 
 
117
 
        if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
118
 
                callJavaVoidMethod(context->env, context->obj, "readCallback");
119
 
        } else {
120
 
                callJavaVoidMethod(pulse_thread_env, context->obj, "readCallback");
121
 
        }
 
108
        void *userdata) {
 
109
    //    printf("stream_read_callback called\n");
 
110
 
 
111
    java_context* context = userdata;
 
112
    assert(stream);
 
113
    assert(context);
 
114
    assert(context->env);
 
115
    assert(context->obj);
 
116
 
 
117
    if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
 
118
        callJavaVoidMethod(context->env, context->obj, "readCallback");
 
119
    } else {
 
120
        callJavaVoidMethod(pulse_thread_env, context->obj, "readCallback");
 
121
    }
122
122
 
123
123
}
124
124
 
125
125
static void stream_overflow_callback(pa_stream *stream, void *userdata) {
126
 
        //printf("stream_overflow_callback called\n");
127
 
 
128
 
        java_context* context = userdata;
129
 
        assert(stream);
130
 
        assert(context);
131
 
        assert(context->env);
132
 
        assert(context->obj);
133
 
 
134
 
        if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
135
 
                callJavaVoidMethod(context->env, context->obj, "overflowCallback");
136
 
        } else {
137
 
                callJavaVoidMethod(pulse_thread_env, context->obj, "overflowCallback");
138
 
        }
 
126
    //printf("stream_overflow_callback called\n");
 
127
 
 
128
    java_context* context = userdata;
 
129
    assert(stream);
 
130
    assert(context);
 
131
    assert(context->env);
 
132
    assert(context->obj);
 
133
 
 
134
    if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
 
135
        callJavaVoidMethod(context->env, context->obj, "overflowCallback");
 
136
    } else {
 
137
        callJavaVoidMethod(pulse_thread_env, context->obj, "overflowCallback");
 
138
    }
139
139
}
140
140
 
141
141
static void stream_underflow_callback(pa_stream *stream, void *userdata) {
142
 
        //      printf("stream_underflow_callback called\n");
143
 
 
144
 
        java_context* context = userdata;
145
 
        assert(stream);
146
 
        assert(context);
147
 
        assert(context->env);
148
 
        assert(context->obj);
149
 
 
150
 
        if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
151
 
                callJavaVoidMethod(context->env, context->obj, "underflowCallback");
152
 
        } else {
153
 
                callJavaVoidMethod(pulse_thread_env, context->obj, "underflowCallback");
154
 
        }
 
142
    //    printf("stream_underflow_callback called\n");
 
143
 
 
144
    java_context* context = userdata;
 
145
    assert(stream);
 
146
    assert(context);
 
147
    assert(context->env);
 
148
    assert(context->obj);
 
149
 
 
150
    if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
 
151
        callJavaVoidMethod(context->env, context->obj, "underflowCallback");
 
152
    } else {
 
153
        callJavaVoidMethod(pulse_thread_env, context->obj, "underflowCallback");
 
154
    }
155
155
}
156
156
 
157
157
 
158
158
static void update_timing_info_callback(pa_stream* stream, int success, void* userdata) {
159
159
 
160
 
        assert(stream);
161
 
        JNIEnv* env = pulse_thread_env;
162
 
        assert(env);
163
 
 
164
 
        notifyWaitingOperations(env);
165
 
 
166
 
        if (success == 0) {
167
 
                throwByName(env, ILLEGAL_STATE_EXCEPTION, "drain failed");
168
 
        }
 
160
    assert(stream);
 
161
    JNIEnv* env = pulse_thread_env;
 
162
    assert(env);
 
163
 
 
164
    notifyWaitingOperations(env);
 
165
 
 
166
    if (success == 0) {
 
167
        throwByName(env, ILLEGAL_STATE_EXCEPTION, "drain failed");
 
168
    }
169
169
 
170
170
}
171
171
 
172
 
 
173
172
// requires pulseaudio 0.9.11 :(
174
173
static void stream_started_callback(pa_stream *stream, void *userdata) {
175
 
        // printf("stream_started_callback called\n");
176
 
        java_context* context = userdata;
177
 
        assert(stream);
178
 
        assert(context);
179
 
        assert(context->env);
180
 
        assert(context->obj);
 
174
    // printf("stream_started_callback called\n");
 
175
    java_context* context = userdata;
 
176
    assert(stream);
 
177
    assert(context);
 
178
    assert(context->env);
 
179
    assert(context->obj);
181
180
 
182
 
        if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
183
 
                callJavaVoidMethod(context->env, context->obj,
184
 
                                "playbackStartedCallback");
185
 
        } else {
186
 
                callJavaVoidMethod(pulse_thread_env, context->obj,
187
 
                                "playbackStartedCallback");
188
 
        }
 
181
    if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
 
182
        callJavaVoidMethod(context->env, context->obj,
 
183
                "playbackStartedCallback");
 
184
    } else {
 
185
        callJavaVoidMethod(pulse_thread_env, context->obj,
 
186
                "playbackStartedCallback");
 
187
    }
189
188
 
190
189
}
191
190
 
192
191
static void stream_latency_update_callback(pa_stream *stream, void *userdata) {
193
 
        //      printf("stream_latency_update_callback called\n");
194
 
 
195
 
        java_context* context = userdata;
196
 
        assert(stream);
197
 
        assert(context);
198
 
        assert(context->env);
199
 
        assert(context->obj);
200
 
 
201
 
        if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
202
 
                callJavaVoidMethod(context->env, context->obj, "latencyUpdateCallback");
203
 
        } else {
204
 
                callJavaVoidMethod(pulse_thread_env, context->obj,
205
 
                                "latencyUpdateCallback");
206
 
        }
 
192
    //    printf("stream_latency_update_callback called\n");
 
193
 
 
194
    java_context* context = userdata;
 
195
    assert(stream);
 
196
    assert(context);
 
197
    assert(context->env);
 
198
    assert(context->obj);
 
199
 
 
200
    if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
 
201
        callJavaVoidMethod(context->env, context->obj, "latencyUpdateCallback");
 
202
    } else {
 
203
        callJavaVoidMethod(pulse_thread_env, context->obj,
 
204
                "latencyUpdateCallback");
 
205
    }
207
206
}
208
207
 
209
208
static void stream_moved_callback(pa_stream *stream, void *userdata) {
210
 
        //      printf("stream_moved_callback called\n");
211
 
 
212
 
        java_context* context = userdata;
213
 
        assert(stream);
214
 
        assert(context);
215
 
        assert(context->env);
216
 
        assert(context->obj);
217
 
 
218
 
        if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
219
 
                callJavaVoidMethod(context->env, context->obj, "movedCallback");
220
 
        } else {
221
 
                callJavaVoidMethod(pulse_thread_env, context->obj, "movedCallback");
222
 
        }
 
209
    //    printf("stream_moved_callback called\n");
 
210
 
 
211
    java_context* context = userdata;
 
212
    assert(stream);
 
213
    assert(context);
 
214
    assert(context->env);
 
215
    assert(context->obj);
 
216
 
 
217
    if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
 
218
        callJavaVoidMethod(context->env, context->obj, "movedCallback");
 
219
    } else {
 
220
        callJavaVoidMethod(pulse_thread_env, context->obj, "movedCallback");
 
221
    }
223
222
 
224
223
}
225
224
 
226
225
static void stream_suspended_callback(pa_stream *stream, void *userdata) {
227
 
        //      printf("stream_suspended_callback called\n");
228
 
 
229
 
        java_context* context = userdata;
230
 
        assert(stream);
231
 
        assert(context);
232
 
        assert(context->env);
233
 
        assert(context->obj);
234
 
 
235
 
        if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
236
 
                callJavaVoidMethod(context->env, context->obj, "suspendedCallback");
237
 
        } else {
238
 
                callJavaVoidMethod(pulse_thread_env, context->obj, "suspendedCallback");
239
 
        }
240
 
 
 
226
    //    printf("stream_suspended_callback called\n");
 
227
 
 
228
    java_context* context = userdata;
 
229
    assert(stream);
 
230
    assert(context);
 
231
    assert(context->env);
 
232
    assert(context->obj);
 
233
 
 
234
    if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
 
235
        callJavaVoidMethod(context->env, context->obj, "suspendedCallback");
 
236
    } else {
 
237
        callJavaVoidMethod(pulse_thread_env, context->obj, "suspendedCallback");
 
238
    }
 
239
 
 
240
}
 
241
 
 
242
static void buf_attr_changed_callback(pa_stream *stream, void *userdata) {
 
243
    java_context* context = userdata;
 
244
    assert(stream);
 
245
    assert(context);
 
246
    assert(context->env);
 
247
    assert(context->obj);
 
248
 
 
249
    if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
 
250
        callJavaVoidMethod(context->env, context->obj, "bufferAttrCallback");
 
251
    } else {
 
252
        callJavaVoidMethod(pulse_thread_env, context->obj, "bufferAttrCallback");
 
253
    }
 
254
}
 
255
 
 
256
// used to set stream flags and states.
 
257
// The names in Stream.java have a {STATE_,FLAG_} prefix, but we don't want to
 
258
// add the underscore in every line in init_constants, so we add it here. If
 
259
// constants with no prefix are ever introduced (i.e. java_prefix is "",
 
260
// it's important to remove the ##_ )
 
261
#define SET_STREAM_ENUM(env, clz, java_prefix, state_name) \
 
262
    SET_JAVA_STATIC_LONG_FIELD_TO_PA_ENUM(env, clz, java_prefix##_, STREAM, state_name)
 
263
 
 
264
/*
 
265
 * Class:     org_classpath_icedtea_pulseaudio_Stream
 
266
 * Method:    init_constants
 
267
 * Signature: ()V
 
268
 */
 
269
JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_init_1constants
 
270
  (JNIEnv *env, jclass clz) {
 
271
    // set states.
 
272
    SET_STREAM_ENUM(env, clz, STATE, UNCONNECTED);
 
273
    SET_STREAM_ENUM(env, clz, STATE, CREATING);
 
274
    SET_STREAM_ENUM(env, clz, STATE, READY);
 
275
    SET_STREAM_ENUM(env, clz, STATE, FAILED);
 
276
    SET_STREAM_ENUM(env, clz, STATE, TERMINATED);
 
277
 
 
278
    // set flags.
 
279
    SET_STREAM_ENUM(env, clz, FLAG, NOFLAGS);
 
280
    SET_STREAM_ENUM(env, clz, FLAG, START_CORKED);
 
281
    SET_STREAM_ENUM(env, clz, FLAG, INTERPOLATE_TIMING);
 
282
    SET_STREAM_ENUM(env, clz, FLAG, NOT_MONOTONIC);
 
283
    SET_STREAM_ENUM(env, clz, FLAG, AUTO_TIMING_UPDATE);
 
284
    SET_STREAM_ENUM(env, clz, FLAG, NO_REMAP_CHANNELS);
 
285
    SET_STREAM_ENUM(env, clz, FLAG, NO_REMIX_CHANNELS);
 
286
    SET_STREAM_ENUM(env, clz, FLAG, FIX_FORMAT);
 
287
    SET_STREAM_ENUM(env, clz, FLAG, FIX_RATE);
 
288
    SET_STREAM_ENUM(env, clz, FLAG, FIX_CHANNELS);
 
289
    SET_STREAM_ENUM(env, clz, FLAG, DONT_MOVE);
 
290
    SET_STREAM_ENUM(env, clz, FLAG, VARIABLE_RATE);
 
291
    SET_STREAM_ENUM(env, clz, FLAG, PEAK_DETECT);
 
292
    SET_STREAM_ENUM(env, clz, FLAG, START_MUTED);
 
293
    SET_STREAM_ENUM(env, clz, FLAG, ADJUST_LATENCY);
 
294
    SET_STREAM_ENUM(env, clz, FLAG, EARLY_REQUESTS);
 
295
    SET_STREAM_ENUM(env, clz, FLAG, DONT_INHIBIT_AUTO_SUSPEND);
 
296
    SET_STREAM_ENUM(env, clz, FLAG, START_UNMUTED);
 
297
    SET_STREAM_ENUM(env, clz, FLAG, FAIL_ON_SUSPEND);
241
298
}
242
299
 
243
300
/*
247
304
 */
248
305
JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1new
249
306
(JNIEnv* env, jobject obj, jbyteArray contextPointer, jstring nameString,
250
 
                jstring encodingString, jint sampleRate, jint channels) {
251
 
 
252
 
        //      printf("creating a new PulseAudio stream\n");
253
 
 
254
 
        java_context* j_context = malloc(sizeof(java_context));
255
 
        assert(j_context);
256
 
        j_context->env = env;
257
 
        j_context->obj = (*env)->NewGlobalRef(env, obj);
258
 
 
259
 
        pa_context* context = convertJavaPointerToNative(env, contextPointer);
260
 
        assert(context);
261
 
 
262
 
        const char* name = NULL;
263
 
        if (nameString) {
264
 
                name = (*env)->GetStringUTFChars(env,nameString, NULL);
265
 
                if (name == NULL) {
266
 
                        (*env)->DeleteGlobalRef(env, obj);
267
 
                        free(j_context);
268
 
                        return; // oome thrown
269
 
                }
270
 
        }
271
 
 
272
 
        const char *encoding = (*env)->GetStringUTFChars(env, encodingString, NULL);
273
 
        if( encoding == NULL) {
274
 
                return; //oome thrown
275
 
        }
276
 
 
277
 
        pa_sample_spec sample_spec;
278
 
 
279
 
        sample_spec.format = getFormatFromString(encoding);
280
 
        sample_spec.rate = sampleRate;
281
 
        sample_spec.channels = channels;
282
 
 
283
 
        if ( !pa_sample_spec_valid(&sample_spec)) {
284
 
                throwByName(env, "java/lang/IllegalArgumentException", "Invalid format");
285
 
                (*env)->ReleaseStringUTFChars(env, encodingString, encoding);
286
 
                if (name) {
287
 
                        (*env)->ReleaseStringUTFChars(env, nameString,name);
288
 
                }
289
 
                return;
290
 
        }
291
 
 
292
 
        pa_stream* stream = pa_stream_new(context, name, &sample_spec, NULL);
293
 
        assert(stream);
294
 
        if (name) {
295
 
                (*env)->ReleaseStringUTFChars(env, nameString,name);
296
 
        }
297
 
 
298
 
        setJavaPointer(env, obj, "streamPointer", stream);
299
 
 
300
 
        /*
301
 
         *
302
 
         * The stream has been created; now setup the callbacks
303
 
         * so we can do somethig about them
304
 
         *
305
 
         */
306
 
 
307
 
        pa_stream_set_state_callback (stream, stream_state_callback, j_context);
308
 
        pa_stream_set_write_callback (stream, stream_write_callback, j_context);
309
 
        pa_stream_set_read_callback (stream, stream_read_callback, j_context);
310
 
        pa_stream_set_overflow_callback (stream, stream_overflow_callback, j_context);
311
 
        pa_stream_set_underflow_callback (stream, stream_underflow_callback, j_context);
312
 
        pa_stream_set_started_callback (stream, stream_started_callback, j_context);
313
 
        pa_stream_set_latency_update_callback (stream, stream_latency_update_callback, j_context);
314
 
        pa_stream_set_moved_callback (stream, stream_moved_callback, j_context);
315
 
        pa_stream_set_suspended_callback (stream, stream_suspended_callback, j_context);
316
 
 
 
307
        jstring encodingString, jint sampleRate, jint channels) {
 
308
 
 
309
    //    printf("creating a new PulseAudio stream\n");
 
310
 
 
311
    java_context* j_context = malloc(sizeof(java_context));
 
312
    assert(j_context);
 
313
    j_context->env = env;
 
314
    j_context->obj = (*env)->NewGlobalRef(env, obj);
 
315
 
 
316
    setJavaPointer(env, obj, CONTEXT_POINTER, j_context);
 
317
 
 
318
    pa_context* context = convertJavaPointerToNative(env, contextPointer);
 
319
    assert(context);
 
320
 
 
321
    const char* name = NULL;
 
322
    if (nameString) {
 
323
        name = (*env)->GetStringUTFChars(env,nameString, NULL);
 
324
        if (name == NULL) {
 
325
            (*env)->DeleteGlobalRef(env, obj);
 
326
            free(j_context);
 
327
            return; // oome thrown
 
328
        }
 
329
    }
 
330
 
 
331
    const char *encoding = (*env)->GetStringUTFChars(env, encodingString, NULL);
 
332
    if( encoding == NULL) {
 
333
        return; //oome thrown
 
334
    }
 
335
 
 
336
    pa_sample_spec sample_spec;
 
337
 
 
338
    sample_spec.format = getFormatFromString(encoding);
 
339
    sample_spec.rate = sampleRate;
 
340
    sample_spec.channels = channels;
 
341
 
 
342
    if ( !pa_sample_spec_valid(&sample_spec)) {
 
343
        throwByName(env, "java/lang/IllegalArgumentException", "Invalid format");
 
344
        (*env)->ReleaseStringUTFChars(env, encodingString, encoding);
 
345
        if (name) {
 
346
            (*env)->ReleaseStringUTFChars(env, nameString,name);
 
347
        }
 
348
        return;
 
349
    }
 
350
 
 
351
    pa_stream* stream = pa_stream_new(context, name, &sample_spec, NULL);
 
352
    assert(stream);
 
353
    if (name) {
 
354
        (*env)->ReleaseStringUTFChars(env, nameString,name);
 
355
    }
 
356
 
 
357
    setJavaPointer(env, obj, STREAM_POINTER, stream);
 
358
 
 
359
    /*
 
360
     *
 
361
     * The stream has been created; now setup the callbacks
 
362
     * so we can do somethig about them
 
363
     *
 
364
     */
 
365
 
 
366
    pa_stream_set_state_callback (stream, stream_state_callback, j_context);
 
367
    pa_stream_set_write_callback (stream, stream_write_callback, j_context);
 
368
    pa_stream_set_read_callback (stream, stream_read_callback, j_context);
 
369
    pa_stream_set_overflow_callback (stream, stream_overflow_callback, j_context);
 
370
    pa_stream_set_underflow_callback (stream, stream_underflow_callback, j_context);
 
371
    pa_stream_set_started_callback (stream, stream_started_callback, j_context);
 
372
    pa_stream_set_latency_update_callback (stream, stream_latency_update_callback, j_context);
 
373
    pa_stream_set_moved_callback (stream, stream_moved_callback, j_context);
 
374
    pa_stream_set_suspended_callback (stream, stream_suspended_callback, j_context);
 
375
    pa_stream_set_buffer_attr_callback(stream, buf_attr_changed_callback, j_context);
317
376
}
318
377
 
319
378
/*
323
382
 */
324
383
JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1unref
325
384
(JNIEnv* env, jobject obj) {
326
 
        pa_stream* stream = getJavaPointer(env, obj, STREAM_POINTER);
327
 
        assert(stream);
328
 
        pa_stream_unref(stream);
329
 
        setJavaPointer(env, obj, "streamPointer", NULL);
 
385
 
 
386
    java_context* j_context = getJavaPointer(env, obj, CONTEXT_POINTER);
 
387
    assert(j_context);
 
388
    (*env)->DeleteGlobalRef(env, j_context->obj);
 
389
    free(j_context);
 
390
    setJavaPointer(env, obj, CONTEXT_POINTER, NULL);
 
391
 
 
392
    pa_stream* stream = getJavaPointer(env, obj, STREAM_POINTER);
 
393
    assert(stream);
 
394
    pa_stream_unref(stream);
 
395
    setJavaPointer(env, obj, STREAM_POINTER, NULL);
330
396
}
331
397
 
332
398
/*
334
400
 * Method:    native_pa_stream_get_state
335
401
 * Signature: ()I
336
402
 */
337
 
JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1state
 
403
JNIEXPORT jlong JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1state
338
404
(JNIEnv* env, jobject obj) {
339
 
        pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
340
 
        assert(stream);
341
 
        return pa_stream_get_state(stream);
 
405
    pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
 
406
    assert(stream);
 
407
    return pa_stream_get_state(stream);
342
408
}
343
409
 
344
410
/*
349
415
JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1context
350
416
(JNIEnv* env, jobject obj) {
351
417
 
352
 
        pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
353
 
        assert(stream);
354
 
        pa_context* context = pa_stream_get_context(stream);
355
 
        assert(context);
356
 
        return convertNativePointerToJava(env, context);
 
418
    pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
 
419
    assert(stream);
 
420
    pa_context* context = pa_stream_get_context(stream);
 
421
    assert(context);
 
422
    return convertNativePointerToJava(env, context);
357
423
}
358
424
 
359
425
/*
363
429
 */
364
430
JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1index
365
431
(JNIEnv* env, jobject obj) {
366
 
        pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
367
 
        assert(stream);
368
 
        return pa_stream_get_index(stream);
 
432
    pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
 
433
    assert(stream);
 
434
    return pa_stream_get_index(stream);
369
435
}
370
436
 
371
437
/*
375
441
 */
376
442
JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1device_1index
377
443
(JNIEnv* env, jobject obj) {
378
 
        pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
379
 
        assert(stream);
380
 
        return pa_stream_get_device_index(stream);
 
444
    pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
 
445
    assert(stream);
 
446
    return pa_stream_get_device_index(stream);
381
447
}
382
448
 
383
449
/*
387
453
 */
388
454
JNIEXPORT jstring JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1device_1name
389
455
(JNIEnv* env, jobject obj) {
390
 
        pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
391
 
        assert(stream);
392
 
        const char* name = pa_stream_get_device_name(stream);
393
 
        assert(name);
394
 
        return (*env)->NewStringUTF(env, name);
 
456
    pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
 
457
    assert(stream);
 
458
    const char* name = pa_stream_get_device_name(stream);
 
459
    assert(name);
 
460
    return (*env)->NewStringUTF(env, name);
395
461
}
396
462
 
397
463
/*
401
467
 */
402
468
JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1is_1suspended
403
469
(JNIEnv* env, jobject obj) {
404
 
        pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
405
 
        assert(stream);
406
 
        return pa_stream_is_suspended(stream);
 
470
    pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
 
471
    assert(stream);
 
472
    return pa_stream_is_suspended(stream);
407
473
}
408
474
 
409
475
/*
413
479
 */
414
480
JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1connect_1playback
415
481
(JNIEnv* env, jobject obj, jstring device, jint bufferMaxLength,
416
 
                jint bufferTargetLength, jint bufferPreBuffering,
417
 
                jint bufferMinimumRequest, jint bufferFragmentSize, jint flags,
418
 
                jbyteArray volumePointer, jbyteArray sync_streamPointer) {
419
 
 
420
 
        pa_stream *sync_stream;
421
 
        if(sync_streamPointer != NULL) {
422
 
                sync_stream = convertJavaPointerToNative(env, sync_streamPointer);
423
 
                printf("Master stream is %p\n", sync_stream);
424
 
        } else {
425
 
                sync_stream = NULL;
426
 
        }
427
 
 
428
 
        pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
429
 
 
430
 
        pa_buffer_attr buffer_attr;
431
 
 
432
 
        memset(&buffer_attr, 0, sizeof(buffer_attr));
433
 
 
434
 
        buffer_attr.maxlength = (uint32_t) bufferMaxLength;
435
 
        buffer_attr.tlength = (uint32_t) bufferTargetLength;
436
 
        buffer_attr.prebuf = (uint32_t) bufferPreBuffering;
437
 
        buffer_attr.minreq = (uint32_t) bufferMinimumRequest;
438
 
 
439
 
        /*
440
 
         printf("buffer maxlength: %u\n", buffer_attr.maxlength);
441
 
         printf("buffer tlength: %u\n", buffer_attr.tlength);
442
 
         printf("buffer prebuf: %u\n", buffer_attr.prebuf);
443
 
         printf("buffer minreq: %u\n", buffer_attr.minreq);
444
 
         printf("buffer fragsize: %u\n", buffer_attr.fragsize);
445
 
         */
446
 
 
447
 
        const char* dev = NULL;
448
 
        if (device != NULL) {
449
 
                dev = (*env)->GetStringUTFChars(env, device, NULL);
450
 
                if (dev == NULL) {
451
 
                        return -1; // oome thrown
452
 
                }
453
 
        }
454
 
        /* Set flags to 0 to fix problem with draining before calling start, might need to
455
 
         be changed back to PA_STREAM_START_CORKED in the future, if we'll be able to implement
456
 
         synchronization*/
457
 
        int value = pa_stream_connect_playback(stream, dev, &buffer_attr, PA_STREAM_START_CORKED, NULL, sync_stream);
458
 
 
459
 
        if (dev != NULL) {
460
 
                (*env)->ReleaseStringUTFChars(env, device, dev);
461
 
                dev = NULL;
462
 
        }
463
 
        return value;
 
482
        jint bufferTargetLength, jint bufferPreBuffering,
 
483
        jint bufferMinimumRequest, jint bufferFragmentSize, jlong flags,
 
484
        jbyteArray volumePointer, jbyteArray sync_streamPointer) {
 
485
    pa_stream *sync_stream;
 
486
    if(sync_streamPointer != NULL) {
 
487
        sync_stream = convertJavaPointerToNative(env, sync_streamPointer);
 
488
        printf("Master stream is %p\n", sync_stream);
 
489
    } else {
 
490
        sync_stream = NULL;
 
491
    }
 
492
 
 
493
    pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
 
494
 
 
495
    pa_buffer_attr buffer_attr;
 
496
 
 
497
    memset(&buffer_attr, 0, sizeof(buffer_attr));
 
498
 
 
499
    buffer_attr.maxlength = (uint32_t) bufferMaxLength;
 
500
    buffer_attr.tlength = (uint32_t) bufferTargetLength;
 
501
    buffer_attr.prebuf = (uint32_t) bufferPreBuffering;
 
502
    buffer_attr.minreq = (uint32_t) bufferMinimumRequest;
 
503
 
 
504
    const char* dev = NULL;
 
505
    if (device != NULL) {
 
506
        dev = (*env)->GetStringUTFChars(env, device, NULL);
 
507
        if (dev == NULL) {
 
508
            return -1; // oome thrown
 
509
        }
 
510
    }
 
511
 
 
512
    int value = pa_stream_connect_playback(stream, dev, &buffer_attr,
 
513
            (pa_stream_flags_t) flags, NULL, sync_stream);
 
514
 
 
515
    if (dev != NULL) {
 
516
        (*env)->ReleaseStringUTFChars(env, device, dev);
 
517
        dev = NULL;
 
518
    }
 
519
    return value;
464
520
}
465
521
 
466
522
/*
470
526
 */
471
527
JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1connect_1record
472
528
(JNIEnv* env, jobject obj, jstring device, jint bufferMaxLength,
473
 
                jint bufferTargetLength, jint bufferPreBuffereing,
474
 
                jint bufferMinimumRequest, jint bufferFragmentSize, jint flags,
475
 
                jbyteArray volumePointer, jbyteArray sync_streamPointer) {
476
 
 
477
 
        pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
478
 
        assert(stream);
479
 
 
480
 
        pa_buffer_attr buffer_attr;
481
 
        memset(&buffer_attr, 0 , sizeof(buffer_attr));
482
 
        buffer_attr.maxlength = (uint32_t) bufferMaxLength;
483
 
        buffer_attr.fragsize = (uint32_t) bufferFragmentSize;
484
 
 
485
 
        /*
486
 
         printf("buffer maxlength: %u\n", buffer_attr.maxlength);
487
 
         printf("buffer tlength: %u\n", buffer_attr.tlength);
488
 
         printf("buffer prebuf: %u\n", buffer_attr.prebuf);
489
 
         printf("buffer minreq: %u\n", buffer_attr.minreq);
490
 
         printf("buffer fragsize: %u\n", buffer_attr.fragsize);
491
 
         */
492
 
 
493
 
        const char* dev = NULL;
494
 
        if (device != NULL) {
495
 
                dev = (*env)->GetStringUTFChars(env, device, NULL);
496
 
                if (dev == NULL) {
497
 
                        return -1; // oome thrown
498
 
                }
499
 
        }
500
 
 
501
 
        int value = pa_stream_connect_record(stream, dev, &buffer_attr, flags);
502
 
 
503
 
        if (dev != NULL) {
504
 
                (*env)->ReleaseStringUTFChars(env, device, dev);
505
 
                dev = NULL;
506
 
        }
507
 
        return value;
 
529
        jint bufferTargetLength, jint bufferPreBuffereing,
 
530
        jint bufferMinimumRequest, jint bufferFragmentSize, jlong flags,
 
531
        jbyteArray volumePointer, jbyteArray sync_streamPointer) {
 
532
 
 
533
    pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
 
534
    assert(stream);
 
535
 
 
536
    pa_buffer_attr buffer_attr;
 
537
    memset(&buffer_attr, 0 , sizeof(buffer_attr));
 
538
    buffer_attr.maxlength = (uint32_t) bufferMaxLength;
 
539
    buffer_attr.fragsize = (uint32_t) bufferFragmentSize;
 
540
 
 
541
    const char* dev = NULL;
 
542
    if (device != NULL) {
 
543
        dev = (*env)->GetStringUTFChars(env, device, NULL);
 
544
        if (dev == NULL) {
 
545
            return -1; // oome thrown
 
546
        }
 
547
    }
 
548
 
 
549
    int value = pa_stream_connect_record(stream, dev, &buffer_attr,
 
550
                                         (pa_stream_flags_t) flags);
 
551
 
 
552
    if (dev != NULL) {
 
553
        (*env)->ReleaseStringUTFChars(env, device, dev);
 
554
        dev = NULL;
 
555
    }
 
556
    return value;
508
557
 
509
558
}
510
559
 
515
564
 */
516
565
JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1disconnect
517
566
(JNIEnv* env, jobject obj) {
518
 
        pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
519
 
        assert(stream);
520
 
        int return_value = pa_stream_disconnect(stream);
 
567
    pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
 
568
    assert(stream);
 
569
    int return_value = pa_stream_disconnect(stream);
521
570
 
522
 
        return return_value;
 
571
    return return_value;
523
572
}
524
573
 
525
574
/*
529
578
 */
530
579
JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1write
531
580
(JNIEnv* env, jobject obj, jbyteArray data, jint offset, jint data_length) {
532
 
        pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
533
 
        assert(stream);
534
 
        jbyte* data_buffer = (*env)->GetByteArrayElements(env, data, NULL);
535
 
        if (data_buffer == NULL) {
536
 
                return -1; // oome thrown
537
 
        }
538
 
        jbyte* buffer_start = data_buffer + offset;
539
 
        int value = pa_stream_write(stream, buffer_start, data_length, NULL, 0, PA_SEEK_RELATIVE);
540
 
        (*env)->ReleaseByteArrayElements(env, data, data_buffer, 0);
541
 
        return value;
 
581
    pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
 
582
    assert(stream);
 
583
    jbyte* data_buffer = (*env)->GetByteArrayElements(env, data, NULL);
 
584
    if (data_buffer == NULL) {
 
585
        return -1; // oome thrown
 
586
    }
 
587
    jbyte* buffer_start = data_buffer + offset;
 
588
    int value = pa_stream_write(stream, buffer_start, data_length, NULL, 0, PA_SEEK_RELATIVE);
 
589
    (*env)->ReleaseByteArrayElements(env, data, data_buffer, 0);
 
590
    return value;
542
591
}
543
592
 
544
593
/*
549
598
JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1peek
550
599
(JNIEnv* env, jobject obj) {
551
600
 
552
 
        pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
553
 
        assert(stream);
554
 
        const void* startLocation;
555
 
        size_t count;
556
 
 
557
 
        if ( pa_stream_peek(stream, &startLocation, &count) < 0 ) {
558
 
                return NULL;
559
 
        }
560
 
 
561
 
        /* no data available */
562
 
        if (startLocation == NULL) {
563
 
                return NULL;
564
 
        }
565
 
 
566
 
        jsize length = count;
567
 
        jbyteArray data = (*env)->NewByteArray(env, length);
568
 
 
569
 
        if ( data == NULL) {
570
 
                return NULL; // oome thrown
571
 
        }
572
 
 
573
 
        (*env)->SetByteArrayRegion(env, data, 0, count, startLocation);
574
 
        return data;
 
601
    pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
 
602
    assert(stream);
 
603
    const void* startLocation;
 
604
    size_t count;
 
605
 
 
606
    if ( pa_stream_peek(stream, &startLocation, &count) < 0 ) {
 
607
        return NULL;
 
608
    }
 
609
 
 
610
    /* no data available */
 
611
    if (startLocation == NULL) {
 
612
        return NULL;
 
613
    }
 
614
 
 
615
    jsize length = count;
 
616
    jbyteArray data = (*env)->NewByteArray(env, length);
 
617
 
 
618
    if ( data == NULL) {
 
619
        return NULL; // oome thrown
 
620
    }
 
621
 
 
622
    (*env)->SetByteArrayRegion(env, data, 0, count, startLocation);
 
623
    return data;
575
624
}
576
625
 
577
626
/*
581
630
 */
582
631
JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1drop
583
632
(JNIEnv* env, jobject obj) {
584
 
        pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
585
 
        assert(stream);
586
 
        return pa_stream_drop(stream);
 
633
    pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
 
634
    assert(stream);
 
635
    return pa_stream_drop(stream);
587
636
}
588
637
 
589
638
/*
593
642
 */
594
643
JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1writable_1size
595
644
(JNIEnv* env, jobject obj) {
596
 
        pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
597
 
        if(!stream) {
598
 
                return 0;
599
 
        }
600
 
        size_t size = pa_stream_writable_size(stream);
601
 
        return size;
 
645
    pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
 
646
    if(!stream) {
 
647
        return 0;
 
648
    }
 
649
    size_t size = pa_stream_writable_size(stream);
 
650
    return size;
602
651
 
603
652
}
604
653
 
609
658
 */
610
659
JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1readable_1size
611
660
(JNIEnv* env, jobject obj) {
612
 
        pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
613
 
        assert(stream);
614
 
        return pa_stream_readable_size(stream);
 
661
    pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
 
662
    assert(stream);
 
663
    return pa_stream_readable_size(stream);
615
664
}
616
665
 
617
666
static void drain_callback(pa_stream* stream, int success, void* userdata) {
618
667
 
619
 
        assert(stream);
620
 
        JNIEnv* env = pulse_thread_env;
621
 
        assert(env);
622
 
 
623
 
        notifyWaitingOperations(env);
624
 
 
625
 
        if (success == 0) {
626
 
                throwByName(env, ILLEGAL_STATE_EXCEPTION, "drain failed");
627
 
        }
 
668
    assert(stream);
 
669
    JNIEnv* env = pulse_thread_env;
 
670
    assert(env);
 
671
 
 
672
    notifyWaitingOperations(env);
 
673
 
 
674
    if (success == 0) {
 
675
        throwByName(env, ILLEGAL_STATE_EXCEPTION, "drain failed");
 
676
    }
628
677
 
629
678
}
630
679
 
635
684
 */
636
685
JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1drain
637
686
(JNIEnv* env, jobject obj) {
638
 
        pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
639
 
        assert(stream);
640
 
        pa_operation* operation = pa_stream_drain(stream, drain_callback, NULL);
641
 
        assert(operation);
642
 
        return convertNativePointerToJava(env, operation);
 
687
    pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
 
688
    assert(stream);
 
689
    pa_operation* operation = pa_stream_drain(stream, drain_callback, NULL);
 
690
    assert(operation);
 
691
    return convertNativePointerToJava(env, operation);
643
692
}
644
693
 
645
694
/*
649
698
 */
650
699
JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1is_1corked
651
700
(JNIEnv* env, jobject obj) {
652
 
        pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
653
 
        assert(stream);
654
 
        return pa_stream_is_corked(stream);
 
701
    pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
 
702
    assert(stream);
 
703
    return pa_stream_is_corked(stream);
655
704
}
656
705
 
657
706
static void cork_callback(pa_stream* stream, int success, void* userdata) {
658
707
 
659
 
        java_context* context = userdata;
660
 
        assert(stream);
661
 
        assert(context);
662
 
        JNIEnv* env = pulse_thread_env;
663
 
        assert(env);
664
 
        notifyWaitingOperations(env);
 
708
    assert(stream);
 
709
    JNIEnv* env = pulse_thread_env;
 
710
    assert(env);
 
711
    notifyWaitingOperations(env);
665
712
 
666
 
        if (success == 0) {
667
 
                throwByName(env, ILLEGAL_STATE_EXCEPTION, "cork failed");
668
 
        }
 
713
    if (success == 0) {
 
714
        throwByName(env, ILLEGAL_STATE_EXCEPTION, "cork failed");
 
715
    }
669
716
 
670
717
}
671
718
 
676
723
 */
677
724
JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1cork
678
725
(JNIEnv* env, jobject obj, jint yes) {
679
 
        pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
680
 
        assert(stream);
681
 
        java_context* j_context = malloc(sizeof(java_context));
682
 
        assert(j_context);
683
 
        j_context->env = env;
684
 
        j_context->obj = (*env)->NewGlobalRef(env, obj);
685
 
        pa_operation* operation = pa_stream_cork(stream, yes, cork_callback, j_context);
686
 
        assert(operation);
687
 
        return convertNativePointerToJava(env, operation);
 
726
    pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
 
727
    assert(stream);
 
728
    pa_operation* operation = pa_stream_cork(stream, yes, cork_callback, NULL);
 
729
    assert(operation);
 
730
    return convertNativePointerToJava(env, operation);
688
731
}
689
732
 
690
733
static void flush_callback(pa_stream* stream, int success, void* userdata) {
691
 
        assert(stream);
692
 
        JNIEnv* env = pulse_thread_env;
693
 
        assert(env);
694
 
        notifyWaitingOperations(env);
 
734
    assert(stream);
 
735
    JNIEnv* env = pulse_thread_env;
 
736
    assert(env);
 
737
    notifyWaitingOperations(env);
695
738
 
696
 
        if (success == 0) {
697
 
                throwByName(env, ILLEGAL_STATE_EXCEPTION, "flush failed");
698
 
        }
 
739
    if (success == 0) {
 
740
        throwByName(env, ILLEGAL_STATE_EXCEPTION, "flush failed");
 
741
    }
699
742
 
700
743
}
701
744
 
706
749
 */
707
750
JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1flush
708
751
(JNIEnv* env, jobject obj) {
709
 
        pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
710
 
        assert(stream);
711
 
        pa_operation* operation = pa_stream_flush(stream, flush_callback, NULL);
712
 
        assert(operation);
713
 
        return convertNativePointerToJava(env, operation);
 
752
    pa_stream* stream = (pa_stream*) getJavaPointer(env, obj, STREAM_POINTER);
 
753
    assert(stream);
 
754
    pa_operation* operation = pa_stream_flush(stream, flush_callback, NULL);
 
755
    assert(operation);
 
756
    return convertNativePointerToJava(env, operation);
714
757
}
715
758
 
716
759
static void trigger_callback(pa_stream* stream, int success, void* userdata) {
717
 
        assert(stream);
718
 
        JNIEnv* env = pulse_thread_env;
719
 
        assert(env);
720
 
        notifyWaitingOperations(env);
 
760
    assert(stream);
 
761
    JNIEnv* env = pulse_thread_env;
 
762
    assert(env);
 
763
    notifyWaitingOperations(env);
721
764
 
722
 
        if (success == 0) {
723
 
                throwByName(env, ILLEGAL_STATE_EXCEPTION, "trigger failed");
724
 
        }
 
765
    if (success == 0) {
 
766
        throwByName(env, ILLEGAL_STATE_EXCEPTION, "trigger failed");
 
767
    }
725
768
 
726
769
}
727
770
 
732
775
 */
733
776
JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1trigger
734
777
(JNIEnv* env, jobject obj) {
735
 
        pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
736
 
        assert(stream);
737
 
        pa_operation* operation = pa_stream_trigger(stream, trigger_callback, NULL);
738
 
        assert(operation);
739
 
        return convertNativePointerToJava(env, operation);
 
778
    pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
 
779
    assert(stream);
 
780
    pa_operation* operation = pa_stream_trigger(stream, trigger_callback, NULL);
 
781
    assert(operation);
 
782
    return convertNativePointerToJava(env, operation);
740
783
}
741
784
 
742
785
static void set_name_callback(pa_stream* stream, int success, void* userdata) {
743
 
        assert(stream);
744
 
        JNIEnv* env = pulse_thread_env;
745
 
        notifyWaitingOperations(env);
 
786
    assert(stream);
 
787
    JNIEnv* env = pulse_thread_env;
 
788
    notifyWaitingOperations(env);
746
789
 
747
 
        if (success == 0) {
748
 
                throwByName(env, ILLEGAL_STATE_EXCEPTION, "set_name failed");
749
 
        }
 
790
    if (success == 0) {
 
791
        throwByName(env, ILLEGAL_STATE_EXCEPTION, "set_name failed");
 
792
    }
750
793
}
751
794
 
752
795
/*
756
799
 */
757
800
JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1set_1name
758
801
(JNIEnv* env, jobject obj, jstring newName) {
759
 
        pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
760
 
        assert(stream);
761
 
 
762
 
        const char* name;
763
 
        name = (*env)->GetStringUTFChars(env, newName, NULL);
764
 
        if (name == NULL) {
765
 
                return 0; // OutOfMemoryError already thrown
766
 
        }
767
 
 
768
 
        pa_operation* operation = pa_stream_set_name(stream, name, set_name_callback, NULL);
769
 
        assert(operation);
770
 
        (*env)->ReleaseStringUTFChars(env, newName, name);
771
 
 
772
 
        return convertNativePointerToJava(env, operation);
 
802
    pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
 
803
    assert(stream);
 
804
 
 
805
    const char* name;
 
806
    name = (*env)->GetStringUTFChars(env, newName, NULL);
 
807
    if (name == NULL) {
 
808
        return 0; // OutOfMemoryError already thrown
 
809
    }
 
810
 
 
811
    pa_operation* operation = pa_stream_set_name(stream, name, set_name_callback, NULL);
 
812
    assert(operation);
 
813
    (*env)->ReleaseStringUTFChars(env, newName, name);
 
814
 
 
815
    return convertNativePointerToJava(env, operation);
773
816
}
774
817
 
775
818
/*
779
822
 */
780
823
JNIEXPORT jlong JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1time
781
824
(JNIEnv* env, jobject obj) {
782
 
        pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
783
 
        assert(stream);
784
 
 
785
 
        pa_usec_t time = 0;
786
 
        int result = pa_stream_get_time (stream,&time);
787
 
        assert(result == 0);
788
 
 
789
 
        return time;
 
825
    pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
 
826
    assert(stream);
 
827
 
 
828
    pa_usec_t time = 0;
 
829
    int result = pa_stream_get_time (stream,&time);
 
830
    assert(result == 0);
 
831
 
 
832
    return time;
790
833
 
791
834
}
792
835
 
797
840
 */
798
841
JNIEXPORT jlong JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1latency
799
842
(JNIEnv* env, jobject obj) {
800
 
        pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
801
 
        assert(stream);
802
 
        pa_usec_t returnValue = 0;
803
 
        int negative = 0;
804
 
        int result = pa_stream_get_latency ( stream, &returnValue, &negative);
805
 
        assert(result == 0);
806
 
        assert(negative == 0);
807
 
        return returnValue;
 
843
    pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
 
844
    assert(stream);
 
845
    pa_usec_t returnValue = 0;
 
846
    int negative = 0;
 
847
    int result = pa_stream_get_latency ( stream, &returnValue, &negative);
 
848
    assert(result == 0);
 
849
    assert(negative == 0);
 
850
    return returnValue;
808
851
}
809
852
 
810
853
/*
814
857
 */
815
858
JNIEXPORT jobject JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1sample_1spec
816
859
(JNIEnv* env, jobject obj) {
817
 
        pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
818
 
        assert(stream);
819
 
 
820
 
        const pa_sample_spec* sample_spec = pa_stream_get_sample_spec(stream);
821
 
        assert(sample_spec);
822
 
 
823
 
        char* name = "Lorg/classpath/icedtea/pulseaudio/StreamSampleSpecification;";
824
 
        jclass cls = (*env)->FindClass(env, name);
825
 
        assert(cls);
826
 
        jmethodID constructor_mid = (*env)->GetMethodID(env, cls, "<init>", "V");
827
 
        assert(constructor_mid);
828
 
 
829
 
        const char* formatString = getStringFromFormat(sample_spec->format);
830
 
        assert(formatString);
831
 
        int rate = sample_spec->rate;
832
 
        int channels = sample_spec->channels;
833
 
 
834
 
        jstring format = (*env)->NewStringUTF(env, formatString);
835
 
        if ( format == NULL) {
836
 
                return NULL; // oome
837
 
        }
838
 
        jobject return_object = (*env)->NewObject(env, cls, constructor_mid, format, rate, channels);
839
 
 
840
 
        return return_object;
 
860
    pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
 
861
    assert(stream);
 
862
 
 
863
    const pa_sample_spec* sample_spec = pa_stream_get_sample_spec(stream);
 
864
    assert(sample_spec);
 
865
 
 
866
    char* name = "Lorg/classpath/icedtea/pulseaudio/StreamSampleSpecification;";
 
867
    jclass cls = (*env)->FindClass(env, name);
 
868
    assert(cls);
 
869
    jmethodID constructor_mid = (*env)->GetMethodID(env, cls, "<init>", "V");
 
870
    assert(constructor_mid);
 
871
 
 
872
    const char* formatString = getStringFromFormat(sample_spec->format);
 
873
    assert(formatString);
 
874
    int rate = sample_spec->rate;
 
875
    int channels = sample_spec->channels;
 
876
 
 
877
    jstring format = (*env)->NewStringUTF(env, formatString);
 
878
    if ( format == NULL) {
 
879
        return NULL; // oome
 
880
    }
 
881
    jobject return_object = (*env)->NewObject(env, cls, constructor_mid, format, rate, channels);
 
882
 
 
883
    return return_object;
841
884
}
842
885
 
843
886
/*
848
891
JNIEXPORT jobject JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1get_1buffer_1attr
849
892
(JNIEnv* env, jobject obj) {
850
893
 
851
 
        //      printf("in native_pa_stream_get_buffer_attributes");
852
 
 
853
 
        pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
854
 
        assert(stream);
855
 
        const pa_buffer_attr* buffer = pa_stream_get_buffer_attr(stream);
856
 
        assert(buffer);
857
 
 
858
 
        const char* class_name = "Lorg/classpath/icedtea/pulseaudio/StreamBufferAttributes;";
859
 
        jclass cls = (*env)->FindClass(env, class_name);
860
 
        assert(cls);
861
 
        jmethodID constructor_mid = (*env)->GetMethodID(env, cls, "<init>", "(IIIII)V");
862
 
        assert(constructor_mid);
863
 
        jint maxLength = buffer->maxlength;
864
 
        jint targetLength = buffer->tlength;
865
 
        jint preBuffering = buffer->prebuf;
866
 
        jint minimumRequest = buffer->minreq;
867
 
        jint fragmentSize = buffer->fragsize;
868
 
 
869
 
        jobject return_object = (*env)->NewObject(env, cls, constructor_mid, maxLength, targetLength,
870
 
                        preBuffering, minimumRequest, fragmentSize);
871
 
 
872
 
        return return_object;
 
894
    //    printf("in native_pa_stream_get_buffer_attributes");
 
895
 
 
896
    pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
 
897
    assert(stream);
 
898
    const pa_buffer_attr* buffer = pa_stream_get_buffer_attr(stream);
 
899
    assert(buffer);
 
900
 
 
901
    const char* class_name = "org/classpath/icedtea/pulseaudio/StreamBufferAttributes";
 
902
    jclass cls = (*env)->FindClass(env, class_name);
 
903
    assert(cls);
 
904
    jmethodID constructor_mid = (*env)->GetMethodID(env, cls, "<init>", "(IIIII)V");
 
905
    assert(constructor_mid);
 
906
    jint maxLength = buffer->maxlength;
 
907
    jint targetLength = buffer->tlength;
 
908
    jint preBuffering = buffer->prebuf;
 
909
    jint minimumRequest = buffer->minreq;
 
910
    jint fragmentSize = buffer->fragsize;
 
911
 
 
912
    jobject return_object = (*env)->NewObject(env, cls, constructor_mid, maxLength, targetLength,
 
913
            preBuffering, minimumRequest, fragmentSize);
 
914
 
 
915
    return return_object;
873
916
}
874
917
 
875
918
static void set_buffer_attr_callback(pa_stream* stream, int success,
876
 
                void* userdata) {
877
 
 
878
 
        assert(stream);
879
 
        JNIEnv* env = pulse_thread_env;
880
 
        assert(env);
881
 
        notifyWaitingOperations(env);
882
 
 
883
 
        if (success == 0) {
884
 
                throwByName(env, ILLEGAL_STATE_EXCEPTION, "set_buffer_attr failed");
885
 
        }
 
919
        void* userdata) {
 
920
 
 
921
    assert(stream);
 
922
    JNIEnv* env = pulse_thread_env;
 
923
    assert(env);
 
924
    notifyWaitingOperations(env);
 
925
 
 
926
    if (success == 0) {
 
927
        throwByName(env, ILLEGAL_STATE_EXCEPTION, "set_buffer_attr failed");
 
928
    }
886
929
}
887
930
 
888
931
/*
893
936
JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1set_1buffer_1attr
894
937
(JNIEnv* env, jobject obj, jobject bufferAttributeObject) {
895
938
 
896
 
        pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
897
 
        assert(stream);
898
 
 
899
 
        jclass cls = (*env)->GetObjectClass(env, bufferAttributeObject);
900
 
        assert(cls);
901
 
 
902
 
        pa_buffer_attr buffer;
903
 
 
904
 
        jmethodID getMaxLengthID = (*env)->GetMethodID(env,cls,"getMaxLength","()I");
905
 
        assert(getMaxLengthID);
906
 
        buffer.maxlength = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getMaxLengthID);
907
 
 
908
 
        jmethodID getTargetLengthID = (*env)->GetMethodID(env,cls,"getTargetLength","()I");
909
 
        assert(getTargetLengthID);
910
 
        buffer.tlength = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getTargetLengthID);
911
 
 
912
 
        jmethodID getPreBufferingID = (*env)->GetMethodID(env,cls,"getPreBuffering","()I");
913
 
        assert(getPreBufferingID);
914
 
        buffer.prebuf = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getPreBufferingID);
915
 
 
916
 
        jmethodID getMinimumRequestID = (*env)->GetMethodID(env, cls, "getMinimumRequest", "()I");
917
 
        assert(getMinimumRequestID);
918
 
        buffer.minreq = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getMinimumRequestID );
919
 
 
920
 
        jmethodID getFragmentSizeID = (*env)->GetMethodID(env,cls,"getFragmentSize","()I");
921
 
        assert(getFragmentSizeID);
922
 
        buffer.fragsize = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getFragmentSizeID );
923
 
 
924
 
        /*
925
 
         const pa_buffer_attr* old_buffer = pa_stream_get_buffer_attr(stream);
926
 
 
927
 
         printf("old buffer values: %u %u %u %u %u\n", old_buffer->maxlength, old_buffer->tlength, old_buffer->prebuf, old_buffer->minreq, old_buffer->fragsize);
928
 
 
929
 
         printf("want these values: %u %u %u %u %u\n", buffer.maxlength, buffer.tlength, buffer.prebuf, buffer.minreq, buffer.fragsize);
930
 
         */
931
 
 
932
 
        pa_operation* operation = pa_stream_set_buffer_attr(stream, &buffer, set_buffer_attr_callback, NULL);
933
 
 
934
 
        assert(operation);
935
 
        return convertNativePointerToJava(env,operation);
 
939
    pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
 
940
    assert(stream);
 
941
 
 
942
    jclass cls = (*env)->GetObjectClass(env, bufferAttributeObject);
 
943
    assert(cls);
 
944
 
 
945
    pa_buffer_attr buffer;
 
946
 
 
947
    jmethodID getMaxLengthID = (*env)->GetMethodID(env,cls,"getMaxLength","()I");
 
948
    assert(getMaxLengthID);
 
949
    buffer.maxlength = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getMaxLengthID);
 
950
 
 
951
    jmethodID getTargetLengthID = (*env)->GetMethodID(env,cls,"getTargetLength","()I");
 
952
    assert(getTargetLengthID);
 
953
    buffer.tlength = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getTargetLengthID);
 
954
 
 
955
    jmethodID getPreBufferingID = (*env)->GetMethodID(env,cls,"getPreBuffering","()I");
 
956
    assert(getPreBufferingID);
 
957
    buffer.prebuf = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getPreBufferingID);
 
958
 
 
959
    jmethodID getMinimumRequestID = (*env)->GetMethodID(env, cls, "getMinimumRequest", "()I");
 
960
    assert(getMinimumRequestID);
 
961
    buffer.minreq = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getMinimumRequestID );
 
962
 
 
963
    jmethodID getFragmentSizeID = (*env)->GetMethodID(env,cls,"getFragmentSize","()I");
 
964
    assert(getFragmentSizeID);
 
965
    buffer.fragsize = (uint32_t) (*env)->CallIntMethod(env, bufferAttributeObject, getFragmentSizeID );
 
966
 
 
967
    /*
 
968
     const pa_buffer_attr* old_buffer = pa_stream_get_buffer_attr(stream);
 
969
 
 
970
     printf("old buffer values: %u %u %u %u %u\n", old_buffer->maxlength, old_buffer->tlength, old_buffer->prebuf, old_buffer->minreq, old_buffer->fragsize);
 
971
 
 
972
     printf("want these values: %u %u %u %u %u\n", buffer.maxlength, buffer.tlength, buffer.prebuf, buffer.minreq, buffer.fragsize);
 
973
     */
 
974
 
 
975
    pa_operation* operation = pa_stream_set_buffer_attr(stream, &buffer, set_buffer_attr_callback, NULL);
 
976
 
 
977
    assert(operation);
 
978
    return convertNativePointerToJava(env,operation);
936
979
}
937
980
 
938
981
static void update_sample_rate_callback(pa_stream* stream, int success,
939
 
                void* userdata) {
940
 
        assert(stream);
941
 
        JNIEnv* env = pulse_thread_env;
942
 
        assert(env);
943
 
        notifyWaitingOperations(env);
 
982
        void* userdata) {
 
983
    assert(stream);
 
984
    JNIEnv* env = pulse_thread_env;
 
985
    assert(env);
 
986
    notifyWaitingOperations(env);
944
987
 
945
 
        if (success == 0) {
946
 
                throwByName(env, ILLEGAL_STATE_EXCEPTION, "update_sampl_rate failed");
947
 
        }
 
988
    if (success == 0) {
 
989
        throwByName(env, ILLEGAL_STATE_EXCEPTION, "update_sampl_rate failed");
 
990
    }
948
991
 
949
992
}
950
993
/*
955
998
JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1update_1sample_1rate
956
999
(JNIEnv* env, jobject obj, jint newRate) {
957
1000
 
958
 
        uint32_t rate = (uint32_t) newRate;
 
1001
    uint32_t rate = (uint32_t) newRate;
959
1002
 
960
 
        pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
961
 
        assert(stream);
962
 
        pa_operation* operation = pa_stream_update_sample_rate(stream,rate, update_sample_rate_callback, NULL);
963
 
        assert(operation);
964
 
        return convertNativePointerToJava(env, operation);
 
1003
    pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
 
1004
    assert(stream);
 
1005
    pa_operation* operation = pa_stream_update_sample_rate(stream,rate, update_sample_rate_callback, NULL);
 
1006
    assert(operation);
 
1007
    return convertNativePointerToJava(env, operation);
965
1008
 
966
1009
}
967
1010
 
973
1016
JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1set_1volume
974
1017
(JNIEnv *env, jobject obj, jfloat new_volume) {
975
1018
 
976
 
        pa_stream *stream = getJavaPointer(env, obj, STREAM_POINTER);
977
 
        assert(stream);
978
 
        pa_context *context = pa_stream_get_context(stream);
979
 
        assert(context);
980
 
 
981
 
        int stream_id = pa_stream_get_index(stream);
982
 
        int channels = pa_stream_get_sample_spec(stream)->channels;
983
 
        pa_cvolume cv;
984
 
 
985
 
        pa_operation* o = pa_context_set_sink_input_volume(context, stream_id, pa_cvolume_set(&cv, channels, new_volume), set_sink_input_volume_callback, NULL);
986
 
        assert(o);
987
 
 
988
 
        return convertNativePointerToJava(env, o);
 
1019
    pa_stream *stream = getJavaPointer(env, obj, STREAM_POINTER);
 
1020
    assert(stream);
 
1021
    pa_context *context = pa_stream_get_context(stream);
 
1022
    assert(context);
 
1023
 
 
1024
    int stream_id = pa_stream_get_index(stream);
 
1025
    int channels = pa_stream_get_sample_spec(stream)->channels;
 
1026
    pa_cvolume cv;
 
1027
 
 
1028
    pa_operation* o = pa_context_set_sink_input_volume(context, stream_id, pa_cvolume_set(&cv, channels, new_volume), set_sink_input_volume_callback, NULL);
 
1029
    assert(o);
 
1030
 
 
1031
    return convertNativePointerToJava(env, o);
989
1032
 
990
1033
}
991
1034
 
992
1035
 
993
1036
static void get_sink_input_volume_callback(pa_context *context, const pa_sink_input_info *i,
994
 
                int eol, void *userdata) {
995
 
 
996
 
        JNIEnv* env = pulse_thread_env;
997
 
 
998
 
        assert(context);
999
 
        assert(env);
1000
 
        jobject obj = (jobject) userdata;
1001
 
        assert(obj);
1002
 
 
1003
 
        if (eol == 0) {
1004
 
                jclass cls = (*pulse_thread_env)->GetObjectClass(pulse_thread_env, obj);
1005
 
                assert(cls);
1006
 
                jmethodID mid1 = (*pulse_thread_env)->GetMethodID(pulse_thread_env, cls,
1007
 
                                "update_channels_and_volume", "(IF)V");
1008
 
                assert(mid1);
1009
 
                (*pulse_thread_env)->CallVoidMethod(pulse_thread_env, obj, mid1,
1010
 
                                (int) (i->volume).channels, (float) (i->volume).values[0]) ;
1011
 
        } else {
1012
 
                notifyWaitingOperations(pulse_thread_env);
1013
 
                (*env)->DeleteGlobalRef(env, obj);
1014
 
        }
 
1037
        int eol, void *userdata) {
 
1038
 
 
1039
    JNIEnv* env = pulse_thread_env;
 
1040
 
 
1041
    assert(context);
 
1042
    assert(env);
 
1043
    jobject obj = (jobject) userdata;
 
1044
    assert(obj);
 
1045
 
 
1046
    if (eol == 0) {
 
1047
        jclass cls = (*pulse_thread_env)->GetObjectClass(pulse_thread_env, obj);
 
1048
        assert(cls);
 
1049
        jmethodID mid1 = (*pulse_thread_env)->GetMethodID(pulse_thread_env, cls,
 
1050
                "update_channels_and_volume", "(IF)V");
 
1051
        assert(mid1);
 
1052
        (*pulse_thread_env)->CallVoidMethod(pulse_thread_env, obj, mid1,
 
1053
                (int) (i->volume).channels, (float) (i->volume).values[0]) ;
 
1054
    } else {
 
1055
        notifyWaitingOperations(pulse_thread_env);
 
1056
        (*env)->DeleteGlobalRef(env, obj);
 
1057
    }
1015
1058
}
1016
1059
 
1017
1060
/*
1022
1065
JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1update_1volume
1023
1066
(JNIEnv* env, jobject obj) {
1024
1067
 
1025
 
        pa_stream* stream = getJavaPointer(env, obj, STREAM_POINTER);
1026
 
        assert(stream);
1027
 
 
1028
 
        int sink_input_index = pa_stream_get_index(stream);
1029
 
 
1030
 
        pa_context* context = pa_stream_get_context(stream);
1031
 
        assert(context);
1032
 
 
1033
 
        obj = (*env)->NewGlobalRef(env, obj);
1034
 
        pa_operation *o = pa_context_get_sink_input_info(context, sink_input_index , get_sink_input_volume_callback, obj);
1035
 
        assert(o);
1036
 
        return convertNativePointerToJava(env, o);
 
1068
    pa_stream* stream = getJavaPointer(env, obj, STREAM_POINTER);
 
1069
    assert(stream);
 
1070
 
 
1071
    int sink_input_index = pa_stream_get_index(stream);
 
1072
 
 
1073
    pa_context* context = pa_stream_get_context(stream);
 
1074
    assert(context);
 
1075
 
 
1076
    obj = (*env)->NewGlobalRef(env, obj);
 
1077
    pa_operation *o = pa_context_get_sink_input_info(context, sink_input_index , get_sink_input_volume_callback, obj);
 
1078
    assert(o);
 
1079
    return convertNativePointerToJava(env, o);
1037
1080
 
1038
1081
 
1039
1082
}
1040
1083
 
1041
1084
JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_bytesInBuffer(JNIEnv *env, jobject obj) {
1042
 
        pa_stream *stream = getJavaPointer(env, obj, STREAM_POINTER);
1043
 
        assert(stream);
1044
 
        const pa_timing_info *timing_info = pa_stream_get_timing_info(stream);
1045
 
        int write_index = timing_info->write_index;
1046
 
        int read_index = timing_info->read_index;
1047
 
        return write_index - read_index;
 
1085
    pa_stream *stream = getJavaPointer(env, obj, STREAM_POINTER);
 
1086
    assert(stream);
 
1087
    const pa_timing_info *timing_info = pa_stream_get_timing_info(stream);
 
1088
    int write_index = timing_info->write_index;
 
1089
    int read_index = timing_info->read_index;
 
1090
    return write_index - read_index;
1048
1091
}
1049
1092
 
1050
1093
JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1updateTimingInfo(JNIEnv* env, jobject obj) {
1051
 
        pa_stream *stream = getJavaPointer(env, obj, STREAM_POINTER);
1052
 
        assert(stream);
1053
 
        pa_operation* o = pa_stream_update_timing_info(stream, update_timing_info_callback, NULL);
1054
 
        assert(o);
1055
 
        return convertNativePointerToJava(env, o);
 
1094
    pa_stream *stream = getJavaPointer(env, obj, STREAM_POINTER);
 
1095
    assert(stream);
 
1096
    pa_operation* o = pa_stream_update_timing_info(stream, update_timing_info_callback, NULL);
 
1097
    assert(o);
 
1098
    return convertNativePointerToJava(env, o);
1056
1099
 
1057
1100
}
1058
1101