1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <string.h>
5 #include "ctronome.h"
6 #include "routines.h"
7
8 dword bytes_read;
9
10 int dsp_device;
11
12 dword dsp_pattern_length;
13
14 /* the two wav files */
15 byte wav1[1000000];
16 byte wav2[1000000];
17
18 dword wav_bytes_to_read;
19
20 byte wav_header[100];
21
22 const char *wave1, *wave2;
23
24 FILE *wavfile, *program;
25
26 byte is_program;
27 dword bpm_base_length;
28
29 dword c1,c2,c3,c4,lo;
30
31 word wav_channels;
32 dword wav_samplerate;
33 word wav_bitspersample;
34 word wav2_channels;
35 dword wav2_samplerate;
36 word wav2_bitspersample;
37
38 int bpt_base_specified,bpm_base_specified;
39 int i1,i2,i3,i4,i5;
40 byte tmp[8219];
41
main(int argc,char * argv[])42 int main(int argc,char *argv[]){
43 parm_init(argc,argv);
44
45 /* create an endless/pcount times loop */
46 while(pcount > 0){
47 if (is_program){
48 next_program(program);
49 }
50
51 if (pcount > 0){
52 if (is_program) printf("count: %d, bpm: %d/%d, bpt: %d/%d\n",count,bpm[0],bpm[1],bpt[0],bpt[1]);
53
54 /* lets calculate the appropriate pattern length for our bpm and bpt */
55 bpm_base_length = dsp_speed * dsp_depth * dsp_channels * 60 / bpm[0];
56 dsp_pattern_length = bpm_base_length * bpm[1] / bpt[1];
57 /* if (debug){
58 printf("dsp_speed: >%d<, dsp_depth: >%d<, dsp_channels: >%d<, patt. length: >%d<\n",dsp_speed,dsp_depth,dsp_channels,
59 dsp_pattern_length);
60 } */
61
62 while(i3 = dsp_pattern_length % (dsp_depth * dsp_channels)){
63 dsp_pattern_length++;
64 }
65
66 for (c4 = 0;c4 < count;c4++){
67 dsp_write(dsp_device,wav1,dsp_pattern_length);
68 for (c3 = bpt[0];c3 > 1; c3--){
69 dsp_write(dsp_device,wav2,dsp_pattern_length);
70 }
71 }
72 if (!(is_program)) pcount -= pdecrease;
73 }
74 }
75 dsp_close;
76 return(0);
77 }
78
next_program(FILE * programfile)79 void next_program(FILE *programfile){
80 byte temp[8192];
81 dword lo1;
82 int lo2,lo3,lo4;
83 /* a normal line should be at least 5 characters long + newline */
84 lo2 = 0;
85 while (lo2 >= 0){
86 while ( (lo1 = getnextline(temp,programfile,8192)) < 6){
87 /* if 0 character has been read, seek to the beginning of the file */
88 if (lo1 < 1){
89 fseek(programfile,SEEK_SET,0);
90 pcount -= pdecrease;
91 if (pcount) printf("repeat\n");
92 }
93 }
94 lo2 = str_search(temp,hashmark);
95 }
96 count = atoi(temp);
97
98 lo2 = str_search(temp,space);
99 lo2++;
100 lo2 += str_search(&temp[lo2],space);
101 bpm_base_specified = bpt_base_specified = 0;
102
103 if (lo2) {
104 lo3 = str_search(&temp[++lo2],slash);
105 bpt[0] = atoi(&temp[lo2]);
106
107 if (lo3 >= 0){
108 bpt[1] = atoi(&temp[lo2] + ++lo3);
109 bpt_base_specified = 1;
110 }
111 }
112
113 lo2 = str_search(temp,space);
114 if (lo2) {
115 lo3 = str_search(&temp[++lo2],slash);
116 bpm[0] = atoi(&temp[lo2]);
117 if (debug) printf("debug: prg: bpm0: '%d', lo3: '%d'\n",bpm[0],lo3);
118 if (lo3 >= 0){
119 bpm[1] = atoi(&temp[lo2] + ++lo3);
120 bpm_base_specified = 1;
121 }
122 }
123
124 /* some parameter post-processing */
125 if (!(bpt_base_specified)){
126 if (bpm_base_specified){
127 bpt[1] = bpm[1];
128 } else {
129 bpt[1] = default_base_note;
130 }
131 }
132
133 if (!(bpm_base_specified)){
134 if (bpt_base_specified){
135 bpm[1] = bpt[1];
136 } else {
137 bpm[1] = default_base_note;
138 }
139 }
140
141 if (bpt[0] < 1) bpt[0] = 1; if (bpt[0] > 50) bpt[0] = 50;
142 if (bpt[1] < 1) bpt[1] = 1; if (bpt[1] > 50) bpt[1] = 50;
143
144 if (bpm[0] > 250) bpm[0] = 250; if (bpm[0] < 30) bpm[0] = 30;
145 if (bpm[1] > 20) bpm[1] = 20; if (bpm[1] < 1) bpm[1] = 1;
146 }
147
148
parm_init(int argc,char * argv[])149 void parm_init(int argc,char *argv[]){
150
151 /* first, get the parameters */
152 int i;
153 dword bytes_read;
154
155 debug = 0;
156 bpm_base_specified = bpt_base_specified = 0;
157
158 for (i = 1; i < argc; i++){
159 /* debug */
160 if ((strcmp(argv[i], "-debug") == 0) ||
161 (strcmp(argv[i], "--debug") == 0)) {
162 printf("debug mode\n");
163 debug = 1;
164 }
165 }
166
167 for (i = 1; i < argc; i++){
168 /* help */
169 if ((strcmp(argv[i], "-h") == 0) ||
170 (strcmp(argv[i], "--h") == 0) ||
171 (strcmp(argv[i], "-help") == 0) ||
172 (strcmp(argv[i], "--help") == 0)) {
173 printf(HELP);
174 exit(0);
175 }
176
177 /* version and credits */
178 if ((strcmp(argv[i], "-v") == 0) ||
179 (strcmp(argv[i], "--v") == 0) ||
180 (strcmp(argv[i], "-version") == 0) ||
181 (strcmp(argv[i], "--version") == 0)) {
182 printf("%s v%s\n%s",MYNAME,VERSION,CREDITS);
183 }
184
185 /* wav1 */
186 if ((strcmp(argv[i], "-w1") == 0) && (i + 1 < argc)){
187 metronomewav1 = argv[++i];
188 if (debug) printf("debug: wav1: '%s'\n",metronomewav1);
189 }
190
191 /* wav2 */
192 if ((strcmp(argv[i], "-w2") == 0) && (i + 1 < argc)){
193 metronomewav2 = argv[++i];
194 if (debug) printf("debug: wav2: '%s'\n",metronomewav2);
195 }
196
197 /* dsp device */
198 if ((strcmp(argv[i], "-d") == 0) && (i + 1 < argc)){
199 dspdev = argv[++i];
200 if (debug) printf("debug: dsp: '%s'\n",dspdev);
201 }
202
203 /* bpt */
204 if ( (strcmp(argv[i], "-t") == 0) && (i + 1 < argc)){
205 i1 = str_search(argv[++i],slash);
206 bpt[0] = atoi(argv[i]);
207 if (i1 >= 0){
208 bpt[1] = atoi(argv[i] + ++i1);
209 bpt_base_specified = 1;
210 }
211 if (debug) printf("debug: bpt: '%d'/'%d'\n",bpt[0],bpt[1]);
212 }
213
214 /* bpm */
215 if ((strcmp(argv[i], "-b") == 0) && (i + 1 < argc)){
216 i2 = str_search(argv[++i],slash);
217 bpm[0] = atoi(argv[i]);
218 if (i2 >= 0){
219 bpm[1] = atoi(argv[i] + ++i2);
220 bpm_base_specified = 1;
221 }
222 if (debug) printf("debug: bpm: '%d'/'%d'\n",bpm[0],bpm[1]);
223 }
224
225 /* pcount */
226 if ((strcmp(argv[i], "-c") == 0) && (i + 1 < argc)){
227 pcount = atoi(argv[++i]);
228 pdecrease = 1;
229 if (debug) printf("debug: count: '%d'\n",pcount);
230 }
231
232 /* program file */
233 if ((strcmp(argv[i], "-p") == 0) && (i + 1 < argc)){
234 programfile = argv[++i];
235 is_program = 1;
236 if (debug) printf("debug: program: '%s'\n",programfile);
237 }
238 }
239
240 /* some parameter post-processing */
241 if (!(bpt_base_specified)){
242 if (bpm_base_specified){
243 bpt[1] = bpm[1];
244 } else {
245 bpt[1] = default_base_note;
246 }
247 }
248
249 if (!(bpm_base_specified)){
250 if (bpt_base_specified){
251 bpm[1] = bpt[1];
252 } else {
253 bpm[1] = default_base_note;
254 }
255 }
256
257 if (bpm[0] > 250) bpm[0] = 250; if (bpm[0] < 30) bpm[0] = 30;
258 if (bpm[1] > 20) bpm[1] = 20; if (bpm[1] < 1) bpm[1] = 1;
259
260 if (bpt[0] < 1) bpt[0] = 1; if (bpt[0] > 50) bpt[0] = 50;
261 if (bpt[1] < 1) bpt[1] = 1; if (bpt[1] > 50) bpt[1] = 50;
262
263 /* cleanup buffers */
264 for (c1 = 0; c1 < 1000000; c1++){
265 wav1[c1] = 0;
266 wav2[c1] = 0;
267 }
268
269 /* open wav file 1 */
270 wavfile = openread(metronomewav1);
271
272 /* read the header first */
273 bytes_read = fread(&wav_header,1,44,wavfile);
274 if (bytes_read < 44){
275 printf("wav file %s too short\n",metronomewav1);
276 exit(1);
277 }
278
279 wav_channels = * (word *) &wav_header[22];
280 wav_samplerate = * (dword *) &wav_header[24];
281 wav_bitspersample = * (word *) &wav_header[34];
282
283 if (debug)
284 printf("debug: wav channels: '%d', samplerate: '%d', bits per sample: '%d'\n",wav_channels,wav_samplerate,wav_bitspersample);
285
286 if (debug) printf("debug: calling dsp_init(%s)\n",dspdev);
287
288 dsp_device = dsp_init(dspdev,wav_bitspersample,wav_channels,wav_samplerate);
289
290 if (debug)
291 printf("debug: dsp channels: '%d', samplerate: '%d', bits per sample: '%d'\n",dsp_channels,dsp_speed,dsp_format);
292
293 dsp_depth = dsp_format / 8;
294
295 wav_bytes_to_read = dsp_depth * dsp_channels * dsp_speed / 2;
296 if (debug) printf("debug: maximum wav bytes to read: '%d'\n",wav_bytes_to_read);
297
298 bytes_read = fread(&wav1,1,wav_bytes_to_read,wavfile);
299 if (debug) printf("debug: wav1 bytes read: '%d'\n",bytes_read);
300 if (bytes_read < 10){
301 printf("wav file %s too short\n",metronomewav1);
302 exit(1);
303 }
304
305 fclose(wavfile);
306
307 /* open wav file 2 */
308 wavfile = openread(metronomewav2);
309
310 /* read the header first */
311 bytes_read = fread(&wav_header,1,44,wavfile);
312 if (bytes_read < 44){
313 printf("wav file %s too short\n",metronomewav2);
314 exit(1);
315 }
316
317 wav2_channels = * (word *) &wav_header[22];
318 wav2_samplerate = * (dword *) &wav_header[24];
319 wav2_bitspersample = * (word *) &wav_header[34];
320
321 if (debug)
322 printf("debug: wav2 channels: '%d', samplerate: '%d', bits per sample: '%d'\n",wav2_channels,wav2_samplerate,wav2_bitspersample);
323
324 if ((wav_channels != wav2_channels) ||
325 (wav_bitspersample != wav2_bitspersample)){
326 printf("the two WAV files must have the same number of channels and same samplerate\n");
327 exit(1);
328 }
329
330 if ((debug) && (wav_samplerate != wav2_samplerate)){
331 printf("debug: wav1 and wav2 samplerate differs, may sound funny\n");
332 }
333
334 /* skip the wav header */
335 /* fseek(wavfile,44,SEEK_SET); */
336
337 bytes_read = fread(&wav2,1,wav_bytes_to_read,wavfile);
338 if (debug) printf("debug: wav2 bytes read: '%d'\n",bytes_read);
339 if (bytes_read < 10){
340 printf("wav file %s too short\n",metronomewav2);
341 exit(1);
342 }
343 fclose(wavfile);
344
345 /* open wav file 2 */
346 if (is_program) program = openread(programfile);
347
348 printf ("bpm: %d/%d, bpt: %d/%d",bpm[0],bpm[1],bpt[0],bpt[1]);
349 if (pdecrease) printf ("repeat count: %d",pcount);
350 if (is_program) printf ("\nprogram file: %s",programfile);
351 printf ("\n");
352 }
353
354