changeset 37:127841aeb6e9

added flush() and drain() to SourceDataLine committer: Ioana Ivan <iivan@redhat.com>
author Ioana Ivan <iivan@redhat.com>
date Fri, 01 Aug 2008 12:12:03 -0400
parents a22db30b1290 (current diff) 73125e09b897 (diff)
children 92e04ec1b947
files src/PulseAudioMixer.c src/PulseAudioMixer.h src/PulseAudioSourceDataLine.c src/PulseAudioSourceDataLine.h src/PulseAudioTargetDataLine.c src/org/openjdk/sound/PulseAudioMixer.java src/org/openjdk/sound/PulseAudioSourceDataLine.java src/org_openjdk_sound_PulseAudioMixer.c src/org_openjdk_sound_PulseAudioSourceDataLine.c src/org_openjdk_sound_PulseAudioSourceDataLine.c_ORIGINAL src/org_openjdk_sound_PulseAudioSourceDataLine.h
diffstat 18 files changed, 367 insertions(+), 1600 deletions(-) [+]
line wrap: on
line diff
--- a/makefile	Fri Aug 01 12:07:21 2008 -0400
+++ b/makefile	Fri Aug 01 12:12:03 2008 -0400
@@ -22,7 +22,8 @@
 
 lib/libpulse-java.so: \
                       bin/org_openjdk_sound_EventLoop.o \
-                      bin/org_openjdk_sound_PulseAudioSourceDataLine.o 
+                      bin/org_openjdk_sound_PulseAudioSourceDataLine.o \
+					  bin/jni-common.o
 #                      bin/org_openjdk_sound_PulseAudioTargetDataLine.o 
 	gcc -g -shared -o $@ $^ /usr/lib/libpulse.so
 
@@ -37,6 +38,9 @@
 #bin/org_openjdk_sound_PulseAudioTargetDataLine.o: src/org_openjdk_sound_PulseAudioTargetDataLine.c src/org_openjdk_sound_PulseAudioTargetDataLine.h bin
 #	gcc -g -c -o $@ $<
 
+bin/jni-common.o: src/jni-common.c src/jni-common.h
+	gcc -g -c -o $@ $<
+
 # Java headers
 
 src/org_openjdk_sound_EventLoop.h: src/org/openjdk/sound/EventLoop.class
