Nsound::FilterIIR Class Reference

#include <Nsound/FilterIIR.h>

Inheritance diagram for Nsound::FilterIIR:
Inheritance graph
[legend]

List of all members.

Public Member Functions

 FilterIIR (const float64 &sample_rate, uint32 n_poles)
 FilterIIR (const FilterIIR &copy)
virtual ~FilterIIR ()
Buffer designFrequencyResponse (const Buffer &frequency_response, const float64 &max_error=0.01, const int32 max_iterations=1000)
Buffer designImpulseResponse (const Buffer &impulse_response, const float64 &max_error=0.01, const int32 max_iterations=1000)
AudioStream filter (const AudioStream &x)
AudioStream filter (const AudioStream &x, const Buffer &frequencies)
Buffer filter (const Buffer &x)
Buffer filter (const Buffer &x, const Buffer &frequencies)
float64 filter (const float64 &x)
float64 filter (const float64 &x, const float64 &frequency)
uint32 getKernelSize () const
Buffer getImpulseResponse (const uint32 n_samples=8192)
FilterIIRoperator= (const FilterIIR &rhs)
void reset ()
AudioStream filter (const AudioStream &x, const float64 &frequency)
Buffer filter (const Buffer &x, const float64 &frequency)
Buffer getFrequencyAxis (const uint32 n_fft=8192)
Buffer getFrequencyResponse (const uint32 n_fft=8192)
Buffer getPhaseResponse ()
float64 getSampleRate () const
void plot (boolean show_phase=false)

Protected Types

enum  SignalType { FREQUENCY_RESSPONSE = 0, IMPULSE_RESPONSE }

Protected Member Functions

Buffer designKernel (const Buffer &response, const float64 &max_rms_error, const int32 max_iterations, const SignalType type)
float64 getRMS (const Kernel &kernel, const Buffer &response, const SignalType type)
void savePlot (const Kernel &k, const Buffer &response, uint32 n, const float64 &error)

Protected Attributes

uint32 n_poles_
Kernelkernel_
float64x_history_
float64x_ptr_
float64x_end_ptr_
float64y_history_
float64y_ptr_
float64y_end_ptr_
RngTauswortherng_
float64 sample_rate_
float64 two_pi_over_sample_rate_
uint32 kernel_size_

Friends

std::ostream & operator<< (std::ostream &out, const FilterIIR &rhs)

Detailed Description

WARNING: This is Experimental, you should not use this class as it may not be working or will change in future releases of Nsound.

Definition at line 52 of file FilterIIR.h.


Member Enumeration Documentation

Enumerator:
FREQUENCY_RESSPONSE 
IMPULSE_RESPONSE 

Definition at line 149 of file FilterIIR.h.

00150     {
00151         FREQUENCY_RESSPONSE = 0,
00152         IMPULSE_RESPONSE
00153     };


Constructor & Destructor Documentation

FilterIIR::FilterIIR ( const float64 sample_rate,
uint32  n_poles 
)

Definition at line 58 of file FilterIIR.cc.

References kernel_, n_poles_, reset(), rng_, x_end_ptr_, x_history_, x_ptr_, y_end_ptr_, y_history_, and y_ptr_.

00062     :
00063     Filter(sample_rate),
00064     n_poles_(n_poles),
00065     kernel_(NULL),
00066     x_history_(NULL),
00067     x_ptr_(NULL),
00068     x_end_ptr_(NULL),
00069     y_history_(NULL),
00070     y_ptr_(NULL),
00071     y_end_ptr_(NULL),
00072     rng_(NULL)
00073 {
00074     kernel_ = new Kernel(n_poles_, n_poles_);
00075 
00076     x_history_ = new float64 [n_poles_ + 1];
00077     x_ptr_     = x_history_;
00078     x_end_ptr_ = x_history_ + n_poles_ + 1;
00079 
00080     y_history_ = new float64 [n_poles_ + 1];
00081     y_ptr_     = y_history_;
00082     y_end_ptr_ = y_history_ + n_poles_ + 1;
00083 
00084     rng_ = new RngTausworthe();
00085 
00086     reset();
}

FilterIIR::FilterIIR ( const FilterIIR copy  ) 

Definition at line 90 of file FilterIIR.cc.

References n_poles_, reset(), rng_, x_history_, and y_history_.

00092     :
00093     Filter(copy.sample_rate_),
00094     n_poles_(copy.n_poles_),
00095     kernel_(NULL),
00096     x_history_(NULL),
00097     x_ptr_(NULL),
00098     x_end_ptr_(NULL),
00099     y_history_(NULL),
00100     y_ptr_(NULL),
00101     y_end_ptr_(NULL),
00102     rng_(NULL)
00103 {
00104     x_history_ = new float64 [n_poles_];
00105     y_history_ = new float64 [n_poles_];
00106 
00107     rng_ = new RngTausworthe();
00108 
00109     *this = copy;
00110 
00111     reset();
}

