1 /* 2 * Copyright (c) 2024, Alliance for Open Media. All rights reserved 3 * 4 * This source code is subject to the terms of the BSD 3-Clause Clear License 5 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear 6 * License was not distributed with this source code in the LICENSE file, you 7 * can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the 8 * Alliance for Open Media Patent License 1.0 was not distributed with this 9 * source code in the PATENTS file, you can obtain it at 10 * www.aomedia.org/license/patent. 11 */ 12 #ifndef CLI_INTERNAL_RENDERER_AUDIO_ELEMENT_RENDERER_AMBISONICS_TO_CHANNEL_H_ 13 #define CLI_INTERNAL_RENDERER_AUDIO_ELEMENT_RENDERER_AMBISONICS_TO_CHANNEL_H_ 14 #include <cstddef> 15 #include <memory> 16 #include <vector> 17 18 #include "absl/base/thread_annotations.h" 19 #include "absl/status/status.h" 20 #include "absl/types/span.h" 21 #include "iamf/cli/audio_element_with_data.h" 22 #include "iamf/cli/channel_label.h" 23 #include "iamf/cli/renderer/audio_element_renderer_base.h" 24 #include "iamf/obu/audio_element.h" 25 #include "iamf/obu/mix_presentation.h" 26 #include "iamf/obu/types.h" 27 28 namespace iamf_tools { 29 30 /*!\brief Renders demixed channels to the requested output layout. 31 * 32 * This class represents a renderer which is suitable for use for a scene-based 33 * audio element being rendered to loudspeakers according to IAMF Spec 7.3.2.2 34 * (https://aomediacodec.github.io/iamf/#processing-mixpresentation-rendering-a2l). 35 * 36 * - Call `RenderAudioFrame()` to render a labeled frame. The rendering may 37 * happen asynchronously. 38 * - Call `SamplesAvailable()` to see if there are samples available. 39 * - Call `Flush()` to retrieve finished frames, in the order they were 40 * received by `RenderLabeledFrame()`. 41 * - Call `Finalize()` to close the renderer, telling it to finish rendering 42 * any remaining frames, which can be retrieved one last time via `Flush()`. 43 * After calling `Finalize()`, any subsequent call to `RenderAudioFrame()` 44 * may fail. 45 */ 46 class AudioElementRendererAmbisonicsToChannel 47 : public AudioElementRendererBase { 48 public: 49 /*!\brief Creates a renderer from an ambisonics-based config. 50 * 51 * \param ambisonics_config Config for the ambisonics layout. 52 * \param audio_substream_ids Audio substream IDs. 53 * \param substream_id_to_labels Mapping of substream IDs to labels. 54 * \param playback_layout Layout of the audio element to be rendered. 55 * \param num_samples_per_frame Number of samples per frame. 56 * \return Render to use or `nullptr` on failure. 57 */ 58 static std::unique_ptr<AudioElementRendererAmbisonicsToChannel> 59 CreateFromAmbisonicsConfig( 60 const AmbisonicsConfig& ambisonics_config, 61 const std::vector<DecodedUleb128>& audio_substream_ids, 62 const SubstreamIdLabelsMap& substream_id_to_labels, 63 const Layout& playback_layout, size_t num_samples_per_frame); 64 65 /*!\brief Destructor. */ 66 ~AudioElementRendererAmbisonicsToChannel() override = default; 67 68 private: 69 /*!\brief Constructor. 70 * 71 * Used only by the factory method. 72 * 73 * \param num_output_channels Number of output channels. 74 * \param ambisonics_config Config for the ambisonics layout. 75 * \param ordered_labels Ordered list of channel labels to render. 76 * \param gains Gains matrix. 77 */ AudioElementRendererAmbisonicsToChannel(size_t num_output_channels,size_t num_samples_per_frame,const AmbisonicsConfig & ambisonics_config,const std::vector<ChannelLabel::Label> & ordered_labels,const std::vector<std::vector<double>> & gains)78 AudioElementRendererAmbisonicsToChannel( 79 size_t num_output_channels, size_t num_samples_per_frame, 80 const AmbisonicsConfig& ambisonics_config, 81 const std::vector<ChannelLabel::Label>& ordered_labels, 82 const std::vector<std::vector<double>>& gains) 83 : AudioElementRendererBase(ordered_labels, num_samples_per_frame, 84 num_output_channels), 85 ambisonics_config_(ambisonics_config), 86 gains_(gains) {} 87 88 /*!\brief Renders samples. 89 * 90 * \param samples_to_render Samples to render arranged in (time, channel). 91 * \param rendered_samples Output rendered samples. 92 * \return `absl::OkStatus()` on success. A specific status on failure. 93 */ 94 absl::Status RenderSamples( 95 absl::Span<const std::vector<InternalSampleType>> samples_to_render, 96 std::vector<InternalSampleType>& rendered_samples) 97 ABSL_SHARED_LOCKS_REQUIRED(mutex_) override; 98 99 const AmbisonicsConfig ambisonics_config_; 100 101 std::vector<std::vector<double>> gains_; 102 }; 103 104 } // namespace iamf_tools 105 #endif // CLI_INTERNAL_RENDERER_AUDIO_ELEMENT_RENDERER_AMBISONICS_TO_CHANNEL_H_ 106