Implement fir3db tool
This commit is contained in:
		
							parent
							
								
									d3f85fea20
								
							
						
					
					
						commit
						9beb3fd39d
					
				
							
								
								
									
										2
									
								
								config
								
								
								
								
							
							
						
						
									
										2
									
								
								config
								
								
								
								
							| 
						 | 
				
			
			@ -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"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
../fir2csv/200_load_filter.c
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
*/
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
*/
 | 
			
		||||
| 
						 | 
				
			
			@ -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}..."
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue