annotate tools/conv.c @ 0:5242703e91d3 tip

Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author tomwalters
date Fri, 20 May 2011 15:19:45 +0100
parents
children
rev   line source
tomwalters@0 1 /*
tomwalters@0 2 conv.c Convolution. [NR: 407-413].
tomwalters@0 3 ------
tomwalters@0 4
tomwalters@0 5 Usage: conv [options] signal_file response_file
tomwalters@0 6
tomwalters@0 7 The response of a linear filter to an arbitiary input signal is the
tomwalters@0 8 convolution of the signal with the filter's impulse response.
tomwalters@0 9 The `response_file' contains the impulse response which characterises the
tomwalters@0 10 filter, and the result of the convolution operation is the response of
tomwalters@0 11 that filter to the signal contained in the `signal_file'.
tomwalters@0 12
tomwalters@0 13 The program uses the FFT to transform both input files, and then obtains
tomwalters@0 14 the convolution by multiplying in the frequency domain, and inverse
tomwalters@0 15 transforming the result.
tomwalters@0 16
tomwalters@0 17 Eg:
tomwalters@0 18
tomwalters@0 19 ptrain > foo1 -signal
tomwalters@0 20 gauss -b5 | op type=float mult=500 > foo3 -response
tomwalters@0 21 conv factor=.0005 foo1 foo3 | x11plot
tomwalters@0 22
tomwalters@0 23 Deconv doesn't seem to work !
tomwalters@0 24 */
tomwalters@0 25
tomwalters@0 26
tomwalters@0 27 #include <stdio.h>
tomwalters@0 28 #include <math.h>
tomwalters@0 29 #include <sys/types.h>
tomwalters@0 30 #include <sys/dir.h>
tomwalters@0 31 #include <sys/stat.h>
tomwalters@0 32 #include "options.h"
tomwalters@0 33 #include "units.h"
tomwalters@0 34 #include "strmatch.h"
tomwalters@0 35 #include "sigproc.h"
tomwalters@0 36
tomwalters@0 37 char applic[] = "Convolution. \n i/p and o/p signal in binary shorts, impulse response file in floats." ;
tomwalters@0 38 char usage[] = "conv [options] signal_file response_file" ;
tomwalters@0 39
tomwalters@0 40 static char *helpstr, *debugstr, *sampstr, *lenstr, *domstr, *scalestr ;
tomwalters@0 41
tomwalters@0 42 static Options option[] = {
tomwalters@0 43 { "help" , "off" , &helpstr , "help" , DEBUG },
tomwalters@0 44 { "debug" , "off" , &debugstr , "debugging switch" , DEBUG },
tomwalters@0 45 { "samplerate", "20kHz" , &sampstr , "samplerate " , VAL },
tomwalters@0 46 { "length" , "max" , &lenstr , "Size of input." , VAL },
tomwalters@0 47 { "domain" , "time" , &domstr , "Convolve in time or frequency domain" , VAL },
tomwalters@0 48 { "scale" , "1.0" , &scalestr , "scale factor for output" , VAL },
tomwalters@0 49 ( char * ) 0 } ;
tomwalters@0 50
tomwalters@0 51
tomwalters@0 52 int samplerate ;
tomwalters@0 53 float scale ;
tomwalters@0 54
tomwalters@0 55 short *signal ;
tomwalters@0 56 float *response ;
tomwalters@0 57 float *out ;
tomwalters@0 58
tomwalters@0 59 main (argc, argv)
tomwalters@0 60 int argc;
tomwalters@0 61 char **argv;
tomwalters@0 62 {
tomwalters@0 63 FILE *fp1, *fp2 ;
tomwalters@0 64 struct stat stbuf ;
tomwalters@0 65 int i, n, m ;
tomwalters@0 66 float f ;
tomwalters@0 67
tomwalters@0 68 if ( getopts( option, argc, argv ) != 2 || !isoff( helpstr ) )
tomwalters@0 69 helpopts3( helpstr, argv[0], applic, usage, option ) ;
tomwalters@0 70
tomwalters@0 71 samplerate = to_Hz( sampstr ) ;
tomwalters@0 72 scale = atof( scalestr ) ;
tomwalters@0 73
tomwalters@0 74 if ( ( fp1 = fopen( argv[argc-2], "r" ) ) == (FILE *)0 ) {
tomwalters@0 75 fprintf( stderr,"%s: can't open %s\n", argv[0], argv[argc-2] ) ;
tomwalters@0 76 exit( 1 ) ;
tomwalters@0 77 }
tomwalters@0 78 stat( argv[argc-2], &stbuf ) ;
tomwalters@0 79 if ( ismax( lenstr ) )
tomwalters@0 80 n = stbuf.st_size / sizeof( short ) ; /* size of signal file */
tomwalters@0 81 else if ( ( n = to_p( lenstr, samplerate ) ) > stbuf.st_size / sizeof( short ) ) {
tomwalters@0 82 fprintf( stderr,"conv: insufficient signal\n");
tomwalters@0 83 exit( 1 ) ;
tomwalters@0 84 }
tomwalters@0 85
tomwalters@0 86
tomwalters@0 87 if ( ( fp2 = fopen( argv[argc-1], "r" ) ) == (FILE *)0 ) {
tomwalters@0 88 fprintf( stderr,"%s: can't open %s\n", argv[0], argv[argc-1] ) ;
tomwalters@0 89 exit( 1 ) ;
tomwalters@0 90 }
tomwalters@0 91 stat( argv[argc-1], &stbuf ) ;
tomwalters@0 92 m = stbuf.st_size / sizeof( float ) ; /* size of response file */
tomwalters@0 93
tomwalters@0 94 if ( m > n ) { /* size of response file must <= signal file */
tomwalters@0 95 fprintf( stderr,"conv: size of response file must be <= size of signal file\n" ) ;
tomwalters@0 96 exit( 1 ) ;
tomwalters@0 97 }
tomwalters@0 98
tomwalters@0 99 signal = (short *)malloc( n * sizeof(short) ) ;
tomwalters@0 100 response = (float *)malloc( m * sizeof(float) ) ;
tomwalters@0 101 out = (float *)malloc( n * sizeof(float) ) ;
tomwalters@0 102
tomwalters@0 103 fread( signal, sizeof(short), n, fp1 ) ;
tomwalters@0 104 fread( response, sizeof(float), m, fp2 ) ;
tomwalters@0 105 fclose( fp1 ) ; fclose( fp2 ) ;
tomwalters@0 106
tomwalters@0 107
tomwalters@0 108 if ( iststr( domstr, "time" ) )
tomwalters@0 109 convolve_time( signal, n, response, m, out ) ;
tomwalters@0 110
tomwalters@0 111 else if ( iststr( domstr, "frequency" ) )
tomwalters@0 112 convolve_freq( signal, n, response, m, out ) ;
tomwalters@0 113
tomwalters@0 114 else {
tomwalters@0 115 fprintf( stderr,"conv: unknown domain [%s]\n", domstr ) ;
tomwalters@0 116 exit( 1 ) ;
tomwalters@0 117 }
tomwalters@0 118
tomwalters@0 119
tomwalters@0 120 if ( ( f = ftos( out, signal, n, scale ) ) < 1. )
tomwalters@0 121 fprintf( stderr,"Warning: 16-bit overflow during convolution. Try scale factor < %f\n", f ) ;
tomwalters@0 122
tomwalters@0 123 fwrite( signal, sizeof(short), n, stdout ) ;
tomwalters@0 124
tomwalters@0 125 }
tomwalters@0 126
tomwalters@0 127
tomwalters@0 128