Nsound  0.9.4
ReverberationRoom.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 //
3 // $Id: ReverberationRoom.cc 874 2014-09-08 02:21:29Z weegreenblobbie $
4 //
5 // Copyright (c) 2008 to Present Nick Hilton
6 //
7 // weegreenblobbie_yahoo_com (replace '_' with '@' and '.')
8 //
9 //-----------------------------------------------------------------------------
10 
11 //-----------------------------------------------------------------------------
12 //
13 // This program is free software; you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation; either version 2 of the License, or
16 // (at your option) any later version.
17 //
18 // This program is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU Library General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with this program; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 //
27 //-----------------------------------------------------------------------------////
28 
29 #include <Nsound/AudioStream.h>
30 #include <Nsound/Buffer.h>
31 #include <Nsound/FilterAllPass.h>
34 
35 #include <ctime>
36 #include <cstdlib>
37 
38 using namespace Nsound;
39 
40 using std::cerr;
41 using std::endl;
42 
43 #define CERR_HEADER __FILE__ << ":" << __LINE__ << ": "
44 
45 const
46 float64
48 COMB_DELAY_TIME_SECONDS_[N_COMB_FILTERS_] =
49 {
50  1116.0 / 44100.0,
51  1188.0 / 44100.0,
52  1277.0 / 44100.0,
53  1356.0 / 44100.0,
54  1422.0 / 44100.0,
55  1491.0 / 44100.0,
56  1557.0 / 44100.0,
57  1617.0 / 44100.0
58 };
59 
60 const
61 float64
63 ALL_PASS_DELAY_TIME_SECONDS_[N_ALL_PASS_FILTERS_] =
64 {
65  556.0 / 44100.0,
66  441.0 / 44100.0,
67  341.0 / 44100.0,
68  225.0 / 44100.0
69 };
70 
71 const
72 float64
75 
76 const
77 float64
80 
81 
82 //-----------------------------------------------------------------------------
83 float64
85 {
86  return static_cast<float64>(rand() / (RAND_MAX + 1.0));
87 }
88 
89 //-----------------------------------------------------------------------------
92  const float64 & sample_rate,
93  const float64 & room_feedback,
94  const float64 & wet_percent,
95  const float64 & dry_percent,
96  const float64 & low_pass_frequency_Hz,
97  const float64 & stereo_spread_seconds)
98  :
99  sample_rate_(sample_rate),
100  wet_percent_(wet_percent),
101  dry_percent_(dry_percent),
102  comb_left_(NULL),
103  comb_right_(NULL),
104  allpass_left_(NULL),
105  allpass_right_(NULL)
106 {
107  // Bounds checks:
108  if(wet_percent_ < 0.0)
109  {
110  wet_percent_ = 0.0;
111  }
112 
113  if(wet_percent_ > 1.0)
114  {
115  wet_percent_ = 1.0;
116  }
117 
118  if(dry_percent_ < 0.0)
119  {
120  dry_percent_ = 0.0;
121  }
122 
123  if(dry_percent_ > 1.0)
124  {
125  dry_percent_ = 1.0;
126  }
127 
128  float64 lpf = low_pass_frequency_Hz;
129 
130  if(lpf < 0.0)
131  {
132  lpf = 0.0;
133  }
134 
135  float64 stereo_spread = stereo_spread_seconds;
136 
137  if(stereo_spread < 0.0)
138  {
139  stereo_spread = 0.0;
140  }
141 
142  // Convert the room size to a delay time.
143  float64 comb_feedback = ROOM_FEEDBACK_SCALE_ * room_feedback
145 
146  // Allocate filter pointers
149 
150  for(uint32 i = 0; i < N_COMB_FILTERS_; ++i)
151  {
153  sample_rate_,
155  comb_feedback,
156  lpf);
157 
159  sample_rate_,
160  COMB_DELAY_TIME_SECONDS_[i] + stereo_spread,
161  comb_feedback,
162  lpf);
163  }
164 
165  // Allocate filter pointers
168 
169  for(uint32 i = 0; i < N_ALL_PASS_FILTERS_; ++i)
170  {
171  allpass_left_[i] = new FilterAllPass(
172  sample_rate_,
174  0.5);
175 
176  allpass_right_[i] = new FilterAllPass(
177  sample_rate_,
178  ALL_PASS_DELAY_TIME_SECONDS_[i] + stereo_spread,
179  0.5);
180  }
181 
183 
184  // Init random number generator.
185  std::srand(static_cast<unsigned int>(std::time(0)));
186 }
187 
188 //-----------------------------------------------------------------------------
191  :
192  sample_rate_(copy.sample_rate_),
193  wet_percent_(copy.wet_percent_),
194  dry_percent_(copy.dry_percent_),
195  comb_left_(NULL),
196  comb_right_(NULL),
197  allpass_left_(NULL),
198  allpass_right_(NULL)
199 {
200  *this = copy;
201 }
202 
203 //-----------------------------------------------------------------------------
206 {
207  for(uint32 i = 0; i < N_COMB_FILTERS_; ++i)
208  {
209  delete comb_left_[i];
210  delete comb_right_[i];
211  }
212  delete [] comb_left_;
213  delete [] comb_right_;
214 
215  for(uint32 i = 0; i < N_ALL_PASS_FILTERS_; ++i)
216  {
217  delete allpass_left_[i];
218  delete allpass_right_[i];
219  }
220  delete [] allpass_left_;
221  delete [] allpass_right_;
222 }
223 
226 filter(const AudioStream & x)
227 {
228  if(x.getNChannels() == 1)
229  {
230  return filter(x[0]);
231  }
232  else if(x.getNChannels() < 2)
233  {
234  return x;
235  }
236 
237  reset();
238 
240 
241  uint32 n_samples = x.getLength();
242 
243  float64 left;
244  float64 right;
245 
246  for(uint32 n = 0; n < n_samples; ++n)
247  {
248  filter(left, right, x[0][n], x[1][n]);
249 
250  y[0] << left;
251  y[1] << right;
252  }
253 
254  return y;
255 }
256 
259 filter(const Buffer & x)
260 {
261  reset();
263 
264  uint32 n_samples = x.getLength();
265 
266  float64 left;
267  float64 right;
268 
269  for(uint32 n = 0; n < n_samples; ++n)
270  {
271  filter(left, right, x[n], x[n]);
272 
273  y[0] << left;
274  y[1] << right;
275  }
276 
277  return y;
278 }
279 
280 void
283  float64 & out_left,
284  float64 & out_right,
285  const float64 & in_left,
286  const float64 & in_right)
287 {
288  out_left = 0.0 + getRandom() * 1e-23;
289  out_right = 0.0 + getRandom() * 1e-23;
290 
291  // Sum the comb filters in parallel
292  for(uint32 i = 0; i < N_COMB_FILTERS_; ++i)
293  {
294  out_left += comb_left_[i]->filter(in_left * 0.15);
295  out_right += comb_right_[i]->filter(in_right * 0.15);
296  }
297 
298  // Serilalize the all pass fitlers
299  for(uint32 i = 0; i < N_ALL_PASS_FILTERS_; ++i)
300  {
301  out_left = allpass_left_[i]->filter(out_left);
302  out_right = allpass_right_[i]->filter(out_left);
303  }
304 
305  out_left = wet_percent_ * out_left + dry_percent_ * in_left;
306  out_right = wet_percent_ * out_right + dry_percent_ * in_right;
307 }
308 
309 //-----------------------------------------------------------------------------
313 {
314  if(this == & rhs)
315  {
316  return *this;
317  }
318 
322 
323  for(uint32 i = 0; i < N_COMB_FILTERS_; ++i)
324  {
325  *comb_left_[i] = *(rhs.comb_left_[i]);
326  *comb_right_[i] = *(rhs.comb_right_[i]);
327  }
328 
329  for(uint32 i = 0; i < N_ALL_PASS_FILTERS_; ++i)
330  {
331  *allpass_left_[i] = *(rhs.allpass_left_[i]);
332  *allpass_right_[i] = *(rhs.allpass_right_[i]);
333  }
334 
335  return *this;
336 }
337 
338 void
341 {
342  for(uint32 i = 0; i < N_COMB_FILTERS_; ++i)
343  {
344  comb_left_[i]->reset();
345  comb_right_[i]->reset();
346  }
347 
348  for(uint32 i = 0; i < N_ALL_PASS_FILTERS_; ++i)
349  {
350  allpass_left_[i]->reset();
351  allpass_right_[i]->reset();
352  }
353 }
354 
unsigned int uint32
Definition: Nsound.h:153
FilterCombLowPassFeedback ** comb_left_
static const float64 ALL_PASS_DELAY_TIME_SECONDS_[N_ALL_PASS_FILTERS_]
FilterCombLowPassFeedback ** comb_right_
static const float64 ROOM_FEEDBACK_OFFSET_
uint32 getLength() const
Returns the number of samples of audio data in the stream.
Definition: AudioStream.cc:197
float64 getRandom()
AudioStream filter(const AudioStream &x)
ReverberationRoom(const float64 &sample_rate, const float64 &room_feedback, const float64 &wet_percent=0.5, const float64 &dry_percent=1.0, const float64 &low_pass_frequency_Hz=7644.9, const float64 &stereo_spread_seconds=0.0005215)
Default Constructor.
double float64
Definition: Nsound.h:146
static const float64 ROOM_FEEDBACK_SCALE_
AudioStream filter(const AudioStream &x)
uint32 getLength() const
Returns the number of samples in the Buffer.
Definition: Buffer.h:587
static const float64 COMB_DELAY_TIME_SECONDS_[N_COMB_FILTERS_]
uint32 getNChannels(void) const
Returns the number of audio channels in the stream.
Definition: AudioStream.h:212
static const uint32 N_COMB_FILTERS_
A class for filtering audio in the frequecy domain.
A Buffer for storing audio samples.
Definition: Buffer.h:60
AudioStream filter(const AudioStream &x)
ReverberationRoom & operator=(const ReverberationRoom &rhs)
FilterAllPass ** allpass_left_
static const uint32 N_ALL_PASS_FILTERS_
FilterAllPass ** allpass_right_