#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "services/audio/input_controller.h"
#include <inttypes.h>
#include <algorithm>
#include <limits>
#include <memory>
#include <utility>
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/task/bind_post_task.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "media/audio/audio_io.h"
#include "media/audio/audio_manager.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_parameters.h"
#include "media/base/audio_processing.h"
#include "media/base/media_switches.h"
#include "media/base/user_input_monitor.h"
#include "services/audio/audio_manager_power_user.h"
#include "services/audio/device_output_listener.h"
#include "services/audio/output_tapper.h"
#include "services/audio/processing_audio_fifo.h"
#include "services/audio/reference_output.h"
#if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
#include "services/audio/audio_processor_handler.h"
#endif
namespace audio {
namespace {
OpenOutcome;
const int kMaxInputChannels = …;
constexpr base::TimeDelta kCheckMutedStateInterval = …;
#if defined(AUDIO_POWER_MONITORING)
constexpr base::TimeDelta kPowerMonitorLogInterval = …;
const int kLowLevelMicrophoneLevelPercent = …;
enum MicrophoneMuteResult { … };
void LogMicrophoneMuteResult(MicrophoneMuteResult result) { … }
const char* SilenceStateToString(InputController::SilenceState state) { … }
float AveragePower(const media::AudioBus& buffer) { … }
#endif
}
class AudioCallback : public media::AudioInputStream::AudioInputCallback { … };
InputController::InputController(
EventHandler* event_handler,
SyncWriter* sync_writer,
media::UserInputMonitor* user_input_monitor,
DeviceOutputListener* device_output_listener,
media::AecdumpRecordingManager* aecdump_recording_manager,
media::mojom::AudioProcessingConfigPtr processing_config,
const media::AudioParameters& output_params,
const media::AudioParameters& device_params,
StreamType type)
: … { … }
#if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
void InputController::MaybeSetUpAudioProcessing(
media::mojom::AudioProcessingConfigPtr processing_config,
const media::AudioParameters& processing_output_params,
const media::AudioParameters& device_params,
DeviceOutputListener* device_output_listener,
media::AecdumpRecordingManager* aecdump_recording_manager) { … }
#endif
InputController::~InputController() { … }
std::unique_ptr<InputController> InputController::Create(
media::AudioManager* audio_manager,
EventHandler* event_handler,
SyncWriter* sync_writer,
media::UserInputMonitor* user_input_monitor,
DeviceOutputListener* device_output_listener,
media::AecdumpRecordingManager* aecdump_recording_manager,
media::mojom::AudioProcessingConfigPtr processing_config,
const media::AudioParameters& params,
const std::string& device_id,
bool enable_agc) { … }
void InputController::Record() { … }
void InputController::Close() { … }
void InputController::SetVolume(double volume) { … }
void InputController::SetOutputDeviceForAec(
const std::string& output_device_id) { … }
void InputController::OnStreamActive(Snoopable* output_stream) { … }
void InputController::OnStreamInactive(Snoopable* output_stream) { … }
InputController::ErrorCode MapOpenOutcomeToErrorCode(OpenOutcome outcome) { … }
void InputController::DoCreate(media::AudioManager* audio_manager,
const media::AudioParameters& params,
const std::string& device_id,
bool enable_agc) { … }
void InputController::DoReportError() { … }
void InputController::DoLogAudioLevels(float level_dbfs,
int microphone_volume_percent) { … }
#if defined(AUDIO_POWER_MONITORING)
void InputController::UpdateSilenceState(bool silence) { … }
#endif
void InputController::LogCaptureStartupResult(CaptureStartupResult result) { … }
void InputController::LogCallbackError() { … }
void InputController::LogMessage(const std::string& message) { … }
bool InputController::CheckForKeyboardInput() { … }
bool InputController::CheckAudioPower(const media::AudioBus* source,
double volume,
float* average_power_dbfs,
int* mic_volume_percent) { … }
void InputController::CheckMutedState() { … }
void InputController::ReportIsAlive() { … }
void InputController::OnData(const media::AudioBus* source,
base::TimeTicks capture_time,
double volume,
const media::AudioGlitchInfo& glitch_info) { … }
#if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
void InputController::DeliverProcessedAudio(
const media::AudioBus& audio_bus,
base::TimeTicks audio_capture_time,
std::optional<double> new_volume,
const media::AudioGlitchInfo& glitch_info) { … }
#endif
InputController::StreamType InputController::ParamsToStreamType(
const media::AudioParameters& params) { … }
}