OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/voice_engine/dtmf_inband.h" | 11 #include "webrtc/voice_engine/dtmf_inband.h" |
12 | 12 |
13 #include <assert.h> | 13 #include <assert.h> |
14 | 14 |
15 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | |
16 #include "webrtc/system_wrappers/include/trace.h" | 15 #include "webrtc/system_wrappers/include/trace.h" |
17 | 16 |
18 namespace webrtc { | 17 namespace webrtc { |
19 | 18 |
20 const int16_t Dtmf_a_times2Tab8Khz[8]= | 19 const int16_t Dtmf_a_times2Tab8Khz[8]= |
21 { | 20 { |
22 27978, 26956, 25701, 24219, | 21 27978, 26956, 25701, 24219, |
23 19073, 16325, 13085, 9314 | 22 19073, 16325, 13085, 9314 |
24 }; | 23 }; |
25 | 24 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
59 8090, 7210, 6426, 5727, 5104, 4549, | 58 8090, 7210, 6426, 5727, 5104, 4549, |
60 4054, 3614, 3221, 2870, 2558, 2280, | 59 4054, 3614, 3221, 2870, 2558, 2280, |
61 2032, 1811, 1614, 1439, 1282, 1143, | 60 2032, 1811, 1614, 1439, 1282, 1143, |
62 1018, 908, 809, 721, 643, 573, | 61 1018, 908, 809, 721, 643, 573, |
63 510, 455, 405, 361, 322, 287, | 62 510, 455, 405, 361, 322, 287, |
64 256 | 63 256 |
65 }; | 64 }; |
66 | 65 |
67 | 66 |
68 DtmfInband::DtmfInband(int32_t id) : | 67 DtmfInband::DtmfInband(int32_t id) : |
69 _critSect(*CriticalSectionWrapper::CreateCriticalSection()), | |
70 _id(id), | 68 _id(id), |
71 _outputFrequencyHz(8000), | 69 _outputFrequencyHz(8000), |
72 _frameLengthSamples(0), | 70 _frameLengthSamples(0), |
73 _remainingSamples(0), | 71 _remainingSamples(0), |
74 _eventCode(0), | 72 _eventCode(0), |
75 _attenuationDb(0), | 73 _attenuationDb(0), |
76 _lengthMs(0), | 74 _lengthMs(0), |
77 _reinit(true), | 75 _reinit(true), |
78 _playing(false), | 76 _playing(false), |
79 _delaySinceLastToneMS(1000) | 77 _delaySinceLastToneMS(1000) |
80 { | 78 { |
81 memset(_oldOutputLow, 0, sizeof(_oldOutputLow)); | 79 memset(_oldOutputLow, 0, sizeof(_oldOutputLow)); |
82 memset(_oldOutputHigh, 0, sizeof(_oldOutputHigh)); | 80 memset(_oldOutputHigh, 0, sizeof(_oldOutputHigh)); |
83 } | 81 } |
84 | 82 |
85 DtmfInband::~DtmfInband() | 83 DtmfInband::~DtmfInband() |
86 { | 84 { |
87 delete &_critSect; | |
88 } | 85 } |
89 | 86 |
90 int | 87 int |
91 DtmfInband::SetSampleRate(uint16_t frequency) | 88 DtmfInband::SetSampleRate(uint16_t frequency) |
92 { | 89 { |
93 if (frequency != 8000 && | 90 if (frequency != 8000 && |
94 frequency != 16000 && | 91 frequency != 16000 && |
95 frequency != 32000) | 92 frequency != 32000) |
96 { | 93 { |
97 // invalid sample rate | 94 // invalid sample rate |
98 assert(false); | 95 assert(false); |
99 return -1; | 96 return -1; |
100 } | 97 } |
101 _outputFrequencyHz = frequency; | 98 _outputFrequencyHz = frequency; |
102 return 0; | 99 return 0; |
103 } | 100 } |
104 | 101 |
105 int | 102 int |
106 DtmfInband::GetSampleRate(uint16_t& frequency) | 103 DtmfInband::GetSampleRate(uint16_t& frequency) |
107 { | 104 { |
108 frequency = _outputFrequencyHz; | 105 frequency = _outputFrequencyHz; |
109 return 0; | 106 return 0; |
110 } | 107 } |
111 | 108 |
112 void | 109 void |
113 DtmfInband::Init() | 110 DtmfInband::Init() |
114 { | 111 { |
115 _remainingSamples = 0; | 112 _remainingSamples = 0; |
116 _frameLengthSamples = 0; | 113 _frameLengthSamples = 0; |
117 _eventCode = 0; | 114 _eventCode = 0; |
118 _attenuationDb = 0; | 115 _attenuationDb = 0; |
119 _lengthMs = 0; | 116 _lengthMs = 0; |
120 _reinit = true; | 117 _reinit = true; |
121 _oldOutputLow[0] = 0; | 118 _oldOutputLow[0] = 0; |
122 _oldOutputLow[1] = 0; | 119 _oldOutputLow[1] = 0; |
123 _oldOutputHigh[0] = 0; | 120 _oldOutputHigh[0] = 0; |
124 _oldOutputHigh[1] = 0; | 121 _oldOutputHigh[1] = 0; |
125 _delaySinceLastToneMS = 1000; | 122 _delaySinceLastToneMS = 1000; |
126 } | 123 } |
127 | 124 |
128 int | 125 int |
129 DtmfInband::AddTone(uint8_t eventCode, | 126 DtmfInband::AddTone(uint8_t eventCode, |
130 int32_t lengthMs, | 127 int32_t lengthMs, |
131 int32_t attenuationDb) | 128 int32_t attenuationDb) |
132 { | 129 { |
133 CriticalSectionScoped lock(&_critSect); | 130 rtc::CritScope lock(&_critSect); |
134 | 131 |
135 if (attenuationDb > 36 || eventCode > 15) | 132 if (attenuationDb > 36 || eventCode > 15) |
136 { | 133 { |
137 assert(false); | 134 assert(false); |
138 return -1; | 135 return -1; |
139 } | 136 } |
140 | 137 |
141 if (IsAddingTone()) | 138 if (IsAddingTone()) |
142 { | 139 { |
143 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_id,-1), | 140 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_id,-1), |
144 "DtmfInband::AddTone() new tone interrupts ongoing tone"); | 141 "DtmfInband::AddTone() new tone interrupts ongoing tone"); |
145 } | 142 } |
146 | 143 |
147 ReInit(); | 144 ReInit(); |
148 | 145 |
149 _frameLengthSamples = static_cast<int16_t> (_outputFrequencyHz / 100); | 146 _frameLengthSamples = static_cast<int16_t> (_outputFrequencyHz / 100); |
150 _eventCode = static_cast<int16_t> (eventCode); | 147 _eventCode = static_cast<int16_t> (eventCode); |
151 _attenuationDb = static_cast<int16_t> (attenuationDb); | 148 _attenuationDb = static_cast<int16_t> (attenuationDb); |
152 _remainingSamples = static_cast<int32_t> | 149 _remainingSamples = static_cast<int32_t> |
153 (lengthMs * (_outputFrequencyHz / 1000)); | 150 (lengthMs * (_outputFrequencyHz / 1000)); |
154 _lengthMs = lengthMs; | 151 _lengthMs = lengthMs; |
155 | 152 |
156 return 0; | 153 return 0; |
157 } | 154 } |
158 | 155 |
159 int | 156 int |
160 DtmfInband::ResetTone() | 157 DtmfInband::ResetTone() |
161 { | 158 { |
162 CriticalSectionScoped lock(&_critSect); | 159 rtc::CritScope lock(&_critSect); |
163 | 160 |
164 ReInit(); | 161 ReInit(); |
165 | 162 |
166 _frameLengthSamples = static_cast<int16_t> (_outputFrequencyHz / 100); | 163 _frameLengthSamples = static_cast<int16_t> (_outputFrequencyHz / 100); |
167 _remainingSamples = static_cast<int32_t> | 164 _remainingSamples = static_cast<int32_t> |
168 (_lengthMs * (_outputFrequencyHz / 1000)); | 165 (_lengthMs * (_outputFrequencyHz / 1000)); |
169 | 166 |
170 return 0; | 167 return 0; |
171 } | 168 } |
172 | 169 |
173 int | 170 int |
174 DtmfInband::StartTone(uint8_t eventCode, | 171 DtmfInband::StartTone(uint8_t eventCode, |
175 int32_t attenuationDb) | 172 int32_t attenuationDb) |
176 { | 173 { |
177 CriticalSectionScoped lock(&_critSect); | 174 rtc::CritScope lock(&_critSect); |
178 | 175 |
179 if (attenuationDb > 36 || eventCode > 15) | 176 if (attenuationDb > 36 || eventCode > 15) |
180 { | 177 { |
181 assert(false); | 178 assert(false); |
182 return -1; | 179 return -1; |
183 } | 180 } |
184 | 181 |
185 if (IsAddingTone()) | 182 if (IsAddingTone()) |
186 { | 183 { |
187 return -1; | 184 return -1; |
188 } | 185 } |
189 | 186 |
190 ReInit(); | 187 ReInit(); |
191 | 188 |
192 _frameLengthSamples = static_cast<int16_t> (_outputFrequencyHz / 100); | 189 _frameLengthSamples = static_cast<int16_t> (_outputFrequencyHz / 100); |
193 _eventCode = static_cast<int16_t> (eventCode); | 190 _eventCode = static_cast<int16_t> (eventCode); |
194 _attenuationDb = static_cast<int16_t> (attenuationDb); | 191 _attenuationDb = static_cast<int16_t> (attenuationDb); |
195 _playing = true; | 192 _playing = true; |
196 | 193 |
197 return 0; | 194 return 0; |
198 } | 195 } |
199 | 196 |
200 int | 197 int |
201 DtmfInband::StopTone() | 198 DtmfInband::StopTone() |
202 { | 199 { |
203 CriticalSectionScoped lock(&_critSect); | 200 rtc::CritScope lock(&_critSect); |
204 | 201 |
205 if (!_playing) | 202 if (!_playing) |
206 { | 203 { |
207 return 0; | 204 return 0; |
208 } | 205 } |
209 | 206 |
210 _playing = false; | 207 _playing = false; |
211 | 208 |
212 return 0; | 209 return 0; |
213 } | 210 } |
214 | 211 |
215 // Shall be called between tones | 212 // Shall be called between tones |
216 void | 213 void |
217 DtmfInband::ReInit() | 214 DtmfInband::ReInit() |
218 { | 215 { |
219 _reinit = true; | 216 _reinit = true; |
220 } | 217 } |
221 | 218 |
222 bool | 219 bool |
223 DtmfInband::IsAddingTone() | 220 DtmfInband::IsAddingTone() |
224 { | 221 { |
225 CriticalSectionScoped lock(&_critSect); | 222 rtc::CritScope lock(&_critSect); |
226 return (_remainingSamples > 0 || _playing); | 223 return (_remainingSamples > 0 || _playing); |
227 } | 224 } |
228 | 225 |
229 int | 226 int |
230 DtmfInband::Get10msTone(int16_t output[320], | 227 DtmfInband::Get10msTone(int16_t output[320], |
231 uint16_t& outputSizeInSamples) | 228 uint16_t& outputSizeInSamples) |
232 { | 229 { |
233 CriticalSectionScoped lock(&_critSect); | 230 rtc::CritScope lock(&_critSect); |
234 if (DtmfFix_generate(output, | 231 if (DtmfFix_generate(output, |
235 _eventCode, | 232 _eventCode, |
236 _attenuationDb, | 233 _attenuationDb, |
237 _frameLengthSamples, | 234 _frameLengthSamples, |
238 _outputFrequencyHz) == -1) | 235 _outputFrequencyHz) == -1) |
239 { | 236 { |
240 return -1; | 237 return -1; |
241 } | 238 } |
242 _remainingSamples -= _frameLengthSamples; | 239 _remainingSamples -= _frameLengthSamples; |
243 outputSizeInSamples = _frameLengthSamples; | 240 outputSizeInSamples = _frameLengthSamples; |
244 _delaySinceLastToneMS = 0; | 241 _delaySinceLastToneMS = 0; |
245 return 0; | 242 return 0; |
246 } | 243 } |
247 | 244 |
248 void | 245 void |
249 DtmfInband::UpdateDelaySinceLastTone() | 246 DtmfInband::UpdateDelaySinceLastTone() |
250 { | 247 { |
251 _delaySinceLastToneMS += kDtmfFrameSizeMs; | 248 _delaySinceLastToneMS += kDtmfFrameSizeMs; |
the sun
2016/01/21 13:07:28
Add CritScope; there's a a race with this function
tommi
2016/01/21 15:29:23
Done.
| |
252 // avoid wraparound | 249 // avoid wraparound |
253 if (_delaySinceLastToneMS > (1<<30)) | 250 if (_delaySinceLastToneMS > (1<<30)) |
254 { | 251 { |
255 _delaySinceLastToneMS = 1000; | 252 _delaySinceLastToneMS = 1000; |
256 } | 253 } |
257 } | 254 } |
258 | 255 |
259 uint32_t | 256 uint32_t |
260 DtmfInband::DelaySinceLastTone() const | 257 DtmfInband::DelaySinceLastTone() const |
261 { | 258 { |
262 return _delaySinceLastToneMS; | 259 return _delaySinceLastToneMS; |
the sun
2016/01/21 13:07:28
Add CritScope to avoid TSAN warnings?
tommi
2016/01/21 15:29:23
Done.
| |
263 } | 260 } |
264 | 261 |
265 int16_t | 262 int16_t |
266 DtmfInband::DtmfFix_generate(int16_t *decoded, | 263 DtmfInband::DtmfFix_generate(int16_t *decoded, |
267 int16_t value, | 264 int16_t value, |
268 int16_t volume, | 265 int16_t volume, |
269 int16_t frameLen, | 266 int16_t frameLen, |
270 int16_t fs) | 267 int16_t fs) |
271 { | 268 { |
272 const int16_t *a_times2Tbl; | 269 const int16_t *a_times2Tbl; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
381 tempVal=(tempVal+16384)>>15; | 378 tempVal=(tempVal+16384)>>15; |
382 | 379 |
383 /* Scale the signal to correct dbM0 value */ | 380 /* Scale the signal to correct dbM0 value */ |
384 signal[i]=(int16_t)((tempVal*Dtmf_dBm0kHz[volume]+8192)>>14); | 381 signal[i]=(int16_t)((tempVal*Dtmf_dBm0kHz[volume]+8192)>>14); |
385 } | 382 } |
386 | 383 |
387 return(0); | 384 return(0); |
388 } | 385 } |
389 | 386 |
390 } // namespace webrtc | 387 } // namespace webrtc |
OLD | NEW |