FilterIIR::~FilterIIR (  )  [virtual]

Definition at line 115 of file FilterIIR.cc.

References kernel_, rng_, x_history_, and y_history_.

00116 {
00117     delete kernel_;
00118     delete [] x_history_;
00119     delete [] y_history_;
00120 
00121     delete rng_;
00122 }


Member Function Documentation

Buffer FilterIIR::designFrequencyResponse ( const Buffer frequency_response,
const float64 max_error = 0.01,
const int32  max_iterations = 1000 
)

Designs a filter kernel using a genetic algorithm that trys to match the provided frequency response. Designs a filter kernel that trys to match the provide frequency response. The method uses a genetic algorithm to arrive at a fit solution and retuns the error per generation. The error signal is nice to plot to get an idea of how quickly the solution was found.

Definition at line 127 of file FilterIIR.cc.

References designKernel(), and FREQUENCY_RESSPONSE.

Referenced by main().

00131 {
00132     return designKernel(
00133         frequency_response,
00134         max_error,
00135         max_iterations,
00136         FREQUENCY_RESSPONSE);
00137 }

Buffer FilterIIR::designImpulseResponse ( const Buffer impulse_response,
const float64 max_error = 0.01,
const int32  max_iterations = 1000 
)

Designs a filter kernel using a genetic algorithm that trys to match the provided impulse response. Designs a filter kernel that trys to match the provide impulse response The method uses a genetic algorithm to arrive at a fit solution and retuns the error per generation. The error signal is nice to plot to get an idea of how quickly the solution was found.

Definition at line 142 of file FilterIIR.cc.

References designKernel(), and IMPULSE_RESPONSE.

00146 {
00147     return designKernel(
00148         impulse_response,
00149         max_error,
00150         max_iterations,
00151         IMPULSE_RESPONSE);
00152 }

AudioStream Nsound::FilterIIR::filter ( const AudioStream x  )  [inline]

Reimplemented from Nsound::Filter.

Definition at line 95 of file FilterIIR.h.

Referenced by filter().

00096     { return Filter::filter(x);};

AudioStream Nsound::FilterIIR::filter ( const AudioStream x,
const Buffer frequencies 
) [inline]

Reimplemented from Nsound::Filter.

Definition at line 100 of file FilterIIR.h.

References filter().

00101     { return Filter::filter(x);};

Buffer Nsound::FilterIIR::filter ( const Buffer x  )  [inline]

Reimplemented from Nsound::Filter.

Definition at line 105 of file FilterIIR.h.

References filter().

00106     {return Filter::filter(x);};

Buffer Nsound::FilterIIR::filter ( const Buffer x,
const Buffer frequencies 
) [inline]

Reimplemented from Nsound::Filter.

Definition at line 110 of file FilterIIR.h.

References filter().

Referenced by filter().

00111     {return filter(x);};

float64 FilterIIR::filter ( const float64 x  )  [virtual]

Implements Nsound::Filter.

Definition at line 629 of file FilterIIR.cc.

References Nsound::Kernel::getA(), Nsound::Kernel::getB(), kernel_, n_poles_, x_end_ptr_, x_history_, x_ptr_, y_end_ptr_, y_history_, and y_ptr_.

00630 {
00631     // Write x to history
00632     *x_ptr_ = x;
00633 
00634     // Increment history pointer
00635     ++x_ptr_;
00636 
00637     // Bounds check
00638     if(x_ptr_ >= x_end_ptr_)
00639     {
00640         x_ptr_ = x_history_;
00641     }
00642 
00643     float64 y = 0.0;
00644     float64 * x_hist = x_ptr_;
00645     const float64 * bb = kernel_->getB();
00646     const float64 * b_end = bb + n_poles_;
00647     for(const float64 * b = bb; b < b_end; ++b)
00648     {
00649         // When we enter this loop, x_hist is pointing at x[n + 1]
00650         --x_hist;
00651 
00652         // Bounds check
00653         if(x_hist < x_history_)
00654         {
00655             x_hist = x_end_ptr_ - 1;
00656         }
00657 
00658         y += *b * *x_hist;
00659     }
00660 
00661     float64 * y_hist = y_ptr_;
00662     const float64 * aa = kernel_->getA();
00663     const float64 * a_end = aa + n_poles_;
00664     for(const float64 * a = aa + 1; a < a_end; ++a)
00665     {
00666         // When we enter this loop, y_hist is pointing at y[n + 1]
00667         --y_hist;
00668 
00669         // Bounds check
00670         if(y_hist < y_history_)
00671         {
00672             y_hist = y_end_ptr_ - 1;
00673         }
00674 
00675         y += *a * *y_hist;
00676     }
00677 
00678     // insert output into history buffer
00679     *y_ptr_ = y;
00680 
00681     // Increment history pointer
00682     ++y_ptr_;
00683 
00684     // Bounds check
00685     if(y_ptr_ >= y_end_ptr_)
00686     {
00687         y_ptr_ = y_history_;
00688     }
00689 
00690     return y;
00691 }

