1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "general.h"
6 #include "fileoutput.h"
7
8 #ifdef DSP
9 #ifndef WINDOWS
10 #include <unistd.h>
11 #include <fcntl.h>
12 #include <sys/ioctl.h>
13 #include <sys/soundcard.h>
14 int audio_fd;
15 #else
16 #include <windows.h>
17 #include <mmsystem.h>
18 unsigned long result;
19 HWAVEOUT outHandle;
20 WAVEFORMATEX waveFormat;
21 #endif
22 #endif
23
24 #define SAMPLES 700
25 #define CUTOFF 7
26 #define WAVES 2
27 #define ZEROS 1000
28
29 /*
30
31 Ringtonetools - Copyright 2001-2005 Michael Kohn (mike@mikekohn.net)
32 This falls under the Kohnian license. Please read
33 it at http://ringtonetools.mikekohn.net/
34
35 This program is NOT opensourced. You may not use any part
36 of this program for your own software.
37
38 */
39
40 int get_duration(float duration);
41
42 /* WAV */
43
write_wav_header(FILE * out,struct note_t * note)44 void write_wav_header(FILE *out, struct note_t *note)
45 {
46 int t;
47
48 note->marker=ftell(out)-4;
49
50 /* Write RIFF header */
51
52 fprintf(out,"RIFF");
53 write_long(out,4);
54 fprintf(out,"WAVE");
55
56 /* Write fmt header */
57
58 fprintf(out,"fmt ");
59 write_long(out,16);
60 write_word(out,1);
61 write_word(out,1);
62 write_long(out,note->sample_rate);
63 write_long(out,note->sample_rate*note->bytes);
64 if (note->bytes==1)
65 { write_word(out,1); }
66 else
67 if (note->bytes==2)
68 { write_word(out,2); }
69 write_word(out,note->bytes*8);
70
71 /* Write the start of the data header */
72
73 fprintf(out,"data");
74 write_long(out,0);
75
76 note->samples_per_beat=(double)note->sample_rate*(60/(double)note->bpm);
77 t=(note->samples_per_beat)*4;
78
79 note->wav_buffer=malloc(note->bytes*(t+(t/2)+(t/4)));
80 }
81
write_wav_note(FILE * out,struct note_t * note)82 void write_wav_note(FILE *out, struct note_t *note)
83 {
84 unsigned int samples_per_note;
85 double samples_per_wave;
86 double waveform;
87 double waveform_slope;
88 double actual_freq;
89 double waveform_x;
90 /* P C C# C D# E F */
91 double freqs[]={ 0, 261.625, 277.175, 293.675, 311.125, 329.625, 349.225,
92 370, 392, 415.3, 440, 466.15, 493.883 };
93 /* F# G G# A A# B */
94 int t;
95 short int sample16;
96 char sample8;
97 int style_length;
98 /* unsigned char buffer[256000]; */
99 int ptr;
100
101
102 #ifdef DSP
103 #ifdef WINDOWS
104 WAVEHDR waveheader;
105 #else
106 if (out==0 && audio_fd==-1) return;
107 #endif
108 #endif
109 ptr=0;
110
111 if (note->transpose>0) note->scale+=note->transpose;
112
113 /* note->samples_per_beat=(double)note->sample_rate*(60/(double)note->bpm); */
114
115 samples_per_note=(double)note->samples_per_beat*(double)((double)4/(double)(1<<(note->length)));
116
117 if (note->modifier==1)
118 { samples_per_note=samples_per_note+(samples_per_note/2); }
119 else
120 if (note->modifier==2)
121 { samples_per_note=samples_per_note+(samples_per_note/2)+(samples_per_note/4); }
122
123 #ifdef DEBUG
124 printf("Samples per note %d\n",samples_per_note);
125 #endif
126
127 if (note->tone==0)
128 {
129 for (t=0; t<samples_per_note; t++)
130 {
131 if (note->bytes==1)
132 { note->wav_buffer[ptr++]=0; }
133 else
134 { note->wav_buffer[ptr++]=0; note->wav_buffer[ptr++]=0; }
135 }
136 }
137 else
138 {
139 if (note->tone>12) note->tone=1;
140
141 actual_freq=freqs[note->tone];
142 actual_freq=actual_freq*(double)(1<<note->scale);
143
144 samples_per_wave=(double)note->sample_rate/(double)actual_freq;
145 waveform_x=0;
146
147 if (note->style==0)
148 { style_length=samples_per_note-(double)note->sample_rate/64; }
149 else
150 if (note->style==2)
151 { style_length=samples_per_note/3; }
152 else
153 { style_length=samples_per_note; }
154
155 if (note->bytes==1)
156 {
157 waveform_slope=255/(double)samples_per_wave;
158 waveform=127;
159
160 for (t=0; t<samples_per_note; t++)
161 {
162 if (t<style_length)
163 {
164 if (waveform_x>samples_per_wave)
165 {
166 waveform=127;
167 waveform_x=waveform_x-samples_per_wave;
168 }
169
170 sample8=waveform;
171 /* putc(sample8,out); */
172 note->wav_buffer[ptr++]=sample8;
173 waveform=waveform-waveform_slope;
174 if (waveform<-127) waveform=-127;
175 waveform_x=waveform_x+1;
176 }
177 else
178 { note->wav_buffer[ptr++]=0; }
179 }
180 }
181 else
182 if (note->bytes==2)
183 {
184 waveform_slope=65534/(double)samples_per_wave;
185 waveform=32767;
186
187 for (t=0; t<samples_per_note; t++)
188 {
189 if (t<style_length)
190 {
191 if (waveform_x>samples_per_wave)
192 {
193 waveform=32767;
194 waveform_x=waveform_x-samples_per_wave;
195 }
196
197 sample16=waveform;
198 /* write_word(out,sample16); */
199 note->wav_buffer[ptr++]=(sample16&255);
200 note->wav_buffer[ptr++]=(sample16>>8);
201 waveform=waveform-waveform_slope;
202 if (waveform<-32767) waveform=-32767;
203 waveform_x=waveform_x+1;
204 }
205 else
206 { note->wav_buffer[ptr++]=0; note->wav_buffer[ptr++]=0; }
207 }
208 }
209 }
210
211 #ifdef DSP
212 #ifndef WINDOWS
213
214 if (out==0) { write(audio_fd,note->wav_buffer,ptr); }
215 else
216 #else
217 if (out==0)
218 {
219 waveheader.lpData=note->wav_buffer;
220 waveheader.dwBufferLength=ptr;
221 waveheader.dwFlags=0;
222 waveOutPrepareHeader(outHandle,&waveheader,sizeof(WAVEHDR));
223 t=waveOutWrite(outHandle,&waveheader,sizeof(WAVEHDR));
224
225 while(!(waveheader.dwFlags & WHDR_DONE));
226
227 MMTIME mmtime;
228 mmtime.wType=TIME_BYTES;
229
230 waveOutUnprepareHeader(outHandle,&waveheader,sizeof(WAVEHDR));
231 }
232 else
233 #endif
234 #endif
235 {
236 fwrite(note->wav_buffer,1,ptr,out);
237 }
238 }
239
240
write_wav_footer(FILE * out,struct note_t * note)241 void write_wav_footer(FILE *out, struct note_t *note)
242 {
243 unsigned int data_length,t;
244
245 t=ftell(out);
246 data_length=t-44;
247 fseek(out,40,0);
248 write_long(out,data_length);
249 fseek(out,4,0);
250 write_long(out,t-8);
251
252 if (note->wav_buffer!=0)
253 {
254 free(note->wav_buffer);
255 note->wav_buffer=0;
256 }
257 }
258
259
260 #ifdef DSP
261
write_dsp_header(FILE * out,struct note_t * note)262 void write_dsp_header(FILE *out, struct note_t *note)
263 {
264 #ifndef WINDOWS
265 int format;
266
267 note->bytes=2;
268 note->sample_rate=44100;
269
270 audio_fd=open(note->outname, O_WRONLY, 0);
271 if (audio_fd==-1)
272 {
273 printf("Problem opening %s\n",note->outname);
274 return;
275 }
276
277 format=AFMT_S16_LE;
278 if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format)==-1)
279 { goto dsperror; }
280
281 if (format!=AFMT_S16_LE)
282 {
283 note->bytes=1;
284
285 format=AFMT_S8;
286 if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format)==-1)
287 {
288 goto dsperror;
289 }
290 if (format!=AFMT_S8) goto dsperror;
291 }
292
293 format=0;
294 if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &format)==-1)
295 {
296 goto dsperror;
297 }
298 if (format==-1) goto dsperror;
299
300 format=44100;
301 if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &format)==-1)
302 {
303 goto dsperror;
304 }
305
306 if (format!=44100)
307 {
308 format=11025;
309 if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &format)==-1) goto dsperror;
310 if (format!=11025)
311 {
312 format=8000;
313 if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &format)==-1) goto dsperror;
314 if (format!=8000) goto dsperror;
315 }
316 }
317
318 note->sample_rate=format;
319
320 #ifdef DEBUG
321 printf("%d\n",format);
322 #endif
323
324 /* out=fdopen(audio_fd,"w"); */
325 /* if (out==0) goto dsperror; */
326
327 return;
328
329 dsperror:
330 printf("Error: Problem setting up DSP device.\n");
331 close(audio_fd);
332 audio_fd=-1;
333 out=0;
334 return;
335 #else
336
337 waveFormat.wFormatTag = WAVE_FORMAT_PCM;
338 waveFormat.nChannels = 1;
339 waveFormat.nSamplesPerSec = 44100;
340 waveFormat.wBitsPerSample = 16;
341 waveFormat.nBlockAlign = waveFormat.nChannels * (waveFormat.wBitsPerSample/8);
342 waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
343 waveFormat.cbSize = 0;
344
345 /* int result = waveOutOpen(&outHandle, WAVE_MAPPER, &waveFormat, (DWORD)myWindow, 0, CALLBACK_WINDOW); */
346 /* int result = waveOutOpen(&outHandle, WAVE_MAPPER, &waveFormat, (DWORD)NULL, 0, CALLBACK_WINDOW); */
347 int result = waveOutOpen(&outHandle, WAVE_MAPPER, &waveFormat, (DWORD)NULL, 0,CALLBACK_NULL );
348
349 if (result)
350 {
351 printf("Error: Problem setting up sound device.\r\n");
352 waveFormat.nChannels=0;
353 return;
354 }
355
356 note->bytes=2;
357 note->sample_rate=44100;
358
359 #endif
360 }
361
write_dsp_note(FILE * out,struct note_t * note)362 void write_dsp_note(FILE *out, struct note_t *note)
363 {
364 #ifndef WINDOWS
365 if (audio_fd==-1) return;
366 #endif
367
368 write_wav_note(out,note);
369 }
370
write_dsp_footer(FILE * out,struct note_t * note)371 void write_dsp_footer(FILE *out, struct note_t *note)
372 {
373 #ifndef WINDOWS
374 if (ioctl(audio_fd, SNDCTL_DSP_SYNC, 0)==-1) {}
375 close(audio_fd);
376 #else
377 /* waveOutUnprepareHeader(outHandle,&waveheader,sizeof(WAVEHDR)); */
378 #endif
379
380 }
381
382 #endif
383
get_note_from_freq(float freq,struct note_t * note)384 int get_note_from_freq(float freq, struct note_t *note)
385 {
386 double freqs[13];
387 /* P C C# C D# E F */
388 double freqs_t[]={ 0, 261.625, 277.175, 293.675, 311.125, 329.625, 349.225,
389 370, 392, 415.3, 440, 466.15, 493.883 };
390 /* F# G G# A A# B */
391 int t,m;
392
393 if (freq<freqs_t[1]-5) return 0;
394
395 m=0;
396 if (freq>freqs_t[12]+12) m=1;
397 if (freq>(freqs_t[12]*2)+24) m=2;
398
399 for(t=0; t<12; t++)
400 { freqs[t]=freqs_t[t+1]*(1<<m); }
401
402 if (freq<freqs[0]) freq=freqs[0];
403
404 for (t=0; t<12; t++)
405 {
406 if (freqs[t]==freq) return (t+(m*12))+1;
407
408 if (freqs[t]<freq && freq<freqs[t+1])
409 {
410 if (freq-freqs[t]<freqs[t+1]-freq)
411 { return (t+(m*12))+1; }
412 else
413 { return (t+(m*12))+2; }
414 }
415 }
416
417 return t;
418 }
419
parse_wav(FILE * in,FILE * out,int out_type,struct note_t * note)420 int parse_wav(FILE *in, FILE *out, int out_type, struct note_t *note)
421 {
422 char notes[2048];
423 char name[5],riff_type[5];
424 int duration[2048],sample_rate,channels,bytes;
425 int count,quarter_note,curr_note,last_note;
426 short int curr_sample;
427 int waves,samples,zeros;
428 int peak=1,length,t,a,ch,zero;
429 int datalength;
430 double freq;
431
432 read_chars(in,name,4);
433 t=read_long(in);
434 read_chars(in,riff_type,4);
435
436 zero=0;
437
438 if (strcasecmp(name,"RIFF")!=0 || strcasecmp(riff_type,"wave")!=0)
439 {
440 printf("Invalid WAV format.\n");
441 return -1;
442 }
443
444 read_chars(in,name,4);
445 read_long(in);
446 read_word(in);
447 channels=read_word(in);
448 sample_rate=read_long(in);
449 read_long(in);
450 bytes=read_word(in);
451 read_word(in);
452
453 read_chars(in,name,4);
454 datalength=read_long(in);
455
456 curr_sample=0;
457 samples=0;
458 waves=0;
459 zeros=0;
460 t=0;
461 count=0;
462 last_note=-1;
463 length=0;
464
465 #ifdef DEBUG
466 printf("going to read %d bytes\n",datalength);
467 printf("bytes_per_sample=%d channels=%d\n",bytes,channels);
468 #endif
469
470 while (t<datalength)
471 {
472 if (bytes==1)
473 {
474 ch=getc(in);
475 curr_sample=ch*65535/255;
476 }
477 else
478 if (bytes==2 && channels==2)
479 {
480 ch=getc(in)+getc(in);
481 ch=ch/2;
482 curr_sample=ch*65535/255;
483 }
484 else
485 if (bytes==2 && channels==1)
486 {
487 curr_sample=read_word(in);
488 }
489 else
490 if (bytes==4 && channels==2)
491 {
492 read_word(in);
493 curr_sample=(short int)read_word(in);
494 }
495
496 #ifdef DEBUG
497 /* printf("curr_sample=%d t=%d\n",curr_sample,t); */
498 #endif
499
500 t=t+note->bytes;
501
502 if (curr_sample<CUTOFF && curr_sample>-CUTOFF)
503 { curr_sample=0; }
504
505 if (curr_sample==0)
506 {
507 zero++;
508 if (zero>=ZEROS)
509 {
510 if (count!=0)
511 {
512 notes[count]=0;
513 duration[count]=((double)zeros/(double)sample_rate)*1000;
514 count++;
515 }
516 zero=0;
517 samples=0;
518 waves=0;
519 }
520 }
521 else
522 {
523 zero=0;
524
525 if (curr_sample<0 && peak==1)
526 {
527 peak=-1;
528 }
529 else
530 if (curr_sample>0 && peak==-1)
531 {
532 peak=1;
533 waves++;
534 }
535 }
536
537 samples++;
538
539 /* if (samples>=SAMPLES) */
540 if (waves>=WAVES)
541 {
542 freq=(double)waves/((double)samples/(double)sample_rate);
543 curr_note=get_note_from_freq(freq,note);
544
545 #ifdef DEBUG
546 printf("waves: %d freq: %f curr_note: %d\n",waves,freq,curr_note);
547 #endif
548
549 if (curr_note!=last_note)
550 {
551 if (last_note!=-1)
552 {
553 if (!(count==0 && last_note==0))
554 {
555 notes[count]=last_note;
556 /* duration[count]=((double)length/(double)SAMPLES)*1000; */
557 duration[count]=((double)length/(double)sample_rate)*1000;
558 #ifdef DEBUG
559 printf("Note %d Dur %d sam %d\n",last_note,duration[count],samples);
560 #endif
561 if (duration[count]>10)
562 { count++; }
563 }
564 length=0;
565 }
566 }
567
568 length=length+samples;
569
570 last_note=curr_note;
571 waves=0;
572 samples=0;
573 }
574 }
575
576
577 if (count==0)
578 {
579 printf("No notes were processed. Aborting!\n");
580 return -1;
581 }
582
583 #ifdef DEBUG
584 printf("count: %d\n",count);
585 #endif
586
587 quarter_note=duration[0];
588
589 t=0;
590 while(t<8)
591 {
592 note->bpm=60000/quarter_note;
593 if (note->bpm<250) break;
594
595 quarter_note=quarter_note*2;
596 t++;
597 }
598
599 t=0;
600 while(t<8)
601 {
602 if (note->bpm>100) break;
603 quarter_note=quarter_note/2;
604 note->bpm=60000/quarter_note;
605
606 t++;
607 }
608
609 #ifdef DEBUG
610 printf("Quarter note: %d ms\n",quarter_note);
611 #endif
612
613 t=0;
614 if (note->songname[0]==0)
615 {
616 while(note->filename[t]!='.' && note->filename[t]!=0 && t<14)
617 {
618 note->songname[t]=note->filename[t];
619 t++;
620 }
621 note->songname[t]=0;
622 }
623
624 header_route(out,note,0,out_type);
625
626 for (t=0; t<count; t++)
627 {
628 if (notes[t]==0)
629 {
630 note->tone=0;
631 }
632 else
633 {
634 note->tone=(notes[t]-1)%12+1;
635 note->scale=(notes[t]-1)/12;
636 }
637
638 a=get_duration((float)duration[t]/((float)quarter_note*4));
639 note->length=a/2;
640 note->modifier=(a%2)^1;
641
642 if (note->length>5) continue;
643
644 note_route(out,note,0,out_type);
645 }
646
647 footer_route(out,note,0,out_type);
648
649 return (0);
650 }
651
652