FM音源:フィードバックの導入(2)

スポンサーリンク

前回オシレーターをフィードバック対応にしたので今回はそれを読み込む側の修正を行います。

FM音源:フィードバックの導入(1)

オシレーター読み込みクラスOscillatorReaderの改修

public class OscillatorReader implements SoundReadable

フィールドにフィードバック用のエンベロープを追加します。

DoubleMap fbMap;

またコンストラクタも変更します。

public OscillatorReader(
  Oscillatable oscillatable, DoubleMap freqMap, DoubleMap envMap, DoubleMap fbMap, double seconds,
  SoundReadable... freqModulators) {
  this.oscillatable = oscillatable;
  this.freqMap = freqMap;
  this.envMap = envMap;
  this.fbMap = fbMap;
  this.seconds = seconds;
  this.freqModulators = freqModulators;
}

読み込みの処理を変更します。オシレーターのreadを呼び出す問いにフィードバックエンベロープから取得した値を投げるようにします。

@Override
public double read() {
  double omega_t = freqMap.next();
  for (SoundReadable freqModulator : freqModulators) {
    omega_t += freqModulator.read();
  }
  return oscillatable.read(omega_t, fbMap.next(), 1) * envMap.next();
}

音出しによる確認

ここまで出来たところで試しで音を出したいと思います。オシレーターと音量を指定して500Hzの高さで3秒の長さの音を作るメソッドを作ります。

public static OscillatorReader getOscillatorReader(Oscillatable oscillatable, double fbAmp) {
  DoubleMap freq = new DoubleMap(500);
  DoubleMap env = new DoubleMap(1);
  DoubleMap fb = new DoubleMap(fbAmp);

  env.putSecondValue(3, 0);
  return new OscillatorReader(oscillatable, freq, env, fb, 3.0);
}

次に試し演奏をします。
フィードバックの出力を0、1.1、2、2.2、5でサイン波、三角波、ノコギリ波、矩形波のオシレーターで鳴らします。

TimeLine tl = new TimeLine();
int i = 0;

tl.addReadable(i++ * 3, getOscillatorReader(new SineOscillator(), 0));
tl.addReadable(i++ * 3, getOscillatorReader(new SineOscillator(), 1.1));
tl.addReadable(i++ * 3, getOscillatorReader(new SineOscillator(), 2));
tl.addReadable(i++ * 3, getOscillatorReader(new SineOscillator(), 2.2));
tl.addReadable(i++ * 3, getOscillatorReader(new SineOscillator(), 5));

tl.addReadable(i++ * 3, getOscillatorReader(new TriangleOscillator(), 0));
tl.addReadable(i++ * 3, getOscillatorReader(new TriangleOscillator(), 1.1));
tl.addReadable(i++ * 3, getOscillatorReader(new TriangleOscillator(), 2));
tl.addReadable(i++ * 3, getOscillatorReader(new TriangleOscillator(), 2.2));
tl.addReadable(i++ * 3, getOscillatorReader(new TriangleOscillator(), 5));

tl.addReadable(i++ * 3, getOscillatorReader(new SawOscillator(), 0));
tl.addReadable(i++ * 3, getOscillatorReader(new SawOscillator(), 1.1));
tl.addReadable(i++ * 3, getOscillatorReader(new SawOscillator(), 2));
tl.addReadable(i++ * 3, getOscillatorReader(new SawOscillator(), 2.2));
tl.addReadable(i++ * 3, getOscillatorReader(new SawOscillator(), 5));

tl.addReadable(i++ * 3, getOscillatorReader(new SquareOscillator(), 0));
tl.addReadable(i++ * 3, getOscillatorReader(new SquareOscillator(), 1.1));
tl.addReadable(i++ * 3, getOscillatorReader(new SquareOscillator(), 2));
tl.addReadable(i++ * 3, getOscillatorReader(new SquareOscillator(), 2.2));
tl.addReadable(i++ * 3, getOscillatorReader(new SquareOscillator(), 5));

WavFileWriter.create(tl, new File("wav/fb.wav"));

サイン波が一番効果があることがわかります。

スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

%d人のブロガーが「いいね」をつけました。