Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(551)

Unified Diff: webrtc/modules/audio_mixer/audio_mixer.cc

Issue 2104363003: A simple copy of the old mixer to a new directory. I also plan to run 'git cl format'. In another C… (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixed cpplint complaints in old code. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/modules/audio_mixer/audio_mixer.h ('k') | webrtc/modules/audio_mixer/audio_mixer.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/modules/audio_mixer/audio_mixer.cc
diff --git a/webrtc/modules/audio_mixer/audio_mixer.cc b/webrtc/modules/audio_mixer/audio_mixer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9048c39a95c2439032267aff65a753d69fffa9c7
--- /dev/null
+++ b/webrtc/modules/audio_mixer/audio_mixer.cc
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/audio_mixer/audio_mixer.h"
+
+#include "webrtc/base/format_macros.h"
+#include "webrtc/modules/audio_processing/include/audio_processing.h"
+#include "webrtc/modules/utility/include/audio_frame_operations.h"
+#include "webrtc/system_wrappers/include/file_wrapper.h"
+#include "webrtc/system_wrappers/include/trace.h"
+#include "webrtc/voice_engine/include/voe_external_media.h"
+#include "webrtc/voice_engine/statistics.h"
+#include "webrtc/voice_engine/utility.h"
+
+namespace webrtc {
+namespace voe {
+
+void AudioMixer::NewMixedAudio(int32_t id,
+ const AudioFrame& generalAudioFrame,
+ const AudioFrame** uniqueAudioFrames,
+ uint32_t size) {
+ WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::NewMixedAudio(id=%d, size=%u)", id, size);
+
+ _audioFrame.CopyFrom(generalAudioFrame);
+ _audioFrame.id_ = id;
+}
+
+void AudioMixer::PlayNotification(int32_t id, uint32_t durationMs) {
+ WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::PlayNotification(id=%d, durationMs=%d)", id,
+ durationMs);
+ // Not implement yet
+}
+
+void AudioMixer::RecordNotification(int32_t id, uint32_t durationMs) {
+ WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::RecordNotification(id=%d, durationMs=%d)", id,
+ durationMs);
+
+ // Not implement yet
+}
+
+void AudioMixer::PlayFileEnded(int32_t id) {
+ WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::PlayFileEnded(id=%d)", id);
+
+ // not needed
+}
+
+void AudioMixer::RecordFileEnded(int32_t id) {
+ WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::RecordFileEnded(id=%d)", id);
+ assert(id == _instanceId);
+
+ rtc::CritScope cs(&_fileCritSect);
+ _outputFileRecording = false;
+ WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::RecordFileEnded() =>"
+ "output file recorder module is shutdown");
+}
+
+int32_t AudioMixer::Create(AudioMixer*& mixer, uint32_t instanceId) {
+ WEBRTC_TRACE(kTraceMemory, kTraceVoice, instanceId,
+ "AudioMixer::Create(instanceId=%d)", instanceId);
+ mixer = new AudioMixer(instanceId);
+ if (mixer == NULL) {
+ WEBRTC_TRACE(kTraceMemory, kTraceVoice, instanceId,
+ "AudioMixer::Create() unable to allocate memory for"
+ "mixer");
+ return -1;
+ }
+ return 0;
+}
+
+AudioMixer::AudioMixer(uint32_t instanceId)
+ : _mixerModule(*NewAudioConferenceMixer::Create(instanceId)),
+ _audioLevel(),
+ _instanceId(instanceId),
+ _externalMediaCallbackPtr(NULL),
+ _externalMedia(false),
+ _panLeft(1.0f),
+ _panRight(1.0f),
+ _mixingFrequencyHz(8000),
+ _outputFileRecorderPtr(NULL),
+ _outputFileRecording(false) {
+ WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::AudioMixer() - ctor");
+
+ if (_mixerModule.RegisterMixedStreamCallback(this) == -1) {
+ WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::AudioMixer() failed to register mixer"
+ "callbacks");
+ }
+}
+
+void AudioMixer::Destroy(AudioMixer*& mixer) {
+ if (mixer) {
+ delete mixer;
+ mixer = NULL;
+ }
+}
+
+AudioMixer::~AudioMixer() {
+ WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::~AudioMixer() - dtor");
+ if (_externalMedia) {
+ DeRegisterExternalMediaProcessing();
+ }
+ {
+ rtc::CritScope cs(&_fileCritSect);
+ if (_outputFileRecorderPtr) {
+ _outputFileRecorderPtr->RegisterModuleFileCallback(NULL);
+ _outputFileRecorderPtr->StopRecording();
+ FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr);
+ _outputFileRecorderPtr = NULL;
+ }
+ }
+ _mixerModule.UnRegisterMixedStreamCallback();
+ delete &_mixerModule;
+}
+
+int32_t AudioMixer::SetEngineInformation(voe::Statistics& engineStatistics) {
+ WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::SetEngineInformation()");
+ _engineStatisticsPtr = &engineStatistics;
+ return 0;
+}
+
+int32_t AudioMixer::SetAudioProcessingModule(
+ AudioProcessing* audioProcessingModule) {
+ WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::SetAudioProcessingModule("
+ "audioProcessingModule=0x%x)",
+ audioProcessingModule);
+ _audioProcessingModulePtr = audioProcessingModule;
+ return 0;
+}
+
+int AudioMixer::RegisterExternalMediaProcessing(
+ VoEMediaProcess& proccess_object) {
+ WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::RegisterExternalMediaProcessing()");
+
+ rtc::CritScope cs(&_callbackCritSect);
+ _externalMediaCallbackPtr = &proccess_object;
+ _externalMedia = true;
+
+ return 0;
+}
+
+int AudioMixer::DeRegisterExternalMediaProcessing() {
+ WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::DeRegisterExternalMediaProcessing()");
+
+ rtc::CritScope cs(&_callbackCritSect);
+ _externalMedia = false;
+ _externalMediaCallbackPtr = NULL;
+
+ return 0;
+}
+
+int32_t AudioMixer::SetMixabilityStatus(MixerAudioSource& participant,
+ bool mixable) {
+ return _mixerModule.SetMixabilityStatus(&participant, mixable);
+}
+
+int32_t AudioMixer::SetAnonymousMixabilityStatus(MixerAudioSource& participant,
+ bool mixable) {
+ return _mixerModule.SetAnonymousMixabilityStatus(&participant, mixable);
+}
+
+int32_t AudioMixer::MixActiveChannels() {
+ _mixerModule.Process();
+ return 0;
+}
+
+int AudioMixer::GetSpeechOutputLevel(uint32_t& level) {
+ int8_t currentLevel = _audioLevel.Level();
+ level = static_cast<uint32_t>(currentLevel);
+ WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
+ "GetSpeechOutputLevel() => level=%u", level);
+ return 0;
+}
+
+int AudioMixer::GetSpeechOutputLevelFullRange(uint32_t& level) {
+ int16_t currentLevel = _audioLevel.LevelFullRange();
+ level = static_cast<uint32_t>(currentLevel);
+ WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
+ "GetSpeechOutputLevelFullRange() => level=%u", level);
+ return 0;
+}
+
+int AudioMixer::SetOutputVolumePan(float left, float right) {
+ WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::SetOutputVolumePan()");
+ _panLeft = left;
+ _panRight = right;
+ return 0;
+}
+
+int AudioMixer::GetOutputVolumePan(float& left, float& right) {
+ left = _panLeft;
+ right = _panRight;
+ WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, -1),
+ "GetOutputVolumePan() => left=%2.1f, right=%2.1f", left, right);
+ return 0;
+}
+
+int AudioMixer::StartRecordingPlayout(const char* fileName,
+ const CodecInst* codecInst) {
+ WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::StartRecordingPlayout(fileName=%s)", fileName);
+
+ if (_outputFileRecording) {
+ WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
+ "StartRecordingPlayout() is already recording");
+ return 0;
+ }
+
+ FileFormats format;
+ const uint32_t notificationTime(0);
+ CodecInst dummyCodec = {100, "L16", 16000, 320, 1, 320000};
+
+ if ((codecInst != NULL) &&
+ ((codecInst->channels < 1) || (codecInst->channels > 2))) {
+ _engineStatisticsPtr->SetLastError(
+ VE_BAD_ARGUMENT, kTraceError,
+ "StartRecordingPlayout() invalid compression");
+ return (-1);
+ }
+ if (codecInst == NULL) {
+ format = kFileFormatPcm16kHzFile;
+ codecInst = &dummyCodec;
+ } else if ((STR_CASE_CMP(codecInst->plname, "L16") == 0) ||
+ (STR_CASE_CMP(codecInst->plname, "PCMU") == 0) ||
+ (STR_CASE_CMP(codecInst->plname, "PCMA") == 0)) {
+ format = kFileFormatWavFile;
+ } else {
+ format = kFileFormatCompressedFile;
+ }
+
+ rtc::CritScope cs(&_fileCritSect);
+
+ // Destroy the old instance
+ if (_outputFileRecorderPtr) {
+ _outputFileRecorderPtr->RegisterModuleFileCallback(NULL);
+ FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr);
+ _outputFileRecorderPtr = NULL;
+ }
+
+ _outputFileRecorderPtr =
+ FileRecorder::CreateFileRecorder(_instanceId, (const FileFormats)format);
+ if (_outputFileRecorderPtr == NULL) {
+ _engineStatisticsPtr->SetLastError(
+ VE_INVALID_ARGUMENT, kTraceError,
+ "StartRecordingPlayout() fileRecorder format isnot correct");
+ return -1;
+ }
+
+ if (_outputFileRecorderPtr->StartRecordingAudioFile(
+ fileName, (const CodecInst&)*codecInst, notificationTime) != 0) {
+ _engineStatisticsPtr->SetLastError(
+ VE_BAD_FILE, kTraceError,
+ "StartRecordingAudioFile() failed to start file recording");
+ _outputFileRecorderPtr->StopRecording();
+ FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr);
+ _outputFileRecorderPtr = NULL;
+ return -1;
+ }
+ _outputFileRecorderPtr->RegisterModuleFileCallback(this);
+ _outputFileRecording = true;
+
+ return 0;
+}
+
+int AudioMixer::StartRecordingPlayout(OutStream* stream,
+ const CodecInst* codecInst) {
+ WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::StartRecordingPlayout()");
+
+ if (_outputFileRecording) {
+ WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
+ "StartRecordingPlayout() is already recording");
+ return 0;
+ }
+
+ FileFormats format;
+ const uint32_t notificationTime(0);
+ CodecInst dummyCodec = {100, "L16", 16000, 320, 1, 320000};
+
+ if (codecInst != NULL && codecInst->channels != 1) {
+ _engineStatisticsPtr->SetLastError(
+ VE_BAD_ARGUMENT, kTraceError,
+ "StartRecordingPlayout() invalid compression");
+ return (-1);
+ }
+ if (codecInst == NULL) {
+ format = kFileFormatPcm16kHzFile;
+ codecInst = &dummyCodec;
+ } else if ((STR_CASE_CMP(codecInst->plname, "L16") == 0) ||
+ (STR_CASE_CMP(codecInst->plname, "PCMU") == 0) ||
+ (STR_CASE_CMP(codecInst->plname, "PCMA") == 0)) {
+ format = kFileFormatWavFile;
+ } else {
+ format = kFileFormatCompressedFile;
+ }
+
+ rtc::CritScope cs(&_fileCritSect);
+
+ // Destroy the old instance
+ if (_outputFileRecorderPtr) {
+ _outputFileRecorderPtr->RegisterModuleFileCallback(NULL);
+ FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr);
+ _outputFileRecorderPtr = NULL;
+ }
+
+ _outputFileRecorderPtr =
+ FileRecorder::CreateFileRecorder(_instanceId, (const FileFormats)format);
+ if (_outputFileRecorderPtr == NULL) {
+ _engineStatisticsPtr->SetLastError(
+ VE_INVALID_ARGUMENT, kTraceError,
+ "StartRecordingPlayout() fileRecorder format isnot correct");
+ return -1;
+ }
+
+ if (_outputFileRecorderPtr->StartRecordingAudioFile(*stream, *codecInst,
+ notificationTime) != 0) {
+ _engineStatisticsPtr->SetLastError(
+ VE_BAD_FILE, kTraceError,
+ "StartRecordingAudioFile() failed to start file recording");
+ _outputFileRecorderPtr->StopRecording();
+ FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr);
+ _outputFileRecorderPtr = NULL;
+ return -1;
+ }
+
+ _outputFileRecorderPtr->RegisterModuleFileCallback(this);
+ _outputFileRecording = true;
+
+ return 0;
+}
+
+int AudioMixer::StopRecordingPlayout() {
+ WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::StopRecordingPlayout()");
+
+ if (!_outputFileRecording) {
+ WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, -1),
+ "StopRecordingPlayout() file isnot recording");
+ return -1;
+ }
+
+ rtc::CritScope cs(&_fileCritSect);
+
+ if (_outputFileRecorderPtr->StopRecording() != 0) {
+ _engineStatisticsPtr->SetLastError(
+ VE_STOP_RECORDING_FAILED, kTraceError,
+ "StopRecording(), could not stop recording");
+ return -1;
+ }
+ _outputFileRecorderPtr->RegisterModuleFileCallback(NULL);
+ FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr);
+ _outputFileRecorderPtr = NULL;
+ _outputFileRecording = false;
+
+ return 0;
+}
+
+int AudioMixer::GetMixedAudio(int sample_rate_hz,
+ size_t num_channels,
+ AudioFrame* frame) {
+ WEBRTC_TRACE(
+ kTraceStream, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::GetMixedAudio(sample_rate_hz=%d, num_channels=%" PRIuS ")",
+ sample_rate_hz, num_channels);
+
+ // --- Record playout if enabled
+ {
+ rtc::CritScope cs(&_fileCritSect);
+ if (_outputFileRecording && _outputFileRecorderPtr)
+ _outputFileRecorderPtr->RecordAudioToFile(_audioFrame);
+ }
+
+ frame->num_channels_ = num_channels;
+ frame->sample_rate_hz_ = sample_rate_hz;
+ // TODO(andrew): Ideally the downmixing would occur much earlier, in
+ // AudioCodingModule.
+ RemixAndResample(_audioFrame, &resampler_, frame);
+ return 0;
+}
+
+int32_t AudioMixer::DoOperationsOnCombinedSignal(bool feed_data_to_apm) {
+ if (_audioFrame.sample_rate_hz_ != _mixingFrequencyHz) {
+ WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioMixer::DoOperationsOnCombinedSignal() => "
+ "mixing frequency = %d",
+ _audioFrame.sample_rate_hz_);
+ _mixingFrequencyHz = _audioFrame.sample_rate_hz_;
+ }
+
+ // Scale left and/or right channel(s) if balance is active
+ if (_panLeft != 1.0 || _panRight != 1.0) {
+ if (_audioFrame.num_channels_ == 1) {
+ AudioFrameOperations::MonoToStereo(&_audioFrame);
+ } else {
+ // Pure stereo mode (we are receiving a stereo signal).
+ }
+
+ assert(_audioFrame.num_channels_ == 2);
+ AudioFrameOperations::Scale(_panLeft, _panRight, _audioFrame);
+ }
+
+ // --- Far-end Voice Quality Enhancement (AudioProcessing Module)
+ if (feed_data_to_apm) {
+ if (_audioProcessingModulePtr->ProcessReverseStream(&_audioFrame) != 0) {
+ WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
+ "AudioProcessingModule::ProcessReverseStream() => error");
+ RTC_DCHECK(false);
+ }
+ }
+
+ // --- External media processing
+ {
+ rtc::CritScope cs(&_callbackCritSect);
+ if (_externalMedia) {
+ const bool is_stereo = (_audioFrame.num_channels_ == 2);
+ if (_externalMediaCallbackPtr) {
+ _externalMediaCallbackPtr->Process(
+ -1, kPlaybackAllChannelsMixed,
+ reinterpret_cast<int16_t*>(_audioFrame.data_),
+ _audioFrame.samples_per_channel_, _audioFrame.sample_rate_hz_,
+ is_stereo);
+ }
+ }
+ }
+
+ // --- Measure audio level (0-9) for the combined signal
+ _audioLevel.ComputeLevel(_audioFrame);
+
+ return 0;
+}
+} // namespace voe
+} // namespace webrtc
« no previous file with comments | « webrtc/modules/audio_mixer/audio_mixer.h ('k') | webrtc/modules/audio_mixer/audio_mixer.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698