140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org/* 240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org * 440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org * Use of this source code is governed by a BSD-style license 540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org * in the file PATENTS. All contributing project authors may 840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org */ 1040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 1140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#include "webrtc/voice_engine/transmit_mixer.h" 1240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 13dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting#include "webrtc/base/format_macros.h" 14ad856229a796a8efa1126ef8aa8d238f2b0a2b21pbos#include "webrtc/base/logging.h" 15ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/utility/include/audio_frame_operations.h" 1698f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/critical_section_wrapper.h" 1798f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/event_wrapper.h" 1898f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/trace.h" 1940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#include "webrtc/voice_engine/channel.h" 2040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#include "webrtc/voice_engine/channel_manager.h" 2140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#include "webrtc/voice_engine/include/voe_external_media.h" 2240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#include "webrtc/voice_engine/statistics.h" 2340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#include "webrtc/voice_engine/utility.h" 2440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#include "webrtc/voice_engine/voe_base_impl.h" 2540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 2640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgnamespace webrtc { 2740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgnamespace voe { 2840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 2940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org// TODO(ajm): The thread safety of this is dubious... 3040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgvoid 3140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::OnPeriodicProcess() 3240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 3340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1), 3440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::OnPeriodicProcess()"); 3540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 3640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#if defined(WEBRTC_VOICE_ENGINE_TYPING_DETECTION) 37302c978c921c2c63e1ab2414f0db03d19d5bfc60solenberg bool send_typing_noise_warning = false; 38302c978c921c2c63e1ab2414f0db03d19d5bfc60solenberg bool typing_noise_detected = false; 3940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 40302c978c921c2c63e1ab2414f0db03d19d5bfc60solenberg CriticalSectionScoped cs(&_critSect); 41302c978c921c2c63e1ab2414f0db03d19d5bfc60solenberg if (_typingNoiseWarningPending) { 42302c978c921c2c63e1ab2414f0db03d19d5bfc60solenberg send_typing_noise_warning = true; 43302c978c921c2c63e1ab2414f0db03d19d5bfc60solenberg typing_noise_detected = _typingNoiseDetected; 44302c978c921c2c63e1ab2414f0db03d19d5bfc60solenberg _typingNoiseWarningPending = false; 45302c978c921c2c63e1ab2414f0db03d19d5bfc60solenberg } 46302c978c921c2c63e1ab2414f0db03d19d5bfc60solenberg } 47302c978c921c2c63e1ab2414f0db03d19d5bfc60solenberg if (send_typing_noise_warning) { 4840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 49302c978c921c2c63e1ab2414f0db03d19d5bfc60solenberg if (_voiceEngineObserverPtr) { 50302c978c921c2c63e1ab2414f0db03d19d5bfc60solenberg if (typing_noise_detected) { 5140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 5240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::OnPeriodicProcess() => " 5340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "CallbackOnError(VE_TYPING_NOISE_WARNING)"); 5440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _voiceEngineObserverPtr->CallbackOnError( 5540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org -1, 5640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_TYPING_NOISE_WARNING); 5740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } else { 5840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 5940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::OnPeriodicProcess() => " 6040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "CallbackOnError(VE_TYPING_NOISE_OFF_WARNING)"); 6140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _voiceEngineObserverPtr->CallbackOnError( 6240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org -1, 6340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_TYPING_NOISE_OFF_WARNING); 6440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 6540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 6640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 6740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#endif 6840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 6940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org bool saturationWarning = false; 7040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 7140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Modify |_saturationWarning| under lock to avoid conflict with write op 7240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // in ProcessAudio and also ensure that we don't hold the lock during the 7340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // callback. 7440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 7540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org saturationWarning = _saturationWarning; 7640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_saturationWarning) 7740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _saturationWarning = false; 7840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 7940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 8040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (saturationWarning) 8140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 8240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 8340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_voiceEngineObserverPtr) 8440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 8540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 8640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::OnPeriodicProcess() =>" 8740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org " CallbackOnError(VE_SATURATION_WARNING)"); 8840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _voiceEngineObserverPtr->CallbackOnError(-1, VE_SATURATION_WARNING); 8940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 9040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 9140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 9240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 9340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 9440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgvoid TransmitMixer::PlayNotification(int32_t id, 9540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org uint32_t durationMs) 9640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 9740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1), 9840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::PlayNotification(id=%d, durationMs=%d)", 9940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org id, durationMs); 10040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 10140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Not implement yet 10240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 10340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 10440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgvoid TransmitMixer::RecordNotification(int32_t id, 10540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org uint32_t durationMs) 10640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 10740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,-1), 10840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::RecordNotification(id=%d, durationMs=%d)", 10940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org id, durationMs); 11040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 11140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Not implement yet 11240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 11340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 11440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgvoid TransmitMixer::PlayFileEnded(int32_t id) 11540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 11640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1), 11740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::PlayFileEnded(id=%d)", id); 11840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 11940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org assert(id == _filePlayerId); 12040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 12140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 12240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 12340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlaying = false; 12440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1), 12540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::PlayFileEnded() =>" 12640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "file player module is shutdown"); 12740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 12840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 12940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgvoid 13040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::RecordFileEnded(int32_t id) 13140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 13240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1), 13340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::RecordFileEnded(id=%d)", id); 13440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 13540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (id == _fileRecorderId) 13640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 13740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 13840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecording = false; 13940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1), 14040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::RecordFileEnded() => fileRecorder module" 14140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "is shutdown"); 14240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } else if (id == _fileCallRecorderId) 14340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 14440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 14540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecording = false; 14640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1), 14740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::RecordFileEnded() => fileCallRecorder" 14840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "module is shutdown"); 14940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 15040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 15140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 15240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint32_t 15340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::Create(TransmitMixer*& mixer, uint32_t instanceId) 15440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 15540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId, -1), 15640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::Create(instanceId=%d)", instanceId); 15740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org mixer = new TransmitMixer(instanceId); 15840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (mixer == NULL) 15940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 16040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId, -1), 16140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::Create() unable to allocate memory" 16240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "for mixer"); 16340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 16440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 16540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 16640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 16740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 16840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgvoid 16940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::Destroy(TransmitMixer*& mixer) 17040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 17140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (mixer) 17240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 17340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org delete mixer; 17440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org mixer = NULL; 17540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 17640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 17740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 17840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::TransmitMixer(uint32_t instanceId) : 17940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr(NULL), 18040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _channelManagerPtr(NULL), 18140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org audioproc_(NULL), 18240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _voiceEngineObserverPtr(NULL), 18340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _processThreadPtr(NULL), 18440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr(NULL), 18540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr(NULL), 18640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr(NULL), 18740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Avoid conflict with other channels by adding 1024 - 1026, 18840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // won't use as much as 1024 channels. 18940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerId(instanceId + 1024), 19040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderId(instanceId + 1025), 19140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderId(instanceId + 1026), 19240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlaying(false), 19340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecording(false), 19440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecording(false), 19540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _audioLevel(), 19640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _critSect(*CriticalSectionWrapper::CreateCriticalSection()), 19740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _callbackCritSect(*CriticalSectionWrapper::CreateCriticalSection()), 19840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION 19940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _typingNoiseWarningPending(false), 20040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _typingNoiseDetected(false), 20140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#endif 20240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _saturationWarning(false), 20340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _instanceId(instanceId), 20440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _mixFileWithMicrophone(false), 20540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _captureLevel(0), 20640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org external_postproc_ptr_(NULL), 20740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org external_preproc_ptr_(NULL), 20840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _mute(false), 20940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _remainingMuteMicTimeMs(0), 21040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org stereo_codec_(false), 21140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org swap_stereo_channels_(false) 21240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 21340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1), 21440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::TransmitMixer() - ctor"); 21540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 21640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 21740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::~TransmitMixer() 21840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 21940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1), 22040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::~TransmitMixer() - dtor"); 22140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _monitorModule.DeRegisterObserver(); 22240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_processThreadPtr) 22340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 22440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _processThreadPtr->DeRegisterModule(&_monitorModule); 22540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 22640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org DeRegisterExternalMediaProcessing(kRecordingAllChannelsMixed); 22740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org DeRegisterExternalMediaProcessing(kRecordingPreprocessing); 22840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 22940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 23040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileRecorderPtr) 23140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 23240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr->RegisterModuleFileCallback(NULL); 23340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr->StopRecording(); 23440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileRecorder::DestroyFileRecorder(_fileRecorderPtr); 23540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr = NULL; 23640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 23740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileCallRecorderPtr) 23840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 23940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr->RegisterModuleFileCallback(NULL); 24040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr->StopRecording(); 24140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileRecorder::DestroyFileRecorder(_fileCallRecorderPtr); 24240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr = NULL; 24340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 24440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_filePlayerPtr) 24540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 24640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr->RegisterModuleFileCallback(NULL); 24740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr->StopPlayingFile(); 24840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FilePlayer::DestroyFilePlayer(_filePlayerPtr); 24940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr = NULL; 25040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 25140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 25240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org delete &_critSect; 25340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org delete &_callbackCritSect; 25440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 25540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 25640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint32_t 25740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::SetEngineInformation(ProcessThread& processThread, 25840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org Statistics& engineStatistics, 25940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org ChannelManager& channelManager) 26040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 26140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 26240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::SetEngineInformation()"); 26340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 26440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _processThreadPtr = &processThread; 26540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr = &engineStatistics; 26640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _channelManagerPtr = &channelManager; 26740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 2683985f0151aff9b91418733795a98140079c19a73tommi@webrtc.org _processThreadPtr->RegisterModule(&_monitorModule); 2693985f0151aff9b91418733795a98140079c19a73tommi@webrtc.org _monitorModule.RegisterObserver(*this); 27040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 27140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 27240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 27340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 27440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint32_t 27540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::RegisterVoiceEngineObserver(VoiceEngineObserver& observer) 27640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 27740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 27840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::RegisterVoiceEngineObserver()"); 27940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 28040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 28140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_voiceEngineObserverPtr) 28240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 28340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 28440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_INVALID_OPERATION, kTraceError, 28540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "RegisterVoiceEngineObserver() observer already enabled"); 28640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 28740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 28840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _voiceEngineObserverPtr = &observer; 28940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 29040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 29140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 29240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint32_t 29340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::SetAudioProcessingModule(AudioProcessing* audioProcessingModule) 29440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 29540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 29640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::SetAudioProcessingModule(" 29740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "audioProcessingModule=0x%x)", 29840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org audioProcessingModule); 29940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org audioproc_ = audioProcessingModule; 30040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 30140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 30240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 3036955870806624479723addfae6dcf5d13968796cPeter Kastingvoid TransmitMixer::GetSendCodecInfo(int* max_sample_rate, 3046955870806624479723addfae6dcf5d13968796cPeter Kasting size_t* max_channels) { 30540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org *max_sample_rate = 8000; 30640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org *max_channels = 1; 30740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org for (ChannelManager::Iterator it(_channelManagerPtr); it.IsValid(); 30840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org it.Increment()) { 30940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org Channel* channel = it.GetChannel(); 31040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (channel->Sending()) { 31140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CodecInst codec; 31240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org channel->GetSendCodec(codec); 31340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org *max_sample_rate = std::max(*max_sample_rate, codec.plfreq); 31440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org *max_channels = std::max(*max_channels, codec.channels); 31540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 31640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 31740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 31840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 31940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint32_t 32040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::PrepareDemux(const void* audioSamples, 321dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t nSamples, 3226955870806624479723addfae6dcf5d13968796cPeter Kasting size_t nChannels, 32340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org uint32_t samplesPerSec, 32440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org uint16_t totalDelayMS, 32540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org int32_t clockDrift, 32640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org uint16_t currentMicLevel, 32740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org bool keyPressed) 32840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 32940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1), 330dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting "TransmitMixer::PrepareDemux(nSamples=%" PRIuS ", " 3316955870806624479723addfae6dcf5d13968796cPeter Kasting "nChannels=%" PRIuS ", samplesPerSec=%u, totalDelayMS=%u, " 332dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting "clockDrift=%d, currentMicLevel=%u)", 333dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting nSamples, nChannels, samplesPerSec, totalDelayMS, clockDrift, 334dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting currentMicLevel); 33540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 33640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // --- Resample input audio and create/store the initial audio frame 33740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org GenerateAudioFrame(static_cast<const int16_t*>(audioSamples), 33840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org nSamples, 33940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org nChannels, 34040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org samplesPerSec); 34140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 34240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 34340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 34440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (external_preproc_ptr_) { 34540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org external_preproc_ptr_->Process(-1, kRecordingPreprocessing, 34640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _audioFrame.data_, 34740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _audioFrame.samples_per_channel_, 34840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _audioFrame.sample_rate_hz_, 34940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _audioFrame.num_channels_ == 2); 35040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 35140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 35240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 35340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // --- Near-end audio processing. 35440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org ProcessAudio(totalDelayMS, clockDrift, currentMicLevel, keyPressed); 35540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 35640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (swap_stereo_channels_ && stereo_codec_) 35740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Only bother swapping if we're using a stereo codec. 35840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org AudioFrameOperations::SwapStereoChannels(&_audioFrame); 35940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 36040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // --- Annoying typing detection (utilizes the APM/VAD decision) 36140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION 36240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org TypingDetection(keyPressed); 36340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#endif 36440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 36540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // --- Mute during DTMF tone if direct feedback is enabled 36640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_remainingMuteMicTimeMs > 0) 36740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 36840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org AudioFrameOperations::Mute(_audioFrame); 36940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _remainingMuteMicTimeMs -= 10; 37040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_remainingMuteMicTimeMs < 0) 37140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 37240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _remainingMuteMicTimeMs = 0; 37340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 37440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 37540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 37640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // --- Mute signal 37740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_mute) 37840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 37940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org AudioFrameOperations::Mute(_audioFrame); 38040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 38140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 38240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // --- Mix with file (does not affect the mixing frequency) 38340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_filePlaying) 38440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 38540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org MixOrReplaceAudioWithFile(_audioFrame.sample_rate_hz_); 38640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 38740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 38840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // --- Record to file 38940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org bool file_recording = false; 39040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 39140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 39240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org file_recording = _fileRecording; 39340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 39440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (file_recording) 39540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 39640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org RecordAudioToFile(_audioFrame.sample_rate_hz_); 39740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 39840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 39940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 40040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 40140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (external_postproc_ptr_) { 40240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org external_postproc_ptr_->Process(-1, kRecordingAllChannelsMixed, 40340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _audioFrame.data_, 40440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _audioFrame.samples_per_channel_, 40540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _audioFrame.sample_rate_hz_, 40640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _audioFrame.num_channels_ == 2); 40740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 40840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 40940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 41040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // --- Measure audio level of speech after all processing. 41140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _audioLevel.ComputeLevel(_audioFrame); 41240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 41340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 41440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 41540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint32_t 41640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::DemuxAndMix() 41740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 41840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1), 41940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::DemuxAndMix()"); 42040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 42140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org for (ChannelManager::Iterator it(_channelManagerPtr); it.IsValid(); 42240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org it.Increment()) 42340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 42440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org Channel* channelPtr = it.GetChannel(); 42566803489f9694cb7c7c0dd3ba07b63e2b6b71779henrika@webrtc.org if (channelPtr->Sending()) 42640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 42740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Demultiplex makes a copy of its input. 42840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org channelPtr->Demultiplex(_audioFrame); 42940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org channelPtr->PrepareEncodeAndSend(_audioFrame.sample_rate_hz_); 43040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 43140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 43240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 43340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 43440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 43540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgvoid TransmitMixer::DemuxAndMix(const int voe_channels[], 4366955870806624479723addfae6dcf5d13968796cPeter Kasting size_t number_of_voe_channels) { 4376955870806624479723addfae6dcf5d13968796cPeter Kasting for (size_t i = 0; i < number_of_voe_channels; ++i) { 43840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org voe::ChannelOwner ch = _channelManagerPtr->GetChannel(voe_channels[i]); 43940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org voe::Channel* channel_ptr = ch.channel(); 44040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (channel_ptr) { 44166803489f9694cb7c7c0dd3ba07b63e2b6b71779henrika@webrtc.org if (channel_ptr->Sending()) { 44240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Demultiplex makes a copy of its input. 44340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org channel_ptr->Demultiplex(_audioFrame); 44440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org channel_ptr->PrepareEncodeAndSend(_audioFrame.sample_rate_hz_); 44540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 44640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 44740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 44840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 44940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 45040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint32_t 45140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::EncodeAndSend() 45240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 45340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1), 45440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::EncodeAndSend()"); 45540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 45640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org for (ChannelManager::Iterator it(_channelManagerPtr); it.IsValid(); 45740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org it.Increment()) 45840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 45940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org Channel* channelPtr = it.GetChannel(); 46066803489f9694cb7c7c0dd3ba07b63e2b6b71779henrika@webrtc.org if (channelPtr->Sending()) 46140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 46240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org channelPtr->EncodeAndSend(); 46340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 46440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 46540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 46640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 46740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 46840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgvoid TransmitMixer::EncodeAndSend(const int voe_channels[], 4696955870806624479723addfae6dcf5d13968796cPeter Kasting size_t number_of_voe_channels) { 4706955870806624479723addfae6dcf5d13968796cPeter Kasting for (size_t i = 0; i < number_of_voe_channels; ++i) { 47140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org voe::ChannelOwner ch = _channelManagerPtr->GetChannel(voe_channels[i]); 47240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org voe::Channel* channel_ptr = ch.channel(); 47366803489f9694cb7c7c0dd3ba07b63e2b6b71779henrika@webrtc.org if (channel_ptr && channel_ptr->Sending()) 47440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org channel_ptr->EncodeAndSend(); 47540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 47640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 47740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 47840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orguint32_t TransmitMixer::CaptureLevel() const 47940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 48040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return _captureLevel; 48140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 48240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 48340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgvoid 48440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::UpdateMuteMicrophoneTime(uint32_t lengthMs) 48540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 48640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 48740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::UpdateMuteMicrophoneTime(lengthMs=%d)", 48840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org lengthMs); 48940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _remainingMuteMicTimeMs = lengthMs; 49040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 49140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 49240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint32_t 49340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::StopSend() 49440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 49540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 49640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::StopSend()"); 49740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _audioLevel.Clear(); 49840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 49940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 50040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 50140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint TransmitMixer::StartPlayingFileAsMicrophone(const char* fileName, 50240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org bool loop, 50340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileFormats format, 50440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org int startPosition, 50540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org float volumeScaling, 50640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org int stopPosition, 50740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org const CodecInst* codecInst) 50840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 50940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 51040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::StartPlayingFileAsMicrophone(" 51140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "fileNameUTF8[]=%s,loop=%d, format=%d, volumeScaling=%5.3f," 51240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org " startPosition=%d, stopPosition=%d)", fileName, loop, 51340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org format, volumeScaling, startPosition, stopPosition); 51440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 51540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_filePlaying) 51640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 51740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 51840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_ALREADY_PLAYING, kTraceWarning, 51940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartPlayingFileAsMicrophone() is already playing"); 52040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 52140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 52240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 52340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 52440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 52540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Destroy the old instance 52640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_filePlayerPtr) 52740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 52840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr->RegisterModuleFileCallback(NULL); 52940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FilePlayer::DestroyFilePlayer(_filePlayerPtr); 53040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr = NULL; 53140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 53240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 53340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Dynamically create the instance 53440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr 53540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org = FilePlayer::CreateFilePlayer(_filePlayerId, 53640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (const FileFormats) format); 53740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 53840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_filePlayerPtr == NULL) 53940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 54040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 54140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_INVALID_ARGUMENT, kTraceError, 54240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartPlayingFileAsMicrophone() filePlayer format isnot correct"); 54340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 54440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 54540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 54640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org const uint32_t notificationTime(0); 54740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 54840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_filePlayerPtr->StartPlayingFile( 54940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileName, 55040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org loop, 55140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org startPosition, 55240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org volumeScaling, 55340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org notificationTime, 55440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org stopPosition, 55540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (const CodecInst*) codecInst) != 0) 55640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 55740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 55840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_BAD_FILE, kTraceError, 55940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartPlayingFile() failed to start file playout"); 56040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr->StopPlayingFile(); 56140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FilePlayer::DestroyFilePlayer(_filePlayerPtr); 56240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr = NULL; 56340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 56440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 56540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 56640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr->RegisterModuleFileCallback(this); 56740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlaying = true; 56840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 56940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 57040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 57140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 57240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint TransmitMixer::StartPlayingFileAsMicrophone(InStream* stream, 57340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileFormats format, 57440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org int startPosition, 57540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org float volumeScaling, 57640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org int stopPosition, 57740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org const CodecInst* codecInst) 57840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 57940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,-1), 58040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::StartPlayingFileAsMicrophone(format=%d," 58140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org " volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)", 58240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org format, volumeScaling, startPosition, stopPosition); 58340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 58440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (stream == NULL) 58540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 58640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 58740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_BAD_FILE, kTraceError, 58840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartPlayingFileAsMicrophone() NULL as input stream"); 58940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 59040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 59140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 59240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_filePlaying) 59340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 59440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 59540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_ALREADY_PLAYING, kTraceWarning, 59640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartPlayingFileAsMicrophone() is already playing"); 59740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 59840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 59940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 60040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 60140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 60240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Destroy the old instance 60340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_filePlayerPtr) 60440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 60540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr->RegisterModuleFileCallback(NULL); 60640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FilePlayer::DestroyFilePlayer(_filePlayerPtr); 60740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr = NULL; 60840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 60940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 61040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Dynamically create the instance 61140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr 61240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org = FilePlayer::CreateFilePlayer(_filePlayerId, 61340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (const FileFormats) format); 61440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 61540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_filePlayerPtr == NULL) 61640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 61740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 61840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_INVALID_ARGUMENT, kTraceWarning, 61940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartPlayingFileAsMicrophone() filePlayer format isnot correct"); 62040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 62140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 62240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 62340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org const uint32_t notificationTime(0); 62440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 62540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_filePlayerPtr->StartPlayingFile( 62640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (InStream&) *stream, 62740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org startPosition, 62840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org volumeScaling, 62940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org notificationTime, 63040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org stopPosition, 63140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (const CodecInst*) codecInst) != 0) 63240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 63340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 63440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_BAD_FILE, kTraceError, 63540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartPlayingFile() failed to start file playout"); 63640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr->StopPlayingFile(); 63740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FilePlayer::DestroyFilePlayer(_filePlayerPtr); 63840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr = NULL; 63940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 64040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 64140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr->RegisterModuleFileCallback(this); 64240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlaying = true; 64340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 64440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 64540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 64640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 64740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint TransmitMixer::StopPlayingFileAsMicrophone() 64840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 64940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,-1), 65040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::StopPlayingFileAsMicrophone()"); 65140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 65240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (!_filePlaying) 65340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 65440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 65540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 65640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 65740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 65840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 65940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_filePlayerPtr->StopPlayingFile() != 0) 66040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 66140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 66240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_CANNOT_STOP_PLAYOUT, kTraceError, 66340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StopPlayingFile() couldnot stop playing file"); 66440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 66540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 66640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 66740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr->RegisterModuleFileCallback(NULL); 66840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FilePlayer::DestroyFilePlayer(_filePlayerPtr); 66940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlayerPtr = NULL; 67040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _filePlaying = false; 67140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 67240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 67340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 67440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 67540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint TransmitMixer::IsPlayingFileAsMicrophone() const 67640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 67740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 67840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::IsPlayingFileAsMicrophone()"); 67940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return _filePlaying; 68040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 68140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 68240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint TransmitMixer::StartRecordingMicrophone(const char* fileName, 68340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org const CodecInst* codecInst) 68440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 68540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 68640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::StartRecordingMicrophone(fileName=%s)", 68740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileName); 68840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 68940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 69040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 69140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileRecording) 69240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 69340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1), 69440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartRecordingMicrophone() is already recording"); 69540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 69640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 69740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 69840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileFormats format; 69940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org const uint32_t notificationTime(0); // Not supported in VoE 70040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CodecInst dummyCodec = { 100, "L16", 16000, 320, 1, 320000 }; 70140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 7026955870806624479723addfae6dcf5d13968796cPeter Kasting if (codecInst != NULL && codecInst->channels > 2) 70340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 70440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 70540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_BAD_ARGUMENT, kTraceError, 70640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartRecordingMicrophone() invalid compression"); 70740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return (-1); 70840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 70940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (codecInst == NULL) 71040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 71140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org format = kFileFormatPcm16kHzFile; 71240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org codecInst = &dummyCodec; 71340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } else if ((STR_CASE_CMP(codecInst->plname,"L16") == 0) || 71440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) || 71540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (STR_CASE_CMP(codecInst->plname,"PCMA") == 0)) 71640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 71740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org format = kFileFormatWavFile; 71840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } else 71940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 72040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org format = kFileFormatCompressedFile; 72140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 72240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 72340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Destroy the old instance 72440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileRecorderPtr) 72540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 72640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr->RegisterModuleFileCallback(NULL); 72740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileRecorder::DestroyFileRecorder(_fileRecorderPtr); 72840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr = NULL; 72940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 73040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 73140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr = 73240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileRecorder::CreateFileRecorder(_fileRecorderId, 73340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (const FileFormats) format); 73440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileRecorderPtr == NULL) 73540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 73640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 73740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_INVALID_ARGUMENT, kTraceError, 73840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartRecordingMicrophone() fileRecorder format isnot correct"); 73940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 74040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 74140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 74240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileRecorderPtr->StartRecordingAudioFile( 74340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileName, 74440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (const CodecInst&) *codecInst, 74540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org notificationTime) != 0) 74640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 74740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 74840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_BAD_FILE, kTraceError, 74940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartRecordingAudioFile() failed to start file recording"); 75040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr->StopRecording(); 75140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileRecorder::DestroyFileRecorder(_fileRecorderPtr); 75240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr = NULL; 75340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 75440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 75540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr->RegisterModuleFileCallback(this); 75640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecording = true; 75740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 75840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 75940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 76040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 76140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint TransmitMixer::StartRecordingMicrophone(OutStream* stream, 76240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org const CodecInst* codecInst) 76340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 76440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 76540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::StartRecordingMicrophone()"); 76640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 76740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 76840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 76940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileRecording) 77040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 77140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1), 77240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartRecordingMicrophone() is already recording"); 77340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 77440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 77540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 77640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileFormats format; 77740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org const uint32_t notificationTime(0); // Not supported in VoE 77840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CodecInst dummyCodec = { 100, "L16", 16000, 320, 1, 320000 }; 77940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 78040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (codecInst != NULL && codecInst->channels != 1) 78140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 78240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 78340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_BAD_ARGUMENT, kTraceError, 78440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartRecordingMicrophone() invalid compression"); 78540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return (-1); 78640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 78740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (codecInst == NULL) 78840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 78940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org format = kFileFormatPcm16kHzFile; 79040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org codecInst = &dummyCodec; 79140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } else if ((STR_CASE_CMP(codecInst->plname,"L16") == 0) || 79240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) || 79340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (STR_CASE_CMP(codecInst->plname,"PCMA") == 0)) 79440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 79540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org format = kFileFormatWavFile; 79640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } else 79740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 79840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org format = kFileFormatCompressedFile; 79940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 80040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 80140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Destroy the old instance 80240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileRecorderPtr) 80340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 80440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr->RegisterModuleFileCallback(NULL); 80540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileRecorder::DestroyFileRecorder(_fileRecorderPtr); 80640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr = NULL; 80740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 80840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 80940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr = 81040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileRecorder::CreateFileRecorder(_fileRecorderId, 81140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (const FileFormats) format); 81240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileRecorderPtr == NULL) 81340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 81440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 81540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_INVALID_ARGUMENT, kTraceError, 81640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartRecordingMicrophone() fileRecorder format isnot correct"); 81740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 81840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 81940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 82040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileRecorderPtr->StartRecordingAudioFile(*stream, 82140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org *codecInst, 82240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org notificationTime) != 0) 82340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 82440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 82540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartRecordingAudioFile() failed to start file recording"); 82640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr->StopRecording(); 82740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileRecorder::DestroyFileRecorder(_fileRecorderPtr); 82840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr = NULL; 82940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 83040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 83140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 83240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr->RegisterModuleFileCallback(this); 83340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecording = true; 83440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 83540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 83640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 83740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 83840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 83940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint TransmitMixer::StopRecordingMicrophone() 84040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 84140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 84240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::StopRecordingMicrophone()"); 84340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 84440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 84540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 84640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (!_fileRecording) 84740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 84840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1), 84940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StopRecordingMicrophone() isnot recording"); 85040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 85140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 85240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 85340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileRecorderPtr->StopRecording() != 0) 85440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 85540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 85640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_STOP_RECORDING_FAILED, kTraceError, 85740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StopRecording(), could not stop recording"); 85840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 85940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 86040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr->RegisterModuleFileCallback(NULL); 86140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileRecorder::DestroyFileRecorder(_fileRecorderPtr); 86240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecorderPtr = NULL; 86340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileRecording = false; 86440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 86540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 86640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 86740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 86840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint TransmitMixer::StartRecordingCall(const char* fileName, 86940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org const CodecInst* codecInst) 87040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 87140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 87240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::StartRecordingCall(fileName=%s)", fileName); 87340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 87440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileCallRecording) 87540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 87640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1), 87740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartRecordingCall() is already recording"); 87840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 87940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 88040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 88140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileFormats format; 88240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org const uint32_t notificationTime(0); // Not supported in VoE 88340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CodecInst dummyCodec = { 100, "L16", 16000, 320, 1, 320000 }; 88440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 88540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (codecInst != NULL && codecInst->channels != 1) 88640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 88740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 88840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_BAD_ARGUMENT, kTraceError, 88940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartRecordingCall() invalid compression"); 89040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return (-1); 89140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 89240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (codecInst == NULL) 89340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 89440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org format = kFileFormatPcm16kHzFile; 89540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org codecInst = &dummyCodec; 89640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } else if ((STR_CASE_CMP(codecInst->plname,"L16") == 0) || 89740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) || 89840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (STR_CASE_CMP(codecInst->plname,"PCMA") == 0)) 89940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 90040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org format = kFileFormatWavFile; 90140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } else 90240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 90340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org format = kFileFormatCompressedFile; 90440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 90540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 90640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 90740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 90840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Destroy the old instance 90940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileCallRecorderPtr) 91040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 91140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr->RegisterModuleFileCallback(NULL); 91240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileRecorder::DestroyFileRecorder(_fileCallRecorderPtr); 91340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr = NULL; 91440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 91540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 91640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr 91740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org = FileRecorder::CreateFileRecorder(_fileCallRecorderId, 91840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (const FileFormats) format); 91940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileCallRecorderPtr == NULL) 92040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 92140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 92240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_INVALID_ARGUMENT, kTraceError, 92340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartRecordingCall() fileRecorder format isnot correct"); 92440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 92540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 92640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 92740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileCallRecorderPtr->StartRecordingAudioFile( 92840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileName, 92940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (const CodecInst&) *codecInst, 93040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org notificationTime) != 0) 93140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 93240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 93340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_BAD_FILE, kTraceError, 93440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartRecordingAudioFile() failed to start file recording"); 93540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr->StopRecording(); 93640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileRecorder::DestroyFileRecorder(_fileCallRecorderPtr); 93740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr = NULL; 93840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 93940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 94040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr->RegisterModuleFileCallback(this); 94140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecording = true; 94240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 94340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 94440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 94540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 94640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint TransmitMixer::StartRecordingCall(OutStream* stream, 94740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org const CodecInst* codecInst) 94840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 94940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 95040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::StartRecordingCall()"); 95140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 95240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileCallRecording) 95340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 95440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1), 95540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartRecordingCall() is already recording"); 95640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 95740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 95840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 95940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileFormats format; 96040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org const uint32_t notificationTime(0); // Not supported in VoE 96140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CodecInst dummyCodec = { 100, "L16", 16000, 320, 1, 320000 }; 96240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 96340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (codecInst != NULL && codecInst->channels != 1) 96440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 96540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 96640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_BAD_ARGUMENT, kTraceError, 96740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartRecordingCall() invalid compression"); 96840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return (-1); 96940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 97040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (codecInst == NULL) 97140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 97240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org format = kFileFormatPcm16kHzFile; 97340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org codecInst = &dummyCodec; 97440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } else if ((STR_CASE_CMP(codecInst->plname,"L16") == 0) || 97540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) || 97640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (STR_CASE_CMP(codecInst->plname,"PCMA") == 0)) 97740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 97840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org format = kFileFormatWavFile; 97940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } else 98040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 98140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org format = kFileFormatCompressedFile; 98240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 98340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 98440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 98540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 98640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Destroy the old instance 98740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileCallRecorderPtr) 98840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 98940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr->RegisterModuleFileCallback(NULL); 99040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileRecorder::DestroyFileRecorder(_fileCallRecorderPtr); 99140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr = NULL; 99240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 99340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 99440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr = 99540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileRecorder::CreateFileRecorder(_fileCallRecorderId, 99640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org (const FileFormats) format); 99740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileCallRecorderPtr == NULL) 99840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 99940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 100040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_INVALID_ARGUMENT, kTraceError, 100140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartRecordingCall() fileRecorder format isnot correct"); 100240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 100340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 100440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 100540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileCallRecorderPtr->StartRecordingAudioFile(*stream, 100640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org *codecInst, 100740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org notificationTime) != 0) 100840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 100940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 101040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StartRecordingAudioFile() failed to start file recording"); 101140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr->StopRecording(); 101240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileRecorder::DestroyFileRecorder(_fileCallRecorderPtr); 101340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr = NULL; 101440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 101540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 101640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 101740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr->RegisterModuleFileCallback(this); 101840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecording = true; 101940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 102040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 102140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 102240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 102340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint TransmitMixer::StopRecordingCall() 102440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 102540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 102640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::StopRecordingCall()"); 102740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 102840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (!_fileCallRecording) 102940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 103040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, -1), 103140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StopRecordingCall() file isnot recording"); 103240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 103340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 103440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 103540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 103640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 103740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileCallRecorderPtr->StopRecording() != 0) 103840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 103940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _engineStatisticsPtr->SetLastError( 104040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VE_STOP_RECORDING_FAILED, kTraceError, 104140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "StopRecording(), could not stop recording"); 104240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 104340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 104440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 104540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr->RegisterModuleFileCallback(NULL); 104640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org FileRecorder::DestroyFileRecorder(_fileCallRecorderPtr); 104740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecorderPtr = NULL; 104840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _fileCallRecording = false; 104940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 105040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 105140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 105240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 105340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgvoid 105440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::SetMixWithMicStatus(bool mix) 105540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 105640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _mixFileWithMicrophone = mix; 105740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 105840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 105940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint TransmitMixer::RegisterExternalMediaProcessing( 106040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VoEMediaProcess* object, 106140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org ProcessingTypes type) { 106240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 106340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::RegisterExternalMediaProcessing()"); 106440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 106540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 106640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (!object) { 106740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 106840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 106940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 107040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Store the callback object according to the processing type. 107140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (type == kRecordingAllChannelsMixed) { 107240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org external_postproc_ptr_ = object; 107340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } else if (type == kRecordingPreprocessing) { 107440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org external_preproc_ptr_ = object; 107540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } else { 107640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 107740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 107840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 107940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 108040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 108140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint TransmitMixer::DeRegisterExternalMediaProcessing(ProcessingTypes type) { 108240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 108340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::DeRegisterExternalMediaProcessing()"); 108440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 108540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 108640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (type == kRecordingAllChannelsMixed) { 108740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org external_postproc_ptr_ = NULL; 108840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } else if (type == kRecordingPreprocessing) { 108940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org external_preproc_ptr_ = NULL; 109040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } else { 109140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 109240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 109340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 109440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 109540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 109640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint 109740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::SetMute(bool enable) 109840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 109940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1), 110040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::SetMute(enable=%d)", enable); 110140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _mute = enable; 110240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 110340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 110440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 110540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgbool 110640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgTransmitMixer::Mute() const 110740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 110840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return _mute; 110940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 111040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 111140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint8_t TransmitMixer::AudioLevel() const 111240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 111340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Speech + file level [0,9] 111440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return _audioLevel.Level(); 111540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 111640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 111740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint16_t TransmitMixer::AudioLevelFullRange() const 111840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 111940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Speech + file level [0,32767] 112040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return _audioLevel.LevelFullRange(); 112140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 112240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 112340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgbool TransmitMixer::IsRecordingCall() 112440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 112540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return _fileCallRecording; 112640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 112740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 112840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgbool TransmitMixer::IsRecordingMic() 112940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 113040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 113140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return _fileRecording; 113240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 113340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 113440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgvoid TransmitMixer::GenerateAudioFrame(const int16_t* audio, 1135dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t samples_per_channel, 11366955870806624479723addfae6dcf5d13968796cPeter Kasting size_t num_channels, 113740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org int sample_rate_hz) { 113840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org int codec_rate; 11396955870806624479723addfae6dcf5d13968796cPeter Kasting size_t num_codec_channels; 114040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org GetSendCodecInfo(&codec_rate, &num_codec_channels); 114140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org stereo_codec_ = num_codec_channels == 2; 114240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 1143cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs // We want to process at the lowest rate possible without losing information. 1144cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs // Choose the lowest native rate at least equal to the input and codec rates. 1145cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs const int min_processing_rate = std::min(sample_rate_hz, codec_rate); 1146cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs for (size_t i = 0; i < AudioProcessing::kNumNativeSampleRates; ++i) { 1147cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs _audioFrame.sample_rate_hz_ = AudioProcessing::kNativeSampleRatesHz[i]; 1148cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs if (_audioFrame.sample_rate_hz_ >= min_processing_rate) { 1149cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs break; 1150cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs } 1151cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs } 1152cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs if (audioproc_->echo_control_mobile()->is_enabled()) { 1153cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs // AECM only supports 8 and 16 kHz. 1154cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs _audioFrame.sample_rate_hz_ = std::min( 1155cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs _audioFrame.sample_rate_hz_, AudioProcessing::kMaxAECMSampleRateHz); 115640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 1157cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs _audioFrame.num_channels_ = std::min(num_channels, num_codec_channels); 1158cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs RemixAndResample(audio, samples_per_channel, num_channels, sample_rate_hz, 1159cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs &resampler_, &_audioFrame); 116040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 116140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 116240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint32_t TransmitMixer::RecordAudioToFile( 116340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org uint32_t mixingFrequency) 116440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 116540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 116640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileRecorderPtr == NULL) 116740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 116840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1), 116940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::RecordAudioToFile() filerecorder doesnot" 117040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "exist"); 117140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 117240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 117340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 117440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_fileRecorderPtr->RecordAudioToFile(_audioFrame) != 0) 117540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 117640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1), 117740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::RecordAudioToFile() file recording" 117840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "failed"); 117940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 118040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 118140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 118240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 118340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 118440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 118540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint32_t TransmitMixer::MixOrReplaceAudioWithFile( 118640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org int mixingFrequency) 118740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 118800b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org rtc::scoped_ptr<int16_t[]> fileBuffer(new int16_t[640]); 118940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 1190dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t fileSamples(0); 119140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 119240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 119340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_filePlayerPtr == NULL) 119440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 119540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, 119640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org VoEId(_instanceId, -1), 119740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::MixOrReplaceAudioWithFile()" 119840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "fileplayer doesnot exist"); 119940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 120040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 120140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 120240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_filePlayerPtr->Get10msAudioFromFile(fileBuffer.get(), 120340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileSamples, 120440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org mixingFrequency) == -1) 120540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 120640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1), 120740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org "TransmitMixer::MixOrReplaceAudioWithFile() file" 120840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org " mixing failed"); 120940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return -1; 121040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 121140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 121240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 121340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org assert(_audioFrame.samples_per_channel_ == fileSamples); 121440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 121540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_mixFileWithMicrophone) 121640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 121740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Currently file stream is always mono. 121840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // TODO(xians): Change the code when FilePlayer supports real stereo. 121940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org MixWithSat(_audioFrame.data_, 122040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _audioFrame.num_channels_, 122140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileBuffer.get(), 122240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 1, 122340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileSamples); 122440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } else 122540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org { 122640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Replace ACM audio with file. 122740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Currently file stream is always mono. 122840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // TODO(xians): Change the code when FilePlayer supports real stereo. 122940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _audioFrame.UpdateFrame(-1, 1230eec6ecdb1e249871dd25d04b62fc9ddc03dc8a34tommi@webrtc.org 0xFFFFFFFF, 123140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileBuffer.get(), 123240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileSamples, 123340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org mixingFrequency, 123440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org AudioFrame::kNormalSpeech, 123540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org AudioFrame::kVadUnknown, 123640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 1); 123740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 123840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 123940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 124040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 124140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgvoid TransmitMixer::ProcessAudio(int delay_ms, int clock_drift, 124240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org int current_mic_level, bool key_pressed) { 124340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (audioproc_->set_stream_delay_ms(delay_ms) != 0) { 1244ad856229a796a8efa1126ef8aa8d238f2b0a2b21pbos // Silently ignore this failure to avoid flooding the logs. 124540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 124640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 124740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org GainControl* agc = audioproc_->gain_control(); 124840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (agc->set_stream_analog_level(current_mic_level) != 0) { 1249ad856229a796a8efa1126ef8aa8d238f2b0a2b21pbos LOG(LS_ERROR) << "set_stream_analog_level failed: current_mic_level = " 1250ad856229a796a8efa1126ef8aa8d238f2b0a2b21pbos << current_mic_level; 125140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org assert(false); 125240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 125340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 125440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org EchoCancellation* aec = audioproc_->echo_cancellation(); 125540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (aec->is_drift_compensation_enabled()) { 125640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org aec->set_stream_drift_samples(clock_drift); 125740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 125840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 125940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org audioproc_->set_stream_key_pressed(key_pressed); 126040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 126140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org int err = audioproc_->ProcessStream(&_audioFrame); 126240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (err != 0) { 126340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org LOG(LS_ERROR) << "ProcessStream() error: " << err; 126440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org assert(false); 126540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 126640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 126740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Store new capture level. Only updated when analog AGC is enabled. 126840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _captureLevel = agc->stream_analog_level(); 126940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 127040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org CriticalSectionScoped cs(&_critSect); 127140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Triggers a callback in OnPeriodicProcess(). 127240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _saturationWarning |= agc->stream_is_saturated(); 127340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 127440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 127540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION 127640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgvoid TransmitMixer::TypingDetection(bool keyPressed) 127740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 127840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // We let the VAD determine if we're using this feature or not. 127940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_audioFrame.vad_activity_ == AudioFrame::kVadUnknown) { 128040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return; 128140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 128240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 128340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org bool vadActive = _audioFrame.vad_activity_ == AudioFrame::kVadActive; 128440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (_typingDetection.Process(keyPressed, vadActive)) { 1285302c978c921c2c63e1ab2414f0db03d19d5bfc60solenberg CriticalSectionScoped cs(&_critSect); 128640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _typingNoiseWarningPending = true; 128740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _typingNoiseDetected = true; 128840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } else { 1289302c978c921c2c63e1ab2414f0db03d19d5bfc60solenberg CriticalSectionScoped cs(&_critSect); 129040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // If there is already a warning pending, do not change the state. 129140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Otherwise set a warning pending if last callback was for noise detected. 129240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (!_typingNoiseWarningPending && _typingNoiseDetected) { 129340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _typingNoiseWarningPending = true; 129440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _typingNoiseDetected = false; 129540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 129640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org } 129740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 129840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#endif 129940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 130040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint TransmitMixer::GetMixingFrequency() 130140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 130240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org assert(_audioFrame.sample_rate_hz_ != 0); 130340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return _audioFrame.sample_rate_hz_; 130440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 130540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 130640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION 130740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint TransmitMixer::TimeSinceLastTyping(int &seconds) 130840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 130940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // We check in VoEAudioProcessingImpl that this is only called when 131040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // typing detection is active. 131140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org seconds = _typingDetection.TimeSinceLastDetectionInSeconds(); 131240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 131340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 131440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#endif 131540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 131640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#ifdef WEBRTC_VOICE_ENGINE_TYPING_DETECTION 131740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgint TransmitMixer::SetTypingDetectionParameters(int timeWindow, 131840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org int costPerTyping, 131940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org int reportingThreshold, 132040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org int penaltyDecay, 132140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org int typeEventDelay) 132240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org{ 132340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _typingDetection.SetParameters(timeWindow, 132440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org costPerTyping, 132540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org reportingThreshold, 132640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org penaltyDecay, 132740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org typeEventDelay, 132840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 0); 132940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return 0; 133040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 133140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org#endif 133240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 133340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgvoid TransmitMixer::EnableStereoChannelSwapping(bool enable) { 133440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org swap_stereo_channels_ = enable; 133540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 133640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 133740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.orgbool TransmitMixer::IsStereoChannelSwappingEnabled() { 133840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org return swap_stereo_channels_; 133940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} 134040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 134140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} // namespace voe 134240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org} // namespace webrtc 1343