--- a/src/PulseAudioMixer.c	Fri Aug 01 12:07:21 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-#include <jni.h>
-#include <pulse/pulseaudio.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);
-}
-
-static void context_state_cb(pa_context* context, void* userdata) {
-    assert(context);
-    pa_threaded_mainloop *mainloop = userdata;
-    switch (pa_context_get_state(context)) {
-        case PA_CONTEXT_READY:
-        case PA_CONTEXT_TERMINATED:
-        case PA_CONTEXT_FAILED:
-            pa_threaded_mainloop_signal(mainloop, 0);
-            break;
-        default:
-            break;
-    }
-}
-
-JNIEXPORT void JNICALL Java_PulseAudioMixer_initialize(JNIEnv *env, jobject obj) {
-
-	//TO DO :check return value for system calls
-    pa_threaded_mainloop *mainloop = pa_threaded_mainloop_new();
-    pa_mainloop_api *mainloop_api = pa_threaded_mainloop_get_api(mainloop);
-    pa_context *context = pa_context_new(mainloop_api, "Java app");
-
-    pa_context_set_state_callback(context, context_state_cb, mainloop);
-    pa_context_connect(context, NULL, 0, NULL);
-
-    pa_threaded_mainloop_lock(mainloop);
-
-    pa_threaded_mainloop_start(mainloop);
-   
-    pa_threaded_mainloop_wait(mainloop);
-
-    if ( pa_context_get_state(context) != PA_CONTEXT_READY ) {
-        printf("context initialization failed\n");
-    }
-    
-    pa_threaded_mainloop_unlock(mainloop);
-    
-    setJavaLongField(env, obj, context, "contextPointer");
-    setJavaLongField(env, obj, mainloop, "mainLoopPointer");
-}
-
-
-
-
-
-
--- a/src/PulseAudioMixer.h	Fri Aug 01 12:07:21 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class PulseAudioMixer */
-
-#ifndef _Included_PulseAudioMixer
-#define _Included_PulseAudioMixer
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class:     PulseAudioMixer
- * Method:    initialize
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_PulseAudioMixer_initialize
-  (JNIEnv *, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
--- a/src/PulseAudioSourceDataLine.c	Fri Aug 01 12:07:21 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,267 +0,0 @@
-#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:
-        case PA_STREAM_TERMINATED:
-            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 = 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 {
-     	//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_PulseAudioSourceDataLine_startStream(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_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 JNICALL Java_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 JNICALL Java_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_PulseAudioSourceDataLine_writeToStream(JNIEnv *env, jobject obj, jbyteArray data, jint bytesRead, jint indexJava) {
-    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);
-      
-
-        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_PulseAudioSourceDataLine_closeConnection(JNIEnv *env, jobject obj, jint channels, jfloat rate) {
-
-    
-    pa_threaded_mainloop *mainloop = getJavaLongField (env, obj, "mainLoopPointer"); 
-    pa_stream *stream = getJavaLongField(env, obj, "streamPointer");
-	
-    printf("pulse_shutdown() called\n");
-
-    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);
-
-    //pa_threaded_mainloop_stop(mainloop);
-    //pa_threaded_mainloop_free(mainloop);
-}
-
-JNIEXPORT jint JNICALL Java_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 jint JNICALL Java_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 jint JNICALL Java_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);
- }
-
-
-
-
-
-
--- a/src/PulseAudioSourceDataLine.h	Fri Aug 01 12:07:21 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class PulseAudioSourceDataLine */
-
-#ifndef _Included_PulseAudioSourceDataLine
-#define _Included_PulseAudioSourceDataLine
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class:     PulseAudioSourceDataLine
- * Method:    openStream
- * Signature: (IF)V
- */
-JNIEXPORT void JNICALL Java_PulseAudioSourceDataLine_openStream
-  (JNIEnv *, jobject, jint, jfloat);
-
-/*
- * Class:     PulseAudioSourceDataLine
- * Method:    write
- * Signature: ([BIILjava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_PulseAudioSourceDataLine_write
-  (JNIEnv *, jobject, jbyteArray, jint, jint, jstring);
-
-/*
- * Class:     PulseAudioSourceDataLine
- * Method:    closeConnection
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_PulseAudioSourceDataLine_closeConnection
-  (JNIEnv *, jobject);
-
-/*
- * Class:     PulseAudioSourceDataLine
- * Method:    startStream
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_PulseAudioSourceDataLine_startStream
-  (JNIEnv *, jobject);
-
-/*
- * Class:     PulseAudioSourceDataLine
- * Method:    pauseStream
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_PulseAudioSourceDataLine_pauseStream
-  (JNIEnv *, jobject);
-
-/*
- * Class:     PulseAudioSourceDataLine
- * Method:    resumeStream
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_PulseAudioSourceDataLine_resumeStream
-  (JNIEnv *, jobject);
-
-/*
- * Class:     PulseAudioSourceDataLine
- * Method:    available
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL Java_PulseAudioSourceDataLine_available
-  (JNIEnv *, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
--- a/src/PulseAudioTargetDataLine.c	Fri Aug 01 12:07:21 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <jni.h>
-#include <pulse/pulseaudio.h>
-#include <string.h>
-
-
-const char* const APP_NAME = "simple-rec";
-
-pa_threaded_mainloop* _mainloop = NULL;
-pa_mainloop_api* _mainloop_api = NULL;
-pa_context* _context = NULL;
-pa_stream* _stream = NULL;
-const void *read_data = NULL;
-size_t read_index, read_length;
-
-
-pa_sample_spec _sample_spec;
-
-static void stream_read_cb(pa_stream* stream, size_t length, void* userdata) {
-
-    pa_threaded_mainloop_signal(_mainloop,0);
-}
-
-static void stream_drain_complete_cb(pa_stream* stream, int success, void* userdata) {
-   pa_threaded_mainloop_signal(_mainloop,0);
-}
-
-
-
-
-static void stream_state_cb(pa_stream* stream, void* userdata) {
-    assert(stream);
-
-    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:
-        case PA_STREAM_TERMINATED:
-            pa_threaded_mainloop_signal(_mainloop, 0);
-            break;
-
-        default:
-            /* do nothing */
-            break;
-    }
- }
-
-static void context_state_cb(pa_context* context, void* userdata) {
-    assert(context);
-
-    printf("context state changed to %d\n", pa_context_get_state(context));
-
-    switch (pa_context_get_state(context)) {
-        case PA_CONTEXT_READY:
-        case PA_CONTEXT_TERMINATED:
-        case PA_CONTEXT_FAILED:
-            pa_threaded_mainloop_signal(_mainloop, 0);
-            break;
-        default:
-            /* do nothing */
-            break;
-    }
-}
-
-static void init_streams(void) {
-    _sample_spec.format = PA_SAMPLE_S16LE;
-    _sample_spec.rate = 44100;
-    _sample_spec.channels = 2;
-
-    _stream = pa_stream_new(_context, "default stream", &_sample_spec, NULL);
-
-    pa_stream_set_state_callback(_stream, stream_state_cb, NULL);
-    pa_stream_set_read_callback(_stream, stream_read_cb, NULL);
-  
-
-
-    int check = pa_stream_connect_record(_stream, NULL, NULL, 0);
-    if(check < 0) {
-    	printf("couldn't connect\n");
-    }
-
-    /* wait for stream to initilize */
-    pa_threaded_mainloop_wait(_mainloop);
-
-    if (pa_stream_get_state(_stream) != PA_STREAM_READY) {
-        printf("stream initialization failed\n");
-    }
-}
-
-static void pulse_init(void) {
-
-    printf("pulse_init() called\n");
-
-
-    _mainloop = pa_threaded_mainloop_new();
-    _mainloop_api = pa_threaded_mainloop_get_api(_mainloop);
-    _context = pa_context_new(_mainloop_api, APP_NAME);
-
-    pa_context_set_state_callback(_context, context_state_cb, NULL);
-    pa_context_connect(_context, NULL, 0, NULL);
-
-    pa_threaded_mainloop_lock(_mainloop);
-
-    pa_threaded_mainloop_start(_mainloop);
-    /* wait for context to be ready */
-    pa_threaded_mainloop_wait(_mainloop);
-
-    if ( pa_context_get_state(_context) != PA_CONTEXT_READY ) {
-        printf("context initialization failed\n");
-        goto unlock_and_fail;
-    }
-
-
-    init_streams();
-
-    pa_threaded_mainloop_unlock(_mainloop);
-
-    printf("pulse_init() returning\n");
-    return;
-
-unlock_and_fail:
-    pa_threaded_mainloop_unlock(_mainloop);
-
-fail:
-    return;
-}
-
-int pulse_read (void *data, size_t length) {
-	printf("IN READ\n");
-	pa_threaded_mainloop_lock(_mainloop);
-	while(length > 0) {
-		size_t l;
-		while(!read_data) {
-			int r = pa_stream_peek(_stream, &read_data, &read_length);
-			//printf("read length = %d\n", read_length);
-			if(!read_data) {
-				pa_threaded_mainloop_wait(_mainloop);
-			} else {
-				read_index = 0;
-			}			
-		}
-		
-		l = read_length < length ? read_length : length;
-		memcpy(data, read_data+read_index, l);
-		
-		data = data + l;
-		length -= l;
-		read_index +=l;
-		read_length-=l;
-		
-		if(! read_length) {
-			int r = pa_stream_drop(_stream);
-			read_data = NULL;
-			read_length = 0;
-			read_index = 0;
-			
-		}
-		
-		
-	}
-	pa_threaded_mainloop_unlock(_mainloop);
-}
-
-void closeConnection() {
- printf("pulse_shutdown() called\n");
-
-    pa_threaded_mainloop_lock(_mainloop);
-    pa_operation *o = pa_stream_drain(_stream, stream_drain_complete_cb, NULL);
-    while(pa_operation_get_state(o) != PA_OPERATION_DONE) {
-        pa_threaded_mainloop_wait(_mainloop);
-    }
-    pa_operation_unref(o);
-    pa_threaded_mainloop_unlock(_mainloop);
-
-    pa_threaded_mainloop_stop(_mainloop);
-    pa_threaded_mainloop_free(_mainloop);
-
-    printf("pulse_shutdown() returning\n");
-    return;
-}
-                  
-
-int main() {
-	pulse_init();
-	uint8_t buf[10000];
-	pulse_read(buf, 10000); 
-	//write(1, buf, 10000);
-	//closeConnection();
-
-}
-    
-    
-
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jni-common.c	Fri Aug 01 12:12:03 2008 -0400
@@ -0,0 +1,30 @@
+#include "jni-common.h"
+
+void setJavaIntField(JNIEnv *env, jobject obj,char *fieldName, int value) {
+	jclass cls = (*env)->GetObjectClass(env, obj);
+	jfieldID fid =(*env)->GetFieldID(env, cls, fieldName, "I");
+	(*env)->SetIntField(env, obj, fid, value);
+	(*env)->DeleteLocalRef(env, cls);
+}
+
+void* getJavaIntField(JNIEnv* env, jobject obj, char* fieldName) {
+	jclass cls = (*env)->GetObjectClass(env, obj);
+	jfieldID fid = (*env)->GetFieldID(env, cls, fieldName, "I");
+	jlong value = (*env)->GetIntField(env, obj, fid);
+	(*env)->DeleteLocalRef(env, cls);
+	return (void *) value;
+}
+
+/*
+ * Throw an exception by name
+ */
+void throwByName(JNIEnv* env, const char* name, const char* msg) {
+	jclass cls = (*env)->FindClass(env, name);
+	/* if cls is NULL, an exception has already been thrown */
+	if (cls != NULL) {
+		(*env)->ThrowNew(env, cls, msg);
+	}
+	/* free the local ref */
+	(*env)->DeleteLocalRef(env, cls);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jni-common.h	Fri Aug 01 12:12:03 2008 -0400
@@ -0,0 +1,15 @@
+#ifndef _JNI_COMMON_H
+#define _JNI_COMMON_H
+
+#include <jni.h>
+/*
+ * This file contains some commonly used functions 
+ * 
+ */
+
+void* getJavaIntField(JNIEnv* env, jobject obj, char* fieldName);
+void setJavaIntField(JNIEnv* env, jobject obj, char* fieldName, int value);
+
+void throwByName(JNIEnv* const env, const char* const name, const char* const msg);
+
+#endif
--- a/src/org/openjdk/sound/EventLoop.java	Fri Aug 01 12:07:21 2008 -0400
+++ b/src/org/openjdk/sound/EventLoop.java	Fri Aug 01 12:12:03 2008 -0400
@@ -49,7 +49,16 @@
 	private native void native_set_sink_volume(int contextPointer,
 			int streamPointer, int volume);
 
-	// pointers
+	/*
+	 * These fields hold pointers
+	 * 
+	 * When going from 32 bit to 64 bit, these will have to be changed to longs,
+	 * but not otherwise
+	 * 
+	 * Pointer sizes change from 32 bit to 64 bit, but java data types's sizes
+	 * dont
+	 * 
+	 */
 	@SuppressWarnings("unused")
 	private int contextPointer;
 	@SuppressWarnings("unused")
@@ -76,8 +85,6 @@
 		contextListeners = new ArrayList<ContextListener>();
 	}
 
