1 /***
2 * CopyPolicy: GNU Public License 2 applies
3 * Copyright (C) by Monty (xiphmont@mit.edu)
4 *
5 * Gapa analysis support code for paranoia
6 *
7 ***/
8
9 #include <string.h>
10 #include "p_block.h"
11 #include "cdda_paranoia.h"
12 #include "gap.h"
13
14 /**** Gap analysis code ***************************************************/
15
i_paranoia_overlap_r(int16_t * buffA,int16_t * buffB,long offsetA,long offsetB)16 long i_paranoia_overlap_r(int16_t *buffA,int16_t *buffB,
17 long offsetA, long offsetB){
18 long beginA=offsetA;
19 long beginB=offsetB;
20
21 for(;beginA>=0 && beginB>=0;beginA--,beginB--)
22 if(buffA[beginA]!=buffB[beginB])break;
23 beginA++;
24 beginB++;
25
26 return(offsetA-beginA);
27 }
28
i_paranoia_overlap_f(int16_t * buffA,int16_t * buffB,long offsetA,long offsetB,long sizeA,long sizeB)29 long i_paranoia_overlap_f(int16_t *buffA,int16_t *buffB,
30 long offsetA, long offsetB,
31 long sizeA,long sizeB){
32 long endA=offsetA;
33 long endB=offsetB;
34
35 for(;endA<sizeA && endB<sizeB;endA++,endB++)
36 if(buffA[endA]!=buffB[endB])break;
37
38 return(endA-offsetA);
39 }
40
i_stutter_or_gap(int16_t * A,int16_t * B,long offA,long offB,long gap)41 int i_stutter_or_gap(int16_t *A, int16_t *B,long offA, long offB,
42 long gap){
43 long a1=offA;
44 long b1=offB;
45
46 if(a1<0){
47 b1-=a1;
48 gap+=a1;
49 a1=0;
50 }
51
52 return(memcmp(A+a1,B+b1,gap*2));
53 }
54
55 /* riftv is the first value into the rift -> or <- */
i_analyze_rift_f(int16_t * A,int16_t * B,long sizeA,long sizeB,long aoffset,long boffset,long * matchA,long * matchB,long * matchC)56 void i_analyze_rift_f(int16_t *A,int16_t *B,
57 long sizeA, long sizeB,
58 long aoffset, long boffset,
59 long *matchA,long *matchB,long *matchC){
60
61 long apast=sizeA-aoffset;
62 long bpast=sizeB-boffset;
63 long i;
64
65 *matchA=0, *matchB=0, *matchC=0;
66
67 /* Look for three possible matches... (A) Ariftv->B, (B) Briftv->A and
68 (c) AB->AB. */
69
70 for(i=0;;i++){
71 if(i<bpast) /* A */
72 if(i_paranoia_overlap_f(A,B,aoffset,boffset+i,sizeA,sizeB)>=MIN_WORDS_RIFT){
73 *matchA=i;
74 break;
75 }
76
77 if(i<apast){ /* B */
78 if(i_paranoia_overlap_f(A,B,aoffset+i,boffset,sizeA,sizeB)>=MIN_WORDS_RIFT){
79 *matchB=i;
80 break;
81 }
82 if(i<bpast) /* C */
83 if(i_paranoia_overlap_f(A,B,aoffset+i,boffset+i,sizeA,sizeB)>=MIN_WORDS_RIFT){
84 *matchC=i;
85 break;
86 }
87 }else
88 if(i>=bpast)break;
89
90 }
91
92 if(*matchA==0 && *matchB==0 && *matchC==0)return;
93
94 if(*matchC)return;
95 if(*matchA){
96 if(i_stutter_or_gap(A,B,aoffset-*matchA,boffset,*matchA))
97 return;
98 *matchB=-*matchA; /* signify we need to remove n bytes from B */
99 *matchA=0;
100 return;
101 }else{
102 if(i_stutter_or_gap(B,A,boffset-*matchB,aoffset,*matchB))
103 return;
104 *matchA=-*matchB;
105 *matchB=0;
106 return;
107 }
108 }
109
110 /* riftv must be first even val of rift moving back */
111
i_analyze_rift_r(int16_t * A,int16_t * B,long sizeA,long sizeB,long aoffset,long boffset,long * matchA,long * matchB,long * matchC)112 void i_analyze_rift_r(int16_t *A,int16_t *B,
113 long sizeA, long sizeB,
114 long aoffset, long boffset,
115 long *matchA,long *matchB,long *matchC){
116
117 long apast=aoffset+1;
118 long bpast=boffset+1;
119 long i;
120
121 *matchA=0, *matchB=0, *matchC=0;
122
123 /* Look for three possible matches... (A) Ariftv->B, (B) Briftv->A and
124 (c) AB->AB. */
125
126 for(i=0;;i++){
127 if(i<bpast) /* A */
128 if(i_paranoia_overlap_r(A,B,aoffset,boffset-i)>=MIN_WORDS_RIFT){
129 *matchA=i;
130 break;
131 }
132 if(i<apast){ /* B */
133 if(i_paranoia_overlap_r(A,B,aoffset-i,boffset)>=MIN_WORDS_RIFT){
134 *matchB=i;
135 break;
136 }
137 if(i<bpast) /* C */
138 if(i_paranoia_overlap_r(A,B,aoffset-i,boffset-i)>=MIN_WORDS_RIFT){
139 *matchC=i;
140 break;
141 }
142 }else
143 if(i>=bpast)break;
144
145 }
146
147 if(*matchA==0 && *matchB==0 && *matchC==0)return;
148
149 if(*matchC)return;
150
151 if(*matchA){
152 if(i_stutter_or_gap(A,B,aoffset+1,boffset-*matchA+1,*matchA))
153 return;
154 *matchB=-*matchA; /* signify we need to remove n bytes from B */
155 *matchA=0;
156 return;
157 }else{
158 if(i_stutter_or_gap(B,A,boffset+1,aoffset-*matchB+1,*matchB))
159 return;
160 *matchA=-*matchB;
161 *matchB=0;
162 return;
163 }
164 }
165
analyze_rift_silence_f(int16_t * A,int16_t * B,long sizeA,long sizeB,long aoffset,long boffset,long * matchA,long * matchB)166 void analyze_rift_silence_f(int16_t *A,int16_t *B,long sizeA,long sizeB,
167 long aoffset, long boffset,
168 long *matchA, long *matchB){
169 *matchA=-1;
170 *matchB=-1;
171
172 sizeA=prna_min(sizeA,aoffset+MIN_WORDS_RIFT);
173 sizeB=prna_min(sizeB,boffset+MIN_WORDS_RIFT);
174
175 aoffset++;
176 boffset++;
177
178 while(aoffset<sizeA){
179 if(A[aoffset]!=A[aoffset-1]){
180 *matchA=0;
181 break;
182 }
183 aoffset++;
184 }
185
186 while(boffset<sizeB){
187 if(B[boffset]!=B[boffset-1]){
188 *matchB=0;
189 break;
190 }
191 boffset++;
192 }
193 }
194