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 | |