Refactors (neomeida's) volume control for the purposes of optimization, simplification.

cusax-fix
Lyubomir Marinov 14 years ago
parent d69f6a830f
commit 3bb4311fb9

@ -24,8 +24,9 @@
* functionalities to work as one.
*
* @author Damian Minkov
* @author Lyubomir Marinov
*/
public abstract class AbstractVolumeControl
public class AbstractVolumeControl
implements VolumeControl,
GainControl
{
@ -55,8 +56,8 @@ public abstract class AbstractVolumeControl
* The <tt>VolumeChangeListener</tt> interested in volume change events
* through VolumeControl Interface.
*/
private List<VolumeChangeListener> volumeChangeListeners =
new ArrayList<VolumeChangeListener>();
private final List<VolumeChangeListener> volumeChangeListeners
= new ArrayList<VolumeChangeListener>();
/**
* Listeners interested in volume change inside jmf.
@ -66,12 +67,12 @@ public abstract class AbstractVolumeControl
/**
* The current volume level.
*/
private float currentVolumeLevel = DEFAULT_VOLUME_LEVEL;
private float volumeLevel = DEFAULT_VOLUME_LEVEL;
/**
* Current mute state, by default we start unmuted.
*/
private boolean currentMuteState = false;
private boolean mute = false;
/**
* Current level in db.
@ -81,34 +82,53 @@ public abstract class AbstractVolumeControl
/**
* The initial volume level, when this instance was created.
*/
private float initialVolumeLevel = DEFAULT_VOLUME_LEVEL;
private final float initialVolumeLevel;
/**
* Creates volume control instance and initialise initial level value
* if stored in config service.
* The name of the configuration property which specifies the value of the
* volume level of this <tt>AbstractVolumeControl</tt>.
*/
AbstractVolumeControl()
private final String volumeLevelConfigurationPropertyName;
/**
* Creates volume control instance and initializes initial level value
* if stored in the configuration service.
*
* @param volumeLevelConfigurationPropertyName the name of the configuration
* property which specifies the value of the volume level of the new
* instance
*/
public AbstractVolumeControl(
String volumeLevelConfigurationPropertyName)
{
this.volumeLevelConfigurationPropertyName
= volumeLevelConfigurationPropertyName;
// read initial level from config service if any
String initialLevel =
NeomediaActivator.getConfigurationService()
.getString(getStoreLevelPropertyName());
String initialVolumeLevelString
= NeomediaActivator.getConfigurationService().getString(
this.volumeLevelConfigurationPropertyName);
float initialVolumeLevel = DEFAULT_VOLUME_LEVEL;
try
{
if(initialLevel != null)
if (initialVolumeLevelString != null)
{
currentVolumeLevel = Float.valueOf(initialLevel);
initialVolumeLevel = currentVolumeLevel;
initialVolumeLevel = Float.parseFloat(initialVolumeLevelString);
if(logger.isDebugEnabled())
logger.debug("Restore volume: "
+ currentVolumeLevel);
{
logger.debug(
"Restored volume: " + initialVolumeLevelString);
}
}
}
catch(Throwable t)
{
logger.warn("Error restoring volume", t);
}
this.initialVolumeLevel = initialVolumeLevel;
this.volumeLevel = this.initialVolumeLevel;
}
/**
@ -170,7 +190,7 @@ else if (si < Short.MIN_VALUE)
*/
public float getVolume()
{
return currentVolumeLevel;
return volumeLevel;
}
/**
@ -183,7 +203,7 @@ public float getVolume()
*/
public float getLevel()
{
return this.currentVolumeLevel;
return volumeLevel;
}
/**
@ -250,22 +270,22 @@ public float setLevel(float level)
*/
private float setVolumeLevel(float value)
{
if(this.currentVolumeLevel == value)
if (volumeLevel == value)
return value;
if(value < MIN_VOLUME_LEVEL)
this.currentVolumeLevel = MIN_VOLUME_LEVEL;
volumeLevel = MIN_VOLUME_LEVEL;
else if(value > MAX_VOLUME_LEVEL)
this.currentVolumeLevel = MAX_VOLUME_LEVEL;
volumeLevel = MAX_VOLUME_LEVEL;
else
this.currentVolumeLevel = value;
volumeLevel = value;
fireVolumeChange();
// save the level change, so we can restore it on next run
NeomediaActivator.getConfigurationService().setProperty(
getStoreLevelPropertyName(),
String.valueOf(currentVolumeLevel));
this.volumeLevelConfigurationPropertyName,
String.valueOf(volumeLevel));
float f1 = value / initialVolumeLevel;
db = (float)((Math.log((double)f1 != 0.0D ?
@ -274,7 +294,7 @@ else if(value > MAX_VOLUME_LEVEL)
fireGainEvents();
return this.currentVolumeLevel;
return volumeLevel;
}
/**
@ -284,14 +304,13 @@ else if(value > MAX_VOLUME_LEVEL)
*/
public void setMute(boolean mute)
{
if(mute == this.currentMuteState)
return;
this.currentMuteState = mute;
fireVolumeChange();
if (this.mute != mute)
{
this.mute = mute;
fireGainEvents();
fireVolumeChange();
fireGainEvents();
}
}
/**
@ -301,7 +320,7 @@ public void setMute(boolean mute)
*/
public boolean getMute()
{
return this.currentMuteState;
return mute;
}
/**
@ -321,20 +340,16 @@ public float setDB(float gain)
if(this.db != gain)
{
this.db = gain;
float f1 = (float)Math.pow(10D, (double)this.db / 20D);
this.currentVolumeLevel = f1 * this.initialVolumeLevel;
if((double)this.currentVolumeLevel < 0.0D)
{
setVolumeLevel(0.0F);
}
else if((double)this.currentVolumeLevel > 1.0D)
{
setVolumeLevel(1.0F);
}
else
{
setVolumeLevel(this.currentVolumeLevel);
}
float volumeLevel = f1 * this.initialVolumeLevel;
if(volumeLevel < 0.0F)
volumeLevel = 0.0F;
else if(volumeLevel > 1.0F)
volumeLevel = 1.0F;
setVolumeLevel(volumeLevel);
}
return this.db;
}
@ -361,7 +376,6 @@ public void addGainChangeListener(GainChangeListener listener)
{
if(gainChangeListeners == null)
gainChangeListeners = new ArrayList<GainChangeListener>();
gainChangeListeners.add(listener);
}
}
@ -388,9 +402,7 @@ public void addVolumeChangeListener(VolumeChangeListener listener)
synchronized(volumeChangeListeners)
{
if(!volumeChangeListeners.contains(listener))
{
volumeChangeListeners.add(listener);
}
}
}
@ -412,21 +424,20 @@ public void removeVolumeChangeListener(VolumeChangeListener listener)
*/
private void fireVolumeChange()
{
List<VolumeChangeListener> copyVolumeListeners;
VolumeChangeListener[] ls;
synchronized(volumeChangeListeners)
{
copyVolumeListeners =
new ArrayList<VolumeChangeListener>(volumeChangeListeners);
ls
= volumeChangeListeners.toArray(
new VolumeChangeListener[volumeChangeListeners.size()]);
}
VolumeChangeEvent changeEvent = new VolumeChangeEvent(
this, this.currentVolumeLevel, this.currentMuteState);
VolumeChangeEvent changeEvent
= new VolumeChangeEvent(this, volumeLevel, mute);
for(VolumeChangeListener l : copyVolumeListeners)
{
for(VolumeChangeListener l : ls)
l.volumeChange(changeEvent);
}
}
/**
@ -436,14 +447,11 @@ private void fireGainEvents()
{
if(gainChangeListeners != null)
{
GainChangeEvent gainchangeevent =
new GainChangeEvent(
this, currentMuteState, db, currentVolumeLevel);
GainChangeEvent gainchangeevent
= new GainChangeEvent(this, mute, db, volumeLevel);
for(GainChangeListener gainchangelistener : gainChangeListeners)
{
gainchangelistener.gainChange(gainchangeevent);
}
}
}
@ -455,12 +463,4 @@ public Component getControlComponent()
{
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();
}

@ -1,30 +0,0 @@
/*
* Jitsi, 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;
}
}

@ -134,12 +134,12 @@ public class MediaServiceImpl
/**
* The volume control of the media service playback.
*/
private static OutputVolumeControl outputVolumeControl;
private static VolumeControl outputVolumeControl;
/**
* The volume control of the media service capture.
*/
private static InputVolumeControl inputVolumeControl;
private static VolumeControl inputVolumeControl;
/**
* Lock to protected reinitialization of video devices.
@ -591,28 +591,40 @@ public SDesControl createSDesControl()
}
/**
* Returns the control that handles current playback levels.
* Gets the <tt>VolumeControl</tt> which controls the volume level of audio
* output/playback.
*
* @return the volume playback control.
* @return the <tt>VolumeControl</tt> which controls the volume level of
* audio output/playback
* @see MediaService#getOutputVolumeControl()
*/
public OutputVolumeControl getOutputVolumeControl()
public VolumeControl getOutputVolumeControl()
{
if(outputVolumeControl == null)
outputVolumeControl = new OutputVolumeControlImpl();
if (outputVolumeControl == null)
{
outputVolumeControl
= new AbstractVolumeControl(
VolumeControl.PLAYBACK_VOLUME_LEVEL_PROPERTY_NAME);
}
return outputVolumeControl;
}
/**
* Returns the control that handles current capture levels.
* Gets the <tt>VolumeControl</tt> which controls the volume level of audio
* input/capture.
*
* @return the volume capture control.
* @return the <tt>VolumeControl</tt> which controls the volume level of
* audio input/capture
* @see MediaService#getInputVolumeControl()
*/
public InputVolumeControl getInputVolumeControl()
public VolumeControl getInputVolumeControl()
{
if(inputVolumeControl == null)
inputVolumeControl = new InputVolumeControlImpl();
if (inputVolumeControl == null)
{
inputVolumeControl
= new AbstractVolumeControl(
VolumeControl.CAPTURE_VOLUME_LEVEL_PROPERTY_NAME);
}
return inputVolumeControl;
}

@ -1,30 +0,0 @@
/*
* Jitsi, 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;
}
}

@ -65,6 +65,12 @@ public class PortAudioStream
*/
private int framesPerBuffer;
/**
* The <tt>GainControl</tt> through which the volume/gain of captured media
* is controlled.
*/
private final GainControl gainControl;
/**
* Native pointer to a PaStreamParameters object.
*/
@ -86,11 +92,6 @@ public class PortAudioStream
*/
private boolean streamIsBusy = false;
/**
* Volume Control used to control volume of current captured media.
*/
private final GainControl volumeControl;
/**
* Initializes a new <tt>PortAudioStream</tt> instance which is to have its
* <tt>Format</tt>-related information abstracted by a specific
@ -113,7 +114,7 @@ public PortAudioStream(
this.audioQualityImprovement = audioQualityImprovement;
this.volumeControl
gainControl
= (GainControl)
NeomediaActivator.getMediaServiceImpl().getInputVolumeControl();
}
@ -191,10 +192,10 @@ public void read(Buffer buffer)
}
// if we have some volume setting apply them
if(volumeControl != null)
if (gainControl != null)
{
AbstractVolumeControl.applyGain(
volumeControl,
gainControl,
bufferData, 0, bytesPerBuffer);
}

@ -145,10 +145,10 @@ public class PortAudioRenderer
private Format[] supportedInputFormats;
/**
* The <tt>GainControl</tt> used to control volume/gain of current played
* media.
* The <tt>GainControl</tt> through which volume/gain of rendered media is
* controlled.
*/
private GainControl gainControl = null;
private final GainControl gainControl;
/**
* Initializes a new <tt>PortAudioRenderer</tt> instance.
@ -166,12 +166,14 @@ public PortAudioRenderer()
*/
public PortAudioRenderer(boolean enableVolumeControl)
{
if(enableVolumeControl)
this.gainControl
if (enableVolumeControl)
gainControl
= (GainControl)
NeomediaActivator
.getMediaServiceImpl()
.getOutputVolumeControl();
else
gainControl = null;
}
/**

@ -1,22 +0,0 @@
/*
* Jitsi, 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";
}

@ -145,16 +145,22 @@ public MediaStream createMediaStream(StreamConnector connector,
public SDesControl createSDesControl();
/**
* Returns the control that handles current playback levels.
* @return the volume playback control.
* Gets the <tt>VolumeControl</tt> which controls the volume level of audio
* output/playback.
*
* @return the <tt>VolumeControl</tt> which controls the volume level of
* audio output/playback
*/
public OutputVolumeControl getOutputVolumeControl();
public VolumeControl getOutputVolumeControl();
/**
* Returns the control that handles current capture levels.
* @return the volume capture control.
* Gets the <tt>VolumeControl</tt> which controls the volume level of audio
* input/capture.
*
* @return the <tt>VolumeControl</tt> which controls the volume level of
* audio input/capture
*/
public InputVolumeControl getInputVolumeControl();
public VolumeControl getInputVolumeControl();
/**
* Get available <tt>ScreenDevice</tt>s.

@ -1,22 +0,0 @@
/*
* Jitsi, 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";
}

@ -10,13 +10,25 @@
/**
* Control for volume level in media service.
* @see InputVolumeControl
* @see OutputVolumeControl
*
* @author Damian Minkov
*/
public interface VolumeControl
{
/**
* The name of the configuration property which specifies the volume level
* of audio input.
*/
public final static String CAPTURE_VOLUME_LEVEL_PROPERTY_NAME
= "net.java.sip.communicator.service.media.CAPTURE_VOLUME_LEVEL";
/**
* The name of the configuration property which specifies the volume level
* of audio output.
*/
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.

Loading…
Cancel
Save