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_API_BINAURAL_SURROUND_RENDERER_H_ |
18 | #define RESONANCE_AUDIO_API_BINAURAL_SURROUND_RENDERER_H_ |
19 | |
20 | #include <stddef.h> |
21 | #include <stdint.h> |
22 | |
23 | // Avoid dependency to base/integral_types.h |
24 | typedef int16_t int16; |
25 | |
26 | namespace vraudio { |
27 | |
28 | // Renders virtual surround sound as well as ambisonic soundfields to binaural |
29 | // stereo. |
30 | class BinauralSurroundRenderer { |
31 | public: |
32 | |
33 | enum SurroundFormat { |
34 | // Enables to initialize a yet undefined rendering mode. |
35 | kInvalid = 0, |
36 | |
37 | // Binaurally renders a single virtual speaker at 0 degrees in front. |
38 | kSurroundMono = 1, |
39 | |
40 | // Binaurally renders virtual stereo speakers at -30 degrees and +30 |
41 | // degrees. |
42 | kSurroundStereo = 2, |
43 | |
44 | // Binaurally renders 5.1 surround sound according to the ITU-R BS.775-3 |
45 | // speaker configuration recommendation: |
46 | // - Left (L) at 30 degrees. |
47 | // - Right (R) at -30 degrees. |
48 | // - Center (C) at 0 degrees. |
49 | // - Low frequency effects (LFE) at front center at 0 degrees. |
50 | // - Left surround (LS) at 110 degrees. |
51 | // - Right surround (RS) at -110 degrees. |
52 | // |
53 | // The 5.1 channel input layout must matches AAC: L, R, C, LFE, LS, RS. |
54 | // Note that this differs from the Vorbis/Opus 5.1 channel layout, which |
55 | // is: L, C, R, LS, RS, LFE. |
56 | kSurroundFiveDotOne = 3, |
57 | |
58 | // Binaurally renders 7.1 surround sound according to the ITU-R BS.775-3 |
59 | // speaker configuration recommendation: |
60 | // - Left (FL) at 30 degrees. |
61 | // - Right (FR) at -30 degrees. |
62 | // - Center (C) at 0 degrees. |
63 | // - Low frequency effects (LFE) at front center at 0 degrees. |
64 | // - Left surround 1 (LS1) at 90 degrees. |
65 | // - Right surround 1 (RS1) at -90 degrees. |
66 | // - Left surround 2 (LS2) at 150 degrees. |
67 | // - Right surround 2 (LS2) at -150 degrees. |
68 | // |
69 | // The 7.1 channel input layout must matches AAC: L, R, C, LFE, LS1, RS1, |
70 | // LS2, RS2. |
71 | // Note that this differs from the Vorbis/Opus 7.1 channel layout, which |
72 | // is: L, C, R, LS1, RS1, LS2, RS2, LFE. |
73 | kSurroundSevenDotOne = 10, |
74 | |
75 | // Binaurally renders first-order ambisonics |
76 | // (AmbiX format: 4 channels, ACN channel ordering, SN3D normalization). |
77 | kFirstOrderAmbisonics = 4, |
78 | |
79 | // Binaurally renders second-order ambisonics. |
80 | // (AmbiX format: 9 channels, ACN channel ordering, SN3D normalization). |
81 | kSecondOrderAmbisonics = 5, |
82 | |
83 | // Binaurally renders third-order ambisonics. |
84 | // (AmbiX format: 16 channels, ACN channel ordering, SN3D normalization). |
85 | kThirdOrderAmbisonics = 6, |
86 | |
87 | // Binaurally renders first-order ambisonics with a non-diegetic-stereo |
88 | // track. The first 4 channels contain ambisonic AmbiX format. |
89 | // (AmbiX format: 4 channels, ACN channel ordering, SN3D normalization). |
90 | // Channel 5 to 6 contain non-diegetic-stereo. |
91 | kFirstOrderAmbisonicsWithNonDiegeticStereo = 7, |
92 | |
93 | // Binaurally renders second-order ambisonics with a non-diegetic-stereo |
94 | // track. The first 9 channels contain ambisonic AmbiX format. |
95 | // (AmbiX format: 9 channels, ACN channel ordering, SN3D normalization). |
96 | // Channel 10 to 11 contain non-diegetic-stereo. |
97 | kSecondOrderAmbisonicsWithNonDiegeticStereo = 8, |
98 | |
99 | // Binaurally renders third-order ambisonics with a non-diegetic-stereo |
100 | // track. The first 16 channels contain ambisonic AmbiX format. |
101 | // (AmbiX format: 16 channels, ACN channel ordering, SN3D normalization). |
102 | // Channel 17 to 18 contain non-diegetic-stereo. |
103 | kThirdOrderAmbisonicsWithNonDiegeticStereo = 9, |
104 | |
105 | // Note: Next available value is: 11 |
106 | }; |
107 | |
108 | |
109 | virtual ~BinauralSurroundRenderer() {} |
110 | |
111 | // Factory method to create a |BinauralSurroundRenderer| instance. Caller must |
112 | // take ownership of returned instance and destroy it via operator delete. |
113 | // |
114 | // @param frames_per_buffer Number of frames in output buffer. |
115 | // @param sample_rate_hz Sample rate of audio buffers. |
116 | // @param surround_format Input surround sound format. |
117 | // @param return |BinauralSurroundRenderer| instance, nullptr if creation |
118 | // fails. |
119 | static BinauralSurroundRenderer* Create(size_t frames_per_buffer, |
120 | int sample_rate_hz, |
121 | SurroundFormat surround_format); |
122 | |
123 | // Enables the stereo speaker mode. When activated, it disables HRTF-based |
124 | // filtering and switches to computationally cheaper stereo-panning. This |
125 | // helps to avoid HRTF-based coloring effects when stereo speakers are used |
126 | // and reduces computational complexity when headphone-based HRTF filtering is |
127 | // not needed. By default the stereo speaker mode is disabled. |
128 | // |
129 | // @param enabled Flag to enable stereo speaker mode. |
130 | virtual void SetStereoSpeakerMode(bool enabled) = 0; |
131 | |
132 | // Returns the number of frames the input buffer is currently able to consume. |
133 | // |
134 | // @return Number of available frames in input buffer. |
135 | virtual size_t GetNumAvailableFramesInInputBuffer() const = 0; |
136 | |
137 | // Adds interleaved int16 audio data to the renderer. If enough data has been |
138 | // provided for an output buffer to be generated then it will be immediately |
139 | // available via |Get[Interleaved|Planar]StereoOutputBuffer|. The input data |
140 | // is copied into an internal buffer which allows the caller to re-use the |
141 | // input buffer immediately. The available space in the internal buffer can be |
142 | // obtained via |GetAvailableInputSizeSamples|. |
143 | // |
144 | // @param input_buffer_ptr Pointer to interleaved input data. |
145 | // @param num_channels Number of channels in input buffer. |
146 | // @param num_frames Number of frames in input buffer. |
147 | // @return The number of consumed frames. |
148 | virtual size_t AddInterleavedInput(const int16* input_buffer_ptr, |
149 | size_t num_channels, |
150 | size_t num_frames) = 0; |
151 | |
152 | // Adds interleaved floating point audio data to the renderer. If enough data |
153 | // has been provided for an output buffer to be generated then it will be |
154 | // immediately available via |Get[Interleaved|Planar]StereoOutputBuffer|. The |
155 | // input data is copied into an internal buffer which allows the caller to |
156 | // re-use the input buffer immediately. The available space in the internal |
157 | // buffer can be obtained via |GetAvailableInputSizeSamples|. |
158 | // |
159 | // @param input_buffer_ptr Pointer to interleaved input data. |
160 | // @param num_channels Number of channels in input buffer. |
161 | // @param num_frames Number of frames in input buffer. |
162 | // @return The number of consumed frames. |
163 | virtual size_t AddInterleavedInput(const float* input_buffer_ptr, |
164 | size_t num_channels, |
165 | size_t num_frames) = 0; |
166 | |
167 | // Adds planar int16 audio data to the renderer. If enough data has |
168 | // been provided for an output buffer to be generated then it will be |
169 | // immediately available via |Get[Interleaved|Planar]StereoOutputBuffer|. The |
170 | // input data is copied into an internal buffer which allows the caller to |
171 | // re-use the input buffer immediately. The available space in the internal |
172 | // buffer can be obtained via |GetAvailableInputSizeSamples|. |
173 | // |
174 | // @param input_buffer_ptrs Array of pointers to planar channel data. |
175 | // @param num_channels Number of channels in input buffer. |
176 | // @param num_frames Number of frames in input buffer. |
177 | // @return The number of consumed frames. |
178 | virtual size_t AddPlanarInput(const int16* const* input_buffer_ptrs, |
179 | size_t num_channels, size_t num_frames) = 0; |
180 | |
181 | // Adds planar floating point audio data to the renderer. If enough data has |
182 | // been provided for an output buffer to be generated then it will be |
183 | // immediately available via |Get[Interleaved|Planar]StereoOutputBuffer|. The |
184 | // input data is copied into an internal buffer which allows the caller to |
185 | // re-use the input buffer immediately. The available space in the internal |
186 | // buffer can be obtained via |GetAvailableInputSizeSamples|. |
187 | // |
188 | // @param input_buffer_ptrs Array of pointers to planar channel data. |
189 | // @param num_channels Number of channels in input buffer. |
190 | // @param num_frames Number of frames in input buffer. |
191 | // @return The number of consumed frames. |
192 | virtual size_t AddPlanarInput(const float* const* input_buffer_ptrs, |
193 | size_t num_channels, size_t num_frames) = 0; |
194 | |
195 | // Returns the number of samples available in the output buffer. |
196 | // |
197 | // @return Number of available samples in output buffer. |
198 | virtual size_t GetAvailableFramesInStereoOutputBuffer() const = 0; |
199 | |
200 | // Gets a processed output buffer in interleaved int16 format. |
201 | // |
202 | // @param output_buffer_ptr Pointer to allocated interleaved output buffer. |
203 | // @param num_frames Size of output buffer in frames. |
204 | // @return The number of consumed frames. |
205 | virtual size_t GetInterleavedStereoOutput(int16* output_buffer_ptr, |
206 | size_t num_frames) = 0; |
207 | |
208 | // Gets a processed output buffer in interleaved float format. |
209 | // |
210 | // @param output_buffer_ptr Pointer to allocated interleaved output buffer. |
211 | // @param num_frames Size of output buffer in frames. |
212 | // @return The number of consumed frames. |
213 | virtual size_t GetInterleavedStereoOutput(float* output_buffer_ptr, |
214 | size_t num_frames) = 0; |
215 | |
216 | // Gets a processed output buffer in planar int16 point format. |
217 | // |
218 | // @param output_buffer_ptrs Array of pointers to planar channel data. |
219 | // @param num_frames Number of frames in output buffer. |
220 | // @return The number of consumed frames. |
221 | virtual size_t GetPlanarStereoOutput(int16** output_buffer_ptrs, |
222 | size_t num_frames) = 0; |
223 | |
224 | // Gets a processed output buffer in planar floating point format. |
225 | // |
226 | // @param output_buffer_ptrs Array of pointers to planar channel data. |
227 | // @param num_frames Number of frames in output buffer. |
228 | // @return The number of consumed frames. |
229 | virtual size_t GetPlanarStereoOutput(float** output_buffer_ptrs, |
230 | size_t num_frames) = 0; |
231 | |
232 | // Removes all buffered input and processed output buffers from the buffer |
233 | // queues. |
234 | virtual void Clear() = 0; |
235 | |
236 | // Triggers the processing of data that has been input but not yet processed. |
237 | // Note after calling this method, all processed output must be consumed via |
238 | // |Get[Interleaved|Planar]StereoOutputBuffer| before adding new input |
239 | // buffers. |
240 | // |
241 | // @return Whether any data was processed. |
242 | virtual bool TriggerProcessing() = 0; |
243 | |
244 | // Updates the head rotation. |
245 | // |
246 | // @param w W component of quaternion. |
247 | // @param x X component of quaternion. |
248 | // @param y Y component of quaternion. |
249 | // @param z Z component of quaternion. |
250 | virtual void SetHeadRotation(float w, float x, float y, float z) = 0; |
251 | }; |
252 | |
253 | } // namespace vraudio |
254 | |
255 | #endif // RESONANCE_AUDIO_API_BINAURAL_SURROUND_RENDERER_H_ |
256 | |