#ifndef CHROME_SERVICES_SPEECH_AUDIO_SOURCE_FETCHER_IMPL_H_
#define CHROME_SERVICES_SPEECH_AUDIO_SOURCE_FETCHER_IMPL_H_
#include <memory>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "chrome/services/speech/audio_source_consumer.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_capturer_source.h"
#include "media/base/converting_audio_fifo.h"
#include "media/mojo/common/audio_data_s16_converter.h"
#include "media/mojo/mojom/audio_logging.mojom.h"
#include "media/mojo/mojom/speech_recognition_service.mojom.h"
#include "mojo/public/cpp/bindings/receiver.h"
namespace speech {
class SpeechRecognitionRecognizerImpl;
class AudioSourceFetcherImpl
: public media::mojom::AudioSourceFetcher,
public media::AudioCapturerSource::CaptureCallback,
public media::AudioDataS16Converter,
public media::mojom::AudioLog {
public:
AudioSourceFetcherImpl(
std::unique_ptr<AudioSourceConsumer> recognition_recognizer,
bool is_multi_channel_supported,
bool is_server_based);
~AudioSourceFetcherImpl() override;
AudioSourceFetcherImpl(const AudioSourceFetcherImpl&) = delete;
AudioSourceFetcherImpl& operator=(const AudioSourceFetcherImpl&) = delete;
static void Create(
mojo::PendingReceiver<media::mojom::AudioSourceFetcher> receiver,
std::unique_ptr<AudioSourceConsumer> recognition_recognizer,
bool is_multi_channel_supported,
bool is_server_based);
void Start(
mojo::PendingRemote<media::mojom::AudioStreamFactory> stream_factory,
const std::string& device_id,
const ::media::AudioParameters& audio_parameters) override;
void Stop() override;
void OnCaptureStarted() final {}
void Capture(const media::AudioBus* audio_source,
base::TimeTicks audio_capture_time,
const media::AudioGlitchInfo& glitch_info,
double volume) final;
void OnCaptureError(media::AudioCapturerSource::ErrorCode code,
const std::string& message) final;
void OnCaptureMuted(bool is_muted) final {}
void OnCreated(const media::AudioParameters& params,
const std::string& device_id) override;
void OnStarted() override;
void OnStopped() override;
void OnClosed() override;
void OnError() override;
void OnSetVolume(double volume) override;
void OnLogMessage(const std::string& message) override;
void OnProcessingStateChanged(const std::string& message) override;
void OnAudioFinishedConvert(const media::AudioBus* output_bus);
void set_audio_capturer_source_for_tests(
media::AudioCapturerSource* audio_capturer_source_for_tests) {
audio_capturer_source_for_tests_ = audio_capturer_source_for_tests;
}
private:
using SendAudioToSpeechRecognitionServiceCallback =
base::RepeatingCallback<void(media::mojom::AudioDataS16Ptr audio_data)>;
using SendAudioToResampleCallback = base::RepeatingCallback<void(
std::unique_ptr<media::AudioBus> audio_data)>;
void SendAudioToSpeechRecognitionService(
media::mojom::AudioDataS16Ptr buffer);
void SendAudioToResample(std::unique_ptr<media::AudioBus> audio_data);
void SendAudioEndToSpeechRecognitionService();
void SendError();
media::AudioCapturerSource* GetAudioCapturerSource();
void DrainConverterOutput();
SendAudioToSpeechRecognitionServiceCallback send_audio_callback_;
scoped_refptr<media::AudioCapturerSource> audio_capturer_source_;
raw_ptr<media::AudioCapturerSource> audio_capturer_source_for_tests_ =
nullptr;
media::AudioParameters audio_parameters_;
std::string device_id_;
std::unique_ptr<AudioSourceConsumer> audio_consumer_;
bool is_started_;
mojo::Receiver<media::mojom::AudioLog> audio_log_receiver_{this};
std::unique_ptr<media::ConvertingAudioFifo> converter_;
std::optional<media::AudioParameters> server_based_recognition_params_ =
std::nullopt;
bool is_multi_channel_supported_;
bool is_server_based_;
base::TimeDelta audio_length_ = base::Seconds(0);
SendAudioToResampleCallback resample_callback_;
base::RepeatingClosure send_error_callback_;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<AudioSourceFetcherImpl> weak_factory_{this};
};
}
#endif