| 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 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 "OutputMixer::Create() unable to allocate memory for" | 86 "OutputMixer::Create() unable to allocate memory for" |
| 87 "mixer"); | 87 "mixer"); |
| 88 return -1; | 88 return -1; |
| 89 } | 89 } |
| 90 return 0; | 90 return 0; |
| 91 } | 91 } |
| 92 | 92 |
| 93 OutputMixer::OutputMixer(uint32_t instanceId) : | 93 OutputMixer::OutputMixer(uint32_t instanceId) : |
| 94 _mixerModule(*AudioConferenceMixer::Create(instanceId)), | 94 _mixerModule(*AudioConferenceMixer::Create(instanceId)), |
| 95 _audioLevel(), | 95 _audioLevel(), |
| 96 _dtmfGenerator(instanceId), | |
| 97 _instanceId(instanceId), | 96 _instanceId(instanceId), |
| 98 _externalMediaCallbackPtr(NULL), | 97 _externalMediaCallbackPtr(NULL), |
| 99 _externalMedia(false), | 98 _externalMedia(false), |
| 100 _panLeft(1.0f), | 99 _panLeft(1.0f), |
| 101 _panRight(1.0f), | 100 _panRight(1.0f), |
| 102 _mixingFrequencyHz(8000), | 101 _mixingFrequencyHz(8000), |
| 103 _outputFileRecorderPtr(NULL), | 102 _outputFileRecorderPtr(NULL), |
| 104 _outputFileRecording(false) | 103 _outputFileRecording(false) |
| 105 { | 104 { |
| 106 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,-1), | 105 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,-1), |
| 107 "OutputMixer::OutputMixer() - ctor"); | 106 "OutputMixer::OutputMixer() - ctor"); |
| 108 | 107 |
| 109 if (_mixerModule.RegisterMixedStreamCallback(this) == -1) | 108 if (_mixerModule.RegisterMixedStreamCallback(this) == -1) |
| 110 { | 109 { |
| 111 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,-1), | 110 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,-1), |
| 112 "OutputMixer::OutputMixer() failed to register mixer" | 111 "OutputMixer::OutputMixer() failed to register mixer" |
| 113 "callbacks"); | 112 "callbacks"); |
| 114 } | 113 } |
| 115 | |
| 116 _dtmfGenerator.Init(); | |
| 117 } | 114 } |
| 118 | 115 |
| 119 void | 116 void |
| 120 OutputMixer::Destroy(OutputMixer*& mixer) | 117 OutputMixer::Destroy(OutputMixer*& mixer) |
| 121 { | 118 { |
| 122 if (mixer) | 119 if (mixer) |
| 123 { | 120 { |
| 124 delete mixer; | 121 delete mixer; |
| 125 mixer = NULL; | 122 mixer = NULL; |
| 126 } | 123 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,-1), | 182 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,-1), |
| 186 "OutputMixer::DeRegisterExternalMediaProcessing()"); | 183 "OutputMixer::DeRegisterExternalMediaProcessing()"); |
| 187 | 184 |
| 188 rtc::CritScope cs(&_callbackCritSect); | 185 rtc::CritScope cs(&_callbackCritSect); |
| 189 _externalMedia = false; | 186 _externalMedia = false; |
| 190 _externalMediaCallbackPtr = NULL; | 187 _externalMediaCallbackPtr = NULL; |
| 191 | 188 |
| 192 return 0; | 189 return 0; |
| 193 } | 190 } |
| 194 | 191 |
| 195 int OutputMixer::PlayDtmfTone(uint8_t eventCode, int lengthMs, | |
| 196 int attenuationDb) | |
| 197 { | |
| 198 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), | |
| 199 "OutputMixer::PlayDtmfTone()"); | |
| 200 if (_dtmfGenerator.AddTone(eventCode, lengthMs, attenuationDb) != 0) | |
| 201 { | |
| 202 _engineStatisticsPtr->SetLastError(VE_STILL_PLAYING_PREV_DTMF, | |
| 203 kTraceError, | |
| 204 "OutputMixer::PlayDtmfTone()"); | |
| 205 return -1; | |
| 206 } | |
| 207 return 0; | |
| 208 } | |
| 209 | |
| 210 int32_t | 192 int32_t |
| 211 OutputMixer::SetMixabilityStatus(MixerParticipant& participant, | 193 OutputMixer::SetMixabilityStatus(MixerParticipant& participant, |
| 212 bool mixable) | 194 bool mixable) |
| 213 { | 195 { |
| 214 return _mixerModule.SetMixabilityStatus(&participant, mixable); | 196 return _mixerModule.SetMixabilityStatus(&participant, mixable); |
| 215 } | 197 } |
| 216 | 198 |
| 217 int32_t | 199 int32_t |
| 218 OutputMixer::SetAnonymousMixabilityStatus(MixerParticipant& participant, | 200 OutputMixer::SetAnonymousMixabilityStatus(MixerParticipant& participant, |
| 219 bool mixable) | 201 bool mixable) |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 OutputMixer::DoOperationsOnCombinedSignal(bool feed_data_to_apm) | 467 OutputMixer::DoOperationsOnCombinedSignal(bool feed_data_to_apm) |
| 486 { | 468 { |
| 487 if (_audioFrame.sample_rate_hz_ != _mixingFrequencyHz) | 469 if (_audioFrame.sample_rate_hz_ != _mixingFrequencyHz) |
| 488 { | 470 { |
| 489 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,-1), | 471 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,-1), |
| 490 "OutputMixer::DoOperationsOnCombinedSignal() => " | 472 "OutputMixer::DoOperationsOnCombinedSignal() => " |
| 491 "mixing frequency = %d", _audioFrame.sample_rate_hz_); | 473 "mixing frequency = %d", _audioFrame.sample_rate_hz_); |
| 492 _mixingFrequencyHz = _audioFrame.sample_rate_hz_; | 474 _mixingFrequencyHz = _audioFrame.sample_rate_hz_; |
| 493 } | 475 } |
| 494 | 476 |
| 495 // --- Insert inband Dtmf tone | |
| 496 if (_dtmfGenerator.IsAddingTone()) | |
| 497 { | |
| 498 InsertInbandDtmfTone(); | |
| 499 } | |
| 500 | |
| 501 // Scale left and/or right channel(s) if balance is active | 477 // Scale left and/or right channel(s) if balance is active |
| 502 if (_panLeft != 1.0 || _panRight != 1.0) | 478 if (_panLeft != 1.0 || _panRight != 1.0) |
| 503 { | 479 { |
| 504 if (_audioFrame.num_channels_ == 1) | 480 if (_audioFrame.num_channels_ == 1) |
| 505 { | 481 { |
| 506 AudioFrameOperations::MonoToStereo(&_audioFrame); | 482 AudioFrameOperations::MonoToStereo(&_audioFrame); |
| 507 } | 483 } |
| 508 else | 484 else |
| 509 { | 485 { |
| 510 // Pure stereo mode (we are receiving a stereo signal). | 486 // Pure stereo mode (we are receiving a stereo signal). |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 is_stereo); | 523 is_stereo); |
| 548 } | 524 } |
| 549 } | 525 } |
| 550 } | 526 } |
| 551 | 527 |
| 552 // --- Measure audio level (0-9) for the combined signal | 528 // --- Measure audio level (0-9) for the combined signal |
| 553 _audioLevel.ComputeLevel(_audioFrame); | 529 _audioLevel.ComputeLevel(_audioFrame); |
| 554 | 530 |
| 555 return 0; | 531 return 0; |
| 556 } | 532 } |
| 557 | |
| 558 // ---------------------------------------------------------------------------- | |
| 559 // Private methods | |
| 560 // ---------------------------------------------------------------------------- | |
| 561 | |
| 562 int | |
| 563 OutputMixer::InsertInbandDtmfTone() | |
| 564 { | |
| 565 uint16_t sampleRate(0); | |
| 566 _dtmfGenerator.GetSampleRate(sampleRate); | |
| 567 if (sampleRate != _audioFrame.sample_rate_hz_) | |
| 568 { | |
| 569 // Update sample rate of Dtmf tone since the mixing frequency changed. | |
| 570 _dtmfGenerator.SetSampleRate( | |
| 571 (uint16_t)(_audioFrame.sample_rate_hz_)); | |
| 572 // Reset the tone to be added taking the new sample rate into account. | |
| 573 _dtmfGenerator.ResetTone(); | |
| 574 } | |
| 575 | |
| 576 int16_t toneBuffer[320]; | |
| 577 uint16_t toneSamples(0); | |
| 578 if (_dtmfGenerator.Get10msTone(toneBuffer, toneSamples) == -1) | |
| 579 { | |
| 580 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1), | |
| 581 "OutputMixer::InsertInbandDtmfTone() inserting Dtmf" | |
| 582 "tone failed"); | |
| 583 return -1; | |
| 584 } | |
| 585 | |
| 586 // replace mixed audio with Dtmf tone | |
| 587 if (_audioFrame.num_channels_ == 1) | |
| 588 { | |
| 589 // mono | |
| 590 memcpy(_audioFrame.data_, toneBuffer, sizeof(int16_t) | |
| 591 * toneSamples); | |
| 592 } else | |
| 593 { | |
| 594 // stereo | |
| 595 for (size_t i = 0; i < _audioFrame.samples_per_channel_; i++) | |
| 596 { | |
| 597 _audioFrame.data_[2 * i] = toneBuffer[i]; | |
| 598 _audioFrame.data_[2 * i + 1] = 0; | |
| 599 } | |
| 600 } | |
| 601 assert(_audioFrame.samples_per_channel_ == toneSamples); | |
| 602 | |
| 603 return 0; | |
| 604 } | |
| 605 | |
| 606 } // namespace voe | 533 } // namespace voe |
| 607 } // namespace webrtc | 534 } // namespace webrtc |
| OLD | NEW |