#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "content/browser/speech/speech_recognizer_impl.h"
#include <stdint.h>
#include <algorithm>
#include <memory>
#include "base/functional/bind.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/speech/audio_buffer.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/media/media_internals.h"
#include "content/public/browser/audio_service.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/speech_recognition_audio_forwarder_config.h"
#include "content/public/browser/speech_recognition_event_listener.h"
#include "media/audio/audio_system.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_converter.h"
#include "media/base/audio_parameters.h"
#include "media/mojo/mojom/audio_logging.mojom.h"
#include "services/audio/public/cpp/device_factory.h"
#if BUILDFLAG(IS_WIN)
#include "media/audio/win/core_audio_util_win.h"
#endif
AudioBus;
AudioConverter;
AudioGlitchInfo;
AudioParameters;
ChannelLayout;
namespace content {
class SpeechRecognizerImpl::OnDataConverter
: public media::AudioConverter::InputCallback { … };
namespace {
const float kUpSmoothingFactor = …;
const float kDownSmoothingFactor = …;
const float kAudioMeterMaxDb = …;
const float kAudioMeterMinDb = …;
const float kAudioMeterDbRange = …;
const float kAudioMeterRangeMaxUnclipped = …;
bool DetectClipping(const AudioChunk& chunk) { … }
}
media::AudioSystem* SpeechRecognizerImpl::audio_system_for_tests_ = …;
media::AudioCapturerSource*
SpeechRecognizerImpl::audio_capturer_source_for_tests_ = …;
SpeechRecognizerImpl::OnDataConverter::OnDataConverter(
const AudioParameters& input_params,
const AudioParameters& output_params)
: … { … }
SpeechRecognizerImpl::OnDataConverter::~OnDataConverter() { … }
scoped_refptr<AudioChunk> SpeechRecognizerImpl::OnDataConverter::Convert(
const AudioBus* data) { … }
double SpeechRecognizerImpl::OnDataConverter::ProvideInput(
AudioBus* dest,
uint32_t frames_delayed,
const AudioGlitchInfo& glitch_info) { … }
SpeechRecognizerImpl::SpeechRecognizerImpl(
SpeechRecognitionEventListener* listener,
media::AudioSystem* audio_system,
int session_id,
bool continuous,
bool provisional_results,
std::unique_ptr<SpeechRecognitionEngine> engine,
std::optional<SpeechRecognitionAudioForwarderConfig> audio_forwarder_config)
: … { … }
void SpeechRecognizerImpl::StartRecognition(const std::string& device_id) { … }
void SpeechRecognizerImpl::AbortRecognition() { … }
void SpeechRecognizerImpl::StopAudioCapture() { … }
bool SpeechRecognizerImpl::IsActive() const { … }
bool SpeechRecognizerImpl::IsCapturingAudio() const { … }
const SpeechRecognitionEngine&
SpeechRecognizerImpl::recognition_engine() const { … }
SpeechRecognizerImpl::~SpeechRecognizerImpl() { … }
void SpeechRecognizerImpl::Capture(const AudioBus* data,
base::TimeTicks audio_capture_time,
const AudioGlitchInfo& glitch_info,
double volume,
bool key_pressed) { … }
void SpeechRecognizerImpl::OnCaptureError(
media::AudioCapturerSource::ErrorCode code,
const std::string& message) { … }
void SpeechRecognizerImpl::AddAudioFromRenderer(
media::mojom::AudioDataS16Ptr buffer) { … }
void SpeechRecognizerImpl::OnSpeechRecognitionEngineResults(
const std::vector<media::mojom::WebSpeechRecognitionResultPtr>& results) { … }
void SpeechRecognizerImpl::OnSpeechRecognitionEngineEndOfUtterance() { … }
void SpeechRecognizerImpl::OnSpeechRecognitionEngineError(
const media::mojom::SpeechRecognitionError& error) { … }
void SpeechRecognizerImpl::DispatchEvent(const FSMEventArgs& event_args) { … }
void SpeechRecognizerImpl::ProcessAudioPipeline(
const FSMEventArgs& event_args) { … }
void SpeechRecognizerImpl::OnAudioParametersReceived(
const std::optional<media::AudioParameters>& params) { … }
SpeechRecognizerImpl::FSMState SpeechRecognizerImpl::PrepareRecognition(
const FSMEventArgs&) { … }
SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::StartRecording(const FSMEventArgs&) { … }
SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::StartRecognitionEngine(const FSMEventArgs& event_args) { … }
SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::WaitEnvironmentEstimationCompletion(const FSMEventArgs&) { … }
SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::DetectUserSpeechOrTimeout(const FSMEventArgs&) { … }
SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::DetectEndOfSpeech(const FSMEventArgs& event_args) { … }
SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::StopCaptureAndWaitForResult(const FSMEventArgs&) { … }
SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::AbortSilently(const FSMEventArgs& event_args) { … }
SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::AbortWithError(const FSMEventArgs& event_args) { … }
SpeechRecognizerImpl::FSMState SpeechRecognizerImpl::Abort(
const media::mojom::SpeechRecognitionError& error) { … }
SpeechRecognizerImpl::FSMState SpeechRecognizerImpl::ProcessIntermediateResult(
const FSMEventArgs& event_args) { … }
SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::ProcessFinalResult(const FSMEventArgs& event_args) { … }
SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::DoNothing(const FSMEventArgs&) const { … }
SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::NotFeasible(const FSMEventArgs& event_args) { … }
void SpeechRecognizerImpl::CloseAudioCapturerSource() { … }
int SpeechRecognizerImpl::GetElapsedTimeMs() const { … }
void SpeechRecognizerImpl::UpdateSignalAndNoiseLevels(const float& rms,
bool clip_detected) { … }
void SpeechRecognizerImpl::SetAudioEnvironmentForTesting(
media::AudioSystem* audio_system,
media::AudioCapturerSource* audio_capturer_source) { … }
media::AudioSystem* SpeechRecognizerImpl::GetAudioSystem() { … }
void SpeechRecognizerImpl::CreateAudioCapturerSource() { … }
media::AudioCapturerSource* SpeechRecognizerImpl::GetAudioCapturerSource() { … }
}