音遊び日記

ハードウェアとソフトウェアの両面から”音”で遊んだ事を備忘録として書いています。

C言語を使ったエフェクター 第三回:ディレイ

 

1. はじめに

 歪みの次によく使われるであろうディレイ。ディレイはその名の通り音を遅らせるエフェクターですが、様々な用途で使われ、多くのエフェクトの元になっています。

用途① 付点8分ディレイ

有名な曲ではやはり凛として時雨の「DISCO FLIGHT」のイントロですね

。あとは斉藤和義の名曲「やさしくなりたい」でも使われています。ディレイタイムを付点8分の長さに設定し、8分音符のリフを弾くと音と音の間にディレイ音が入る事になり、速弾きギミックプレイをしているように聴かせる事が出来ます。

用途② ツインギター

ディレイタイムを短くしてディレイレベルを大きく、フィードバックを無くす事で、2本のギターが鳴っているように聞かせる事が出来ます。

用途③ 残響

ディレイタイムを少し長めに、ディレイレベルを小さく、フィードバックを長くする事で、狭い会場やスタジオでも、大会場の残響感を再現する事が出来ます。音を歪ませてこれをやるだけですごくギターが上手くなったように聞こえます。この設定でかけっぱなしという事も多いのではないでしょうか。

 

というように様々な用途で使われるディレイですが、同時にコーラスとフランジャーやビブラートなどのエフェクトの元になっています。これらはディレイタイムをリアルタイムで変化させる事でピッチを変化させる事でエフェクトです。

ピッチを変化させられるという事は実はピッチシフターとディレイのピッチ変化は「再生速度を変える」という点で似ています。昔BOSSからピッチシフターとディレイが一台にまとめられた機種が出てたりします。

2. ディレイの原理

アナログディジタル関わらずディレイは図1のようなブロック図になります。

 f:id:hsy221:20181007170855j:plain

      図1 ディレイブロック図

入力された音はディレイ回路に入る信号と出力に送られる信号に分岐します。そして実はディレイエフェクターというのは本来一度しか音を遅延させる事はできません。そこで複数回ディレイさせるためにフィードバック回路が使われます。一度遅延させた音をもう一度入力に戻し、再び遅延させるわけです。入力とフェードバックで返ってきた信号がミックスされ遅延回路に入ります。それをLevelツマミで調整し原音とミックスして出力します。

そうすると結果として、ディレイエフェクターの出力は図2のように減衰します。

f:id:hsy221:20181007173456j:plain

        図2 ディレイ音の減衰

Levelを0.6倍、Feed Backを0.8倍としています。最初のディレイ音とその後のフィードバック音で減衰量が違うのがわかると思います。Levelは全てのディレイ音に影響しますが、Feed Backはフィードバック音にしか影響しません。LevelをマックスにしてFeed Backを0にすれば、同じ音量の初期ディレイ音のみが鳴り、その後のフィードバック音は鳴らないというような設定もできる訳です。原音から均等に音が減衰していくわけではなく、初期ディレイ音から均等に減衰していく事になります。

Feed Backはディレイが鳴る回数だと解説されている事もありますが、それは間違いです。ブロック図の通りに考えればあくまでどれだけ入力に戻すかという値であり、図1のブロック図を正しく理解しないとディレイを使いこなす事は出来ません。

 

アナログディレイ

アナログ回路で信号を遅らせるにはBBD(Bucket Bridge Device)というICが使われます。このICは沢山のコンデンサが充放電を繰り返し信号を伝達する事で、バケツリレーのように音を遅らせていくICです。電気信号をAD変換で言う所のサンプリングを行って単位時間毎に切り取ってコンデンサに充電させ、外部クロックに合わせて次のコンデンサに伝達するという事を繰り返していきます。アナログと言うより半ディジタルという感じですね。コンデンサの数はもちろん決まっているので、ディレイタイムを長くするには外部クロックを遅くします。当然サンプリング周波数が低くなり、さらに一つのコンデンサに長い時間充電される事になり、漏れ電流があります。これにより高周波が落ちて音量が小さくなり、音質が劣化します。それがアナログディレイ特有の温かさと言われたりしますが、ディジタルディレイでこの音質劣化を再現するという事が一般的に行われており、その技術もどんどん高まっています。よっぽどこだわりがある人以外はディジタルディレイですべて事足りるのでは無いかと。

