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