2018/04/29

LADSPA Compressor 機能追加

Win10環境でプログラムできる環境が整ったので、リハビリ程度に、 去年の夏に作ったLADSPAのCompに機能を追加してみた 前回メモも残しておらず、ソースコード上にコメントもほとんど書かなかったので、解析に苦労してしまった。 自分で作ったプログラムなのに、解析だけで半日は費やしてしまった。 ということで、数年後にまた必要になりそうな気がしたので、Blogにメモしておくことにした。
半年以上前のプログラムとなると、やっぱり忘れるものね。目に見える設計などは、結構忘れないのだが、読んで頭の中で構築する必要のあるプログラム設計はダメだった。特に数式をいじくりまわしてしまうと、何をやっているのかひも解くだけでも一苦労。

改定コンプ

主な変更点は、 アタックを追加し、普通のコンプのようにした。 そして音のつながりカーブをコサインカーブを使用してなめらかにした。 パラメーター幅も多少変更した等々。 開発時間の多くは解析に使い、新しい機能は2、3時間で実現できた。

コンプの特徴

あくまでもナチュラルに圧縮し、決して歪まない。どんな設定にしても波形は崩れないため、原音のイメージを保つことができる。 またアタックタイム0を実現することで、突然のピークにも対応することができる。 リリース、およびアタックとのつながりがスムーズ。 設定どおりの圧縮が可能。多くのコンプは、設定値と実際の圧縮が合ってなくて感覚で操作するものが多い。そういう曖昧なことをやめてみた。
Audacityで利用した場合、インターフェイスは以下のようなもので、コンプとしてはオーソドックスなパラメータが並ぶ。

Threshold(0~1.0)
リニア表示で、dBではない。Audacityで使う場合はリニアの方が使いやすいため。

Ratio(1:1~20)
普通は最大無限にするが、プログラム的に楽をするため20とした。リミッター的に使う場合は20を使うが、普通は2~4程度。

Attack(0~500msec)
新たに加えたパラメータ。0が設定できるところが大きな特徴。 今回設置した理由としては、やはり音によっては、アタックがあった方がよいと思えたため。

Release(0~2000msec)
このコンプ場合、0設定では使わない方が無難で、音に合わせて慎重に設定する必要がある。音色が変化してしまった場合はリリースタイムを見直すとよい。

以下はAudacity上で波形にコンプを掛けてみたところ。上段はオリジナルで、下段がコンプ適用波形。

パラメータ設定は上インターフェイスの値。スレッショルド0.5で、レシオ、アタック、リリースとも最大にした状態。 下絵はアタック部分を拡大したところ。なめらかなカーブを実現しているのがわかると思う。


波形のひずみについて。下絵の上段は通常コンプで圧縮した状態。オリジナル波形はサイン波なので、これが三角波になってしまっているのがわかると思う。普通のコンプでは、大なり小なりこのように歪んでしまう。コンプらしい音とか言われるが、個人的にはよろしくないね。下段は今回作ったコンプ。サイン波のままであることがわかると思う。


下はアタックタイムの比較。 通常コンプはアタックタイム0が設定できないため、上段のように初めの波形が適用されないままとなってしまう。 下段はアタックタイム0設定により、スレッショルド以上の波形は一番の初めの波形からきれいに圧縮している例。


下はアタックタイムによる波形維持の例。 上段がオリジナル波形で、0ラインに対して、大小さまざまな波形が組み合わさって音色を作っている。これを今回作ったコンプで、リリース0にして掛けてしまうと中段のようになり、小さい波形はまったくいじられない。大きな波形だけが圧縮されるので、音色が少し違ってしまう。そこで、リリースの設定で、圧縮波形の周辺はすべて同様に圧縮させることで、これを回避する。 波形全体の印象もオリジナルがそのまま小さくなっているのが確認できると思う。 リリースの設定はとても大事。



プログラム上のメモ

ここからプログラム内部のメモとなる。多分作った本人しか分からない話。

大まかな信号の流れ

入力信号を、まずバッファに入るだけ入れてしまう。サンプリング周波数ごとにバッファサイズは違い、サイズは20Hz基準とした。48000Hzの場合は、1/20の2400タップとなる。 入力信号をバッファに入れてから、バッファ内の信号を評価及び処理するプロセスに入る。 必要に応じて、信号を圧縮処理し、信号を書き換える。バッファ内の信号処理が完了したら、まとめて出力する。そして、また入力信号をバッファに蓄えて処理するという繰り返し。リアルタイムは重視していないので、バッファに一度入れてすべての処理が終わってから出力する流れとなっている。

バッファ内の信号の評価及び処理手順

バッファ内の半周期分を単位として処理する。信号が0以上になり、0以下になるまでの間であり、サイン波の半周期分と同じ。この部分を切り出し、ピークを特定する。

次にピークを特定したら、そのピークがスレッショルド以上であるかどうかの評価を行う。 スレッショルド以上であれば、パラメーターに従って、半周期分をまるごと同じ圧縮率で圧縮処理をする。そしてバッファ内の信号を上書きする。スレッショルド以上の信号だけをいじるわけではないので、波形の歪みを最小限にしている。ある意味過去のデータにさかのぼって処理するので、先読み処理ともいえる。 読み込み及び書き込みはstatic inline関数を使用。

また半周期分ごとに処理するので、基本的に0以上の波形と0未満の波形処理の2種類が存在するが、評価等は絶対値によって行うので、プラスマイナスは意識せず、同じ関数内ですべて処理している。


カーブ

アタック及びリリースとのつながりをスムーズにするためコサインカーブを利用。
buffer[i]*(0.5+0.5*cos(i*M_PI/len));
基本的には上記式をいじくってコードに埋め込んでいる。アタックとリリースの関係は向きが逆なだけ。 カーブは、サンプル単位で適用している。


それにしても・・・

LADSPAで作るのはやめようかと思い始める。たまにちょろっと作るにはお手軽なのだが、 問題は、仕様の古さと、インターフェイスがどうにもならないこと。何か作ろうとしても制約が出てしまって妥協せざる得ない。

そこでLADSPAの後継規格であるLV2というものがあり、Audacityでもサポートしているのだが、これは開発環境にGTKが必要だったりして何かと面倒。

Winをメインで使うなら素直にVSTで作る方がいいかもしれない。Audacity以外でも利用可能になるメリットがある。少し調べてみたら、現在VSTは3.6になっていて、これはAudacityで使えなさそう。そうなると古い2.4で開発することになるが、今更そんな古いプラグイン開発するのも気が引ける。

ということで、プラグイン規格はどれも一長一短で、都合のよいものが見つからない。


sound programming 目次