PT2399ディレイ

ディレイを自作する時に使われる定番ICとしてPT2399があります。このIC自体はディジタル処理をしていますが、フィードバック回路やディレイレベルを決める回路はアナログです。よくこのICを使ったディレイはディジタルディレイとして紹介されますが、アナログ回路を通る以上、そこで音質劣化が起きます。先ほど述べた用にBBDを使ったディレイもディジタル的な処理があると言いました。アナログディレイと言ってもフルアナログではなく、ディジタルとアナログの混在という事になります。そういう意味でPT2399も同じくディジタルアナログ混在であるため、アナログディレイであると個人的には思っています。

ディジタルディレイ

 今回はC言語で設計するため、このディジタルディレイを設計する事になります。やる事は一つ、図1のブロック図を数式で表してやればいいだけです。ディレイタイムをdt[sample]、フィードバックをFb、ディレイレベルをLvとして数式に表すと以下のようになります。

f:id:hsy221:20181007193211j:plain

 Lvで括られたかっこの中はブロック図左の加算を表しています。ディレイタイム分だけ遡った過去の信号とフィードバックで返ってきた信号を足し合わせて、Lv倍し、現在の入力信号と加算して出力します。ややこしいのはフィードバック部分ですが、入力信号がk回フィードバックされるとk×dt[sample]遅延し、Fbがk-1回掛かるという事です。

 

3. ソースコード

 

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "header\audioio.h"

int main(int argc, char *argv[])
{
  //変数宣言
  WAV_PRM prm_in, prm_out;
  double *data_in, *data_out;
  int n, k, ds;
  double dt, fb, dL;
  char filename[64];
 
  //コマンドライン引数が違う場合
  if(argc != 2){
    printf("引数が違います\n");
    exit( 1 );
  }
 
  //wavファイルの読み込み
  data_in = audio_read(&prm_in, argv[1]);

  //各種パラメータ入力
  printf("delay time [ms] : ");
  scanf("%lf", &dt);
  printf("feed back [%%] : ");
  scanf("%lf", &fb);
  printf("delay level [%%] : ");
  scanf("%lf", &dL);
  printf("output file name : ");
  scanf("%s", filename);
  dt = dt / 1000 * prm_in.fs;
  ds = (int) dt;
  fb = fb / 100;
  dL = dL / 100;

  //パラメータコピーとメモリ確保
  prm_out.fs = prm_in.fs;
  prm_out.bits = prm_in.bits;
  prm_out.L = prm_in.L;
  data_out = calloc(prm_out.L, sizeof(double));

  //処理
  for (n = 0; n < prm_out.L; n++) {
    if(n >= ds) {
      //初期ディレイ追加
      data_out[n] = data_in[n - ds];
      //フィードバック追加
      k = 2;
      while(pow(fb, k - 1) > 0.05 && n >= k * ds) {
        data_out[n] += pow(fb, k - 1) * data_in[n - k * ds];
        k++;
      }
      //ディレイ音をdL倍
      data_out[n] = data_out[n] * dL;
      //原音を追加
      data_out[n] += data_in[n];
    } else {
      data_out[n] = data_in[n];
    }
  }
 
  //書き込み
  audio_write(data_out, &prm_out, filename);
 
  //メモリ解放
  free(data_in);
  free(data_out);
 
  return 0;
}

 処理の部分はブロック図よりも式と見比べた方が理解しやすいかもしれません。「初期ディレイ追加」の部分は式で言う「入力信号の遅延」の項に対応します。それにフィードバックの項をkを繰り返し加算していきます。この時理論上は無限に足し合わせる事になりますが、プログラミングではそんな事はできません。そこで、係数が0.05以下になったらほぼ聞き取れないとしてそこで処理が終わるようになっています。次にその値にDelay Levelを掛けて、原音を追加して出力します。

 

5.まとめ

今回はディレイをC言語で実現させるだけでは無く、ディレイというエフェクター自体についても色々語りました。まだまだ面白さがあるエフェクターなのですが、私はディレイがエフェクターの中で一番好きです。冒頭でも述べた用にディレイは多くの用途があり、様々なエフェクトの元になっています。他のエフェクトに比べ応用が利くのです。ディレイの可能性は無限大です。アナログディレイだったら発振させても面白いし、ディジタル技術を使えばさらに面白いエフェクトがディレイを元にして作られると思っています。