-
-
 	public void setAppName(String name) {
 		this.name = name;
 	}
--- a/src/org/openjdk/sound/PulseAudioMixer.java	Fri Aug 01 12:07:21 2008 -0400
+++ b/src/org/openjdk/sound/PulseAudioMixer.java	Fri Aug 01 12:12:03 2008 -0400
@@ -31,7 +31,7 @@
 
 	private boolean isOpen = false;
 
-	 private List<PulseAudioSourceDataLine> _sourceLines = new ArrayList();
+	 private List<PulseAudioSourceDataLine> _sourceLines = new ArrayList<PulseAudioSourceDataLine>();
 	// private List<PulseAudioTargetDataLine> _targetLines = null;
 
 	private Line.Info _sourceDataLineInfo = new
--- a/src/org/openjdk/sound/PulseAudioSourceDataLine.java	Fri Aug 01 12:07:21 2008 -0400
+++ b/src/org/openjdk/sound/PulseAudioSourceDataLine.java	Fri Aug 01 12:12:03 2008 -0400
@@ -19,13 +19,10 @@
 
 public class PulseAudioSourceDataLine implements SourceDataLine {
 
-	
-	
 	private static final int DEFAULT_BUFFER_SIZE = 1000;
 	private String streamName = "Java Stream";
-	private List<StreamListener> streamListeners = new ArrayList();
+	private List<StreamListener> streamListeners = new ArrayList<StreamListener>();
 
-	
 	private EventLoop eventLoop = null;
 
 	private boolean isOpen = false;
@@ -33,15 +30,21 @@
 
 	private  AudioFormat format = null;
 	
-	private ArrayList<LineListener> listeners;
+	private List<LineListener> listeners;
 
+	/*
+	 * When moving from 32bit platform to 64 bit platform, these variables that
+	 * hold pointers will need their sizes changed
+	 * 
+	 */
 	@SuppressWarnings("unused")
 	private int streamPointer;
 
-	private native void native_open(int contextPointer, String name, String encoding, float rate, int size,
-			int channels, boolean bigEndian, int bufferSize);
+	private native void native_open(int contextPointer, String name,
+			String encoding, float rate, int size, int channels,
+			boolean bigEndian, int bufferSize);
 
-	private native void native_write(byte[] data, int length);
+	private native void native_write(byte[] data,int offset, int length);
 
 	private native int native_get_writable_size();
 	
@@ -49,18 +52,20 @@
 
 	private native int native_flush();
 	
+
 	private native void native_start();
-	
+
 	private native void native_pause();
 
 	private native void native_resume();
+
 	
 	private native int native_drain();
 
 	private native void native_close();
 
 
-	/*static {
+	static {
 		try {
 			String library = new java.io.File(".").getCanonicalPath()
 					+ java.io.File.separatorChar + "lib"
@@ -71,10 +76,11 @@
 		} catch (IOException e) {
 			assert ("Loading failed".endsWith("library"));
 		}
-	}*/
+    }
 
 	public PulseAudioSourceDataLine(EventLoop eventLoop) {
 		this.eventLoop = eventLoop;
+		this.listeners = new ArrayList<LineListener>();
 	}
 
 	public void open(AudioFormat format, int bufferSize)
@@ -86,9 +92,10 @@
 		int sampleSize = format.getSampleSizeInBits();
 		String encoding = format.getEncoding().toString();
 		boolean bigEndian = format.isBigEndian();
-		
+
 		synchronized (eventLoop.threadLock) {
-			native_open(eventLoop.getContextPointer(), streamName, encoding, rate, sampleSize, channels, bigEndian, bufferSize);
+			native_open(eventLoop.getContextPointer(), streamName, encoding,
+					rate, sampleSize, channels, bigEndian, bufferSize);
 		}
 	}
 
@@ -100,30 +107,31 @@
 	public void open() throws LineUnavailableException {
 		format = new AudioFormat(44100, 16, 2, true, false);
 		open(format, DEFAULT_BUFFER_SIZE);
-		
 	}
 
