changeset 2516:4ffbd8c06389

Start PulseAudioTargetDataLines in the corked state.
author Denis Lila <dlila@redhat.com>
date Fri, 17 Jun 2011 16:16:47 -0400
parents 2b986620b907
children 4d1216f65423
files ChangeLog pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java pulseaudio/src/native/jni-common.h pulseaudio/src/native/org_classpath_icedtea_pulseaudio_ContextEvent.c pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Operation.c pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c
diffstat 7 files changed, 137 insertions(+), 65 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Jun 16 11:11:35 2011 -0400
+++ b/ChangeLog	Fri Jun 17 16:16:47 2011 -0400
@@ -1,3 +1,35 @@
+2011-06-17  Denis Lila  <dlila@redhat.com>
+
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java
+	(FLAG_NOFLAGS, FLAG_START_CORKED, FLAG_INTERPOLATE_TIMING,
+	 FLAG_NOT_MONOTONIC, FLAG_AUTO_TIMING_UPDATE, FLAG_NO_REMAP_CHANNELS,
+	 FLAG_NO_REMIX_CHANNELS, FLAG_FIX_FORMAT, FLAG_FIX_RATE,
+	 FLAG_FIX_CHANNELS, FLAG_DONT_MOVE, FLAG_VARIABLE_RATE, FLAG_PEAK_DETECT,
+	 FLAG_START_MUTED, FLAG_ADJUST_LATENCY, FLAG_EARLY_REQUESTS,
+	 FLAG_DONT_INHIBIT_AUTO_SUSPEND, FLAG_START_UNMUTED, FLAG_FAIL_ON_SUSPEND):
+	New static long variables mirroring pa_stream_flag_t values.
+	(STATE_UNCONNECTED, STATE_CREATING, STATE_READY, STATE_FAILED,
+	 STATE_TERMINATED): Add the STATE_ prefix to distinguish them from
+	the flag variables.
+	(native_pa_stream_connect_playback, native_pa_stream_connect_record):
+	Change flags parameter to long.
+	(connectForPlayback, connectForRecording): Start the stream corked.
+	Change formatting to make it more readable.
+	* pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c
+	(SET_STREAM_ENUM): Renamed from SET_STREAM_STATE_ENUM, since the
+	macro could have been used for any PA_STREAM constants, not just
+	stream states (and indeed, we now use it for flag constants too).
+	(Java_org_classpath_icedtea_pulseaudio_Stream_init_1constants):
+	Initialize flag constants in addition to the stream states.
+	(Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1connect_1playback):
+	Change flags parameter to jlong (from jint), remove commented out
+	dead code, remove obsolete comment, and start the stream with whatever
+	flags were passed in the flags parameter, instead of ignoring that
+	parameter and using PA_STREAM_START_CORKED.
+	(Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1connect_1record):
+	Change flags parameter to jlong (from jint), remove commented out
+	dead code.
+
 2011-06-16  Denis Lila  <dlila@redhat.com>
 
 	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java	Thu Jun 16 11:11:35 2011 -0400
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java	Fri Jun 17 16:16:47 2011 -0400
@@ -170,7 +170,7 @@
                      * the listener is guaranteed to have run
                      */
 
