From 1a4676be4ff1ed7cc91707488c22f91ded72fd06 Mon Sep 17 00:00:00 2001 From: Lyubomir Marinov Date: Tue, 8 May 2012 18:42:32 +0000 Subject: [PATCH] Provides source and binary compatibility with PulseAudio 0.9.21 which is the current version available in Debian stable. --- lib/native/linux-64/libjnpulseaudio.so | Bin 39553 -> 37117 bytes lib/native/linux/libjnpulseaudio.so | Bin 0 -> 31424 bytes ...communicator_impl_neomedia_pulseaudio_PA.c | 76 +++++++--- ...communicator_impl_neomedia_pulseaudio_PA.h | 8 ++ .../neomedia/device/PulseAudioSystem.java | 132 ++++++------------ .../media/protocol/pulseaudio/DataSource.java | 36 ++++- .../impl/neomedia/pulseaudio/PA.java | 2 + 7 files changed, 147 insertions(+), 107 deletions(-) create mode 100755 lib/native/linux/libjnpulseaudio.so diff --git a/lib/native/linux-64/libjnpulseaudio.so b/lib/native/linux-64/libjnpulseaudio.so index a31e9846b8753de7c31d6070b81ed3c8edd0fc78..1440a46ad3d3f56ea88cbf3bb6734597c1622d0e 100755 GIT binary patch literal 37117 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 #include #include +typedef pa_operation * (*pa_context_set_source_output_volume_t)(pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); + static void PulseAudio_contextStateCallback(pa_context *c, void *userdata); +#if (PA_MAJOR >= 1) static jlongArray PulseAudio_getFormatInfos(JNIEnv *env, jclass clazz, jsize length, pa_format_info **formats); +#endif /* #if (PA_MAJOR >= 1) */ static void PulseAudio_infoCallback(pa_context *c, jlong i, int eol, void *userdata, jmethodID methodID); static void PulseAudio_sinkInfoCallback(pa_context *c, const pa_sink_info *i, int eol, void *userdata); static void PulseAudio_sourceInfoCallback(pa_context *c, const pa_source_info *i, int eol, void *userdata); @@ -18,6 +26,7 @@ static void PulseAudio_stateCallback(void *userdata); static void PulseAudio_streamRequestCallback(pa_stream *s, size_t nbytes, void *userdata); static void PulseAudio_streamStateCallback(pa_stream *s, void *userdata); +static pa_context_set_source_output_volume_t PulseAudio_contextSetSourceOutputVolume = NULL; static jclass PulseAudio_runnableClass = NULL; static jmethodID PulseAudio_runnableMethodID = 0; static jclass PulseAudio_sinkInfoCbClass = NULL; @@ -177,14 +186,21 @@ JNIEXPORT jlong JNICALL Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_context_1set_1source_1output_1volume (JNIEnv *env, jclass clazz, jlong c, jint idx, jlong volume, jobject cb) { - return - (intptr_t) - pa_context_set_source_output_volume( + pa_operation *o; + + if (PulseAudio_contextSetSourceOutputVolume) + { + o + = PulseAudio_contextSetSourceOutputVolume( (pa_context *) (intptr_t) c, (uint32_t) idx, (const pa_cvolume *) (intptr_t) volume, NULL, NULL); + } + else + o = NULL; + return (intptr_t) o; } JNIEXPORT void JNICALL @@ -236,6 +252,7 @@ Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_cvolume_1set (pa_volume_t) v); } +#if (PA_MAJOR >= 1) JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_format_1info_1get_1encoding (JNIEnv *env, jclass clazz, jlong f) @@ -279,6 +296,16 @@ Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_format_1info_1get_1pr } return ret; } +#endif /* #if (PA_MAJOR >= 1) */ + +JNIEXPORT jstring JNICALL +Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_get_1library_1version + (JNIEnv *env, jclass clazz) +{ + const char *chars = pa_get_library_version(); + + return chars ? (*env)->NewStringUTF(env, chars) : NULL; +} JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_operation_1get_1state @@ -371,11 +398,12 @@ JNIEXPORT jstring JNICALL Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_sink_1info_1get_1description (JNIEnv *env, jclass clazz, jlong i) { - const char *description = ((pa_sink_info *) (intptr_t) i)->description; + const char *chars = ((pa_sink_info *) (intptr_t) i)->description; - return description ? (*env)->NewStringUTF(env, description) : NULL; + return chars ? (*env)->NewStringUTF(env, chars) : NULL; } +#if (PA_MAJOR >= 1) JNIEXPORT jlongArray JNICALL Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_sink_1info_1get_1formats (JNIEnv *env, jclass clazz, jlong i) @@ -387,6 +415,7 @@ Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_sink_1info_1get_1form env, clazz, sinkInfo->n_formats, sinkInfo->formats); } +#endif /* #if (PA_MAJOR >= 1) */ JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_sink_1info_1get_1index @@ -406,20 +435,18 @@ JNIEXPORT jstring JNICALL Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_sink_1info_1get_1monitor_1source_1name (JNIEnv *env, jclass clazz, jlong i) { - const char *monitorSourceName - = ((pa_sink_info *) (intptr_t) i)->monitor_source_name; + const char *chars = ((pa_sink_info *) (intptr_t) i)->monitor_source_name; - return - monitorSourceName ? (*env)->NewStringUTF(env, monitorSourceName) : NULL; + return chars ? (*env)->NewStringUTF(env, chars) : NULL; } JNIEXPORT jstring JNICALL Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_sink_1info_1get_1name (JNIEnv *env, jclass clazz, jlong i) { - const char *name = ((pa_sink_info *) (intptr_t) i)->name; + const char *chars = ((pa_sink_info *) (intptr_t) i)->name; - return name ? (*env)->NewStringUTF(env, name) : NULL; + return chars ? (*env)->NewStringUTF(env, chars) : NULL; } JNIEXPORT jint JNICALL @@ -447,11 +474,12 @@ JNIEXPORT jstring JNICALL Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_source_1info_1get_1description (JNIEnv *env, jclass clazz, jlong i) { - const char *description = ((pa_source_info *) (intptr_t) i)->description; + const char *chars = ((pa_source_info *) (intptr_t) i)->description; - return description ? (*env)->NewStringUTF(env, description) : NULL; + return chars ? (*env)->NewStringUTF(env, chars) : NULL; } +#if (PA_MAJOR >= 1) JNIEXPORT jlongArray JNICALL Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_source_1info_1get_1formats (JNIEnv *env, jclass clazz, jlong i) @@ -463,6 +491,7 @@ Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_source_1info_1get_1fo env, clazz, sourceInfo->n_formats, sourceInfo->formats); } +#endif /* #if (PA_MAJOR >= 1) */ JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_source_1info_1get_1index @@ -482,9 +511,9 @@ JNIEXPORT jstring JNICALL Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_source_1info_1get_1name (JNIEnv *env, jclass clazz, jlong i) { - const char *name = ((pa_source_info *) (intptr_t) i)->name; + const char *chars = ((pa_source_info *) (intptr_t) i)->name; - return name ? (*env)->NewStringUTF(env, name) : NULL; + return chars ? (*env)->NewStringUTF(env, chars) : NULL; } JNIEXPORT jint JNICALL @@ -607,9 +636,9 @@ Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_stream_1new_1with_1pr = pa_stream_new_with_proplist( (pa_context *) (intptr_t) c, nameChars, - (const pa_sample_spec *) ss, - (const pa_channel_map *) map, - (pa_proplist *) p); + (const pa_sample_spec *) (intptr_t) ss, + (const pa_channel_map *) (intptr_t) map, + (pa_proplist *) (intptr_t) p); (*env)->ReleaseStringUTFChars(env, name, nameChars); } return (intptr_t) stream; @@ -914,7 +943,14 @@ JNI_OnLoad(JavaVM *vm, void *reserved) } } } - return PulseAudio_streamRequestCbMethodID ? version : JNI_ERR; + if (PulseAudio_streamRequestCbMethodID) + { + PulseAudio_contextSetSourceOutputVolume + = dlsym(RTLD_DEFAULT, "pa_context_set_source_output_volume"); + } + else + version = JNI_ERR; + return version; } JNIEXPORT void JNICALL @@ -962,6 +998,7 @@ PulseAudio_contextStateCallback(pa_context *c, void *userdata) PulseAudio_stateCallback(userdata); } +#if (PA_MAJOR >= 1) static jlongArray PulseAudio_getFormatInfos (JNIEnv *env, jclass clazz, jsize length, pa_format_info **formats) @@ -981,6 +1018,7 @@ PulseAudio_getFormatInfos } return ret; } +#endif /* #if (PA_MAJOR >= 1) */ static void PulseAudio_infoCallback diff --git a/src/native/linux/pulseaudio/net_java_sip_communicator_impl_neomedia_pulseaudio_PA.h b/src/native/linux/pulseaudio/net_java_sip_communicator_impl_neomedia_pulseaudio_PA.h index a0c0a7cf8..8624de6b0 100644 --- a/src/native/linux/pulseaudio/net_java_sip_communicator_impl_neomedia_pulseaudio_PA.h +++ b/src/native/linux/pulseaudio/net_java_sip_communicator_impl_neomedia_pulseaudio_PA.h @@ -151,6 +151,14 @@ JNIEXPORT jlong JNICALL Java_net_java_sip_communicator_impl_neomedia_pulseaudio_ JNIEXPORT jint JNICALL Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_format_1info_1get_1prop_1int (JNIEnv *, jclass, jlong, jstring); +/* + * Class: net_java_sip_communicator_impl_neomedia_pulseaudio_PA + * Method: get_library_version + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_net_java_sip_communicator_impl_neomedia_pulseaudio_PA_get_1library_1version + (JNIEnv *, jclass); + /* * Class: net_java_sip_communicator_impl_neomedia_pulseaudio_PA * Method: operation_get_state diff --git a/src/net/java/sip/communicator/impl/neomedia/device/PulseAudioSystem.java b/src/net/java/sip/communicator/impl/neomedia/device/PulseAudioSystem.java index 347330282..2234572a1 100644 --- a/src/net/java/sip/communicator/impl/neomedia/device/PulseAudioSystem.java +++ b/src/net/java/sip/communicator/impl/neomedia/device/PulseAudioSystem.java @@ -367,7 +367,8 @@ public void callback(long c, long i, int eol) new CaptureDeviceInfo( NULL_DEV_CAPTURE_DEVICE_INFO_NAME, new MediaLocator(LOCATOR_PROTOCOL + ":"), - captureDeviceFormats.toArray(new Format[captureDeviceFormats.size()]))); + captureDeviceFormats.toArray( + new Format[captureDeviceFormats.size()]))); } if (!playbackDevices.isEmpty()) { @@ -492,94 +493,51 @@ private void sourceInfoListCallback( if (sampleSpecFormat != PA.SAMPLE_S16LE) return; - long[] formats = PA.source_info_get_formats(sourceInfo); - - if ((formats != null) && (formats.length > 0)) + int channels = PA.source_info_get_sample_spec_channels(sourceInfo); + int rate = PA.source_info_get_sample_spec_rate(sourceInfo); + List sourceInfoFormatList = new LinkedList(); + + if ((MediaUtils.MAX_AUDIO_CHANNELS != Format.NOT_SPECIFIED) + && (MediaUtils.MAX_AUDIO_CHANNELS < channels)) + channels = MediaUtils.MAX_AUDIO_CHANNELS; + if ((MediaUtils.MAX_AUDIO_SAMPLE_RATE != Format.NOT_SPECIFIED) + && (MediaUtils.MAX_AUDIO_SAMPLE_RATE < rate)) + rate = (int) MediaUtils.MAX_AUDIO_SAMPLE_RATE; + + AudioFormat audioFormat + = new AudioFormat( + AudioFormat.LINEAR, + rate, + 16, + channels, + AudioFormat.LITTLE_ENDIAN, + AudioFormat.SIGNED, + Format.NOT_SPECIFIED /* frameSizeInBits */, + Format.NOT_SPECIFIED /* frameRate */, + Format.byteArray); + + if (!sourceInfoFormatList.contains(audioFormat)) { - int sampleSpecChannels - = PA.source_info_get_sample_spec_channels(sourceInfo); - int sampleSpecRate - = PA.source_info_get_sample_spec_rate(sourceInfo); - List sourceInfoFormatList = new LinkedList(); - - for (long format : formats) - { - int encoding = PA.format_info_get_encoding(format); - - if ((encoding != PA.ENCODING_ANY) - && (encoding != PA.ENCODING_PCM)) - continue; - - int channels - = PA.format_info_get_prop_int( - format, - PA.PROP_FORMAT_CHANNELS); - - if (channels <= 0) - { - channels = sampleSpecChannels; - if (channels <= 0) - continue; - } - - int rate - = PA.format_info_get_prop_int( - format, - PA.PROP_FORMAT_RATE); - - if (rate <= 0) - { - rate = sampleSpecRate; - if (rate <= 0) - continue; - } - - if ((MediaUtils.MAX_AUDIO_CHANNELS != Format.NOT_SPECIFIED) - && (MediaUtils.MAX_AUDIO_CHANNELS < channels)) - channels = MediaUtils.MAX_AUDIO_CHANNELS; - if ((MediaUtils.MAX_AUDIO_SAMPLE_RATE != Format.NOT_SPECIFIED) - && (MediaUtils.MAX_AUDIO_SAMPLE_RATE < rate)) - rate = (int) MediaUtils.MAX_AUDIO_SAMPLE_RATE; - - AudioFormat audioFormat - = new AudioFormat( - AudioFormat.LINEAR, - rate, - 16, - channels, - AudioFormat.LITTLE_ENDIAN, - AudioFormat.SIGNED, - Format.NOT_SPECIFIED /* frameSizeInBits */, - Format.NOT_SPECIFIED /* frameRate */, - Format.byteArray); - - if (!sourceInfoFormatList.contains(audioFormat)) - { - sourceInfoFormatList.add(audioFormat); - if (!formatList.contains(audioFormat)) - formatList.add(audioFormat); - } - } + sourceInfoFormatList.add(audioFormat); + if (!formatList.contains(audioFormat)) + formatList.add(audioFormat); + } + if (!formatList.isEmpty()) + { + String description = PA.source_info_get_description(sourceInfo); + String name = PA.source_info_get_name(sourceInfo); - if (!formatList.isEmpty()) - { - String description = PA.source_info_get_description(sourceInfo); - String name = PA.source_info_get_name(sourceInfo); - - if (description == null) - description = name; - deviceList.add( - new CaptureDeviceInfo( - description, - new MediaLocator( - LOCATOR_PROTOCOL - + ":" - + name), - sourceInfoFormatList.toArray( - new Format[ - sourceInfoFormatList - .size()]))); - } + if (description == null) + description = name; + deviceList.add( + new CaptureDeviceInfo( + description, + new MediaLocator( + LOCATOR_PROTOCOL + + ":" + + name), + sourceInfoFormatList.toArray( + new Format[sourceInfoFormatList.size()]))); } } diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/pulseaudio/DataSource.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/pulseaudio/DataSource.java index 88a94f922..209dd1ca5 100644 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/pulseaudio/DataSource.java +++ b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/pulseaudio/DataSource.java @@ -7,6 +7,7 @@ package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.pulseaudio; import java.io.*; +import java.util.*; import javax.media.*; import javax.media.control.*; @@ -33,7 +34,40 @@ public class DataSource private static final int FRAGSIZE_IN_TENS_OF_MILLIS = 2; - private static final boolean SOFTWARE_GAIN = false; + private static final boolean SOFTWARE_GAIN; + + static { + boolean softwareGain = true; + + try + { + String libraryVersion = PA.get_library_version(); + + if (libraryVersion != null) + { + StringTokenizer st = new StringTokenizer(libraryVersion, "."); + int major = Integer.parseInt(st.nextToken()); + int minor = Integer.parseInt(st.nextToken()); + + if ((major >= 1) && (minor >= 0)) + { + softwareGain = false; + if (logger.isDebugEnabled()) + { + logger.debug( + "Will control the volume" + + " through the native PulseAudio API."); + } + } + } + } + catch (Throwable t) + { + if (t instanceof ThreadDeath) + throw (ThreadDeath) t; + } + SOFTWARE_GAIN = softwareGain; + } private class PulseAudioStream extends AbstractPullBufferStream diff --git a/src/net/java/sip/communicator/impl/neomedia/pulseaudio/PA.java b/src/net/java/sip/communicator/impl/neomedia/pulseaudio/PA.java index 971ae8c98..9f221c252 100644 --- a/src/net/java/sip/communicator/impl/neomedia/pulseaudio/PA.java +++ b/src/net/java/sip/communicator/impl/neomedia/pulseaudio/PA.java @@ -158,6 +158,8 @@ public static native long context_set_source_output_volume( public static native int format_info_get_prop_int(long f, String key); + public static native String get_library_version(); + public static native int operation_get_state(long o); public static native void operation_unref(long o);