2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ベートーベンの耳を手に入れる Beethovenを用いたピッチ検出処理

Last updated at Posted at 2019-03-25

発端

好きな曲のハーモニカを吹きたいのだが採譜がめんどくさいという万人に共通の悩み、、、ありますよね。

例えば Jukeはハーモニカ界のスタンダードですけど、これの冒頭(チャララララーラッ♪)はもちろん**+3-3-4-5-6**です。

このフレーズなら皆さん暗譜していることでしょう。。。しかしこんな調子で1フレーズ毎に耳コピしてたら日が暮れるっちゅーことで自動採譜ツールを作り、、、作ろうとしました。

ベートーベン

ちゅーことで、iphoneのマイクに聞かせてフレーズを自動で作らせればええやん、swiftも勉強できるし一石二鳥!!ということでswiftのライブラリを漁ったところ、ありました。Beethovenです。最初ビートバンと読んだのは内緒です。何かと思いました。。。

Beethoven is an audio processing Swift library that provides an easy-to-use interface to solve an age-old problem of pitch detection of musical signals. You can read more about this subject on Wikipedia.

ということで今回やりたいことに一致しているようにみえます。やったぜ。

ハマる

readmeを読み始めたあたりでなんかシグナルトラッキングとかEstimationとか、よく分からん単語が乱立しており、これは大変な沼にハマってしまったなぁという感想。

しかし作者の方が大変気が利くようでして、Exampleを用意してくれていました。ありがとう、マジありがとう。CocoaPodsとかなんか良く分からんswift環境周りのアレに翻弄されながらもなんとかビルドしコードを読む。ふむ。

キモ

ViewController.swiftの中、メンバ変数pitchEngineの生成箇所と、その使用箇所がキモのようです。

生成箇所
lazy var pitchEngine: PitchEngine = { [weak self] in
    let config = Config(estimationStrategy: .yin)
    let pitchEngine = PitchEngine(config: config, delegate: self)
    pitchEngine.levelThreshold = -30.0
    return pitchEngine
  }()

コード見りゃ分かるんですが、Configにバッファサイズと評価方式(多分解析精度に絡むやつ)を渡します。もうここを突っ込んでいくと窓関数とかフーリエ変換とか、大学の時にもっとちゃんと勉強しておくべきだったことがいっぱい出てきます。あれ、大事だったんだなぁって。。。留年、してる場合じゃなかったなぁって。

使用箇所
  func pitchEngine(_ pitchEngine: PitchEngine, didReceivePitch pitch: Pitch) {
    noteLabel.text = pitch.note.string

    let offsetPercentage = pitch.closestOffset.percentage
    let absOffsetPercentage = abs(offsetPercentage)

    print("pitch : \(pitch.note.string) - percentage : \(offsetPercentage)")

    guard absOffsetPercentage > 1.0 else {
      return
    }

    let prefix = offsetPercentage > 0 ? "+" : "-"
    let color = offsetColor(offsetPercentage)

    offsetLabel.text = "\(prefix)" + String(format:"%.2f", absOffsetPercentage) + "%"
    offsetLabel.textColor = color
    offsetLabel.isHidden = false
  }

白状しますとDelegateパターンをよく理解していないのでこの関数がどういう経緯で動くのかがぼんやりしているのですが、ここでpitchEngineで評価した結果をいじいじして使っています。引数pitchには評価結果が入ってきます。

後はこの結果を元にいい感じに画面表示を行えば難しくない。
という訳でいい感じの採譜ツールができました。

、、、の、はず。だったのですが。。。

倍音問題

どーーーーも良くわからないのですが、高音を鳴らすと一オクターブ下の音を誤検出してしまいがちなんですよね〜〜〜〜うーーーーん。。。
ウェッブで調べたところによると、自己相関関数とかいう的な何かを使えば良いかもしれないと思われるのですが全く分からずです、はい。

という訳でなんか別のやり方を勉強しなきゃな〜と感じています。難しぃ。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?