1 /*
2 ********************************************************************************
3 File: process.c
4
5 Tab size: 4
6 Max line length: 80
7 Programmer: Volker Kuhlmann
8
9
10 wav2cdr 2.3.4 Copyright (C) 1997, 1998, 1999, 2000, 2006 Volker Kuhlmann
11 This program is free software under the terms of the GNU General Public License
12 version 2 (or later, at your option).
13 See the file COPYING for details about license terms and warranty.
14 <VolkerKuhlmann@gmx.de>
15
16
17 DESCRIPTION:
18
19 This module handles all number crunching.
20 Operations are performed on blocks of data.
21 Functions in here are stand-alone and do not depend on anything else in wav2cdr
22 (except for perhaps wav2cdr.h).
23
24 As the amount of data returned from processing does not have to be the same as
25 the amount which goes in, process_t has a variable for the number of bytes
26 which go out. This is not necessarily set by all functions, but it is by those
27 which return a differing amount, and by process_sector(). Functions may write to
28 the buffer area provided, but not return any data.
29
30 These functions all take a buffer pointer and a pointer to an initialised
31 processing info struct (process_t) as arguments. Not all values in the info
32 struct will be used by all functions.
33
34 Functions process_swap_... will take care of the byte order in the input data,
35 and produce the requested byte ordering in the output data.
36 Functions process_... assume the byte ordering of the input data is that of the
37 local machine; the byte ordering is unchanged on return.
38
39
40 CONDITIONALS:
41 see wav2cdr.c
42
43
44 HISTORY:
45 see wav2cdr.c
46
47 ********************************************************************************
48 */
49
50
51
52 #include <stddef.h>
53 #include <limits.h>
54 #include <stdlib.h>
55 #include <math.h>
56 #include <assert.h>
57 #include <string.h>
58 #ifdef DEBUG
59 #include <stdio.h>
60 #endif
61
62 #include "wav2cdr.h"
63 #include "chelp.h"
64 #ifdef VKCLIB
65 #include "vkclib.h"
66 #endif
67
68
69
70 /* local function prototypes */
71 static BOOL is_silent_sector (void * buf, const process_t *pinfo);
72
73
74
75 /*
76 Saturation of numbers.
77 Take a long and see whether it fits in a short, if not set to
78 short min/max.
79 Expression, implemented as macro because it's mission critical :-)
80 (Although we could play around with inlining.)
81 In: long signed int
82 Out: ---
83 Return: short signed int
84 */
85 #define SATURATE_SSHORT(argshort) (\
86 ((argshort) > (signed long) SHRT_MAX) ? \
87 SHRT_MAX \
88 : ((argshort) < (signed long) SHRT_MIN) ?\
89 SHRT_MIN \
90 : (signed short) (argshort) \
91 )
92
93
94
95 /*
96 Swap consecutive bytes with each other.
97 The last byte will be ignored if the number of bytes in the buffer is not
98 even (unless assert is used).
99 This will work with any byte order (in and out)... (of course)
100 In: buffer, buffer size
101 Out: correct byte order
102 Return: ---
103 */
process_swap_bytes(void * buf,process_t * pinfo)104 void process_swap_bytes (void * buf, process_t *pinfo)
105 {
106 size_t i;
107
108 #ifndef NO_ASSERTMANY
109 assert ((pinfo->n_in BITAND 0x1) == 0);
110 #endif
111
112 for (i = 0; i < (pinfo->n_in / 2); i++)
113 SWAP2BYTES (AS_S16(buf)[i]);
114
115 } /* process_swap_bytes() */
116
117
118
119 /*
120 Swap consecutive 16-bit values.
121 The last up to 3 bytes will be ignored if the number of bytes in the buffer
122 is not even (unless assert is used).
123 This will work with any byte order (in and out).
124 In: buffer, buffer size
125 Out: correct byte order
126 Return: ---
127 */
process_swap_words(void * buf,process_t * pinfo)128 void process_swap_words (void * buf, process_t *pinfo)
129 {
130 size_t i;
131
132 #ifndef NO_ASSERTMANY
133 assert ((pinfo->n_in BITAND 0x3) == 0);
134 #endif
135
136 for (i = 0; i < (pinfo->n_in / 4); i++)
137 SWAP2WORDS (AS_S32(buf)[i]);
138
139 } /* process_swap_words() */
140
141
142
143 /*
144 Ensure byte order is that of local machine. Swap if necessary.
145 Assuming 16-bit values.
146 The last byte will be ignored if the number of bytes in the buffer is not
147 even (unless assert is used).
148 In: buffer, relevant fields in *pinfo
149 Out: correct byte order
150 Return: ---
151 */
process_swap_tolocal(void * buf,process_t * pinfo)152 void process_swap_tolocal (void * buf, process_t *pinfo)
153 {
154 size_t i;
155
156 #ifndef NO_ASSERTMANY
157 assert ((pinfo->n_in BITAND 0x1) == 0);
158 #endif
159
160 if (pinfo->from_little != pinfo->little_host)
161 for (i = 0; i < (pinfo->n_in / 2); i++)
162 SWAP2BYTES (AS_S16(buf)[i]);
163
164 } /* process_swap_tolocal() */
165
166
167
168 /*
169 Ensure byte order is that of the target. Swap if necessary.
170 Assuming 16-bit values.
171 The last byte will be ignored if the number of bytes in the buffer is not
172 even (unless assert is used).
173 In: buffer, relevant fields in *pinfo
174 Out: correct byte order
175 Return: ---
176 */
process_swap_totarget(void * buf,process_t * pinfo)177 void process_swap_totarget (void * buf, process_t *pinfo)
178 {
179 size_t i;
180
181 #ifndef NO_ASSERTMANY
182 assert ((pinfo->n_in BITAND 0x1) == 0);
183 #endif
184
185 if (pinfo->to_little != pinfo->little_host)
186 for (i = 0; i < (pinfo->n_in / 2); i++)
187 SWAP2BYTES (AS_S16(buf)[i]);
188
189 } /* process_swap_totarget() */
190
191
192
193 /*
194 Convert stereo samples to mono. Result is the average of left and right
195 channel.
196 The result has only half as many values! Stored at the start of the buffer.
197 The input byte order must be that of the local machine.
198 In: buffer, relevant fields in *pinfo
199 Out: correct byte order
200 Return: ---
201 */
process_tomono(void * buf,process_t * pinfo)202 void process_tomono (void * buf, process_t *pinfo)
203 {
204 size_t i;
205
206 #ifndef NO_ASSERTMANY
207 assert ((pinfo->n_in BITAND 0x3) == 0);
208 #endif
209
210 for (i = 0; i < (pinfo->n_in / 4); i++)
211 AS_S16(buf)[i] = ((SINT32) AS_S16(buf)[2*i]
212 + (SINT32) AS_S16(buf)[2*i + 1]) / 2;
213
214 pinfo->n_returned = pinfo->n_in / 2;
215
216 } /* process_tomono() */
217
218
219
220 /*
221 Convert mono samples to stereo. The value for the second channel is that of
222 the first.
223 The given buffer size is filled up by repeating the values in the first half
224 of the buffer! (The first value is repeated once, then the second, ...)
225 This will work with any byte order (in and out).
226 In: buffer, relevant fields in *pinfo
227 Out: correct byte order
228 Return: ---
229 */
process_tostereo(void * buf,process_t * pinfo)230 void process_tostereo (void * buf, process_t *pinfo)
231 {
232 size_t i;
233
234 #ifndef NO_ASSERTMANY
235 assert ((pinfo->n_in BITAND 0x3) == 0);
236 #endif
237
238 i = pinfo->n_in / 4; /* this time we need to go downwards!!! */
239 pinfo->n_returned = 0;
240 if (i == 0) return;
241
242 REPEAT
243 --i;
244 AS_S16(buf)[2*i + 1] = AS_S16(buf)[i];
245 AS_S16(buf)[2*i] = AS_S16(buf)[i];
246 UNTIL (i == 0);
247
248 pinfo->n_returned = pinfo->n_in * 2;
249
250 } /* process_tostereo() */
251
252
253
254 /*
255 Convert stereo samples to mono, and back to stereo.
256 Result is the average of left and right channel, and both channels have the
257 same value.
258 The input byte order must be that of the local machine.
259 In: buffer, relevant fields in *pinfo
260 Out: the same (average) value for both channels
261 Return: ---
262 */
process_tomonostereo(void * buf,process_t * pinfo)263 void process_tomonostereo (void * buf, process_t *pinfo)
264 {
265 size_t i;
266
267 /* must assert this! */
268 assert ((pinfo->n_in BITAND 0x3) == 0);
269
270 for (i = 0; i < (pinfo->n_in / 2); i+=2)
271 AS_S16(buf)[i]
272 = AS_S16(buf)[i + 1]
273 = ((SINT32) AS_S16(buf)[i]
274 + (SINT32) AS_S16(buf)[i + 1]) / 2;
275
276 } /* process_tomonostereo() */
277
278
279
280 /*
281 Take a number of 16-bit ints, and scale them with integer arithmetic.
282 The results will not overflow but SATURATE_SSHORT.
283 The numbers can be in either byte order before and after processing, and the
284 algorithm will work on both big and little endian machines.
285 The last byte will be ignored if the number of bytes in the buffer is not
286 even (unless assert is used).
287 In: buffer, scale factor, byte order of host / before / after
288 Out: process numbers
289 Return: ---
290 */
process_swap_iscale(void * buf,process_t * pinfo)291 void process_swap_iscale (void * buf, process_t *pinfo)
292 {
293 signed long si32;
294 size_t i;
295
296 #ifndef NO_ASSERTMANY
297 assert ((pinfo->n_in BITAND 0x1) == 0);
298 #endif
299
300 if ((pinfo->from_little != 0) BITXOR (pinfo->little_host != 0))
301 /* input != host: swap first */
302 if ((pinfo->to_little != 0) BITXOR (pinfo->little_host != 0))
303 /* Swap -> Process -> Swap */
304 for (i = 0; i < (pinfo->n_in / 2); i++) {
305 si32 = (signed long) pinfo->iscale
306 * (signed short) BYTES2SWAPPED (AS_S16(buf)[i]);
307 si32 /= 100L;
308 AS_S16(buf)[i] = SATURATE_SSHORT (si32);
309 SWAP2BYTES (AS_S16(buf)[i]);
310 }
311 else
312 /* Swap -> Process */
313 for (i = 0; i < (pinfo->n_in / 2); i++) {
314 si32 = (signed long) pinfo->iscale
315 * (signed short) BYTES2SWAPPED (AS_S16(buf)[i]);
316 si32 /= 100L;
317 AS_S16(buf)[i] = SATURATE_SSHORT (si32);
318 }
319 else
320 if ((pinfo->to_little != 0) BITXOR (pinfo->little_host != 0))
321 /* Process -> Swap */
322 for (i = 0; i < (pinfo->n_in / 2); i++) {
323 si32 = (signed long) pinfo->iscale
324 * AS_S16(buf)[i];
325 si32 /= 100L;
326 AS_S16(buf)[i] = SATURATE_SSHORT (si32);
327 SWAP2BYTES (AS_S16(buf)[i]);
328 }
329 else
330 /* Process */
331 for (i = 0; i < (pinfo->n_in / 2); i++) {
332 si32 = (signed long) pinfo->iscale
333 * AS_S16(buf)[i];
334 si32 /= 100L;
335 AS_S16(buf)[i] = SATURATE_SSHORT (si32);
336 }
337 } /* process_swap_iscale() */
338
339
340
341 /*
342 Take a number of 16-bit ints, and scale them with floating point arithmetic.
343 The results will not overflow but saturate (16 bits).
344 The numbers can be in either byte order before and after processing.
345 The algorithm will work on both big and little endian machines.
346 The last byte will be ignored if the number of bytes in the buffer is not
347 even (unless assert is used).
348 In: buffer, scale factor, byte order of host / before / after
349 Out: process numbers
350 Return: ---
351 */
process_swap_fscale(void * buf,process_t * pinfo)352 void process_swap_fscale (void * buf, process_t *pinfo)
353 {
354 signed long int si32;
355 size_t i;
356
357 #ifndef NO_ASSERTMANY
358 assert ((pinfo->n_in BITAND 0x1) == 0);
359 #endif
360
361 if ((pinfo->from_little != 0) BITXOR (pinfo->little_host != 0))
362 /* input != host: swap first */
363 if ((pinfo->to_little != 0) BITXOR (pinfo->little_host != 0))
364 /* Swap -> Process -> Swap */
365 for (i = 0; i < (pinfo->n_in / 2); i++) {
366 si32 = pinfo->fscale
367 * (signed short) BYTES2SWAPPED (AS_S16(buf)[i]);
368 AS_S16(buf)[i] = SATURATE_SSHORT (si32);
369 SWAP2BYTES (AS_S16(buf)[i]);
370 }
371 else
372 /* Swap -> Process */
373 for (i = 0; i < (pinfo->n_in / 2); i++) {
374 si32 = pinfo->fscale
375 * (signed short) BYTES2SWAPPED (AS_S16(buf)[i]);
376 AS_S16(buf)[i] = SATURATE_SSHORT (si32);
377 }
378 else
379 if ((pinfo->to_little != 0) BITXOR (pinfo->little_host != 0))
380 /* Process -> Swap */
381 for (i = 0; i < (pinfo->n_in / 2); i++) {
382 si32 = pinfo->fscale * AS_S16(buf)[i];
383 AS_S16(buf)[i] = SATURATE_SSHORT (si32);
384 SWAP2BYTES (AS_S16(buf)[i]);
385 }
386 else
387 /* Process */
388 for (i = 0; i < (pinfo->n_in / 2); i++) {
389 si32 = pinfo->fscale * AS_S16(buf)[i];
390 AS_S16(buf)[i] = SATURATE_SSHORT (si32);
391 }
392 } /* process_swap_fscale() */
393
394
395
396 /*
397 Take a number of 16-bit ints and swap the bytes if input and output byte
398 orders are different.
399 The last byte will be ignored if the number of bytes in the buffer is not
400 even (unless assert is used).
401 In: buffer
402 Out: swapped bytes
403 Return: ---
404 */
process_swap_noscale(void * buf,process_t * pinfo)405 void process_swap_noscale (void * buf, process_t *pinfo)
406 {
407 size_t i;
408
409 #ifndef NO_ASSERTMANY
410 assert ((pinfo->n_in BITAND 0x1) == 0);
411 #endif
412
413 if ((pinfo->from_little != 0) BITXOR (pinfo->to_little != 0))
414 for (i = 0; i < (pinfo->n_in / 2); i++)
415 SWAP2BYTES (AS_S16(buf)[i]);
416
417 } /* process_swap_noscale() */
418
419
420
421 /*
422 */
process_fading(void * buf,process_t * pinfo)423 void process_fading (void * buf, process_t *pinfo)
424 {
425 float fade;
426 size_t i;
427 static cdseccount_t fi_len = 0, fo_len = 0;
428
429 #ifndef NO_ASSERTMANY
430 assert ((pinfo->n_in BITAND 0x1) == 0);
431 #endif
432
433 /* initialise when fading starts */
434 if (fi_len == 0 AND pinfo->fadein != 0) {
435 fi_len = pinfo->fadein + 1;
436 }
437 if (fo_len == 0 AND pinfo->fadeout != 0) {
438 fo_len = pinfo->fadeout + 1;
439 }
440 DBGPRINTF2 ("fading in %li, out %li\n", fi_len, fo_len);
441
442 /* fade-in and fade-out, possibly combined */
443 if (fi_len > 0) {
444 if (fo_len > 0) {
445 fade = (((float) (fi_len - pinfo->fadein)) / ((float) fi_len))
446 * (((float) pinfo->fadeout) / ((float) fo_len));
447 if (--pinfo->fadein == 0) fi_len = 0;
448 if (--pinfo->fadeout == 0) fo_len = 0;
449 } else {
450 fade = ((float) (fi_len - pinfo->fadein)) / ((float) fi_len);
451 if (--pinfo->fadein == 0) fi_len = 0;
452 }
453 } else {
454 if (fo_len > 0) {
455 fade = ((float) pinfo->fadeout) / ((float) fo_len);
456 if (--pinfo->fadeout == 0) fo_len = 0;
457 } else {
458 return; /* both fi_len and fo_len are 0, no fading */
459 }
460 }
461 DBGPRINTF1 ("fading scale: %2.5f\n", fade);
462
463 for (i = 0; i < (pinfo->n_in / 2); i++)
464 (AS_S16(buf)[i]) = (SINT16) (((float) (AS_S16(buf)[i])) * fade);
465
466 } /* process_fading() */
467
468
469
470 /*
471 Decide whether this sector is silent
472 In: buffer
473 Out: buffer content '\0'-terminated
474 Return: TRUE if sector is silent
475 */
is_silent_sector(void * buf,const process_t * pinfo)476 static BOOL is_silent_sector (void * buf, const process_t *pinfo)
477 {
478 #ifdef DEBUG
479 unsigned long sumabs = 0L; /* sum of abs(x) */
480 UINT16 avgabs;
481 #endif
482 signed long sum = 0L; /* sum of x */
483 SINT16 avg;
484 unsigned long sumdcpk = 0L; /* sum of abs(x - avg) */
485 UINT16 avgdcpk;
486
487 size_t i;
488 #ifdef DEBUG
489 static size_t secnum = 0;
490 #endif
491 BOOL is_silent;
492
493 #define ABS(arg) (((arg) < 0) ? (-(arg)) : (arg))
494 #define BUF(buf) ((char *) (buf) + strlen (buf))
495
496 if ((pinfo->n_in / 2) == 0) {
497 * (char *) buf = '\0';
498 return TRUE; /* nothing to do... */
499 }
500
501 /* fast case for threshold == 0: because the silence value of this sector
502 can not be less than zero, we treat this as "this is a silent sector if
503 all samples are 0" */
504 if (pinfo->silence_thresh == 0) {
505 for (i = 0; i < (pinfo->n_in / 2); i++)
506 if (AS_S16(buf)[i] != 0)
507 return FALSE;
508 return TRUE;
509 }
510
511 /* calculate averages: (sum(x)/N), and (sum(abs(x))/N)
512 */
513 for (i = 0; i < (pinfo->n_in / 2); i++) {
514 #ifdef DEBUG
515 #ifdef MSDOS_BC
516 sumabs += ABS ((signed long) AS_S16(buf)[i]);
517 #else
518 sumabs += ABS (AS_S16(buf)[i]);
519 #endif
520 #endif
521 sum += AS_S16(buf)[i];
522 }
523 #ifdef DEBUG
524 avgabs = sumabs / (unsigned long) (pinfo->n_in / 2);
525 #endif
526 avg = sum / (signed long) (pinfo->n_in / 2); /* cast here is necessary
527 or division stuffs up (signed/unsigned)) */
528 /* calculate average of the difference between each value and the average
529 of all values
530 */
531 for (i = 0; i < (pinfo->n_in / 2); i++) {
532 #ifdef MSDOS_BC
533 sumdcpk += ABS (avg - (signed long) AS_S16(buf)[i]);
534 #else
535 sumdcpk += ABS (avg - AS_S16(buf)[i]);
536 #endif
537 }
538 avgdcpk = sumdcpk / (unsigned long) (pinfo->n_in / 2);
539
540 /* decide whether this is a "silent" sector:
541 This is somewhat tricky. I have seen sectors with a very high DC offset
542 in the signal (crappy digitizer hardware?), the DC offset equals about
543 the absolutes average (sum(abs(x))/N) in non-quiet sectors.
544 Let's subtract the DC offset from the absolutes average and see how far
545 that goes. Note very: fails dismally in sectors with only positive
546 numbers! but then that would be a rather weird audio signal.
547 Let's try the difference between
548 */
549 #if 0
550 /* average of the sum of absolute values: sum(abs(x))/N
551 Fails if DC offsets are present. */
552 is_silent = (avgabs < pinfo->silence_thresh);
553 #elif 0
554 /* absolute of the difference between average (which is the DC
555 offset), and the above: abs(sum(abs(x))/N - sum(x)/N)
556 Fails dismally in sectors with only positive numbers!
557 but then that would be a rather weird audio signal */
558 is_silent = (ABS ((signed long) avgabs - (signed long) avg)
559 < pinfo->silence_thresh);
560 /* without the casts, cond is always false for Borland C 3.1 */
561 #else
562 /* avg := sum(x)/N; sum(abs(x - avg)) */
563 is_silent = (avgdcpk < pinfo->silence_thresh);
564 #endif
565
566 * (char *) buf = '\0';
567 #ifdef DEBUG
568 sprintf (buf,
569 " %li: av %6i, +av %5i, d %3i, avdc %5i"
570 ", s%7li, +s %6li, +sdc %5li, n %i, =%c\n",
571 (long) secnum++,
572 avg, avgabs, avgabs - avg, avgdcpk,
573 sum, sumabs, sumdcpk, pinfo->n_in / 2, is_silent ? 'Y' : 'N');
574 /* note silence_info() scans for this = sign */
575 #endif
576 /* verbose output of how silent this sector is */
577 if (pinfo->silence_val) sprintf (BUF(buf), "S%hu ", avgdcpk);
578
579 return is_silent;
580 #undef BUF
581 } /* is_silent_sector() */
582
583
584
585 /*
586 Return cut numbers according to the silent intervals in the input.
587 These cut numbers can be fed back into --cut, then every second track
588 generated (even numbers) contains a silent interval.
589 The silence delay period is part of the signal interval, not the silence
590 interval. If the silent interval between two signal intervals is less than
591 (2 * silence delay), the silent part at the start of the second signal
592 period will be shortened.
593 Conditional HARDON_CUT: if set, the silence delay period is counted to the
594 silent interval, not the signal interval.
595 The input byte order must be that of the local machine.
596 This function will produce incorrect results if called with buffer sizes not
597 equal to CDAUDIOSECTORSIZE (unless the call is the last).
598 In: buffer
599 Out: cut numbers
600 Return: ---
601 */
process_silencecuts(void * buf,process_t * pinfo)602 void process_silencecuts (void * buf, process_t *pinfo)
603 {
604 static cdseccount_t secnum = 0; /* counter of sectors */
605 static BOOL sigstarted = FALSE; /* a non-silent interval has started */
606 static cdseccount_t sigstart; /* start of signal (i.e. non-silence) */
607 static cdseccount_t
608 silentsectors = 0; /* silent sectors so far, this interval */
609 static cdseccount_t silencestart; /* first sector of silence, this interval */
610 #ifndef HARDON_CUT
611 static cdseccount_t lastsigend = 0;
612 #endif
613
614 #ifdef DEBUG
615 if (secnum == 0) {
616 DBGPRINTF1 ("cut: threshold: %i\n", pinfo->silence_thresh);
617 DBGPRINTF1 ("cut: delay: %i\n", pinfo->silence_delay);
618 #ifdef HARDON_CUT
619 DBGPRINTF0 ("cut: HARD\n");
620 #endif
621 }
622 /* in case is_silent_sector() wrote something: */
623 #define BUF ((char *) buf + strlen (buf))
624 #else
625 /*#define BUF buf*/
626 #define BUF ((char *) buf + strlen (buf))
627 #endif
628
629 /* is_silent_sector() will put a '\0' into the buffer returned */
630 if (is_silent_sector (buf, pinfo)) {
631 if ((pinfo->n_in / 2) > 0U) {
632 if (silentsectors++ == 0U)
633 silencestart = secnum;
634 if (silentsectors == pinfo->silence_delay AND sigstarted) {
635 #ifdef HARDON_CUT
636 DBGPRINTF2 ("cut: signal: %ldC,%ldC\n", sigstart, silencestart);
637 sprintf (BUF, "%ldC %ldC\n", sigstart, silencestart);
638 #else
639 DBGPRINTF2 ("cut: signal: %ldC,%ldC\n", sigstart, secnum + 1U);
640 sprintf (BUF, "%ldC %ldC\n", sigstart, secnum + 1U);
641 lastsigend = secnum + 1U;
642 #endif
643 sigstarted = FALSE;
644 }
645 }
646 } else {
647 if (NOT sigstarted) {
648 #ifdef HARDON_CUT
649 sigstart = secnum;
650 if (silentsectors < pinfo->silence_delay)
651 sigstart -= silentsectors;
652 #else
653 sigstart = secnum - (silentsectors < pinfo->silence_delay ?
654 silentsectors : pinfo->silence_delay);
655 if (sigstart < lastsigend)
656 sigstart = lastsigend;
657 #endif
658 sigstarted = TRUE;
659 }
660 silentsectors = 0U;
661 }
662
663 if (pinfo->last AND sigstarted) {
664 DBGPRINTF2 ("cut: signal: %ldC,%ldC\n", sigstart, secnum);
665 sprintf (BUF, "%ldC %ldC\n", sigstart, secnum);
666 }
667
668 #undef BUF
669 secnum++;
670 pinfo->n_returned = strlen (buf);
671 /* do not include \0 in number of returned bytes because it is more
672 hassle than it's worth afterwards; buffer will be large enough
673 to hold one more byte */
674 } /* process_silencecuts() */
675
676
677
678 /*
679 Process one block of data. This will usually be one audio sector, but it can
680 be any size divisable by 4.
681 Processing depends on the setting of the variables in struct *pinfo.
682 Byte swapping and scaling is handled here.
683 Runs on big and little endian machines.
684 Handles little and big input data, generates little or big output.
685 Some care was taken to make things more efficient depending on the
686 processing to be done.
687 In: buffer, processing info
688 Out: buffer contents changed
689 Return: ---
690 */
process_sector(void * buf,process_t * pinfo)691 void process_sector (void *buf, process_t *pinfo)
692 {
693 BOOL order;
694
695 /* always assert here */
696 assert ((pinfo->n_in BITAND 0x3) == 0);
697
698 /* preset bytes returned to bytes in; make sure those functions which do
699 not return the same amount update n_returned */
700 pinfo->n_returned = pinfo->n_in;
701
702 /* do any byte swapping and scaling if necessary */
703 if (pinfo->iscale != 100)
704 process_swap_iscale (buf, pinfo);
705 else if (pinfo->fscale != 1.0) /* is a precise float comparison ok here? */
706 process_swap_fscale (buf, pinfo);
707 else
708 process_swap_noscale (buf, pinfo);
709 /* now byte order of data is that of target audio format! */
710
711 /* More processing with byte swapping to do? */
712 if (pinfo->monostereo != MS_NONE
713 OR pinfo->silencecuts
714 OR pinfo->fadein != 0 OR pinfo->fadeout != 0) {
715
716 /* get byte order of local architecture, swap data to it if necessary */
717 order = pinfo->from_little;
718 pinfo->from_little = pinfo->to_little;
719 process_swap_tolocal (buf, pinfo);
720
721 /* convert between mono and stereo */
722 if (pinfo->monostereo != MS_NONE) {
723 switch (pinfo->monostereo) {
724 case MS_TOMONO:
725 process_tomono (buf, pinfo); break;
726 case MS_TOSTEREO:
727 process_tostereo (buf, pinfo); break;
728 case MS_TOMONOSTEREO:
729 process_tomonostereo (buf, pinfo); break;
730 default:
731 ; /* tough luck */
732 }
733 }
734
735 /* find silent intervals, and output cut numbers accordingly */
736 if (pinfo->silencecuts)
737 process_silencecuts (buf, pinfo);
738
739 /* process fading */
740 if (pinfo->fadein != 0 OR pinfo->fadeout != 0)
741 process_fading (buf, pinfo);
742
743 /* swap data back to byte order of target audio format, if necessary */
744 process_swap_totarget (buf, pinfo);
745 pinfo->from_little = order;
746 }
747
748 /* swap pairs of words in buffer */
749 if (pinfo->swap_channels)
750 process_swap_words (buf, pinfo);
751
752 } /* process_sector() */
753
754
755
756 /* EOF process.c */
757 /******************************************************************************/
758