<commit_before>import Complex from './complex';

class Pitcher{
  private static parabola(nsdf: Array<number>, i:number){
    const a:number = nsdf[i-1];
    const b:number = nsdf[i];
    const c:number = nsdf[i+1];

    const bottom:number = a + c - 2.0 * b;
    var x:number, y:number;
    if (bottom == 0.0){
      x = i;
      y = b;
    }else{
      var delta = a - c;
      x = i + delta / (2.0 * bottom);
      y = b - delta * delta / (8.0 * bottom);
    }
    return {x:x, y:y};
  }

  private static acf(x: Array<Complex>){
    const n = x.length;
    const tmp = new Array<Complex>();
    for (let i = 0; i < n; i++){tmp[i] = x[i];}
    for (let i = n; i < (n*2); i++){tmp[i] = new Complex(0,0);}

    FFT.fft(tmp, n*2);
    for (let i = 0; i < (n*2); i++){tmp[i] = tmp[i].abs2();}

    FFT.fft(tmp, n*2);
    const out = new Array<number>();
    for (let i = 0; i < n; i++){out[i] = tmp[i].real/n/2;}
    return out;
  }

  private static nsdf(x: Array<Complex>){
    function sq(n:number){ return n*n;}

    const n = x.length;
    var out = this.acf(x);
    var tsq = out[0]*2.0;
    for (let i = 0; i < n; i++){
      out[i] = tsq>0.0 ? out[i]/tsq : 0.0;
      tsq -= sq(x[n-1-i].real) + sq(x[i].real);
    }
    return out;
  }

  private static picking(nsdf: Array<number>){
    var maxI = 0;
    var nega = false;
    var peaks = new Array<number>();
    for (let i = 0; i < nsdf.length-1; i++){
      if (nsdf[i] > 0.0){
        if (nega && (maxI==0 || nsdf[i]>nsdf[maxI])) maxI = i;
      }else{
        if (maxI>0){
          peaks.push(maxI);
          maxI = 0;
        }
        nega = true;
      }
    }
    if (maxI>0) peaks.push(maxI);

    return peaks;
  }

  static pitch(ary: Array<number>, sampleRate: number){
    const DEFAULT_CUTOFF = 0.95;

    const x = new Array<Complex>();
    for (let i = 0; i < ary.length; i++) x[i] = new Complex(ary[i], 0);

    const nsdf = this.nsdf(x);

    const peaks = this.picking(nsdf);
    if (peaks.length == 0) return -1.0;

    const periods = new Array<number>();
    const amps = new Array<number>();

    for (let i = 0; i < peaks.length; i++){
      var h = this.parabola(nsdf, peaks[i]);
      amps.push(h.y);
      periods.push(h.x);
    }

    const max = Lambda.fold(amps, function(e, max){return e > max ? e : max;}, 0.0);

    if (max < 0.35) return -1.0;
    const coff = DEFAULT_CUTOFF * max;

    let idx = -1;
    for (let i = 0; i < amps.length; i++){
      if (amps[i] > coff){
        idx = i;
        break;
      }
    }

    if (idx == -1) return -1.0;

    return sampleRate / periods[idx];
  }
}

class FFT{
  static fft_ = function(n,s,eo,x,y) {
    const m = Math.floor(n / 2);
    const theta = 2.0 * Math.PI / n;
    if(n == 1) {
      if(eo) {
        for (let q = 0; q < s; q++){
          y[q] = x[q];
        }
      }
    } else {
      for (let p = 0; p < m; p++){
        var wp = new Complex(Math.cos(p * theta),-Math.sin(p * theta));
        for (let q = 0; q < s; q++){
          var a = x[q + s * p];
          var b = x[q + s * (p + m)];
          y[q + s * (2 * p)] = a.plus(b);
          y[q + s * (2 * p + 1)] = a.minus_bang(b).multi(wp);
        }
      }
      FFT.fft_(n / 2,2 * s,!eo,y,x);
    }
  }

  static fft = function(x,n) {
    FFT.fft_(n,1,false,x,new Array());
  }
}

