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