1 /*---------------------------------------------------------------------------*\
2 
3   FILE........: tinterp.c
4   AUTHOR......: David Rowe
5   DATE CREATED: 22/8/10
6 
7   Tests interpolation functions.
8 
9 \*---------------------------------------------------------------------------*/
10 
11 /*
12   Copyright (C) 2010 David Rowe
13 
14   All rights reserved.
15 
16   This program is free software; you can redistribute it and/or modify
17   it under the terms of the GNU Lesser General Public License version 2.1, as
18   published by the Free Software Foundation.  This program is
19   distributed in the hope that it will be useful, but WITHOUT ANY
20   WARRANTY; without even the implied warranty of MERCHANTABILITY or
21   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
22   License for more details.
23 
24   You should have received a copy of the GNU Lesser General Public License
25   along with this program; if not, see <http://www.gnu.org/licenses/>.
26 */
27 
28 #include <assert.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <math.h>
33 #include <ctype.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <unistd.h>
37 
38 #include "defines.h"
39 #include "sine.h"
40 #include "interp.h"
41 
make_amp(MODEL * model,float f0,float cdB,float mdBHz)42 void make_amp(MODEL *model, float f0, float cdB, float mdBHz)
43 {
44     int   i;
45     float mdBrad = mdBHz*FS/TWO_PI;
46 
47     model->Wo = f0*TWO_PI/FS;
48     model->L  = PI/model->Wo;
49     for(i=0; i<=model->L; i++)
50 	model->A[i] = pow(10.0,(cdB + (float)i*model->Wo*mdBrad)/20.0);
51     model->voiced = 1;
52 }
53 
write_amp(char file[],MODEL * model)54 void write_amp(char file[], MODEL *model)
55 {
56     FILE  *f;
57     int    i;
58 
59     f = fopen(file,"wt");
60     for(i=1; i<=model->L; i++)
61 	fprintf(f, "%f\t%f\n", model->Wo*i, model->A[i]);
62     fclose(f);
63 }
64 
get_next_float(const char * s,float * num)65 const char *get_next_float(const char *s, float *num)
66 {
67     const char *p = s;
68     char  tmp[MAX_STR];
69 
70     while(*p && !isspace(*p))
71 	p++;
72     assert((p-s) < (int)(sizeof(tmp)-1));
73     memcpy(tmp, s, p-s);
74     tmp[p-s] = 0;
75     *num = atof(tmp);
76 
77     return p+1;
78 }
79 
get_next_int(const char * s,int * num)80 const char *get_next_int(const char *s, int *num)
81 {
82     const char *p = s;
83     char  tmp[MAX_STR];
84 
85     while(*p && !isspace(*p))
86 	p++;
87     assert((p-s) < (int)(sizeof(tmp)-1));
88     memcpy(tmp, s, p-s);
89     tmp[p-s] = 0;
90     *num = atoi(tmp);
91 
92     return p+1;
93 }
94 
load_amp(MODEL * model,const char * file,int frame)95 void load_amp(MODEL *model, const char * file, int frame)
96 {
97     FILE *f;
98     int   i;
99     char  s[1024];
100     const char *ps;
101 
102     f = fopen(file,"rt");
103     assert(f);
104 
105     for(i=0; i<frame; i++)
106 	ps = fgets(s, 1023, f);
107 
108     /// can frame ever be 0? what if fgets fails?
109     ps = s;
110     ps = get_next_float(ps, &model->Wo);
111     ps = get_next_int(ps, &model->L);
112     for(i=1; i<=model->L; i++)
113 	ps = get_next_float(ps, &model->A[i]);
114 
115     fclose(f);
116 }
117 
load_or_make_amp(MODEL * model,const char * filename,int frame,float f0,float cdB,float mdBHz)118 void load_or_make_amp(MODEL *model,
119                       const char * filename, int frame,
120                       float f0, float cdB, float mdBHz)
121 {
122     struct stat buf;
123     int rc = stat(filename, &buf);
124     if (rc || !S_ISREG(buf.st_mode) || ((buf.st_mode & S_IRUSR) != S_IRUSR))
125     {
126         make_amp(model, f0, cdB, mdBHz);
127     }
128     else
129     {
130         load_amp(model, filename, frame);
131     }
132 }
main()133 int main() {
134     MODEL  prev, next, interp;
135 
136     load_or_make_amp(&prev,
137                      "../src/hts1a_model.txt", 32,
138                      50.0, 60.0, 6E-3);
139     load_or_make_amp(&next,
140                      "../src/hts1a_model.txt", 34,
141                      50.0, 40.0, 6E-3);
142 
143     interp.voiced = 1;
144     interpolate(&interp, &prev, &next);
145 
146     write_amp("tinterp_prev.txt", &prev);
147     write_amp("tinterp_interp.txt", &interp);
148     write_amp("tinterp_next.txt", &next);
149 
150     return 0;
151 }
152