5 Copyright (C) 2003 Angel Ortega <angel@triptico.com>
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 http://www.triptico.com
36 /* main output frequency */
47 /* digital synth generators */
50 int in_use
; /* 2 - playing, 1 - released, 0 - free */
52 int * lwave
; /* left channel wave */
53 int * rwave
; /* right channel wave */
54 int size
; /* size in samples */
55 double loop_start
; /* start of loop (-1, no loop) */
56 double loop_end
; /* end of loop */
57 double inc
; /* increment */
58 double lvol
; /* left volume */
59 double rvol
; /* right volume */
61 double cursor
; /* offset of next sample */
62 int sustain
; /* number of samples to play after release */
63 double dlvol
; /* delta of left volume (sustain) */
64 double drvol
; /* delta of right volume (sustain) */
67 #define NUM_GENERATORS 64
68 struct generator _generators
[NUM_GENERATORS
];
71 /* note frequencies */
73 double _middle_A_freq
=440.0;
76 double _note_freq
[NUM_NOTES
];
83 void build_note_freq(void)
87 for(n
=0;n
< NUM_NOTES
;n
++)
88 _note_freq
[n
]=(_middle_A_freq
/ 32.0) *
89 pow(2.0, (((double)n
- 9.0) / 12.0));
93 #define TIME2SAMPLES(s) ((s) * _frequency)
95 int * wave_resample(int * wave
, int freq
, int * size
)
103 ratio
=(double) freq
/ (double) _frequency
;
104 new_size
=(int)((double) (*size
) / ratio
);
106 new_wave
=(int *)malloc(new_size
* sizeof(int));
108 printf("wave_resample: ratio %f\n", (float)ratio
);
110 for(n
=i
=0;n
< new_size
;n
++,i
+=ratio
)
111 new_wave
[n
]=wave
[(int)i
];
115 /* free the old wave */
122 int load_sample(FILE * f
, int bits
)
134 s
|=(((unsigned char)fgetc(f
)) << 8);
141 void load_pcm_wave(FILE * f
, int * size
, int bits
, int channels
,
142 int frequency
, int ** lwave
, int ** rwave
)
148 ls
=(int *)malloc(*size
* sizeof(int));
151 rs
=(int *)malloc(*size
* sizeof(int));
155 for(n
=0;n
< *size
;n
++)
157 ls
[n
]=load_sample(f
, bits
);
160 rs
[n
]=load_sample(f
, bits
);
163 /* resample if needed */
164 if(frequency
!= _frequency
)
166 ls
=wave_resample(ls
, frequency
, size
);
169 rs
=wave_resample(rs
, frequency
, size
);
179 int load_wavfile(char * filename
, int * size
, int ** lwave
, int ** rwave
)
184 short int b_per_sec
,num_channels
,tag
;
185 char riffid
[5],waveid
[5],fmtid
[5],dataid
[5];
186 int wav_frequency
, wav_bits
;
190 if((f
=fopen(filename
,"rb"))==NULL
)
199 if(strcmp(waveid
,"WAVE"))
214 num_channels
=fget16(f
);
215 wav_frequency
=fget32(f
);
218 wav_bits
=fget16(f
) / num_channels
;
221 fread(dummydata
,1,(size_t)flen
-14,f
);
226 if(wav_bits
==16) (*size
)/=2;
227 if(num_channels
==2) (*size
)/=2;
229 load_pcm_wave(f
, size
, wav_bits
, num_channels
,
230 wav_frequency
, &ls
, &rs
);
241 void generator_startup(void)
243 memset(_generators
, '\0', sizeof(_generators
));
249 int generator_play(struct generator
* g
, int * lwave
, int * rwave
,
250 int size
, double inc
, int loop_start
, int loop_end
,
251 double lvol
, double rvol
, int sustain
)
253 if(g
->in_use
) return(0);
259 g
->loop_start
=(double) loop_start
;
260 g
->loop_end
=(double) loop_end
;
272 int generator_release(struct generator
* g
)
274 if(g
->in_use
!= 2) return(0);
276 /* if no sustain, generator can be immediately reused */
283 /* generator is released */
286 /* calculates delta volume values */
287 g
->dlvol
=g
->lvol
/ (double) g
->sustain
;
288 g
->drvol
=g
->rvol
/ (double) g
->sustain
;
290 /* put generator in auto-stop */
291 /* g->loop_start=-1; */
292 g
->loop_end
=(double) g
->size
;
298 void machine(struct generator
* g
, int * left
, int * right
)
302 /* return if generator is not active */
303 if(! g
->in_use
) return;
306 l
=g
->lwave
[(int)g
->cursor
];
307 r
=g
->rwave
[(int)g
->cursor
];
309 /* increment pointer */
312 /* test boundaries */
313 if(g
->cursor
> g
->loop_end
)
316 if(g
->loop_start
== -1)
319 g
->cursor
=g
->loop_start
;
322 l
=(int)((double)l
* g
->lvol
);
323 r
=(int)((double)r
* g
->rvol
);
325 if(g
->in_use
== 1 && g
->sustain
!= -1)
331 if(--g
->sustain
== 0)
340 void sample_trim(int * left
, int * right
)
342 if(*left
< -32768) *left
=-32768;
343 if(*left
> 32767) *left
=32767;
344 if(*right
< -32768) *right
=-32768;
345 if(*right
> 32767) *right
=32767;
359 load_wavfile("samples/amen1.wav", &size
, &ls
, &rs
);
361 generator_play(&_generators
[0], ls
, rs
, size
, 1, 0, size
, 0.2, 1, 4410);
363 load_wavfile("samples/01c1.wav", &size
, &ls
, &rs
);
364 generator_play(&_generators
[1], ls
, rs
, size
,
365 _note_freq
[24] / _note_freq
[36], 0, size
, 1, 1, 44100 / 3);
367 load_wavfile("samples/05c3.wav", &size
, &ls
, &rs
);
369 generator_play(&_generators
[2], ls
, rs
, size
,
370 _note_freq
[36] / _note_freq
[36], 0, size
, 0.5, 0.5, 0);
372 generator_play(&_generators
[3], ls
, rs
, size
,
373 _note_freq
[39] / _note_freq
[36], 0, size
, 0.5, 0.5, 0);
375 generator_play(&_generators
[4], ls
, rs
, size
,
376 _note_freq
[43] / _note_freq
[36], 0, size
, 0.5, 0.5, 0);
378 load_wavfile("samples/as-al017.wav", &size
, &ls
, &rs
);
379 generator_play(&_generators
[5], ls
, rs
, size
, 1, 0, size
, 2, 2, 0);
382 f=popen("sox -V -t raw -s -r 44100 -c 2 -w - qq.wav","w");
385 if(output_open("wav", "qq.wav") < 0)
387 printf("Error: can't init driver\n");
391 for(n
=TIME2SAMPLES(15);n
> 0;n
--)
397 for(m
=0;m
< NUM_GENERATORS
;m
++)
398 machine(&_generators
[m
], &l
, &r
);
404 if(n
< TIME2SAMPLES(14))
405 generator_release(&_generators
[1]);