changeset 1322:a08ebb168e2f

2009-01-21 Omair Majid <omajid@redhat.com> * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java: Remove unused variables volume and muted. (PulseAudioClip): Remove variable volume. (open): Remove muteControl, volume and muted. (native_setVolume): Rename to native_set_volume. (native_update_volume): New function. (isMuted): Remove. (setMuted): Remove. (setVolume): Rename to setCachedVolume. (getVolume): Rename to getCachedVolume. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMuteControl.java: Remove file. Mute relied on chaning the volume only through the api. That assumption is invalid as the user can change volume through pulseaudio's controls. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPlaybackLine.java (isMuted): Remove. (setMuted): Remove. (native_setVolume): Rename to native_set_volume. (native_update_volume): New function. (getVolume): Rename to getCachedVolume. (setVolume): Rename to setCachedVolume. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java: Remove muted and muteControl. Rename volume to cachedVolume. (PulseAudioPort): Remove muteControl. (isMuted): Remove function. (setMuted): Remove. (native_setVolume): Rename to native_set_volume. (native_updateVolumeInfo): Rename to native_update_volume. (setVolume): Rename to setCachedVolume. (getVolume): Rename to getCachedVolume. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java: Remove muteControl, muted and volume. (open): Remove muteControl. (native_setVolume): Rename to native_set_volume. (native_update_volume): New function. (isMuted): Remove. (setMuted): Remove. (getVolume): Rename to getCachedVolume. (setVolume): Rename to setCachedVolume. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java (native_setVolume): Rename to native_set_volume. (native_updateVolumeInfo): Rename to native_update_volume. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java (native_setVolume): Rename to native_set_volume. (native_updateVolumeInfo): Rename to native_update_volume. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioVolumeControl.java (setValue): Dont check for mute. (getValue): Query pulseaudio for any change in volume. * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java: New variable cachedVolume. (native_setVolume): Rename to native_set_volume. (native_update_volume): New function. (getCachedVolume): New function. (setCachedVolume): New function. (update_channels_and_volume): New function. * pulseaudio/src/native/org_classpath_icedtea_pulseaudio_EventLoop.c (sink_input_volume_change_complete): Remove. (sink_input_change_volume): Remove. (Java_org_classpath_icedtea_pulseaudio_EventLoop_native_1set_1sink_1volume): Remove. * pulseaudio/src/native/org_classpath_icedtea_pulseaudio_PulseAudioSourcePort.c (Java_org_classpath_icedtea_pulseaudio_PulseAudioSourcePort_native_1updateVolumeInfo): Rename to Java_org_classpath_icedtea_pulseaudio_PulseAudioSourcePort_native_1update_1volume. (Java_org_classpath_icedtea_pulseaudio_PulseAudioSourcePort_native_1setVolume): Rename to Java_org_classpath_icedtea_pulseaudio_PulseAudioSourcePort_native_1set_1volume. * pulseaudio/src/native/org_classpath_icedtea_pulseaudio_PulseAudioTargetPort.c (Java_org_classpath_icedtea_pulseaudio_PulseAudioTargetPort_native_1updateVolumeInfo): Rename to Java_org_classpath_icedtea_pulseaudio_PulseAudioTargetPort_native_1update_1volume. (Java_org_classpath_icedtea_pulseaudio_PulseAudioTargetPort_native_1setVolume): Rename to Java_org_classpath_icedtea_pulseaudio_PulseAudioTargetPort_native_1set_1volume. * pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c (Java_org_classpath_icedtea_pulseaudio_Stream_native_1setVolume): Rename to Java_org_classpath_icedtea_pulseaudio_Stream_native_1set_1volume. (get_sink_input_volume_callback): New function. (Java_org_classpath_icedtea_pulseaudio_Stream_native_1update_1volume): New function. * pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java (testSupportedControls): Update to not check for MuteControl. * pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineRawTest.java (testVolumeAndMute): Rename to testVolume. Remove test for MuteControl. * pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java (testVolumeAndMute): Likewise. (testSupportedControls): Update to not check for MuteControl. * pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourcePortTest.java (testControls): Update to not check for MuteControl. * pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetPortTest.java (testControls): Likewise.
author Omair Majid <omajid@redhat.com>
date Wed, 21 Jan 2009 17:17:47 -0500
parents c5ad89aedcb0
children fd00fcaea171
files ChangeLog pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMuteControl.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPlaybackLine.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioVolumeControl.java pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java pulseaudio/src/native/org_classpath_icedtea_pulseaudio_EventLoop.c pulseaudio/src/native/org_classpath_icedtea_pulseaudio_PulseAudioSourcePort.c pulseaudio/src/native/org_classpath_icedtea_pulseaudio_PulseAudioTargetPort.c pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineRawTest.java pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourcePortTest.java pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetPortTest.java
diffstat 19 files changed, 291 insertions(+), 287 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Jan 21 12:13:43 2009 -0500
+++ b/ChangeLog	Wed Jan 21 17:17:47 2009 -0500
@@ -1,3 +1,98 @@
+2009-01-21  Omair Majid  <omajid@redhat.com>
+
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java: 
+	Remove unused variables volume and muted.
+	(PulseAudioClip): Remove variable volume.
+	(open): Remove muteControl, volume and muted.
+	(native_setVolume): Rename to native_set_volume.
+	(native_update_volume): New function.
+	(isMuted): Remove.
+	(setMuted): Remove.
+	(setVolume): Rename to setCachedVolume.
+	(getVolume): Rename to getCachedVolume.
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMuteControl.java:
+	Remove file. Mute relied on chaning the volume only through the api. That
+	assumption is invalid as the user can change volume through pulseaudio's
+	controls.
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPlaybackLine.java
+	(isMuted): Remove.
+	(setMuted): Remove.
+	(native_setVolume): Rename to native_set_volume.
+	(native_update_volume): New function.
+	(getVolume): Rename to getCachedVolume.
+	(setVolume): Rename to setCachedVolume.
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java:
+	Remove muted and muteControl. Rename volume to cachedVolume. 
+	(PulseAudioPort): Remove muteControl.
+	(isMuted): Remove function.
+	(setMuted): Remove.
+	(native_setVolume): Rename to native_set_volume.
+	(native_updateVolumeInfo): Rename to native_update_volume.
+	(setVolume): Rename to setCachedVolume.
+	(getVolume): Rename to getCachedVolume.
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java:
+	Remove muteControl, muted and volume.
+	(open): Remove muteControl.
+	(native_setVolume): Rename to native_set_volume.
+	(native_update_volume): New function.
+	(isMuted): Remove.
+	(setMuted): Remove.
+	(getVolume): Rename to getCachedVolume.
+	(setVolume): Rename to setCachedVolume.
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java
+	(native_setVolume): Rename to native_set_volume.
+	(native_updateVolumeInfo): Rename to native_update_volume.
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java
+	(native_setVolume): Rename to native_set_volume.
+	(native_updateVolumeInfo): Rename to native_update_volume.
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioVolumeControl.java
+	(setValue): Dont check for mute.
+	(getValue): Query pulseaudio for any change in volume.
+	* pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java:
+	New variable cachedVolume.
+	(native_setVolume): Rename to native_set_volume.
+	(native_update_volume): New function.
+	(getCachedVolume): New function.
+	(setCachedVolume): New function.
+	(update_channels_and_volume): New function.
+	* pulseaudio/src/native/org_classpath_icedtea_pulseaudio_EventLoop.c
+	(sink_input_volume_change_complete): Remove.
+	(sink_input_change_volume): Remove.
+	(Java_org_classpath_icedtea_pulseaudio_EventLoop_native_1set_1sink_1volume):
+	Remove.
+	* pulseaudio/src/native/org_classpath_icedtea_pulseaudio_PulseAudioSourcePort.c
+	(Java_org_classpath_icedtea_pulseaudio_PulseAudioSourcePort_native_1updateVolumeInfo):
+	Rename to
+	Java_org_classpath_icedtea_pulseaudio_PulseAudioSourcePort_native_1update_1volume.
+	(Java_org_classpath_icedtea_pulseaudio_PulseAudioSourcePort_native_1setVolume):
+	Rename to
+	Java_org_classpath_icedtea_pulseaudio_PulseAudioSourcePort_native_1set_1volume.
+	* pulseaudio/src/native/org_classpath_icedtea_pulseaudio_PulseAudioTargetPort.c
+	(Java_org_classpath_icedtea_pulseaudio_PulseAudioTargetPort_native_1updateVolumeInfo):
+	Rename to
+	Java_org_classpath_icedtea_pulseaudio_PulseAudioTargetPort_native_1update_1volume.
+	(Java_org_classpath_icedtea_pulseaudio_PulseAudioTargetPort_native_1setVolume):
+	Rename to
+	Java_org_classpath_icedtea_pulseaudio_PulseAudioTargetPort_native_1set_1volume.
+	* pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c
+	(Java_org_classpath_icedtea_pulseaudio_Stream_native_1setVolume): Rename
+	to Java_org_classpath_icedtea_pulseaudio_Stream_native_1set_1volume.
+	(get_sink_input_volume_callback): New function.
+	(Java_org_classpath_icedtea_pulseaudio_Stream_native_1update_1volume): New
+	function.
+
+	* pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java
+	(testSupportedControls): Update to not check for MuteControl.
+	* pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineRawTest.java
+	(testVolumeAndMute): Rename to testVolume. Remove test for MuteControl.
+	* pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java
+	(testVolumeAndMute): Likewise.
+	(testSupportedControls): Update to not check for MuteControl.
+	* pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourcePortTest.java	
+	(testControls): Update to not check for MuteControl.
+	* pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetPortTest.java
+	(testControls): Likewise.
+
 2009-01-21  Lillian Angel  <langel@redhat.com>
 
 	* plugin/icedtea/sun/applet/AppletSecurityContextManager.java: Added
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioClip.java	Wed Jan 21 17:17:47 2009 -0500
@@ -55,9 +55,6 @@
 
 	private byte[] data = null;
 
