Implement fir3db tool

This commit is contained in:
Laurence Withers 2014-09-09 12:46:25 +00:00
parent d3f85fea20
commit 9beb3fd39d
6 changed files with 175 additions and 3 deletions

2
config
View File

@ -33,8 +33,6 @@ source "scripts/paths"
# Project-specific variables below.
[ -z "${LIBFIR_CFLAGS}" ] && LIBFIR_CFLAGS="$(libfir-config --cflags)"
[ -z "${LIBFIR_LIBS}" ] && LIBFIR_LIBS="$(libfir-config --libs)"
[ -z "${GSL_CFLAGS}" ] && GSL_CFLAGS="$(gsl-config --cflags)"
[ -z "${GSL_LIBS}" ] && GSL_LIBS="$(gsl-config --libs)"
[ -z "${CC}" ] && CC="gcc"
[ -z "${CFLAGS}" ] && CFLAGS="-g -O2 -W -Wall"

View File

@ -6,6 +6,16 @@
*/
/* Below are all the includes used throughout the application. */
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fir.h>
/* options for text editors
vim: expandtab:ts=4:sw=4

View File

@ -0,0 +1 @@
../fir2csv/200_load_filter.c

77
src/fir3db/800_fir3db.c Normal file
View File

@ -0,0 +1,77 @@
/* fir-tools/src/fir3db/800_fir3db.c
*
* Copyright: ©2014, Laurence Withers
* Author: Laurence Withers <l@lwithers.me.uk>
* License: GPLv3
*/
enum {
/* number of points for initial coarse search */
npoints = 1000,
/* number of iterations when finding -3dB point */
niter = 10,
};
void
fir3db_aux(struct fir_filter_t* fi, double freq1, double freq2, double gain)
{
int i;
double complex resp;
double fmid, mag;
for(i = 0; i < niter; ++i) {
fmid = (freq1 + freq2) / 2;
resp = fir_filter_response(fi, fmid);
mag = cabs(resp);
if(mag > gain) {
freq2 = fmid;
} else {
freq1 = fmid;
}
}
printf("%.8g\n", fmid);
}
void
fir3db(struct fir_filter_t* fi, double gain)
{
double freq, freq_last, mag, mag_last;
double complex resp;
int i;
resp = fir_filter_response(fi, 0);
mag_last = cabs(resp);
freq_last = 0;
for(i = 1; i < npoints; ++i) {
freq = (i * 0.5) / (npoints - 1);
resp = fir_filter_response(fi, freq);
mag = cabs(resp);
if(mag_last < gain && mag >= gain) {
fir3db_aux(fi, freq_last, freq, gain);
}
if(mag_last >= gain && mag < gain) {
fir3db_aux(fi, freq, freq_last, gain);
}
mag_last = mag;
freq_last = freq;
}
}
/* options for text editors
vim: expandtab:ts=4:sw=4
*/

85
src/fir3db/999_main.c Normal file
View File

@ -0,0 +1,85 @@
/* fir-tools/src/fir3db/999_main.c
*
* Copyright: ©2014, Laurence Withers
* Author: Laurence Withers <l@lwithers.me.uk>
* License: GPLv3
*/
void
usage(void)
{
fputs("Usage:\n\n"
" " APP_NAME " [options] coeff.txt\n\n"
"Options:\n"
" -h, --help Display this screen.\n"
" -V, --version Display version number.\n"
" -g, --gain <gain> Gain to search for (default: 0.5).\n"
"", stdout);
}
const struct option options[] = {
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'V' },
{ "gain", no_argument, 0, 'g' },
{ 0, 0, 0, 0 }
};
const char* optstr = "g:hV";
int
main(int argc, char* argv[])
{
struct fir_filter_t* fi;
double gain = 0.5;
char* endp;
while(1) {
switch(getopt_long(argc, argv, optstr, options, 0)) {
case -1:
goto opts_done;
case '?':
return 1;
case 'h':
usage();
return 0;
case 'V':
fputs(APP_NAME " " VERSION "\n", stdout);
return 0;
case 'g':
errno = 0;
gain = strtod(optarg, &endp);
if(errno || !endp || *endp || gain <= 0) {
fputs(APP_NAME ": invalid gain. Expecting magnitude > 0.\n",
stderr);
return 1;
}
break;
}
}
opts_done:
if(optind != (argc - 1)) {
usage();
return 1;
}
fi = load_filter(argv[optind]);
fir3db(fi, gain);
return 0;
}
/* options for text editors
vim: expandtab:ts=4:sw=4
*/

View File

@ -6,7 +6,8 @@
if [ -z ${fir3db_BUILT} ]
then
fir3db="obj/fir3db"
EXTRAS="-std=gnu99 -D_GNU_SOURCE -DAPP_NAME=\"fir3db\"" # TODO: more flags
EXTRAS="-std=gnu99 -D_GNU_SOURCE -DAPP_NAME=\"fir3db\" -lm \
${LIBFIR_CFLAGS} ${LIBFIR_LIBS}"
echo "Building application ${fir3db}..."