前回は通奏低音について説明しました。今回はパッヘルベルのカノンの通奏低音を実装したいと思います。
使用する音の一覧
通奏低音ではベースの音が与えられています。その上に重ねる和音は数字や記号での指定がない限りその曲の調での3和音triadです。4分音符2章節分で8種類の和音を定義します。音高の数字はMIDIのノート番号と同じです。
ベース | ベースの音高 | コード名 | 構成音 | コードの音高 |
---|---|---|---|---|
D | 50 | Dmaj | A D F# | 57, 62, 66 |
A | 45 | Amaj | C# E A | 61, 64, 69 |
B | 47 | Bmin | B D F# | 59, 62, 66 |
F# | 42 | F#min | A C# F# | 57, 61, 66 |
G | 43 | Gmaj | B D G | 59, 62, 67 |
D | 38 | Dmaj | A D F# | 57, 62, 66 |
G | 43 | Gmaj | B D G | 59, 62, 67 |
A | 45 | Amaj | A C# E | 57, 61, 64 |
実装
では実装をします。
曲に指定はないのですがテンポは40bpmにします。遅めにするのは曲の中盤で32分音符のフレーズがでるためあまり早くすると不自然になってしまうからです。拍子は4拍子です。楽器は前回作ったFM音源の楽器を使います。
TempoMap tempoMap = new TempoMap(40); Measures Played = new Measures(new TimeSign(4), tempoMap); Instrumental inst = new SecondInstrument();
右手と左手で別の演奏者を設定します。右手と左手の音を左右にパニングするためです。
Player rightHand = new Player(Played, inst); Player leftHand = new Player(Played, inst);
右手の演奏情報を定義します。配列の配列にします。最初の配列は演奏するコードの数、後の配列は一度に演奏するコードの各音を表します。
double[][] rightNotes = new double[][]{ new double[]{57, 62, 66}, new double[]{61, 64, 69}, new double[]{59, 62, 66}, new double[]{57, 61, 66}, new double[]{59, 62, 67}, new double[]{57, 62, 66}, new double[]{59, 62, 67}, new double[]{57, 61, 64},};
左手の演奏情報を定義します。こちらは単音なので1次の配列です。
double[] leftNotes = new double[]{50, 45, 47, 42, 43, 38, 43, 45};
アルペジオ時間を指定します。4分音符が1なので0.0625は64分音符になります。bpmが40と遅いので64分音符でも十分アルペジオ効果を得ることができます。
double arpegio = 0.0625;
2小節を1回として4回繰り返すようにしました。
for (int i = 0; i < 4; i++) { leftHand.play(leftNotes[0], 1, 0.9, 0.7); rightHand.play(rightNotes[0], 1, 0.9, 0.6, arpegio); leftHand.play(leftNotes[1], 1, 0.9, 0.7); rightHand.play(rightNotes[1], 1, 0.9, 0.6, arpegio); leftHand.play(leftNotes[2], 1, 0.9, 0.7); rightHand.play(rightNotes[2], 1, 0.9, 0.6, arpegio); leftHand.play(leftNotes[3], 1, 0.9, 0.7); rightHand.play(rightNotes[3], 1, 0.9, 0.6, arpegio); leftHand.nextMeasure(); rightHand.nextMeasure(); leftHand.play(leftNotes[4], 1, 0.9, 0.7); rightHand.play(rightNotes[4], 1, 0.9, 0.6, arpegio); leftHand.play(leftNotes[5], 1, 0.9, 0.7); rightHand.play(rightNotes[5], 1, 0.9, 0.6, arpegio); leftHand.play(leftNotes[6], 1, 0.9, 0.7); rightHand.play(rightNotes[6], 1, 0.9, 0.6, arpegio); leftHand.play(leftNotes[7], 1, 0.9, 0.7); rightHand.play(rightNotes[7], 1, 0.9, 0.6, arpegio); leftHand.nextMeasure(); rightHand.nextMeasure(); }
最後はパニングをしてファイルに書き出せば終了です。
TimeLine tl = new TimeLine(); tl.addReadable(0, new Panner(leftHand.getPlayed(), new DoubleMap(0.75))); tl.addReadable(0, new Panner(rightHand.getPlayed(), new DoubleMap(0.25))); WavFileWriter.create(tl, new File("wav/pachelbelCanon.wav"));
実行結果
2小節を4回繰り返したので8小節の長さになっています。アルペジオのように右手の和音がずれているのが聞こえましたでしょうか?