17#ifndef RESONANCE_AUDIO_AMBISONICS_UTILS_H_
18#define RESONANCE_AUDIO_AMBISONICS_UTILS_H_
22#include "base/constants_and_types.h"
23#include "base/logging.h"
24#include "base/misc_math.h"
29inline int AcnSequence(
int degree,
int order) {
31 DCHECK_LE(-degree, order);
32 DCHECK_LE(order, degree);
34 return degree * degree + degree + order;
39inline float Sn3dNormalization(
int degree,
int order) {
41 DCHECK_LE(-degree, order);
42 DCHECK_LE(order, degree);
43 return std::sqrt((2.0f - ((order == 0) ? 1.0f : 0.0f)) *
44 Factorial(degree - std::abs(order)) /
45 Factorial(degree + std::abs(order)));
52template <
size_t AmbisonicOrder>
54 enum { value = (AmbisonicOrder + 1) * (AmbisonicOrder + 1) };
59inline size_t GetNumPeriphonicComponents(
int ambisonic_order) {
60 return static_cast<size_t>((ambisonic_order + 1) * (ambisonic_order + 1));
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 - 1));
74inline int GetPeriphonicAmbisonicOrder(
size_t num_components) {
75 DCHECK_GT(num_components, 0);
76 const int ambisonic_order =
static_cast<int>(std::sqrt(num_components)) - 1;
78 DCHECK_EQ((ambisonic_order + 1) * (ambisonic_order + 1),
79 static_cast<int>(num_components));
80 return ambisonic_order;
91inline int GetPeriphonicAmbisonicOrderForChannel(
size_t channel) {
92 return static_cast<int>(sqrtf(
static_cast<float>(channel)));
102inline int GetPeriphonicAmbisonicDegreeForChannel(
size_t channel) {
103 const int order = GetPeriphonicAmbisonicOrderForChannel(channel);
104 return static_cast<int>(channel) - order * (order + 1);
109inline bool IsValidAmbisonicOrder(
size_t num_channels) {
110 if (num_channels == 0) {
114 const size_t sqrt_num_channels =
static_cast<size_t>(std::sqrt(num_channels));
115 return num_channels == sqrt_num_channels * sqrt_num_channels;