float64 FilterIIR::filter ( const float64 x,
const float64 frequency 
) [virtual]

Implements Nsound::Filter.

Definition at line 696 of file FilterIIR.cc.

References filter().

00697 {
00698     return FilterIIR::filter(x);
00699 }

uint32 Nsound::FilterIIR::getKernelSize (  )  const [inline, virtual]

Reimplemented from Nsound::Filter.

Definition at line 123 of file FilterIIR.h.

References n_poles_.

00123 {return n_poles_;};

Buffer Nsound::FilterIIR::getImpulseResponse ( const uint32  n_samples = 8192  )  [inline]

Reimplemented from Nsound::Filter.

Definition at line 127 of file FilterIIR.h.

References reset().

Referenced by getRMS().

00128     { reset(); return Filter::getImpulseResponse(n_samples); };

FilterIIR & FilterIIR::operator= ( const FilterIIR rhs  ) 

Definition at line 704 of file FilterIIR.cc.

References kernel_, n_poles_, rng_, Nsound::Filter::sample_rate_, x_history_, and y_history_.

00705 {
00706     if(this == &rhs)
00707     {
00708         return *this;
00709     }
00710 
00711     sample_rate_ = rhs.sample_rate_;
00712 
00713     if(n_poles_ != rhs.n_poles_)
00714     {
00715         delete [] x_history_;
00716         delete [] y_history_;
00717 
00718         n_poles_ = rhs.n_poles_;
00719 
00720         x_history_ = new float64 [n_poles_];
00721         y_history_ = new float64 [n_poles_];
00722     }
00723 
00724     memcpy(x_history_, rhs.x_history_, sizeof(float64) * n_poles_);
00725     memcpy(y_history_, rhs.y_history_, sizeof(float64) * n_poles_);
00726 
00727     *kernel_ = *rhs.kernel_;
00728     *rng_ = *rhs.rng_;
00729 
00730     return *this;
00731 }

void FilterIIR::reset (  )  [virtual]

Implements Nsound::Filter.

Definition at line 746 of file FilterIIR.cc.

References n_poles_, x_history_, x_ptr_, y_history_, and y_ptr_.

Referenced by FilterIIR(), getImpulseResponse(), getRMS(), and savePlot().

00747 {
00748     memset(x_history_, 0, sizeof(float64) * (n_poles_ + 1));
00749     memset(y_history_, 0, sizeof(float64) * (n_poles_ + 1));
00750 
00751     x_ptr_ = x_history_;
00752     y_ptr_ = y_history_;
00753 }

Buffer FilterIIR::designKernel ( const Buffer ref_response,
const float64 max_rms_error,
const int32  max_iterations,
const SignalType  type 
) [protected]

Designs a filter kernel that trys to match the provide frequency response. Designs a filter kernel that trys to match the provide frequency response. The method uses a genetic algorithm to arrive at a fit solution and retuns the error per generation. The error signal is nice to plot to get an idea of how quickly the solution was found.

This method is VERY EXPERMENTAL! Use at your own risk!

Definition at line 251 of file FilterIIR.cc.

References Nsound::Kernel::ga_interleave(), Nsound::Kernel::ga_swap_ab(), Nsound::RngTausworthe::get(), Nsound::Kernel::getA(), Nsound::Kernel::getB(), Nsound::Buffer::getLength(), getRMS(), Nsound::Kernel::getSum(), kernel_, n_poles_, PRINT_LINE, Nsound::Kernel::randomize(), rng_, Nsound::Kernel::setA(), and Nsound::Kernel::setB().

Referenced by designFrequencyResponse(), and designImpulseResponse().