-	public int write(byte[] data, int off, int len) {
-		byte[] buffer;
-		int position = off;
-		int remainingLength = len;
+	@Override
+	public int write(byte[] data, int offset, int length) {
+
+		int position = offset;
+		int remainingLength = length;
 		int availableSize;
-		// 
+
+		int sizeWritten = 0;
+
 		while (remainingLength != 0) {
 
 			synchronized (eventLoop.threadLock) {
-				availableSize = available();
+				availableSize = native_get_writable_size();
 				if (availableSize < 0) {
-					//throw new StreamFailed();
+					return sizeWritten;
 				}
 				if (availableSize > remainingLength) {
 					availableSize = remainingLength;
 				}
-				buffer = new byte[availableSize];
-				System.arraycopy(data, position, buffer, 0, availableSize);
 				/* write a little bit of the buffer */
-				native_write(buffer, buffer.length);
+				native_write(data, position, availableSize);
 
+				sizeWritten += availableSize;
 				position += availableSize;
 				remainingLength -= availableSize;
 
@@ -131,14 +139,14 @@
 		}
 
 		// all the data should have been played by now
-
-	
+		assert (sizeWritten == length);
 
 		/*
 		 * FIXME when the stream is flushed() etc, instead of returning length
 		 * this should unblock and return the the size of data written so far
 		 */
-		return len;
+
+		return sizeWritten;
 	}
 
 	public void start() {
@@ -176,9 +184,6 @@
 		
 			
 			
-			
-		
-
 		/*
 		 * for(LineListener l :listeners) { l.update(new LineEvent(this,
 		 * LineEvent.Type.START, 0)); }
@@ -219,15 +224,13 @@
 		synchronized (eventLoop.threadLock) {
 			native_close();
 		}
-		
-		
+
 		for (LineListener l : this.listeners) {
 			l.update(new LineEvent(this, LineEvent.Type.CLOSE, 0));
 		}
 
 	}
 
-
 	public int getBufferSize() {
 		// TODO Auto-generated method stub
 		return 0;
--- a/src/org_openjdk_sound_EventLoop.c	Fri Aug 01 12:07:21 2008 -0400
+++ b/src/org_openjdk_sound_EventLoop.c	Fri Aug 01 12:12:03 2008 -0400
@@ -1,6 +1,7 @@
 #include <pulse/pulseaudio.h>
 
 #include "org_openjdk_sound_EventLoop.h"
+#include "jni-common.h"
 
 const int PA_ITERATE_BLOCK = 1;
 const int PA_ITERATE_NOBLOCK = 0;
@@ -10,7 +11,7 @@
 	jobject obj;
 } java_context_t;
 
-java_context_t* java_context = NULL;
+static java_context_t* java_context = NULL;
 
 JNIEnv* pulse_thread_env = NULL;
 
@@ -98,12 +99,8 @@
 		pa_context_connect(context, NULL, 0, NULL);
 	}
 
-	fid = (*env)->GetFieldID(env, cls, "mainloopPointer", "I");
-	(*env)->SetIntField(env, obj, fid, (jint)mainloop);
-
-	fid = (*env)->GetFieldID(env, cls, "contextPointer", "I");
-	(*env)->SetIntField(env, obj, fid, (jint) context);
-
+	setJavaIntField(env, obj, "mainloopPointer", (int) mainloop);
+	setJavaIntField(env, obj, "contextPointer", (int) context);
 	printf("native_setup() returning\n");
 	return;
 
--- a/src/org_openjdk_sound_PulseAudioMixer.c	Fri Aug 01 12:07:21 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,384 +0,0 @@
-#include "org_openjdk_sound_PulseAudioMixer.h"
-
-#include <stdio.h>
-#include <assert.h>
-
-#include <pulse/pulseaudio.h>
-
-/* FIXME
- *  jvm and native code scoping problems
- */
-typedef struct java_context_t {
-	pa_threaded_mainloop* mainloop;
-	JavaVM* jvm;
-	/* each JNIEnv* is valid for the thread that obtained it */
-	JNIEnv* env;				
-	JNIEnv* pulse_thread_env;
-} java_context_t;
-
-
-/*
- * store a structure with different JNIEnv pointers
- * so we can use it across threads
- */
-static java_context_t* java_context = NULL;
-
-
-/*
- * Throw an exception by name
- */
-static void ThrowByName(JNIEnv *env, const char *name, const char *msg) {
-	jclass cls = (*env)->FindClass(env, name);
-	/* if cls is NULL, an exception has already been thrown */
-	if (cls != NULL) {
-		(*env)->ThrowNew(env, cls, msg);
-	}
-	/* free the local ref */
-	(*env)->DeleteLocalRef(env, cls);
-}
-
-
-/*
- * do the actual callback
- * 
- * a good chance this method is running in a thread other than the main one
- * 
- */
-static void callback(JNIEnv* env) {
-	
-	/* find the instance of the Mixer */
-	char class_name[] = "org/openjdk/sound/PulseAudioMixer";
-    jclass cls = (*env)->FindClass(env, class_name);
-    if ( cls == NULL) {
-    	printf("class not found");
-    	return; /* class not found */
-    }
-    
-    jmethodID mid = (*env)->GetStaticMethodID(env, cls, "getInstance", "()Lorg/openjdk/sound/PulseAudioMixer;");
-    if (mid == NULL) {
-    	printf("method not found\n");
-        return;  /* method not found */
-    }
-    
-    jobject mixer = (*env)->CallStaticObjectMethod(env, cls, mid);
-    if ( mixer == NULL) {
-    	printf("unable to get mixer\n");
-    	return;
-    }
-    printf("after getting the mixer instance\n");
-    
-    
-    mid = (*env)->GetMethodID(env, cls, "callback", "()V");
-    if ( mid == NULL) {
-    	printf("unable to get callback method\n");
-    	return;
-    	
-    }
-	printf("got callback method\n");
-	
-	(*env)->CallVoidMethod(env, mixer, mid);
-	return;
-}
-
-
-/*
- * Class:     org_openjdk_sound_PulseAudioMixer
- * Method:    native_getStatus
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL Java_org_openjdk_sound_PulseAudioMixer_native_1getStatus
-  (JNIEnv* env, jobject obj) {
-	jint result;
-	jclass cls = (*env)->GetObjectClass(env, obj);
-	
-	jfieldID fid = (*env)->GetFieldID(env, cls, "contextPointer", "I");
-	pa_context* context = (pa_context*) ((*env)->GetIntField(env, obj, fid));
-	
-	if ( context != NULL) {
-		result = pa_context_get_state(context);
-	} else  {
-		result = -1;
-	}
-	
-	if ( result != 1) {
-		jmethodID mid = (*env)->GetMethodID(env, cls, "notify", "()V");
-		(*env)->CallVoidMethod(env, obj, mid);
-	}
-	return result;
-}
-
-
-/* 
- * we need the separate thread for the pulseaudio's stuff 
- * so we need to attach the jvm to that thread.
- */
-static void attach_thread_to_jvm(java_context_t* j_context) {
-	assert(j_context);
-	assert(j_context->pulse_thread_env == NULL);
-	
-	printf("finding the JVM\n");
-
-	jsize actual_vms;
-	jint result = JNI_GetCreatedJavaVMs(&(j_context->jvm), 1, &actual_vms);
-	assert(result == 0);
-	//printf("JNI VM INFO: actual vm's created:%d\n", actual_vms);
-
-	printf("attaching to jvm...\n");
-	result = (*(j_context->jvm))->AttachCurrentThread((j_context->jvm), (void**)&(j_context->pulse_thread_env), NULL);
-			printf("attached to jvm\n");
-	assert(result == 0);
-
-//	ThrowByName(j_context->pulse_thread_env, "java/lang/UnsupportedOperationException", "Attached Native thread to jvm!");
-}
-
-
-/*
- * 
- * Detach the curren thread from the JVM
- * 
- */
-static void detach_thread_from_jvm(java_context_t* j_context) {
-	assert(j_context);
-	assert(j_context->pulse_thread_env);
-	//FIXME
-	j_context->pulse_thread_env = NULL;
-	(*(j_context->jvm))->DetachCurrentThread(j_context->jvm);
-}
-
-
-/*
- * want a call to a listener :(
- * 
- */
-static void context_drain_complete_cb(pa_context* context, void* userdata) {
-	return;
-}
-
-
-/* FIXME
- * problems: 
- *  ideally we want to tell some sort of listener on the java
- *  side that this eveven happened. question is, how to do that?
- *   - cant pass obj or env through userdata (scoping problems with jvm)
- * 
- * this method is called from either the java thread (on pa_context_connect())
- * or from the PulseAudio's thread. so its either a part of jvm, or needs to be 
- * attached to the jvm to be of use
- * 
- */
-static void context_state_cb(pa_context* context, void* userdata) {
-	assert(context);
-	
-	java_context_t* j_context = (java_context_t*)userdata;
-	pa_threaded_mainloop *mainloop = j_context->mainloop;
-
-	printf("context changed to %d\n", pa_context_get_state(context));
-	
-	static int attached = 0;
-
-	if (!attached) {
-		if (pa_context_get_state(context) != PA_CONTEXT_CONNECTING ) {
-			attached = 1;
-			attach_thread_to_jvm(j_context);
-		}
-	}
-	
-	if ( attached ) {
-		callback(j_context->pulse_thread_env);
-	} else {
-		callback(j_context->env);
-	}
-	
-	switch (pa_context_get_state(context)) {
-	case PA_CONTEXT_CONNECTING:
-		break;
-	case PA_CONTEXT_READY:
-//		ThrowByName(j_context->pulse_thread_env, "java/lang/UnsupportedOperationException", "Context connected");
-		
-		pa_threaded_mainloop_signal(mainloop, 0);
-
-		break;
-	case PA_CONTEXT_TERMINATED:
-		/* connection has sanely terminated
-		 */
-
-		if (attached) {
-			attached = 0;
-//			ThrowByName(j_context->pulse_thread_env, "java/lang/UnsupportedOperationException", "Context terminated");
-
-			detach_thread_from_jvm(j_context);
-		} else {
-//			ThrowByName(j_context->env, "java/lang/UnsupportedOperationException", "context terminated");
-		}
-		printf("ERROR: CONTEXT_TERMINATED\n");
-
-		pa_threaded_mainloop_signal(mainloop, 0);
-		break;
-		
-	case PA_CONTEXT_FAILED:
-		/* this can happen before we connect (ie error connecting to server)
-		 * or after we connect. so check whether we are connected, 
-		 * and then use the appropriate thread(env) to send the exception
-		 */
-		pa_threaded_mainloop_signal(mainloop, 0);
-
-		if (attached) {
-//			ThrowByName(j_context->pulse_thread_env, "java/lang/UnsupportedOperationException", "context failed");
-//			callback(j_context->pulse_thread_env);
-			attached = 0;
-			detach_thread_from_jvm(j_context);
-		} else {
-//			ThrowByName(j_context->env, "java/lang/UnsupportedOperationException", "context failed");
-		}
-		printf("ERROR: CONTEXT_FAILED\n");
-
-		//TODO throw an exception here?
-		// this does happen when we are trying to quit as well
-		break;
-	default:
-		break;
-	}
-}
-
-/*
- * Class:     org_openjdk_sound_PulseAudioMixer
- * Method:    native_initialize
- * Signature: (Ljava/lang/String;Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_org_openjdk_sound_PulseAudioMixer_native_1initialize
-(JNIEnv* env, jobject obj, jstring appName, jstring server) {
-
-	jfieldID fid;       /* the field id */
-	jclass cls = (*env)->GetObjectClass(env,obj);
-
-	printf("native_initialize() called\n");
-	pa_threaded_mainloop *mainloop = pa_threaded_mainloop_new();
-	assert(mainloop != NULL);
-	pa_mainloop_api *mainloop_api = pa_threaded_mainloop_get_api(mainloop);
-	assert(mainloop != NULL);
-
-	pa_context *context = NULL;
-
-	assert(appName != NULL);
-
-	const jbyte* string_appName;
-	string_appName = (*env)->GetStringUTFChars(env, appName, NULL);
-	if (string_appName == NULL) {
-		return;        /* a OutOfMemoryError thrown by vm */
-	}
-	printf("using appName : %s\n", string_appName);
-	context = pa_context_new(mainloop_api, string_appName);
-	assert(mainloop != NULL);
-	(*env)->ReleaseStringUTFChars(env, appName, string_appName);
-
-	java_context = malloc(sizeof(java_context_t));
-	java_context->mainloop = mainloop;
-	java_context->env = env;
-	java_context->pulse_thread_env = NULL;
-	
-	
-	pa_context_set_state_callback(context, context_state_cb, java_context);
-
-	if (server != NULL) {
-		const jbyte* string_server = NULL;
-		string_server = (*env)->GetStringUTFChars(env, server, NULL);
-		if (string_server == NULL) {
-			return;	/* OutOfMemoryError */
-		}
-		printf("About to connect to server: %s\n", string_server);
-		pa_context_connect(context, string_server, 0, NULL);
-		(*env)->ReleaseStringUTFChars(env, appName, string_server);
-	} else {
-		printf("using default server\n");
-		pa_context_connect(context, NULL, 0, NULL);
-	}
-
-	pa_threaded_mainloop_lock(mainloop);
-	pa_threaded_mainloop_start(mainloop);
-	pa_threaded_mainloop_wait(mainloop);	// wait for the context to initialize
-
-	if ( pa_context_get_state(context) != PA_CONTEXT_READY ) {
-		printf("ERROR: context initialization failed\n");
-		goto unlock_and_fail;
-	}
-
-	pa_threaded_mainloop_unlock(mainloop);
-
-	fid = (*env)->GetFieldID(env, cls, "mainloopPointer", "I");
-	(*env)->SetIntField(env, obj, fid, (jint)mainloop);
-
-	fid = (*env)->GetFieldID(env, cls, "contextPointer", "I");
-	(*env)->SetIntField(env, obj, fid, (jint) context);
-
-	printf("native_initialize() returning\n");
-	return;
-	
-unlock_and_fail:
-	printf("about to wait");
-
-	jmethodID mid = (*env)->GetMethodID(env, cls, "wait", "()V");
-	(*env)->CallVoidMethod(env, obj, mid);
-
-	ThrowByName(env, "java/lang/UnsupportedOperationException", "Mixer initialization failed");
-
-	pa_threaded_mainloop_unlock(mainloop);
-	pa_threaded_mainloop_stop(mainloop);
-	pa_threaded_mainloop_free(mainloop);
-
-	mainloop = NULL;
-	context = NULL;
-	
-	fid = (*env)->GetFieldID(env, cls, "mainloopPointer", "I");
-	(*env)->SetIntField(env, obj, fid, (jint)mainloop);
-
-	fid = (*env)->GetFieldID(env, cls, "contextPointer", "I");
-	(*env)->SetIntField(env, obj, fid, (jint) context);
-	
-	return;
-}
-
-/*
- * Class:     org_openjdk_sound_PulseAudioMixer
- * Method:    native_shutdown
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_openjdk_sound_PulseAudioMixer_native_1shutdown
-(JNIEnv * env, jobject obj) {
-
-	printf("native_shutdown() starting\n");
-
-	jfieldID fid;       /* the field id */
-	jclass cls = (*env)->GetObjectClass(env,obj);
-
-	fid = (*env)->GetFieldID(env, cls, "mainloopPointer", "I");
-	pa_threaded_mainloop* mainloop = (pa_threaded_mainloop*) ((*env)->GetIntField(env, obj, fid));
-	assert(mainloop != NULL);
-
-	fid = (*env)->GetFieldID(env, cls, "contextPointer", "I");
-	pa_context* context = (pa_context*) ((*env)->GetIntField(env, obj, fid));
-	assert(context != NULL);
-
-	printf("trying to acquire lock\n");
-	pa_threaded_mainloop_lock(mainloop);
-	printf("got lock\n");
-	
-	pa_operation* o = pa_context_drain(context, context_drain_complete_cb, NULL);
-	/* o is NULL if there is nothing to drain */
-	if (o != NULL) {
-		while (pa_operation_get_state(o) != PA_OPERATION_DONE) {
-			pa_threaded_mainloop_wait(mainloop);
-		}
-		pa_operation_unref(o);
-	}
-
-	pa_context_disconnect(context);
-
-	pa_threaded_mainloop_unlock(mainloop);
-	pa_threaded_mainloop_stop(mainloop);
-	pa_threaded_mainloop_free(mainloop);
-
-	free(java_context);
-	
-	printf("native_shutdown() returning\n");
-}
-
--- a/src/org_openjdk_sound_PulseAudioSourceDataLine.c	Fri Aug 01 12:07:21 2008 -0400
+++ b/src/org_openjdk_sound_PulseAudioSourceDataLine.c	Fri Aug 01 12:12:03 2008 -0400
@@ -3,24 +3,9 @@
 #include <fcntl.h>
 #include <jni.h>
 #include <pulse/pulseaudio.h>
+
 #include "org_openjdk_sound_PulseAudioSourceDataLine.h"
-
-void setJavaIntField(JNIEnv *env, jobject obj, void *ptr, char *fieldName) {
-	jclass cls = (*env)->GetObjectClass(env, obj);
-	jlong value = (int) ptr;
-	jfieldID fid =(*env)->GetFieldID(env, cls, fieldName, "I");
-	(*env)->SetIntField(env, obj, fid, value);
-	//CHECK No DeleteLocalReference Method?
-	//(*env)->DeleteLocalReference(cls);
-}
-
-void *getJavaIntField(JNIEnv *env, jobject obj, char *fieldName) {
-jclass cls = (*env)->GetObjectClass(env, obj);
-	jfieldID fid = (*env)->GetFieldID(env, cls, fieldName, "I");
-	jlong value = (*env)->GetIntField(env, obj, fid);
-	//(*env)->DeleteLocalReference(cls);
-	return (void *) value;
-}
+#include "jni-common.h"
 
 
 typedef struct java_context_t {
@@ -28,6 +13,7 @@
 	jobject obj;
 } java_context_t;
 
+static java_context_t* java_context;
 
 /* defined in EventLoop.c */
 extern JNIEnv* pulse_thread_env;
@@ -48,7 +34,7 @@
 
 	java_context_t* java_context = (java_context_t*)userdata;
 	JNIEnv* env;
-	
+
 	/* needed so we can create a stream from another thread
 	 */
 	if (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
@@ -84,8 +70,6 @@
 
 }
 
-
-
 /*
  * Class:     org_openjdk_sound_PulseAudioSourceDataLine
  * Method:    native_open
@@ -94,46 +78,58 @@
 JNIEXPORT void JNICALL Java_org_openjdk_sound_PulseAudioSourceDataLine_native_1open
 (JNIEnv* env, jobject obj, jint contextPointer, jstring name, jstring encodingString, jfloat rate, jint size, jint channels, jboolean bigEndian, jint bufferSize) {
 
+	//TODO: Need to deal with the buffer size. Currently ignored
+
+	printf("entering native_open\n");
 	java_context_t* java_context = malloc(sizeof(java_context));
 	java_context->env = env;
-;
 	java_context->obj = (*env)->NewGlobalRef(env, obj);
-;
-	    
-    pa_sample_spec sample_spec;
-    
-    char *encoding = (*env)->GetStringUTFChars(env, encodingString, 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_context* context = (pa_context*) contextPointer;
+	assert(context != NULL);
+
+	pa_sample_spec sample_spec;
+
+	const char *encoding = (*env)->GetStringUTFChars(env, encodingString, NULL);
 
-    
-    pa_stream *stream = pa_stream_new(contextPointer, "default stream", &sample_spec, 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");
+		//TODO: Invalid format :throw Exception;
+	}
 
-    pa_stream_set_state_callback(stream, stream_state_change_callback, java_context);
-  
+	sample_spec.rate = rate;
+	sample_spec.channels = channels;
 
+	/* obtain the server from the caller */
+	const jbyte* stream_name = NULL;
+	stream_name = (*env)->GetStringUTFChars(env, name, NULL);
+	if (stream_name == NULL) {
+		return; /* OutOfMemoryError */
+	}
+	printf("About to create stream: %s\n", stream_name);
+	pa_stream* stream = pa_stream_new(context, stream_name, &sample_spec, NULL);
+	assert(stream != NULL);
+	(*env)->ReleaseStringUTFChars(env, name, stream_name);
 
-    setJavaIntField(env, obj, stream, "streamPointer");    
+	pa_stream_set_state_callback(stream, stream_state_change_callback, java_context);
+
+	setJavaIntField(env, obj, "streamPointer", (int) stream);
+	printf("returning from native_open\n");
+
 }
 
 /*
@@ -142,14 +138,19 @@
  * Signature: ([BII)V
  */
 JNIEXPORT void JNICALL Java_org_openjdk_sound_PulseAudioSourceDataLine_native_1write
