鈍足ランナーのIT日記

走るのが好きな5流のITエンジニアのブログ。

趣味の範囲は広いけど、どれも中途半端なクソブロガー楽しめるWebアプリを作ってあっと言わせたい。サーバーサイドPerl(Mojolicious)、クライアントサイドVue.js。Arduinoにも触手を伸ばす予定。

pitcfinder.jsのMPMアルゴリズムを動くようにしたい

pitchfinder.jsという波形から周波数をだしてくれる便利モジュール
MPMアルゴリズムだと-1が常に返るので、console.logを埋め込みながら実行して
動きを見ている。

functionの中でArray(maxPositions)にpushしているのですが、そのあと長さを参照すると0になっているのがどうも変な動きっぽい。
functionの中のmaxPositions変数と呼び出し元の変数が違うものになっているのかな?
javascript変数のスコープについて調べないと。。。

    // Finds the highest value between each pair of positive zero crossings.
    var peakPicking = function() {
      var pos = 0,
          curMaxPos = 0;

      // find the first negative zero crossing.
      while (pos < nsdf.length - 1 / 3 && nsdf[pos] > 0) {
        pos++;
      }

      // loop over all the values below zero.
      while (pos < nsdf.length - 1 && nsdf[pos <= 0]) {
        pos++;
      }

      // can happen if output[0] is NAN
      if (pos == 0) {
        pos = 1;
      }

      while (pos < nsdf.length - 1) {
        if (nsdf[pos] > nsdf[pos - 1] && nsdf[pos] >= nsdf[pos + 1]) {
          console.log("condition ok"+ pos);          
          if (curMaxPos == 0) {
            // the first max (between zero crossings)
            curMaxPos = pos;
          } else if (nsdf[pos] > nsdf[curMaxPos]) {
            // a higher max (between the zero crossings)
            curMaxPos = pos;
          }
        }
        pos++;
        // a negative zero crossing
        if (pos < nsdf.length - 1 && nsdf[pos] <= 0) {
          console.log("negative zero crossing true" + curMaxPos);          
          // if there was a maximum add it to the list of maxima
          if (curMaxPos > 0) {
            console.log("push!");
            maxPositions.push(curMaxPos);
            curMaxPos = 0; // clear the maximum position, so we start
            // looking for a new ones
          }
          while (pos < nsdf.length - 1 && nsdf[pos] <= 0) {
            pos++; // loop over all the values below zero
          }
        }
      }
      if (curMaxPos > 0) {
        maxPositions.push(curMaxPos);
      }
    };

    return function(float32AudioBuffer) {

      // 0. Clear old results.
      var pitch,
          maxPositions = [],
          periodEstimates = [],
          ampEstimates = [];

      // 1. Calculute the normalized square difference for each Tau value.
      normalizedSquareDifference(float32AudioBuffer);
      // 2. Peak picking time: time to pick some peaks.
      peakPicking();

      console.log("maxPositions.length" + maxPositions.length);

なんとなく、こうすればいい気がする。

      var pitch;
      // 0. Clear old results.
      maxPositions = [],
      periodEstimates = [],
      ampEstimates = [];


コチラヲ見ながら修正シテイルノデスガ、
440HZの正弦波が47000HZトデテシマウ。もう少し何ですがナカナカ
ムズイ。

grgsiberia-mitou.hatenadiary.jp

http://miracle.otago.ac.nz/tartini/papers/A_Smarter_Way_to_Find_Pitch.pdf

NSDFの値は1から-1まで取ること。どれだけ時間をずらしたら
1に近いところになるかを求めればいいような感じですが。
47000という数字はサンプリングレート近い値だから
つまり時間をずらしていないところを指してしまっているのだろうなぁ。
peakPickingのあたりの動きをよく見てみないとわからない。。

結局いろいろ見直してなんとか440HZがでるようになりました。
後できれいにしてプルリクの準備にとりかかろう。

というわけで、プルリク作成完了。でもメンテされていないようなので
取り込まれることはないかもかも。

github.com