[go: nahoru, domu]

blob: 20a8d797e9ee7017dba0203cc4a8d0569d82281d [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_SERVICES_TTS_TTS_PLAYER_H_
#define CHROMEOS_SERVICES_TTS_TTS_PLAYER_H_
#include <queue>
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "base/time/time.h"
#include "chromeos/services/tts/public/mojom/tts_service.mojom.h"
#include "media/base/audio_renderer_sink.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/audio/public/cpp/output_device.h"
namespace chromeos {
namespace tts {
class TtsPlayer : public media::AudioRendererSink::RenderCallback {
public:
typedef std::pair<int, base::TimeDelta> Timepoint;
// Helper group of state to pass from main thread to audio thread.
struct AudioBuffer {
AudioBuffer();
~AudioBuffer();
AudioBuffer(const AudioBuffer& other) = delete;
AudioBuffer(AudioBuffer&& other);
std::vector<float> frames;
int char_index = -1;
int status = 0;
bool is_first_buffer = false;
};
TtsPlayer(mojo::PendingRemote<media::mojom::AudioStreamFactory> factory,
const media::AudioParameters& params);
~TtsPlayer() override;
// Audio operations.
void Play(
base::OnceCallback<void(mojo::PendingReceiver<mojom::TtsEventObserver>)>
callback);
void AddAudioBuffer(AudioBuffer buf);
void AddExplicitTimepoint(int char_index, base::TimeDelta delay);
void Stop();
void SetVolume(float volume);
void Pause();
void Resume();
// media::AudioRendererSink::RenderCallback:
int Render(base::TimeDelta delay,
base::TimeTicks delay_timestamp,
int prior_frames_skipped,
media::AudioBus* dest) override;
void OnRenderError() override;
private:
// Handles stopping tts.
void StopLocked(bool clear_buffers = true)
EXCLUSIVE_LOCKS_REQUIRED(state_lock_);
// Do any processing (e.g. sending start/end events) on buffers that have just
// been rendered on the audio thread.
void ProcessRenderedBuffers();
// Protects access to state from main thread and audio thread.
base::Lock state_lock_;
// Connection to send tts events.
mojo::Remote<mojom::TtsEventObserver> tts_event_observer_;
// Outputs speech synthesis to audio.
audio::OutputDevice output_device_;
// The queue of audio buffers to be played by the audio thread.
std::queue<AudioBuffer> buffers_ GUARDED_BY(state_lock_);
std::queue<AudioBuffer> rendered_buffers_;
// An explicit list of increasing time delta sorted timepoints to be fired
// while rendering audio at the specified |delay| from start of audio
// playback. An AudioBuffer may contain an implicit timepoint for callers who
// specify a character index along with the audio buffer.
std::queue<Timepoint> timepoints_ GUARDED_BY(state_lock_);
// The time at which playback of the current utterance started.
base::Time start_playback_time_;
// Whether a task to process rendered audio buffers has been posted.
bool process_rendered_buffers_posted_ GUARDED_BY(state_lock_) = false;
// Handles tasks posted from the audio thread, processed in the main thread.
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::WeakPtrFactory<TtsPlayer> weak_factory_{this};
};
} // namespace tts
} // namespace chromeos
#endif // CHROMEOS_SERVICES_TTS_TTS_PLAYER_H_