Blame paranoia/gap.c

Packit Service 3e823c
/***
Packit Service 3e823c
 * CopyPolicy: GNU Public License 2 applies
Packit Service 3e823c
 * Copyright (C) by Monty (xiphmont@mit.edu)
Packit Service 3e823c
 *
Packit Service 3e823c
 * Gapa analysis support code for paranoia
Packit Service 3e823c
 *
Packit Service 3e823c
 ***/
Packit Service 3e823c
Packit Service 3e823c
#include <string.h>
Packit Service 3e823c
#include "p_block.h"
Packit Service 3e823c
#include "cdda_paranoia.h"
Packit Service 3e823c
#include "gap.h"
Packit Service 3e823c
Packit Service 3e823c
/**** Gap analysis code ***************************************************/
Packit Service 3e823c
Packit Service 3e823c
long i_paranoia_overlap_r(int16_t *buffA,int16_t *buffB,
Packit Service 3e823c
			  long offsetA, long offsetB){
Packit Service 3e823c
  long beginA=offsetA;
Packit Service 3e823c
  long beginB=offsetB;
Packit Service 3e823c
Packit Service 3e823c
  for(;beginA>=0 && beginB>=0;beginA--,beginB--)
Packit Service 3e823c
    if(buffA[beginA]!=buffB[beginB])break;
Packit Service 3e823c
  beginA++;
Packit Service 3e823c
  beginB++;
Packit Service 3e823c
  
Packit Service 3e823c
  return(offsetA-beginA);
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
long i_paranoia_overlap_f(int16_t *buffA,int16_t *buffB,
Packit Service 3e823c
			  long offsetA, long offsetB,
Packit Service 3e823c
			  long sizeA,long sizeB){
Packit Service 3e823c
  long endA=offsetA;
Packit Service 3e823c
  long endB=offsetB;
Packit Service 3e823c
  
Packit Service 3e823c
  for(;endA
Packit Service 3e823c
    if(buffA[endA]!=buffB[endB])break;
Packit Service 3e823c
  
Packit Service 3e823c
  return(endA-offsetA);
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
int i_stutter_or_gap(int16_t *A, int16_t *B,long offA, long offB,
Packit Service 3e823c
		     long gap){
Packit Service 3e823c
  long a1=offA;
Packit Service 3e823c
  long b1=offB;
Packit Service 3e823c
  
Packit Service 3e823c
  if(a1<0){
Packit Service 3e823c
    b1-=a1;
Packit Service 3e823c
    gap+=a1;
Packit Service 3e823c
    a1=0;
Packit Service 3e823c
  }
Packit Service 3e823c
  
Packit Service 3e823c
  return(memcmp(A+a1,B+b1,gap*2));
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
/* riftv is the first value into the rift -> or <- */
Packit Service 3e823c
void i_analyze_rift_f(int16_t *A,int16_t *B,
Packit Service 3e823c
		      long sizeA, long sizeB,
Packit Service 3e823c
		      long aoffset, long boffset, 
Packit Service 3e823c
		      long *matchA,long *matchB,long *matchC){
Packit Service 3e823c
  
Packit Service 3e823c
  long apast=sizeA-aoffset;
Packit Service 3e823c
  long bpast=sizeB-boffset;
Packit Service 3e823c
  long i;
Packit Service 3e823c
  
Packit Service 3e823c
  *matchA=0, *matchB=0, *matchC=0;
Packit Service 3e823c
  
Packit Service 3e823c
  /* Look for three possible matches... (A) Ariftv->B, (B) Briftv->A and 
Packit Service 3e823c
     (c) AB->AB. */
Packit Service 3e823c
  
Packit Service 3e823c
  for(i=0;;i++){
Packit Service 3e823c
    if(i
Packit Service 3e823c
      if(i_paranoia_overlap_f(A,B,aoffset,boffset+i,sizeA,sizeB)>=MIN_WORDS_RIFT){
Packit Service 3e823c
	*matchA=i;
Packit Service 3e823c
	break;
Packit Service 3e823c
      }
Packit Service 3e823c
    
Packit Service 3e823c
    if(i
Packit Service 3e823c
      if(i_paranoia_overlap_f(A,B,aoffset+i,boffset,sizeA,sizeB)>=MIN_WORDS_RIFT){
Packit Service 3e823c
	*matchB=i;
Packit Service 3e823c
	break;
Packit Service 3e823c
      }
Packit Service 3e823c
      if(i
Packit Service 3e823c
	if(i_paranoia_overlap_f(A,B,aoffset+i,boffset+i,sizeA,sizeB)>=MIN_WORDS_RIFT){
Packit Service 3e823c
	  *matchC=i;
Packit Service 3e823c
	  break;
Packit Service 3e823c
	}
Packit Service 3e823c
    }else
Packit Service 3e823c
      if(i>=bpast)break;
Packit Service 3e823c
    
Packit Service 3e823c
  }
Packit Service 3e823c
  
Packit Service 3e823c
  if(*matchA==0 && *matchB==0 && *matchC==0)return;
Packit Service 3e823c
  
Packit Service 3e823c
  if(*matchC)return;
Packit Service 3e823c
  if(*matchA){
Packit Service 3e823c
    if(i_stutter_or_gap(A,B,aoffset-*matchA,boffset,*matchA))
Packit Service 3e823c
      return;
Packit Service 3e823c
    *matchB=-*matchA; /* signify we need to remove n bytes from B */
Packit Service 3e823c
    *matchA=0;
Packit Service 3e823c
    return;
Packit Service 3e823c
  }else{
Packit Service 3e823c
    if(i_stutter_or_gap(B,A,boffset-*matchB,aoffset,*matchB))
Packit Service 3e823c
      return;
Packit Service 3e823c
    *matchA=-*matchB;
Packit Service 3e823c
    *matchB=0;
Packit Service 3e823c
    return;
Packit Service 3e823c
  }
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
/* riftv must be first even val of rift moving back */
Packit Service 3e823c
Packit Service 3e823c
void i_analyze_rift_r(int16_t *A,int16_t *B,
Packit Service 3e823c
		      long sizeA, long sizeB,
Packit Service 3e823c
		      long aoffset, long boffset, 
Packit Service 3e823c
		      long *matchA,long *matchB,long *matchC){
Packit Service 3e823c
  
Packit Service 3e823c
  long apast=aoffset+1;
Packit Service 3e823c
  long bpast=boffset+1;
Packit Service 3e823c
  long i;
Packit Service 3e823c
  
Packit Service 3e823c
  *matchA=0, *matchB=0, *matchC=0;
Packit Service 3e823c
  
Packit Service 3e823c
  /* Look for three possible matches... (A) Ariftv->B, (B) Briftv->A and 
Packit Service 3e823c
     (c) AB->AB. */
Packit Service 3e823c
  
Packit Service 3e823c
  for(i=0;;i++){
Packit Service 3e823c
    if(i
Packit Service 3e823c
      if(i_paranoia_overlap_r(A,B,aoffset,boffset-i)>=MIN_WORDS_RIFT){
Packit Service 3e823c
	*matchA=i;
Packit Service 3e823c
	break;
Packit Service 3e823c
      }
Packit Service 3e823c
    if(i
Packit Service 3e823c
      if(i_paranoia_overlap_r(A,B,aoffset-i,boffset)>=MIN_WORDS_RIFT){
Packit Service 3e823c
	*matchB=i;
Packit Service 3e823c
	break;
Packit Service 3e823c
      }      
Packit Service 3e823c
      if(i
Packit Service 3e823c
	if(i_paranoia_overlap_r(A,B,aoffset-i,boffset-i)>=MIN_WORDS_RIFT){
Packit Service 3e823c
	  *matchC=i;
Packit Service 3e823c
	  break;
Packit Service 3e823c
	}
Packit Service 3e823c
    }else
Packit Service 3e823c
      if(i>=bpast)break;
Packit Service 3e823c
    
Packit Service 3e823c
  }
Packit Service 3e823c
  
Packit Service 3e823c
  if(*matchA==0 && *matchB==0 && *matchC==0)return;
Packit Service 3e823c
  
Packit Service 3e823c
  if(*matchC)return;
Packit Service 3e823c
  
Packit Service 3e823c
  if(*matchA){
Packit Service 3e823c
    if(i_stutter_or_gap(A,B,aoffset+1,boffset-*matchA+1,*matchA))
Packit Service 3e823c
      return;
Packit Service 3e823c
    *matchB=-*matchA; /* signify we need to remove n bytes from B */
Packit Service 3e823c
    *matchA=0;
Packit Service 3e823c
    return;
Packit Service 3e823c
  }else{
Packit Service 3e823c
    if(i_stutter_or_gap(B,A,boffset+1,aoffset-*matchB+1,*matchB))
Packit Service 3e823c
      return;
Packit Service 3e823c
    *matchA=-*matchB;
Packit Service 3e823c
    *matchB=0;
Packit Service 3e823c
    return;
Packit Service 3e823c
  }
Packit Service 3e823c
}
Packit Service 3e823c
Packit Service 3e823c
void  analyze_rift_silence_f(int16_t *A,int16_t *B,long sizeA,long sizeB,
Packit Service 3e823c
			     long aoffset, long boffset,
Packit Service 3e823c
			     long *matchA, long *matchB){
Packit Service 3e823c
  *matchA=-1;
Packit Service 3e823c
  *matchB=-1;
Packit Service 3e823c
Packit Service 3e823c
  sizeA=prna_min(sizeA,aoffset+MIN_WORDS_RIFT);
Packit Service 3e823c
  sizeB=prna_min(sizeB,boffset+MIN_WORDS_RIFT);
Packit Service 3e823c
Packit Service 3e823c
  aoffset++;
Packit Service 3e823c
  boffset++;
Packit Service 3e823c
Packit Service 3e823c
  while(aoffset
Packit Service 3e823c
    if(A[aoffset]!=A[aoffset-1]){
Packit Service 3e823c
      *matchA=0;
Packit Service 3e823c
      break;
Packit Service 3e823c
    }
Packit Service 3e823c
    aoffset++;
Packit Service 3e823c
  }
Packit Service 3e823c
Packit Service 3e823c
  while(boffset
Packit Service 3e823c
    if(B[boffset]!=B[boffset-1]){
Packit Service 3e823c
      *matchB=0;
Packit Service 3e823c
      break;
Packit Service 3e823c
    }
Packit Service 3e823c
    boffset++;
Packit Service 3e823c
  }
Packit Service 3e823c
}