Mercurial > hg > aim92
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 |