SAL
A C++ library for spatial audio.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ambisonics.h
Go to the documentation of this file.
1 /*
2  ambisonics.h
3  Spatial Audio Library (SAL)
4  Copyright (c) 2012, Enzo De Sena
5  All rights reserved.
6 
7  This include contains definition of classes and functions
8  related to higer-order ambisonics.
9 
10  Authors: Enzo De Sena, enzodesena@gmail.com
11 
12  */
13 
14 #ifndef SAL_HOA_H
15 #define SAL_HOA_H
16 
17 
18 #include "microphone.h"
19 #include "point.h"
20 #include "decoder.h"
21 #include "microphonearray.h"
22 #include "salconstants.h"
23 #include "iirfilter.h"
24 
25 namespace sal {
26 
29  N3d,
32 };
33 
34 
35 class AmbisonicsMic : public Microphone {
36 public:
45  AmbisonicsMic(const mcl::Point& position, mcl::Quaternion orientation,
46  Int order, HoaNormalisation normalisation = HoaNormalisation::sqrt2,
47  HoaOrdering ordering = HoaOrdering::Acn) :
48  Microphone(position, orientation),
49  order_(order), normalisation_convention_(normalisation),
50  ordering_convention_(ordering) {}
51 
52  bool IsCoincident() const noexcept { return true; }
53 
54  Int num_channels() const noexcept {
55  return HoaBuffer::GetNumChannels(order_);
56  }
57 
58  static std::vector<mcl::Real> HorizontalEncoding(Int order, Angle theta);
59 
60  static bool Test();
61  virtual void AddPlaneWaveRelative(const Sample* input_data,
62  const Int num_samples,
63  const mcl::Point& point,
64  const Int wave_id,
65  Buffer& output_buffer) noexcept;
66 
67 
68 private:
69 
70  const Int order_;
71  HoaNormalisation normalisation_convention_;
72  HoaOrdering ordering_convention_;
73 };
74 
75 
80 class AmbisonicsHorizDec : public Decoder {
81 public:
98  AmbisonicsHorizDec(const Int order,
99  const bool energy_decoding,
100  const Time cut_off_frequency,
101  const std::vector<Angle>& loudspeaker_angles,
102  const bool near_field_correction,
103  const Length loudspeakers_distance,
104  const Time sampling_frequency,
105  const Speed sound_speed,
106  const HoaOrdering ordering_convention = HoaOrdering::Acn);
107 
108  virtual void Decode(const Buffer& input_buffer,
109  Buffer& output_buffer);
110 
111 
112  static bool Test();
113 
114  virtual ~AmbisonicsHorizDec() {}
115 
116 private:
117 
118  static mcl::Matrix<Sample>
119  ModeMatchingDec(Int order, const std::vector<Angle>& loudspeaker_angles);
120 
125  static mcl::Matrix<Sample>
126  MaxEnergyDec(Int order, const std::vector<Angle>& loudspeaker_angles);
127 
133  static Sample MaxEnergyDecWeight(Int index, Int order) {
134  return (Sample) cos(((Angle) index)*PI/(2.0*((Angle) order)+2.0));
135  }
136 
137  std::vector<Sample> GetFrame(const Int order, const Int sample_id,
138  const Buffer& buffer);
139 
150  static mcl::IirFilter NFCFilter(const Int order,
151  const Length loudspeaker_distance,
152  const Time sampling_frequency,
153  const Length sound_speed);
154 
155 
161  static mcl::IirFilter CrossoverFilterLow(const Time cut_off_frequency,
162  const Time sampling_frequency);
163  static mcl::IirFilter CrossoverFilterHigh(const Time cut_off_frequency,
164  const Time sampling_frequency);
165 
166  std::vector<Angle> loudspeaker_angles_;
167  Int num_loudspeakers_;
168  bool near_field_correction_;
169  Length loudspeakers_distance_;
170  bool energy_decoding_;
171  // Ambisonics order
172  Int order_;
173  HoaOrdering ordering_convention_;
174 
175  // One filter per component
176  std::vector<mcl::IirFilter> nfc_filters_;
177  // One filter per loudspeaker
178  std::vector<mcl::IirFilter> crossover_filters_high_;
179  std::vector<mcl::IirFilter> crossover_filters_low_;
180 
181  // Cache the decoding matrix (mode-matching) for performance purposes.
182  mcl::Matrix<Sample> mode_matching_matrix_;
183 
184  // Cache the decoding matrix (maximum energy) for performance purposes.
185  mcl::Matrix<Sample> max_energy_matrix_;
186 
187  Time sampling_frequency_;
188 };
189 
190 
191 } // namespace sal
192 
193 #endif
194