1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/voice_engine/voe_base_impl.h" 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 13b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org#include "webrtc/common.h" 14471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" 15471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h" 16471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/modules/audio_device/audio_device_impl.h" 17471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/modules/audio_processing/include/audio_processing.h" 18471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 19471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/system_wrappers/interface/file_wrapper.h" 20471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/system_wrappers/interface/trace.h" 21471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/voice_engine/channel.h" 22471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/voice_engine/include/voe_errors.h" 23471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/voice_engine/output_mixer.h" 24471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/voice_engine/transmit_mixer.h" 25471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/voice_engine/utility.h" 26471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/voice_engine/voice_engine_impl.h" 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVoEBase* VoEBase::GetInterface(VoiceEngine* voiceEngine) 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (NULL == voiceEngine) 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return NULL; 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 37b9e5a3d589349ee55e41cb54eca4ec822018f5c5tommi@webrtc.org VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine); 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org s->AddRef(); 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return s; 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVoEBaseImpl::VoEBaseImpl(voe::SharedData* shared) : 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _voiceEngineObserverPtr(NULL), 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _callbackCritSect(*CriticalSectionWrapper::CreateCriticalSection()), 45ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org _voiceEngineObserver(false), _shared(shared) 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1), 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "VoEBaseImpl() - ctor"); 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVoEBaseImpl::~VoEBaseImpl() 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1), 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "~VoEBaseImpl() - dtor"); 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org TerminateInternal(); 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete &_callbackCritSect; 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 61ca7a9a2696d2f73f543241093c4faeb4c608678cpbos@webrtc.orgvoid VoEBaseImpl::OnErrorIsReported(ErrorCode error) 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_voiceEngineObserver) 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_voiceEngineObserverPtr) 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int errCode(0); 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (error == AudioDeviceObserver::kRecordingError) 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org errCode = VE_RUNTIME_REC_ERROR; 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VoEId(_shared->instance_id(), -1), 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "VoEBaseImpl::OnErrorIsReported() => VE_RUNTIME_REC_ERROR"); 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (error == AudioDeviceObserver::kPlayoutError) 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org errCode = VE_RUNTIME_PLAY_ERROR; 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VoEId(_shared->instance_id(), -1), 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "VoEBaseImpl::OnErrorIsReported() => " 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "VE_RUNTIME_PLAY_ERROR"); 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Deliver callback (-1 <=> no channel dependency) 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _voiceEngineObserverPtr->CallbackOnError(-1, errCode); 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 90ca7a9a2696d2f73f543241093c4faeb4c608678cpbos@webrtc.orgvoid VoEBaseImpl::OnWarningIsReported(WarningCode warning) 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_voiceEngineObserver) 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_voiceEngineObserverPtr) 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int warningCode(0); 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (warning == AudioDeviceObserver::kRecordingWarning) 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org warningCode = VE_RUNTIME_REC_WARNING; 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VoEId(_shared->instance_id(), -1), 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "VoEBaseImpl::OnErrorIsReported() => " 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "VE_RUNTIME_REC_WARNING"); 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (warning == AudioDeviceObserver::kPlayoutWarning) 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org warningCode = VE_RUNTIME_PLAY_WARNING; 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VoEId(_shared->instance_id(), -1), 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "VoEBaseImpl::OnErrorIsReported() => " 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "VE_RUNTIME_PLAY_WARNING"); 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Deliver callback (-1 <=> no channel dependency) 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _voiceEngineObserverPtr->CallbackOnError(-1, warningCode); 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 12054f03bc96c30337a3a97af7262cfb5148063b162pbos@webrtc.orgint32_t VoEBaseImpl::RecordedDataIsAvailable( 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const void* audioSamples, 122ca7a9a2696d2f73f543241093c4faeb4c608678cpbos@webrtc.org uint32_t nSamples, 123ca7a9a2696d2f73f543241093c4faeb4c608678cpbos@webrtc.org uint8_t nBytesPerSample, 124ca7a9a2696d2f73f543241093c4faeb4c608678cpbos@webrtc.org uint8_t nChannels, 125ca7a9a2696d2f73f543241093c4faeb4c608678cpbos@webrtc.org uint32_t samplesPerSec, 126ca7a9a2696d2f73f543241093c4faeb4c608678cpbos@webrtc.org uint32_t totalDelayMS, 127ca7a9a2696d2f73f543241093c4faeb4c608678cpbos@webrtc.org int32_t clockDrift, 128ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org uint32_t micLevel, 129ca7a9a2696d2f73f543241093c4faeb4c608678cpbos@webrtc.org bool keyPressed, 13054f03bc96c30337a3a97af7262cfb5148063b162pbos@webrtc.org uint32_t& newMicLevel) 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_shared->instance_id(), -1), 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "VoEBaseImpl::RecordedDataIsAvailable(nSamples=%u, " 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "nBytesPerSample=%u, nChannels=%u, samplesPerSec=%u, " 135ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org "totalDelayMS=%u, clockDrift=%d, micLevel=%u)", 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nSamples, nBytesPerSample, nChannels, samplesPerSec, 137ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org totalDelayMS, clockDrift, micLevel); 1380e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org newMicLevel = static_cast<uint32_t>(ProcessRecordedDataWithAPM( 1390e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org NULL, 0, audioSamples, samplesPerSec, nChannels, nSamples, 140ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org totalDelayMS, clockDrift, micLevel, keyPressed)); 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 14554f03bc96c30337a3a97af7262cfb5148063b162pbos@webrtc.orgint32_t VoEBaseImpl::NeedMorePlayData( 146ca7a9a2696d2f73f543241093c4faeb4c608678cpbos@webrtc.org uint32_t nSamples, 147ca7a9a2696d2f73f543241093c4faeb4c608678cpbos@webrtc.org uint8_t nBytesPerSample, 148ca7a9a2696d2f73f543241093c4faeb4c608678cpbos@webrtc.org uint8_t nChannels, 149ca7a9a2696d2f73f543241093c4faeb4c608678cpbos@webrtc.org uint32_t samplesPerSec, 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void* audioSamples, 15122f69bd27abc89979460df6d01de8685cb058aabwu@webrtc.org uint32_t& nSamplesOut, 15281f8df9af96c6b4bf43234f2a0162146a5da6112wu@webrtc.org int64_t* elapsed_time_ms, 15322f69bd27abc89979460df6d01de8685cb058aabwu@webrtc.org int64_t* ntp_time_ms) 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 15591d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_shared->instance_id(), -1), 15691d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org "VoEBaseImpl::NeedMorePlayData(nSamples=%u, " 15791d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org "nBytesPerSample=%d, nChannels=%d, samplesPerSec=%u)", 15891d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org nSamples, nBytesPerSample, nChannels, samplesPerSec); 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 16091d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org GetPlayoutData(static_cast<int>(samplesPerSec), 16191d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org static_cast<int>(nChannels), 16222f69bd27abc89979460df6d01de8685cb058aabwu@webrtc.org static_cast<int>(nSamples), true, audioSamples, 16381f8df9af96c6b4bf43234f2a0162146a5da6112wu@webrtc.org elapsed_time_ms, ntp_time_ms); 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 16591d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org nSamplesOut = _audioFrame.samples_per_channel_; 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 16791d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org return 0; 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1700e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.orgint VoEBaseImpl::OnDataAvailable(const int voe_channels[], 17144f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org int number_of_voe_channels, 17244f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org const int16_t* audio_data, 17344f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org int sample_rate, 17444f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org int number_of_channels, 17544f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org int number_of_frames, 17644f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org int audio_delay_milliseconds, 177ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org int volume, 17844f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org bool key_pressed, 17944f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org bool need_audio_processing) { 18044f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_shared->instance_id(), -1), 18144f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org "VoEBaseImpl::OnDataAvailable(number_of_voe_channels=%d, " 18244f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org "sample_rate=%d, number_of_channels=%d, number_of_frames=%d, " 183ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org "audio_delay_milliseconds=%d, volume=%d, " 18444f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org "key_pressed=%d, need_audio_processing=%d)", 18544f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org number_of_voe_channels, sample_rate, number_of_channels, 186ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org number_of_frames, audio_delay_milliseconds, volume, 18744f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org key_pressed, need_audio_processing); 1880e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org if (number_of_voe_channels == 0) 1890e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org return 0; 19044f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org 19144f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org if (need_audio_processing) { 1920e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org return ProcessRecordedDataWithAPM( 1930e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org voe_channels, number_of_voe_channels, audio_data, sample_rate, 1940e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org number_of_channels, number_of_frames, audio_delay_milliseconds, 195ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org 0, volume, key_pressed); 19644f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org } 19744f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org 19844f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org // No need to go through the APM, demultiplex the data to each VoE channel, 19944f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org // encode and send to the network. 20044f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org for (int i = 0; i < number_of_voe_channels; ++i) { 201f7c73b531c9f2aca2adb87044613a7b7fa94de84andrew@webrtc.org // TODO(ajm): In the case where multiple channels are using the same codec 202f7c73b531c9f2aca2adb87044613a7b7fa94de84andrew@webrtc.org // rate, this path needlessly does extra conversions. We should convert once 203f7c73b531c9f2aca2adb87044613a7b7fa94de84andrew@webrtc.org // and share between channels. 20491d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org PushCaptureData(voe_channels[i], audio_data, 16, sample_rate, 20591d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org number_of_channels, number_of_frames); 20644f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org } 20744f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org 20844f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org // Return 0 to indicate no need to change the volume. 20944f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org return 0; 21044f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org} 21144f1239d9595c91f69f656e5beb1382463c4da8fxians@webrtc.org 21287c8b86c9f8a9929a2a564b2833244c6290e4701xians@webrtc.orgvoid VoEBaseImpl::OnData(int voe_channel, const void* audio_data, 21387c8b86c9f8a9929a2a564b2833244c6290e4701xians@webrtc.org int bits_per_sample, int sample_rate, 21487c8b86c9f8a9929a2a564b2833244c6290e4701xians@webrtc.org int number_of_channels, 21587c8b86c9f8a9929a2a564b2833244c6290e4701xians@webrtc.org int number_of_frames) { 21691d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org PushCaptureData(voe_channel, audio_data, bits_per_sample, sample_rate, 21791d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org number_of_channels, number_of_frames); 21891d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org} 21991d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org 22091d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.orgvoid VoEBaseImpl::PushCaptureData(int voe_channel, const void* audio_data, 22191d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org int bits_per_sample, int sample_rate, 22291d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org int number_of_channels, 22391d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org int number_of_frames) { 224942ba53c7737740f4513cc658e51c41c8839a3a6xians@webrtc.org voe::ChannelOwner ch = _shared->channel_manager().GetChannel(voe_channel); 225942ba53c7737740f4513cc658e51c41c8839a3a6xians@webrtc.org voe::Channel* channel_ptr = ch.channel(); 226942ba53c7737740f4513cc658e51c41c8839a3a6xians@webrtc.org if (!channel_ptr) 227942ba53c7737740f4513cc658e51c41c8839a3a6xians@webrtc.org return; 228942ba53c7737740f4513cc658e51c41c8839a3a6xians@webrtc.org 229692224a58367e945336c7fd62376fcfa54497437henrika@webrtc.org if (channel_ptr->Sending()) { 230942ba53c7737740f4513cc658e51c41c8839a3a6xians@webrtc.org channel_ptr->Demultiplex(static_cast<const int16_t*>(audio_data), 231942ba53c7737740f4513cc658e51c41c8839a3a6xians@webrtc.org sample_rate, number_of_frames, number_of_channels); 232942ba53c7737740f4513cc658e51c41c8839a3a6xians@webrtc.org channel_ptr->PrepareEncodeAndSend(sample_rate); 233942ba53c7737740f4513cc658e51c41c8839a3a6xians@webrtc.org channel_ptr->EncodeAndSend(); 234942ba53c7737740f4513cc658e51c41c8839a3a6xians@webrtc.org } 235942ba53c7737740f4513cc658e51c41c8839a3a6xians@webrtc.org} 236942ba53c7737740f4513cc658e51c41c8839a3a6xians@webrtc.org 23791d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.orgvoid VoEBaseImpl::PullRenderData(int bits_per_sample, int sample_rate, 23891d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org int number_of_channels, int number_of_frames, 23922f69bd27abc89979460df6d01de8685cb058aabwu@webrtc.org void* audio_data, 24081f8df9af96c6b4bf43234f2a0162146a5da6112wu@webrtc.org int64_t* elapsed_time_ms, 24122f69bd27abc89979460df6d01de8685cb058aabwu@webrtc.org int64_t* ntp_time_ms) { 24291d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org assert(bits_per_sample == 16); 24391d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org assert(number_of_frames == static_cast<int>(sample_rate / 100)); 24491d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org 24591d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org GetPlayoutData(sample_rate, number_of_channels, number_of_frames, false, 24681f8df9af96c6b4bf43234f2a0162146a5da6112wu@webrtc.org audio_data, elapsed_time_ms, ntp_time_ms); 24791d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org} 24891d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org 249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEBaseImpl::RegisterVoiceEngineObserver(VoiceEngineObserver& observer) 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "RegisterVoiceEngineObserver(observer=0x%d)", &observer); 253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_voiceEngineObserverPtr) 255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_INVALID_OPERATION, kTraceError, 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "RegisterVoiceEngineObserver() observer already enabled"); 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Register the observer in all active channels 262b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org for (voe::ChannelManager::Iterator it(&_shared->channel_manager()); 263b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org it.IsValid(); 264b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org it.Increment()) { 265b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org it.GetChannel()->RegisterVoiceEngineObserver(observer); 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 267b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->transmit_mixer()->RegisterVoiceEngineObserver(observer); 269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _voiceEngineObserverPtr = &observer; 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _voiceEngineObserver = true; 272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEBaseImpl::DeRegisterVoiceEngineObserver() 277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "DeRegisterVoiceEngineObserver()"); 280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_voiceEngineObserverPtr) 282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_INVALID_OPERATION, kTraceError, 284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "DeRegisterVoiceEngineObserver() observer already disabled"); 285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _voiceEngineObserver = false; 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _voiceEngineObserverPtr = NULL; 290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Deregister the observer in all active channels 292b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org for (voe::ChannelManager::Iterator it(&_shared->channel_manager()); 293b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org it.IsValid(); 294b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org it.Increment()) { 295b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org it.GetChannel()->DeRegisterVoiceEngineObserver(); 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 301b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.orgint VoEBaseImpl::Init(AudioDeviceModule* external_adm, 302b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org AudioProcessing* audioproc) 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Init(external_adm=0x%p)", external_adm); 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(_shared->crit_sec()); 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcSpl_Init(); 309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->statistics().Initialized()) 311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->process_thread()) 316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->process_thread()->Start() != 0) 318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_THREAD_ERROR, kTraceError, 320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Init() failed to start module process thread"); 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Create an internal ADM if the user has not added an external 326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // ADM implementation as input to Init(). 327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (external_adm == NULL) 328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Create the internal ADM implementation. 330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->set_audio_device(AudioDeviceModuleImpl::Create( 331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VoEId(_shared->instance_id(), -1), _shared->audio_device_layer())); 332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device() == NULL) 334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_NO_MEMORY, kTraceCritical, 336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Init() failed to create the ADM"); 337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Use the already existing external ADM implementation. 343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->set_audio_device(external_adm); 344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1), 345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "An external ADM implementation will be used in VoiceEngine"); 346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Register the ADM to the process thread, which will drive the error 349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // callback mechanism 350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->process_thread() && 351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->process_thread()->RegisterModule(_shared->audio_device()) != 0) 352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceError, 354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Init() failed to register the ADM"); 355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool available(false); 359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // -------------------- 361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reinitialize the ADM 362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Register the AudioObserver implementation 364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->RegisterEventObserver(this) != 0) { 365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceWarning, 366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Init() failed to register event observer for the ADM"); 367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Register the AudioTransport implementation 370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->RegisterAudioCallback(this) != 0) { 371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceWarning, 372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Init() failed to register audio callback for the ADM"); 373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // ADM initialization 376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->Init() != 0) 377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceError, 379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Init() failed to initialize the ADM"); 380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize the default speaker 384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->SetPlayoutDevice( 385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_VOICE_ENGINE_DEFAULT_DEVICE) != 0) 386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceInfo, 388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Init() failed to set the default output device"); 389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->InitSpeaker() != 0) 391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_CANNOT_ACCESS_SPEAKER_VOL, kTraceInfo, 393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Init() failed to initialize the speaker"); 394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize the default microphone 397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->SetRecordingDevice( 398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_VOICE_ENGINE_DEFAULT_DEVICE) != 0) 399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_SOUNDCARD_ERROR, kTraceInfo, 401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Init() failed to set the default input device"); 402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->InitMicrophone() != 0) 404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_CANNOT_ACCESS_MIC_VOL, kTraceInfo, 406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Init() failed to initialize the microphone"); 407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Set number of channels 410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->StereoPlayoutIsAvailable(&available) != 0) { 411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_SOUNDCARD_ERROR, kTraceWarning, 412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Init() failed to query stereo playout mode"); 413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->SetStereoPlayout(available) != 0) 415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_SOUNDCARD_ERROR, kTraceWarning, 417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Init() failed to set mono/stereo playout mode"); 418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // TODO(andrew): These functions don't tell us whether stereo recording 421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // is truly available. We simply set the AudioProcessing input to stereo 422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // here, because we have to wait until receiving the first frame to 423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // determine the actual number of channels anyway. 424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // 425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // These functions may be changed; tracked here: 426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // http://code.google.com/p/webrtc/issues/detail?id=204 427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->audio_device()->StereoRecordingIsAvailable(&available); 428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->SetStereoRecording(available) != 0) 429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_SOUNDCARD_ERROR, kTraceWarning, 431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Init() failed to set mono/stereo recording mode"); 432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 434b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org if (!audioproc) { 435b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org audioproc = AudioProcessing::Create(VoEId(_shared->instance_id(), -1)); 436b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org if (!audioproc) { 437b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org LOG(LS_ERROR) << "Failed to create AudioProcessing."; 438b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org _shared->SetLastError(VE_NO_MEMORY); 439b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org return -1; 440b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org } 441b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org } 442b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org _shared->set_audio_processing(audioproc); 443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 444b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org // Set the error state for any failures in this block. 445b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org _shared->SetLastError(VE_APM_ERROR); 446e06943f2aeb970e7c11070c327ab3b3264e2722fandrew@webrtc.org // Configure AudioProcessing components. 447b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org if (audioproc->high_pass_filter()->Enable(true) != 0) { 448b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org LOG_FERR1(LS_ERROR, high_pass_filter()->Enable, true); 449b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org return -1; 450b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org } 451b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org if (audioproc->echo_cancellation()->enable_drift_compensation(false) != 0) { 452b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org LOG_FERR1(LS_ERROR, enable_drift_compensation, false); 453b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org return -1; 454b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org } 455b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org if (audioproc->noise_suppression()->set_level(kDefaultNsMode) != 0) { 456b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org LOG_FERR1(LS_ERROR, noise_suppression()->set_level, kDefaultNsMode); 457b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org return -1; 458b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org } 459b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org GainControl* agc = audioproc->gain_control(); 460b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org if (agc->set_analog_level_limits(kMinVolumeLevel, kMaxVolumeLevel) != 0) { 461b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org LOG_FERR2(LS_ERROR, agc->set_analog_level_limits, kMinVolumeLevel, 462b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org kMaxVolumeLevel); 463b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org return -1; 464b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org } 465b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org if (agc->set_mode(kDefaultAgcMode) != 0) { 466b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org LOG_FERR1(LS_ERROR, agc->set_mode, kDefaultAgcMode); 467b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org return -1; 468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 469b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org if (agc->Enable(kDefaultAgcState) != 0) { 470b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org LOG_FERR1(LS_ERROR, agc->Enable, kDefaultAgcState); 471b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org return -1; 472b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org } 473b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org _shared->SetLastError(0); // Clear error state. 474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef WEBRTC_VOICE_ENGINE_AGC 476b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org bool agc_enabled = agc->mode() == GainControl::kAdaptiveAnalog && 477b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org agc->is_enabled(); 478b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org if (_shared->audio_device()->SetAGC(agc_enabled) != 0) { 479b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org LOG_FERR1(LS_ERROR, audio_device()->SetAGC, agc_enabled); 480b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR); 4810f919be3c4aeb12157d9bda58c765050fed1ebf8andrew@webrtc.org // TODO(ajm): No error return here due to 4820f919be3c4aeb12157d9bda58c765050fed1ebf8andrew@webrtc.org // https://code.google.com/p/webrtc/issues/detail?id=1464 483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return _shared->statistics().SetInitialized(); 487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEBaseImpl::Terminate() 490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Terminate()"); 493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(_shared->crit_sec()); 494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return TerminateInternal(); 495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 497b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.orgint VoEBaseImpl::CreateChannel() { 498b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 499b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org "CreateChannel()"); 500b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org CriticalSectionScoped cs(_shared->crit_sec()); 501b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org if (!_shared->statistics().Initialized()) { 502b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org _shared->SetLastError(VE_NOT_INITED, kTraceError); 503b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org return -1; 504b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org } 505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 506b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org voe::ChannelOwner channel_owner = _shared->channel_manager().CreateChannel(); 507b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org 508b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org return InitializeChannel(&channel_owner); 509b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org} 510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 511b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.orgint VoEBaseImpl::CreateChannel(const Config& config) { 512b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org CriticalSectionScoped cs(_shared->crit_sec()); 513b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org if (!_shared->statistics().Initialized()) { 514b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org _shared->SetLastError(VE_NOT_INITED, kTraceError); 515b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org return -1; 516b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org } 517b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org voe::ChannelOwner channel_owner = _shared->channel_manager().CreateChannel( 518b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org config); 519b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org return InitializeChannel(&channel_owner); 520b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org} 521b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org 522b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.orgint VoEBaseImpl::InitializeChannel(voe::ChannelOwner* channel_owner) 523b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org{ 524b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org if (channel_owner->channel()->SetEngineInformation( 525b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org _shared->statistics(), 526b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org *_shared->output_mixer(), 527b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org *_shared->transmit_mixer(), 528b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org *_shared->process_thread(), 529b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org *_shared->audio_device(), 530b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org _voiceEngineObserverPtr, 531b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org &_callbackCritSect) != 0) { 532b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org _shared->SetLastError( 533b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org VE_CHANNEL_NOT_CREATED, 534b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org kTraceError, 535b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org "CreateChannel() failed to associate engine and channel." 536b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org " Destroying channel."); 537b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org _shared->channel_manager() 538b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org .DestroyChannel(channel_owner->channel()->ChannelId()); 539b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org return -1; 540b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org } else if (channel_owner->channel()->Init() != 0) { 541b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org _shared->SetLastError( 542b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org VE_CHANNEL_NOT_CREATED, 543b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org kTraceError, 544b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org "CreateChannel() failed to initialize channel. Destroying" 545b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org " channel."); 546b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org _shared->channel_manager() 547b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org .DestroyChannel(channel_owner->channel()->ChannelId()); 548b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org return -1; 549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VoEId(_shared->instance_id(), -1), 553b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org "CreateChannel() => %d", channel_owner->channel()->ChannelId()); 554b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org return channel_owner->channel()->ChannelId(); 555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEBaseImpl::DeleteChannel(int channel) 558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "DeleteChannel(channel=%d)", channel); 561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(_shared->crit_sec()); 562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_shared->statistics().Initialized()) 564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_NOT_INITED, kTraceError); 566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 570b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 571b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::Channel* channelPtr = ch.channel(); 572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (channelPtr == NULL) 573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "DeleteChannel() failed to locate channel"); 576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 580b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org _shared->channel_manager().DestroyChannel(channel); 581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 582b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (StopSend() != 0) 583b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (StopPlayout() != 0) 588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 591912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org 592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEBaseImpl::StartReceive(int channel) 596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StartReceive(channel=%d)", channel); 599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(_shared->crit_sec()); 600b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_shared->statistics().Initialized()) 601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_NOT_INITED, kTraceError); 603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 605b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 606b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::Channel* channelPtr = ch.channel(); 607b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (channelPtr == NULL) 608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 609b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StartReceive() failed to locate channel"); 611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return channelPtr->StartReceiving(); 614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 616b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEBaseImpl::StopReceive(int channel) 617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StopListen(channel=%d)", channel); 620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(_shared->crit_sec()); 621b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_shared->statistics().Initialized()) 622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_NOT_INITED, kTraceError); 624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 626b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 627b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::Channel* channelPtr = ch.channel(); 628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (channelPtr == NULL) 629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "SetLocalReceiver() failed to locate channel"); 632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return channelPtr->StopReceiving(); 635b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEBaseImpl::StartPlayout(int channel) 638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 639b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StartPlayout(channel=%d)", channel); 641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(_shared->crit_sec()); 642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_shared->statistics().Initialized()) 643b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_NOT_INITED, kTraceError); 645b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 647b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 648b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::Channel* channelPtr = ch.channel(); 649b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (channelPtr == NULL) 650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StartPlayout() failed to locate channel"); 653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 654b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (channelPtr->Playing()) 656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (StartPlayout() != 0) 660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceError, 662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StartPlayout() failed to start playout"); 663b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 664b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 665b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return channelPtr->StartPlayout(); 666b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEBaseImpl::StopPlayout(int channel) 669b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 670b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 671b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StopPlayout(channel=%d)", channel); 672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(_shared->crit_sec()); 673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_shared->statistics().Initialized()) 674b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 675b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_NOT_INITED, kTraceError); 676b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 677b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 678b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 679b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::Channel* channelPtr = ch.channel(); 680b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (channelPtr == NULL) 681b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 682b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 683b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StopPlayout() failed to locate channel"); 684b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 685b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 686b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (channelPtr->StopPlayout() != 0) 687b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 688b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, 689b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VoEId(_shared->instance_id(), -1), 690b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StopPlayout() failed to stop playout for channel %d", channel); 691b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 692b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return StopPlayout(); 693b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 694b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 695b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEBaseImpl::StartSend(int channel) 696b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 697b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 698b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StartSend(channel=%d)", channel); 699b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(_shared->crit_sec()); 700b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_shared->statistics().Initialized()) 701b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 702b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_NOT_INITED, kTraceError); 703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 704b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 705b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 706b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::Channel* channelPtr = ch.channel(); 707b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (channelPtr == NULL) 708b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 709b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 710b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StartSend() failed to locate channel"); 711b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 712b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 713b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (channelPtr->Sending()) 714b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 715b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 716b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 717b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (StartSend() != 0) 718b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 719b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceError, 720b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StartSend() failed to start recording"); 721b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 722b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 723b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return channelPtr->StartSend(); 724b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 725b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 726b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEBaseImpl::StopSend(int channel) 727b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 728b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 729b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StopSend(channel=%d)", channel); 730b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(_shared->crit_sec()); 731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_shared->statistics().Initialized()) 732b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 733b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_NOT_INITED, kTraceError); 734b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 735b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 736b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 737b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org voe::Channel* channelPtr = ch.channel(); 738b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (channelPtr == NULL) 739b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 740b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 741b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StopSend() failed to locate channel"); 742b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 743b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 744b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (channelPtr->StopSend() != 0) 745b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 746b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, 747b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VoEId(_shared->instance_id(), -1), 748b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StopSend() failed to stop sending for channel %d", channel); 749b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 750b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return StopSend(); 751b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 752b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 753b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEBaseImpl::GetVersion(char version[1024]) 754b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 755b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 756b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "GetVersion(version=?)"); 757b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(kVoiceEngineVersionMaxMessageSize == 1024); 758b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 759b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (version == NULL) 760b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 761b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError); 762b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return (-1); 763b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 764b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 765b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org char versionBuf[kVoiceEngineVersionMaxMessageSize]; 766b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org char* versionPtr = versionBuf; 767b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 76854f03bc96c30337a3a97af7262cfb5148063b162pbos@webrtc.org int32_t len = 0; 76954f03bc96c30337a3a97af7262cfb5148063b162pbos@webrtc.org int32_t accLen = 0; 770b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 771b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org len = AddVoEVersion(versionPtr); 772b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (len == -1) 773b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 774b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 775b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 776b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org versionPtr += len; 777b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org accLen += len; 778b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(accLen < kVoiceEngineVersionMaxMessageSize); 779b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 780b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org len = AddBuildInfo(versionPtr); 781b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (len == -1) 782b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 783b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 784b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 785b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org versionPtr += len; 786b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org accLen += len; 787b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(accLen < kVoiceEngineVersionMaxMessageSize); 788b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 789912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org#ifdef WEBRTC_EXTERNAL_TRANSPORT 790912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org len = AddExternalTransportBuild(versionPtr); 791912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org if (len == -1) 792912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org { 793912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org return -1; 794912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org } 795912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org versionPtr += len; 796912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org accLen += len; 797912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org assert(accLen < kVoiceEngineVersionMaxMessageSize); 798912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org#endif 799b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 800b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(version, versionBuf, accLen); 801b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org version[accLen] = '\0'; 802b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 803b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // to avoid the truncation in the trace, split the string into parts 804b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org char partOfVersion[256]; 805b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 806b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VoEId(_shared->instance_id(), -1), "GetVersion() =>"); 807b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int partStart = 0; partStart < accLen;) 808b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 809b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(partOfVersion, 0, sizeof(partOfVersion)); 810b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int partEnd = partStart + 180; 811b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (version[partEnd] != '\n' && version[partEnd] != '\0') 812b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 813b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org partEnd--; 814b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 815b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (partEnd < accLen) 816b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 817b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(partOfVersion, &version[partStart], partEnd - partStart); 818b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 819b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 820b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 821b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(partOfVersion, &version[partStart], accLen - partStart); 822b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 823b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org partStart = partEnd; 824b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 825b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VoEId(_shared->instance_id(), -1), "%s", partOfVersion); 826b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 827b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 828b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 829b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 830b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 83154f03bc96c30337a3a97af7262cfb5148063b162pbos@webrtc.orgint32_t VoEBaseImpl::AddBuildInfo(char* str) const 832b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 833c7d736366468e04cd818fd74ee4844b954012614andrew@webrtc.org return sprintf(str, "Build: %s\n", BUILDINFO); 834b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 835b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 83654f03bc96c30337a3a97af7262cfb5148063b162pbos@webrtc.orgint32_t VoEBaseImpl::AddVoEVersion(char* str) const 837b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 838b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return sprintf(str, "VoiceEngine 4.1.0\n"); 839b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 840b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 841912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org#ifdef WEBRTC_EXTERNAL_TRANSPORT 84254f03bc96c30337a3a97af7262cfb5148063b162pbos@webrtc.orgint32_t VoEBaseImpl::AddExternalTransportBuild(char* str) const 843912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org{ 844912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org return sprintf(str, "External transport build\n"); 845912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org} 846912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org#endif 847912b7f727086279bfa950dce96953fe018f49580pwestin@webrtc.org 848b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoEBaseImpl::LastError() 849b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 850b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 851b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "LastError()"); 852b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return (_shared->statistics().LastError()); 853b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 854b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 85554f03bc96c30337a3a97af7262cfb5148063b162pbos@webrtc.orgint32_t VoEBaseImpl::StartPlayout() 856b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 857b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1), 858b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "VoEBaseImpl::StartPlayout()"); 859b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->Playing()) 860b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 861b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 862b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 863b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_shared->ext_playout()) 864b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 865b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->InitPlayout() != 0) 866b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 867b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceError, kTraceVoice, 868b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VoEId(_shared->instance_id(), -1), 869b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StartPlayout() failed to initialize playout"); 870b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 871b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 872b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->StartPlayout() != 0) 873b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 874b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceError, kTraceVoice, 875b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VoEId(_shared->instance_id(), -1), 876b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StartPlayout() failed to start playout"); 877b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 878b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 879b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 880b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 881b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 882b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 883b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgint32_t VoEBaseImpl::StopPlayout() { 884b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org WEBRTC_TRACE(kTraceInfo, 885b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org kTraceVoice, 886b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org VoEId(_shared->instance_id(), -1), 887b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org "VoEBaseImpl::StopPlayout()"); 888b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org // Stop audio-device playing if no channel is playing out 8893d553d4203f945029900c85c0e402e598fef4361xians@webrtc.org if (_shared->NumOfPlayingChannels() == 0) { 890b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org if (_shared->audio_device()->StopPlayout() != 0) { 891b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org _shared->SetLastError(VE_CANNOT_STOP_PLAYOUT, 892b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org kTraceError, 893b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org "StopPlayout() failed to stop playout"); 894b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org return -1; 895b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 896b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org } 897b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org return 0; 898b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 899b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 90054f03bc96c30337a3a97af7262cfb5148063b162pbos@webrtc.orgint32_t VoEBaseImpl::StartSend() 901b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 902b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1), 903b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "VoEBaseImpl::StartSend()"); 904b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->Recording()) 905b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 906b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 907b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 908b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!_shared->ext_recording()) 909b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 910b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->InitRecording() != 0) 911b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 912b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceError, kTraceVoice, 913b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VoEId(_shared->instance_id(), -1), 914b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StartSend() failed to initialize recording"); 915b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 916b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 917b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->StartRecording() != 0) 918b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 919b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceError, kTraceVoice, 920b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VoEId(_shared->instance_id(), -1), 921b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StartSend() failed to start recording"); 922b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 923b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 924b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 925b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 926b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 927b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 928b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 92954f03bc96c30337a3a97af7262cfb5148063b162pbos@webrtc.orgint32_t VoEBaseImpl::StopSend() 930b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 931b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1), 932b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "VoEBaseImpl::StopSend()"); 933b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 934b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->NumOfSendingChannels() == 0 && 935b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org !_shared->transmit_mixer()->IsRecordingMic()) 936b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 937b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Stop audio-device recording if no channel is recording 938b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->StopRecording() != 0) 939b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 940b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_CANNOT_STOP_RECORDING, kTraceError, 941b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "StopSend() failed to stop recording"); 942b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 943b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 944b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->transmit_mixer()->StopSend(); 945b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 946b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 947b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 948b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 949b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 95054f03bc96c30337a3a97af7262cfb5148063b162pbos@webrtc.orgint32_t VoEBaseImpl::TerminateInternal() 951b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 952b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1), 953b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "VoEBaseImpl::TerminateInternal()"); 954b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 955b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Delete any remaining channel objects 956b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org _shared->channel_manager().DestroyAllChannels(); 957b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 958b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->process_thread()) 959b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 960b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()) 961b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 962b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->process_thread()-> 963b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org DeRegisterModule(_shared->audio_device()) != 0) 964b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 965b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_THREAD_ERROR, kTraceError, 966b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "TerminateInternal() failed to deregister ADM"); 967b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 968b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 969b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->process_thread()->Stop() != 0) 970b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 971b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_THREAD_ERROR, kTraceError, 972b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "TerminateInternal() failed to stop module process thread"); 973b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 974b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 975b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 976b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org if (_shared->audio_device()) 977b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 978b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->StopPlayout() != 0) 979b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 980b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_SOUNDCARD_ERROR, kTraceWarning, 981b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "TerminateInternal() failed to stop playout"); 982b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 983b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->StopRecording() != 0) 984b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 985b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_SOUNDCARD_ERROR, kTraceWarning, 986b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "TerminateInternal() failed to stop recording"); 987b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 988b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->RegisterEventObserver(NULL) != 0) { 989b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceWarning, 990b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "TerminateInternal() failed to de-register event observer " 991b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "for the ADM"); 992b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 993b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->RegisterAudioCallback(NULL) != 0) { 994b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceWarning, 995b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "TerminateInternal() failed to de-register audio callback " 996b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "for the ADM"); 997b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 998b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_shared->audio_device()->Terminate() != 0) 999b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 1000b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceError, 1001b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "TerminateInternal() failed to terminate the ADM"); 1002b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1003b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->set_audio_device(NULL); 1004b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1005b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1006b79627b0f3cf072721f3ae4a584a4f90edba2d1bandrew@webrtc.org if (_shared->audio_processing()) { 1007b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _shared->set_audio_processing(NULL); 1008b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1009b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1010b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return _shared->statistics().SetUnInitialized(); 1011b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1012b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 10130e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.orgint VoEBaseImpl::ProcessRecordedDataWithAPM( 10140e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org const int voe_channels[], 10150e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org int number_of_voe_channels, 10160e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org const void* audio_data, 10170e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org uint32_t sample_rate, 10180e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org uint8_t number_of_channels, 10190e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org uint32_t number_of_frames, 10200e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org uint32_t audio_delay_milliseconds, 10210e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org int32_t clock_drift, 1022ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org uint32_t volume, 10230e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org bool key_pressed) { 10240e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org assert(_shared->transmit_mixer() != NULL); 10250e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org assert(_shared->audio_device() != NULL); 10260e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org 10270e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org uint32_t max_volume = 0; 1028ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org uint16_t voe_mic_level = 0; 102922470b5ee6298ed0fe8209563758ec171a1c4397andrew@webrtc.org // Check for zero to skip this calculation; the consumer may use this to 103022470b5ee6298ed0fe8209563758ec171a1c4397andrew@webrtc.org // indicate no volume is available. 1031ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org if (volume != 0) { 10320e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org // Scale from ADM to VoE level range 10330e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org if (_shared->audio_device()->MaxMicrophoneVolume(&max_volume) == 0) { 10340e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org if (max_volume) { 1035ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org voe_mic_level = static_cast<uint16_t>( 1036ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org (volume * kMaxVolumeLevel + 10370e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org static_cast<int>(max_volume / 2)) / max_volume); 10380e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org } 10390e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org } 1040ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org // We learned that on certain systems (e.g Linux) the voe_mic_level 10410e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org // can be greater than the maxVolumeLevel therefore 1042ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org // we are going to cap the voe_mic_level to the maxVolumeLevel 1043ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org // and change the maxVolume to volume if it turns out that 1044ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org // the voe_mic_level is indeed greater than the maxVolumeLevel. 1045ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org if (voe_mic_level > kMaxVolumeLevel) { 1046ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org voe_mic_level = kMaxVolumeLevel; 1047ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org max_volume = volume; 10480e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org } 10490e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org } 10500e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org 10510e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org // Perform channel-independent operations 10520e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org // (APM, mix with file, record to file, mute, etc.) 10530e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org _shared->transmit_mixer()->PrepareDemux( 10540e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org audio_data, number_of_frames, number_of_channels, sample_rate, 10550e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org static_cast<uint16_t>(audio_delay_milliseconds), clock_drift, 1056ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org voe_mic_level, key_pressed); 10570e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org 10580e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org // Copy the audio frame to each sending channel and perform 10590e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org // channel-dependent operations (file mixing, mute, etc.), encode and 10600e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org // packetize+transmit the RTP packet. When |number_of_voe_channels| == 0, 10610e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org // do the operations on all the existing VoE channels; otherwise the 10620e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org // operations will be done on specific channels. 10630e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org if (number_of_voe_channels == 0) { 10640e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org _shared->transmit_mixer()->DemuxAndMix(); 10650e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org _shared->transmit_mixer()->EncodeAndSend(); 10660e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org } else { 10670e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org _shared->transmit_mixer()->DemuxAndMix(voe_channels, 10680e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org number_of_voe_channels); 10690e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org _shared->transmit_mixer()->EncodeAndSend(voe_channels, 10700e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org number_of_voe_channels); 10710e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org } 10720e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org 10730e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org // Scale from VoE to ADM level range. 10740e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org uint32_t new_voe_mic_level = _shared->transmit_mixer()->CaptureLevel(); 10750e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org 1076ad065d00af1d67641f9dbba6b6842d68daa714c1andrew@webrtc.org if (new_voe_mic_level != voe_mic_level) { 10770e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org // Return the new volume if AGC has changed the volume. 10780e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org return static_cast<int>( 10790e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org (new_voe_mic_level * max_volume + 10800e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org static_cast<int>(kMaxVolumeLevel / 2)) / kMaxVolumeLevel); 10810e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org } 10820e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org 10830e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org // Return 0 to indicate no change on the volume. 10840e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org return 0; 10850e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org} 10860e6fa8c05cde2587e30dcf5e405132193d60dd42xians@webrtc.org 108791d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.orgvoid VoEBaseImpl::GetPlayoutData(int sample_rate, int number_of_channels, 108891d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org int number_of_frames, bool feed_data_to_apm, 108922f69bd27abc89979460df6d01de8685cb058aabwu@webrtc.org void* audio_data, 109081f8df9af96c6b4bf43234f2a0162146a5da6112wu@webrtc.org int64_t* elapsed_time_ms, 109122f69bd27abc89979460df6d01de8685cb058aabwu@webrtc.org int64_t* ntp_time_ms) { 109291d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org assert(_shared->output_mixer() != NULL); 109391d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org 109491d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org // TODO(andrew): if the device is running in mono, we should tell the mixer 109591d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org // here so that it will only request mono from AudioCodingModule. 109691d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org // Perform mixing of all active participants (channel-based mixing) 109791d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org _shared->output_mixer()->MixActiveChannels(); 109891d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org 109991d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org // Additional operations on the combined signal 110091d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org _shared->output_mixer()->DoOperationsOnCombinedSignal(feed_data_to_apm); 110191d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org 110291d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org // Retrieve the final output mix (resampled to match the ADM) 110391d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org _shared->output_mixer()->GetMixedAudio(sample_rate, number_of_channels, 110491d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org &_audioFrame); 110591d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org 110691d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org assert(number_of_frames == _audioFrame.samples_per_channel_); 110791d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org assert(sample_rate == _audioFrame.sample_rate_hz_); 110891d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org 110991d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org // Deliver audio (PCM) samples to the ADM 111091d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org memcpy(audio_data, _audioFrame.data_, 111191d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org sizeof(int16_t) * number_of_frames * number_of_channels); 111222f69bd27abc89979460df6d01de8685cb058aabwu@webrtc.org 111381f8df9af96c6b4bf43234f2a0162146a5da6112wu@webrtc.org *elapsed_time_ms = _audioFrame.elapsed_time_ms_; 111422f69bd27abc89979460df6d01de8685cb058aabwu@webrtc.org *ntp_time_ms = _audioFrame.ntp_time_ms_; 111591d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org} 111691d88e1320d33fdc3648041bd941509e722f3ac4xians@webrtc.org 11173b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org} // namespace webrtc 1118