[go: nahoru, domu]

blob: 70304c894aef7ef66f4b4cc9d79b8200b5139342 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/audio/audio_processor_handler.h"
#include <algorithm>
#include "base/trace_event/trace_event.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_parameters.h"
namespace audio {
AudioProcessorHandler::AudioProcessorHandler(
const media::AudioProcessingSettings& settings,
const media::AudioParameters& input_format,
const media::AudioParameters& output_format,
LogCallback log_callback,
DeliverProcessedAudioCallback deliver_processed_audio_callback,
mojo::PendingReceiver<media::mojom::AudioProcessorControls>
controls_receiver,
media::AecdumpRecordingManager* aecdump_recording_manager)
: audio_processor_(media::AudioProcessor::Create(
// Unretained is safe because this class owns audio_processor_, so it
// will be destroyed first.
base::BindRepeating(&AudioProcessorHandler::DeliverProcessedAudio,
base::Unretained(this)),
std::move(log_callback),
settings,
input_format,
output_format)),
deliver_processed_audio_callback_(
std::move(deliver_processed_audio_callback)),
receiver_(this, std::move(controls_receiver)),
aecdump_recording_manager_(aecdump_recording_manager) {
DCHECK(settings.NeedAudioModification());
if (aecdump_recording_manager_) {
aecdump_recording_manager->RegisterAecdumpSource(this);
}
}
AudioProcessorHandler::~AudioProcessorHandler() {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
if (aecdump_recording_manager_) {
// If an aecdump is currently ongoing, this will trigger a StopAecdump()
// call.
aecdump_recording_manager_->DeregisterAecdumpSource(this);
}
}
void AudioProcessorHandler::ProcessCapturedAudio(
const media::AudioBus& audio_source,
base::TimeTicks audio_capture_time,
double volume,
bool key_pressed,
const media::AudioGlitchInfo& audio_glitch_info) {
glitch_info_accumulator_.Add(audio_glitch_info);
const int num_preferred_channels =
num_preferred_channels_.load(std::memory_order_acquire);
audio_processor_->ProcessCapturedAudio(audio_source, audio_capture_time,
num_preferred_channels, volume,
key_pressed);
}
void AudioProcessorHandler::OnPlayoutData(const media::AudioBus& audio_bus,
int sample_rate,
base::TimeDelta delay) {
TRACE_EVENT2("audio", "AudioProcessorHandler::OnPlayoutData", " this ",
static_cast<void*>(this), "delay", delay.InMillisecondsF());
audio_processor_->OnPlayoutData(audio_bus, sample_rate, delay);
}
void AudioProcessorHandler::GetStats(GetStatsCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
media::AudioProcessingStats stats;
const webrtc::AudioProcessingStats processor_stats =
audio_processor_->GetStats();
stats.echo_return_loss = processor_stats.echo_return_loss;
stats.echo_return_loss_enhancement =
processor_stats.echo_return_loss_enhancement;
std::move(callback).Run(stats);
}
void AudioProcessorHandler::SetPreferredNumCaptureChannels(
int32_t num_preferred_channels) {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
num_preferred_channels = std::clamp(
num_preferred_channels, 1, audio_processor_->output_format().channels());
num_preferred_channels_.store(num_preferred_channels,
std::memory_order_release);
}
void AudioProcessorHandler::StartAecdump(base::File aecdump_file) {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
audio_processor_->OnStartDump(std::move(aecdump_file));
}
void AudioProcessorHandler::StopAecdump() {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
audio_processor_->OnStopDump();
}
void AudioProcessorHandler::DeliverProcessedAudio(
const media::AudioBus& audio_bus,
base::TimeTicks audio_capture_time,
std::optional<double> new_volume) {
deliver_processed_audio_callback_.Run(audio_bus, audio_capture_time,
new_volume,
glitch_info_accumulator_.GetAndReset());
}
} // namespace audio