changeset 2622:cc35d8ed9124

PR1741: Start PulseAudioTargetDataLines in the corked state. 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.
author Denis Lila <dlila@redhat.com>
date Fri, 17 Jun 2011 16:16:47 -0400
parents ae07c41dc3c2
children 26295314f6d6
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 28 20:14:46 2012 -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.
+
 2012-06-28  Omair Majid  <omajid@redhat.com>
 
 	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java	Thu Jun 28 20:14:46 2012 -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,
@@ -273,7 +273,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 28 20:14:46 2012 -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
@@ -183,15 +204,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,
@@ -471,11 +492,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");
@@ -492,11 +517,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 28 20:14:46 2012 -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 28 20:14:46 2012 -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 28 20:14:46 2012 -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 28 20:14:46 2012 -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);
 }
 
 /*
@@ -440,9 +463,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);
@@ -462,14 +484,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);
@@ -477,10 +491,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);
@@ -497,7 +510,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);
@@ -508,14 +521,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);
@@ -524,7 +529,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);