2025年2月3日月曜日

12平均律を鳴らすプログラムについて考える

これまでの続きです。Raspberry Pi Picoを使って、音を鳴らすこと(楽曲の演奏)ができるところまではやってみましたが、これも以前IchigoJamで「(PC用)キーボードを鍵盤のように使って音楽の演奏をする」ことにチャレンジしたように、各キーに任意の音を割り振って楽曲の演奏ができるようにすることができないか、そのプログラムはどう書いたらよいのかということについて考えています。

キーボードの各キーに1音1音を割り当てるのは、力技ではあるものの可能であることは想像ができます。しかし今回は、できるだけスマートにプログラムを書くことを目標に考えていきたいと思っています。そのため、「12平均律の式をプログラムに活かす」ことを目指し、12平均律の仕組みや音の周波数はどのような式で表せるのか、そしてそれをプログラムとして書き表せるのかを検証することにしました。
#以下、わかっている人には当たり前の話が続きます。広い心でご覧ください。(^^;;;

はじめに、「A*2^(n/12)」を使って12平均律の音階をExcelでグラフ化してみました。(「A=440」としてセルに入力した値を参照させ、nはAを0としてAから半音上を1、全音上を2…と表したセルを参照させた)すると、見覚えのある曲線のようなものが見えてきます。すっかり忘れていたので、記憶を頼りに「〇〇曲線」とか「〇〇関数」とか、いろいろなキーワードでGoogle先生に尋ねてみました。

すると、当たり前ではありますが「y=a^x(aのx乗)」の描く曲線にたどり着きました。「指数関数」というやつですね。昔学んだことを思い出してきました。以前にPicoで音を鳴らしたときのMicroPythonでのプログラムの中に、「ahz*(2**(2/12))」や「ahz * (2 ** (3/12))」のような表記をしましたが、「ahz」がA4の周波数を表していて、それに「2の(2/12)乗」や「2の(3/12)乗」をかけるという計算をしています。もう少し汎用的な式で表すと「A[i]*2^(n/12)」というような式になると思います。「i=4」なら「A[4]=440」、「i=3」なら「A[3]=220」となるようにプログラムして、「n」の値を「0」〜「12」までの数値で変化させれば、音階に必要な周波数が得られると考えました。

Excelで作った表には、以前紹介した「12平均律と周波数」で示されている数値と同じ周波数値が並びました。第1段階はクリアできました。しかしこれだと、A[i]の値をいちいち用意しなければなりません。そこで、「A[i]*2^(n/12)」(0≦n≦12)という考え方を改めて、初項の「ahz=440」だけを決めて、「ahz*2^(z/12)」(z=整数)という数式で考えることにしました。「z」には、12を超えた数を入れたり、0よりも小さい負の数を入れたりしても、「A4=440Hz」からの音階的な距離(1あたりの変化量は半音)で表現できることがわかり、実際にExcelで表を作って平均律の周波数を得ることができることも確かめました。

MicroPythonでのプログラミングでは、「ahz*(2**(z/12))」のように表現すればよいことになります。この関数に、「A4」の距離を「0」として、そこからの音階的な距離を表す数値「z」を入れると目的の周波数が得られることになります。これならば、「ahz=442」にしたとしても、12平均律を簡単に作ることができるはずです。

試しにプログラムを作ってみているのですが、どうもうまく動かなくてまだ試行錯誤中です。うまくいったら、失敗の原因も含めてお知らせできればと思っています。

0 件のコメント: