2
* CopyPolicy: GNU Public License 2 applies
3
* Copyright (C) by Monty (xiphmont@mit.edu)
5
* Statistic code and cache management for overlap settings
13
#include "cdda_paranoia.h"
17
/**** Internal cache management *****************************************/
19
void paranoia_resetcache(cdrom_paranoia *p){
20
c_block *c=c_first(p);
35
void paranoia_resetall(cdrom_paranoia *p){
36
p->root.returnedlimit=0;
41
i_cblock_destructor(p->root.vector);
45
paranoia_resetcache(p);
48
void i_paranoia_trim(cdrom_paranoia *p,long beginword,long endword){
49
root_block *root=&(p->root);
50
if(root->vector!=NULL){
51
long target=beginword-MAX_SECTOR_OVERLAP*CD_FRAMEWORDS;
52
long rbegin=cb(root->vector);
53
long rend=ce(root->vector);
58
if(rbegin+MAX_SECTOR_OVERLAP*CD_FRAMEWORDS<beginword){
59
if(target+MIN_WORDS_OVERLAP>rend)
63
long offset=target-rbegin;
64
c_removef(root->vector,offset);
69
c_block *c=c_first(p);
71
c_block *next=c_next(c);
72
if(ce(c)<beginword-MAX_SECTOR_OVERLAP*CD_FRAMEWORDS)
83
i_cblock_destructor(root->vector);
85
root->returnedlimit=-1;
90
/**** Statistical and heuristic[al? :-] management ************************/
92
void offset_adjust_settings(cdrom_paranoia *p, void(*callback)(long,int)){
93
if(p->stage2.offpoints>=10){
94
/* drift: look at the average offset value. If it's over one
95
sector, frob it. We just want a little hysteresis [sp?]*/
96
long av=(p->stage2.offpoints?p->stage2.offaccum/p->stage2.offpoints:0);
98
if(abs(av)>p->dynoverlap/4){
99
av=(av/MIN_SECTOR_EPSILON)*MIN_SECTOR_EPSILON;
101
if(callback)(*callback)(ce(p->root.vector),PARANOIA_CB_DRIFT);
104
/* Adjust all the values in the cache otherwise we get a
105
(potentially unstable) feedback loop */
107
c_block *c=c_first(p);
108
v_fragment *v=v_first(p);
111
/* safeguard beginning bounds case with a hammer */
112
if(fb(v)<av || cb(v->one)<av){
120
long adj=min(av,cb(c));
126
p->stage2.offaccum=0;
129
p->stage2.offpoints=0;
130
p->stage2.newpoints=0;
135
if(p->stage1.offpoints>=10){
136
/* dynoverlap: we arbitrarily set it to 4x the running difference
137
value, unless min/max are more */
139
p->dynoverlap=(p->stage1.offpoints?p->stage1.offdiff/
140
p->stage1.offpoints*3:CD_FRAMEWORDS);
142
if(p->dynoverlap<-p->stage1.offmin*1.5)
143
p->dynoverlap=-p->stage1.offmin*1.5;
145
if(p->dynoverlap<p->stage1.offmax*1.5)
146
p->dynoverlap=p->stage1.offmax*1.5;
148
if(p->dynoverlap<MIN_SECTOR_EPSILON)p->dynoverlap=MIN_SECTOR_EPSILON;
149
if(p->dynoverlap>MAX_SECTOR_OVERLAP*CD_FRAMEWORDS)
150
p->dynoverlap=MAX_SECTOR_OVERLAP*CD_FRAMEWORDS;
152
if(callback)(*callback)(p->dynoverlap,PARANOIA_CB_OVERLAP);
154
if(p->stage1.offpoints>600){ /* bit of a bug; this routine is
155
called too often due to the overlap
156
mesh alg we use in stage 1 */
157
p->stage1.offpoints/=1.2;
158
p->stage1.offaccum/=1.2;
159
p->stage1.offdiff/=1.2;
163
p->stage1.newpoints=0;
167
void offset_add_value(cdrom_paranoia *p,offsets *o,long value,
168
void(*callback)(long,int)){
169
if(o->offpoints!=-1){
171
o->offdiff+=abs(value);
175
if(value<o->offmin)o->offmin=value;
176
if(value>o->offmax)o->offmax=value;
178
if(o->newpoints>=10)offset_adjust_settings(p,callback);