00256 {
00257     // The reference response curve must be a power of two to guarentee correct
00258     // comparision to the designed kernel response.
00259 
00260     uint32 p2 = 2;
00261     uint32 ref_size = ref_response.getLength();
00262 
00263     while( p2 < ref_size )
00264     {
00265         p2 <<= 1;
00266     }
00267 
00268     if(ref_size != p2)
00269     {
00270         cerr << PRINT_LINE
00271              << "The reference response Buffer length must be a power of 2"
00272              << " (" << ref_size << " != " << p2 << ")"
00273              << endl
00274              << "Aborting kernel design."
00275              << endl;
00276         ::exit(1);
00277     }
00278 
00279     // Create the initial 2 parents
00280     Kernel * mom = new Kernel(n_poles_, n_poles_);
00281 
00282     float64 LARGE_RMS = 1.0;
00283     float64 STALE_RMS = 0.001;
00284 
00285     float64 rms_error = LARGE_RMS;
00286     int32 dead_count = 0;
00287     while(rms_error > LARGE_RMS && dead_count < 1000)
00288     {
00289         mom->randomize(-0.1, 0.1);
00290         rms_error = getRMS(*mom, ref_response, type);
00291         dead_count++;
00292     }
00293 
00294     if(rms_error > LARGE_RMS)
00295     {
00296         cerr << PRINT_LINE
00297              << "RMS = " << rms_error << endl;
00298 
00299         cerr << "Could not find a stable random kernel, aborting kernel design."
00300              << endl;
00301 
00302         delete mom;
00303 
00304         ::exit(1);
00305     }
00306 
00307     Kernel * dad = new Kernel(n_poles_, n_poles_);
00308 
00309     dad->randomize(-0.1, 0.1);
00310 
00311     int32 N_CHILDREN = 14;
00312 
00313     // Allocate N children
00314     Kernel * child[N_CHILDREN];
00315 
00316     for(int32 i = 0; i < N_CHILDREN; ++i)
00317     {
00318         child[i] = new Kernel(n_poles_, n_poles_);
00319     }
00320 
00321     Buffer rms_history;
00322 
00323     rms_history << rms_error;
00324 
00325     float64 dad_rms_error = getRMS(*dad, ref_response, type);
00326 
00327     cout << std::setprecision(10)
00328          << "mom's RMS = " << rms_error << endl
00329          << "dad's RMS = " << dad_rms_error << endl;
00330 
00331     float64 rms_error1 = LARGE_RMS;
00332     float64 rms_error2 = LARGE_RMS;
00333 
00334     Kernel * low1 = NULL;
00335     Kernel * low2 = NULL;
00336 
00337     float64 last_rms_error = rms_error;
00338     int32 stale_count = 0;
00339     int32 major_stale_count = 0;
00340     int32 count = 0;
00341 
00342     while(count < max_iterations && rms_error > max_rms_error)
00343     {
00344         ++count;
00345 
00346         // First two children just swap mom & dads a & b coeffs;
00347         *child[0] = *mom;
00348         *child[1] = *dad;
00349         child[0]->ga_swap_ab(*child[1]);
00350 
00351         #ifdef GA_DEBUG
00352             cout << __LINE__ << "\tmom.getSum() = " << mom->getSum()
00353                  << "\terror = " << error << endl << endl;
00354         #endif
00355 
00356         // Next two children interleave coeffs
00357         *child[2] = *mom;
00358         *child[3] = *dad;
00359 
00360         child[2]->ga_interleave(*child[3]);
00361 
00362         #ifdef GA_DEBUG
00363             cout << __LINE__ << "\tmom.getSum() = " << mom->getSum()
00364                  << "\terror = " << error << endl << endl;
00365         #endif
00366 
00367         // The next two children randomly mutate one coeff from mom & dad
00368         *child[4] = *mom;
00369         *child[5] = *dad;
00370 
00371         for(uint32 i = 4; i < 6; ++i)
00372         {
00373             float64 delta = rng_->get(-0.1f, 0.1f);
00374 
00375             uint32 index = rng_->get(0, n_poles_);
00376 
00377             child[i]->setB(child[i]->getB(index) + delta, index);
00378 
00379             delta = rng_->get(-0.1f, 0.1f);
00380 
00381             index = rng_->get(0, n_poles_);
00382 
00383             child[i]->setA(child[i]->getA(index) + delta, index);
00384         }
00385 
00386         #ifdef GA_DEBUG
00387             cout << __LINE__ << "\tmom.getSum() = " << mom->getSum()
00388                  << "\terror = " << error << endl << endl;
00389         #endif
00390 
00391         // The next two children randomly mutate sign
00392         *child[6] = *mom;
00393         *child[7] = *dad;
00394 
00395         for(uint32 i = 6; i < 8; ++i)
00396         {
00397             uint32 index = rng_->get(0, n_poles_);
00398 
00399             float64 a_or_b = rng_->get(-1.0f, 1.0f);
00400 
00401             if(a_or_b > 0.0)
00402             {
00403                 child[i]->setB(child[i]->getB(index) * -1.0, index);
00404             }
00405             else
00406             {
00407                 child[i]->setA(child[i]->getA(index) * -1.0, index);
00408             }
00409         }
00410 
00411         #ifdef GA_DEBUG
00412             cout << __LINE__ << "\tmom.getSum() = " << mom->getSum()
00413                  << "\terror = " << error << endl << endl;
00414         #endif
00415 
00416         // These two children randomly multiply one coef.
00417         *child[8] = *mom;
00418         *child[9] = *dad;
00419 
00420         for(uint32 i = 8; i < 10; ++i)
00421         {
00422             uint32 index = rng_->get(0, n_poles_);
00423 
00424             float64 a_or_b = rng_->get(-1.0f, 1.0f);
00425 
00426             float64 delta = rng_->get(-0.1f, 0.1f);
00427 
00428             if(a_or_b > 0.0)
00429             {
00430                 child[i]->setB(child[i]->getB(index) * delta, index);
00431             }
00432             else
00433             {
00434                 child[i]->setA(child[i]->getA(index) * delta, index);
00435             }
00436         }
00437 
00438         #ifdef GA_DEBUG
00439             cout << __LINE__ << "\tmom.getSum() = " << mom->getSum()
00440                  << "\terror = " << error << endl << endl;
00441         #endif
00442 
00443         // These two children randomly swap mom & dad coeffs
00444         *child[10] = *mom;
00445         *child[11] = *dad;
00446 
00447         uint32 start_index = rng_->get(0, n_poles_);
00448         uint32 stop_index  = rng_->get(0, n_poles_);
00449 
00450         if(start_index < 0) start_index = 0;
00451         if(stop_index >= n_poles_) stop_index = n_poles_ - 1;
00452 
00453         if(start_index > stop_index)
00454         {
00455             uint32 temp = start_index;
00456             start_index = stop_index;
00457             stop_index = temp;
00458         }
00459 
00460         for(uint32 j = start_index; j < stop_index; ++j)
00461         {
00462             child[10]->setB(dad->getB(j), j);
00463             child[11]->setB(mom->getB(j), j);
00464         }
00465 
00466         #ifdef GA_DEBUG
00467             cout << __LINE__ << "\tmom.getSum() = " << mom->getSum()
00468                  << "\terror = " << error << endl << endl;
00469         #endif
00470 
00471         start_index = rng_->get(0, n_poles_);
00472         stop_index  = rng_->get(0, n_poles_);
00473 
00474         if(start_index < 0) start_index = 0;
00475         if(stop_index >= n_poles_) stop_index = n_poles_ - 1;
00476 
00477         if(start_index > stop_index)
00478         {
00479             int32 temp = start_index;
00480             start_index = stop_index;
00481             stop_index = temp;
00482         }
00483 
00484         for(uint32 j = start_index; j < stop_index; ++j)
00485         {
00486             child[10]->setA(dad->getA(j), j);
00487             child[11]->setA(mom->getA(j), j);
00488         }
00489 
00490         #ifdef GA_DEBUG
00491             cout << __LINE__ << "\tmom.getSum() = " << mom->getSum()
00492                  << "\terror = " << error << endl << endl;
00493         #endif
00494 
00495         // These two children randomly add mom & dad coeffs
00496         *child[12] = *mom;
00497         *child[13] = *dad;
00498 
00499         for(uint32 i = 12; i < 14; ++i)
00500         {
00501             for(uint32 j = 0; j < n_poles_; ++j)
00502             {
00503                 child[i]->setB(child[i]->getB(j) + rng_->get(-0.1f, 0.1f), j);
00504                 child[i]->setA(child[i]->getA(j) + rng_->get(-0.1f, 0.1f), j);
00505             }
00506         }
00507 
00508         // Score the kiddies.
00509 
00510         rms_error1 = getRMS(*mom, ref_response, type);
00511         rms_error2 = getRMS(*dad, ref_response, type);
00512 
00513         low1 = mom;
00514         low2 = dad;
00515 
00516         for(int32 i = 0; i < N_CHILDREN; ++i)
00517         {
00518             float64 rms = getRMS(*child[i], ref_response, type);
00519 
00520             if(rms > LARGE_RMS) continue;
00521 
00522             if(rms < rms_error1)
00523             {
00524                 rms_error1 = rms;
00525                 low1 = child[i];
00526             }
00527             else if(rms < rms_error2)
00528             {
00529                 rms_error2 = rms;
00530                 low2 = child[i];
00531             }
00532         }
00533 
00534         #ifdef GA_DEBUG
00535             cout << __LINE__ << "\tmom.getSum() = " << mom->getSum()
00536                  << "\terror = " << error << endl << endl;
00537         #endif
00538 
00539         *mom = *low1;
00540         *dad = *low2;
00541 
00542         rms_error     = getRMS(*mom, ref_response, type);
00543         dad_rms_error = getRMS(*dad, ref_response, type);
00544 
00545         rms_history << rms_error;
00546 
00547         #ifdef GA_DEBUG
00548             cout << __LINE__ << "\tmom.getSum() = " << mom->getSum()
00549                  << "\terror = " << error << endl;
00550         #endif
00551 
00552         // Check if dad is unstable.
00553         if(dad_rms_error > LARGE_RMS)
00554         {
00555             cout << PRINT_LINE << "dad's RMS > 10, ballistic!" << endl;
00556             dad->randomize(-0.01f, 0.01f);
00557         }
00558 
00559         // Check if our evolution is getting stale
00560         if(std::fabs(rms_error - last_rms_error) < STALE_RMS)
00561         {
00562             ++stale_count;
00563         }
00564         else
00565         {
00566             stale_count = 0;
00567         }
00568 
00569         last_rms_error = rms_error;
00570 
00571         if(count % 200 == 0)
00572         {
00573             cout << "Generation " << count << endl
00574                  << "    1st maximum RMS = " << rms_error     << endl
00575                  << "    2nd maximum RMS = " << dad_rms_error << endl;
00576 //~                  << "    major_stale_count = " << major_stale_count << endl;
00577         }
00578 
00579         if(stale_count > 6)
00580         {
00581             for(uint32 i = 0; i < n_poles_; ++i)
00582             {
00583                 dad->setB(dad->getB(i) + rng_->get(-0.10501f, 0.10501f), i);
00584                 dad->setA(dad->getA(i) + rng_->get(-0.10501f, 0.10501f), i);
00585             }
00586 
00587             stale_count = 0;
00588             ++major_stale_count;
00589 
00590             if(major_stale_count > 1)
00591             {
00592                 for(uint32 i = 0; i < n_poles_; ++i)
00593                 {
00594                     dad->setB(dad->getB(i) * rng_->get(-0.501f, 0.501f), i);
00595                     dad->setA(dad->getA(i) * rng_->get(-0.501f, 0.501f), i);
00596                 }
00597 
00598                 major_stale_count = 0;
00599             }
00600         }
00601 
00602         #ifdef GA_DEBUG
00603             cout << __LINE__ << "\tmom.getSum() = " << mom->getSum()
00604                  << "\terror = " << error << endl;
00605         #endif
00606 
00607     }
00608 
00609     cout << "count = " << count << "  RMS = " << rms_error << endl;
00610 
00611     // copy mom into the filter.
00612     *kernel_ = *mom;
00613 
00614     for(int32 i = 0; i < N_CHILDREN; ++i)
00615     {
00616         delete child[i];
00617     }
00618 
00619     delete mom;
00620     delete dad;
00621 
00622     return rms_history;
00623 }

