123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- // Copyright 2022 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 SERVICES_AUDIO_PROCESSING_AUDIO_FIFO_H_
- #define SERVICES_AUDIO_PROCESSING_AUDIO_FIFO_H_
- #include "base/callback_forward.h"
- #include "base/sequence_checker.h"
- #include "base/strings/string_piece.h"
- #include "base/synchronization/atomic_flag.h"
- #include "base/synchronization/lock.h"
- #include "base/synchronization/waitable_event.h"
- #include "base/thread_annotations.h"
- #include "media/base/audio_parameters.h"
- #include "services/audio/realtime_audio_thread.h"
- namespace media {
- class AudioBus;
- }
- namespace audio {
- // ProcessingAudioFifo is a ring buffer, which offloads audio processing to its
- // own dedicated real-time thread. It interacts with 3 sequences:
- // - An owning sequence, on which it is constructed, started, stopped and
- // destroyed.
- // - A capture sequence which calls PushData().
- // - A processing thread, which ProcessingAudioFifo owns, on which a
- // processing callback is called.
- class ProcessingAudioFifo {
- public:
- using ProcessAudioCallback = base::RepeatingCallback<
- void(const media::AudioBus&, base::TimeTicks, double, bool)>;
- using LogCallback = base::RepeatingCallback<void(base::StringPiece)>;
- // |processing_callback| will only be called back on the processing thread.
- ProcessingAudioFifo(const media::AudioParameters& input_params,
- int fifo_size,
- ProcessAudioCallback processing_callback,
- LogCallback log_callback);
- // Note: This synchronously waits for |audio_processing_thread_.Stop()|.
- ~ProcessingAudioFifo();
- // Disallow copy and assign.
- ProcessingAudioFifo(const ProcessingAudioFifo&) = delete;
- ProcessingAudioFifo& operator=(const ProcessingAudioFifo&) = delete;
- // Adds data to the FIFO, waking up the processing thread in the process.
- // If the FIFO is full, new data will be dropped.
- // Called on the capture thread.
- void PushData(const media::AudioBus* audio_bus,
- base::TimeTicks capture_time,
- double volume,
- bool key_pressed);
- // Starts the processing thread. Cannot be called more than once.
- void Start();
- // |fake_new_data_captured| will replace |new_data_captured_| in the
- // ProcessAudioLoop().
- void StartForTesting(base::WaitableEvent* fake_new_data_captured);
- // Adds a callback that will be run immediately after |processing_callback_|,
- // on the same sequences as |processing_callback_|.
- void AttachOnProcessedCallbackForTesting(
- base::RepeatingClosure on_processed_callback);
- private:
- friend class ProcessingAudioFifoTest;
- class StatsReporter;
- struct CaptureData;
- void StartInternal(base::WaitableEvent* new_data_captured);
- void StopProcessingLoop();
- void ProcessAudioLoop(base::WaitableEvent* new_data_captured);
- CaptureData* GetDataAtIndex(int idx);
- base::Lock fifo_index_lock_;
- // Total number of segments written to |fifo_|.
- // Updated on capture thread. Read on capture and processing thread.
- int write_count_ GUARDED_BY(fifo_index_lock_) = 0;
- // Total number of segments read from the |fifo_|, and processed by
- // |processing_callback_|.
- // Updated on processing thread. Read on capture and processing thread.
- int read_count_ GUARDED_BY(fifo_index_lock_) = 0;
- // Pre-allocated circular buffer of captured audio data, used to handoff data
- // from the capture thread to the processing thread.
- const int fifo_size_;
- std::vector<CaptureData> fifo_;
- // Expected format of captured audio data.
- const media::AudioParameters input_params_;
- // Real-time audio processing thread, on which |processing_callback_| is
- // called.
- RealtimeAudioThread audio_processing_thread_;
- // Processes captured audio data. Only run on |audio_processing_thread_|.
- ProcessAudioCallback processing_callback_;
- base::AtomicFlag fifo_stopping_;
- // Event signaling that there is new audio data to process. Called from the
- // capture thread, and waited for on the processing thread.
- base::WaitableEvent new_data_captured_;
- std::unique_ptr<StatsReporter> stats_reporter_;
- SEQUENCE_CHECKER(owning_sequence_checker_);
- };
- } // namespace audio
- #endif // SERVICES_AUDIO_PROCESSING_AUDIO_FIFO_H_
|