00001
00002
00003
00004
00005
00006
00007
00008
00010
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00028
00029 #include <Nsound/AudioStream.h>
00030 #include <Nsound/Buffer.h>
00031 #include <Nsound/FilterStageIIR.h>
00032
00033 #include <cmath>
00034 #include <string.h>
00035 #include <iostream>
00036
00037 using namespace Nsound;
00038
00039 using std::cout;
00040 using std::endl;
00041
00043 FilterStageIIR::
00044 FilterStageIIR(
00045 Type type,
00046 const float64 & sample_rate,
00047 uint32 n_poles,
00048 const float64 & frequency,
00049 const float64 & percent_ripple)
00050 :
00051 Filter(sample_rate),
00052 type_(type),
00053 n_poles_(n_poles),
00054 frequency_(frequency),
00055 percent_ripple_(percent_ripple),
00056 a_(NULL),
00057 b_(NULL),
00058 x_history_(NULL),
00059 x_ptr_(NULL),
00060 x_end_ptr_(NULL),
00061 y_history_(NULL),
00062 y_ptr_(NULL),
00063 y_end_ptr_(NULL),
00064 kernel_cache_()
00065 {
00066 if(n_poles_ > 20)
00067 {
00068 n_poles_ = 20;
00069 }
00070 else if(n_poles_ < 2)
00071 {
00072 n_poles_ = 2;
00073 }
00074
00075 if(n_poles_ % 2 != 0)
00076 {
00077 ++n_poles_;
00078 }
00079
00080 x_history_ = new float64 [n_poles_ + 1];
00081 x_ptr_ = x_history_;
00082 x_end_ptr_ = x_history_ + n_poles_ + 1;
00083
00084 y_history_ = new float64 [n_poles_ + 1];
00085 y_ptr_ = y_history_;
00086 y_end_ptr_ = y_history_ + n_poles_ + 1;
00087
00088 reset();
00089 }
00090
00092 FilterStageIIR::
00093 FilterStageIIR(const FilterStageIIR & copy)
00094 :
00095 Filter(copy.sample_rate_),
00096 type_(copy.type_),
00097 n_poles_(copy.n_poles_),
00098 frequency_(copy.frequency_),
00099 percent_ripple_(copy.percent_ripple_),
00100 a_(NULL),
00101 b_(NULL),
00102 x_history_(NULL),
00103 x_ptr_(NULL),
00104 x_end_ptr_(NULL),
00105 y_history_(NULL),
00106 y_ptr_(NULL),
00107 y_end_ptr_(NULL),
00108 kernel_cache_()
00109 {
00110 *this = copy;
00111 }
00112
00114 FilterStageIIR::
00115 ~FilterStageIIR()
00116 {
00117 delete [] x_history_;
00118 delete [] y_history_;
00119
00120 FilterStageIIR::KernelCache::iterator itor = kernel_cache_.begin();
00121 FilterStageIIR::KernelCache::iterator end = kernel_cache_.end();
00122
00123 while(itor != end)
00124 {
00125 delete [] itor->b_;
00126 delete [] itor->a_;
00127 ++itor;
00128 }
00129 }
00130
00132 AudioStream
00133 FilterStageIIR::
00134 filter(const AudioStream & x)
00135 {
00136 return Filter::filter(x);
00137 };
00138
00139
00141 AudioStream
00142 FilterStageIIR::
00143 filter(const AudioStream & x, const float64 & f)
00144 {
00145 return Filter::filter(x, f);
00146 }
00147
00149 AudioStream
00150 FilterStageIIR::
00151 filter(const AudioStream & x, const Buffer & frequencies)
00152 {
00153 return Filter::filter(x, frequencies);
00154 }
00155
00157 Buffer
00158 FilterStageIIR::
00159 filter(const Buffer & x)
00160 {
00161 return Filter::filter(x);
00162 }
00163
00165 Buffer
00166 FilterStageIIR::
00167 filter(const Buffer & x, const float64 & f)
00168 {
00169
00170
00171
00172
00173
00174 FilterStageIIR::reset();
00175 FilterStageIIR::makeKernel(f);
00176
00177 Buffer::const_iterator itor = x.begin();
00178 Buffer::const_iterator end = x.end();
00179
00180 Buffer y(x.getLength());
00181 while(itor != end)
00182 {
00183 y << FilterStageIIR::filter(*itor);
00184 ++itor;
00185 }
00186
00187 return y;
00188 }
00189
00191 Buffer
00192 FilterStageIIR::
00193 filter(const Buffer & x, const Buffer & frequencies)
00194 {
00195 return Filter::filter(x, frequencies);
00196 }
00197
00199 FilterStageIIR &
00200 FilterStageIIR::
00201 operator=(const FilterStageIIR & rhs)
00202 {
00203 if(this == &rhs) return *this;
00204
00205 uint32 n_poles_orig = n_poles_;
00206
00207 type_ = rhs.type_;
00208 n_poles_ = rhs.n_poles_;
00209 frequency_ = rhs.frequency_;
00210 percent_ripple_ = rhs.percent_ripple_;
00211
00212
00213 KernelCache::iterator itor = kernel_cache_.begin();
00214
00215 while(itor != kernel_cache_.end())
00216 {
00217 delete [] itor->b_;
00218 delete [] itor->a_;
00219 ++itor;
00220 }
00221
00222 kernel_cache_.clear();
00223
00224
00225 itor = rhs.kernel_cache_.begin();
00226 while(itor != rhs.kernel_cache_.end())
00227 {
00228 Kernel new_kernel(static_cast<uint32>(itor->frequency_));
00229
00230
00231 new_kernel.b_ = new float64 [n_poles_ + 1];
00232 new_kernel.a_ = new float64 [n_poles_ + 1];
00233
00234
00235 memcpy(new_kernel.b_, itor->b_, sizeof(float64) * (n_poles_ + 1));
00236 memcpy(new_kernel.a_, itor->a_, sizeof(float64) * (n_poles_ + 1));
00237
00238
00239 kernel_cache_.insert(new_kernel);
00240 }
00241
00242
00243 if(n_poles_orig != rhs.n_poles_)
00244 {
00245 delete [] x_history_;
00246 delete [] y_history_;
00247
00248 x_history_ = new float64 [n_poles_ + 1];
00249 x_ptr_ = x_history_;
00250 x_end_ptr_ = x_history_ + n_poles_ + 1;
00251
00252 y_history_ = new float64 [n_poles_ + 1];
00253 y_ptr_ = y_history_;
00254 y_end_ptr_ = y_history_ + n_poles_ + 1;
00255 }
00256
00257 reset();
00258
00259 return *this;
00260 }
00261
00263 void
00264 FilterStageIIR::
00265 reset()
00266 {
00267 memset(x_history_, 0, sizeof(float64) * (n_poles_ + 1));
00268 memset(y_history_, 0, sizeof(float64) * (n_poles_ + 1));
00269
00270 x_ptr_ = x_history_;
00271 y_ptr_ = y_history_;
00272
00273 makeKernel(frequency_);
00274 }
00275
00277 float64
00278 FilterStageIIR::
00279 filter(const float64 & x)
00280 {
00281
00282 *x_ptr_ = x;
00283
00284
00285 ++x_ptr_;
00286
00287
00288 if(x_ptr_ >= x_end_ptr_)
00289 {
00290 x_ptr_ = x_history_;
00291 }
00292
00293 float64 y = 0.0;
00294 float64 * x_hist = x_ptr_;
00295 for(float64 * b = b_; b != b_ + n_poles_ + 1; ++b)
00296 {
00297
00298 --x_hist;
00299
00300
00301 if(x_hist < x_history_)
00302 {
00303 x_hist = x_end_ptr_ - 1;
00304 }
00305
00306 y += *b * *x_hist;
00307 }
00308
00309 float64 * y_hist = y_ptr_;
00310 for(float64 * a = a_ + 1; a != a_ + n_poles_ + 1; ++a)
00311 {
00312
00313 --y_hist;
00314
00315
00316 if(y_hist < y_history_)
00317 {
00318 y_hist = y_end_ptr_ - 1;
00319 }
00320
00321 y += *a * *y_hist;
00322
00323 }
00324
00325
00326 *y_ptr_ = y;
00327
00328
00329 ++y_ptr_;
00330
00331
00332 if(y_ptr_ >= y_end_ptr_)
00333 {
00334 y_ptr_ = y_history_;
00335 }
00336
00337 return y;
00338 }
00339
00341 float64
00342 FilterStageIIR::
00343 filter(const float64 & x, const float64 & frequency)
00344 {
00345 makeKernel(frequency);
00346 return FilterStageIIR::filter(x);
00347 }
00348
00350 void
00351 FilterStageIIR::
00352 makeKernel(const float64 & frequency)
00353 {
00354 FilterStageIIR::
00355 Kernel new_kernel(static_cast<uint32>(frequency));
00356
00357
00358
00359 FilterStageIIR::
00360 KernelCache::const_iterator itor = kernel_cache_.find(new_kernel);
00361
00362 if(itor != kernel_cache_.end())
00363 {
00364 b_ = itor->b_;
00365 a_ = itor->a_;
00366
00367 return;
00368 }
00369
00370
00371 new_kernel.b_ = new float64 [n_poles_ + 1];
00372 new_kernel.a_ = new float64 [n_poles_ + 1];
00373
00374 b_ = new_kernel.b_;
00375 a_ = new_kernel.a_;
00376
00377
00378
00379 if(type_ == LOW_PASS && frequency < 1.0)
00380 {
00381
00382 memset(new_kernel.b_, 0, sizeof(float64) * (n_poles_ + 1));
00383 memset(new_kernel.a_, 0, sizeof(float64) * (n_poles_ + 1));
00384 }
00385
00386 else if(type_ == LOW_PASS && frequency >= (sample_rate_ / 2.0))
00387 {
00388
00389 memset(new_kernel.b_, 0, sizeof(float64) * (n_poles_ + 1));
00390 memset(new_kernel.a_, 0, sizeof(float64) * (n_poles_ + 1));
00391
00392 b_[0] = 1.0;
00393 }
00394
00395 else if(type_ == HIGH_PASS && frequency < 1.0)
00396 {
00397
00398 memset(new_kernel.b_, 0, sizeof(float64) * (n_poles_ + 1));
00399 memset(new_kernel.a_, 0, sizeof(float64) * (n_poles_ + 1));
00400
00401 b_[0] = 1.0;
00402 }
00403
00404 else if(type_ == HIGH_PASS && frequency >= (sample_rate_ / 2.0))
00405 {
00406
00407 memset(new_kernel.b_, 0, sizeof(float64) * (n_poles_ + 1));
00408 memset(new_kernel.a_, 0, sizeof(float64) * (n_poles_ + 1));
00409 }
00410
00411 else
00412 {
00413
00414 float64 B[23];
00415 float64 A[23];
00416
00417 float64 TB[23];
00418 float64 TA[23];
00419
00420 memset(B,0,sizeof(float64) * 23);
00421 memset(A,0,sizeof(float64) * 23);
00422 memset(TB,0,sizeof(float64) * 23);
00423 memset(TA,0,sizeof(float64) * 23);
00424
00425 B[2] = A[2] = 1.0;
00426
00427 for(uint32 p = 1; p <= n_poles_ / 2; ++p)
00428 {
00429 float64 b[3];
00430 float64 a[3];
00431
00432 makeIIRKernelHelper(frequency, b, a, p);
00433
00434 memcpy(TB,B, sizeof(float64) * 23);
00435 memcpy(TA,A, sizeof(float64) * 23);
00436
00437 for(uint32 i = 2; i <= 22; ++i)
00438 {
00439 B[i] = b[0] * TB[i] + b[1] * TB[i - 1] + b[2] * TB[i - 2];
00440 A[i] = TA[i] - a[1] * TA[i - 1] - a[2] * TA[i - 2];
00441 }
00442 }
00443
00444 A[2] = 0.0;
00445 for(uint32 i = 0; i <= 20; ++i)
00446 {
00447 B[i] = B[i + 2];
00448 A[i] = -1.0 * A[i + 2];
00449 }
00450
00451 float64 sumB = 0.0;
00452 float64 sumA = 0.0;
00453
00454 for(int32 i = 0; i <= 22; ++i)
00455 {
00456 if(type_ == LOW_PASS)
00457 {
00458 sumB += B[i];
00459 sumA += A[i];
00460 }
00461 else if(type_ == HIGH_PASS)
00462 {
00463 sumB += B[i] * pow(-1.0,i);
00464 sumA += A[i] * pow(-1.0,i);
00465 }
00466 }
00467 float64 gain = sumB / (1.0 - sumA);
00468
00469 for(uint32 i = 0; i <= 22; ++i)
00470 {
00471 B[i] /= gain;
00472 }
00473
00474 memcpy(b_, B, sizeof(float64) * (n_poles_ + 1));
00475 memcpy(a_, A, sizeof(float64) * (n_poles_ + 1));
00476 }
00477
00478
00479 kernel_cache_.insert(new_kernel);
00480 }
00481
00483 void
00484 FilterStageIIR::
00485 makeIIRKernelHelper(
00486 const float64 & frequency,
00487 float64 * b,
00488 float64 * a,
00489 uint32 p)
00490 {
00491 float64 n_poles = static_cast<float64>(n_poles_);
00492
00493 float64 RP = -1.0 * cos(M_PI / (n_poles * 2.0) + (p - 1) * (M_PI / n_poles));
00494 float64 IP = sin(M_PI / (n_poles * 2.0) + (p - 1) * (M_PI / n_poles));
00495
00496 float64 ES = 0.0;
00497 float64 VX = 0.0;
00498 float64 KX = 0.0;
00499
00500 if(percent_ripple_ != 0.0)
00501 {
00502 float64 temp = (1.0 / (1.0 - percent_ripple_));
00503
00504 ES = sqrt(temp * temp - 1.0);
00505
00506 VX = (1.0 / n_poles) * log((1.0 / ES) + sqrt((1.0 /(ES * ES)) + 1.0));
00507 KX = (1.0 / n_poles) * log((1.0 / ES) + sqrt((1.0 /(ES * ES)) - 1.0));
00508 KX = (exp(KX) + exp(-KX)) / 2.0;
00509 RP = RP * ( (exp(VX) - exp(-1.0 * VX) ) / 2.0) / KX;
00510 IP = IP * ( (exp(VX) + exp(-1.0 * VX) ) / 2.0) / KX;
00511 }
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 float64 T = 2.0 * tan(0.5);
00527 float64 W = 2.0 * M_PI * (frequency / static_cast<float64>(sample_rate_));
00528 float64 M = RP * RP + IP * IP;
00529 float64 D = 4.0 - (4.0 * RP * T) + (M * T * T);
00530 float64 X0 = T * T / D;
00531 float64 X1 = 2.0 * X0;
00532 float64 X2 = X0;
00533 float64 Y1 = (8.0 - 2.0 * M * T * T) / D;
00534 float64 Y2 = (-4.0 - (4.0 * RP * T) - M * T * T) / D;
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 float64 K = 0.0;
00554
00555 if(type_ == LOW_PASS)
00556 {
00557 K = sin(0.5 - W / 2.0) / sin(0.5 + W / 2.0);
00558 }
00559
00560
00561 else if(type_ == HIGH_PASS)
00562 {
00563 K = -1.0 * cos(W / 2.0 + 0.5) / cos(W / 2.0 - 0.5);
00564 }
00565
00566 D = 1.0 + Y1 * K - Y2 * K * K;
00567 b[0] = (X0 - X1 * K + X2 * K * K) / D;
00568 b[1] = (-2.0 * X0 *K + X1 + X1 * K * K - 2.0 * X2 * K) / D;
00569 b[2] = (X0 * K * K - X1 * K + X2) / D;
00570 a[1] = (2.0 * K + Y1 + Y1 * K * K - 2.0 * Y2 * K) / D;
00571 a[2] = (-1.0 * K * K - Y1 * K + Y2) / D;
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587 if(type_ == HIGH_PASS)
00588 {
00589 b[1] = -b[1];
00590 a[1] = -a[1];
00591 }
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603 }
00604
00606 FilterStageIIR::
00607 Kernel::
00608 Kernel(const uint32 & frequency)
00609 :
00610 b_(NULL),
00611 a_(NULL),
00612 frequency_(frequency)
00613 {
00614 }
00615
00617 bool
00618 FilterStageIIR::
00619 Kernel::
00620 operator<(const Kernel & rhs) const
00621 {
00622 return frequency_ < rhs.frequency_;
00623 }
00624