Chromium Code Reviews| 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 |