-(JNIEnv* env, jobject obj, jbyteArray data, jint data_length) {
+(JNIEnv* env, jobject obj, jbyteArray data, jint offset, jint data_length) {
 
-	pa_stream *stream = getJavaIntField(env, obj, "streamPointer");
+	jclass cls = (*env)->GetObjectClass(env, obj);
+	jfieldID fid = (*env)->GetFieldID(env, cls, "streamPointer", "I");
+	assert(fid);
+
+	pa_stream* stream = (pa_stream*) (*env)->GetIntField(env, obj, fid);
 	jbyte* data_buffer = (*env)->GetByteArrayElements(env, data, NULL);
+	data_buffer +=offset;
 
 	pa_stream_write(stream, data_buffer, data_length, NULL, 0, PA_SEEK_RELATIVE);
 	(*env)->ReleaseByteArrayElements(env, data, data_buffer, 0);
-	
+
 }
 
 /*
@@ -166,7 +167,6 @@
  }
 	
 
-
 /*
  * Class:     org_openjdk_sound_PulseAudioSourceDataLine
  * Method:    native_flush
@@ -198,11 +198,10 @@
 JNIEXPORT void JNICALL Java_org_openjdk_sound_PulseAudioSourceDataLine_native_1start
 (JNIEnv *env, jobject obj) {
 	printf("start called\n");
-  
-    pa_stream *stream = getJavaIntField(env, obj, "streamPointer");
 
-    pa_stream_connect_playback(stream, NULL, NULL, 0, NULL, NULL);
+	pa_stream *stream = (pa_stream*)getJavaIntField(env, obj, "streamPointer");
 
+	pa_stream_connect_playback(stream, NULL, NULL, 0, NULL, NULL);
 
 }
 
--- a/src/org_openjdk_sound_PulseAudioSourceDataLine.c_ORIGINAL	Fri Aug 01 12:07:21 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,260 +0,0 @@
-#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);
- }
-
-
-
-
-
-
--- a/src/org_openjdk_sound_PulseAudioSourceDataLine.h	Fri Aug 01 12:07:21 2008 -0400
+++ b/src/org_openjdk_sound_PulseAudioSourceDataLine.h	Fri Aug 01 12:12:03 2008 -0400
@@ -20,10 +20,10 @@
 /*
  * Class:     org_openjdk_sound_PulseAudioSourceDataLine
  * Method:    native_write
- * Signature: ([BI)V
+ * Signature: ([BII)V
  */
 JNIEXPORT void JNICALL Java_org_openjdk_sound_PulseAudioSourceDataLine_native_1write
-  (JNIEnv *, jobject, jbyteArray, jint);
+  (JNIEnv *, jobject, jbyteArray, jint, jint);
 
 /*
  * Class:     org_openjdk_sound_PulseAudioSourceDataLine
--- a/src/org_openjdk_sound_PulseAudioStreamVolumeControl.c	Fri Aug 01 12:07:21 2008 -0400
+++ b/src/org_openjdk_sound_PulseAudioStreamVolumeControl.c	Fri Aug 01 12:12:03 2008 -0400
@@ -2,7 +2,7 @@
 #include <pulse/pulseaudio.h>
 #include "org_openjdk_sound_PulseAudioStreamVolumeControl.h"
 
-typedef struct{
+typedef struct {
 	pa_threaded_mainloop *mainloop;
 	pa_cvolume *volume;
 } userdata_info;
@@ -15,41 +15,43 @@
 	return (void *) value;
 }
 
-static void sink_input_change_volume(pa_context* context, const pa_sink_input_info* sink_input_info, int eol, void* userdata) {
+static void sink_input_change_volume(pa_context* context,
+		const pa_sink_input_info* sink_input_info, int eol, void* userdata) {
 	assert(context);
 	if (eol) {
 		return;
-  	}
+	}
 	assert(sink_input_info);
-	
-	
- 	(((userdata_info *) userdata)->volume)->channels = sink_input_info->volume.channels;
- 	int j;
- 	for (j = 0; j < (((userdata_info *)userdata)->volume)->channels; j++) {
-		(((userdata_info *)userdata)->volume)->values[j] = sink_input_info->volume.values[j];
- 	}
- 	pa_threaded_mainloop_signal(((userdata_info *) userdata)->mainloop, 0);
- 	
+
+	(((userdata_info *) userdata)->volume)->channels
+			= sink_input_info->volume.channels;
+	int j;
+	for (j = 0; j < (((userdata_info *)userdata)->volume)->channels; j++) {
+		(((userdata_info *)userdata)->volume)->values[j]
+				= sink_input_info->volume.values[j];
+	}
+	pa_threaded_mainloop_signal(((userdata_info *) userdata)->mainloop, 0);
+
 }
 
-JNIEXPORT jfloat JNICALL Java_org_openjdk_sound_PulseAudioStreamVolumeControl_getValue(JNIEnv *env, jobject obj)  {
-	 pa_stream *stream = getJavaLongField(env, obj, "streamPointer");
-	 pa_threaded_mainloop *mainloop = getJavaLongField(env, obj, "mainLoopPointer");
-	 pa_context *context = pa_stream_get_context(stream);
-	 int stream_id = pa_stream_get_index(stream);
-	
-	 userdata_info *userdata =  malloc(sizeof(userdata_info));
-	 userdata->mainloop = mainloop;
-	 userdata->volume = malloc(sizeof(pa_cvolume));
-	 pa_threaded_mainloop_lock(mainloop);
-	 pa_operation *o = pa_context_get_sink_input_info((pa_context*) context ,stream_id,sink_input_change_volume, userdata);
-    	 while(pa_operation_get_state(o) != PA_OPERATION_DONE) {
-    		pa_threaded_mainloop_wait(mainloop);
-    	}
-    	pa_operation_unref(o);
-    	pa_threaded_mainloop_unlock(mainloop);
+JNIEXPORT jfloat JNICALL Java_org_openjdk_sound_PulseAudioStreamVolumeControl_getValue(JNIEnv *env, jobject obj) {
+	pa_stream *stream = getJavaLongField(env, obj, "streamPointer");
+	pa_threaded_mainloop *mainloop = getJavaLongField(env, obj, "mainLoopPointer");
+	pa_context *context = pa_stream_get_context(stream);
+	int stream_id = pa_stream_get_index(stream);
+
+	userdata_info *userdata = malloc(sizeof(userdata_info));
+	userdata->mainloop = mainloop;
+	userdata->volume = malloc(sizeof(pa_cvolume));
+	pa_threaded_mainloop_lock(mainloop);
+	pa_operation *o = pa_context_get_sink_input_info((pa_context*) context ,stream_id,sink_input_change_volume, userdata);
+	while(pa_operation_get_state(o) != PA_OPERATION_DONE) {
+		pa_threaded_mainloop_wait(mainloop);
+	}
+	pa_operation_unref(o);
+	pa_threaded_mainloop_unlock(mainloop);
 	return pa_sw_volume_to_dB(userdata->volume->values[0]);
-	 
+
 }
 
 JNIEXPORT void JNICALL Java_org_openjdk_sound_PulseAudioStreamVolumeControl_setValue (JNIEnv *env, jobject obj, jfloat new_volume) {
@@ -61,5 +63,3 @@
 	pa_context_set_sink_input_by_index(context, stream_id, pa_cvolume_set(&cv, channels, pa_sw_volume_from_dB(new_volume)), NULL, NULL);
 }
 
-
-
--- a/src/org_openjdk_sound_PulseAudioTargetDataLine.c	Fri Aug 01 12:07:21 2008 -0400
+++ b/src/org_openjdk_sound_PulseAudioTargetDataLine.c	Fri Aug 01 12:12:03 2008 -0400
@@ -4,256 +4,225 @@
 #include <jni.h>
 #include <pulse/pulseaudio.h>
 #include <string.h>
+
 #include "org_openjdk_sound_PulseAudioTargetDataLine.h"
-
-
-
-
-
+#include "jni-common.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);
+static void stream_read_cb(pa_stream* stream, size_t length, void* userdata) {
+	pa_threaded_mainloop *mainloop = userdata;
+	pa_threaded_mainloop_signal(mainloop, 0);
 }
 
-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_operation_complete_cb(pa_stream* stream, int success,
+		void* userdata) {
+	pa_threaded_mainloop *mainloop = userdata;
+	pa_threaded_mainloop_signal(mainloop, 0);
 }
 
-
-
-static void stream_read_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:
-        case PA_STREAM_TERMINATED:
-            pa_threaded_mainloop_signal(mainloop, 0);
-            break;
+	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:
+	case PA_STREAM_TERMINATED:
+		pa_threaded_mainloop_signal(mainloop, 0);
+		break;
 
-        default:
-            /* do nothing */
-            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
+(JNIEnv * env, jobject obj, jstring string, jfloat rate, jint size, jint channels, jboolean bigEndian, jint bufferSize) {
+
+	printf("entering native_open\n");
+
+	pa_context* context = (pa_context*) contextPointer;
+	assert(context != NULL);
+
+	obj = (*env)->NewGlobalRef(env, obj);
+
+	java_context_t* java_context = malloc(sizeof(java_context));
+	java_context->env = env;
+	java_context->obj = obj;
+
+	//TODO: Need to deal with the buffer size. Currently ignored
+
+	pa_sample_spec sample_spec;
+
+	char *encoding = GetStringUTFChars(env, string, NULL);
 
-    pa_threaded_mainloop *mainloop = getJavaLongField (env, obj, "mainLoopPointer"); 
-    pa_context *context = getJavaLongField(env, obj, "contextPointer");
-    
-   
-    pa_sample_spec sample_spec;
-    
-    char *encoding = 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 {
-     	//TO DO: Invalid format :throw Exception;
-     }
-    
-    sample_spec.rate = rate;
-    sample_spec.channels = channels;
+	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 {
+		//TODO: Invalid format :throw Exception;
+	}
 
-    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_read_callback(stream, stream_read_cb, mainloop);
-    
-  
-    pa_threaded_mainloop_unlock(mainloop);
+	sample_spec.rate = rate;
+	sample_spec.channels = channels;
 
-
-    setJavaLongField(env, obj, stream, "streamPointer");    
-    return;
+	/* obtain the server from the caller */
+	const jbyte* stream_name = NULL;
+	stream_name = (*env)->GetStringUTFChars(env, name, NULL);
+	if (stream_name == NULL) {
+		return; /* OutOfMemoryError */
+	}
+	printf("About to create stream: %s\n", stream_name);
+	pa_stream* stream = pa_stream_new(context, stream_name, &sample_spec, NULL);
+	assert(stream != NULL);
+	(*env)->ReleaseStringUTFChars(env, name, stream_name);
 
-unlock_and_fail:
-    pa_threaded_mainloop_unlock(mainloop);
+	pa_stream_set_state_callback(stream, stream_state_change_callback, java_context);
 
-fail:
-    return;
+	jclass cls = (*env)->GetObjectClass(env,obj);
+	jfieldID fid = (*env)->GetFieldID(env, cls, "streamPointer", "I");
+	(*env)->SetIntField(env, obj, fid, (jint) stream);
+
+	printf("returning from native_open\n");
+
 }
 
 JNIEXPORT void JNICALL
 Java_org_openjdk_sound_PulseAudioSourceDataLine_startStream(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_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);
+	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_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 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);
 }
