Sigrid Solveig Haflínudóttirbuild libsox on Plan 9f261dd33 years agoHistory
178 lines · 5.9 KB · C
RawDownload
/* libSoX Biquad filter common functions   (c) 2006-7 robs@users.sourceforge.net * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or (at * your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA */ #include "biquad.h"#include <string.h> typedef biquad_t priv_t; static char const * const width_str[] = {  "band-width(Hz)",  "band-width(kHz)",  "band-width(Hz, no warp)", /* deprecated */  "band-width(octaves)",  "Q",  "slope",};static char const all_width_types[] = "hkboqs";  int lsx_biquad_getopts(sox_effect_t * effp, int argc, char **argv,    int min_args, int max_args, int fc_pos, int width_pos, int gain_pos,    char const * allowed_width_types, filter_t filter_type){  priv_t * p = (priv_t *)effp->priv;  char width_type = *allowed_width_types;  char dummy, * dummy_p;     /* To check for extraneous chars. */  --argc, ++argv;   p->filter_type = filter_type;  if (argc < min_args || argc > max_args ||      (argc > fc_pos    && ((p->fc = lsx_parse_frequency(argv[fc_pos], &dummy_p)) <= 0 || *dummy_p)) ||      (argc > width_pos && ((unsigned)(sscanf(argv[width_pos], "%lf%c %c", &p->width, &width_type, &dummy)-1) > 1 || p->width <= 0)) ||      (argc > gain_pos  && sscanf(argv[gain_pos], "%lf %c", &p->gain, &dummy) != 1) ||      !strchr(allowed_width_types, width_type) || (width_type == 's' && p->width > 1))    return lsx_usage(effp);  p->width_type = strchr(all_width_types, width_type) - all_width_types;  if ((size_t)p->width_type >= strlen(all_width_types))    p->width_type = 0;  if (p->width_type == width_bw_kHz) {    p->width *= 1000;    p->width_type = width_bw_Hz;  }  return SOX_SUCCESS;}  static int start(sox_effect_t * effp){  priv_t * p = (priv_t *)effp->priv;  /* Simplify: */  p->b2 /= p->a0;  p->b1 /= p->a0;  p->b0 /= p->a0;  p->a2 /= p->a0;  p->a1 /= p->a0;   p->o2 = p->o1 = p->i2 = p->i1 = 0;  return SOX_SUCCESS;}  int lsx_biquad_start(sox_effect_t * effp){  priv_t * p = (priv_t *)effp->priv;   start(effp);   if (effp->global_info->plot == sox_plot_octave) {    printf(      "%% GNU Octave file (may also work with MATLAB(R) )\n"      "Fs=%g;minF=10;maxF=Fs/2;\n"      "sweepF=logspace(log10(minF),log10(maxF),200);\n"      "[h,w]=freqz([%.15e %.15e %.15e],[1 %.15e %.15e],sweepF,Fs);\n"      "semilogx(w,20*log10(h))\n"      "title('SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)')\n"      "xlabel('Frequency (Hz)')\n"      "ylabel('Amplitude Response (dB)')\n"      "axis([minF maxF -35 25])\n"      "grid on\n"      "disp('Hit return to continue')\n"      "pause\n"      , effp->in_signal.rate, p->b0, p->b1, p->b2, p->a1, p->a2      , effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width      , effp->in_signal.rate);    return SOX_EOF;  }  if (effp->global_info->plot == sox_plot_gnuplot) {    printf(      "# gnuplot file\n"      "set title 'SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)'\n"      "set xlabel 'Frequency (Hz)'\n"      "set ylabel 'Amplitude Response (dB)'\n"      "Fs=%g\n"      "b0=%.15e; b1=%.15e; b2=%.15e; a1=%.15e; a2=%.15e\n"      "o=2*pi/Fs\n"      "H(f)=sqrt((b0*b0+b1*b1+b2*b2+2.*(b0*b1+b1*b2)*cos(f*o)+2.*(b0*b2)*cos(2.*f*o))/(1.+a1*a1+a2*a2+2.*(a1+a1*a2)*cos(f*o)+2.*a2*cos(2.*f*o)))\n"      "set logscale x\n"      "set samples 250\n"      "set grid xtics ytics\n"      "set key off\n"      "plot [f=10:Fs/2] [-35:25] 20*log10(H(f))\n"      "pause -1 'Hit return to continue'\n"      , effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width      , effp->in_signal.rate, effp->in_signal.rate      , p->b0, p->b1, p->b2, p->a1, p->a2);    return SOX_EOF;  }  if (effp->global_info->plot == sox_plot_data) {    printf("# SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)\n"      "# IIR filter\n"      "# rate: %g\n"      "# name: b\n"      "# type: matrix\n"      "# rows: 3\n"      "# columns: 1\n"      "%24.16e\n%24.16e\n%24.16e\n"      "# name: a\n"      "# type: matrix\n"      "# rows: 3\n"      "# columns: 1\n"      "%24.16e\n%24.16e\n%24.16e\n"      , effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width      , effp->in_signal.rate, effp->in_signal.rate      , p->b0, p->b1, p->b2, 1. /* a0 */, p->a1, p->a2);    return SOX_EOF;  }  return SOX_SUCCESS;}  int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf,    sox_sample_t *obuf, size_t *isamp, size_t *osamp){  priv_t * p = (priv_t *)effp->priv;  size_t len = *isamp = *osamp = min(*isamp, *osamp);  while (len--) {    double o0 = *ibuf*p->b0 + p->i1*p->b1 + p->i2*p->b2 - p->o1*p->a1 - p->o2*p->a2;    p->i2 = p->i1, p->i1 = *ibuf++;    p->o2 = p->o1, p->o1 = o0;    *obuf++ = SOX_ROUND_CLIP_COUNT(o0, effp->clips);  }  return SOX_SUCCESS;} static int soxcreate(sox_effect_t * effp, int argc, char * * argv){  priv_t             * p = (priv_t *)effp->priv;  double             * d = &p->b0;  char               c;   --argc, ++argv;  if (argc == 6)    for (; argc && sscanf(*argv, "%lf%c", d, &c) == 1; --argc, ++argv, ++d);  return argc? lsx_usage(effp) : SOX_SUCCESS;} sox_effect_handler_t const * lsx_biquad_effect_fn(void){  static sox_effect_handler_t handler = {    "biquad", "b0 b1 b2 a0 a1 a2", 0,    soxcreate, lsx_biquad_start, lsx_biquad_flow, NULL, NULL, NULL, sizeof(priv_t)  };  return &handler;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t