LoginSignup
10
9

More than 5 years have passed since last update.

Ableton Live の Operator の設定値を WebAudioAPI で利用する

Last updated at Posted at 2015-08-15

スクリーンショット 2015-08-16 7.05.17.png

Ableton Live の FM音源 Operator では Coarse と Fine の値で各オシレーターの周波数の調節ができます。

調節後の周波数を求める式は以下のとおり。

outputFrequency = inputFrequency * Coarse * (1 + Fine / 1000);

上記の式をすごく雑に説明すると、計算前の周波数に対する比率を計算していて、Coarse が整数部分、Fine が小数点以下の部分となっています。

計算後の周波数 = 計算前の周波数 * Coarse.Fine

# Coarse = 11, Fine = 965 のときなら、計算前の周波数に 11.965 をかける

そこで、以下のような関数を用意すると..

function convertFineIntoRatio(fine) {
  if (fine < 0) {
    return 1 / (1 - fine / 1000);
  }
  return 1 + fine / 1000;
}

冒頭のスクリーンショットの設定は、このように書ける。

opA.frequency.value = frequency *  0.5 * convertFineIntoRatio(993);
opB.frequency.value = frequency * 12.0 * convertFineIntoRatio(  0);
opC.frequency.value = frequency *  0.5 * convertFineIntoRatio(995);
opD.frequency.value = frequency * 11.0 * convertFineIntoRatio(965);

マイナス値の設定にも対応しているので、このようにも書ける。

opA.frequency.value = frequency *  1.0 * convertFineIntoRatio( -7);
opB.frequency.value = frequency * 12.0 * convertFineIntoRatio(  0);
opC.frequency.value = frequency *  1.0 * convertFineIntoRatio( -5);
opD.frequency.value = frequency * 12.0 * convertFineIntoRatio(-35);

比率からMIDIノート番号を計算してやれば、その100倍が detune の値となるので、以下のような関数を用意すると..

function convertFineIntoDetune(fine) {
  var sign = fine < 0 ? -1 : +1;
  var ratio = 1 + Math.abs(fine) / 1000;

  return sign * Math.log(ratio) * Math.LOG2E * 12 * 100;
}

このように書ける。

opA.frequency.value = frequency * 0.5;
opB.frequency.value = frequency * 12;
opC.frequency.value = frequency * 0.5;
opD.frequency.value = frequency * 11;

opA.detune.value = convertFineIntoDetune(993);
opB.detune.value = convertFineIntoDetune(0);
opC.detune.value = convertFineIntoDetune(995);
opD.detune.value = convertFineIntoDetune(965);

もしくはマイナス値を使ってこう。

opA.frequency.value = frequency;
opB.frequency.value = frequency * 12;
opC.frequency.value = frequency;
opD.frequency.value = frequency * 12;

opA.detune.value = convertFineIntoDetune(-7);
opB.detune.value = convertFineIntoDetune(0);
opC.detune.value = convertFineIntoDetune(-5);
opD.detune.value = convertFineIntoDetune(-35);

ちなみに Level 値の dB は以下の式で変換できるので、

function convertDecibelIntoGain(db) {
  return Math.pow(10, db * 0.05);
}

こう書ける。

opALevel.gain.value = convertDecibelIntoGain(-2.8);
opBLevel.gain.value = convertDecibelIntoGain(-22);
opCLevel.gain.value = convertDecibelIntoGain(-5.7);
opDLevel.gain.value = convertDecibelIntoGain(-40);

けど、多分変調方式が異なる (よくある位相で変調するやり方に対して、Web Audio API は周波数でしか変調できない) のでゲインの値は適宜調節が必要。

僕はモジュレーターのゲイン値は勘で調節している。

opALevel.gain.value = convertDecibelIntoGain(-2.8);
opBLevel.gain.value = convertDecibelIntoGain(-22) * frequency * 20;
opCLevel.gain.value = convertDecibelIntoGain(-5.7);
opDLevel.gain.value = convertDecibelIntoGain(-40) * frequency * 20;

これをFMアルゴリズムに従って接続すれば そこそこ 同じ音がつくれる。

参考にしたトピック
https://forum.ableton.com/viewtopic.php?f=4&t=26560

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9