blob: 49288a4f9ac190dafbd706229b9e1b0cf4e2b8b9 [file] [log] [blame]
// Copyright 2019 The Fuchsia 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 SRC_MEDIA_AUDIO_AUDIO_CORE_EFFECTS_STAGE_H_
#define SRC_MEDIA_AUDIO_AUDIO_CORE_EFFECTS_STAGE_H_
#include <memory>
#include "src/media/audio/audio_core/audio_clock.h"
#include "src/media/audio/audio_core/cached_readable_stream_buffer.h"
#include "src/media/audio/audio_core/pipeline_config.h"
#include "src/media/audio/audio_core/stream.h"
#include "src/media/audio/audio_core/volume_curve.h"
#include "src/media/audio/lib/effects_loader/effects_processor.h"
namespace media::audio {
// An |EffectsStage| is a stream adapter that produces frames by reading them from a source
// |ReadableStream|, and then running a set of audio 'effects' on those frames.
class EffectsStage : public ReadableStream {
public:
struct RingoutBuffer {
static RingoutBuffer Create(const Format& format, const EffectsProcessor& processor);
static RingoutBuffer Create(const Format& format, uint32_t ringout_frames,
uint32_t max_batch_size, uint32_t block_size);
const uint32_t total_frames = 0;
const uint32_t buffer_frames = 0;
std::vector<float> buffer;
};
static std::shared_ptr<EffectsStage> Create(const std::vector<PipelineConfig::Effect>& effects,
std::shared_ptr<ReadableStream> source,
VolumeCurve volume_curve);
EffectsStage(std::shared_ptr<ReadableStream> source,
std::unique_ptr<EffectsProcessor> effects_processor, VolumeCurve volume_curve);
uint32_t block_size() const { return effects_processor_->block_size(); }
fit::result<void, fuchsia::media::audio::UpdateEffectError> UpdateEffect(
const std::string& instance_name, const std::string& config);
const EffectsProcessor& effects_processor() const { return *effects_processor_; }
// |media::audio::ReadableStream|
TimelineFunctionSnapshot ref_time_to_frac_presentation_frame() const override;
AudioClock& reference_clock() override { return source_->reference_clock(); }
std::optional<ReadableStream::Buffer> ReadLock(Fixed dest_frame, size_t frame_count) override;
void Trim(Fixed dest_frame) override { source_->Trim(dest_frame); }
void SetPresentationDelay(zx::duration external_delay) override;
void ReportUnderflow(Fixed frac_source_start, Fixed frac_source_mix_point,
zx::duration underflow_duration) override {
source_->ReportUnderflow(frac_source_start, frac_source_mix_point, underflow_duration);
}
void ReportPartialUnderflow(Fixed frac_source_offset, int64_t dest_mix_offset) override {
source_->ReportPartialUnderflow(frac_source_offset, dest_mix_offset);
}
private:
zx::duration ComputeIntrinsicMinLeadTime() const;
std::shared_ptr<ReadableStream> source_;
std::unique_ptr<EffectsProcessor> effects_processor_;
VolumeCurve volume_curve_;
// The last buffer returned from ReadLock, saved to prevent recomputing frames on
// consecutive calls to ReadLock. This is reset once the caller has unlocked the buffer,
// signifying that the buffer is no longer needed.
CachedReadableStreamBuffer cached_buffer_;
uint32_t ringout_frames_sent_ = 0;
int64_t next_ringout_frame_ = 0;
RingoutBuffer ringout_;
};
} // namespace media::audio
#endif // SRC_MEDIA_AUDIO_AUDIO_CORE_EFFECTS_STAGE_H_