tts_player.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef CHROMEOS_SERVICES_TTS_TTS_PLAYER_H_
  5. #define CHROMEOS_SERVICES_TTS_TTS_PLAYER_H_
  6. #include <queue>
  7. #include "base/synchronization/lock.h"
  8. #include "base/thread_annotations.h"
  9. #include "base/time/time.h"
  10. #include "chromeos/services/tts/public/mojom/tts_service.mojom.h"
  11. #include "media/base/audio_renderer_sink.h"
  12. #include "mojo/public/cpp/bindings/pending_receiver.h"
  13. #include "mojo/public/cpp/bindings/receiver.h"
  14. #include "mojo/public/cpp/bindings/remote.h"
  15. #include "services/audio/public/cpp/output_device.h"
  16. namespace chromeos {
  17. namespace tts {
  18. class TtsPlayer : public media::AudioRendererSink::RenderCallback {
  19. public:
  20. typedef std::pair<int, base::TimeDelta> Timepoint;
  21. // Helper group of state to pass from main thread to audio thread.
  22. struct AudioBuffer {
  23. AudioBuffer();
  24. ~AudioBuffer();
  25. AudioBuffer(const AudioBuffer& other) = delete;
  26. AudioBuffer(AudioBuffer&& other);
  27. std::vector<float> frames;
  28. int char_index = -1;
  29. int status = 0;
  30. bool is_first_buffer = false;
  31. };
  32. TtsPlayer(mojo::PendingRemote<media::mojom::AudioStreamFactory> factory,
  33. const media::AudioParameters& params);
  34. ~TtsPlayer() override;
  35. // Audio operations.
  36. void Play(
  37. base::OnceCallback<void(mojo::PendingReceiver<mojom::TtsEventObserver>)>
  38. callback);
  39. void AddAudioBuffer(AudioBuffer buf);
  40. void AddExplicitTimepoint(int char_index, base::TimeDelta delay);
  41. void Stop();
  42. void SetVolume(float volume);
  43. void Pause();
  44. void Resume();
  45. // media::AudioRendererSink::RenderCallback:
  46. int Render(base::TimeDelta delay,
  47. base::TimeTicks delay_timestamp,
  48. int prior_frames_skipped,
  49. media::AudioBus* dest) override;
  50. void OnRenderError() override;
  51. private:
  52. // Handles stopping tts.
  53. void StopLocked(bool clear_buffers = true)
  54. EXCLUSIVE_LOCKS_REQUIRED(state_lock_);
  55. // Do any processing (e.g. sending start/end events) on buffers that have just
  56. // been rendered on the audio thread.
  57. void ProcessRenderedBuffers();
  58. // Protects access to state from main thread and audio thread.
  59. base::Lock state_lock_;
  60. // Connection to send tts events.
  61. mojo::Remote<mojom::TtsEventObserver> tts_event_observer_;
  62. // Outputs speech synthesis to audio.
  63. audio::OutputDevice output_device_;
  64. // The queue of audio buffers to be played by the audio thread.
  65. std::queue<AudioBuffer> buffers_ GUARDED_BY(state_lock_);
  66. std::queue<AudioBuffer> rendered_buffers_;
  67. // An explicit list of increasing time delta sorted timepoints to be fired
  68. // while rendering audio at the specified |delay| from start of audio
  69. // playback. An AudioBuffer may contain an implicit timepoint for callers who
  70. // specify a character index along with the audio buffer.
  71. std::queue<Timepoint> timepoints_ GUARDED_BY(state_lock_);
  72. // The time at which playback of the current utterance started.
  73. base::Time start_playback_time_;
  74. // Whether a task to process rendered audio buffers has been posted.
  75. bool process_rendered_buffers_posted_ GUARDED_BY(state_lock_) = false;
  76. // Handles tasks posted from the audio thread, processed in the main thread.
  77. scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
  78. base::WeakPtrFactory<TtsPlayer> weak_factory_{this};
  79. };
  80. } // namespace tts
  81. } // namespace chromeos
  82. #endif // CHROMEOS_SERVICES_TTS_TTS_PLAYER_H_