1 /*
2 * xwave - an interactive audio player, recorder, editor
3 * for the XWindow System
4 *
5 * Copyright (C) 1996 Kai Kollmorgen
6 * (kkollmor@informatik.uni-rostock.de)
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <dirent.h>
28
29 #include <fcntl.h>
30 #include <unistd.h>
31
32 #include <sys/types.h>
33 #include <math.h>
34
35 #include <X11/Intrinsic.h>/* Intrinsics Definitions */
36 #include <X11/StringDefs.h>/* Standard Name-String definitions */
37 #include <X11/Shell.h> /* Shell Definitions */
38
39 #include "types.h"
40 #include "xwave.h"
41 #include "xwave_widget.h"
42 #include "misc.h"
43 #include "graphics.h"
44 #include "sample_settings.h"
45 #include "audio_file.h"
46 #include "effects.h"
47
48 extern Main_Data *MD;
49 extern AppResources app_resources;
50
51 static void reverse_8(char *buffer,int channels,int length);
52 static void reverse_16(short *buffer,int channels,int length);
53 static void swap_8(char *buffer,int length);
54 static void swap_16(short *buffer,int length);
55 static void props_return(Sample_Return *sr);
56 static void resample_16(int inlength,int infreq,short *inbuf,
57 int outlength,int outfreq,short *outbuf);
58 static void resample_8(int inlength,int infreq,byte *inbuf,
59 int outlength,int outfreq,byte *outbuf);
60 static void av_return(float mult1,float mult2);
61 static void ev_return(float fo_time[MAX_CHANNELS],
62 float fo_factor[MAX_CHANNELS],
63 float sup_amp[MAX_CHANNELS]);
64 static void ec_return(float fo_time[MAX_CHANNELS],
65 float fo_factor[MAX_CHANNELS]);
66
67
reverse_8(char * buffer,int channels,int length)68 void reverse_8(char *buffer,int channels,int length)
69 {
70 int i,j,hi,lo;
71 static char valbuf[MAX_CHANNELS];
72
73 if (channels>MAX_CHANNELS) return;
74
75 for (i=0;i<length/2;i+=channels) {
76 lo=i;
77 hi=length-i-channels;
78 j=0;
79 while (j<channels) {
80 valbuf[j]=buffer[lo+j];
81 buffer[lo+j]=buffer[hi+j];
82 buffer[hi+j]=valbuf[j];
83 j++;
84 }
85 }
86 }
87
reverse_16(short * buffer,int channels,int length)88 void reverse_16(short *buffer,int channels,int length)
89 {
90 int i,j,hi,lo;
91 static short valbuf[MAX_CHANNELS];
92
93 if (channels>MAX_CHANNELS) return;
94
95 for (i=0;i<length/2;i+=channels) {
96 lo=i;
97 hi=length-i-channels;
98 j=0;
99 while (j<channels) {
100 valbuf[j]=buffer[lo+j];
101 buffer[lo+j]=buffer[hi+j];
102 buffer[hi+j]=valbuf[j];
103 j++;
104 }
105 }
106 }
107
reverse_call(Widget w,XtPointer client_data,XtPointer call_data)108 void reverse_call(Widget w, XtPointer client_data, XtPointer call_data)
109 {
110 Main_Data *md=(Main_Data*) client_data;
111 int length;
112 char *buf=(char*)md->wd->buffer;
113
114 if (!md->wd->inmem) {
115 warn_popup(md->mw->form,app_resources.err_notimplement);
116 return;
117 }
118
119 watch_cursor(True);
120
121 length=md->wd->length;
122
123 if (md->wd->ismark) {
124 buf+=md->wd->markbeg*md->wd->bpspl;
125 length=md->wd->marklength*md->wd->bpspl;
126 }
127
128 if (md->wd->inmem) {
129 switch (md->wd->res) {
130 case 8:
131 reverse_8(buf,md->wd->channels,length);
132 break;
133 case 16:
134 reverse_16((short*)buf,md->wd->channels,length/2);
135 break;
136 }
137 md->cb->update=True;
138 md->cb->modified=True;
139 update_canvas(md,NULL);
140 update_display(md);
141 }
142 watch_cursor(False);
143 }
144
swap_8(char * buffer,int length)145 void swap_8(char *buffer,int length)
146 {
147 int i;
148 char val;
149
150 for (i=0;i<length;i+=2) {
151 val=buffer[i];
152 buffer[i]=buffer[i+1];
153 buffer[i+1]=val;
154 }
155 }
156
swap_16(short * buffer,int length)157 void swap_16(short *buffer,int length)
158 {
159 int i;
160 short val;
161
162 for (i=0;i<length;i+=2) {
163 val=buffer[i];
164 buffer[i]=buffer[i+1];
165 buffer[i+1]=val;
166 }
167 }
168
swap_call(Widget w,XtPointer client_data,XtPointer call_data)169 void swap_call(Widget w, XtPointer client_data, XtPointer call_data)
170 {
171 Main_Data *md=(Main_Data*) client_data;
172 int length;
173 char *buf=(char*)md->wd->buffer;
174
175
176 if (md->wd->channels<2) return;
177
178 if (!md->wd->inmem) {
179 warn_popup(md->mw->form,app_resources.err_notimplement);
180 return;
181 }
182
183 watch_cursor(True);
184
185 length=md->wd->length;
186
187 if (md->wd->ismark) {
188 buf+=md->wd->markbeg*md->wd->bpspl;
189 length=md->wd->marklength*md->wd->bpspl;
190 }
191
192 if (md->wd->inmem) {
193 switch (md->wd->res) {
194 case 8:
195 swap_8(buf,length);
196 break;
197 case 16:
198 swap_16((short*) buf,md->wd->length/2);
199 break;
200 }
201 md->cb->update=True;
202 md->cb->modified=True;
203 update_canvas(md,NULL);
204 update_display(md);
205 }
206 watch_cursor(False);
207 }
208
pitch_call(Widget w,XtPointer client_data,XtPointer call_data)209 void pitch_call(Widget w, XtPointer client_data, XtPointer call_data)
210 {
211 }
212
213
props_call(Widget w,XtPointer client_data,XtPointer call_data)214 void props_call(Widget w, XtPointer client_data, XtPointer call_data)
215 {
216 Main_Data *md=(Main_Data*) client_data;
217
218 if (!md->wd->inmem) {
219 warn_popup(md->mw->form,app_resources.err_notimplement);
220 return;
221 }
222 sample_dialog(props_return,md->wd);
223 }
224
props_return(Sample_Return * sr)225 void props_return(Sample_Return *sr)
226 {
227 int i;
228 Main_Data *md=MD;
229 Wave_Data *wd=md->wd;
230
231 watch_cursor(True);
232
233 if (sr->freq!=wd->freq) {
234 int newlength;
235 char *newbuf,*sbufin=NULL,*sbufout=NULL;
236
237 newlength=(int)((double)sr->freq/
238 (double)wd->freq*(double)wd->length);
239
240 if ((newbuf=malloc(newlength))==NULL) {
241 watch_cursor(False);
242 warn_popup(md->mw->form,app_resources.err_mem);
243 return;
244 }
245
246 if (wd->channels>1) {
247 if ((sbufin=malloc(wd->length/2))==NULL) {
248 watch_cursor(False);
249 warn_popup(md->mw->form,app_resources.err_mem);
250 free(newbuf);
251 return;
252 }
253 if ((sbufout=malloc(newlength/2))==NULL) {
254 watch_cursor(False);
255 warn_popup(md->mw->form,app_resources.err_mem);
256 free(sbufin);
257 free(newbuf);
258 return;
259 }
260 }
261
262 switch (wd->res) {
263 case 8:
264 switch (wd->channels) {
265 case 1:
266 resample_8(wd->length,wd->freq,wd->buffer,
267 newlength,sr->freq,(byte*) newbuf);
268 break;
269 case 2: {
270 /* catch every 2nd sample (channel 1) */
271 for (i=0;i<wd->length/2;i++) sbufin[i]=wd->buffer[i<<1];
272
273 resample_8(wd->length/2,wd->freq,sbufin,
274 newlength/2,sr->freq,sbufout);
275 for (i=0;i<newlength/2;i++) newbuf[i<<1]=sbufout[i];
276
277 /* catch every 2nd sample (channel 2) */
278 for (i=0;i<wd->length/2;i++)
279 sbufin[i]=wd->buffer[(i<<1)+1];
280
281 resample_8(wd->length/2,wd->freq,(byte*)sbufin,
282 newlength/2,sr->freq,(byte*)sbufout);
283 for (i=0;i<newlength/2;i++) newbuf[(i<<1)+1]=sbufout[i];
284
285 break;
286 }
287 }
288 break;
289 case 16:
290 switch (wd->channels) {
291 case 1:
292 resample_16(wd->length/2,wd->freq,(short*) wd->buffer,
293 newlength/2,sr->freq,(short*)newbuf);
294 break;
295 case 2: {
296 short *buf=(short*) wd->buffer;
297 short *inbuf=(short*) sbufin;
298 short *outbuf=(short*) sbufout;
299 short *nbuf=(short*) newbuf;
300
301 /* catch every 2nd sample (channel 1) */
302 for (i=0;i<wd->length/4;i++) inbuf[i]=buf[i<<1];
303
304 resample_16(wd->length/4,wd->freq,inbuf,
305 newlength/4,sr->freq,(short*)outbuf);
306 for (i=0;i<newlength/4;i++) nbuf[i<<1]=outbuf[i];
307
308 /* catch every 2nd sample (channel 2) */
309 for (i=0;i<wd->length/4;i++) inbuf[i]=buf[(i<<1)+1];
310 resample_16(wd->length/4,wd->freq,(short*) inbuf,
311 newlength/4,sr->freq,(short*)outbuf);
312 for (i=0;i<newlength/4;i++) nbuf[(i<<1)+1]=outbuf[i];
313
314 break;
315 }
316 }
317 break;
318 }
319
320 if (wd->channels>1) {
321 free(sbufin);
322 free(sbufout);
323 }
324
325 free(wd->buffer);
326 wd->buffer=(unsigned char*)newbuf;
327 wd->length=newlength;
328 wd->tlength=newlength/wd->bpspl;
329 wd->freq=sr->freq;
330
331 md->cb->modified=True;
332
333 } /* resample */
334
335 if (sr->res!=wd->res) {
336 char *obuf=(char*)wd->buffer;
337 char *newbuf;
338 int newlength;
339
340 newlength=(int)((float) sr->res/(float) wd->res *
341 (float) wd->length);
342
343 if ((newbuf=malloc(newlength))==NULL) {
344 watch_cursor(False);
345 warn_popup(md->mw->form,app_resources.err_mem);
346 return;
347 }
348
349 switch (sr->res) {
350 case 8: {
351 #if defined (linux) || defined (__FreeBSD__)
352 for (i=0;i<newlength;i++) newbuf[i]=obuf[(i<<1)+1]+128;
353 #elif defined (sgi) || defined (sun)
354 for (i=0;i<newlength;i++) newbuf[i]=obuf[(i<<1)]+128;
355 #endif
356 break;
357 }
358 case 16: {
359 #if defined (linux) || defined (__FreeBSD__)
360 for (i=0;i<wd->length;i++) newbuf[(i<<1)+1]=obuf[i]-128;
361 #elif defined (sgi) || defined (sun)
362 for (i=0;i<wd->length;i++) newbuf[(i<<1)]=obuf[i]-128;
363 #endif
364 break;
365 }
366 }
367
368 free(wd->buffer);
369 wd->buffer=(unsigned char*)newbuf;
370 wd->length=newlength;
371 wd->res=sr->res;
372 wd->bpspl=(wd->res*wd->channels)/8;
373 wd->tlength=newlength/wd->bpspl;
374 md->cb->modified=True;
375
376 } /* resolution */
377
378 /* at the moment only 2 channels supported
379 * MONO to STEREO and vice versa
380 */
381 if (sr->channels!=wd->channels) {
382 char *newbuf;
383 int newlength;
384
385 if (sr->channels==1) newlength=wd->length/2;
386 else newlength=wd->length*2;
387
388 if ((newbuf=malloc(newlength))==NULL) {
389 watch_cursor(False);
390 warn_popup(md->mw->form,app_resources.err_mem);
391 return;
392 }
393
394 switch (sr->res) {
395 case 8: {
396 byte *obuf=wd->buffer;
397
398 switch (sr->channels) {
399 case 1:
400 /* (channel_1 / 2) + (channel_2 / 2) */
401 for (i=0;i<newlength;i++) {
402 newbuf[i]=(obuf[i<<1]>>1) + (obuf[(i<<1)+1]>>1);
403 }
404 break;
405 case 2:
406 for (i=0;i<wd->length;i++) {
407 newbuf[i<<1]=obuf[i];
408 newbuf[(i<<1)+1]=obuf[i];
409 }
410 break;
411 }
412 break;
413 } /* 8 bit */
414 case 16: {
415 short *inbuf=(short*) wd->buffer;
416 short *outbuf=(short*) newbuf;
417
418 switch (sr->channels) {
419 case 1:
420 /* (channel_1 / 2) + (channel_2 / 2) */
421 for (i=0;i<newlength/2;i++) {
422 outbuf[i]=(inbuf[i<<1]>>1) + (inbuf[(i<<1)+1]>>1);
423 }
424 break;
425 case 2:
426 for (i=0;i<wd->length/2;i++) {
427 outbuf[i<<1]=inbuf[i];
428 outbuf[(i<<1)+1]=inbuf[i];
429 }
430 break;
431 }
432 break;
433 } /* 16 bit */
434 } /* switch (sr->res) */
435
436 free(wd->buffer);
437 wd->buffer=(unsigned char*)newbuf;
438 wd->length=newlength;
439 wd->channels=sr->channels;
440 wd->bpspl=(wd->res*wd->channels)/8;
441 wd->tlength=newlength/wd->bpspl;
442 md->cb->modified=True;
443 } /* channels */
444
445 XtFree((char*) sr);
446
447 if (md->cb->modified) {
448 md->cb->update=True;
449 update_canvas(md,NULL);
450 update_display(md);
451 }
452
453 watch_cursor(False);
454 }
455
resample_16(int inlength,int infreq,short * inbuf,int outlength,int outfreq,short * outbuf)456 void resample_16(int inlength,int infreq,short *inbuf,
457 int outlength,int outfreq,short *outbuf)
458 {
459 int lcmrate,inskip,outskip,intot,outtot;
460 int len,done,val,last;
461
462 lcmrate=lcm(infreq,outfreq);
463 inskip=lcmrate/infreq;
464 outskip=lcmrate/outfreq;
465 intot=outtot=0;
466
467 last=*inbuf++;
468 *outbuf++=last;
469 outtot+=outskip;
470 while ((intot + inskip) <= outtot) intot += inskip;
471
472 len = (inlength * inskip) / outskip;
473 if (len > outlength) len = outlength;
474 for(done=1; done < len; done++) {
475 val=last;
476 val+=((float)((*inbuf)-last)*((float)outtot-intot))/inskip;
477 *outbuf = val;
478 outbuf++;
479 outtot += outskip;
480 while ((intot + inskip) <= outtot) {
481 last = *inbuf++;
482 intot += inskip;
483 }
484 }
485 }
486
resample_8(int inlength,int infreq,byte * inbuf,int outlength,int outfreq,byte * outbuf)487 void resample_8(int inlength,int infreq,byte *inbuf,
488 int outlength,int outfreq,byte *outbuf)
489 {
490 int lcmrate,inskip,outskip,intot,outtot;
491 int len,done,val,last;
492
493 lcmrate=lcm(infreq,outfreq);
494 inskip=lcmrate/infreq;
495 outskip=lcmrate/outfreq;
496 intot=outtot=0;
497
498 last=*inbuf++;
499 *outbuf++=last;
500 outtot+=outskip;
501 while ((intot + inskip) <= outtot) intot += inskip;
502
503 len = (inlength * inskip) / outskip;
504 if (len > outlength) len = outlength;
505 for(done=1; done < len; done++) {
506 val=last;
507 val+=((float)((*inbuf)-last)*((float)outtot-intot))/inskip;
508 *outbuf = val;
509 outbuf++;
510 outtot += outskip;
511 while ((intot + inskip) <= outtot) {
512 last = *inbuf++;
513 intot += inskip;
514 }
515 }
516 }
517
abs_vol_call(Widget w,XtPointer client_data,XtPointer call_data)518 void abs_vol_call(Widget w, XtPointer client_data, XtPointer call_data)
519 {
520 Main_Data *md=(Main_Data*) client_data;
521
522 if (!md->wd->inmem) {
523 warn_popup(md->mw->form,app_resources.err_notimplement);
524 return;
525 }
526
527 watch_cursor(True);
528
529 find_peak(md->wd);
530
531 watch_cursor(False);
532
533 absvol_dialog(av_return,md);
534 }
535
av_return(float mult1,float mult2)536 void av_return(float mult1,float mult2)
537 {
538 int i,new_val,max;
539 Main_Data *md=MD;
540 Wave_Data *wd=md->wd;
541 int length=wd->length;
542 char *buf=(char*)wd->buffer;
543
544 watch_cursor(True);
545
546 max=(int)pow(2.0,(float)wd->res)/2.0;
547
548 if (wd->ismark) {
549 buf+=wd->markbeg*wd->bpspl;
550 length=wd->marklength*wd->bpspl;
551 }
552
553 switch (wd->res) {
554 case 8: {
555 char val;
556
557 switch (wd->channels) {
558 case 1:
559 for (i=0;i<length;i++) {
560 val=buf[i]^0x80;
561 new_val=(int)((float)val*mult1);
562 if (new_val>max) new_val=max;
563 if (new_val<-max) new_val=-max;
564 buf[i]=new_val^0x80;
565 }
566 break;
567 case 2:
568 for (i=0;i<length;) {
569 val=buf[i]^0x80;
570 new_val=(int)((float)val*mult1);
571 if (new_val>max) new_val=max;
572 if (new_val<-max) new_val=-max;
573 buf[i]=new_val^0x80;
574 i++;
575 val=buf[i]^0x80;
576 new_val=(int)((float)val*mult2);
577 if (new_val>max) new_val=max;
578 if (new_val<-max) new_val=-max;
579 buf[i]=new_val^0x80;
580 i++;
581 }
582 break;
583 }
584 break;
585 }
586 case 16: {
587 short *sbuf=(short*) buf,val;
588
589 switch (md->wd->channels) {
590 case 1:
591 for (i=0;i<length/2;i++) {
592 val=sbuf[i];
593 new_val=(int)((float)val*mult1);
594 if (new_val>max-1) new_val=max-1;
595 if (new_val<-max) new_val=-max;
596 sbuf[i]=new_val;
597 }
598 break;
599 case 2:
600 for (i=0;i<length/2;) {
601 val=sbuf[i];
602 new_val=(int)((float)val*mult1);
603 if (new_val>max-1) new_val=max-1;
604 if (new_val<-max) new_val=-max;
605 sbuf[i]=new_val;
606 i++;
607 val=sbuf[i];
608 new_val=(int)((float)val*mult2);
609 if (new_val>max-1) new_val=max;
610 if (new_val<-max) new_val=-max;
611 sbuf[i]=new_val;
612 i++;
613 }
614 break;
615 }
616 break;
617 }
618 }
619
620 md->cb->modified=True;
621 md->cb->update=True;
622 update_canvas(md,NULL);
623 update_display(md);
624
625 watch_cursor(False);
626 }
627
env_vol_call(Widget w,XtPointer client_data,XtPointer call_data)628 void env_vol_call(Widget w, XtPointer client_data, XtPointer call_data)
629 {
630 Main_Data *md=(Main_Data*) client_data;
631
632 if (!md->wd->inmem) {
633 warn_popup(md->mw->form,app_resources.err_notimplement);
634 return;
635 }
636
637 envvol_dialog(ev_return,md->wd);
638 }
639
ev_return(float fo_time[MAX_CHANNELS],float fo_factor[MAX_CHANNELS],float sup_amp[MAX_CHANNELS])640 void ev_return(float fo_time[MAX_CHANNELS],
641 float fo_factor[MAX_CHANNELS],
642 float sup_amp[MAX_CHANNELS])
643 {
644 Main_Data *md=MD;
645 Wave_Data *wd=md->wd;
646 char *buf;
647 float k;
648 int i,j,value,env,time_wait,time_index,k_index,max,min_amp;
649 int length=wd->length;
650
651 watch_cursor(True);
652
653 max=(int)pow(2.0,(float)wd->res)/2.0;
654
655 switch(wd->res) {
656 case 8: {
657 char val;
658
659 for (j=0;j<wd->channels;j++) {
660
661 buf=(char*) wd->buffer;
662 if (wd->ismark) {
663 buf+=wd->markbeg*wd->bpspl;
664 length=wd->marklength*wd->bpspl;
665 }
666 env=0;
667 time_index=0;
668 k_index=0;
669 k=1.0;
670 min_amp=(int) ((float)max*sup_amp[j]);
671 time_wait=(int) ((float)(wd->freq*fo_time[j])/1000.0 /*1ms*/);
672
673 for (i=j;i<length;i+=wd->channels) {
674 val=buf[i]^0x80;
675 value=abs(val);
676 if (value>env) {
677 time_index=0;
678 env=value;
679 } else {
680 if (time_index<time_wait) time_index++;
681 else env=(int) ((float)env*fo_factor[j]);
682 }
683 if (env>min_amp) {
684 k+=(1-fo_factor[j])*(((float)(max-1)/(float) env)-k);
685 k_index=0;
686 } else {
687 if (k_index<time_wait) k_index++;
688 else k*=fo_factor[j];
689 }
690 if (value*k>max-1) k=((float)max-1)/((float)value);
691 val*=k;
692 buf[i]=val^0x80;
693 }
694 } /* for (j=0;j<wd->channels;j++) */
695 break;
696 }
697 case 16: {
698 short val,*buf16;
699
700 for (j=0;j<wd->channels;j++) {
701
702 buf=(char*) wd->buffer;
703 if (wd->ismark) {
704 buf+=wd->markbeg*wd->bpspl;
705 length=wd->marklength*wd->bpspl;
706 }
707 buf16=(short*)buf;
708 env=0;
709 time_index=0;
710 k_index=0;
711 k=1.0;
712 min_amp=(int) ((float)max*sup_amp[j]);
713 time_wait=(int) ((float)(wd->freq*fo_time[j])/1000.0 /*1ms*/);
714
715 for (i=j;i<length/2;i+=wd->channels) {
716 val=buf16[i];
717 value=abs(val);
718 if (value>env) {
719 time_index=0;
720 env=value;
721 } else {
722 if (time_index<time_wait) time_index++;
723 else env=env*fo_factor[j];
724 }
725 if (env>min_amp) {
726 k+=(1-fo_factor[j])*(((float)(max-1)/(float) env)-k);
727 k_index=0;
728 } else {
729 if (k_index<time_wait) k_index++;
730 else k*=fo_factor[j];
731 }
732 if (value*k>max-1) k=((float)max-1)/((float)value);
733 val*=k;
734 buf16[i]=val;
735 }
736 } /* for (j=0;j<wd->channels;j++) */
737 break;
738 }
739 } /* switch (wd->res) */
740 md->cb->modified=True;
741 md->cb->update=True;
742 update_canvas(md,NULL);
743 update_display(md);
744
745 watch_cursor(False);
746 }
747
echo_call(Widget w,XtPointer client_data,XtPointer call_data)748 void echo_call(Widget w, XtPointer client_data, XtPointer call_data)
749 {
750 Main_Data *md=(Main_Data*) client_data;
751
752 if (!md->wd->inmem) {
753 warn_popup(md->mw->form,app_resources.err_notimplement);
754 return;
755 }
756
757 echo_dialog(ec_return,md->wd);
758 }
759
ec_return(float fo_time[MAX_CHANNELS],float fo_factor[MAX_CHANNELS])760 void ec_return(float fo_time[MAX_CHANNELS],
761 float fo_factor[MAX_CHANNELS])
762 {
763 Main_Data *md=MD;
764 Wave_Data *wd=md->wd;
765 char *ring,*buf;
766 int i,j,echo,ring_length,ring_count;
767 int length=wd->length;
768 float teiler;
769
770 watch_cursor(True);
771
772 for (j=0;j<wd->channels;j++) {
773
774 buf=(char*) wd->buffer;
775 if (wd->ismark) {
776 buf+=wd->markbeg*wd->bpspl;
777 length=wd->marklength*wd->bpspl;
778 }
779
780 ring_length=(int) (fo_time[j]*(float)wd->freq);
781
782 if (ring_length*(wd->res/8)<MAXUSHORT) ring=(char*)md->mg->fbuf;
783 else {
784 if ((ring=malloc(ring_length*(wd->res/8)))==NULL) {
785 watch_cursor(False);
786 warn_popup(md->mw->form,app_resources.err_mem);
787 return;
788 }
789 }
790 for (i=0;i<ring_length*(wd->res/8);i++) ring[i]=0;
791 ring_count=0;
792 teiler=2.0*fo_factor[j];
793
794 switch (wd->res) {
795 case 8: {
796 char val;
797 for (i=j;i<length;i++) {
798 val=buf[i]^0x80;
799 echo=ring[ring_count % ring_length]*fo_factor[j];
800 val+=echo;
801 ring[ring_count]=val/2;
802 val/=teiler;
803 buf[i]=val^0x80;
804 ring_count++;
805 if (ring_count==ring_length) ring_count=0;
806 }
807 break;
808 }
809 case 16: {
810 short val,*ring16,*buf16;
811
812 buf16=(short*)buf;
813 ring16=(short*)ring;
814
815 for (i=j;i<length/2;i++) {
816 val=buf16[i];
817 echo=ring16[ring_count % ring_length]*fo_factor[j];
818 val+=echo;
819 ring16[ring_count]=val/2;
820 buf16[i]=val/teiler;
821 ring_count++;
822 if (ring_count==ring_length) ring_count=0;
823 }
824 break;
825 }
826 }
827 if (ring_length*(wd->res/8)>=MAXUSHORT) free(ring);
828 }
829
830 md->cb->modified=True;
831 md->cb->update=True;
832 update_canvas(md,NULL);
833 update_display(md);
834
835 watch_cursor(False);
836 }
837
838
find_peak(Wave_Data * wd)839 void find_peak(Wave_Data *wd)
840 {
841 int i,peak_r=0,peak_l=0;
842 char *buffer;
843 int begin=0,length=wd->length;
844
845 if (wd->ismark) {
846 begin=wd->markbeg*wd->bpspl;
847 length=wd->marklength*wd->bpspl;
848 }
849
850 if (wd->inmem) {
851 buffer=(char*)(wd->buffer+begin);
852
853 switch (wd->res) {
854 case 8: {
855 char val_l,val_r;
856
857 switch (wd->channels) {
858 case 1:
859 for (i=0;i<length;i++) {
860 val_l=buffer[i]^0x80;
861 if (abs(val_l)>peak_l) {
862 peak_l=abs(val_l);
863 wd->ind_peak_l=i;
864 }
865 }
866 break;
867 case 2:
868 for (i=0;i<length;) {
869 val_l=buffer[i++]^0x80;
870 if (abs(val_l)>peak_l) {
871 peak_l=abs(val_l);
872 wd->ind_peak_l=i;
873 }
874 val_r=buffer[i++]^0x80;
875 if (abs(val_r)>peak_r) {
876 peak_r=abs(val_r);
877 wd->ind_peak_r=i;
878 }
879 }
880 break;
881 } /* switch (wd->channels) */
882 break;
883 } /* case 8 */
884 case 16: {
885 short *buf=(short*) buffer,val_l,val_r;
886
887 switch (wd->channels) {
888 case 1:
889 for (i=0;i<length/2;i++) {
890 val_l=abs(buf[i]);
891 if (val_l>peak_l) {
892 peak_l=val_l;
893 wd->ind_peak_l=i<<1;
894 }
895 }
896 break;
897 case 2:
898 for (i=0;i<length/2;) {
899 val_l=abs(buf[i++]);
900 if (val_l>peak_l) {
901 peak_l=val_l;
902 wd->ind_peak_l=i<<1;
903 }
904 val_r=abs(buf[i++]);
905 if (val_r>peak_r) {
906 peak_r=val_r;
907 wd->ind_peak_r=i<<1;
908 }
909 }
910 } /* switch (wd->channels) */
911 break;
912 } /* case 16 */
913 break;
914 } /* switch (wd->res) */
915 } else { /* if (wd->inmem) */
916 Audio_File af;
917 int toread,r_index=0;
918
919 wd2af(wd,&af);
920 af_rewind(af);
921 af_seek(af,begin,SEEK_CUR);
922
923 buffer=(char*)MD->mg->fbuf;
924
925 i=length;
926 while (i>0) {
927 if (i>MAXUSHORT) toread=MAXUSHORT;
928 else toread=i;
929 toread=af_read(af,buffer,toread);
930 if (toread<=0) break;
931
932 switch (wd->res) {
933 case 8: {
934 char val_l,val_r;
935
936 switch (wd->channels) {
937 case 1:
938 for (i=0;i<MAXUSHORT;i++) {
939 val_l=buffer[i]^0x80;
940 if (abs(val_l)>peak_l) {
941 peak_l=abs(val_l);
942 wd->ind_peak_l=i+(r_index*MAXUSHORT);
943 }
944 }
945 break;
946 case 2:
947 for (i=0;i<MAXUSHORT;) {
948 val_l=buffer[i++]^0x80;
949 if (abs(val_l)>peak_l) {
950 peak_l=abs(val_l);
951 wd->ind_peak_l=i+(r_index*MAXUSHORT);
952 }
953 val_r=buffer[i++]^0x80;
954 if (abs(val_r)>peak_r) {
955 peak_r=abs(val_r);
956 wd->ind_peak_r=i+(r_index*MAXUSHORT);
957 }
958 }
959 break;
960 } /* switch (wd->channels) */
961 break;
962 } /* case 8 */
963 case 16: {
964 short *buf=(short*) buffer,val_l,val_r;
965
966 switch (wd->channels) {
967 case 1:
968 for (i=0;i<MAXUSHORT/2;i++) {
969 val_l=abs(buf[i]);
970 if (val_l>peak_l) {
971 peak_l=val_l;
972 wd->ind_peak_l=(i<<1)+(r_index*MAXUSHORT);
973 }
974 }
975 break;
976 case 2:
977 for (i=0;i<MAXUSHORT/2;) {
978 val_l=abs(buf[i++]);
979 if (val_l>peak_l) {
980 peak_l=val_l;
981 wd->ind_peak_l=(i<<1)+(r_index*MAXUSHORT);
982 }
983 val_r=abs(buf[i++]);
984 if (val_r>peak_r) {
985 peak_r=val_r;
986 wd->ind_peak_r=(i<<1)+(r_index*MAXUSHORT);
987 }
988 }
989 } /* switch (wd->channels) */
990 break;
991 } /* case 16 */
992 break;
993 } /* switch (wd->res) */
994 r_index++;
995 } /* while (i>0) */
996 }
997 wd->ind_peak_r+=begin;
998 wd->ind_peak_l+=begin;
999 wd->peak_l=peak_l;
1000 wd->peak_r=peak_r;
1001 }
1002
1003
1004 /* merge buf2 into buf1, buf1 must be bigger than buf2 */
merge_8(char * buf1,char * buf2,int length,float factor1,float factor2)1005 void merge_8(char *buf1,char *buf2,int length,float factor1,float factor2)
1006 {
1007 char val1,val2;
1008 int i;
1009
1010 if (factor1==factor2) {
1011 for (i=0;i<length;i++) {
1012 val1=buf1[i]^0x80;
1013 val2=buf2[i]^0x80;
1014 val1=(char) (val1*factor1);
1015 val2=(char) (val2*factor1);
1016 buf1[i]=(val1 + val2)^0x80;
1017 }
1018 } else {
1019 for (i=0;i<length;) {
1020 val1=buf1[i]^0x80;
1021 val2=buf2[i]^0x80;
1022 val1=(char) (val1*factor1);
1023 val2=(char) (val2*factor1);
1024 buf1[i]=(val1 + val2)^0x80;
1025 i++;
1026 val1=buf1[i]^0x80;
1027 val2=buf2[i]^0x80;
1028 val1=(char) (val1*factor2);
1029 val2=(char) (val2*factor2);
1030 buf1[i]=(val1 + val2)^0x80;
1031 i++;
1032 }
1033 }
1034 }
1035
1036 /* merge buf2 into buf1, buf1 must be bigger than buf2 */
merge_16(short * buf1,short * buf2,int length,float factor1,float factor2)1037 void merge_16(short *buf1,short *buf2,int length,float factor1,float factor2)
1038 {
1039 short val1,val2;
1040 int i;
1041
1042 if (factor1==factor2) {
1043 for (i=0;i<length;i++) {
1044 val1=buf1[i]*factor1;
1045 val2=buf2[i]*factor1;
1046 buf1[i]=val1 + val2;
1047 }
1048 } else {
1049 for (i=0;i<length;) {
1050 val1=buf1[i]*factor1;
1051 val2=buf2[i]*factor1;
1052 buf1[i]=val1 + val2;
1053 i++;
1054 val1=buf1[i]*factor2;
1055 val2=buf2[i]*factor2;
1056 buf1[i]=val1 + val2;
1057 i++;
1058 }
1059 }
1060 }
1061