1 /*
2  * silencedetect.h
3  *
4  * Open Phone Abstraction Library (OPAL)
5  * Formally known as the Open H323 project.
6  *
7  * Copyright (c) 2004 Post Increment
8  *
9  * The contents of this file are subject to the Mozilla Public License
10  * Version 1.0 (the "License"); you may not use this file except in
11  * compliance with the License. You may obtain a copy of the License at
12  * http://www.mozilla.org/MPL/
13  *
14  * Software distributed under the License is distributed on an "AS IS"
15  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
16  * the License for the specific language governing rights and limitations
17  * under the License.
18  *
19  * The Original Code is Open Phone Abstraction Library.
20  *
21  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
22  *
23  * Contributor(s): ______________________________________.
24  *
25  * $Revision: 24320 $
26  * $Author: csoutheren $
27  * $Date: 2010-05-06 10:20:51 -0500 (Thu, 06 May 2010) $
28  */
29 
30 #ifndef OPAL_CODEC_SILENCEDETECT_H
31 #define OPAL_CODEC_SILENCEDETECT_H
32 
33 #ifdef P_USE_PRAGMA
34 #pragma interface
35 #endif
36 
37 #include <opal/buildopts.h>
38 #include <rtp/rtp.h>
39 
40 
41 ///////////////////////////////////////////////////////////////////////////////
42 
43 class OpalSilenceDetector : public PObject
44 {
45     PCLASSINFO(OpalSilenceDetector, PObject);
46   public:
47     enum Mode {
48       NoSilenceDetection,
49       FixedSilenceDetection,
50       AdaptiveSilenceDetection,
51       NumModes
52     };
53 
54     struct Params {
55       Params(
56         Mode mode = AdaptiveSilenceDetection, ///<  New silence detection mode
57         unsigned threshold = 0,               ///<  Threshold value if FixedSilenceDetection
58         unsigned signalDeadband = 10,         ///<  10 milliseconds of signal needed
59         unsigned silenceDeadband = 400,       ///<  400 milliseconds of silence needed
60         unsigned adaptivePeriod = 600         ///<  600 millisecond window for adaptive threshold
61       )
m_modeParams62         : m_mode(mode),
63           m_threshold(threshold),
64           m_signalDeadband(signalDeadband),
65           m_silenceDeadband(silenceDeadband),
66           m_adaptivePeriod(adaptivePeriod)
67         { }
68 
69       Mode     m_mode;             /// Silence detection mode
70       unsigned m_threshold;        /// Threshold value if FixedSilenceDetection
71       unsigned m_signalDeadband;   /// milliseconds of signal needed
72       unsigned m_silenceDeadband;  /// milliseconds of silence needed
73       unsigned m_adaptivePeriod;   /// millisecond window for adaptive threshold
74     };
75 
76   /**@name Construction */
77   //@{
78     /**Create a new detector. Default clock rate is 8000.
79      */
80     OpalSilenceDetector(
81       const Params & newParam ///<  New parameters for silence detector
82     );
83   //@}
84 
85   /**@name Basic operations */
86   //@{
GetReceiveHandler()87     const PNotifier & GetReceiveHandler() const { return receiveHandler; }
88 
89     /**Set the silence detector parameters.
90        This adjusts the silence detector "agression". The deadband and
91        adaptive periods are in ms units to work for any clock rate.
92 	   The clock rate value is optional: 0 leaves value unchanged.
93        This may be called while audio is being transferred, but if in
94        adaptive mode calling this will reset the filter.
95       */
96     void SetParameters(
97       const Params & params,  ///< New parameters for silence detector
98       const int clockRate = 0 ///< Sampling clock rate for the preprocessor
99     );
100 
101     /**Set the sampling clock rate for the preprocessor.
102        Adusts the interpretation of time values.
103        This may be called while audio is being transferred, but if in
104        adaptive mode calling this will reset the filter.
105      */
106     void SetClockRate(
107       const int clockRate     ///< Sampling clock rate for the preprocessor
108     );
109 
110     /**Get the current sampling clock rate.
111       */
GetClockRate()112     int GetClockRate() const { return clockRate; }
113 
114     /**Get silence detection status
115 
116        The inTalkBurst value is true if packet transmission is enabled and
117        false if it is being suppressed due to silence.
118 
119        The currentThreshold value is the value from 0 to 32767 which is used
120        as the threshold value for 16 bit PCM data.
121       */
122     Mode GetStatus(
123       PBoolean * isInTalkBurst,
124       unsigned * currentThreshold
125     ) const;
126 
127     /**Get the average signal level in the stream.
128        This is called from within the silence detection algorithm to
129        calculate the average signal level of the last data frame read from
130        the stream.
131 
132        The default behaviour returns UINT_MAX which indicates that the
133        average signal has no meaning for the stream.
134       */
135     virtual unsigned GetAverageSignalLevel(
136       const BYTE * buffer,  ///<  RTP payload being detected
137       PINDEX size           ///<  Size of payload buffer
138     ) = 0;
139 
140   private:
141     /**Reset the adaptive filter
142      */
143     void AdaptiveReset();
144 
145   protected:
146     PDECLARE_NOTIFIER(RTP_DataFrame, OpalSilenceDetector, ReceivedPacket);
147 
148     PNotifier receiveHandler;
149 
150     Mode mode;
151     unsigned signalDeadband;        // #samples of signal needed
152     unsigned silenceDeadband;       // #samples of silence needed
153     unsigned adaptivePeriod;        // #samples window for adaptive threshold
154     int clockRate;                  // audio sampling rate
155 
156     unsigned lastTimestamp;         // Last timestamp received
157     unsigned receivedTime;          // Signal/Silence duration received so far.
158     unsigned levelThreshold;        // Threshold level for silence/signal
159     unsigned signalMinimum;         // Minimum of frames above threshold
160     unsigned silenceMaximum;        // Maximum of frames below threshold
161     unsigned signalReceivedTime;    // Duration of signal received
162     unsigned silenceReceivedTime;   // Duration of silence received
163     bool     inTalkBurst;           // Currently sending RTP data
164     PMutex   inUse;                 // Protects values to allow change while running
165 };
166 
167 
168 class OpalPCM16SilenceDetector : public OpalSilenceDetector
169 {
170     PCLASSINFO(OpalPCM16SilenceDetector, OpalSilenceDetector);
171   public:
172     /** Construct new silence detector for PCM-16/8000
173       */
OpalPCM16SilenceDetector(const Params & newParam)174     OpalPCM16SilenceDetector(
175       const Params & newParam ///<  New parameters for silence detector
176     ) : OpalSilenceDetector(newParam) { }
177 
178   /**@name Overrides from OpalSilenceDetector */
179   //@{
180     /**Get the average signal level in the stream.
181        This is called from within the silence detection algorithm to
182        calculate the average signal level of the last data frame read from
183        the stream.
184 
185        The default behaviour returns UINT_MAX which indicates that the
186        average signal has no meaning for the stream.
187       */
188     virtual unsigned GetAverageSignalLevel(
189       const BYTE * buffer,  ///<  RTP payload being detected
190       PINDEX size           ///<  Size of payload buffer
191     );
192   //@}
193 };
194 
195 
196 extern ostream & operator<<(ostream & strm, OpalSilenceDetector::Mode mode);
197 
198 
199 #endif // OPAL_CODEC_SILENCEDETECT_H
200 
201 
202 /////////////////////////////////////////////////////////////////////////////
203