DX7の音の設定値はネット上で探すと結構見つかります。FM音源による音作りは感覚的に作るのが難しいためこういう情報を参考にすると比較的近い音を作ることができます。
ストリングスの作成
今までピアノに近い減衰音を作ったので今回は持続する音を作ります。イメージとしてはストリングスを元にします。だいたい以下のようなデザインにしました。
- 二つのキャリアを作る。
- キャリアAは一つのモジュレータを持ち音の基本的な部分を鳴らす
- キャリアBは三つのモジュレータを持ち複雑な倍音をつくり元のこすれるような音を表現する。
以下キャリアAは#1でそのモジュレータは#2です。キャリアBは#3でモジュレータは#4から#6です。
エンベロープenv1-env3の指定は<音量>@<到達時間ミリ秒>にしています。リリース時間relもミリ秒にしています。感度sensitivityはキャリアBの方が高めにしています。
実際には構成をざっくりと決めて個別の値は微調整していくことで値を決定します。また実際に他の楽器と重ね合わせてバランスが悪ければ変更することになります。
# | osc | env1 | env2 | env3 | rel | sens | amp | ratio |
---|---|---|---|---|---|---|---|---|
1 | C | 0.99@150 | 500 | 0.4 | 1 | 1 | ||
2 | 1 | 0.9@100 | 0.98@2200 | 0.93@4500 | 5000 | 0.7 | 800 | 1.001 |
3 | C | 1.0@150 | 500 | 0.7 | 0.5 | 1 | ||
4 | 3 | 0.8@200 | 0.98@1700 | 0.99@3200 | 500 | 0.6 | 1000 | 1 |
5 | 3 | 0.8@100 | 0.95@1200 | 1000 | 0.6 | 1000 | 1 | |
6 | 3 | 0.8@100 | 0.98@1200 | 0.9@2500 | 1000 | 0.6 | 1000 | 2 |
作成した音
ソース
以下楽器のソースです。
package mocha.sound.soundbank; import mocha.sound.DoubleMap; import mocha.sound.EnvelopeGenerator; import mocha.sound.Instrumental; import mocha.sound.OscillatorReader; import mocha.sound.Played; import mocha.sound.SineOscillator; import mocha.sound.Temperament; public class FMStrings implements Instrumental { EnvelopeGenerator eg1, eg2, eg3, eg4, eg5, eg6; public FMStrings() { DoubleMap env6 = new DoubleMap(0); env6.putSecondValue(0.1, 0.8); env6.putSecondValue(1.2, 0.98); env6.putSecondValue(2.5, 0.9); eg6 = new EnvelopeGenerator(env6, 1.0, 0.6, 1000); DoubleMap env5 = new DoubleMap(0); env5.putSecondValue(0.1, 0.8); env5.putSecondValue(1.2, 0.95); eg5 = new EnvelopeGenerator(env5, 1.0, 0.6, 1000); DoubleMap env4 = new DoubleMap(0); env4.putSecondValue(0.2, 0.8); env4.putSecondValue(1.7, 0.98); env4.putSecondValue(3.2, 0.99); eg4 = new EnvelopeGenerator(env4, 0.5, 0.6, 1000); //50 55 80 40 99 99 99 0 DoubleMap env3 = new DoubleMap(0); env3.putSecondValue(0.15, 1.0); eg3 = new EnvelopeGenerator(env3, 0.5, 0.7, 0.5); DoubleMap env2 = new DoubleMap(0); env2.putSecondValue(0.1, 0.9); env2.putSecondValue(2.2, 0.98); env2.putSecondValue(4.5, 0.93); eg2 = new EnvelopeGenerator(env2, 5.0, 0.7, 800); DoubleMap env1 = new DoubleMap(0); env1.putSecondValue(0.15, 0.99); eg1 = new EnvelopeGenerator(env1, 0.5, 0.4, 1); } @Override public Played play(double note, double duration, double velocity) { Played played = new Played(); double freq = Temperament.getFreq(note); DoubleMap freq6 = new DoubleMap(freq * 2.00); DoubleMap env6 = eg6.getEnvelope(duration, velocity); DoubleMap fb6 = new DoubleMap(0); OscillatorReader osc6 = new OscillatorReader( new SineOscillator(), freq6, env6, fb6, duration + eg6.getRelease()); DoubleMap freq5 = new DoubleMap(freq * 1); DoubleMap env5 = eg5.getEnvelope(duration, velocity); DoubleMap fb5 = new DoubleMap(0); OscillatorReader osc5 = new OscillatorReader( new SineOscillator(), freq5, env5, fb5, duration + eg5.getRelease()); DoubleMap freq4 = new DoubleMap(freq * 1.0); DoubleMap env4 = eg4.getEnvelope(duration, velocity); DoubleMap fb4 = new DoubleMap(0); OscillatorReader osc4 = new OscillatorReader( new SineOscillator(), freq4, env4, fb4, duration + eg4.getRelease() ); DoubleMap freq3 = new DoubleMap(freq * 1); DoubleMap env3 = eg3.getEnvelope(duration, velocity); DoubleMap fb3 = new DoubleMap(0.2); OscillatorReader osc3 = new OscillatorReader( new SineOscillator(), freq3, env3, fb3, duration + eg3.getRelease(), osc4, osc6, osc5); DoubleMap freq2 = new DoubleMap(freq * 1.001); DoubleMap env2 = eg2.getEnvelope(duration, velocity); DoubleMap fb2 = new DoubleMap(0.01); OscillatorReader osc2 = new OscillatorReader(new SineOscillator(), freq2, env2, fb2, duration + eg2.getRelease()); DoubleMap freq1 = new DoubleMap(freq * 1.0); DoubleMap env1 = eg1.getEnvelope(duration, velocity); DoubleMap fb1 = new DoubleMap(0); OscillatorReader osc1 = new OscillatorReader(new SineOscillator(), freq1, env1, fb1, duration + eg1.getRelease(), osc2); played.addReadable(0, osc3); played.addReadable(0, osc1); return played; } @Override public String getName() { return "FM sound strings"; } }
試し演奏用のコードです。
import java.io.File; import java.io.IOException; import mocha.sound.DoubleMap; import mocha.sound.Instrumental; import mocha.sound.Panner; import mocha.sound.Played; import mocha.sound.TimeLine; import mocha.sound.WavFilePlayer; import mocha.sound.WavFileWriter; import mocha.sound.soundbank.FMStrings; public class FMStringsTest { public static void main(String[] args) throws IOException { TimeLine tl = new TimeLine(); Instrumental inst = new FMStrings(); Played pl1 = new Played(); Played pl2 = new Played(); int i = 0; double duration = 1.5; pl1.addReadable(i++ * duration, inst.play(78, duration, 0.6)); pl1.addReadable(i++ * duration, inst.play(76, duration, 0.6)); pl1.addReadable(i++ * duration, inst.play(74, duration, 0.6)); pl1.addReadable(i++ * duration, inst.play(73, duration, 0.6)); pl1.addReadable(i++ * duration, inst.play(71, duration, 0.6)); pl1.addReadable(i++ * duration, inst.play(69, duration, 0.6)); pl1.addReadable(i++ * duration, inst.play(71, duration, 0.6)); pl1.addReadable(i++ * duration, inst.play(73, duration, 0.6)); pl1.addReadable(i++ * duration, inst.play(74, duration, 0.6)); pl1.addReadable(i++ * duration, inst.play(73, duration, 0.6)); pl1.addReadable(i++ * duration, inst.play(71, duration, 0.6)); pl1.addReadable(i++ * duration, inst.play(69, duration, 0.6)); pl1.addReadable(i++ * duration, inst.play(67, duration, 0.6)); pl1.addReadable(i++ * duration, inst.play(66, duration, 0.6)); pl1.addReadable(i++ * duration, inst.play(67, duration, 0.6)); pl1.addReadable(i++ * duration, inst.play(64, duration, 0.6)); i = 8; pl2.addReadable(i++ * duration, inst.play(78, duration, 0.6)); pl2.addReadable(i++ * duration, inst.play(76, duration, 0.6)); pl2.addReadable(i++ * duration, inst.play(74, duration, 0.6)); pl2.addReadable(i++ * duration, inst.play(73, duration, 0.6)); pl2.addReadable(i++ * duration, inst.play(71, duration, 0.6)); pl2.addReadable(i++ * duration, inst.play(69, duration, 0.6)); pl2.addReadable(i++ * duration, inst.play(71, duration, 0.6)); pl2.addReadable(i++ * duration, inst.play(73, duration, 0.6)); tl.addReadable(0, new Panner(pl1, new DoubleMap(1))); tl.addReadable(0, new Panner(pl2, new DoubleMap(0))); WavFileWriter.create(tl, new File("wav/fmstrings.wav")); WavFilePlayer.playFile(new File("wav/fmstrings.wav")); } }