1/*
2Copyright 2018 Google Inc. All Rights Reserved.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS-IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#ifndef RESONANCE_AUDIO_AMBISONICS_UTILS_H_
18#define RESONANCE_AUDIO_AMBISONICS_UTILS_H_
19
20#include <cmath>
21
22#include "base/constants_and_types.h"
23#include "base/logging.h"
24#include "base/misc_math.h"
25
26namespace vraudio {
27
28// Returns ACN channel sequence from a degree and order of a spherical harmonic.
29inline int AcnSequence(int degree, int order) {
30 DCHECK_GE(degree, 0);
31 DCHECK_LE(-degree, order);
32 DCHECK_LE(order, degree);
33
34 return degree * degree + degree + order;
35}
36
37// Returns normalization factor for Schmidt semi-normalized spherical harmonics
38// used in AmbiX.
39inline float Sn3dNormalization(int degree, int order) {
40 DCHECK_GE(degree, 0);
41 DCHECK_LE(-degree, order);
42 DCHECK_LE(order, degree);
43 return std::sqrt(x: (2.0f - ((order == 0) ? 1.0f : 0.0f)) *
44 Factorial(x: degree - std::abs(x: order)) /
45 Factorial(x: degree + std::abs(x: order)));
46}
47
48// Returns the number of spherical harmonics for a periphonic ambisonic sound
49// field of |ambisonic_order| at compile-time.
50// We have to use template metaprogramming because MSVC12 doesn't support
51// constexpr.
52template <size_t AmbisonicOrder>
53struct GetNumPeriphonicComponentsStatic {
54 enum { value = (AmbisonicOrder + 1) * (AmbisonicOrder + 1) };
55};
56
57// Returns the number of spherical harmonics for a periphonic ambisonic sound
58// field of |ambisonic_order|.
59inline size_t GetNumPeriphonicComponents(int ambisonic_order) {
60 return static_cast<size_t>((ambisonic_order + 1) * (ambisonic_order + 1));
61}
62
63// Returns the number of periphonic spherical harmonics (SHs) for a particular
64// Ambisonic order. E.g. number of 1st, 2nd or 3rd degree SHs in a 3rd order
65// sound field.
66inline size_t GetNumNthOrderPeriphonicComponents(int ambisonic_order) {
67 if (ambisonic_order == 0) return 1;
68 return static_cast<size_t>(GetNumPeriphonicComponents(ambisonic_order) -
69 GetNumPeriphonicComponents(ambisonic_order: ambisonic_order - 1));
70}
71
72// Calculates the ambisonic order of a periphonic sound field with the given
73// number of spherical harmonics.
74inline int GetPeriphonicAmbisonicOrder(size_t num_components) {
75 DCHECK_GT(num_components, 0);
76 const int ambisonic_order = static_cast<int>(std::sqrt(x: num_components)) - 1;
77 // Detect when num_components is not square.
78 DCHECK_EQ((ambisonic_order + 1) * (ambisonic_order + 1),
79 static_cast<int>(num_components));
80 return ambisonic_order;
81}
82
83// Calculates the order of the current spherical harmonic channel as the integer
84// part of a square root of the channel number. Please note, that in Ambisonics
85// the terms 'order' (usually denoted as 'n') and 'degree' (usually denoted as
86// 'm') are used in the opposite meaning as in more traditional maths or physics
87// conventions:
88// [1] C. Nachbar, F. Zotter, E. Deleflie, A. Sontacchi, "AMBIX - A SUGGESTED
89// AMBISONICS FORMAT", Proc. of the 2nd Ambisonics Symposium, June 2-3 2011,
90// Lexington, KY, https://goo.gl/jzt4Yy.
91inline int GetPeriphonicAmbisonicOrderForChannel(size_t channel) {
92 return static_cast<int>(sqrtf(x: static_cast<float>(channel)));
93}
94
95// Calculates the degree of the current spherical harmonic channel. Please note,
96// that in Ambisonics the terms 'order' (usually denoted as 'n') and 'degree'
97// (usually denoted as 'm') are used in the opposite meaning as in more
98// traditional maths or physics conventions:
99// [1] C. Nachbar, F. Zotter, E. Deleflie, A. Sontacchi, "AMBIX - A SUGGESTED
100// AMBISONICS FORMAT", Proc. of the 2nd Ambisonics Symposium, June 2-3 2011,
101// Lexington, KY, https://goo.gl/jzt4Yy.
102inline int GetPeriphonicAmbisonicDegreeForChannel(size_t channel) {
103 const int order = GetPeriphonicAmbisonicOrderForChannel(channel);
104 return static_cast<int>(channel) - order * (order + 1);
105}
106
107// Returns whether the given |num_channels| corresponds to a valid ambisonic
108// order configuration.
109inline bool IsValidAmbisonicOrder(size_t num_channels) {
110 if (num_channels == 0) {
111 return false;
112 }
113 // Number of channels must be a square number for valid ambisonic orders.
114 const size_t sqrt_num_channels = static_cast<size_t>(std::sqrt(x: num_channels));
115 return num_channels == sqrt_num_channels * sqrt_num_channels;
116}
117
118} // namespace vraudio
119
120#endif // RESONANCE_AUDIO_AMBISONICS_UTILS_H_
121

source code of qtmultimedia/src/3rdparty/resonance-audio/resonance_audio/ambisonics/utils.h