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