| 1 | /* |
| 2 | Copyright 2018 Google Inc. All Rights Reserved. |
| 3 | |
| 4 | Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | you may not use this file except in compliance with the License. |
| 6 | You may obtain a copy of the License at |
| 7 | |
| 8 | http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | |
| 10 | Unless required by applicable law or agreed to in writing, software |
| 11 | distributed under the License is distributed on an "AS-IS" BASIS, |
| 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | See the License for the specific language governing permissions and |
| 14 | limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | #ifndef RESONANCE_AUDIO_GRAPH_BINAURAL_SURROUND_RENDERER_IMPL_H_ |
| 18 | #define RESONANCE_AUDIO_GRAPH_BINAURAL_SURROUND_RENDERER_IMPL_H_ |
| 19 | |
| 20 | #include <memory> |
| 21 | #include <string> |
| 22 | |
| 23 | #include "api/binaural_surround_renderer.h" |
| 24 | #include "api/resonance_audio_api.h" |
| 25 | #include "base/constants_and_types.h" |
| 26 | #include "utils/buffer_partitioner.h" |
| 27 | #include "utils/buffer_unpartitioner.h" |
| 28 | #include "utils/threadsafe_fifo.h" |
| 29 | |
| 30 | namespace vraudio { |
| 31 | |
| 32 | // Renders virtual surround sound as well as ambisonic soundfields to binaural |
| 33 | // stereo. |
| 34 | class BinauralSurroundRendererImpl : public BinauralSurroundRenderer { |
| 35 | public: |
| 36 | // Constructor. |
| 37 | // |
| 38 | // @param frames_per_buffer Number of frames in output buffer. |
| 39 | // @param sample_rate_hz Sample rate of audio buffers. |
| 40 | BinauralSurroundRendererImpl(size_t frames_per_buffer, int sample_rate_hz); |
| 41 | |
| 42 | ~BinauralSurroundRendererImpl() override{}; |
| 43 | |
| 44 | // Initializes surround sound decoding. |
| 45 | // |
| 46 | // @param surround_format Surround sound input format. |
| 47 | // @return True on success. |
| 48 | bool Init(SurroundFormat surround_format); |
| 49 | |
| 50 | // Implements |AudioRenderer| interface. |
| 51 | void SetStereoSpeakerMode(bool enabled) override; |
| 52 | size_t GetNumAvailableFramesInInputBuffer() const override; |
| 53 | size_t AddInterleavedInput(const int16* input_buffer_ptr, size_t num_channels, |
| 54 | size_t num_frames) override; |
| 55 | size_t AddInterleavedInput(const float* input_buffer_ptr, size_t num_channels, |
| 56 | size_t num_frames) override; |
| 57 | size_t AddPlanarInput(const int16* const* input_buffer_ptrs, |
| 58 | size_t num_channels, size_t num_frames) override; |
| 59 | size_t AddPlanarInput(const float* const* input_buffer_ptrs, |
| 60 | size_t num_channels, size_t num_frames) override; |
| 61 | size_t GetAvailableFramesInStereoOutputBuffer() const override; |
| 62 | size_t GetInterleavedStereoOutput(int16* output_buffer_ptr, |
| 63 | size_t num_frames) override; |
| 64 | size_t GetInterleavedStereoOutput(float* output_buffer_ptr, |
| 65 | size_t num_frames) override; |
| 66 | size_t GetPlanarStereoOutput(int16** output_buffer_ptrs, |
| 67 | size_t num_frames) override; |
| 68 | size_t GetPlanarStereoOutput(float** output_buffer_ptrs, |
| 69 | size_t num_frames) override; |
| 70 | bool TriggerProcessing() override; |
| 71 | void Clear() override; |
| 72 | void SetHeadRotation(float w, float x, float y, float z) override; |
| 73 | |
| 74 | protected: |
| 75 | // Protected default constructor for mock tests. |
| 76 | BinauralSurroundRendererImpl(); |
| 77 | |
| 78 | private: |
| 79 | // Callback triggered by |buffer_partitioner_| whenever a new |AudioBuffer| |
| 80 | // has been generated. |
| 81 | // |
| 82 | // @param processed_buffer Pointer to processed buffer. |
| 83 | // @return Pointer to next |AudioBuffer| to be filled up. |
| 84 | AudioBuffer* BufferPartitionerCallback(AudioBuffer* processed_buffer); |
| 85 | |
| 86 | // Helper method to implement |AddInterleavedInput| independently from the |
| 87 | // sample type. |
| 88 | // |
| 89 | // @tparam BufferType Input buffer type. |
| 90 | // @param input_buffer_ptr Pointer to interleaved input data. |
| 91 | // @param num_channels Number of channels in input buffer. |
| 92 | // @param num_frames Number of frames in input buffer. |
| 93 | // @return The number of consumed samples. |
| 94 | template <typename BufferType> |
| 95 | size_t AddInputBufferTemplated(const BufferType input_buffer_ptr, |
| 96 | size_t num_channels, size_t num_frames); |
| 97 | |
| 98 | // Helper method to implement |GetInterleavedOutput| independently from the |
| 99 | // sample type. |
| 100 | // |
| 101 | // @tparam BufferType Output buffer type. |
| 102 | // @param output_buffer_ptr Pointer to allocated interleaved output buffer. |
| 103 | // @param num_frames Size of output buffer in frames. |
| 104 | // @return The number of consumed frames. |
| 105 | template <typename BufferType> |
| 106 | size_t GetStereoOutputBufferTemplated(BufferType output_buffer_ptr, |
| 107 | size_t num_frames); |
| 108 | |
| 109 | // Helper method to obtain the expected number of audio channels for a given |
| 110 | // surround format. |
| 111 | // |
| 112 | // @param surround_format Surround format query. |
| 113 | // @return Number of audio channels. |
| 114 | static size_t GetExpectedNumChannelsFromSurroundFormat( |
| 115 | SurroundFormat surround_format); |
| 116 | |
| 117 | // Process method executed by |buffer_unpartitioner_|. |
| 118 | AudioBuffer* ProcessBuffer(); |
| 119 | |
| 120 | // Initializes binaural mono rendering. |
| 121 | void InitializeBinauralMono(); |
| 122 | |
| 123 | // Initializes binaural stereo rendering. |
| 124 | void InitializeBinauralStereo(); |
| 125 | |
| 126 | // Initializes binaural 5.1 rendering. |
| 127 | void InitializeBinauralSurround5dot1(); |
| 128 | |
| 129 | // Initializes binaural 7.1 rendering. |
| 130 | void InitializeBinauralSurround7dot1(); |
| 131 | |
| 132 | // Initializes binaural ambisonic rendering. |
| 133 | void InitializeAmbisonics(); |
| 134 | |
| 135 | // Initializes binaural ambisonic rendering with non-diegetic stereo. |
| 136 | void InitializeAmbisonicsWithNonDiegeticStereo(); |
| 137 | |
| 138 | // Creates a sound object at given angle within the horizontal listener plane. |
| 139 | SourceId CreateSoundObject(float azimuth_deg); |
| 140 | |
| 141 | // Initializes room reverb for virtual surround sound rendering. |
| 142 | void InitializeRoomReverb(); |
| 143 | |
| 144 | // ResonanceAudioApi instance. |
| 145 | std::unique_ptr<ResonanceAudioApi> resonance_audio_api_; |
| 146 | |
| 147 | // Frames per buffer. |
| 148 | const size_t frames_per_buffer_; |
| 149 | |
| 150 | // System sample rate. |
| 151 | const int sample_rate_hz_; |
| 152 | |
| 153 | // Selected surround sound format. |
| 154 | SurroundFormat surround_format_; |
| 155 | |
| 156 | // Number of input channels. |
| 157 | size_t num_input_channels_; |
| 158 | |
| 159 | // Partitions input buffers into |AudioBuffer|s. |
| 160 | std::unique_ptr<BufferPartitioner> buffer_partitioner_; |
| 161 | |
| 162 | // Buffer queue containing partitioned input |AudioBuffer|s. |
| 163 | std::unique_ptr<ThreadsafeFifo<AudioBuffer>> input_audio_buffer_queue_; |
| 164 | |
| 165 | // Binaural stereo output buffer. |
| 166 | AudioBuffer output_buffer_; |
| 167 | |
| 168 | // Unpartitions processed |AudioBuffer|s into interleaved output buffers. |
| 169 | std::unique_ptr<BufferUnpartitioner> buffer_unpartitioner_; |
| 170 | |
| 171 | // Vector containing the source ids of all rendered sound sources. |
| 172 | std::vector<SourceId> source_ids_; |
| 173 | |
| 174 | // Total number of frames currently buffered. |
| 175 | size_t total_frames_buffered_; |
| 176 | |
| 177 | // Total number of zero padded frames from |TriggerProcessing| calls. |
| 178 | size_t num_zero_padded_frames_; |
| 179 | |
| 180 | // Temporary buffer to store pointers to planar ambisonic and stereo channels. |
| 181 | std::vector<const float*> temp_planar_buffer_ptrs_; |
| 182 | |
| 183 | // Global output gain adjustment, to avoid clipping of individual channels |
| 184 | // in virtual speaker modes. |
| 185 | float output_gain_; |
| 186 | }; |
| 187 | |
| 188 | } // namespace vraudio |
| 189 | |
| 190 | #endif // RESONANCE_AUDIO_GRAPH_BINAURAL_SURROUND_RENDERER_IMPL_H_ |
| 191 | |