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