float64 FilterIIR::getRMS ( const Kernel kernel,
const Buffer response,
const SignalType  type 
) [protected]

Definition at line 213 of file FilterIIR.cc.

References FREQUENCY_RESSPONSE, Nsound::Filter::getFrequencyResponse(), getImpulseResponse(), Nsound::Buffer::getLength(), Nsound::Buffer::getSum(), kernel_, and reset().

Referenced by designKernel().

00217 {
00218     Kernel * orig_k = kernel_;
00219 
00220     kernel_ = const_cast<Kernel *>(&k);
00221 
00222     reset();
00223 
00224     Buffer r;
00225 
00226     if(type == FREQUENCY_RESSPONSE)
00227     {
00228         r = getFrequencyResponse(ref_response.getLength() * 2);
00229     }
00230     else
00231     {
00232         r = getImpulseResponse(ref_response.getLength() * 2);
00233     }
00234 
00235     kernel_ = orig_k;
00236 
00237     Buffer delta = ref_response - r;
00238     delta *= delta;
00239 
00240     float64 rms = delta.getSum() / static_cast<float64>(delta.getLength());
00241 
00242     rms = ::sqrt(rms);
00243 
00244     return rms;
00245 }

void FilterIIR::savePlot ( const Kernel k,
const Buffer response,
uint32  n,
const float64 error 
) [protected]

