blob: 7591591177d3e846c7ace01a1c5a9596e0f635c5 [file] [log] [blame]
// Copyright 2018 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.
#include <zircon/types.h>
#include <vector>
#include "src/media/audio/lib/effects_loader/effect.h"
namespace media::audio {
// EffectsProcessor represents a queue of active effect instances and manages chaining calls of
// Process/ProcessInPlace through a chain of effects.
// This class is designed to be used synchronously and is not explicitly multi-thread-safe.
class EffectsProcessor {
// Creates a new, empty effects processor.
EffectsProcessor() = default;
// Allow move.
EffectsProcessor(EffectsProcessor&& o) noexcept;
EffectsProcessor& operator=(EffectsProcessor&& o) noexcept;
// Disallow copy.
EffectsProcessor(const EffectsProcessor&) = delete;
EffectsProcessor& operator=(const EffectsProcessor&) = delete;
// Adds an `Effect` to the end of the queue of effects included in this processor.
// When the first `Effect` is added, that effects input channels becomes the input to the entire
// processor. Likewise that effects output channels becomes the processors output channels.
// When subsequent effects are added, the new effects input channels must match exactly the out-
// put channels of last added effect. The output channels for the processor will be updated to
// match the output channels of the newly added effect.
// Currently AddEffect will fail if an Effect has channels_in != channels_out (ex: all effects
// must do in-place processing). This is a short-term limitation that will be lifted in the
// future.
// Aborts if `e` is an invalid `Effect`.
zx_status_t AddEffect(Effect e);
// Returns the number of active instances in the enclosed effect chain.
[[nodiscard]] uint16_t size() const { return effects_chain_.size(); }
// Returns the number of input channels for this effect. This will be the number of channels
// expected for input frames to `ProcessInPlace`.
// Returns 0 if this processor has no effects.
[[nodiscard]] uint32_t channels_in() const { return channels_in_; }
// Returns the number of output channels for this effect. Currently this always equals
// `channels_in()`.
// Returns 0 if this processor has no effects.
[[nodiscard]] uint32_t channels_out() const { return channels_out_; }
[[nodiscard]] auto begin() { return effects_chain_.begin(); }
[[nodiscard]] auto end() { return effects_chain_.end(); }
[[nodiscard]] auto cbegin() const { return effects_chain_.cbegin(); }
[[nodiscard]] auto cend() const { return effects_chain_.cend(); }
// Returns the instance at the specified (zero-based) position in the chain.
[[nodiscard]] const Effect& GetEffectAt(size_t position) const;
// These maps directly to the corresponding ABI call, for each instance.
zx_status_t ProcessInPlace(uint32_t num_frames, float* audio_buff_in_out) const;
zx_status_t Flush() const;
std::vector<Effect> effects_chain_;
uint32_t channels_in_ = 0;
uint32_t channels_out_ = 0;
} // namespace media::audio