/* * Copyright 2023 jacqueline * * SPDX-License-Identifier: GPL-3.0-only */ #pragma once #include #include #include #include "samplerate.h" #include "audio_decoder.hpp" #include "audio_sink.hpp" #include "audio_source.hpp" #include "codec.hpp" #include "pipeline.hpp" #include "stream_info.hpp" namespace audio { /* * Handles the final downmix + resample + quantisation stage of audio, * generation sending the result directly to an IAudioSink. */ class SinkMixer { public: SinkMixer(StreamBufferHandle_t dest); ~SinkMixer(); auto MixAndSend(InputStream&, const StreamInfo::Pcm&) -> std::size_t; private: auto Main() -> void; auto SetTargetFormat(const StreamInfo::Pcm& format) -> void; auto HandleBytes() -> void; template auto ConvertFixedToFloating(InputStream&, OutputStream&) -> void; auto Resample(float, int, InputStream&, OutputStream&) -> void; template auto Quantise(InputStream&) -> std::size_t; enum class Command { kReadBytes, kSetSourceFormat, kSetTargetFormat, }; struct Args { Command cmd; StreamInfo::Pcm format; }; QueueHandle_t commands_; SemaphoreHandle_t is_idle_; SRC_STATE* resampler_; std::unique_ptr input_stream_; std::unique_ptr floating_point_stream_; std::unique_ptr resampled_stream_; cpp::span quantisation_buffer_; cpp::span quantisation_buffer_as_shorts_; cpp::span quantisation_buffer_as_ints_; StreamInfo::Pcm target_format_; StreamBufferHandle_t source_; StreamBufferHandle_t sink_; }; template <> auto SinkMixer::ConvertFixedToFloating(InputStream&, OutputStream&) -> void; template <> auto SinkMixer::ConvertFixedToFloating(InputStream&, OutputStream&) -> void; template <> auto SinkMixer::Quantise(InputStream&) -> std::size_t; template <> auto SinkMixer::Quantise(InputStream&) -> std::size_t; } // namespace audio