diff options
author | Damian Minkov <damencho@jitsi.org> | 2010-12-17 14:21:32 +0000 |
---|---|---|
committer | Damian Minkov <damencho@jitsi.org> | 2010-12-17 14:21:32 +0000 |
commit | 5fcaeed371bcf2c2289976f0de40721e300529d4 (patch) | |
tree | e9de4a725eb1fefc5fca86f54938d697caa93e3d /src/net/java/sip/communicator | |
parent | 37826ceb132b911621d30cf498be71605a5a8063 (diff) | |
download | jitsi-5fcaeed371bcf2c2289976f0de40721e300529d4.zip jitsi-5fcaeed371bcf2c2289976f0de40721e300529d4.tar.gz jitsi-5fcaeed371bcf2c2289976f0de40721e300529d4.tar.bz2 |
Introduce possibility to control capture volume from the GUI through media service. Add capture and playback volume buttons to fullscreen call dialog.
Diffstat (limited to 'src/net/java/sip/communicator')
17 files changed, 477 insertions, 132 deletions
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/AbstractCallToggleButton.java b/src/net/java/sip/communicator/impl/gui/main/call/AbstractCallToggleButton.java index 9863c21..f15e38c 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/AbstractCallToggleButton.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/AbstractCallToggleButton.java @@ -53,6 +53,13 @@ public abstract class AbstractCallToggleButton protected ImageID iconImageID; /** + * Whether we should spawn action when clicking the button in new thread. + * Volume control buttons use this abstract button for its fullscreen view + * and don't need the new thread. Default is true, create new thread. + */ + private boolean spawnActionInNewThread = true; + + /** * Initializes a new <tt>AbstractCallToggleButton</tt> instance which is to * control a toggle action for a specific <tt>Call</tt>. * @@ -105,6 +112,16 @@ public abstract class AbstractCallToggleButton } /** + * Changes behaviour, whether we should start new thread for executing + * actions, buttonPressed(). + * @param spawnActionInNewThread + */ + public void setSpawnActionInNewThread(boolean spawnActionInNewThread) + { + this.spawnActionInNewThread = spawnActionInNewThread; + } + + /** * The button model of this call toggle button. */ private class CallToggleButtonModel @@ -125,6 +142,12 @@ public abstract class AbstractCallToggleButton public synchronized void actionPerformed(ActionEvent event) { + if(!spawnActionInNewThread) + { + buttonPressed(); + return; + } + if (runner == null) { runner = new Thread(this, LocalVideoButton.class.getName()); diff --git a/src/net/java/sip/communicator/impl/gui/main/call/AbstractVolumeControlButton.java b/src/net/java/sip/communicator/impl/gui/main/call/AbstractVolumeControlButton.java new file mode 100644 index 0000000..15bd738 --- /dev/null +++ b/src/net/java/sip/communicator/impl/gui/main/call/AbstractVolumeControlButton.java @@ -0,0 +1,131 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.impl.gui.main.call; + +import net.java.sip.communicator.service.neomedia.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.resources.*; + +import javax.swing.*; +import javax.swing.event.*; +import java.awt.*; +import java.awt.event.*; + +/** + * The <tt>VolumeControlButton</tt> is the button shown in the call window, + * which allows to adjust the volume of your call. + * + * @author Yana Stamcheva + */ +public abstract class AbstractVolumeControlButton + extends AbstractCallToggleButton +{ + /** + * The multiplier would just convert the float volume value coming from + * the service to the int value needed for the volume control slider + * component. + */ + private static final int MULTIPLIER = 100; + + /** + * Creates an instance of <tt>VolumeControlButton</tt>. + */ + public AbstractVolumeControlButton( + Call call, + final boolean fullScreen, + boolean selected, + ImageID iconImageID, + String toolTipTextKey) + { + super(call, fullScreen, selected, iconImageID, toolTipTextKey); + + // we don't want new thread when button is pressed + setSpawnActionInNewThread(false); + + // Loads the skin of this button. + loadSkin(); + + final JSlider volumeSlider + = new JSlider(JSlider.VERTICAL, 0, 100, 50); + + volumeSlider.setPreferredSize(new Dimension(20, 100)); + + final VolumeControl volumeControl = getVolumeControl(); + + // Sets the minimum, maximum and default volume values for the volume + // slider. + if (volumeControl != null) + { + volumeSlider.setMinimum( + (int) (volumeControl.getMinValue()*MULTIPLIER)); + volumeSlider.setMaximum( + (int) (volumeControl.getMaxValue()*MULTIPLIER)); + + volumeSlider.setValue( + (int) (volumeControl.getVolume()*MULTIPLIER)); + } + + // Adds a change listener to the slider in order to correctly set + // the volume through the VolumeControl service, on user change. + volumeSlider.addChangeListener(new ChangeListener() + { + public void stateChanged(ChangeEvent e) + { + JSlider source = (JSlider) e.getSource(); + int volume = source.getValue(); + + // Set the volume to the volume control. + volumeControl.setVolume((float) volume/MULTIPLIER); + } + }); + + // Creates the menu that would contain the volume control component. + final JPopupMenu sliderMenu = new JPopupMenu(); + sliderMenu.setInvoker(this); + sliderMenu.add(volumeSlider); + + this.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent arg0) + { + Point location = new Point(getX(), getY() + getHeight()); + + SwingUtilities.convertPointToScreen(location, + AbstractVolumeControlButton.this.getParent()); + + if(fullScreen) + location.setLocation(location.getX(), + location.getY() + - sliderMenu.getPreferredSize().getHeight() + - getHeight()); + + if (volumeControl != null) + volumeSlider.setValue( + (int) (volumeControl.getVolume()*MULTIPLIER)); + + sliderMenu.setLocation(location); + + sliderMenu.setVisible(!sliderMenu.isVisible()); + } + }); + } + + /** + * + */ + public void buttonPressed() + { + // just a # bypass the toggle functionality as we don't use it + setSelected(!isSelected()); + } + + /** + * Volume control used by the button. + * @return volume control used by the button. + */ + public abstract VolumeControl getVolumeControl(); +}
\ No newline at end of file diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallDialog.java b/src/net/java/sip/communicator/impl/gui/main/call/CallDialog.java index b826452..f3261c0 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/CallDialog.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/CallDialog.java @@ -292,6 +292,7 @@ public class CallDialog settingsPanel.add(conferenceButton);
settingsPanel.add(holdButton);
settingsPanel.add(muteButton);
+ settingsPanel.add(volumeControlButton);
settingsPanel.add(recordButton);
if (!isLastConference)
@@ -306,8 +307,6 @@ public class CallDialog addOneToOneSpecificComponents();
}
- settingsPanel.add(volumeControlButton);
-
buttonsPanel.add(settingsPanel, BorderLayout.WEST);
buttonsPanel.add(hangupButton, BorderLayout.EAST);
@@ -1089,4 +1088,14 @@ public class CallDialog settingsPanel.repaint();
}
}
+
+ /**
+ * Checks whether recording is currently enabled or not, state retrieved
+ * from call record button state.
+ * @return
+ */
+ public boolean isRecordingStarted()
+ {
+ return recordButton.isSelected();
+ }
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/MuteButton.java b/src/net/java/sip/communicator/impl/gui/main/call/MuteButton.java index d6f4111..ca967c7 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/MuteButton.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/MuteButton.java @@ -6,7 +6,10 @@ */ package net.java.sip.communicator.impl.gui.main.call; +import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.utils.*; +import net.java.sip.communicator.service.neomedia.*; +import net.java.sip.communicator.service.neomedia.event.*; import net.java.sip.communicator.service.protocol.*; /** @@ -18,14 +21,24 @@ import net.java.sip.communicator.service.protocol.*; * @author Dmitri Melnikov */ public class MuteButton - extends AbstractCallToggleButton + extends AbstractVolumeControlButton + implements VolumeChangeListener, + Runnable { /** - * The serialization-related version of the <tt>MuteButton</tt> class - * explicitly defined to silence a related warning (e.g. in Eclipse IDE) - * since the <tt>MuteButton</tt> class does not add instance fields. + * Mutes the call in other thread. */ - private static final long serialVersionUID = 0L; + private Thread muteRunner; + + /** + * Our volume control. + */ + private VolumeControl volumeControl; + + /** + * Current mute state. + */ + private boolean mute = false; /** * Initializes a new <tt>MuteButton</tt> instance which is to mute the audio @@ -52,18 +65,72 @@ public class MuteButton */ public MuteButton(Call call, boolean fullScreen, boolean selected) { - super( - call, - fullScreen, - selected, - ImageLoader.MUTE_BUTTON, + super(call, fullScreen, selected, ImageLoader.MUTE_BUTTON, "service.gui.MUTE_BUTTON_TOOL_TIP"); + + this.mute = selected; + } + + /** + * Volume control used by the button. + * + * @return volume control used by the button. + */ + @Override + public VolumeControl getVolumeControl() + { + if(volumeControl == null) + { + volumeControl = GuiActivator.getMediaService() + .getInputVolumeControl(); + + volumeControl.addVolumeChangeListener(this); + } + + return volumeControl; } /** * Mutes or unmutes the associated <tt>Call</tt> upon clicking this button. */ - public void buttonPressed() + public void toggleMute() + { + if (muteRunner == null) + { + muteRunner = new Thread(this, getToolTipText()); + muteRunner.setDaemon(true); + + setEnabled(false); + muteRunner.start(); + } + } + + /** + * Toggles state on call in different thread. + */ + public void run() + { + try + { + doRun(); + } + finally + { + synchronized (this) + { + if (Thread.currentThread().equals(muteRunner)) + { + muteRunner = null; + setEnabled(true); + } + } + } + } + + /** + * Do the actual muting/unmuting. + */ + private void doRun() { if (call != null) { @@ -71,7 +138,21 @@ public class MuteButton = call.getProtocolProvider().getOperationSet( OperationSetBasicTelephony.class); - telephony.setMute(call, isSelected()); + mute = !mute; + telephony.setMute(call, mute); } } + + /** + * Event fired when volume has changed. + * + * @param volumeChangeEvent the volume change event. + */ + public void volumeChange(VolumeChangeEvent volumeChangeEvent) + { + if(volumeChangeEvent.getLevel() == 0) + toggleMute(); + else if(mute) + toggleMute(); + } } diff --git a/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPanel.java index e327714..5ec36d4 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPanel.java @@ -267,6 +267,8 @@ public class OneToOneCallPanel new MuteButton(call, true, callPeer.isMute()), + new VolumeControlButton(true), + new RecordButton(call, true, callDialog.isRecordingStarted()), CallPeerRendererUtils.createExitFullScreenButton(this) }; diff --git a/src/net/java/sip/communicator/impl/gui/main/call/VolumeControlButton.java b/src/net/java/sip/communicator/impl/gui/main/call/VolumeControlButton.java index f5fad5e..67ec262 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/VolumeControlButton.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/VolumeControlButton.java @@ -6,111 +6,38 @@ */ package net.java.sip.communicator.impl.gui.main.call; -import java.awt.*; -import java.awt.event.*; - -import javax.swing.*; -import javax.swing.event.*; - import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.service.neomedia.*; -import net.java.sip.communicator.util.skin.*; -import net.java.sip.communicator.util.swing.*; /** * The <tt>VolumeControlButton</tt> is the button shown in the call window, - * which allows to adjust the volume of your call. + * which allows to adjust the playback volume of your call. * * @author Yana Stamcheva */ public class VolumeControlButton - extends SIPCommButton - implements Skinnable + extends AbstractVolumeControlButton { - /** - * The multiplier would just convert the float volume value coming from - * the service to the int value needed for the volume control slider - * component. - */ - private static final int MULTIPLIER = 100; - - /** - * Creates an instance of <tt>VolumeControlButton</tt>. - */ public VolumeControlButton() { - // Loads the skin of this button. - loadSkin(); - - setToolTipText(GuiActivator.getResources().getI18NString( - "service.gui.VOLUME_CONTROL_TOOL_TIP")); - - final JSlider volumeSlider - = new JSlider(JSlider.VERTICAL, 0, 100, 50); - - volumeSlider.setPreferredSize(new Dimension(20, 100)); - - final VolumeControl volumeControl - = GuiActivator.getMediaService().getVolumeControl(); - - // Sets the minimum, maximum and default volume values for the volume - // slider. - if (volumeControl != null) - { - volumeSlider.setMinimum( - (int) (volumeControl.getMinValue()*MULTIPLIER)); - volumeSlider.setMaximum( - (int) (volumeControl.getMaxValue()*MULTIPLIER)); - - volumeSlider.setValue( - (int) (volumeControl.getVolume()*MULTIPLIER)); - } - - // Adds a change listener to the slider in order to correctly set - // the volume through the VolumeControl service, on user change. - volumeSlider.addChangeListener(new ChangeListener() - { - public void stateChanged(ChangeEvent e) - { - JSlider source = (JSlider) e.getSource(); - int volume = source.getValue(); - - // Set the volume to the volume control. - volumeControl.setVolume((float) volume/MULTIPLIER); - } - }); - - // Creates the menu that would contain the volume control component. - final JPopupMenu sliderMenu = new JPopupMenu(); - sliderMenu.setInvoker(this); - sliderMenu.add(volumeSlider); - - this.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent arg0) - { - Point location = new Point(getX(), getY() + getHeight()); - - SwingUtilities.convertPointToScreen(location, - VolumeControlButton.this.getParent()); - - sliderMenu.setLocation(location); + this(false); + } - sliderMenu.setVisible(!sliderMenu.isVisible()); - } - }); + public VolumeControlButton(boolean fullScreen) + { + super(null, fullScreen, false, ImageLoader.VOLUME_CONTROL_BUTTON, + "service.gui.VOLUME_CONTROL_TOOL_TIP"); } /** - * Loads volume control button skin. + * Volume control used by the button. + * + * @return volume control used by the button. */ - public void loadSkin() + @Override + public VolumeControl getVolumeControl() { - this.setBackgroundImage(ImageLoader.getImage( - ImageLoader.CALL_SETTING_BUTTON_BG)); - - this.setIconImage(ImageLoader.getImage( - ImageLoader.VOLUME_CONTROL_BUTTON)); + return GuiActivator.getMediaService().getOutputVolumeControl(); } -}
\ No newline at end of file +} diff --git a/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf b/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf index f6bf8aa..7e6162f 100644 --- a/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf +++ b/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf @@ -30,6 +30,7 @@ Import-Package: org.osgi.framework, net.java.sip.communicator.service.shutdown, net.java.sip.communicator.service.systray, net.java.sip.communicator.service.neomedia, + net.java.sip.communicator.service.neomedia.event, net.java.sip.communicator.service.neomedia.device, net.java.sip.communicator.service.neomedia.format, net.java.sip.communicator.service.contactsource, diff --git a/src/net/java/sip/communicator/impl/neomedia/VolumeControlImpl.java b/src/net/java/sip/communicator/impl/neomedia/AbstractVolumeControl.java index 89bbc58..a03b50f 100644 --- a/src/net/java/sip/communicator/impl/neomedia/VolumeControlImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/AbstractVolumeControl.java @@ -16,15 +16,15 @@ import java.util.*; import java.util.List; /** - * Controls media service playback volume. If a volume level is set - * we change it on all current players, as we synchronize volume on all players. - * Implements interface exposed from media service, also implements - * the interface used in the Renderer part of JMF and merges the two + * Controls media service volume input or output. If a playback volume level + * is set we change it on all current players, as we synchronize volume + * on all players. Implements interface exposed from media service, also + * implements the interface used in the Renderer part of JMF and merges the two * functionalities to work as one. * * @author Damian Minkov */ -public class VolumeControlImpl +public abstract class AbstractVolumeControl implements VolumeControl, GainControl { @@ -33,7 +33,7 @@ public class VolumeControlImpl * its instances for logging output. */ private static final Logger logger - = Logger.getLogger(VolumeControlImpl.class); + = Logger.getLogger(AbstractVolumeControl.class); /** * The minimum volume level we can handle. @@ -73,7 +73,7 @@ public class VolumeControlImpl private boolean currentMuteState = false; /** - * Current playback level in db. + * Current level in db. */ private float db; @@ -86,27 +86,27 @@ public class VolumeControlImpl * Creates volume control instance and initialise initial level value * if stored in config service. */ - VolumeControlImpl() + AbstractVolumeControl() { // read initial level from config service if any - String initialPlaybackLevel = + String initialLevel = NeomediaActivator.getConfigurationService() - .getString(PLAYBACK_VOLUME_LEVEL_PROPERTY_NAME); + .getString(getStoreLevelPropertyName()); try { - if(initialPlaybackLevel != null) + if(initialLevel != null) { - currentVolumeLevel = Float.valueOf(initialPlaybackLevel); + currentVolumeLevel = Float.valueOf(initialLevel); initialVolumeLevel = currentVolumeLevel; if(logger.isDebugEnabled()) - logger.debug("Restore playback volume: " + logger.debug("Restore volume: " + currentVolumeLevel); } } catch(Throwable t) { - logger.warn("Error restoring playback volume", t); + logger.warn("Error restoring volume", t); } } @@ -213,7 +213,7 @@ public class VolumeControlImpl // save the level change, so we can restore it on next run NeomediaActivator.getConfigurationService().setProperty( - PLAYBACK_VOLUME_LEVEL_PROPERTY_NAME, + getStoreLevelPropertyName(), String.valueOf(currentVolumeLevel)); float f1 = value / initialVolumeLevel; @@ -227,9 +227,9 @@ public class VolumeControlImpl } /** - * Mutes current sound playback. + * Mutes current sound. * - * @param mute mutes/unmutes playback. + * @param mute mutes/unmutes. */ public void setMute(boolean mute) { @@ -244,9 +244,9 @@ public class VolumeControlImpl } /** - * Get mute state of sound playback. + * Get mute state of sound. * - * @return mute state of sound playback. + * @return mute state of sound. */ public boolean getMute() { @@ -404,4 +404,12 @@ public class VolumeControlImpl { return null; } + + /** + * Implementers return the property name they use to store + * sound level information. + * + * @return sound level property name for storing configuration. + */ + abstract String getStoreLevelPropertyName(); } diff --git a/src/net/java/sip/communicator/impl/neomedia/InputVolumeControlImpl.java b/src/net/java/sip/communicator/impl/neomedia/InputVolumeControlImpl.java new file mode 100644 index 0000000..3078e1d --- /dev/null +++ b/src/net/java/sip/communicator/impl/neomedia/InputVolumeControlImpl.java @@ -0,0 +1,30 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.impl.neomedia; + +import net.java.sip.communicator.service.neomedia.*; + +/** + * Controls media service capture volume. + * + * @author Damian Minkov + */ +public class InputVolumeControlImpl + extends AbstractVolumeControl + implements InputVolumeControl +{ + /** + * Returns the property we use to store input sound level. + * + * @return sound level property name for storing configuration. + */ + @Override + String getStoreLevelPropertyName() + { + return CAPTURE_VOLUME_LEVEL_PROPERTY_NAME; + } +} diff --git a/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java b/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java index 1a0eaec..aea92bd 100644 --- a/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java @@ -122,7 +122,12 @@ public class MediaServiceImpl /** * The volume control of the media service playback. */ - private static VolumeControl volumeControl; + private static OutputVolumeControl outputVolumeControl; + + /** + * The volume control of the media service capture. + */ + private static InputVolumeControl inputVolumeControl; /** * Create a <tt>MediaStream</tt> which will use a specific @@ -544,12 +549,25 @@ public class MediaServiceImpl * * @return the volume playback control. */ - public VolumeControl getVolumeControl() + public OutputVolumeControl getOutputVolumeControl() + { + if(outputVolumeControl == null) + outputVolumeControl = new OutputVolumeControlImpl(); + + return outputVolumeControl; + } + + /** + * Returns the control that handles current capture levels. + * + * @return the volume capture control. + */ + public InputVolumeControl getInputVolumeControl() { - if(volumeControl == null) - volumeControl = new VolumeControlImpl(); + if(inputVolumeControl == null) + inputVolumeControl = new InputVolumeControlImpl(); - return volumeControl; + return inputVolumeControl; } /** diff --git a/src/net/java/sip/communicator/impl/neomedia/OutputVolumeControlImpl.java b/src/net/java/sip/communicator/impl/neomedia/OutputVolumeControlImpl.java new file mode 100644 index 0000000..6106cbf --- /dev/null +++ b/src/net/java/sip/communicator/impl/neomedia/OutputVolumeControlImpl.java @@ -0,0 +1,30 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.impl.neomedia; + +import net.java.sip.communicator.service.neomedia.*; + +/** + * Controls media service playback volume. + * + * @author Damian Minkov + */ +public class OutputVolumeControlImpl + extends AbstractVolumeControl + implements OutputVolumeControl +{ + /** + * Returns the property we use to store output sound level. + * + * @return sound level property name for storing configuration. + */ + @Override + String getStoreLevelPropertyName() + { + return PLAYBACK_VOLUME_LEVEL_PROPERTY_NAME; + } +} diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/portaudio/PortAudioStream.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/portaudio/PortAudioStream.java index d415fdc..10bae4a 100644 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/portaudio/PortAudioStream.java +++ b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/protocol/portaudio/PortAudioStream.java @@ -7,6 +7,7 @@ package net.java.sip.communicator.impl.neomedia.jmfext.media.protocol.portaudio; import java.io.*; +import java.util.*; import javax.media.*; import javax.media.control.*; @@ -87,6 +88,11 @@ public class PortAudioStream private boolean streamIsBusy = false; /** + * Volume Control used to control volume of current captured media. + */ + private GainControl volumeControl = null; + + /** * Initializes a new <tt>PortAudioStream</tt> instance which is to have its * <tt>Format</tt>-related information abstracted by a specific * <tt>FormatControl</tt>. @@ -104,6 +110,9 @@ public class PortAudioStream super(formatControl); this.audioQualityImprovement = audioQualityImprovement; + + this.volumeControl = (GainControl)NeomediaActivator + .getMediaServiceImpl().getInputVolumeControl(); } /** @@ -178,6 +187,33 @@ public class PortAudioStream throw ioex; } + // if we have some volume setting apply them + if(volumeControl != null) + { + if(volumeControl.getMute()) + { + Arrays.fill(bufferData, (byte) 0); + } + else if(volumeControl.getDB() != 0) + { + // increase/decrease a little more than + // if using levels for factor + // we use factor = pow(10, dB/10), + // but level = pow(10, dB/20); + double factor = Math.pow(10, (volumeControl.getDB() / 10d)); + + for (int i = 0; i < bufferData.length; i+=2) + { + short s = (short)((bufferData[i]&0xff) + | (bufferData[i + 1]<<8)); + s = (short)(s*factor); + + bufferData[i] = (byte) s; + bufferData[i+1] = (byte) (s >> 8); + } + } + } + long bufferTimeStamp = System.nanoTime(); buffer.setFlags(Buffer.FLAG_SYSTEM_TIME); diff --git a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/audio/PortAudioRenderer.java b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/audio/PortAudioRenderer.java index 5bcff9b..7c663f3 100644 --- a/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/audio/PortAudioRenderer.java +++ b/src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/audio/PortAudioRenderer.java @@ -172,7 +172,7 @@ public class PortAudioRenderer { if(enableVolumeControl) this.gainControl = (GainControl)NeomediaActivator - .getMediaServiceImpl().getVolumeControl(); + .getMediaServiceImpl().getOutputVolumeControl(); } /** diff --git a/src/net/java/sip/communicator/service/neomedia/InputVolumeControl.java b/src/net/java/sip/communicator/service/neomedia/InputVolumeControl.java new file mode 100644 index 0000000..2f1f6a2 --- /dev/null +++ b/src/net/java/sip/communicator/service/neomedia/InputVolumeControl.java @@ -0,0 +1,22 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.service.neomedia; + +/** + * Controls the capture volume in media service. + * + * @author Damian Minkov + */ +public interface InputVolumeControl + extends VolumeControl +{ + /** + * Property for storing level into configuration. + */ + public final static String CAPTURE_VOLUME_LEVEL_PROPERTY_NAME + = "net.java.sip.communicator.service.media.CAPTURE_VOLUME_LEVEL"; +} diff --git a/src/net/java/sip/communicator/service/neomedia/MediaService.java b/src/net/java/sip/communicator/service/neomedia/MediaService.java index 58f5273..4f93530 100644 --- a/src/net/java/sip/communicator/service/neomedia/MediaService.java +++ b/src/net/java/sip/communicator/service/neomedia/MediaService.java @@ -142,7 +142,13 @@ public interface MediaService * Returns the control that handles current playback levels. * @return the volume playback control. */ - public VolumeControl getVolumeControl(); + public OutputVolumeControl getOutputVolumeControl(); + + /** + * Returns the control that handles current capture levels. + * @return the volume capture control. + */ + public InputVolumeControl getInputVolumeControl(); /** * Get available <tt>ScreenDevice</tt>s. diff --git a/src/net/java/sip/communicator/service/neomedia/OutputVolumeControl.java b/src/net/java/sip/communicator/service/neomedia/OutputVolumeControl.java new file mode 100644 index 0000000..53b6d26 --- /dev/null +++ b/src/net/java/sip/communicator/service/neomedia/OutputVolumeControl.java @@ -0,0 +1,22 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.service.neomedia; + +/** + * Controls the playback volume in media service. + * + * @author Damian Minkov + */ +public interface OutputVolumeControl + extends VolumeControl +{ + /** + * Property for storing level into configuration. + */ + public final static String PLAYBACK_VOLUME_LEVEL_PROPERTY_NAME + = "net.java.sip.communicator.service.media.PLAYBACK_VOLUME_LEVEL"; +} diff --git a/src/net/java/sip/communicator/service/neomedia/VolumeControl.java b/src/net/java/sip/communicator/service/neomedia/VolumeControl.java index 5dbf25d..e93df44 100644 --- a/src/net/java/sip/communicator/service/neomedia/VolumeControl.java +++ b/src/net/java/sip/communicator/service/neomedia/VolumeControl.java @@ -9,15 +9,14 @@ package net.java.sip.communicator.service.neomedia; import net.java.sip.communicator.service.neomedia.event.*; /** - * Controls the playback volume in media service. + * Control for volume level in media service. + * @see InputVolumeControl + * @see OutputVolumeControl * * @author Damian Minkov */ public interface VolumeControl { - public final static String PLAYBACK_VOLUME_LEVEL_PROPERTY_NAME - = "net.java.sip.communicator.service.media.PLAYBACK_VOLUME_LEVEL"; - /** * Current volume value. * @return the current volume level. |