package com.nerdscentral.audio.pitch.algorithm;
import com.nerdscentral.audio.core.SFConstants;
/*
* RBJ Filters from C++ version by arguru[AT]smartelectronix[DOT]com based on eq filter cookbook by Robert Bristow-Johnson
* <rbj@audioimagination.com> The C++ code is believed to be public domain and license free after best efforts to establish its licensing. As this is a Java translation of that code I have placed this in the public domain as well.
*/
public class SFRBJFilter
{
// filter coeffs
double b0a0, b1a0, b2a0, a1a0, a2a0;
// in/out history
double ou1, ou2, in1, in2;
public SFRBJFilter()
{
// reset filter coeffs
b0a0 = b1a0 = b2a0 = a1a0 = a2a0 = 0.0;
// reset in/out history
ou1 = ou2 = in1 = in2 = 0.0f;
}
public double filter(double in0)
{
// filter
final double yn = b0a0 * in0 + b1a0 * in1 + b2a0 * in2 - a1a0 * ou1 - a2a0 * ou2;
// push in/out buffers
in2 = in1;
in1 = in0;
ou2 = ou1;
ou1 = yn;
// return output
return yn;
}
public double limitedFilter(double in0)
{
// filter
double yn = b0a0 * in0 + b1a0 * in1 + b2a0 * in2 - a1a0 * ou1 - a2a0 * ou2;
double ay = yn < 0 ? -yn : yn;
if(ay > 1.0)
{
yn = yn < 0 ? -1.0 : 1.0;
}
// push in/out buffers
in2 = in1;
in1 = in0;
ou2 = ou1;
ou1 = yn;
// return output
return yn;
}
public enum FilterType
{
LOWPASS, HIGHPASS, BANDPASS_SKIRT, BANDPASS_PEAK, NOTCH, ALLPASS, PEAK, LOWSHELF, HIGHSHELF
}
public void calc_filter_coeffs(final FilterType type, final double frequency, final double q, final double db_gain)
{
boolean q_is_bandwidth;
final double sample_rate = SFConstants.SAMPLE_RATE;
switch (type)
{
case ALLPASS:
case HIGHPASS:
case LOWPASS:
case LOWSHELF:
case HIGHSHELF:
q_is_bandwidth = false;
break;
default:
q_is_bandwidth = true;
break;
}
// System.out.println("Q Is Bandwidth " + q_is_bandwidth);
// temp pi
final double temp_pi = 3.1415926535897932384626433832795;
// temp coef vars
double alpha, a0 = 0, a1 = 0, a2 = 0, b0 = 0, b1 = 0, b2 = 0;
// peaking, lowshelf and hishelf
if (type == FilterType.PEAK || type == FilterType.HIGHSHELF || type == FilterType.LOWSHELF)
{
final double A = Math.pow(10.0, (db_gain / 40.0));
final double omega = 2.0 * temp_pi * frequency / sample_rate;
final double tsin = Math.sin(omega);
final double tcos = Math.cos(omega);
if (type == FilterType.PEAK) alpha = tsin * Math.sinh(Math.log(2.0) / 2.0 * q * omega / tsin);
else
alpha = tsin / 2.0 * Math.sqrt((A + 1 / A) * (1 / q - 1) + 2);
final double beta = Math.sqrt(A) / q;
// peaking
if (type == FilterType.PEAK)
{
b0 = (1.0 + alpha * A);
b1 = (-2.0 * tcos);
b2 = (1.0 - alpha * A);
a0 = (1.0 + alpha / A);
a1 = (-2.0 * tcos);
a2 = (1.0 - alpha / A);
}
// lowshelf
if (type == FilterType.LOWSHELF)
{
b0 = (A * ((A + 1.0) - (A - 1.0) * tcos + beta * tsin));
b1 = (2.0 * A * ((A - 1.0) - (A + 1.0) * tcos));
b2 = (A * ((A + 1.0) - (A - 1.0) * tcos - beta * tsin));
a0 = ((A + 1.0) + (A - 1.0) * tcos + beta * tsin);
a1 = (-2.0 * ((A - 1.0) + (A + 1.0) * tcos));
a2 = ((A + 1.0) + (A - 1.0) * tcos - beta * tsin);
}
// hishelf
if (type == FilterType.HIGHSHELF)
{
b0 = (A * ((A + 1.0) + (A - 1.0) * tcos + beta * tsin));
b1 = (-2.0 * A * ((A - 1.0) + (A + 1.0) * tcos));
b2 = (A * ((A + 1.0) + (A - 1.0) * tcos - beta * tsin));
a0 = ((A + 1.0) - (A - 1.0) * tcos + beta * tsin);
a1 = (2.0 * ((A - 1.0) - (A + 1.0) * tcos));
a2 = ((A + 1.0) - (A - 1.0) * tcos - beta * tsin);
}
}
else
{
// other filters
final double omega = 2.0 * temp_pi * frequency / sample_rate;
final double tsin = Math.sin(omega);
final double tcos = Math.cos(omega);
if (q_is_bandwidth) alpha = tsin * Math.sinh(Math.log(2.0) / 2.0 * q * omega / tsin);
else
alpha = tsin / (2.0 * q);
// lowpass
if (type == FilterType.LOWPASS)
{
b0 = (1.0 - tcos) / 2.0;
b1 = 1.0 - tcos;
b2 = (1.0 - tcos) / 2.0;
a0 = 1.0 + alpha;
a1 = -2.0 * tcos;
a2 = 1.0 - alpha;
}
// hipass
if (type == FilterType.HIGHPASS)
{
b0 = (1.0 + tcos) / 2.0;
b1 = -(1.0 + tcos);
b2 = (1.0 + tcos) / 2.0;
a0 = 1.0 + alpha;
a1 = -2.0 * tcos;
a2 = 1.0 - alpha;
}
// bandpass csg
if (type == FilterType.BANDPASS_SKIRT)
{
b0 = tsin / 2.0;
b1 = 0.0;
b2 = -tsin / 2;
a0 = 1.0 + alpha;
a1 = -2.0 * tcos;
a2 = 1.0 - alpha;
}
// bandpass czpg
if (type == FilterType.BANDPASS_PEAK)
{
b0 = alpha;
b1 = 0.0;
b2 = -alpha;
a0 = 1.0 + alpha;
a1 = -2.0 * tcos;
a2 = 1.0 - alpha;
}
// notch
if (type == FilterType.NOTCH)
{
b0 = 1.0;
b1 = -2.0 * tcos;
b2 = 1.0;
a0 = 1.0 + alpha;
a1 = -2.0 * tcos;
a2 = 1.0 - alpha;
}
// allpass
if (type == FilterType.ALLPASS)
{
b0 = 1.0 - alpha;
b1 = -2.0 * tcos;
b2 = 1.0 + alpha;
a0 = 1.0 + alpha;
a1 = -2.0 * tcos;
a2 = 1.0 - alpha;
}
}
// set filter coeffs
b0a0 = (b0 / a0);
b1a0 = (b1 / a0);
b2a0 = (b2 / a0);
a1a0 = (a1 / a0);
a2a0 = (a2 / a0);
}
}
import com.nerdscentral.audio.core.SFConstants;
/*
* RBJ Filters from C++ version by arguru[AT]smartelectronix[DOT]com based on eq filter cookbook by Robert Bristow-Johnson
* <rbj@audioimagination.com> The C++ code is believed to be public domain and license free after best efforts to establish its licensing. As this is a Java translation of that code I have placed this in the public domain as well.
*/
public class SFRBJFilter
{
// filter coeffs
double b0a0, b1a0, b2a0, a1a0, a2a0;
// in/out history
double ou1, ou2, in1, in2;
public SFRBJFilter()
{
// reset filter coeffs
b0a0 = b1a0 = b2a0 = a1a0 = a2a0 = 0.0;
// reset in/out history
ou1 = ou2 = in1 = in2 = 0.0f;
}
public double filter(double in0)
{
// filter
final double yn = b0a0 * in0 + b1a0 * in1 + b2a0 * in2 - a1a0 * ou1 - a2a0 * ou2;
// push in/out buffers
in2 = in1;
in1 = in0;
ou2 = ou1;
ou1 = yn;
// return output
return yn;
}
public double limitedFilter(double in0)
{
// filter
double yn = b0a0 * in0 + b1a0 * in1 + b2a0 * in2 - a1a0 * ou1 - a2a0 * ou2;
double ay = yn < 0 ? -yn : yn;
if(ay > 1.0)
{
yn = yn < 0 ? -1.0 : 1.0;
}
// push in/out buffers
in2 = in1;
in1 = in0;
ou2 = ou1;
ou1 = yn;
// return output
return yn;
}
public enum FilterType
{
LOWPASS, HIGHPASS, BANDPASS_SKIRT, BANDPASS_PEAK, NOTCH, ALLPASS, PEAK, LOWSHELF, HIGHSHELF
}
public void calc_filter_coeffs(final FilterType type, final double frequency, final double q, final double db_gain)
{
boolean q_is_bandwidth;
final double sample_rate = SFConstants.SAMPLE_RATE;
switch (type)
{
case ALLPASS:
case HIGHPASS:
case LOWPASS:
case LOWSHELF:
case HIGHSHELF:
q_is_bandwidth = false;
break;
default:
q_is_bandwidth = true;
break;
}
// System.out.println("Q Is Bandwidth " + q_is_bandwidth);
// temp pi
final double temp_pi = 3.1415926535897932384626433832795;
// temp coef vars
double alpha, a0 = 0, a1 = 0, a2 = 0, b0 = 0, b1 = 0, b2 = 0;
// peaking, lowshelf and hishelf
if (type == FilterType.PEAK || type == FilterType.HIGHSHELF || type == FilterType.LOWSHELF)
{
final double A = Math.pow(10.0, (db_gain / 40.0));
final double omega = 2.0 * temp_pi * frequency / sample_rate;
final double tsin = Math.sin(omega);
final double tcos = Math.cos(omega);
if (type == FilterType.PEAK) alpha = tsin * Math.sinh(Math.log(2.0) / 2.0 * q * omega / tsin);
else
alpha = tsin / 2.0 * Math.sqrt((A + 1 / A) * (1 / q - 1) + 2);
final double beta = Math.sqrt(A) / q;
// peaking
if (type == FilterType.PEAK)
{
b0 = (1.0 + alpha * A);
b1 = (-2.0 * tcos);
b2 = (1.0 - alpha * A);
a0 = (1.0 + alpha / A);
a1 = (-2.0 * tcos);
a2 = (1.0 - alpha / A);
}
// lowshelf
if (type == FilterType.LOWSHELF)
{
b0 = (A * ((A + 1.0) - (A - 1.0) * tcos + beta * tsin));
b1 = (2.0 * A * ((A - 1.0) - (A + 1.0) * tcos));
b2 = (A * ((A + 1.0) - (A - 1.0) * tcos - beta * tsin));
a0 = ((A + 1.0) + (A - 1.0) * tcos + beta * tsin);
a1 = (-2.0 * ((A - 1.0) + (A + 1.0) * tcos));
a2 = ((A + 1.0) + (A - 1.0) * tcos - beta * tsin);
}
// hishelf
if (type == FilterType.HIGHSHELF)
{
b0 = (A * ((A + 1.0) + (A - 1.0) * tcos + beta * tsin));
b1 = (-2.0 * A * ((A - 1.0) + (A + 1.0) * tcos));
b2 = (A * ((A + 1.0) + (A - 1.0) * tcos - beta * tsin));
a0 = ((A + 1.0) - (A - 1.0) * tcos + beta * tsin);
a1 = (2.0 * ((A - 1.0) - (A + 1.0) * tcos));
a2 = ((A + 1.0) - (A - 1.0) * tcos - beta * tsin);
}
}
else
{
// other filters
final double omega = 2.0 * temp_pi * frequency / sample_rate;
final double tsin = Math.sin(omega);
final double tcos = Math.cos(omega);
if (q_is_bandwidth) alpha = tsin * Math.sinh(Math.log(2.0) / 2.0 * q * omega / tsin);
else
alpha = tsin / (2.0 * q);
// lowpass
if (type == FilterType.LOWPASS)
{
b0 = (1.0 - tcos) / 2.0;
b1 = 1.0 - tcos;
b2 = (1.0 - tcos) / 2.0;
a0 = 1.0 + alpha;
a1 = -2.0 * tcos;
a2 = 1.0 - alpha;
}
// hipass
if (type == FilterType.HIGHPASS)
{
b0 = (1.0 + tcos) / 2.0;
b1 = -(1.0 + tcos);
b2 = (1.0 + tcos) / 2.0;
a0 = 1.0 + alpha;
a1 = -2.0 * tcos;
a2 = 1.0 - alpha;
}
// bandpass csg
if (type == FilterType.BANDPASS_SKIRT)
{
b0 = tsin / 2.0;
b1 = 0.0;
b2 = -tsin / 2;
a0 = 1.0 + alpha;
a1 = -2.0 * tcos;
a2 = 1.0 - alpha;
}
// bandpass czpg
if (type == FilterType.BANDPASS_PEAK)
{
b0 = alpha;
b1 = 0.0;
b2 = -alpha;
a0 = 1.0 + alpha;
a1 = -2.0 * tcos;
a2 = 1.0 - alpha;
}
// notch
if (type == FilterType.NOTCH)
{
b0 = 1.0;
b1 = -2.0 * tcos;
b2 = 1.0;
a0 = 1.0 + alpha;
a1 = -2.0 * tcos;
a2 = 1.0 - alpha;
}
// allpass
if (type == FilterType.ALLPASS)
{
b0 = 1.0 - alpha;
b1 = -2.0 * tcos;
b2 = 1.0 + alpha;
a0 = 1.0 + alpha;
a1 = -2.0 * tcos;
a2 = 1.0 - alpha;
}
}
// set filter coeffs
b0a0 = (b0 / a0);
b1a0 = (b1 / a0);
b2a0 = (b2 / a0);
a1a0 = (a1 / a0);
a2a0 = (a2 / a0);
}
}
The way you presented the blog is really good... Thaks for sharing with us...
ReplyDeleteSoftware Testing Course in Madurai
Software testing Training in Madurai
software testing course in coimbatore with placement
Software Testing Course in Coimbatore
Digital Marketing Courses in Bangalore
German Language Course in Madurai
Android Training in Coimbatore
CCNA Course in Coimbatore
Digital Marketing Course in Coimbatore
Nice article. I liked very much. All the informations given by you are really helpful for my research. keep on posting your views.
ReplyDeleteHadoop Training in Chennai
Big Data Training in Chennai
German Language Classes in Chennai
Advanced Java Training in Chennai
AWS Training in Chennai
Big Data Analytics Courses in Chennai
Hadoop Course in Chennai
Hadoop Training in TNagar
Very Good Post thanks for Sharing information....
ReplyDeleteSEO Training in Bangalore | SEO Course Fees | Best SEO Classes - Join SEO Training in Bangalore at i Digital Academy and learn how to increase your website Traffic by
Google Certified Trainers with 100% Placements and affordable course fees. Book a Free Demo!
Thanks for your excellent blog and giving great kind of information.
ReplyDeleteGreat post!! This can be one particular of the most useful blogs.
Digital Marketing Training in Chennai | Certification | SEO Training Course | Digital Marketing Training in Bangalore | Certification | SEO Training Course | Digital Marketing Training in Hyderabad | Certification | SEO Training Course | Digital Marketing Training in Coimbatore | Certification | SEO Training Course | Digital Marketing Online Training | Certification | SEO Online Training Course
Seriously, I consider your blog is one amongst best blogs that I found. Your efforts awfully help make reading your blog considerably easier.
ReplyDeleteJava Training in Chennai
Java Course in Chennai