ディジタル音声処理特論レポート¶

課題3「エレキギターのエフェクタの実装」¶

学籍番号:G23TX0XX, 氏名:○○ ○○¶

 6.2節では音色を豊かにするために使われる技術であるエフェクタの原理の解説とプログラミングによる実装を行いました。楽器に詳しい人の場合,エフェクタと聞くとエレキギターを演奏する際に用いるデバイスのことを思い浮かべるかもしれません.本節ではエレキギター用の主要なエフェクタの原理とプログラミングによる簡易的な実装,そしてこれらのエフェクタによって音がどのように変化していくのかを見てみましょう。

6.x.1 オーバードライブ¶

 オーバードライブとは,ロックに不可欠な歪んだ音を得るためのエフェクタです。今回は,音を歪ませるために双曲線関数 $\tanh$ を用います。

In [ ]:
x_values = np.linspace(-5, 5, 1000)
y_values = np.tanh(x_values)
plt.plot(x_values, y_values)
plt.title('tanh')
plt.show()

上図のとおり,%tanh% は入力値の絶対値が大きくなるにつれて出力値が飽和して非線形な歪みを発生させます。波形に対してこの関数を通すことにより,音を歪ませるといった原理になっています。
 まず,原音を読み込んで,波形を見て,聞いてみましょう。

In [ ]:
fs, wave_data = scipy.io.wavfile.read ('maou_se_inst_guitar08.wav')  # 音楽データを読み込みます。

sampling_interval = 1.0 / fs                  # サンプリング間隔は,サンプリング周波数の逆数
times = np.arange ( len ( wave_data )) * sampling_interval  # サンプル系列の時刻データの配列

print(len(wave_data))
start = 90000; end = start+15000     # 表示する区間の先頭と末尾を指定して,
plot_wave(times[start:end], wave_data[start:end]) # 波形を表示します。
Audio(wave_data, rate = fs)
172296
Out[ ]:
Your browser does not support the audio element.

それでは,オーバードライブを実装して音がどのように変化するか聞いてみましょう。(音量注意!)

In [ ]:
gain = 1.0*1e-7 # 歪みの強さ
overdrive_wave = np.tanh(gain * wave_data)

plot_wave(times[start:end], overdrive_wave[start:end])
Audio(overdrive_wave, rate = fs)
Out[ ]:
Your browser does not support the audio element.

いわゆる「音が割れている」現象が起きました。波形も隙間がなく海苔みたいになっています(「海苔波形」と言われたりします)。もっと狭い区間を見て波形がどのようになっているか見てみましょう。

In [ ]:
plot_wave(times[start:start+500], overdrive_wave[start:start+500])  # 波形を表示します。

このとおり,ほとんどの時間点において瞬時振幅値が1もしくは-1になっていることがわかります。

6.x.2 コーラス¶

 コーラスは,入力された音に対してピッチを少しずらして遅延させたものを重ねることによって揺らぎや厚みを加えるエフェクタです。まるで2本のギターが鳴っているかのような音になることから,英語で合唱を意味するその名前がついています。
 それでは,コーラスを実装して音がどのように変化するか聞いてみましょう。

In [ ]:
chorus_data = np.zeros_like(wave_data, dtype=np.float64)
depth = 1.5 # コーラス効果の深さ
rate = 0.2 # コーラスの振動の速さ
delay = 1500 # コーラスの遅延
for i in range(len(wave_data)):
  delay_sample = int(delay * np.sin(2 * np.pi * rate * i / len(wave_data)))
  chorus_data[i] = wave_data[i] + depth * wave_data[(i + delay_sample) % len(wave_data)]

plot_wave(times[start:end], chorus_data[start:end])
Audio(chorus_data, rate = fs)
Out[ ]:
Your browser does not support the audio element.

波形には大きな変化は見られませんでしたが,柔らかく心地よいメロウな音色になりました。
 次はコーラスの振動をより速くしてみましょう。