class HxOverrides{
  static iter(a) {
    return { cur : 0, arr : a, hasNext : function() {
      return this.cur < this.arr.length;<commit_msg>no comment<commit_after>import Complex from './complex';

class Pitcher{
  private static parabola(nsdf: Array<number>, i:number){
    const a:number = nsdf[i-1];
    const b:number = nsdf[i];
    const c:number = nsdf[i+1];

    const bottom:number = a + c - 2.0 * b;
    var x:number, y:number;
    if (bottom == 0.0){
      x = i;
      y = b;
    }else{
      var delta = a - c;
      x = i + delta / (2.0 * bottom);
      y = b - delta * delta / (8.0 * bottom);
    }
    return {x:x, y:y};
  }

  private static acf(x: Array<Complex>){
    const n = x.length;
    const tmp = new Array<Complex>();
    for (let i = 0; i < n; i++){tmp[i] = x[i];}
    for (let i = n; i < (n*2); i++){tmp[i] = new Complex(0,0);}

    FFT.fft(tmp, n*2);
    for (let i = 0; i < (n*2); i++){tmp[i] = tmp[i].abs2();}

    FFT.fft(tmp, n*2);
    const out = new Array<number>();
    for (let i = 0; i < n; i++){out[i] = tmp[i].real/n/2;}
    return out;
  }

  private static nsdf(x: Array<Complex>){
    function sq(n:number){ return n*n;}

    const n = x.length;
    var out = this.acf(x);
    var tsq = out[0]*2.0;
    for (let i = 0; i < n; i++){
      out[i] = tsq>0.0 ? out[i]/tsq : 0.0;
      tsq -= sq(x[n-1-i].real) + sq(x[i].real);
    }
    return out;
  }

  private static picking(nsdf: Array<number>){
    var maxI = 0;
    var nega = false;
    var peaks = new Array<number>();
    for (let i = 0; i < nsdf.length-1; i++){
      if (nsdf[i] > 0.0){
        if (nega && (maxI==0 || nsdf[i]>nsdf[maxI])) maxI = i;
      }else{
        if (maxI>0){
          peaks.push(maxI);
          maxI = 0;
        }
        nega = true;
      }
    }
    if (maxI>0) peaks.push(maxI);

    return peaks;
  }

  static pitch(ary: Array<number>, sampleRate: number){
    const DEFAULT_CUTOFF = 0.95;

    const x = new Array<Complex>();
    for (let i = 0; i < ary.length; i++) x[i] = new Complex(ary[i], 0);

    const nsdf = this.nsdf(x);

    const peaks = this.picking(nsdf);
    if (peaks.length == 0) return -1.0;

    const periods = new Array<number>();
    const amps = new Array<number>();

    for (let i = 0; i < peaks.length; i++){
      var h = this.parabola(nsdf, peaks[i]);
      amps.push(h.y);
      periods.push(h.x);
    }

    const max = Lambda.fold(amps, function(e, max){return e > max ? e : max;}, 0.0);

    if (max < 0.35) return -1.0;
    const coff = DEFAULT_CUTOFF * max;

    let idx = -1;
    for (let i = 0; i < amps.length; i++){
      if (amps[i] > coff){
        idx = i;
        break;
      }
    }

    if (idx == -1) return -1.0;

    return sampleRate / periods[idx];
  }
}

class FFT{
  private static fft_inner = function(n: number,s: number,copy_flag: boolean,x: Array<Complex>,y: Array<Complex>) {
    if(n == 1) {
      if(copy_flag) {
        for (let q = 0; q < s; q++){ y[q] = x[q]; }
      }
      return;
    }

    const m = Math.floor(n / 2);
    const theta = 2.0 * Math.PI / n;
    for (let p = 0; p < m; p++){
      const wp = new Complex(Math.cos(p * theta),-Math.sin(p * theta));
      for (let q = 0; q < s; q++){
        const a = x[q + s * p];
        const b = x[q + s * (p + m)];
        y[q + s * (2 * p)] = a.plus(b);
        y[q + s * (2 * p + 1)] = a.minus_bang(b).multi(wp);
      }
    }
    FFT.fft_inner(n / 2, 2 * s, !copy_flag, y, x);
  }

  static fft = function(x,n) {
    FFT.fft_inner(n,1,false,x,new Array());
  }
}

class HxOverrides{
  static iter(a) {
    return { cur : 0, arr : a, hasNext : function() {
      return this.cur < this.arr.length;
{'fraction_non_alphanumeric': 0.19476409666283084, 'fraction_numerical': 0.021288837744533946, 'mean_word_length': 1.99569151227919, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1600761', 'n_tokens_mistral': 2938, 'n_tokens_neox': 2826, 'n_words': 758}