aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLyubomir Marinov <lyubomir.marinov@jitsi.org>2011-03-28 16:55:53 +0000
committerLyubomir Marinov <lyubomir.marinov@jitsi.org>2011-03-28 16:55:53 +0000
commit682469e0f235dd91c172288248580e63d92ed0e5 (patch)
tree80c1af6d4b9cd24ed70cc6b1a147e301d6d219d1 /src
parentac929ade062c8fbd20168b4e3d93d74f019e5f8f (diff)
downloadjitsi-682469e0f235dd91c172288248580e63d92ed0e5.zip
jitsi-682469e0f235dd91c172288248580e63d92ed0e5.tar.gz
jitsi-682469e0f235dd91c172288248580e63d92ed0e5.tar.bz2
Clips the audio signal instead of wrapping it when increasing the volume.
Diffstat (limited to 'src')
-rw-r--r--src/net/java/sip/communicator/impl/neomedia/jmfext/media/renderer/audio/PortAudioRenderer.java79
1 files changed, 52 insertions, 27 deletions
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 7c663f3..4b3648b 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
@@ -21,7 +21,7 @@ import net.java.sip.communicator.util.*;
* Implements an audio <tt>Renderer</tt> which uses PortAudio.
*
* @author Damian Minkov
- * @author Lubomir Marinov
+ * @author Lyubomir Marinov
*/
public class PortAudioRenderer
extends ControlsAdapter
@@ -152,7 +152,8 @@ public class PortAudioRenderer
private Format[] supportedInputFormats;
/**
- * Volume Control used to control volume/gain of current played media.
+ * The <tt>GainControl</tt> used to control volume/gain of current played
+ * media.
*/
private GainControl gainControl = null;
@@ -176,6 +177,53 @@ public class PortAudioRenderer
}
/**
+ * Applies the gain specified by {@link #gainControl} to the signal defined
+ * by the <tt>length</tt> number of samples given in <tt>buffer</tt>
+ * starting at <tt>offset</tt>.
+ *
+ * @param buffer the samples of the signal to apply the gain to
+ * @param offset the start of the samples of the signal in <tt>buffer</tt>
+ * @param length the number of samples of the signal given in
+ * <tt>buffer</tt>
+ */
+ private void applyGain(byte[] buffer, int offset, int length)
+ {
+ if (gainControl.getMute())
+ Arrays.fill(buffer, offset, offset + length, (byte) 0);
+ else
+ {
+ float db = gainControl.getDB();
+
+ if (db != 0)
+ {
+ // factor = pow(10, dB/10)
+ double factor = Math.pow(10, (db / 10d));
+
+ for (int i = offset, toIndex = offset + length;
+ i < toIndex;
+ i += 2)
+ {
+ int i1 = i + 1;
+ short s = (short) ((buffer[i] & 0xff) | (buffer[i1] << 8));
+
+ /* Clip, don't wrap. */
+ int si = (int) (s * factor);
+
+ if (si > Short.MAX_VALUE)
+ s = Short.MAX_VALUE;
+ else if (si < Short.MIN_VALUE)
+ s = Short.MIN_VALUE;
+ else
+ s = (short) si;
+
+ buffer[i] = (byte) s;
+ buffer[i1] = (byte) (s >> 8);
+ }
+ }
+ }
+ }
+
+ /**
* Closes this <tt>PlugIn</tt>.
*/
public synchronized void close()
@@ -504,31 +552,8 @@ public class PortAudioRenderer
if (numberOfWrites > 0)
{
// if we have some volume setting apply them
- if(gainControl != null)
- {
- if(gainControl.getMute())
- {
- Arrays.fill(buffer, (byte)0);
- }
- else if(gainControl.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, (gainControl.getDB() / 10d));
-
- for (int i = 0; i < buffer.length; i+=2)
- {
- short s = (short)((buffer[i]&0xff)
- | (buffer[i + 1]<<8));
- s = (short)(s*factor);
-
- buffer[i] = (byte) s;
- buffer[i+1] = (byte) (s >> 8);
- }
- }
- }
+ if (gainControl != null)
+ applyGain(buffer, offset, length);
PortAudio.Pa_WriteStream(
stream,