| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- /*
- * Copyright (c) 1983-2013 Composers Desktop Project Ltd
- * http://www.composersdesktop.com
- * This file is part of the CDP System.
- * The CDP System 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.
- *
- * The CDP System 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 the CDP System; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
- /* allpass.c
- * allpass filter
- * A. Bentley, Composers' Desktop Project, Version Nov 1987
- */
- /*
- * $Log: allpass.c%v $
- * Revision 3.3 1994/10/31 22:08:15 martin
- * first rcs version
- *
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <sfsys.h>
- #include <cdplib.h>
- static char *sfsys_h_rcsid = SFSYS_H_RCSID;
- static char *cdplib_h_rcsid = CDPLIB_H_RCSID;
- void usage();
- void allpass_long(long,long,long,long,const short*,short*,long*,short *);
- #define BUFLEN (32768)
- #define FP_ONE (65536.0)
- #define LOG_PS (16)
- PROGRAM_NUMBER(0xf93c2700);
- void
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int ifd, ofd;
- int sampsize;
- int quickflag = 1; /* default is fast fixed point calc */
- register int rv;
- float ip, op;
- #ifdef ORIGINAL_VERSION
- long lip, lop;
- long i;
- #endif
- float *delbuf1;
- float *delbuf2;
- long rdsamps;
- long *ldelbuf1;
- short *sdelbuf2;
- short *sinbuf;
- short *soutbuf;
- double delay;
- float gain, prescale = 1.0f;
- long lgain, lprescale;
- long delsamps;
- long dbp1 = 0, dbp2 = 0;
- long chans;
- long isr;
- double sr;
- if(sflinit("allpass")){
- sfperror("Allpass: initialisation");
- exit(1);
- }
- while(argv[1] != 0 && argv[1][0] == '-') {
- switch(argv[1][1]) {
- case 'f':
- quickflag--;
- argv++;
- argc--;
- break;
- default:
- usage();
- break;
- }
- }
- if(argc < 5 || argc > 6) usage();
- if(argv[1] != 0) {
- if((ifd = sndopen(argv[1])) < 0) {
- fprintf(stderr,"Allpass: cannot open input file %s\n", argv[1]);
- exit(1);
- }
- }
- if(sndgetprop(ifd,"sample rate",(char *) &isr, sizeof(long)) < 0){
- fprintf(stderr,
- "\nAllpass: failed to read sample rate for file %s",argv[1]);
- exit(1);
- }
- sr = (double) (isr);
- if(sndgetprop(ifd,"channels",(char *) &chans, sizeof(long)) < 0){
- fprintf(stderr,
- "\nAllpass: failed to read channel data for file %s", argv[1]);
- exit(1);
- }
- if(chans != 1){
- fprintf(stderr,"\nAllpass works only on mono files");
- exit(1);
- }
- if(sndgetprop(ifd,"sample type",(char *) &sampsize, sizeof(long)) < 0){
- fprintf(stderr,
- "\nAllpass: failed to read sample type for file %s", argv[1]);
- exit(1);
- }
- /* get command line args */
- delay = abexpr(argv[3],sr);
- if(delay < 0.0){
- fprintf(stderr,"\nAllpass: invalid delay parameter");
- exit(1);
- }
- gain = (float)abexpr(argv[4],sr);
- if((gain < -1.0) || (gain > 1.0)){
- fprintf(stderr,"\nAllpass: gain out of range");
- exit(1);
- }
- if((ofd = sndcreat(argv[2],-1,sampsize)) < 0) {
- fprintf(stderr,"Cannot open output file %s\n",argv[2]);
- exit(1);
- }
- lgain = (long) (gain * FP_ONE);
- if(argc > 5) {
- prescale = (float)abexpr(argv[5],sr);
- if((prescale < -1.0) || (prescale > 1.0))
- fprintf(stderr,
- "Allpass: warning - prescale exceeds +/-1\n");
- }
- lprescale = (long) (prescale * FP_ONE);
- /* allocate buffer for delay line */
- delsamps = (long) (delay * sr);
- if(quickflag) {
- if(( sinbuf = (short *) malloc(BUFLEN * sizeof(short))) == NULL) {
- fprintf(stderr,"\nNot enough memory for input buffer");
- exit(1);
- }
- if(( soutbuf = (short *) malloc(BUFLEN * sizeof(short))) == NULL) {
- fprintf(stderr,"\nNot enough memory for output buffer");
- exit(1);
- }
- if(( ldelbuf1 = (long *) calloc(delsamps, sizeof(long))) == NULL) {
- fprintf(stderr,"\nNot enough memory for delay buffer 1");
- exit(1);
- }
- if(( sdelbuf2 = (short *) calloc(delsamps, sizeof(short))) == NULL) {
- fprintf(stderr,"\nNot enough memory for delay buffer 2");
- exit(1);
- }
- }else{
- if(( delbuf1 = (float *) calloc(delsamps, sizeof(float))) == NULL) {
- fprintf(stderr,"\nNot enough memory for delay buffer 1");
- exit(1);
- }
- if(( delbuf2 = (float *) calloc(delsamps, sizeof(float))) == NULL) {
- fprintf(stderr,"\nNot enough memory for delay buffer 2");
- exit(1);
- }
- }
- stopwatch(1);
-
- for(;;){
- if((rv = fgetfloat(&ip,ifd)) < 0){
- fprintf(stderr,"\nError in reading file");
- exit(1);
- }
- if(!rv) break;
- ip *= prescale;
- op = (-gain) * ip;
- op += delbuf1[dbp1];
- op += gain * delbuf2[dbp2];
- delbuf1[dbp1++] = ip;
- delbuf2[dbp2++] = op;
- if(dbp1 >= delsamps) dbp1 = 0;
- if(dbp2 >= delsamps) dbp2 = 0;
- if(fputfloat(&op,ofd) < 1){
- fprintf(stderr,"\nError writing to output file");
- exit(1);
- }
- }
- stopwatch(0);
- sndclose(ifd);
- if(sndputprop(ofd,"sample rate", (char *) &isr, sizeof(long)) < 0){
- fprintf(stderr,"\nAllpass: failed to write sample rate");
- }
- if(sndputprop(ofd,"channels",(char *) &chans, sizeof(long)) < 0){
- fprintf(stderr,"\nAllpass: failed to write channel data");
- }
- sndclose(ofd);
- }
- void
- usage()
- {
- fprintf(stderr,"\nAllpass - A Groucho Program: $Revision: 3.3 $");
- fprintf(stderr,"\n%s\n",
- "usage: allpass [-f] infile outfile delay gain [prescale]");
- exit(0);
- }
- /*RWD: my allpass functions */
- //TODO: optimize using ptr arithmetic
- void allpass_long(long prescale,
- long buflen,
- long l_gain,
- long l_delsamps,
- const short *s_inbuf,
- short *s_outbuf,
- long *l_delbuf1,
- short *s_delbuf2)
- {
- int i;
- static long db_p1 = 0;
- static long db_p2 = 0;
- //do allpass on block of samples
- for(i = 0; i < buflen; i++){
- long lip,lop;
- lip = s_inbuf[i] * prescale;
- lop = (-l_gain) * (lip >> LOG_PS);
- lop += l_delbuf1[db_p1];
- lop += l_gain * s_delbuf2[db_p2];
- l_delbuf1[db_p1++] = lip;
- s_outbuf[i] = s_delbuf2[db_p2++] = (short) (lop >> LOG_PS);
- if(db_p1 >= l_delsamps) db_p1 = 0;
- if(db_p2 >= l_delsamps) db_p2 = 0;
- }
- //block done
- //return &soutbuf[0]; //if we return anything?
- }
|