はじめに
Cで実装されたWorld VocoderのSwiftのwrapperを作りました。
リポジトリはこちら → https://github.com/fuziki/WorldInApple
動作の様子
worldのswiftのwrapperを公開しましたー
— ふじき (@fzkqi) February 17, 2020
iPhoneでボイチェンができます!https://t.co/t2Y3BvhvLi pic.twitter.com/b7AI4F1Qkr
WorldInApple
サンプルプロジェクト
- worldをサブモジュールとして組み込んでいるため、--recurse-submodulesオプションをつけてクローンします。
- サンプルプロジェクトはchartsを使っているので、cathageを使ってインストールします。
- xcworkspaceの方(白い方)を開きます。
git clone --recurse-submodules https://github.com/fuziki/WorldInApple
cd WorldInApple/Examples/Example-iOS/
carthage update --platform iOS
cd ../../
open WorldInApple.xcworkspace
機能
概要
AVAudioPCMBufferのピッチとフォルマントを変化させることができます。
AVAudioPCMBufferはiOSでPCMを扱うことができるクラスで、PCMのバイナリとそのフォーマットを格納しています。
Worldには64bit浮動小数点、48kHz、1chのPCMデータを入力します。指定のフォーマットへの変換はAVAudioConverterを使用します。
AVAudioPCMBufferのピッチとフォルマントを変える
1. WorldInAppleのインスタンスを作成する
- x_lengthにはAVAudioPCMBufferのframe長を設定します。
(例えば、48kHzの38400frame分の場合は38400frame/48kHz=0.8sec)
let worldInApple = WorldInApple(fs: 48000, frame_period: 5, x_length: 38400)
2. ピッチとフォルマントを設定する
- ピットとフォルマントの移動分を設定します。
- 1より大きいと高くなり、1より小さい低くなります。
- ピッチは声の音自体の高さであり、フォルマントは声質です。
worldInApple.set(pitch: Double(1.2))
worldInApple.set(formant: Double(1.8))
3. AVAudioPCMBufferを入力する
- convの結果としてAVAudioPCMBufferを受け取ります。
- 0.8sec分の処理に0.4sec~0.7secほど要するため非同期で実行することをオススメします。
let result = worldInApple.conv(buffer: buffer)
イコライザー
サンプルプロジェクトにはイコライザを搭載しています。
worldの変換後の音に対してイコライザ処理ができます。
スライドバーが上にあるほど低音域で、下にあるほど高音域です。
低音域のゲインを小さくすることでノイズを低減する効果がある(気がします)。
おわりに
WorldのSwiftのwrapperを実装しました。
swiftがcの関数の呼び出しが可能なため、比較的簡単に高品質なvocoderを実装ができました。
簡単にiOS実機とmacのエディタで使えるアセットを作成するツールを作っていています
→ https://fzkqi.hatenablog.com/entry/2020/02/12/235202
今後はこれを使って、WorldのUnityのNative Pluginを作りたいなと考えています。