2 * This file has been modified for the cdrkit suite.
4 * The behaviour and appearence of the program code below can differ to a major
5 * extent from the version distributed by the original author(s).
7 * For details, see Changelog file distributed with the cdrkit package. If you
8 * received this file from another source then ask the distributing person for
9 * a log of modifications.
13 /* @(#)gap.c 1.12 04/02/18 J. Schilling from cdparanoia-III-alpha9.8 */
15 * Modifications to make the code portable Copyright (c) 2002 J. Schilling
18 * CopyPolicy: GNU Public License 2 applies
19 * Copyright (C) by Monty (xiphmont@mit.edu)
21 * Gapa analysis support code for paranoia
30 #include "cdda_paranoia.h"
33 long i_paranoia_overlap_r(Int16_t * buffA, Int16_t * buffB, long offsetA,
35 long i_paranoia_overlap_f(Int16_t * buffA, Int16_t * buffB, long offsetA,
36 long offsetB, long sizeA, long sizeB);
37 int i_stutter_or_gap(Int16_t * A, Int16_t * B, long offA, long offB, long gap);
38 void i_analyze_rift_f(Int16_t * A, Int16_t * B,
39 long sizeA, long sizeB,
40 long aoffset, long boffset,
41 long *matchA, long *matchB, long *matchC);
42 void i_analyze_rift_r(Int16_t * A, Int16_t * B,
43 long sizeA, long sizeB,
44 long aoffset, long boffset,
45 long *matchA, long *matchB, long *matchC);
46 void analyze_rift_silence_f(Int16_t * A, Int16_t * B,
47 long sizeA, long sizeB,
48 long aoffset, long boffset,
49 long *matchA, long *matchB);
54 long i_paranoia_overlap_r(Int16_t *buffA, Int16_t *buffB, long offsetA,
57 long beginA = offsetA;
58 long beginB = offsetB;
60 for (; beginA >= 0 && beginB >= 0; beginA--, beginB--)
61 if (buffA[beginA] != buffB[beginB])
66 return (offsetA - beginA);
69 long i_paranoia_overlap_f(Int16_t *buffA, Int16_t *buffB, long offsetA,
70 long offsetB, long sizeA, long sizeB)
75 for (; endA < sizeA && endB < sizeB; endA++, endB++)
76 if (buffA[endA] != buffB[endB])
79 return (endA - offsetA);
82 int i_stutter_or_gap(Int16_t *A, Int16_t *B, long offA, long offB, long gap)
92 return (memcmp(A + a1, B + b1, gap * 2));
96 * riftv is the first value into the rift -> or <-
98 void i_analyze_rift_f(Int16_t *A, Int16_t *B, long sizeA, long sizeB,
99 long aoffset, long boffset, long *matchA, long *matchB,
103 long apast = sizeA - aoffset;
104 long bpast = sizeB - boffset;
107 *matchA = 0, *matchB = 0, *matchC = 0;
110 * Look for three possible matches... (A) Ariftv->B,
111 * (B) Briftv->A and (c) AB->AB.
114 if (i < bpast) /* A */
115 if (i_paranoia_overlap_f(A, B, aoffset, boffset + i, sizeA, sizeB) >= MIN_WORDS_RIFT) {
119 if (i < apast) { /* B */
120 if (i_paranoia_overlap_f(A, B, aoffset + i, boffset, sizeA, sizeB) >= MIN_WORDS_RIFT) {
124 if (i < bpast) /* C */
125 if (i_paranoia_overlap_f(A, B, aoffset + i, boffset + i, sizeA, sizeB) >= MIN_WORDS_RIFT) {
129 } else if (i >= bpast)
134 if (*matchA == 0 && *matchB == 0 && *matchC == 0)
140 if (i_stutter_or_gap(A, B, aoffset - *matchA, boffset, *matchA))
142 *matchB = -*matchA; /* signify we need to remove n bytes */
147 if (i_stutter_or_gap(B, A, boffset - *matchB, aoffset, *matchB))
156 * riftv must be first even val of rift moving back
158 void i_analyze_rift_r(Int16_t *A, Int16_t *B, long sizeA, long sizeB,
159 long aoffset, long boffset, long *matchA, long *matchB,
163 long apast = aoffset + 1;
164 long bpast = boffset + 1;
167 *matchA = 0, *matchB = 0, *matchC = 0;
170 * Look for three possible matches... (A) Ariftv->B, (B) Briftv->A and
174 if (i < bpast) /* A */
175 if (i_paranoia_overlap_r(A, B, aoffset, boffset - i) >= MIN_WORDS_RIFT) {
179 if (i < apast) { /* B */
180 if (i_paranoia_overlap_r(A, B, aoffset - i, boffset) >= MIN_WORDS_RIFT) {
184 if (i < bpast) /* C */
185 if (i_paranoia_overlap_r(A, B, aoffset - i, boffset - i) >= MIN_WORDS_RIFT) {
189 } else if (i >= bpast)
194 if (*matchA == 0 && *matchB == 0 && *matchC == 0)
201 if (i_stutter_or_gap(A, B, aoffset + 1, boffset - *matchA + 1, *matchA))
203 *matchB = -*matchA; /* signify we need to remove n bytes */
208 if (i_stutter_or_gap(B, A, boffset + 1, aoffset - *matchB + 1, *matchB))
216 void analyze_rift_silence_f(Int16_t *A, Int16_t *B, long sizeA, long sizeB,
217 long aoffset, long boffset, long *matchA,
223 sizeA = min(sizeA, aoffset + MIN_WORDS_RIFT);
224 sizeB = min(sizeB, boffset + MIN_WORDS_RIFT);
229 while (aoffset < sizeA) {
230 if (A[aoffset] != A[aoffset - 1]) {
237 while (boffset < sizeB) {
238 if (B[boffset] != B[boffset - 1]) {