From 31ba84c0f2677a2f06dfd4864386d0b7994d9c02 Mon Sep 17 00:00:00 2001
From: Damian Minkov <damencho@jitsi.org>
Date: Fri, 12 Jul 2013 17:00:14 +0300
Subject: [PATCH] Adds volume to RFC4733 dtmf packets and handling of an
 account property to change default value. Changes the default minimum tone
 duration.

---
 .../impl/neomedia/AudioMediaStreamImpl.java   | 10 +++++--
 .../transform/dtmf/DtmfRawPacket.java         | 30 +++++++++++++++----
 .../transform/dtmf/DtmfTransformEngine.java   | 18 +++++++++--
 .../service/neomedia/AudioMediaStream.java    |  5 +++-
 4 files changed, 52 insertions(+), 11 deletions(-)

diff --git a/src/org/jitsi/impl/neomedia/AudioMediaStreamImpl.java b/src/org/jitsi/impl/neomedia/AudioMediaStreamImpl.java
index 02e3d1cc..fe001fa9 100644
--- a/src/org/jitsi/impl/neomedia/AudioMediaStreamImpl.java
+++ b/src/org/jitsi/impl/neomedia/AudioMediaStreamImpl.java
@@ -598,17 +598,20 @@ public void setStreamAudioLevelListener(SimpleAudioLevelListener listener)
      * @param dtmfMethod The kind of DTMF used (RTP, SIP-INOF or INBAND).
      * @param minimalToneDuration The minimal DTMF tone duration.
      * @param maximalToneDuration The maximal DTMF tone duration.
