Go-Challenge-7にエントリーしてみた


Go-Challenge−7って?

サイト: http://golang-challenge.com/go-challenge7/

Go言語を使ったお題に対する回答を集めてより良い回答に賞品をくれる というイベントをやっててその第7回目が開催中(でした)。

(あ・・・これドラフトのまま放置してた・・・。今更ですが公開しておきます・・・)

目標:モバイルデバイス用の仮想ピアノを構築します。

image

挑戦の要件:

  • (少なくとも)Android上で動作すること。
  • キーのセットを表示するのにgolang.org/x/mobile/glパッケージを利用。
  • 音を生成するためにgolang.org/x/mobile/exp/audioパッケージを利用。
  • ユーザー操作で音に作用するのいくつかの仕組みを持っています。

ボーナス機能:

  • 単純なタップ以外の複雑な相互作用を実現する。
  • ユーザーはエクスポート/生成された音楽を保存できる。
  • ユーザーが自分のスキルを示すことができるWebページを作成する。
  • 別のミュージシャンと協奏できる仕組みを提供する。

サンプル画像では14音階のキーが提案としてあげられています。

音の成り立ち

楽器の音は以下のパラメータを基本として音を定量化できます。

  • 音階
  • 音量
  • 波形

1オクターブ上=2倍の周波数で 1オクターブの中に音階は12分割なので 音階nに対し周波数は以下の式で計算できます。 基準をどこかに置く必要があるのですが、定番は440Hz=音叉の音でラ(A)の音ですね。 n=12がラ(A)の音で440Hz。n=0が1オクターブ下のラ(A)で220Hzとなる計算。

f = 220*2**(n/12)

サンプル画像に合わせると、n=2からn=15までの14音階の音が出せれば、 画像と同様のキーに対応する音が出せそうですね。

音階 n 計算式 周波数(Hz)
B 2 220*2^( 212) 246.941650628
C 3 220*2^( 312) 261.625565301
C# 4 220*2^( 412) 277.182630977
D 5 220*2^( 512) 293.664767917
D# 6 220*2^( 612) 311.126983722
E 7 220*2^( 712) 329.627556913
F 8 220*2^( 812) 349.228231433
F# 9 220*2^( 912) 369.994422712
G 10 220*2^(1012) 391.995435982
G# 11 220*2^(1112) 415.304697580
A 12 220*2^(1212) 440.000000000
A# 13 220*2^(1312) 466.163761518
B 14 220*2^(1412) 493.883301256
C 15 220*2^(1512) 523.251130601

音量はエネルギー量を示す。 ピアノは打楽器の一種なので、 打鍵->Max音量まで上昇->減衰->キー離す->さらに減衰速度アップー>エネルギーゼロ。 という流れで音量が変化する。

波形は音色に大きく関係していて、波形をどの形にするかでピアノっぽくなったりフルートっぽくなったり、 幾何学的な波形を持ち込むと電子音っぽくなったりします。 ピアノは弦を叩いた振動音で作られていて正弦波とその倍音によってピアノの波形が形作られます。 ここは職人芸が絡むところなので最後に調整する方向で。

キーに対応する音をどうやって鳴らすか

戦略としては3つ

  • 必要なパラメータをもとに完全に内部で生成する。
  • 波形データにサンプリングデータを用意してそれを加工して生成する。
  • キー一つ一つに対応する音素片をサンプリングしたデータを用意して簡易加工して生成。

サンプリングする場合、再現性を高める効果は得られますが、 高価なピアノと録音環境が必要になるので 個人でこれを実行するのにはお金がかかりすぎます。

なのでここでは完全に内部生成にてピアノ音を作ります。

ピアノの音の成り立ちは弦の振動音をベースにしていて、 弦の振動音はほぼほぼ正弦波と同様と捉えることができます。 また、弦の定倍振動を使っていて倍音成分が多数含まれる音です。

中略

も少し解説書こうと思ってたんですが・・・詳しくは発表資料をどうぞ。

GoConJP2015Winter発表資料: http://golang.rdy.jp/gomobile-piano/#/

まとめ