-  
-
 
 J
 
 JNIEXPORT void JNICALL
 Java_org_openjdk_sound_PulseAudioSourceDataLine__closeStream(JNIEnv *env, jobject obj, jint channels, jfloat rate) {
 
-    
- 
-  	pa_stream *stream = getJavaLongField(env, obj, "streamPointer");
-  	pa_strean_disconnect(stream);
+	pa_stream *stream = getJavaLongField(env, obj, "streamPointer");
+	pa_strean_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);
+(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;
- }
-
+	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);
+(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);
- }
+	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);
+(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);
- }
-
-
-
-
+	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_PulseAudioTargetDataLine_readFromStream
-  (JNIEnv * env, jobject obj, jbyteArray array, jint length, jint offset);
-	pa_threaded_mainloop *mainloop = getJavaLongField (env, obj, "mainLoopPointer");
-  	pa_stream *stream = getJavaLongField(env, obj, "streamPointer");
-	pa_threaded_mainloop_lock(mainloop);
-	char[length] data;
-	while(length > 0) {
-		size_t l;
-		while(!read_data) {
-			int r = pa_stream_peek(_stream, &read_data, &read_length);
-			if(!read_data) {
-				pa_threaded_mainloop_wait(mainloop);
-			} else {
-				read_index = 0;
-			}			
+(JNIEnv * env, jobject obj, jbyteArray array, jint length, jint offset);
+pa_threaded_mainloop *mainloop = getJavaLongField(env, obj, "mainLoopPointer");
+pa_stream *stream = getJavaLongField(env, obj, "streamPointer");
+pa_threaded_mainloop_lock(mainloop);
+char[length] data;
+while(length> 0) {
+	size_t l;
+	while(!read_data) {
+		int r = pa_stream_peek(_stream, &read_data, &read_length);
+		if(!read_data) {
+			pa_threaded_mainloop_wait(mainloop);
+		} else {
+			read_index = 0;
 		}
-		
-		l = read_length < length ? read_length : length;
-		memcpy(data, read_data+read_index, l);
-		
-		data = data + l;
-		length -= l;
-		read_index +=l;
-		read_length-=l;
-		
-		if(! read_length) {
-			int r = pa_stream_drop(stream);
-			read_data = NULL;
-			read_length = 0;
-			read_index = 0;
-			
-		}
-		
-		
 	}
-	
-	pa_threaded_mainloop_unlock(mainloop);
-	SetByteArrayRegion(env, array, offset, initialLength, data);
+
+	l = read_length < length ? read_length : length;
+	memcpy(data, read_data+read_index, l);
+
+	data = data + l;
+	length -= l;
+	read_index +=l;
+	read_length-=l;
+
+	if(! read_length) {
+		int r = pa_stream_drop(stream);
+		read_data = NULL;
+		read_length = 0;
+		read_index = 0;
+
+	}
+
 }
 
-
-
-
+pa_threaded_mainloop_unlock(mainloop);
+SetByteArrayRegion(env, array, offset, initialLength, data);
+}
 
-    
-
-
-