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