音を歪ませる(ディストーション)

Python

ディストーションの原理

概要

ディストーション」は入力信号をアンプなどで増幅したときに、ハードウェアまたはソフトウェアが正しく信号増幅できる増幅限界を超えてしまった際に波形にクリッピングが生じてしまう現象です。

クリッピングが発生すると波形の増幅限界を超えてしまった部分が切り取られたかのように平坦になります

下図の例だと-1~1までの範囲を増幅限界として、音量を1倍、2倍、5倍としたところ、最下段の波形の一部がクリッピングを起こしてしまいました。

\( S1(n) = S0(n) * gain \)

  • \( S1(n) \):増幅の音声
  • \( S0(n) \):増幅の音声
  • \( gain \):増幅率

クリッピングが発生した部分の音声はいわゆる「音割れ」が発生しているため、耳障りがざらつき、エッジの聞いた音になります。
音響効果の世界では、この音の歪みを意図的に引き起こしインパクトのあるサウンドを作り出します。

基本波形を歪ませる

さて、ここで過去の記事に色々な波形の音を聴き比べるというものがありました。

そこで正弦波Sine Wave)と矩形波Square Wave)を紹介しました。2つの波形を見比べてみると、正弦波を増幅させてクリッピングを発生させると矩形波の形になることが想像できるでしょうか。

また、周波数成分に着目すると正弦波の時は440Hzしか含まれていなかったのに対し、矩形波は倍音成分が含まれています。音源の増幅はクリッピングが発生しない程度であれば周波数成分の変化は振幅のみとなりますが、クリッピングが発生するほど音源増幅を行うと本来含まれていない周波数成分が作り出されます

このように新たな周波数成分を発生させない処理を線形処理新たな周波数成分を発生させる処理を非線形処理と呼んだりします。

Pythonでの実装方法

from scipy.io import wavfile
import numpy as np

# wavファイルのパス
INPUT_FILENAME = "input.wav"
OUTPUT_FILENAME = "output.wav"
GAIN = 5 # 増幅量

# WAVファイルからデータを読み込む。
fs, data = wavfile.read(INPUT_FILENAME)
data =  data / (2**15-1) # -1 ~ 1の範囲で正規化

tmp_data = data * GAIN
# クリッピングが発生する箇所の処理
for i in range(len(tmp_data)):
    if tmp_data[i] > 1.0:
        tmp_data[i] = 1.0
    elif tmp_data[i] < -1.0:
        tmp_data[i] = -1.0

tmp_data = tmp_data * (2**15-1) # 正規化した分を元のスケールに戻す

# WAVファイルにデータを書き込む。
wavfile.write(OUTPUT_FILENAME, fs, tmp_data.astype(np.int16))

コメント