MIDI音源を編集してスピーカで鳴らすまでの話
マイコンでスピーカを鳴らしてみました.
くそ雑魚なので,偉大な先輩方の技術を学ばせていただいています.このブログより以下のブログの方が役立つと思います.
音楽的な知識がないので多分適当なこと書いていると思います.その点もご了承ください...
<参考記事>
[1]STMのPWMでスピーカを鳴らす&スピーカに必要な関数について
[2]スピーカ周辺の回路
[3]MIDI音源を使ったスピーカ用音源の作り方について
スピーカで音を鳴らす際に必要となる要素は,
- 音の高さ(周波数)
- 音の長さ(待ち時間)
です.マイコンで音源を鳴らすためには,最低この二つの情報を配列か何かで事前に持っている必要があります.音の大きさについてはDuty比をいじることで変えることはできると思いますが,Duty比は基本的に1/2で固定するので大きさについては変更しません.
音の高さと音階について
音の高さは周波数です.ISOによって制定された?基準周波数はA4の440 Hzです.音階というのは感覚的なもののように感じますが,一オクターブ上がるごとに周波数は2倍になり,その間の音は12等分されています.
すなわち,1音上がることに,周波数は倍されて,
1オクターブ上がって倍音となると,周波数は倍となります.
プログラムで実装する際は,計算誤差と計算時間を考えなければ,事前に音の周波数をすべて書き込まなくても,for文を回してを基準周波数からの音階番号の差の分だけ掛ける(または割る)ことで得ることはできます.
音の長さについて
音楽を鳴らす速度についてbpm(beat per minute)というものがあります.一分間に鳴らすビート(拍)の数というのはいいんですが,拍がどのくらいの長さなのか決まっていないっぽい?ということで,僕はよくわからないので四分音符♪を1拍分としました.MIDIでは音の長さをtickという単位で記録しますが,四分音符が何tickかは決めなければなりません.僕は,480tickを四分音符の長さとしています.
60 bpmの場合,一分間に四分音符が60回なります.だから,四分音符の長さは 1 sです.
一般化して,
ms
ms
となります.
MIDI音源を配列化する
あやたかさんのブログを参照してください.
ネット上のMIDI音源を配列化するためには,MIDI音源から音の高さと音の長さの情報を得る必要があります.加えて多くの音源は複数の楽器を用いているので,トラックが分かれていて,同時に複数の音が鳴ります.1つのスピーカーでかつ簡単な矩形波では単音しかならせないので,音源を適当な形に編集する必要があります.
需要があるかは知りませんが僕がした方法を載せておきます.
フリーでオープンソースのMIDIシーケンサー・MIDI編集ソフト『世界樹』
②単音のみになるように音源の編集
一つのトラックに主旋律を拾い集める.
③イベントリスト(ノートオンのみにチェック)をCSVでエクスポート
右側のチェックの欄でノートオンのみにして,CSVで吐き出し.
④エクセル上で配列としてコピペできる状態にする.
R列に{音階番号,音を鳴らす時間[tick],全体の時間(音を鳴らす時間+その後の待ち時間)[tick]}をまとめて,コピペできるようにした.
四分音符の長さを480tickとすると,1拍は480tick,1小節は4×480tickになるはずです.
⑤配列の初期化の部分にコピペで実装.
クオリティを求めるとブログを公開しなくなりそうなので,適当な記事でお許しください...そのうち気が向いたら割り込みで実装する話とか具体的なプログラムの話とかを書こうと思います().
ブログ用 キー変更 pic.twitter.com/odcLC70Lzs
— makoto (@VrIyoe) 2019年5月21日