2 model.c -- program to help test DSP filter and rate-conversion code.
4 Copyright (C) 1999 Stanley J. Brooks <stabro@megsinet.net>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 // for open,read,write:
24 #include <sys/types.h>
37 # define MAXSAMPL 0x7fff
38 # define MINSAMPL -0x8000
41 # define MAXSAMPL 0x7fffff
42 # define MINSAMPL -0x800000
49 double v
; /* volume */
51 } Env
= {0,0,0,0.5,1.0};
53 static void Usage(void)__attribute__((noreturn
));
55 static void Usage(void)
57 fprintf(stderr
,"Usage: ./model rate0,rate1 [-l len] [-f freq] <in-file>\n"); exit(-1);
60 static int ReadN(int fd
, SAMPL
*v
, int n
)
65 r
= read(fd
, (char*)(v
), n
*sizeof(SAMPL
));
66 }while(r
==-1 && errno
==EINTR
);
67 if (r
==-1 || r
%sizeof(SAMPL
)) {
68 perror("Error reading input"); exit(-1);
70 return r
/sizeof(SAMPL
);
73 #define BSIZ 400000/*0x10000*/
75 static double bestfit(double sx
, double sy
,
76 double h11
, double h12
, double h22
,
77 double *cx
, double *cy
)
83 a
= h12
/h22
; /* u[] = x[] - a*y[] is orthogonal to y[] */
84 *cy
= sy
/h22
; /* *cy*y[] is projection of s[] onto y[] */
86 /* <s,x-ay> = sx -a*sy */
87 su
= sx
- a
*sy
; /* su is iprod of s[] and u[] */
88 /* <u,u> = <x-ay,x-ay> = h11 - 2a*h11 + a*a*h22 */
89 uu
= h11
- 2*a
*h12
+ a
*a
*h22
;
92 cu
= su
/uu
; /* s[] = *cy * y[] + cu * u[] is orthogonal decomposition */
100 static double eCenter(const SAMPL
*ibuff
, int len
)
106 for (n
=0; n
<len
; n
++) {
116 fprintf(stderr
,"eCenter %.2f, STD %.2f\n",v1
,sqrt(v2
));
121 bigcalc(double Factor
, double Freq1
, const SAMPL
*ibuff
, int len
)
128 long double h11
,h12
,h22
;
129 long double sx
,sy
,ss
;
134 inline void a_init(double frq
)
142 inline double a(double k
, double L
)
146 u
= k
/l
- 1; /* in (-1,+1) */
147 a
= 0.5*(1 + cos(M_PI
* u
));
151 inline void a_post(int k
)
157 /* update (x,y) for next tic */
158 if ((k
&0x0f)==0x0f) { /* norm correction each 16 samples */
159 x1
= 1/sqrt(x
*x
+y
*y
);
165 c
= eCenter(ibuff
,len
);
166 Len1
= Env
.c
*Factor
*0.6; /* 60% of original const-amplitude area */
167 c
+= Env
.c
*Factor
*0.15; /* beginning after 30% */
176 fprintf(stderr
,"del %.3f\n", del
);
182 for(n
=0; n
<=k1
; n
++) {
186 s
= ip
[n
]; /* sigval at n */
188 f
= 1; //a(n+del,Len1);
199 //fprintf(stderr,"h12 %.10f\n", (double)h12/(sqrt(h11)*sqrt(h22)));
202 s2
= bestfit(sx
,sy
,h11
,h12
,h22
,&cx
,&cy
)/(k1
+1);
203 cn
= sqrt(cx
*cx
+cy
*cy
);
204 fprintf(stderr
,"amp %.1f, cx %.10f, cy %.10f\n", cn
, cx
/cn
, cy
/cn
);
206 fprintf(stderr
,"[%.1f,%.1f] s2max %.2f, v2max %.2f, rmserr %.2f\n",
207 c
/Factor
, c
, sqrt(s2
), sqrt(v2
), (s2
<=v2
)? sqrt(v2
-s2
):-sqrt(s2
-v2
));
211 int main(int argct
, char **argv
)
218 double Freq0
=0, Freq1
; /* of nyquist */
222 /* Parse the options */
223 while ((optc
= getopt(argct
, argv
, "d:e:f:h")) != -1) {
227 Env
.d
= strtod(optarg
,&p
);
228 if (p
==optarg
|| *p
) {
229 fprintf(stderr
,"option -%c expects float value (%s)\n", optc
, optarg
);
234 Freq0
= strtod(optarg
,&p
);
235 if (p
==optarg
|| *p
) {
236 fprintf(stderr
,"option -%c expects float value (%s)\n", optc
, optarg
);
242 Env
.c
= strtol(p
,&p
,10);
244 Env
.r
= Env
.f
= Env
.c
;
245 Env
.c
= strtol(p
,&p
,10);
248 Env
.f
= strtol(p
,&p
,10);
250 if (*p
|| Env
.c
<=0 || Env
.r
<0 || Env
.f
<0) {
251 fprintf(stderr
,"option -%c not valid (%s)\n", optc
, optarg
);
261 //fprintf(stderr,"optind=%d argct=%d\n",optind,argct);
263 if (optind
!= argct
-2) Usage();
268 rate0
= rate1
= strtol(p0
,&p
,10);
271 fprintf(stderr
,"Invalid rate parameter (%s)\n", p0
);
275 rate1
= strtol(p0
,&p
,10);
277 fprintf(stderr
,"Invalid 2nd rate parameter (%s)\n", p0
);
281 if (rate0
<=0 || rate1
<=0) {
282 fprintf(stderr
,"Invalid rate parameter (%s)\n", argv
[optind
]);
288 Factor
= (double)rate1
/ (double)rate0
;
289 Freq1
= Freq0
/Factor
;
291 //if (optind != argct-1) Usage();
294 fnam1
=argv
[optind
++];
295 fd1
=open(fnam1
,O_RDONLY
);
297 fprintf(stderr
,"Open: %s %s\n",fnam1
,strerror(errno
)); return(1);
300 //fprintf(stderr, "Files: %s %s\n",fnam1,fnam2);
302 ibuff
=(SAMPL
*)malloc(BSIZ
*sizeof(SAMPL
));
306 for (n
=0; n
<BSIZ
; n
+=r
) {
307 r
= ReadN(fd1
,ibuff
+n
,BSIZ
-n
);
312 fprintf(stderr
,"Read %d input samples\n",len
);
314 bigcalc(Factor
, Freq1
, ibuff
, len
);