-                    if (stream.getState() == Stream.READY) {
+                    if (stream.getState() == Stream.STATE_READY) {
                         if (sendEvents) {
                             fireLineEvent(new LineEvent(
                                     PulseAudioDataLine.this,
@@ -178,8 +178,8 @@
                         }
                         semaphore.release();
 
-                    } else if (stream.getState() == Stream.TERMINATED
-                            || stream.getState() == Stream.FAILED) {
+                    } else if (stream.getState() == Stream.STATE_TERMINATED
+                            || stream.getState() == Stream.STATE_FAILED) {
                         if (sendEvents) {
                             fireLineEvent((new LineEvent(
                                     PulseAudioDataLine.this,
@@ -269,7 +269,7 @@
         try {
             semaphore.acquire();
             synchronized (eventLoop.threadLock) {
-                if (stream.getState() != Stream.READY) {
+                if (stream.getState() != Stream.STATE_READY) {
                     stream.disconnect();
                     stream.free();
                     throw new LineUnavailableException(
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java	Thu Jun 16 11:11:35 2011 -0400
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java	Fri Jun 17 16:16:47 2011 -0400
@@ -101,25 +101,46 @@
 
     // see comments in ContextEvent.java and Operation.java
     // These are the possible stream states.
-    // TODO: perhaps we should do this for stream flags too.
-    public static long UNCONNECTED = -1,
-                       CREATING    = -1,
-                       READY       = -1,
-                       FAILED      = -1,
-                       TERMINATED  = -1;
-
-    private static native void init_constants();
+    public static long STATE_UNCONNECTED = -1,
+                       STATE_CREATING    = -1,
+                       STATE_READY       = -1,
+                       STATE_FAILED      = -1,
+                       STATE_TERMINATED  = -1;
 
     // Throw an IllegalStateException if value is not one of the possible
     // states. Otherwise return the input.
     public static long checkNativeStreamState(long value) {
-        if (!Arrays.asList(UNCONNECTED, CREATING, READY, FAILED, TERMINATED)
-                .contains(value)) {
+        if (!Arrays.asList(STATE_UNCONNECTED, STATE_CREATING,
+                STATE_READY, STATE_FAILED, STATE_TERMINATED
+            ).contains(value)) {
             throw new IllegalStateException("Illegal constant for ContextEvent: " + value);
         }
         return value;
     }
 
+    // These are stream flags.
+    public static long FLAG_NOFLAGS                   = -1,
+                       FLAG_START_CORKED              = -1,
+                       FLAG_INTERPOLATE_TIMING        = -1,
+                       FLAG_NOT_MONOTONIC             = -1,
+                       FLAG_AUTO_TIMING_UPDATE        = -1,
+                       FLAG_NO_REMAP_CHANNELS         = -1,
+                       FLAG_NO_REMIX_CHANNELS         = -1,
+                       FLAG_FIX_FORMAT                = -1,
+                       FLAG_FIX_RATE                  = -1,
+                       FLAG_FIX_CHANNELS              = -1,
+                       FLAG_DONT_MOVE                 = -1,
+                       FLAG_VARIABLE_RATE             = -1,
+                       FLAG_PEAK_DETECT               = -1,
+                       FLAG_START_MUTED               = -1,
+                       FLAG_ADJUST_LATENCY            = -1,
+                       FLAG_EARLY_REQUESTS            = -1,
+                       FLAG_DONT_INHIBIT_AUTO_SUSPEND = -1,
+                       FLAG_START_UNMUTED             = -1,
+                       FLAG_FAIL_ON_SUSPEND           = -1;
+
+    private static native void init_constants();
+
     // We don't change this to static longs like we did with all other pulse
     // audio enums mirrored in java because we never use the pulse audio
     // integer value of formats on the java side. In java, the handling of
@@ -180,15 +201,15 @@
     private native int native_pa_stream_connect_playback(String name,
             int bufferMaxLength, int bufferTargetLength,
             int bufferPreBuffering, int bufferMinimumRequest,
-            int bufferFragmentSize, int flags, byte[] volumePointer,
+            int bufferFragmentSize, long flags, byte[] volumePointer,
             byte[] sync_streamPointer);
 
     private native int native_pa_stream_connect_record(String name,
             int bufferMaxLength, int bufferTargetLength,
             int bufferPreBuffering, int bufferMinimumRequest,
-            int bufferFragmentSize, int flags, byte[] volumePointer,
+            int bufferFragmentSize, long flags, byte[] volumePointer,
             byte[] sync_streamPointer);
-
+    
     private native int native_pa_stream_disconnect();
 
     private native int native_pa_stream_write(byte[] data, int offset,
@@ -468,11 +489,15 @@
             StreamBufferAttributes bufferAttributes, byte[] syncStreamPointer)
             throws LineUnavailableException {
 
-        int returnValue = native_pa_stream_connect_playback(deviceName,
-                bufferAttributes.getMaxLength(), bufferAttributes
-                        .getTargetLength(), bufferAttributes.getPreBuffering(),
-                bufferAttributes.getMinimumRequest(), bufferAttributes
-                        .getFragmentSize(), 0, null, syncStreamPointer);
+        int returnValue = native_pa_stream_connect_playback(
+                              deviceName,
+                              bufferAttributes.getMaxLength(),
+                              bufferAttributes.getTargetLength(),
+                              bufferAttributes.getPreBuffering(),
+                              bufferAttributes.getMinimumRequest(),
+                              bufferAttributes.getFragmentSize(),
+                              FLAG_START_CORKED, null, syncStreamPointer
+                          );
         if (returnValue < 0) {
             throw new LineUnavailableException(
                     "Unable To connect a line for playback");
@@ -489,11 +514,15 @@
             StreamBufferAttributes bufferAttributes)
             throws LineUnavailableException {
 
-        int returnValue = native_pa_stream_connect_record(deviceName,
-                bufferAttributes.getMaxLength(), bufferAttributes
-                        .getTargetLength(), bufferAttributes.getPreBuffering(),
-                bufferAttributes.getMinimumRequest(), bufferAttributes
-                        .getFragmentSize(), 0, null, null);
+        int returnValue = native_pa_stream_connect_record(
+                              deviceName,
+                              bufferAttributes.getMaxLength(),
+                              bufferAttributes.getTargetLength(),
+                              bufferAttributes.getPreBuffering(),
+                              bufferAttributes.getMinimumRequest(),
+                              bufferAttributes.getFragmentSize(),
+                              FLAG_START_CORKED, null, null
+                          );
         if (returnValue < 0) {
             throw new LineUnavailableException(
                     "Unable to connect line for recording");
--- a/pulseaudio/src/native/jni-common.h	Thu Jun 16 11:11:35 2011 -0400
+++ b/pulseaudio/src/native/jni-common.h	Fri Jun 17 16:16:47 2011 -0400
@@ -46,11 +46,12 @@
  */
 
 // Sets the field with name field_name from jclass clz to pa_prefix_field_name.
-#define SET_JAVA_STATIC_LONG_FIELD_TO_PA_ENUM(env, clz, pa_prefix, field_name)    \
-    do {                                                                          \
-        jfieldID fid = (*env)->GetStaticFieldID(env, clz, #field_name, "J");      \
-        assert(fid);                                                              \
-        (*env)->SetStaticLongField(env, clz, fid, PA_##pa_prefix##_##field_name); \
+#define SET_JAVA_STATIC_LONG_FIELD_TO_PA_ENUM(env, clz, java_prefix, pa_prefix, name) \
+    do { \
+        char *java_full_name = #java_prefix #name; \
+        jfieldID fid = (*env)->GetStaticFieldID(env, clz, java_full_name, "J"); \
+        assert(fid); \
+        (*env)->SetStaticLongField(env, clz, fid, PA_##pa_prefix##_##name); \
     } while(0);
 
 typedef struct java_context_t {
--- a/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_ContextEvent.c	Thu Jun 16 11:11:35 2011 -0400
+++ b/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_ContextEvent.c	Fri Jun 17 16:16:47 2011 -0400
@@ -40,8 +40,10 @@
 #include "org_classpath_icedtea_pulseaudio_ContextEvent.h"
 #include "jni-common.h"
 
+// we don't prefix the java names with anything, so we leave the third argument
+// empty
 #define SET_CONTEXT_ENUM(env, clz, name) \
-    SET_JAVA_STATIC_LONG_FIELD_TO_PA_ENUM(env, clz, CONTEXT, name)
+    SET_JAVA_STATIC_LONG_FIELD_TO_PA_ENUM(env, clz, , CONTEXT, name)
 
 /*
  * Class:     org_classpath_icedtea_pulseaudio_ContextEvent
--- a/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Operation.c	Thu Jun 16 11:11:35 2011 -0400
+++ b/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Operation.c	Fri Jun 17 16:16:47 2011 -0400
@@ -40,8 +40,10 @@
 #include "jni-common.h"
 #include <pulse/pulseaudio.h>
 
+// we don't prefix the java names with anything, so we leave the third argument
+// empty
 #define SET_OP_ENUM(env, clz, name) \
-    SET_JAVA_STATIC_LONG_FIELD_TO_PA_ENUM(env, clz, OPERATION, name)
+    SET_JAVA_STATIC_LONG_FIELD_TO_PA_ENUM(env, clz, , OPERATION, name)
 
 /*
  * Class:     org_classpath_icedtea_pulseaudio_Operation
--- a/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c	Thu Jun 16 11:11:35 2011 -0400
+++ b/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c	Fri Jun 17 16:16:47 2011 -0400
@@ -240,8 +240,9 @@
 
 }
 
-#define SET_STREAM_STATE_ENUM(env, clz, state_name) \
-    SET_JAVA_STATIC_LONG_FIELD_TO_PA_ENUM(env, clz, STREAM, state_name)
+// used to set stream flags and states.
+#define SET_STREAM_ENUM(env, clz, java_prefix, state_name) \
+    SET_JAVA_STATIC_LONG_FIELD_TO_PA_ENUM(env, clz, java_prefix, STREAM, state_name)
 
 /*
  * Class:     org_classpath_icedtea_pulseaudio_Stream
@@ -250,11 +251,33 @@
  */
 JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_init_1constants
   (JNIEnv *env, jclass clz) {
-    SET_STREAM_STATE_ENUM(env, clz, UNCONNECTED);
-    SET_STREAM_STATE_ENUM(env, clz, CREATING);
-    SET_STREAM_STATE_ENUM(env, clz, READY);
-    SET_STREAM_STATE_ENUM(env, clz, FAILED);
-    SET_STREAM_STATE_ENUM(env, clz, TERMINATED);
+    // set states.
+    SET_STREAM_ENUM(env, clz, STATE, UNCONNECTED);
+    SET_STREAM_ENUM(env, clz, STATE, CREATING);
+    SET_STREAM_ENUM(env, clz, STATE, READY);
+    SET_STREAM_ENUM(env, clz, STATE, FAILED);
+    SET_STREAM_ENUM(env, clz, STATE, TERMINATED);
+
+    // set flags.
+    SET_STREAM_ENUM(env, clz, FLAG, NOFLAGS);
+    SET_STREAM_ENUM(env, clz, FLAG, START_CORKED);
+    SET_STREAM_ENUM(env, clz, FLAG, INTERPOLATE_TIMING);
+    SET_STREAM_ENUM(env, clz, FLAG, NOT_MONOTONIC);
+    SET_STREAM_ENUM(env, clz, FLAG, AUTO_TIMING_UPDATE);
+    SET_STREAM_ENUM(env, clz, FLAG, NO_REMAP_CHANNELS);
+    SET_STREAM_ENUM(env, clz, FLAG, NO_REMIX_CHANNELS);
+    SET_STREAM_ENUM(env, clz, FLAG, FIX_FORMAT);
+    SET_STREAM_ENUM(env, clz, FLAG, FIX_RATE);
+    SET_STREAM_ENUM(env, clz, FLAG, FIX_CHANNELS);
+    SET_STREAM_ENUM(env, clz, FLAG, DONT_MOVE);
+    SET_STREAM_ENUM(env, clz, FLAG, VARIABLE_RATE);
+    SET_STREAM_ENUM(env, clz, FLAG, PEAK_DETECT);
+    SET_STREAM_ENUM(env, clz, FLAG, START_MUTED);
+    SET_STREAM_ENUM(env, clz, FLAG, ADJUST_LATENCY);
+    SET_STREAM_ENUM(env, clz, FLAG, EARLY_REQUESTS);
+    SET_STREAM_ENUM(env, clz, FLAG, DONT_INHIBIT_AUTO_SUSPEND);
+    SET_STREAM_ENUM(env, clz, FLAG, START_UNMUTED);
+    SET_STREAM_ENUM(env, clz, FLAG, FAIL_ON_SUSPEND);
 }
 
 /*
@@ -431,9 +454,8 @@
 JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1connect_1playback
 (JNIEnv* env, jobject obj, jstring device, jint bufferMaxLength,
         jint bufferTargetLength, jint bufferPreBuffering,
-        jint bufferMinimumRequest, jint bufferFragmentSize, jint flags,
+        jint bufferMinimumRequest, jint bufferFragmentSize, jlong flags,
         jbyteArray volumePointer, jbyteArray sync_streamPointer) {
-
     pa_stream *sync_stream;
     if(sync_streamPointer != NULL) {
         sync_stream = convertJavaPointerToNative(env, sync_streamPointer);
@@ -453,14 +475,6 @@
     buffer_attr.prebuf = (uint32_t) bufferPreBuffering;
     buffer_attr.minreq = (uint32_t) bufferMinimumRequest;
 
-    /*
-     printf("buffer maxlength: %u\n", buffer_attr.maxlength);
-     printf("buffer tlength: %u\n", buffer_attr.tlength);
-     printf("buffer prebuf: %u\n", buffer_attr.prebuf);
-     printf("buffer minreq: %u\n", buffer_attr.minreq);
-     printf("buffer fragsize: %u\n", buffer_attr.fragsize);
-     */
-
     const char* dev = NULL;
     if (device != NULL) {
         dev = (*env)->GetStringUTFChars(env, device, NULL);
@@ -468,10 +482,9 @@
             return -1; // oome thrown
         }
     }
-    /* Set flags to 0 to fix problem with draining before calling start, might need to
-     be changed back to PA_STREAM_START_CORKED in the future, if we'll be able to implement
-     synchronization*/
-    int value = pa_stream_connect_playback(stream, dev, &buffer_attr, PA_STREAM_START_CORKED, NULL, sync_stream);
+
+    int value = pa_stream_connect_playback(stream, dev, &buffer_attr,
+            (pa_stream_flags_t) flags, NULL, sync_stream);
 
     if (dev != NULL) {
         (*env)->ReleaseStringUTFChars(env, device, dev);
@@ -488,7 +501,7 @@
 JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1connect_1record
 (JNIEnv* env, jobject obj, jstring device, jint bufferMaxLength,
         jint bufferTargetLength, jint bufferPreBuffereing,
-        jint bufferMinimumRequest, jint bufferFragmentSize, jint flags,
+        jint bufferMinimumRequest, jint bufferFragmentSize, jlong flags,
         jbyteArray volumePointer, jbyteArray sync_streamPointer) {
 
     pa_stream* stream = (pa_stream*)getJavaPointer(env, obj, STREAM_POINTER);
@@ -499,14 +512,6 @@
     buffer_attr.maxlength = (uint32_t) bufferMaxLength;
     buffer_attr.fragsize = (uint32_t) bufferFragmentSize;
 
-    /*
-     printf("buffer maxlength: %u\n", buffer_attr.maxlength);
-     printf("buffer tlength: %u\n", buffer_attr.tlength);
-     printf("buffer prebuf: %u\n", buffer_attr.prebuf);
-     printf("buffer minreq: %u\n", buffer_attr.minreq);
-     printf("buffer fragsize: %u\n", buffer_attr.fragsize);
-     */
-
     const char* dev = NULL;
     if (device != NULL) {
         dev = (*env)->GetStringUTFChars(env, device, NULL);
@@ -515,7 +520,8 @@
         }
     }
 
-    int value = pa_stream_connect_record(stream, dev, &buffer_attr, flags);
+    int value = pa_stream_connect_record(stream, dev, &buffer_attr,
+                                         (pa_stream_flags_t) flags);
 
     if (dev != NULL) {
         (*env)->ReleaseStringUTFChars(env, device, dev);