第29章. 楽曲を書いて書き換える
この章の目的
この章を読み終える頃には、楽曲を書き換えて、その変化を耳で聴いた状態になります。この章を読み終える頃には、楽曲を書き換えて、その変化を耳で聴いた状態になります。
楽曲はあなたが学んだもの全て
examples/scripts/piano_roll/piano_roll_0.kelをテキストエディタで開いてください。一覧の中で最も単純な楽曲で、その中のすべての部分はガイドですでに扱ってきたものです。examples/scripts/piano_roll/piano_roll_0.kelをテキストエディタで開いてください。一覧の中で最も単純な楽曲で、その中のすべての部分はガイドですでに扱ってきたものです。
- 先頭の
useの行は、第16章で導入したホストのネイティブをインポートしています。先頭のuseの行は、第16章で導入したホストのネイティブをインポートしています。 enum Pitchを宣言しています — これは第11章の列挙型です。12の音名とRest(休符)が並んでいます。enum Pitchを宣言しています — これは第11章の列挙型です。12の音名とRest(休符)が並んでいます。- 普通の
fnヘルパー — 第6章の関数 — が音を調べる役を果たします。それぞれが第13章のmatchを使っています。普通のfnヘルパー — 第6章の関数 — が音を調べる役を果たします。それぞれが第13章のmatchを使っています。 data stateブロック — 第18章のものです。- エントリーポイントは
loop main— 第17章のもので、initブロックと第27章で説明したティックごとの本体を持っています。エントリーポイントはloop main— 第17章のもので、initブロックと第27章で説明したティックごとの本体を持っています。
楽曲は特別な種類のファイルではありません。第1部から第7部までのすべての部品で組み立てられたKeleusmaのプログラムです。楽曲は特別な種類のファイルではありません。第1部から第7部までのすべての部品で組み立てられたKeleusmaのプログラムです。
音符の表
あるチャンネルが演奏する音の並びは、ヘルパー関数channel_noteの中に書かれています。チャンネル0(メロディ)については、音の位置に対するmatchを持っています。その最初のアームがメロディの第1音です。あるチャンネルが演奏する音の並びは、ヘルパー関数channel_noteの中に書かれています。チャンネル0(メロディ)については、音の位置に対するmatchを持っています。その最初のアームがメロディの第1音です。
0 => (Pitch::C, 5, 4), // C major: C E G E
このタプルは、ピッチがC、オクターブが5、長さは16分音符4つぶん(つまり4分音符)、という意味です。これがメロディが始める音です。このタプルは、ピッチがC、オクターブが5、長さは16分音符4つぶん(つまり4分音符)、という意味です。これがメロディが始める音です。
書き換えてみる
その第1音を変えてみます。アームを書き換えて、メロディをCの代わりにEで始まるようにします。その第1音を変えてみます。アームを書き換えて、メロディをCの代わりにEで始まるようにします。
0 => (Pitch::E, 5, 4), // C major: C E G E
実行する前に、楽曲がまだコンパイルできるかを確認します。
keleusma compile examples/scripts/piano_roll/piano_roll_0.kel -o /tmp/song.bin
ツールはwrote ... bytesの行を表示します。Pitch::EはPitch列挙型の本物のヴァリアントで、タプルの形も変わらないので、変更は妥当なKeleusmaです。もし書き換えがプログラムを壊していたら、このステップが音を試す前にエラーを報告してくれていたはずです。ツールはwrote ... bytesの行を表示します。Pitch::EはPitch列挙型の本物のヴァリアントで、タプルの形も変わらないので、変更は妥当なKeleusmaです。もし書き換えがプログラムを壊していたら、このステップが音を試す前にエラーを報告してくれていたはずです。
聴いてみる
ピアノロールをもう一度走らせます。
cargo run --release --example piano_roll --features sdl3-example
楽曲0のメロディがEで始まるようになりました。ホストはビルドのときに楽曲ファイルを新しく読み直すので、ファイルを編集して走らせ直すこと自体が、繰り返しのループになっています。これが作曲のループです — 楽譜を変えて、結果を聴いて、また変えて。楽曲0のメロディがEで始まるようになりました。ホストはビルドのときに楽曲ファイルを新しく読み直すので、ファイルを編集して走らせ直すこと自体が、繰り返しのループになっています。これが作曲のループです — 楽譜を変えて、結果を聴いて、また変えて。
さらに先へ
同じchannel_note関数の中に、チャンネル1のベースラインと、チャンネル2のハーモニーがあります。楽曲0のすべての音は、これらのmatchブロックのどれかのアームです。ピッチを変えて、オクターブを変えて、長さを変えてみてください。initブロックのhost::set_waveformの呼び出しを変えれば、チャンネルに別の楽器を持たせられます。各変更はkeleusma compileが確認して、ピアノロールを走らせれば聴けます。同じchannel_note関数の中に、チャンネル1のベースラインと、チャンネル2のハーモニーがあります。楽曲0のすべての音は、これらのmatchブロックのどれかのアームです。ピッチを変えて、オクターブを変えて、長さを変えてみてください。initブロックのhost::set_waveformの呼び出しを変えれば、チャンネルに別の楽器を持たせられます。各変更はkeleusma compileが確認して、ピアノロールを走らせれば聴けます。
この章のまとめ
- 楽曲は普通のKeleusmaプログラムで、ガイド全体の機能で組み立てられています。楽曲は普通のKeleusmaプログラムで、ガイド全体の機能で組み立てられています。
- 楽曲の音符は、音符表関数の
matchアームの中のタプルです。 - 編集ループは、
.kelファイルを変えて、keleusma compileで確認して、ピアノロールを走らせて、聴く、です。編集ループは、.kelファイルを変えて、keleusma compileで確認して、ピアノロールを走らせて、聴く、です。
次の章では10曲すべての一覧を見学します。