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