Definition at line 758 of file FilterIIR.cc.

References Nsound::Plotter::figure(), Nsound::Filter::getFrequencyAxis(), Nsound::Filter::getFrequencyResponse(), Nsound::Buffer::getLength(), Nsound::Buffer::getMax(), kernel_, Nsound::Plotter::plot(), reset(), Nsound::Plotter::text(), Nsound::Plotter::title(), Nsound::Plotter::xlabel(), Nsound::Plotter::xlim(), Nsound::Plotter::ylabel(), and Nsound::Plotter::ylim().

00763 {
00764     Kernel * orig_k = kernel_;
00765 
00766     kernel_ = const_cast<Kernel *>(&k);
00767 
00768     Buffer fr_ref = fr_reference;
00769     Buffer fr = getFrequencyResponse();
00770     Buffer faxis = getFrequencyAxis();
00771 
00772     while(fr_ref.getLength() < fr.getLength())
00773     {
00774         fr_ref << 0.0;
00775     }
00776 
00777     float64 max = fr_ref.getMax();
00778 
00779     Plotter pylab;
00780 
00781     pylab.figure();
00782     pylab.plot(faxis, fr_ref);
00783     pylab.plot(faxis, fr);
00784 
00785     pylab.xlabel("Frequency Hz");
00786     pylab.ylabel("Frequency Response");
00787 
00788     char buffer[256];
00789 
00790     sprintf(buffer, "Generation %06d", n);
00791 
00792     pylab.title(std::string(buffer));
00793 
00794     pylab.xlim(0.0, faxis[fr_reference.getLength() - 1]);
00795     pylab.ylim(0.0, 1.1 * max);
00796 
00797     sprintf(buffer, "Error = %5.2f", error);
00798 
00799     pylab.text(
00800         faxis[static_cast<uint32>(faxis.getLength() * 0.66)],
00801         0.66,
00802         std::string(buffer));
00803 
00804     sprintf(buffer, "generation_%06d.png", n);
00805 
00806 //~    pylab.savefig(std::string(buffer));
00807 
00808     kernel_ = orig_k;
00809 
00810     reset();
00811 }

AudioStream Filter::filter ( const AudioStream x,
const float64 frequency 
) [inherited]

Reimplemented in Nsound::FilterAllPass, Nsound::FilterBandPassIIR, Nsound::FilterBandRejectIIR, Nsound::FilterDelay, Nsound::FilterFlanger, Nsound::FilterHighPassFIR, Nsound::FilterHighPassIIR, Nsound::FilterLeastSquaresFIR, Nsound::FilterLowPassFIR, Nsound::FilterLowPassIIR, and Nsound::FilterStageIIR.

Definition at line 72 of file Filter.cc.

References Nsound::Filter::filter(), Nsound::AudioStream::getNChannels(), Nsound::AudioStream::getSampleRate(), and Nsound::Filter::reset().

00073 {
00074     reset();
00075 
00076     uint32 n_channels = x.getNChannels();
00077 
00078     AudioStream y(x.getSampleRate(), n_channels);
00079 
00080     for(uint32 channel = 0; channel < n_channels; ++channel)
00081     {
00082         y[channel] = filter(x[channel], frequency);
00083     }
00084 
00085     return y;
00086 }

Buffer Filter::filter ( const Buffer x,
const float64 frequency 
) [inherited]
Buffer Filter::getFrequencyAxis ( const uint32  n_fft = 8192  )  [inherited]

Definition at line 176 of file Filter.cc.

References Nsound::FFTransform::roundUp2(), and Nsound::Filter::sample_rate_.

Referenced by main(), Nsound::Filter::plot(), and savePlot().

00177 {
00178     uint32 fft_chunk_size = FFTransform::roundUp2(
00179         static_cast<int32>(n_fft));
00180 
00181     uint32 n_samples = fft_chunk_size / 2 + 1;
00182 
00183     float64 f_step = (1.0 / (static_cast<float64>(fft_chunk_size) / 2.0))
00184                    * (sample_rate_ / 2.0);
00185 
00186     Buffer f_axis;
00187 
00188     float64 f = 0.0;
00189 
00190     for(uint32 i = 0; i < n_samples; ++i)
00191     {
00192         f_axis << f;
00193         f += f_step;
00194     }
00195 
00196     return f_axis;
00197 };

Buffer Filter::getFrequencyResponse ( const uint32  n_fft = 8192  )  [inherited]

Definition at line 202 of file Filter.cc.

References Nsound::FFTransform::fft(), Nsound::Filter::getImpulseResponse(), and Nsound::Filter::sample_rate_.

Referenced by Nsound::FilterBandPassIIR::FilterBandPassIIR(), FilterLeastSquaresFIR_UnitTest(), getRMS(), main(), Nsound::Filter::plot(), and savePlot().

00203 {
00204     FFTransform fft(sample_rate_);
00205 
00206 //~    fft.setWindow(HANNING);
00207 
00208     FFTChunkVector vec;
00209 
00210     vec = fft.fft(getImpulseResponse(), n_fft);
00211 
00212     return vec[0].getMagnitude();
00213 }

Buffer Filter::getPhaseResponse (  )  [inherited]

Definition at line 239 of file Filter.cc.

References Nsound::FFTransform::fft(), Nsound::Filter::getImpulseResponse(), Nsound::Buffer::getLength(), Nsound::Filter::sample_rate_, and Nsound::Buffer::subbuffer().

Referenced by Nsound::Filter::plot().

00240 {
00241     uint32 n_samples = static_cast<uint32>(sample_rate_ * 2);
00242 
00243     FFTransform fft(n_samples);
00244 
00245     FFTChunkVector vec;
00246 
00247     vec = fft.fft(getImpulseResponse(), n_samples);
00248 
00249     Buffer phase = vec[0].getPhase();
00250 
00251     return phase.subbuffer(0, phase.getLength() / 2 + 1);
00252 }

float64 Nsound::Filter::getSampleRate (  )  const [inline, inherited]

Definition at line 117 of file Filter.h.

References Nsound::Filter::sample_rate_.

00117 { return sample_rate_; };

void Filter::plot ( boolean  show_phase = false  )  [inherited]

Definition at line 257 of file Filter.cc.

References Nsound::Plotter::figure(), Nsound::Buffer::getdB(), Nsound::Filter::getFrequencyAxis(), Nsound::Filter::getFrequencyResponse(), Nsound::Buffer::getMax(), Nsound::Filter::getPhaseResponse(), Nsound::Plotter::plot(), Nsound::Plotter::subplot(), Nsound::Plotter::xlabel(), Nsound::Plotter::ylabel(), and Nsound::Plotter::ylim().

