SAL
A C++ library for spatial audio.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
monomics.h
Go to the documentation of this file.
1 /*
2  omnimicrophones.h
3  Spatial Audio Library (SAL)
4  Copyright (c) 2011, Enzo De Sena
5  All rights reserved.
6 
7  Authors: Enzo De Sena, enzodesena@gmail.com
8 
9  */
10 
11 #ifndef SAL_DIRECTIVITYFUNCTION_H
12 #define SAL_DIRECTIVITYFUNCTION_H
13 
14 #include "point.h"
15 #include "salconstants.h"
16 #include "microphone.h"
17 #include "vectorop.h"
18 
19 
20 
21 namespace sal {
22 
23 class MonoMic : virtual public Microphone {
24 public:
25  MonoMic(mcl::Point position, mcl::Quaternion orientation) :
26  Microphone(position, orientation) {}
27 
30  Sample RecordPlaneWave(const Sample input_sample,
31  const mcl::Point& point,
32  const Int& wave_id = 0) noexcept {
33  MonoBuffer output_buffer(1);
34  AddPlaneWave(&input_sample, 1, point, wave_id, output_buffer);
35  return output_buffer.GetSample(0);
36  }
37 
38  bool IsCoincident() const noexcept { return true; }
39 
40  Int num_channels() const noexcept { return 1; }
41 
42  virtual ~MonoMic() {}
43 };
44 
45 
46 class MemorylessMic : virtual public Microphone {
47 public:
48  MemorylessMic(mcl::Point position, mcl::Quaternion orientation) :
49  Microphone(position, orientation) {}
50 
51  virtual ~MemorylessMic() {}
52 private:
53  virtual Sample GetDirectivity(const mcl::Point& point) = 0;
54 };
55 
56 
57 class MemorylessMonoMic : public MemorylessMic, public MonoMic {
58 public:
59  MemorylessMonoMic(mcl::Point position, mcl::Quaternion orientation) :
60  Microphone(position, orientation), MemorylessMic(position, orientation), MonoMic(position, orientation) {}
61 
62  virtual ~MemorylessMonoMic() {}
63 
64  virtual void AddPlaneWaveRelative(const Sample* input_data,
65  const Int num_samples,
66  const mcl::Point& point,
67  const Int /* wave_id */,
68  Buffer& output_buffer) noexcept {
69  ASSERT(output_buffer.num_channels() >= 1);
70  ASSERT(num_samples <= output_buffer.num_samples());
71 
72  mcl::MultiplyAdd(input_data,
73  GetDirectivity(point),
74  output_buffer.GetReadPointer(Buffer::kMonoChannel),
75  num_samples,
76  output_buffer.GetWritePointer(Buffer::kMonoChannel));
77  }
78 
79 private:
80 
81  virtual Sample GetDirectivity(const mcl::Point& point) = 0;
82 };
83 
84 
85 class GainMic : public MemorylessMonoMic {
86 public:
87  GainMic(mcl::Point position, Sample gain) :
88  Microphone(position, mcl::Quaternion::Identity()),
89  MemorylessMonoMic(position, mcl::Quaternion::Identity()),
90  gain_(gain) {}
91 
92  virtual bool IsOmni() const noexcept { return true; }
93 
94  virtual ~GainMic() {}
95 
96 private:
97  virtual Sample GetDirectivity(const mcl::Point& /* point */) {
98  return gain_;
99  }
100 
101  Sample gain_;
102 };
103 
104 
105 class OmniMic : public GainMic {
106 public:
107  OmniMic(mcl::Point position) :
108  Microphone(position, mcl::Quaternion::Identity()),
109  GainMic(position, (Sample) 1.0) {}
110 
111  virtual ~OmniMic() {}
112 };
113 
114 
120 class TrigMic : public MemorylessMonoMic {
121 public:
122  TrigMic(mcl::Point position, mcl::Quaternion orientation,
123  std::vector<Sample> coefficients) :
124  Microphone(position, orientation),
125  MemorylessMonoMic(position, orientation),
126  coefficients_(coefficients) {}
127 
128  virtual ~TrigMic() {}
129 private:
130  virtual Sample GetDirectivity(const mcl::Point& point) {
131  Angle phi = AngleBetweenPoints(point,
132  mcl::Point(1.0, 0.0, 0.0));
133 
134  const Int N = coefficients_.size();
135  Sample directivity(coefficients_[0]);
136  for (Int i=1; i<N; ++i) { directivity += coefficients_[i]*pow(cos(phi),i); }
137  return directivity;
138  }
139 
140  std::vector<Sample> coefficients_;
141 };
142 
143 
149 class TanMic : public MemorylessMonoMic {
150 public:
151  TanMic(mcl::Point position, mcl::Quaternion orientation,
152  sal::Sample base_angle) :
153  Microphone(position, orientation),
154  MemorylessMonoMic(position, orientation),
155  base_angle_(base_angle) {}
156 
157  virtual ~TanMic() {}
158 private:
159  virtual Sample GetDirectivity(const mcl::Point& point) {
160  Angle phi = AngleBetweenPoints(point, mcl::Point(1.0, 0.0, 0.0));
161 
162  sal::Angle phi_l = 0;
163  sal::Angle phi_lp1 = base_angle_; //PI/3.0;
164 
165  sal::Sample directivity;
166  if (phi < phi_lp1) {
167  directivity =
168  1.0/sqrt(1+pow(sin(phi-phi_l), 2.0)/pow(sin(phi_lp1-phi), 2.0));
169  } else { directivity = 0.0; }
170 
171  return directivity;
172  }
173 
174  sal::Sample base_angle_;
175 };
176 
177 
178 
179 
180 } // namespace sal
181 
182 #endif
183 
184 
185