In [ ]:
chorus_data = np.zeros_like(wave_data, dtype=np.float64)
depth = 1.5 # コーラス効果の深さ
rate = 1.0 # コーラスの振動の速さ
delay = 1500 # コーラスの遅延
for i in range(len(wave_data)):
  delay_sample = int(delay * np.sin(2 * np.pi * rate * i / len(wave_data)))
  chorus_data[i] = wave_data[i] + depth * wave_data[(i + delay_sample) % len(wave_data)]

plot_wave(times[start:end], chorus_data[start:end])
Audio(chorus_data, rate = fs)
Out[ ]:
Your browser does not support the audio element.

重なる音のピッチの揺らぎが大きくなったことにより,不協和音が発生しました。

6.x.3 ワウ¶

 ワウは高い周波数を強調するエフェクタです。このエフェクタはペダルの踏み込む加減に応じてその強さを段階的に変更することができます。テンポに合わせて踏み込むことによって「ワウワウ」と聞こえることからこの名前がついています。
 高い周波数を強調するために,IIRフィルタを用いたローパスフィルタを用います。さらに,このローパスフィルタを周期的に掛けることでワウを実現することができます。
 それでは,ワウを実装して音がどのように変化するか聞いてみましょう。

In [ ]:
wahwah_data = np.zeros_like(wave_data)
rate = 2
depth = 3.5
speed = (2.0 * np.pi * rate) / fs
freq = 800

theta = 0
for i in range(len(wave_data)):
  theta += speed
  a = (np.cos(theta) * 0.5) + 0.5
  tmp_freq = freq * (1.0 + a * depth)
  # IIRフィルタを用いたローパスフィルタ
  alpha = (2 * np.pi * tmp_freq) / fs
  b = (1 - np.cos(alpha)) / 2
  a0 = 1 + b
  a1 = -2 * np.cos(alpha)
  a2 = 1 - b

  wahwah_data[i] = b * (wave_data[i] + 2 * wave_data[i - 1] + wave_data[i - 2]) - a1 * wahwah_data[i - 1] - a2 * wahwah_data[i - 2]

wahwah_data = wahwah_data[60000:]

plot_wave(times[start:end], wahwah_data[start:end])
Audio(wahwah_data, rate = fs)
Out[ ]:
Your browser does not support the audio element.

本当にワウ,ワウ,といった感じに聞こえますね。次に,ワウをかける周期を短くしてみましょう。

In [ ]:
wahwah_data = np.zeros_like(wave_data)
rate = 5
depth = 3.5
speed = (2.0 * np.pi * rate) / fs
freq = 800

theta = 0
for i in range(len(wave_data)):
  theta += speed
  a = (np.cos(theta) * 0.5) + 0.5
  tmp_freq = freq * (1.0 + a * depth)
  # IIRフィルタを用いたローパスフィルタ
  alpha = (2 * np.pi * tmp_freq) / fs
  b = (1 - np.cos(alpha)) / 2
  a0 = 1 + b
  a1 = -2 * np.cos(alpha)
  a2 = 1 - b

  wahwah_data[i] = b * (wave_data[i] + 2 * wave_data[i - 1] + wave_data[i - 2]) - a1 * wahwah_data[i - 1] - a2 * wahwah_data[i - 2]

wahwah_data = wahwah_data[60000:]

plot_wave(times[start:end], wahwah_data[start:end])
Audio(wahwah_data, rate = fs)
Out[ ]:
Your browser does not support the audio element.

より細かくワウを掛けることができました。
 エレキギターには他にもたくさんの豊富なエフェクタがあります。興味がある方は他のエフェクタもプログラミングで実装してみてはいかがでしょうか。

参考文献
[1] 【今さら聞けない】エフェクターの基礎知識編 ~エフェクターの種類と効果~ https://guitarsele.com/article/feature/basic-knowledge-of-effector-speicies/
[2] C++でVST作り https://www.utsbox.com/?cat=19

使用した音源
魔王魂 ギター08 https://maou.audio/?s=%E3%82%AE%E3%82%BF%E3%83%BC#google_vignette