+     * @param volume The DTMF tone volume.
      *
      * @throws IllegalArgumentException if <tt>dtmfMethod</tt> is not one of
      * {@link DTMFMethod#INBAND_DTMF}, {@link DTMFMethod#RTP_DTMF}, and
      * {@link DTMFMethod#SIP_INFO_DTMF}
-     * @see AudioMediaStream#startSendingDTMF(DTMFTone, DTMFMethod)
+     * @see AudioMediaStream#startSendingDTMF(
+     *                          DTMFTone, DTMFMethod, int, int, int)
      */
     public void startSendingDTMF(
             DTMFTone tone,
             DTMFMethod dtmfMethod,
             int minimalToneDuration,
-            int maximalToneDuration)
+            int maximalToneDuration,
+            int volume)
     {
         switch (dtmfMethod)
         {
@@ -628,7 +631,8 @@ public void startSendingDTMF(
                     dtmfTransfrmEngine.startSending(
                             t,
                             minimalToneDuration,
-                            maximalToneDuration);
+                            maximalToneDuration,
+                            volume);
             }
             break;
 
diff --git a/src/org/jitsi/impl/neomedia/transform/dtmf/DtmfRawPacket.java b/src/org/jitsi/impl/neomedia/transform/dtmf/DtmfRawPacket.java
index 8ddcfe7b..a0ca934c 100644
--- a/src/org/jitsi/impl/neomedia/transform/dtmf/DtmfRawPacket.java
+++ b/src/org/jitsi/impl/neomedia/transform/dtmf/DtmfRawPacket.java
@@ -43,6 +43,11 @@ public class DtmfRawPacket
      */
     private int duration;
 
+    /**
+     * The volume of the current packet.
+     */
+    private int volume;
+
     /**
      * Creates a <tt>DtmfRawPacket</tt> using the specified buffer.
      *
@@ -72,7 +77,9 @@ public DtmfRawPacket(RawPacket pkt)
         int at = getHeaderLength();
 
         code = readByte(at++);
-        end = (readByte(at++) & 0x80) != 0;
+        byte b= readByte(at++);
+        end = (b & 0x80) != 0;
+        volume = b & 0x7f;
 
         duration = ((readByte(at++) & 0xFF) << 8) | (readByte(at++) & 0xFF);
     }
@@ -85,12 +92,14 @@ public DtmfRawPacket(RawPacket pkt)
      * @param marker the RTP Marker flag
      * @param duration the DTMF duration
      * @param timestamp the RTP timestamp
+     * @param volume the DTMF volume
      */
     public void init(int     code,
                      boolean end,
                      boolean marker,
                      int     duration,
-                     long    timestamp)
+                     long    timestamp,
+                     int volume)
     {
         if(logger.isTraceEnabled())
         {
@@ -106,7 +115,7 @@ public void init(int     code,
         setTimestamp(timestamp);
 
          // Create the RTP data
-        setDtmfPayload(code, end, duration);
+        setDtmfPayload(code, end, duration, volume);
     }
 
     /**
@@ -130,17 +139,19 @@ public void init(int     code,
      * @param end boolean used to mark the two last packets
      * @param duration int increments for each dtmf sending
      * updates, stay unchanged at the end for the 2 last packets.
+     * @param volume describes the power level of the tone, expressed in dBm0
      */
-    private void setDtmfPayload(int code, boolean end, int duration)
+    private void setDtmfPayload(int code, boolean end, int duration, int volume)
     {
         this.code = code;
         this.end = end;
         this.duration = duration;
+        this.volume = volume;
 
         int at = getHeaderLength();
 
         writeByte(at++, (byte)code);
-        writeByte(at++, end ? (byte)0x80 : (byte)0);
+        writeByte(at++, end ? (byte)(volume | 0x80) : (byte)(volume & 0x7f));
         writeByte(at++, (byte)(duration >> 8));
         writeByte(at++, (byte)duration);
     }
@@ -171,4 +182,13 @@ public int getDuration()
     {
         return duration;
     }
+
+    /**
+     * The volume of the current event.
+     * @return the volume
+     */
+    public int getVolume()
+    {
+        return volume;
+    }
 }
diff --git a/src/org/jitsi/impl/neomedia/transform/dtmf/DtmfTransformEngine.java b/src/org/jitsi/impl/neomedia/transform/dtmf/DtmfTransformEngine.java
index 10660960..f55e2426 100644
--- a/src/org/jitsi/impl/neomedia/transform/dtmf/DtmfTransformEngine.java
+++ b/src/org/jitsi/impl/neomedia/transform/dtmf/DtmfTransformEngine.java
@@ -147,6 +147,11 @@ private enum ToneTransmissionState
      */
     private int maximalToneDuration;
 
+    /**
+     * The DTMF tone volume.
+     */
+    private int volume;
+
     /**
      * Creates an engine instance that will be replacing audio packets
      * with DTMF ones upon request.
@@ -376,7 +381,8 @@ else if(toneTransmissionState
             pktEnd,
             pktMarker,
             pktDuration,
-            currentTimestamp);
+            currentTimestamp,
+            volume);
         pkt = dtmfPkt;
 
         return pkt;
@@ -390,11 +396,13 @@ else if(toneTransmissionState
      * @param tone the tone that we'd like to start sending.
      * @param minimalToneDuration The minimal DTMF tone duration.
      * @param maximalToneDuration The maximal DTMF tone duration.
+     * @param volume The DTMF tone volume.
      */
     public void startSending(
             DTMFRtpTone tone,
             int minimalToneDuration,
-            int maximalToneDuration)
+            int maximalToneDuration,
+            int volume)
     {
         synchronized(startStopToneMutex)
         {
@@ -417,6 +425,12 @@ else if(this.maximalToneDuration < this.minimalToneDuration)
         {
             this.maximalToneDuration = this.minimalToneDuration;
         }
+
+        if(volume > 0)
+            this.volume = volume;
+        else
+            this.volume = 0; // we used to sent 0 for
+                             // this field, keep it that way if not set.
     }
 
     /**
diff --git a/src/org/jitsi/service/neomedia/AudioMediaStream.java b/src/org/jitsi/service/neomedia/AudioMediaStream.java
index ddfd8b7e..09204062 100644
--- a/src/org/jitsi/service/neomedia/AudioMediaStream.java
+++ b/src/org/jitsi/service/neomedia/AudioMediaStream.java
@@ -94,12 +94,15 @@ public void setLocalUserAudioLevelListener(
      * @param dtmfMethod The kind of DTMF used (RTP, SIP-INOF or INBAND).
      * @param minimalToneDuration The minimal DTMF tone duration.
      * @param maximalToneDuration The maximal DTMF tone duration.
+     * @param volume The DTMF tone volume. Describes the power level of the
+     *               tone, expressed in dBm0 after dropping the sign.
      */
     public void startSendingDTMF(
             DTMFTone tone,
             DTMFMethod dtmfMethod,
             int minimalToneDuration,
-            int maximalToneDuration);
+            int maximalToneDuration,
+            int volume);
 
     /**
      * Interrupts transmission of a <tt>DTMFTone</tt> started with the
-- 
GitLab