changeset 23:9ce846af2c4d

for debugging committer: Ioana Ivan <iivan@redhat.com>
author Ioana Ivan <iivan@redhat.com>
date Tue, 29 Jul 2008 11:29:44 -0400
parents 68e6a71e97f3
children 03101556665f
files src/org_openjdk_sound_PulseAudioSourceDataLine.c
diffstat 1 files changed, 260 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org_openjdk_sound_PulseAudioSourceDataLine.c	Tue Jul 29 11:29:44 2008 -0400
@@ -0,0 +1,260 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <jni.h>
+#include <pulse/pulseaudio.h>
+#include "org_openjdk_sound_PulseAudioSourceDataLine.h"
+
+void setJavaLongField(JNIEnv *env, jobject obj, void *ptr, char *fieldName) {
+	jclass cls = (*env)->GetObjectClass(env, obj);
+	jlong value = (long) ptr;
+	jfieldID fid =(*env)->GetFieldID(env, cls, fieldName, "J");
+	(*env)->SetLongField(env, obj, fid, value);
+	//CHECK No DeleteLocalReference Method?
+	//(*env)->DeleteLocalReference(cls);
+}
+
+void *getJavaLongField(JNIEnv *env, jobject obj, char *fieldName) {
+jclass cls = (*env)->GetObjectClass(env, obj);
+	jfieldID fid = (*env)->GetFieldID(env, cls, fieldName, "J");
+	jlong value = (*env)->GetLongField(env, obj, fid);
+	//(*env)->DeleteLocalReference(cls);
+	return (void *) value;
+}
+
+
+
+static void stream_write_cb(pa_stream* stream, size_t length, void* userdata) {
+    pa_threaded_mainloop *mainloop = userdata;
+    pa_threaded_mainloop_signal(mainloop,0);
+}
+
+static void stream_operation_complete_cb(pa_stream* stream, int success, void* userdata) {
+  pa_threaded_mainloop *mainloop = userdata;
+   pa_threaded_mainloop_signal(mainloop,0);
+}
+
+
+
+static void stream_state_cb(pa_stream* stream, void* userdata) {
+    assert(stream);
+    pa_threaded_mainloop *mainloop = userdata;
+    printf("stream state changed to %d\n", pa_stream_get_state(stream));
+    switch (pa_stream_get_state(stream)) {
+        case PA_STREAM_READY:
+        case PA_STREAM_FAILED:
+        pa_threaded_mainloop_signal(mainloop, 0);
+            break;
+        case PA_STREAM_TERMINATED:
+            printf("STREAM DISCONNECTING\n");
+            pa_threaded_mainloop_signal(mainloop, 0);
+            break;
+
+        default:
+            /* do nothing */
+            break;
+    }
+ }
+
+
+
+
+JNIEXPORT void JNICALL Java_org_openjdk_sound_PulseAudioSourceDataLine_openStream
+  (JNIEnv * env, jobject obj, jstring string, jfloat rate, jint size, jint channels, jboolean bigEndian, jint bufferSize){
+  
+    //TO DO: Need to deal with the buffer size. Currently ignored
+
+    pa_threaded_mainloop *mainloop = getJavaLongField (env, obj, "mainLoopPointer"); 
+    pa_context *context = getJavaLongField(env, obj, "contextPointer");
+    
+   
+    pa_sample_spec sample_spec;
+    
+    char *encoding = (*env)->GetStringUTFChars(env, string, NULL);
+    
+    if( (strcmp(encoding, "PCM_UNSIGNED") == 0) && (size == 8)) {
+    	sample_spec.format = PA_SAMPLE_U8;
+    } else if( (strcmp(encoding, "ALAW") == 0) && (size == 8)) {
+    	sample_spec.format = PA_SAMPLE_ALAW;
+    } else if( (strcmp(encoding, "ULAW") == 0) && (size == 8)) {
+    	sample_spec.format = PA_SAMPLE_ULAW;
+    } else if ( (strcmp(encoding, "PCM_SIGNED") == 0) && (size == 16) && (bigEndian == 1)) {
+	sample_spec.format = PA_SAMPLE_S16BE;
+     } else if ( (strcmp(encoding, "PCM_SIGNED") == 0) && (size == 16) && (bigEndian == 0)) {
+	sample_spec.format = PA_SAMPLE_S16LE;
+     } else if ( (strcmp(encoding, "PCM_SIGNED") == 0) && (size == 32) && (bigEndian == 1)) {
+	sample_spec.format = PA_SAMPLE_S32BE;
+     } else if ( (strcmp(encoding, "PCM_SIGNED") == 0) && (size == 32) && (bigEndian == 0)) {
+	sample_spec.format = PA_SAMPLE_S32LE;
+     } else {
+     	printf("error in open");
+     	//TO DO: Invalid format :throw Exception;
+     }
+    
+    sample_spec.rate = rate;
+    sample_spec.channels = channels;
+
+    pa_threaded_mainloop_lock(mainloop);
+    
+    pa_stream *stream = pa_stream_new(context, "default stream", &sample_spec, NULL);
+
+    pa_stream_set_state_callback(stream, stream_state_cb, mainloop);
+    pa_stream_set_write_callback(stream, stream_write_cb, mainloop);
+    
+  
+    pa_threaded_mainloop_unlock(mainloop);
+
+
+    setJavaLongField(env, obj, stream, "streamPointer");    
+    return;
+
+unlock_and_fail:
+    pa_threaded_mainloop_unlock(mainloop);
+
+fail:
+    return;
+}
+
+JNIEXPORT void JNICALL
+Java_org_openjdk_sound_PulseAudioSourceDataLine_startStream(JNIEnv *env, jobject obj) {
+    printf("start called\n");
+    pa_threaded_mainloop *mainloop = getJavaLongField (env, obj, "mainLoopPointer"); 
+    pa_stream *stream = getJavaLongField(env, obj, "streamPointer");
+    pa_threaded_mainloop_lock(mainloop);
+    pa_stream_connect_playback(stream, NULL, NULL, 0, NULL, NULL);
+    pa_threaded_mainloop_wait(mainloop);
+    if ( pa_stream_get_state(stream) != PA_STREAM_READY ) {
+        printf("stream initialization failed\n");
+    }
+    pa_threaded_mainloop_unlock(mainloop);
+}
+
+JNIEXPORT void Java_org_openjdk_sound_PulseAudioSourceDataLine_resumeStream(JNIEnv *env, jobject obj) {
+  	 pa_threaded_mainloop *mainloop = getJavaLongField (env, obj, "mainLoopPointer"); 
+  	 pa_stream *stream = getJavaLongField(env, obj, "streamPointer");
+  	 pa_threaded_mainloop_lock(mainloop);
+    	 pa_operation *o = pa_stream_cork(stream, 0, stream_operation_complete_cb, mainloop);
+    	 while(pa_operation_get_state(o) != PA_OPERATION_DONE) {
+    		pa_threaded_mainloop_wait(mainloop);
+    	 }
+    	 pa_operation_unref(o);
+    	 pa_threaded_mainloop_unlock(mainloop);
+
+}
+
+JNIEXPORT void Java_org_openjdk_sound_PulseAudioSourceDataLine__pauseStream(JNIEnv *env, jobject obj) {
+	 pa_threaded_mainloop *mainloop = getJavaLongField (env, obj, "mainLoopPointer"); 
+  	 pa_stream *stream = getJavaLongField(env, obj, "streamPointer");
+  	 pa_threaded_mainloop_lock(mainloop);
+    	 pa_operation *o = pa_stream_cork(stream, 1, stream_operation_complete_cb, mainloop);
+    	 while(pa_operation_get_state(o) != PA_OPERATION_DONE) {
+    		pa_threaded_mainloop_wait(mainloop);
+    	 }
+    	 pa_operation_unref(o);
+    	 pa_threaded_mainloop_unlock(mainloop);
+}
+  
+
+
+JNIEXPORT void JNICALL
+Java_org_openjdk_sound_PulseAudioSourceDataLine_writeToStream(JNIEnv *env, jobject obj, jbyteArray data, jint bytesRead, jint indexJava) {
+    printf("write called\n");
+    pa_threaded_mainloop *mainloop = getJavaLongField (env, obj, "mainLoopPointer"); 
+    pa_stream *stream = getJavaLongField(env, obj, "streamPointer");
+    unsigned char *buffer = (*env)->GetByteArrayElements(env, data, NULL);
+    int length = bytesRead;
+    int offset = indexJava;
+    buffer += offset;
+
+
+    pa_threaded_mainloop_lock(mainloop);
+  
+    while (length > 0) {
+
+	int available_size = pa_stream_writable_size(stream);
+        while (available_size == 0) {
+            pa_threaded_mainloop_wait(mainloop);
+            available_size = pa_stream_writable_size(stream);
+        }
+
+        if (available_size > length) {
+            available_size = length;
+        }
+
+        if (pa_stream_get_state(stream) != PA_STREAM_READY ) {
+            printf("stream errored!\n");
+            goto unlock_and_fail;
+        }
+
+        pa_stream_write(stream, buffer, available_size, NULL, 0, PA_SEEK_RELATIVE);
+        printf("written%d\n", available_size);
+      
+
+        buffer += available_size;
+        length -= available_size;
+       
+    }
+
+    pa_operation_unref(pa_stream_drain(stream, NULL, NULL));
+
+    pa_threaded_mainloop_unlock(mainloop);
+
+   
+    return;
+
+unlock_and_fail:
+    pa_threaded_mainloop_unlock(mainloop);
+fail:
+    return;
+
+}
+
+JNIEXPORT void JNICALL Java_org_openjdk_sound_PulseAudioSourceDataLine_closeStream
+  (JNIEnv *env, jobject obj) {
+	pa_stream *stream = getJavaLongField(env, obj, "streamPointer");
+	printf("STREAM POINTER: %d\n", stream);
+  	pa_stream_disconnect(stream);
+}
+
+JNIEXPORT jint JNICALL Java_org_openjdk_sound_PulseAudioSourceDataLine_available
+  (JNIEnv *env, jobject obj) {
+  	pa_threaded_mainloop *mainloop = getJavaLongField (env, obj, "mainLoopPointer");
+  	pa_stream *stream = getJavaLongField(env, obj, "streamPointer");
+  	pa_threaded_mainloop_lock(mainloop);
+	int available = pa_stream_writable_size(stream);
+    	pa_threaded_mainloop_unlock(mainloop);
+    	return available;
+ }
+
+
+JNIEXPORT void JNICALL Java_org_openjdk_sound_PulseAudioSourceDataLine_drain
+  (JNIEnv *env, jobject obj) {
+  	pa_threaded_mainloop *mainloop = getJavaLongField (env, obj, "mainLoopPointer");
+  	pa_stream *stream = getJavaLongField(env, obj, "streamPointer");
+  	pa_threaded_mainloop_lock(mainloop);
+	pa_operation *o = pa_stream_drain(stream, stream_operation_complete_cb, mainloop);
+    	while(pa_operation_get_state(o) != PA_OPERATION_DONE) {
+    		pa_threaded_mainloop_wait(mainloop);
+    	}
+    	pa_operation_unref(o);
+    	pa_threaded_mainloop_unlock(mainloop);
+ }
+
+JNIEXPORT void JNICALL Java_org_openjdk_sound_PulseAudioSourceDataLine_flush
+  (JNIEnv *env, jobject obj) {
+  	pa_threaded_mainloop *mainloop = getJavaLongField (env, obj, "mainLoopPointer");
+  	pa_stream *stream = getJavaLongField(env, obj, "streamPointer");
+  	pa_threaded_mainloop_lock(mainloop);
+	pa_operation *o = pa_stream_flush(stream, stream_operation_complete_cb, mainloop);
+    	while(pa_operation_get_state(o) != PA_OPERATION_DONE) {
+    		pa_threaded_mainloop_wait(mainloop);
+    	}
+    	pa_operation_unref(o);
+    	pa_threaded_mainloop_unlock(mainloop);
+ }
+
+
+
+
+
+