-	private boolean muted;
-	private float volume;
-
 	// these are frame indices. so counted from 0
 	// the current frame index
 	private int currentFrame = 0;
@@ -206,7 +203,6 @@
 		this.supportedFormats = formats;
 		this.defaultFormat = defaultFormat;
 		this.currentFormat = defaultFormat;
-		this.volume = PulseAudioVolumeControl.MAX_VOLUME;
 		this.streamName = DEFAULT_CLIP_NAME;
 
 		clipThread = new ClipThread();
@@ -416,12 +412,7 @@
 
 		PulseAudioVolumeControl volumeControl = new PulseAudioVolumeControl(
 				this, eventLoop);
-		PulseAudioMuteControl muteControl = new PulseAudioMuteControl(this,
-				volumeControl);
 		controls.add(volumeControl);
-		controls.add(muteControl);
-		volume = volumeControl.getValue();
-		muted = muteControl.getValue();
 
 		PulseAudioMixer mixer = PulseAudioMixer.getInstance();
 		mixer.addSourceLine(this);
@@ -433,28 +424,22 @@
 
 	// FIXME
 	@Override
-	public byte[] native_setVolume(float value) {
-		return stream.native_setVolume(value);
+	public byte[] native_set_volume(float value) {
+		return stream.native_set_volume(value);
 	}
 
+	public byte[] native_update_volume() {
+		return stream.native_update_volume();
+	}
+	
 	@Override
-	public boolean isMuted() {
-		return muted;
+	public float getCachedVolume() {
+		return stream.getCachedVolume();
 	}
 
 	@Override
-	public void setMuted(boolean value) {
-		muted = value;
-	}
-
-	@Override
-	public float getVolume() {
-		return this.volume;
-	}
-
-	@Override
-	public void setVolume(float value) {
-		this.volume = value;
+	public void setCachedVolume(float value) {
+		stream.setCachedVolume(value);
 
 	}
 
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioMuteControl.java	Wed Jan 21 12:13:43 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/* PulseAudioMuteControl.java
-   Copyright (C) 2008 Red Hat, Inc.
-
-This file is part of IcedTea.
-
-IcedTea is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License as published by
-the Free Software Foundation, version 2.
-
-IcedTea is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with IcedTea; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version.
- */
-
-package org.classpath.icedtea.pulseaudio;
-
-import javax.sound.sampled.BooleanControl;
-
-final class PulseAudioMuteControl extends BooleanControl {
-
-	private PulseAudioVolumeControl volumeControl;
-	private PulseAudioPlaybackLine line;
-
-	protected PulseAudioMuteControl(PulseAudioPlaybackLine line,
-			PulseAudioVolumeControl volumeControl) {
-		super(BooleanControl.Type.MUTE, false, "Volume muted", "Volume on");
-		this.volumeControl = volumeControl;
-		this.line = line;
-	}
-
-	public synchronized void setValue(boolean value) {
-		if (!line.isOpen()) {
-			return;
-		}
-
-		if (value == true) {
-			line.setMuted(true);
-			volumeControl.setStreamVolume(0);
-		} else {
-			line.setMuted(false);
-			float newValue = volumeControl.getValue();
-			volumeControl.setStreamVolume(newValue);
-		}
-	}
-
-	public synchronized boolean getValue() {
-		return line.isMuted();
-	}
-
-}
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPlaybackLine.java	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPlaybackLine.java	Wed Jan 21 17:17:47 2009 -0500
@@ -37,18 +37,49 @@
 
 package org.classpath.icedtea.pulseaudio;
 
+/**
+ * Represents a Line that supports changing the volume
+ */
 interface PulseAudioPlaybackLine {
 
-	byte[] native_setVolume(float value);
-
-	boolean isMuted();
+	/**
+	 * Set the volume of the Line (ie, sink input, source, or sink)
+	 * 
+	 * @return an Operation object which can be used to check if the operation
+	 *         has completed
+	 */
+	byte[] native_set_volume(float value);
 
-	void setMuted(boolean mute);
+	/**
+	 * 
+	 * Update the volume information of a Line (sink input, source or sink)
+	 * 
+	 * @return an Operation object which can be used to check if the operation
+	 *         has been completed
+	 */
+	byte[] native_update_volume();
+	
+	
+	/**
+	 * Gets the cached volume. To get the current volume, call
+	 * native_update_volume, and then call this method to get the updated
+	 * volume.
+	 * 
+	 * @return the cached volume of the Line
+	 */
+	float getCachedVolume();
 
-	float getVolume();
+	/**
+	 * Set the cached value of a line
+	 * 
+	 */
+	void setCachedVolume(float volume);
 
-	void setVolume(float volume);
-
+	/**
+	 * Check if a line is open
+	 * 
+	 * @return <code>true</code> if line is open
+	 */
 	boolean isOpen();
 
 }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioPort.java	Wed Jan 21 17:17:47 2009 -0500
@@ -57,10 +57,8 @@
 
 	private EventLoop eventLoop;
 
-	private float volume;
-	private boolean muted;
+	private float cachedVolume;
 
-	private PulseAudioMuteControl muteControl;
 	private PulseAudioVolumeControl volumeControl;
 
 	static {
@@ -76,72 +74,67 @@
 
 		volumeControl = new PulseAudioVolumeControl(this, eventLoop);
 		controls.add(volumeControl);
-		muteControl = new PulseAudioMuteControl(this, volumeControl);
-		controls.add(muteControl);
 
 		/*
 		 * unlike other lines, Ports must either be open or close
 		 * 
 		 * close = no sound. open = sound
-		 * 
 		 */
 		open();
 
 		// System.out.println("Opened Target Port " + name);
 	}
 
-	
 	// FIXME why public
 	@Override
-	public abstract byte[] native_setVolume(float newValue);
+	public abstract byte[] native_set_volume(float newValue);
 
+	/**
+	 * 
+	 * @see {@link update_channels_and_volume}
+	 */
 	// FIXME why public
-	public abstract byte[] native_updateVolumeInfo();
+	public abstract byte[] native_update_volume();
 
 	@Override
-	public boolean isMuted() {
-		return muted;
+	public float getCachedVolume() {
+		return this.cachedVolume;
 	}
 
 	@Override
-	public void setMuted(boolean value) {
-		muted = value;
-	}
-
-	@Override
-	public float getVolume() {
-
-		// FIXME need to query system for volume
-		return this.volume;
-	}
-
-	@Override
-	public void setVolume(float value) {
-		this.volume = value;
+	public void setCachedVolume(float value) {
+		this.cachedVolume = value;
 
 	}
 
-	// FIXME
-	public synchronized void updateVolumeInfo() {
+	private void updateVolumeInfo() {
 		Operation op;
 		synchronized (eventLoop.threadLock) {
-			op = new Operation(native_updateVolumeInfo());
+			op = new Operation(native_update_volume());
 		}
 
 		op.waitForCompletion();
 		op.releaseReference();
 	}
 
-	// FIXME
-	public void update_channels_and_volume(int channels, float volume) {
+	/**
+	 * Callback used by JNI when native_update_volume completes
+	 * 
+	 * @param channels
+	 *            the number of channels
+	 * @param cachedVolume
+	 *            the new volume
+	 */
+	@SuppressWarnings("unused")
+	void update_channels_and_volume(int channels, float volume) {
 		this.channels = channels;
-		this.volume = volume;
+		this.cachedVolume = volume;
 	}
 
 	@Override
 	public void close() {
 
-		native_setVolume((float) 0);
+		native_set_volume((float) 0);
 		isOpen = false;
 		fireLineEvent(new LineEvent(this, LineEvent.Type.CLOSE,
 				AudioSystem.NOT_SPECIFIED));
@@ -155,7 +148,7 @@
 		if (isOpen) {
 			return;
 		}
-		native_setVolume(volume);
+		native_set_volume(cachedVolume);
 		isOpen = true;
 		fireLineEvent(new LineEvent(this, LineEvent.Type.OPEN,
 				AudioSystem.NOT_SPECIFIED));
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLine.java	Wed Jan 21 17:17:47 2009 -0500
@@ -51,10 +51,7 @@
 public final class PulseAudioSourceDataLine extends PulseAudioDataLine
 		implements SourceDataLine, PulseAudioPlaybackLine {
 
-	private PulseAudioMuteControl muteControl;
 	private PulseAudioVolumeControl volumeControl;
-	private boolean muted;
-	private float volume;
 
 	public static final String DEFAULT_SOURCEDATALINE_NAME = "Audio Stream";
 
@@ -67,7 +64,6 @@
 		this.lineListeners = new ArrayList<LineListener>();
 		this.defaultFormat = defaultFormat;
 		this.currentFormat = defaultFormat;
-		this.volume = PulseAudioVolumeControl.MAX_VOLUME;
 		this.streamName = DEFAULT_SOURCEDATALINE_NAME;
 
 	}
@@ -80,8 +76,6 @@
 
 		volumeControl = new PulseAudioVolumeControl(this, eventLoop);
 		controls.add(volumeControl);
-		muteControl = new PulseAudioMuteControl(this, volumeControl);
-		controls.add(muteControl);
 
 		PulseAudioMixer parentMixer = PulseAudioMixer.getInstance();
 		parentMixer.addSourceLine(this);
@@ -97,32 +91,26 @@
 	}
 
 	// FIXME
-	public byte[] native_setVolume(float value) {
+	public byte[] native_set_volume(float value) {
 		synchronized (eventLoop.threadLock) {
-			return stream.native_setVolume(value);
+			return stream.native_set_volume(value);
 		}
 	}
 
-	// FIXME
+	public byte[] native_update_volume() {
+		synchronized (eventLoop.threadLock) {
+			return stream.native_update_volume();
+		}
+	}
+	
 	@Override
-	public boolean isMuted() {
-		return muted;
+	public float getCachedVolume() {
+		return stream.getCachedVolume();
 	}
 
 	@Override
-	public void setMuted(boolean value) {
-		muted = value;
-	}
-
-	@Override
-	public float getVolume() {
-		return this.volume;
-	}
-
-	@Override
-	synchronized public void setVolume(float value) {
-		this.volume = value;
-
+	synchronized public void setCachedVolume(float value) {
+		stream.setCachedVolume(value);
 	}
 
 	@Override
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioSourcePort.java	Wed Jan 21 17:17:47 2009 -0500
@@ -82,10 +82,10 @@
 	}
 
 	// FIXME
-	public native byte[] native_setVolume(float newValue);
+	public native byte[] native_set_volume(float newValue);
 
 	// FIXME
-	public synchronized native byte[] native_updateVolumeInfo();
+	public native byte[] native_update_volume();
 
 	@Override
 	public Line.Info getLineInfo() {
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioTargetPort.java	Wed Jan 21 17:17:47 2009 -0500
@@ -49,7 +49,6 @@
 	}
 
 	PulseAudioTargetPort(String name) {
-
 		super(name);
 	}
 
@@ -75,12 +74,11 @@
 		super.close();
 	}
 
-	
 	// FIXME
-	public native byte[] native_setVolume(float newValue);
+	public native byte[] native_set_volume(float newValue);
 
 	// FIXME
-	public synchronized native byte[] native_updateVolumeInfo();
+	public native byte[] native_update_volume();
 
 	@Override
 	public Line.Info getLineInfo() {
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioVolumeControl.java	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioVolumeControl.java	Wed Jan 21 17:17:47 2009 -0500
@@ -46,8 +46,12 @@
 
 	protected PulseAudioVolumeControl(PulseAudioPlaybackLine line,
 			EventLoop eventLoop) {
+
+		/*
+		 * the initial volume is ignored by pulseaudio.
+		 */
 		super(FloatControl.Type.VOLUME, MIN_VOLUME, MAX_VOLUME, 1, -1, line
-				.getVolume(), "pulseaudio units", "Volume Off",
+				.getCachedVolume(), "pulseaudio units", "Volume Off",
 				"Default Volume", "Full Volume");
 		this.line = line;
 		this.eventLoop = eventLoop;
@@ -66,17 +70,15 @@
 			return;
 		}
 
-		if (!line.isMuted()) {
-			setStreamVolume(newValue);
-		}
+		setStreamVolume(newValue);
 
-		line.setVolume(newValue);
+		line.setCachedVolume(newValue);
 	}
 
 	protected synchronized void setStreamVolume(float newValue) {
 		Operation op;
 		synchronized (eventLoop.threadLock) {
-			op = new Operation(line.native_setVolume(newValue));
+			op = new Operation(line.native_set_volume(newValue));
 		}
 
 		op.waitForCompletion();
@@ -85,7 +87,15 @@
 	}
 
 	public synchronized float getValue() {
-		return line.getVolume();
+		Operation op;
+		synchronized (eventLoop.threadLock) {
+			op = new Operation(line.native_update_volume());
+		}
+
+		op.waitForCompletion();
+		op.releaseReference();
+
+		return line.getCachedVolume();
 	}
 
 }
--- a/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/src/java/org/classpath/icedtea/pulseaudio/Stream.java	Wed Jan 21 17:17:47 2009 -0500
@@ -115,6 +115,7 @@
 	}
 
 	private Format format;
+	private float cachedVolume;
 
 	private List<StateListener> stateListeners;
 	private List<WriteListener> writeListeners;
@@ -222,7 +223,9 @@
 
 	private native byte[] native_pa_stream_update_sample_rate(int rate);
 
-	native byte[] native_setVolume(float newValue);
+	native byte[] native_set_volume(float newValue);
+
+	native byte[] native_update_volume();
 
 	/*
 	 * pa_operation pa_stream_proplist_update (pa_streams, pa_update_mode_t
@@ -777,4 +780,16 @@
 		native_pa_stream_unref();
 	}
 
+	float getCachedVolume() {
+		return this.cachedVolume;
+	}
+
+	void setCachedVolume(float volume) {
+		this.cachedVolume = volume;
+	}
+
+	void update_channels_and_volume(int channels, float volume) {
+		this.cachedVolume = volume;
+	}
+
 }
--- a/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_EventLoop.c	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_EventLoop.c	Wed Jan 21 17:17:47 2009 -0500
@@ -295,69 +295,3 @@
 
 }
 
-static void sink_input_volume_change_complete(pa_context* contest, int success,
-		void* userdata) {
-	// userdata is the pointer to the int containing the new volume 
-
-	assert(userdata);
-	free(userdata);
-	assert(success);
-
-}
-
-static void sink_input_change_volume(pa_context* c,
-		const pa_sink_input_info* i, int eol, void* userdata) {
-	assert(c);
-
-	if (eol) {
-		return;
-	}
-
-	assert(i);
-	assert(userdata);
-	int volume = *((int*)userdata);
-
-	int j = 0;
-	//	printf("changing sink input volume\n");
-	pa_cvolume* new_volume = malloc(sizeof(pa_cvolume));
-
-	//	printf("allocated memory\n");
-	new_volume->channels = i->volume.channels;
-	//	printf("set the number of channels\n");
-	for (j = 0; j < new_volume->channels; j++) {
-		new_volume->values[j] = volume;
-	}
-
-	//	printf("calling set_sick_input_volume\n");
-	pa_operation* o = pa_context_set_sink_input_volume(c, i->index, new_volume,
-			sink_input_volume_change_complete, new_volume);
-	if (o != NULL) {
-		pa_operation_unref(o);
-	}
-
-	//	printf("done setup for changing volume\n");
-}
-
-
-/*
- * Class:     org_classpath_icedtea_pulseaudio_EventLoop
- * Method:    native_set_sink_volume
- * Signature: ([BI)V
- */
-JNIEXPORT void JNICALL Java_org_classpath_icedtea_pulseaudio_EventLoop_native_1set_1sink_1volume
-(JNIEnv* env, jobject obj, jbyteArray streamPointer, jint volume) {
-
-	pa_stream* stream = (pa_stream*) convertJavaPointerToNative(env, streamPointer);
-	assert(stream);
-	pa_context* context = (pa_context*) getJavaPointer(env, obj, "contextPointer");
-	assert(context);
-
-	int* new_volume = malloc(sizeof(int));
-	*new_volume = volume;
-
-	int stream_id = pa_stream_get_index(stream);
-	pa_operation* o = pa_context_get_sink_input_info(context, stream_id,sink_input_change_volume, new_volume);
-	pa_operation_unref(o);
-	return;
-}
-
--- a/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_PulseAudioSourcePort.c	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_PulseAudioSourcePort.c	Wed Jan 21 17:17:47 2009 -0500
@@ -22,7 +22,7 @@
 	assert(pulse_thread_env);
 	
 	if (eol == 0) {
-		// printf("%s\n", i->name); 
+		// printf("%s\n", i->name);
 		jobject obj = (jobject) userdata;
 		assert(obj);
 		jclass cls = (*pulse_thread_env)->GetObjectClass(pulse_thread_env, obj);
@@ -39,10 +39,10 @@
 
 /*
  * Class:     org_classpath_icedtea_pulseaudio_PulseAudioSourcePort
- * Method:    native_updateVolumeInfo
+ * Method:    native_update_volume
  * Signature: ()[B
  */
-JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioSourcePort_native_1updateVolumeInfo
+JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioSourcePort_native_1update_1volume
 (JNIEnv *env, jobject obj) {
 	jclass cls = (*env)->GetObjectClass(env, obj);
 	assert(cls);
@@ -65,10 +65,10 @@
 
 /*
  * Class:     org_classpath_icedtea_pulseaudio_PulseAudioSourcePort
- * Method:    native_setVolume
+ * Method:    native_set_volume
  * Signature: (F)[B
  */
-JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioSourcePort_native_1setVolume
+JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioSourcePort_native_1set_1volume
 (JNIEnv *env, jobject obj, jfloat value) {
 	jclass cls = (*env)->GetObjectClass(env, obj);
 	assert(cls);
--- a/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_PulseAudioTargetPort.c	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_PulseAudioTargetPort.c	Wed Jan 21 17:17:47 2009 -0500
@@ -11,17 +11,17 @@
 
 extern JNIEnv* pulse_thread_env;
 
-void sink_callback(pa_context *context, int success, void *userdata) {
+static void sink_callback(pa_context *context, int success, void *userdata) {
 	notifyWaitingOperations(pulse_thread_env);
 }
 
-void get_sink_volume_callback(pa_context *context, const pa_sink_info *i,
+static void get_sink_volume_callback(pa_context *context, const pa_sink_info *i,
 		int eol, void *userdata) {
 	assert(context);
 	assert(pulse_thread_env);
 
 	if (eol == 0) {
-		// printf("%s\n", i->name); 
+		// printf("%s\n", i->name);
 		jobject obj = (jobject) userdata;
 		assert(obj);
 		jclass cls = (*pulse_thread_env)->GetObjectClass(pulse_thread_env, obj);
@@ -40,10 +40,10 @@
 
 /*
  * Class:     org_classpath_icedtea_pulseaudio_PulseAudioTargetPort
- * Method:    native_updateVolumeInfo
+ * Method:    native_update_volume
  * Signature: ()[B
  */
-JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioTargetPort_native_1updateVolumeInfo
+JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioTargetPort_native_1update_1volume
 (JNIEnv *env, jobject obj) {
 	jclass cls = (*env)->GetObjectClass(env, obj);
 	assert(cls);
@@ -72,10 +72,10 @@
 
 /*
  * Class:     org_classpath_icedtea_pulseaudio_PulseAudioTargetPort
- * Method:    native_setVolume
+ * Method:    native_set_volume
  * Signature: (F)[B
  */
-JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioTargetPort_native_1setVolume
+JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_PulseAudioTargetPort_native_1set_1volume
 (JNIEnv *env, jobject obj, jfloat value) {
 	jclass cls = (*env)->GetObjectClass(env, obj);
 	assert(cls);
--- a/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/src/native/org_classpath_icedtea_pulseaudio_Stream.c	Wed Jan 21 17:17:47 2009 -0500
@@ -5,6 +5,7 @@
 #include <string.h>
 
 #define STREAM_POINTER "streamPointer"
+#define CONTEXT_POINTER "contextPointer"
 
 typedef struct java_context {
 	JNIEnv* env;
@@ -297,10 +298,10 @@
 	setJavaPointer(env, obj, "streamPointer", stream);
 
 	/*
-	 * 
-	 * The stream has been created; now setup the callbacks 
+	 *
+	 * The stream has been created; now setup the callbacks
 	 * so we can do somethig about them
-	 * 
+	 *
 	 */
 
 	pa_stream_set_state_callback (stream, stream_state_callback, j_context);
@@ -966,12 +967,12 @@
 
 /*
  * Class:     org_classpath_icedtea_pulseaudio_Stream
- * Method:    native_setVolume
+ * Method:    native_set_volume
  * Signature: (F)[B
  */
-JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1setVolume
+JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1set_1volume
 (JNIEnv *env, jobject obj, jfloat new_volume) {
-	
+
 	pa_stream *stream = getJavaPointer(env, obj, STREAM_POINTER);
 	assert(stream);
 	pa_context *context = pa_stream_get_context(stream);
@@ -988,6 +989,55 @@
 
 }
 
+
+static void get_sink_input_volume_callback(pa_context *context, const pa_sink_input_info *i,
+		int eol, void *userdata) {
+
+	JNIEnv* env = pulse_thread_env;
+
+	assert(context);
+	assert(env);
+	jobject obj = (jobject) userdata;
+	assert(obj);
+
+	if (eol == 0) {
+		jclass cls = (*pulse_thread_env)->GetObjectClass(pulse_thread_env, obj);
+		assert(cls);
+		jmethodID mid1 = (*pulse_thread_env)->GetMethodID(pulse_thread_env, cls,
+				"update_channels_and_volume", "(IF)V");
+		assert(mid1);
+		(*pulse_thread_env)->CallVoidMethod(pulse_thread_env, obj, mid1,
+				(int) (i->volume).channels, (float) (i->volume).values[0]) ;
+	} else {
+		notifyWaitingOperations(pulse_thread_env);
+		(*env)->DeleteGlobalRef(env, obj);
+	}
+}
+
+/*
+ * Class:     org_classpath_icedtea_pulseaudio_Stream
+ * Method:    native_update_volume
+ * Signature: ()[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1update_1volume
+(JNIEnv* env, jobject obj) {
+
+	pa_stream* stream = getJavaPointer(env, obj, STREAM_POINTER);
+	assert(stream);
+
+	int sink_input_index = pa_stream_get_index(stream);
+
+	pa_context* context = pa_stream_get_context(stream);
+	assert(context);
+
+	obj = (*env)->NewGlobalRef(env, obj);
+	pa_operation *o = pa_context_get_sink_input_info(context, sink_input_index , get_sink_input_volume_callback, obj);
+	assert(o);
+	return convertNativePointerToJava(env, o);
+
+
+}
+
 JNIEXPORT jint JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_bytesInBuffer(JNIEnv *env, jobject obj) {
 	pa_stream *stream = getJavaPointer(env, obj, STREAM_POINTER);
 	assert(stream);
@@ -1000,7 +1050,7 @@
 JNIEXPORT jbyteArray JNICALL Java_org_classpath_icedtea_pulseaudio_Stream_native_1pa_1stream_1updateTimingInfo(JNIEnv* env, jobject obj) {
 	pa_stream *stream = getJavaPointer(env, obj, STREAM_POINTER);
 	assert(stream);
-	pa_operation* o = pa_stream_update_timing_info(stream, update_timing_info_callback, NULL); 
+	pa_operation* o = pa_stream_update_timing_info(stream, update_timing_info_callback, NULL);
 	assert(o);
 	return convertNativePointerToJava(env, o);
 
--- a/pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioClipTest.java	Wed Jan 21 17:17:47 2009 -0500
@@ -447,7 +447,7 @@
 
 		Control[] controls = clip.getControls();
 		Assert.assertNotNull(controls);
-		Assert.assertTrue(controls.length >= 2);
+		Assert.assertTrue(controls.length >= 1);
 		for (Control control : controls) {
 			Assert.assertNotNull(control);
 		}
--- a/pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineRawTest.java	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineRawTest.java	Wed Jan 21 17:17:47 2009 -0500
@@ -43,7 +43,6 @@
 import javax.sound.sampled.AudioFormat;
 import javax.sound.sampled.AudioInputStream;
 import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.BooleanControl;
 import javax.sound.sampled.DataLine;
 import javax.sound.sampled.FloatControl;
 import javax.sound.sampled.Line;
@@ -195,7 +194,7 @@
 	}
 
 	@Test
-	public void testVolumeAndMute() throws Exception {
+	public void testVolume() throws Exception {
 
 		Mixer selectedMixer = mixer;
 		SourceDataLine line = (SourceDataLine) selectedMixer
@@ -211,14 +210,9 @@
 		line.start();
 		PulseAudioVolumeControl volume = (PulseAudioVolumeControl) line
 				.getControl(FloatControl.Type.VOLUME);
-		PulseAudioMuteControl mute = (PulseAudioMuteControl) line
-				.getControl(BooleanControl.Type.MUTE);
 
-		mute.setValue(true);
 		volume.setValue(PulseAudioVolumeControl.MAX_VOLUME);
 
-		mute.setValue(false);
-
 		byte[] abData = new byte[1000];
 		int bytesRead = 0;
 
--- a/pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourceDataLineTest.java	Wed Jan 21 17:17:47 2009 -0500
@@ -287,6 +287,7 @@
 		sourceDataLine.write(buffer, 1, buffer.length);
 	}
 
+	// FIXME
 	@Test
 	public void testWriteWithoutStart() throws UnsupportedAudioFileException,
 			IOException, LineUnavailableException, InterruptedException {
@@ -805,13 +806,11 @@
 		sourceDataLine.open();
 		Assert.assertTrue(sourceDataLine
 				.isControlSupported(FloatControl.Type.VOLUME));
-		Assert.assertTrue(sourceDataLine
-				.isControlSupported(BooleanControl.Type.MUTE));
 		sourceDataLine.close();
 	}
 
 	@Test
-	public void testVolumeAndMute() throws Exception {
+	public void testVolume() throws Exception {
 
 		Mixer selectedMixer = mixer;
 		sourceDataLine = (SourceDataLine) selectedMixer.getLine(new Line.Info(
@@ -827,14 +826,9 @@
 		sourceDataLine.start();
 		FloatControl volume = (FloatControl) sourceDataLine
 				.getControl(FloatControl.Type.VOLUME);
-		BooleanControl mute = (BooleanControl) sourceDataLine
-				.getControl(BooleanControl.Type.MUTE);
 
-		mute.setValue(true);
 		volume.setValue(volume.getMaximum());
 
-		mute.setValue(false);
-
 		byte[] abData = new byte[1000];
 		int bytesRead = 0;
 
--- a/pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourcePortTest.java	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioSourcePortTest.java	Wed Jan 21 17:17:47 2009 -0500
@@ -40,7 +40,6 @@
 import static org.junit.Assert.assertNotNull;
 
 import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.BooleanControl;
 import javax.sound.sampled.FloatControl;
 import javax.sound.sampled.Line;
 import javax.sound.sampled.LineUnavailableException;
@@ -103,10 +102,6 @@
 				FloatControl volumeControl = (FloatControl) port
 						.getControl(FloatControl.Type.VOLUME);
 				volumeControl.setValue(60000);
-				BooleanControl muteControl = (BooleanControl) port
-						.getControl(BooleanControl.Type.MUTE);
-				muteControl.setValue(true);
-				muteControl.setValue(false);
 				port.close();
 			}
 		}
--- a/pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetPortTest.java	Wed Jan 21 12:13:43 2009 -0500
+++ b/pulseaudio/unittests/org/classpath/icedtea/pulseaudio/PulseAudioTargetPortTest.java	Wed Jan 21 17:17:47 2009 -0500
@@ -40,7 +40,6 @@
 import static org.junit.Assert.assertNotNull;
 
 import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.BooleanControl;
 import javax.sound.sampled.FloatControl;
 import javax.sound.sampled.Line;
 import javax.sound.sampled.LineUnavailableException;
@@ -103,10 +102,6 @@
 				FloatControl volumeControl = (FloatControl) port
 						.getControl(FloatControl.Type.VOLUME);
 				volumeControl.setValue(60000);
-				BooleanControl muteControl = (BooleanControl) port
-						.getControl(BooleanControl.Type.MUTE);
-				muteControl.setValue(true);
-				muteControl.setValue(false);
 				port.close();
 			}
 		}