130 lines
3.3 KiB
C
130 lines
3.3 KiB
C
//==========================================================================
|
|
// Name: sox_biquad.h
|
|
// Purpose: Interface into Sox Biquad filters
|
|
// Created: Dec 1, 2012
|
|
// Authors: David Rowe
|
|
//
|
|
// To test:
|
|
// $ gcc sox_biquad.c -o sox_biquad -DSOX_BIQUAD_UNITTEST -Wall \
|
|
// /path/to/sox-14.4.0/src/.libs/libsox.a -lm -lsndfile
|
|
// $ ./sox_biquad
|
|
//
|
|
// License:
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License version 2.1,
|
|
// as published by the Free Software Foundation. This program 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 General Public
|
|
// License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
//==========================================================================
|
|
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "sox.h"
|
|
|
|
#include "sox_biquad.h"
|
|
|
|
|
|
#define N_MAX 1024
|
|
|
|
int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf,
|
|
sox_sample_t *obuf, size_t *isamp, size_t *osamp);
|
|
|
|
void sox_biquad_start(void)
|
|
{
|
|
int r = sox_init();
|
|
assert(r == SOX_SUCCESS);
|
|
}
|
|
|
|
void sox_biquad_finish(void)
|
|
{
|
|
sox_quit();
|
|
}
|
|
|
|
/*
|
|
Effect must be implemented by biquads.c in sox, arguments are just
|
|
like sox command line, for example:
|
|
|
|
char *argv[10];
|
|
argv[0] = "highpass"; argv[1]="1000"; argc=1;
|
|
*/
|
|
|
|
void *sox_biquad_create(int argc, const char *argv[])
|
|
{
|
|
int ret;
|
|
sox_effect_t *e;
|
|
int (*start)(sox_effect_t *); /* function pointer to effect start func */
|
|
|
|
e = sox_create_effect(sox_find_effect(argv[0])); assert(e != NULL);
|
|
ret = sox_effect_options(e, argc, (char * const*)&argv[1]);
|
|
assert(ret == SOX_SUCCESS);
|
|
|
|
start = e->handler.start;
|
|
e->in_signal.rate = 8000; /* locked at FS=8000 Hz */
|
|
ret = start(e); assert(ret == SOX_SUCCESS);
|
|
|
|
return (void *)e;
|
|
}
|
|
|
|
void sox_biquad_destroy(void *sbq) {
|
|
sox_effect_t *e = (sox_effect_t *)sbq;
|
|
free(e);
|
|
}
|
|
|
|
void sox_biquad_filter(void *sbq, short out[], short in[], int n)
|
|
{
|
|
sox_effect_t *e = (sox_effect_t *)sbq;
|
|
sox_sample_t ibuf[N_MAX];
|
|
sox_sample_t obuf[N_MAX];
|
|
size_t isamp, osamp;
|
|
unsigned int clips;
|
|
SOX_SAMPLE_LOCALS;
|
|
int i;
|
|
|
|
assert(n <= N_MAX);
|
|
|
|
clips = 0;
|
|
for(i=0; i<n; i++)
|
|
ibuf[i] = SOX_SIGNED_16BIT_TO_SAMPLE(in[i], clips);
|
|
isamp = osamp = (unsigned int)n;
|
|
lsx_biquad_flow(e, ibuf, obuf, &isamp, &osamp);
|
|
for(i=0; i<n; i++)
|
|
out[i] = SOX_SAMPLE_TO_SIGNED_16BIT(obuf[i], clips);
|
|
}
|
|
|
|
|
|
#ifdef SOX_BIQUAD_UNITTEST
|
|
#define N 20
|
|
int main(void) {
|
|
void *sbq;
|
|
char *argv[10];
|
|
short in[N];
|
|
short out[N];
|
|
int i, argc;;
|
|
|
|
for(i=0; i<N; i++)
|
|
in[i] = 0;
|
|
in[0] = 8000;
|
|
|
|
sox_biquad_start();
|
|
argv[0] = "highpass"; argv[1]="1000"; argc=1;
|
|
sbq = sox_biquad_create(argc, argv);
|
|
|
|
sox_biquad_filter(sbq, out, in, N);
|
|
for(i=0; i<N; i++)
|
|
printf("%d\n", out[i]);
|
|
|
|
sox_biquad_destroy(sbq);
|
|
sox_biquad_finish();
|
|
|
|
return 0;
|
|
}
|
|
#endif
|