46 using namespace Nsound;
55 #define PRINT_LINE "FilterIIR.cc:" << __LINE__ << ": "
94 n_poles_(copy.n_poles_),
128 const Buffer & frequency_response,
130 const int32 max_iterations)
142 const Buffer & impulse_response,
144 const int32 max_iterations)
213 const Buffer & ref_response,
235 Buffer delta = ref_response - r;
250 const Buffer & ref_response,
252 const int32 max_iterations,
261 while( p2 < ref_size )
268 if(ref_size != p2) ::exit(1);
277 int32 dead_count = 0;
278 while(rms_error > LARGE_RMS && dead_count < 1000)
281 rms_error =
getRMS(*mom, ref_response, type);
287 if(rms_error > LARGE_RMS) ::exit(1);
293 int32 N_CHILDREN = 14;
298 for(
int32 i = 0; i < N_CHILDREN; ++i)
305 rms_history << rms_error;
309 cout << std::setprecision(10)
310 <<
"mom's RMS = " << rms_error << endl
311 <<
"dad's RMS = " << dad_rms_error << endl;
313 float64 rms_error1 = LARGE_RMS;
314 float64 rms_error2 = LARGE_RMS;
319 float64 last_rms_error = rms_error;
320 int32 stale_count = 0;
321 int32 major_stale_count = 0;
324 while(count < max_iterations && rms_error > max_rms_error)
334 cout << __LINE__ <<
"\tmom.getSum() = " << mom->
getSum()
335 <<
"\terror = " << error << endl << endl;
345 cout << __LINE__ <<
"\tmom.getSum() = " << mom->
getSum()
346 <<
"\terror = " << error << endl << endl;
353 for(
uint32 i = 4; i < 6; ++i)
359 child[i]->
setB(child[i]->getB(index) + delta, index);
361 delta =
rng_->
get(-0.1f, 0.1f);
365 child[i]->
setA(child[i]->getA(index) + delta, index);
369 cout << __LINE__ <<
"\tmom.getSum() = " << mom->
getSum()
370 <<
"\terror = " << error << endl << endl;
377 for(
uint32 i = 6; i < 8; ++i)
385 child[i]->
setB(child[i]->getB(index) * -1.0, index);
389 child[i]->
setA(child[i]->getA(index) * -1.0, index);
394 cout << __LINE__ <<
"\tmom.getSum() = " << mom->
getSum()
395 <<
"\terror = " << error << endl << endl;
402 for(
uint32 i = 8; i < 10; ++i)
412 child[i]->
setB(child[i]->getB(index) * delta, index);
416 child[i]->
setA(child[i]->getA(index) * delta, index);
421 cout << __LINE__ <<
"\tmom.getSum() = " << mom->
getSum()
422 <<
"\terror = " << error << endl << endl;
434 if(start_index > stop_index)
436 uint32 temp = start_index;
437 start_index = stop_index;
441 for(
uint32 j = start_index; j < stop_index; ++j)
448 cout << __LINE__ <<
"\tmom.getSum() = " << mom->
getSum()
449 <<
"\terror = " << error << endl << endl;
457 if(start_index > stop_index)
459 int32 temp = start_index;
460 start_index = stop_index;
464 for(
uint32 j = start_index; j < stop_index; ++j)
471 cout << __LINE__ <<
"\tmom.getSum() = " << mom->
getSum()
472 <<
"\terror = " << error << endl << endl;
479 for(
uint32 i = 12; i < 14; ++i)
483 child[i]->
setB(child[i]->getB(j) +
rng_->
get(-0.1f, 0.1f), j);
484 child[i]->
setA(child[i]->getA(j) +
rng_->
get(-0.1f, 0.1f), j);
490 rms_error1 =
getRMS(*mom, ref_response, type);
491 rms_error2 =
getRMS(*dad, ref_response, type);
496 for(
int32 i = 0; i < N_CHILDREN; ++i)
500 if(rms > LARGE_RMS)
continue;
507 else if(rms < rms_error2)
515 cout << __LINE__ <<
"\tmom.getSum() = " << mom->
getSum()
516 <<
"\terror = " << error << endl << endl;
522 rms_error =
getRMS(*mom, ref_response, type);
523 dad_rms_error =
getRMS(*dad, ref_response, type);
525 rms_history << rms_error;
528 cout << __LINE__ <<
"\tmom.getSum() = " << mom->
getSum()
529 <<
"\terror = " << error << endl;
533 if(dad_rms_error > LARGE_RMS)
535 cout <<
PRINT_LINE <<
"dad's RMS > 10, ballistic!" << endl;
540 if(std::fabs(rms_error - last_rms_error) < STALE_RMS)
549 last_rms_error = rms_error;
553 cout <<
"Generation " << count << endl
554 <<
" 1st maximum RMS = " << rms_error << endl
555 <<
" 2nd maximum RMS = " << dad_rms_error << endl;
570 if(major_stale_count > 1)
578 major_stale_count = 0;
583 cout << __LINE__ <<
"\tmom.getSum() = " << mom->
getSum()
584 <<
"\terror = " << error << endl;
589 cout <<
"count = " << count <<
" RMS = " << rms_error << endl;
594 for(
int32 i = 0; i < N_CHILDREN; ++i)
627 for(
const float64 * b = bb; b < b_end; ++b)
644 for(
const float64 * a = aa + 1; a < a_end; ++a)
737 const Buffer & fr_reference,
745 Buffer fr_ref = fr_reference;
759 pylab.
plot(faxis, fr_ref);
760 pylab.
plot(faxis, fr);
762 pylab.
xlabel(
"Frequency Hz");
763 pylab.
ylabel(
"Frequency Response");
767 sprintf(buffer,
"Generation %06d", n);
769 pylab.
title(std::string(buffer));
772 pylab.
ylim(0.0, 1.1 * max);
774 sprintf(buffer,
"Error = %5.2f", error);
777 faxis[static_cast<uint32>(faxis.
getLength() * 0.66)],
779 std::string(buffer));
781 sprintf(buffer,
"generation_%06d.png", n);
void xlabel(const std::string &label, const std::string &kwargs="")
Add a label x axis.
void ga_interleave(Kernel &rhs)
Genitic Algorithm Helper Function: interleave B coefs with B, A with A.
#define M_ASSERT_VALUE(a, op, value)
std::ostream & operator<<(std::ostream &out, const Buffer &rhs_buffer)
void plot(const Buffer &y, const std::string &fmt="", const std::string &kwargs="")
Plots the Buffer on the current figure.
float64 getB(uint32 i)
Returns kernel 'b[i]' coef.
void figure(const std::string &kwargs="") const
Creates a new figure window to plot in.
FilterIIR & operator=(const FilterIIR &rhs)
void title(const std::string &title, const std::string &kwargs="")
Add a title to the plot at the top and centered.
void setB(const float64 *b)
Copy getBLength() values from the array a into the Kernel. Use setLength() to set the number of value...
AudioStream filter(const AudioStream &x)
void xlim(const float64 &xmin, const float64 &xmax)
Sets the limit for the x & y axis.
uint32 getLength() const
Returns the number of samples in the Buffer.
Buffer 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...
void ga_swap_ab(Kernel &rhs)
Genitic Algorithm Helper Function: swaps the A & B coefs.
float64 getRMS(const Kernel &kernel, const Buffer &response, const SignalType type)
Base class for IIR Filters, defines the interface.
void ylim(const float64 &ymin, const float64 &ymax)
Buffer getFrequencyAxis(const uint32 n_fft=8192)
uint32 getALength() const
void randomize(const float64 &min=-1.0, const float64 &max=1.0)
Sets all coefs to random float64 values between min & max.
void text(const float64 &x, const float64 &y, const std::string &text, const std::string &kwargs="")
Adds text at the x, y data point.
Buffer getImpulseResponse(const uint32 n_samples=8192)
uint32 getBLength() const
void ylabel(const std::string &label, const std::string &kwargs="")
Add a label y axis.
void savePlot(const Kernel &k, const Buffer &response, uint32 n, const float64 &error)
float64 getSum() const
Returns the sum of all samples.
A Buffer for storing audio samples.
Buffer 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...
FilterIIR(const float64 &sample_rate, uint32 n_poles)
Buffer getFrequencyResponse(const uint32 n_fft=8192)
float64 getMax() const
Returns the maximum sample value in the Buffer.
uint32 get()
Get a random number.
float64 getA(uint32 i)
Returns kernel 'a[i]' coef.
Buffer designKernel(const Buffer &response, const float64 &max_rms_error, const int32 max_iterations, const SignalType type)
Designs a filter kernel that trys to match the provide frequency response.
void setA(const float64 *a)
Copy getALength() values from the array a into the Kernel. Use setLength() to set the number of value...