More work on loading and playing midi files.
[orgux.git] / precompute.c
blob1e21d3c330faede7fa39afce1393bd6fa21a12a6
1 /*
2 orgux - a just-for-fun real time synth
3 Copyright (C) 2009 Evan Rinehart
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 /* precompute waveforms */
22 #include <stdio.h>
23 #include <math.h>
24 #include <stdlib.h>
25 #include "constants.h"
27 extern float square_wave[WAVEFORM_LENGTH];
28 extern float saw_wave[WAVEFORM_LENGTH];
29 extern float triangle_wave[WAVEFORM_LENGTH];
31 extern const unsigned char instr_config[128][16];
33 extern float waveform[128][WAVEFORM_LENGTH];
34 extern float waveform_M[128][WAVEFORM_LENGTH];
35 extern float waveform_Z[128][WAVEFORM_LENGTH];
37 extern float samples[SAMPLE_COUNT][SAMPLE_LENGTH];
38 extern int sample_len[SAMPLE_COUNT];
39 extern float antipop[ANTIPOP_LENGTH];
41 float linterp(float x, int k, float wave[]){
43 float X = x*k;
44 float Xw = X - WAVEFORM_LENGTH*floor(X/WAVEFORM_LENGTH);
45 int X0 = (int)floor(Xw);
46 int X1 = X0+1;
47 if(X1 == WAVEFORM_LENGTH) X1 = 0;
49 float y1 = wave[X1];
50 float y0 = wave[X0];
51 float m = (y1-y0)/(X1-X0);
53 return m*(Xw-X0)+y0;
56 void precompute(int sample_rate){
58 float dt = 1.0/sample_rate;
60 printf("generating band limited bases... ");
62 for(int i=0; i<WAVEFORM_LENGTH; i++){
63 square_wave[i] = 0;
64 triangle_wave[i] = 0;
65 saw_wave[i] = 0;
66 for(int j=0; j<7; j++){
67 square_wave[i] += (4/PI)*sin(i*(2*j+1)*PI2/WAVEFORM_LENGTH)/(2*j+1);
68 triangle_wave[i] += (8/(PI*PI))*(j&1?1:-1)*sin(i*(2*j+1)*PI2/WAVEFORM_LENGTH)/((2*j+1)*(2*j+1));
69 saw_wave[i] += (2/PI)*sin(i*(j+1)*PI2/WAVEFORM_LENGTH)/(j+1);
74 //float maxf[3] = {0,0,0};
75 //for(int i=0; i<WAVEFORM_LENGTH; i++){
76 // if(maxf[0] < square_wave[i]) maxf[0] = square_wave[i];
77 // if(maxf[1] < triangle_wave[i]) maxf[1] = triangle_wave[i];
78 // if(maxf[2] < saw_wave[i]) maxf[2] = saw_wave[i];
79 //}
81 for(int i=0; i<WAVEFORM_LENGTH; i++){
82 square_wave[i] /= 2;
83 triangle_wave[i] /= 1;
84 saw_wave[i] /= 1;
87 //printf("\nsquare max = %f\n",maxf[0]);
88 //printf("triangle max = %f\n",maxf[1]);
89 //printf("saw max = %f\n\n",maxf[2]);
92 printf("OK\n");
94 /* setup wave tables */
96 printf("generating instruments... \n");
98 printf(" harmonic 0 1 2 3 4 5 6 7 |basis FM FM_freq LP HP\n");
99 for(int i=0; i<128; i++){
101 int max = 0;
102 float N = 0;
104 printf("instr[%3d] = {",i);
106 for(int j=0; j<HARMONIC_COUNT; j++){
107 printf("%3d ",instr_config[i][j]);
108 if(instr_config[i][j] > max){ max = instr_config[i][j]; }
111 printf("|");
113 switch(instr_config[i][BASE_CONFIG]){
114 case SINE_BASE: printf("SINE "); break;
115 case SQUARE_BASE: printf("PULSE "); break;
116 case SAW_BASE: printf("SAW "); break;
117 case TRIANGLE_BASE: printf("TRI "); break;
118 case NOISE_BASE: printf("NOISE "); break;
119 default: printf("%5d ",instr_config[i][BASE_CONFIG]); break;
122 for(int j=0; j<HARMONIC_COUNT; j++){
123 if(instr_config[i][j]==0) continue;
124 float M = ((float)instr_config[i][j])/max;
125 M = M*M;
126 N += M;
128 switch(instr_config[i][BASE_CONFIG]){
129 case SINE_BASE:
130 for(int k=0; k<WAVEFORM_LENGTH; k++){
131 waveform[i][k]+=M*sin(k*(j+1)*PI2/WAVEFORM_LENGTH);
133 break;
134 case SQUARE_BASE:
135 for(int k=0; k<WAVEFORM_LENGTH; k++){
136 waveform[i][k]+=M*linterp(k,j+1,square_wave);;
138 break;
139 case SAW_BASE:
140 for(int k=0; k<WAVEFORM_LENGTH; k++){
141 waveform[i][k]+=M*linterp(k,j+1,saw_wave);;
143 break;
144 case TRIANGLE_BASE:
145 for(int k=0; k<WAVEFORM_LENGTH; k++){
146 waveform[i][k]+=M*linterp(k,j+1,triangle_wave);
148 break;
153 if(N>0){
154 for(int j=0; j<WAVEFORM_LENGTH; j++){
155 waveform[i][j] /= N*10;
160 for(int j=0; j<WAVEFORM_LENGTH; j++){
161 waveform[i][j] = 0.0f;
162 N = 0;
163 for(int k=0; k<HARMONIC_COUNT; k++){
164 float M = ((float)instr_config[i][k])/max;
165 M = M*M;
166 N += M;
168 float y;
169 switch(instr_config[i][BASE_CONFIG]){
170 case SINE_BASE: y = sin(j*(k+1)*PI2/WAVEFORM_LENGTH); break;
171 //case SQUARE_BASE: y = ((2*j*(1<<k)/WAVEFORM_LENGTH)&1)?1:-1; break;
172 case SQUARE_BASE: y = linterp(j,k+1,square_wave); break;
173 case TRIANGLE_BASE: y = linterp(j,k+1,triangle_wave); break;
174 case SAW_BASE: y = linterp(j,k+1,saw_wave); break;
175 //case NOISE_BASE: y = RANDF()*2 - 1; break;
176 case NOISE_BASE: y = 0; break;
177 default: y = 0;//use previously defined waveform
180 waveform[i][j] += M*y;
182 if(N>0){ waveform[i][j] /= N*10; }
185 printf("\n");
189 printf("OK\n");
191 //precomputing linear interpolators
192 printf("precomputing linear interpolators...\n");
193 for(int j=0; j<128; j++){
194 for(int i=0; i<WAVEFORM_LENGTH; i++){
196 int X0 = i;
197 int X1 = i+1;
198 if(X1==WAVEFORM_LENGTH){X1 = 0;}
199 waveform_M[j][i] = waveform[j][X1] - waveform[j][X0];
200 waveform_Z[j][i] = waveform[j][X0] - i*waveform_M[j][i];
206 //generate antipop cosine
207 for(int i=0; i<ANTIPOP_LENGTH; i++){
208 antipop[i] = -cos(i*PI2/(2.0*ANTIPOP_LENGTH))/2.0+0.5;
212 //generate samples
214 float par[16][8] = {/**/
215 {50, 500, 0.5, 10000, 0, 0, 0, 0},
216 {200, 200, 0.5, 10000, 0, 0, 0, 0},
217 {100, 500, 0.5, 10000, 0, 0, 0, 0},
218 {100, 1000, 0.5, 10000, 0, 0, 0, 0},
220 {100, 500, 0.5, 3000, 0, 0, 0, 0},
221 {200, 500, 0.5, 3000, 0, 0, 0, 0},
222 {300, 500, 0.5, 3000, 0, 0, 0, 0},
223 {400, 500, 0.5, 3000, 0, 0, 0, 0},
225 {400, 200, 0.5, 3000, 0, 0, 0, 0},
226 {400, 100, 0.5, 3000, 0, 0, 0, 0},
227 {400, 50, 0.5, 3000, 0, 0, 0, 0},
228 {400, 20, 0.5, 3000, 0, 0, 0, 0},
230 {100, 500, 0.5, 10000, 0, 0, 0, 0},
231 {100, 500, 0.5, 10000, 0, 0, 0, 0},
232 {100, 500, 0.5, 10000, 0, 0, 0, 0},
233 {100, 500, 0.5, 10000, 0, 0, 0, 0}
236 double K = PI2 / sample_rate;
237 printf("generating samples... ");
238 for(int i=0; i<SAMPLE_LENGTH; i++){
239 for(int j=0; j<SAMPLE_COUNT; j++){
240 double F_i = par[j][0];
241 double F_r = par[j][1];
242 double A_i = par[j][2];
243 double A_r = par[j][3];
245 if(F_r < 1){F_r = 1;}
246 double f = F_i - i/F_r;
247 if(f < 0) f = 0;
249 if(A_r < 1){A_r = 1;}
250 double A = A_i - i/A_r;
251 if(A < 0) A = 0;
253 double E = 1;
254 if(i < 64){
255 E = -cos((i/64.0) * PI2 / 2)/2+0.5;
258 samples[j][i] = E*A*sin(i*f*K);
264 float y_l;
265 float y_h0=0;
266 float y_h1=0;
269 notes
271 cool hit
272 tau2 = 0.0001 / (1 + i/50.0)
273 alpha2 = tau2 / (tau2 + dt)
274 A = 0.2 - (i/10000.0)
282 for(int i=0; i<SAMPLE_LENGTH; i++){
284 float tau1 = (i/200.0)*0.0001;
285 float alpha1 = dt/(tau1+dt);
287 float tau2 = 0.0001 / (1 + i/50.0);
288 float alpha2 = tau2/(tau2+dt);
290 float y = RAND_SIGNAL();
292 //y = y_l0 + alpha1*(y - y_l0);
293 //y_l0 = y;
295 float temp = y;
296 y = alpha2*(y - y_h0 + y_h1);
297 y_h0 = temp;
298 y_h1 = y;
300 float A = 0.2 - (i/10000.0);
301 if(A<0) A = 0;
303 double E = 1;
304 if(i < 64){
305 E = -cos((i/64.0) * PI2 / 2)/2+0.5;
308 samples[15][i] = A*E*y;
312 for(int j=0; j<SAMPLE_COUNT; j++){
313 for(int i=0; i<SAMPLE_LENGTH; i++){
314 int I = SAMPLE_LENGTH-i-1;
315 if(fabs(samples[j][I]) != 0){
316 sample_len[j] = I;
317 break;
322 printf("OK\n");
324 printf("precompute OK\n");