Referenced by main().

00258 {
00259     Buffer x = getFrequencyAxis();
00260     Buffer fr = getFrequencyResponse().getdB();
00261 
00262     Plotter pylab;
00263 
00264     pylab.figure();
00265 
00266     int subplot_int = 111;
00267 
00268     if(show_phase)
00269     {
00270         subplot_int = 211;
00271     }
00272 
00273     pylab.subplot(subplot_int);
00274 
00275     // Frequency response
00276     pylab.plot(x,fr, "blue");
00277 
00278     pylab.xlabel("Frequency (Hz)");
00279     pylab.ylabel("Frequency Response (dB)");
00280 
00281     // Phase response
00282     if(show_phase)
00283     {
00284         pylab.subplot(subplot_int + 1);
00285 
00286         Buffer pr = getPhaseResponse().getdB();
00287 
00288         pylab.plot(x,pr);
00289 
00290         pylab.xlabel("Frequency (Hz)");
00291         pylab.ylabel("Phase Response (dB)");
00292     }
00293 
00294     float64 ymax = fr.getMax();
00295     float64 height = ymax - -60.0;
00296 
00297     pylab.ylim(-60.0, ymax + 0.05 * height);
00298 
00299 }


Friends And Related Function Documentation

std::ostream& operator<< ( std::ostream &  out,
const FilterIIR rhs 
) [friend]

Prints the coeffents.


Member Data Documentation

Definition at line 184 of file FilterIIR.h.

Referenced by designKernel(), filter(), FilterIIR(), getKernelSize(), operator=(), and reset().

Definition at line 188 of file FilterIIR.h.

Referenced by filter(), FilterIIR(), operator=(), reset(), and ~FilterIIR().

Definition at line 189 of file FilterIIR.h.

Referenced by filter(), FilterIIR(), and reset().

Definition at line 190 of file FilterIIR.h.

Referenced by filter(), and FilterIIR().

Definition at line 192 of file FilterIIR.h.

Referenced by filter(), FilterIIR(), operator=(), reset(), and ~FilterIIR().

Definition at line 193 of file FilterIIR.h.

Referenced by filter(), FilterIIR(), and reset().

Definition at line 194 of file FilterIIR.h.

Referenced by filter(), and FilterIIR().

Definition at line 196 of file FilterIIR.h.

Referenced by designKernel(), FilterIIR(), operator=(), and ~FilterIIR().

float64 Nsound::Filter::sample_rate_ [protected, inherited]

Definition at line 131 of file Filter.h.

Referenced by Nsound::FilterPhaser::filter(), Nsound::FilterDelay::filter(), Nsound::FilterCombLowPassFeedback::filter(), Nsound::FilterAllPass::FilterAllPass(), Nsound::FilterCombLowPassFeedback::FilterCombLowPassFeedback(), Nsound::FilterDelay::FilterDelay(), Nsound::FilterFlanger::FilterFlanger(), Nsound::FilterPhaser::FilterPhaser(), Nsound::FilterSlinky::FilterSlinky(), Nsound::Filter::getFrequencyAxis(), Nsound::Filter::getFrequencyResponse(), Nsound::Filter::getPhaseResponse(), Nsound::Filter::getSampleRate(), Nsound::FilterStageIIR::makeIIRKernelHelper(), Nsound::FilterStageIIR::makeKernel(), Nsound::FilterParametricEqualizer::makeKernel(), Nsound::FilterLeastSquaresFIR::makeKernel(), Nsound::FilterHighPassFIR::makeKernel(), Nsound::FilterBandPassVocoder::makeKernel(), Nsound::FilterPhaser::operator=(), Nsound::FilterLeastSquaresFIR::operator=(), operator=(), Nsound::FilterFlanger::operator=(), Nsound::FilterTone::plot(), Nsound::FilterPhaser::plot(), Nsound::FilterParametricEqualizer::plot(), Nsound::FilterLowPassIIR::plot(), Nsound::FilterLowPassFIR::plot(), Nsound::FilterLeastSquaresFIR::plot(), Nsound::FilterHighPassIIR::plot(), Nsound::FilterHighPassFIR::plot(), Nsound::FilterFlanger::plot(), Nsound::FilterCombLowPassFeedback::plot(), Nsound::FilterBandRejectIIR::plot(), Nsound::FilterBandRejectFIR::plot(), Nsound::FilterBandPassIIR::plot(), Nsound::FilterBandPassFIR::plot(), Nsound::FilterAllPass::plot(), Nsound::FilterLowPassIIR::setCutoff(), and Nsound::FilterLeastSquaresFIR::setWindow().

uint32 Nsound::Filter::kernel_size_ [protected, inherited]

The documentation for this class was generated from the following files:
Generated on Sun Apr 15 20:10:50 2012 for nsound by  doxygen 1.6.3