※ 本記事は,2003年1月号付属CPLD基板をご活用
いただいた読者の方による投稿レポートです.
クロック発振回路(発振周波数は64kHz)と圧電サウンダで自動演奏を行う電子オルゴールを製作しました.演奏データもハードウェア化しています.HDLの特徴を生かして,楽譜をそのまま表現できるようにくふうしています.基板は,2003年1月号の「キッチン・タイマの製作」で使用した基板(写真1,図1)をそのまま利用しました.
[写真1] キッチン・タイマの外観
[図1] キッチン・タイマの回路図
●音と周波数
まず,回路を組むための基本データとなる音階と分周比の関係を表1に示します.平均律音階では,中心の“ラ”の音の周波数が440Hz,その1オクターブ低い“ラ”の音が220Hzになります.この間の1オクターブの音階を,
音階の周波数=220×2^(n/12) nは,1から12の整数
として計算します.なお,表1には,基本クロックとして64kHzを使用する場合の分周比も示しています.基本クロック周波数が変われば,この値も変わるので注意してください.また,音符のデータとしては,この半分になる値(82)を使います.
音階の番号 |
音階 |
平均律音階の周波数 |
分周比(CLK=64000) |
分周比の半分 |
オクターブ高いときの分周 |
0 |
ラ |
220 |
290.91 |
145 |
72 |
1 |
ラ# |
233.08 |
274.58 |
137 |
68 |
2 |
シ |
246.94 |
259.17 |
129 |
65(si) |
3 |
ド |
261.63 |
244.62 |
122(do) |
61(octdo) |
4 |
ド# |
277.18 |
230.9 |
115 |
57 |
5 |
レ |
293.66 |
217.94 |
109(re) |
54(octre) |
6 |
レ# |
311.13 |
205.7 |
102 |
51 |
7 |
ミ |
329.63 |
194.16 |
97(mi) |
48(octmi) |
8 |
ファ |
349.23 |
183.26 |
92(fa) |
46(octfa) |
9 |
ファ# |
369.99 |
172.98 |
86 |
43 |
10 |
ソ |
392 |
163.27 |
82(so) |
41(octso) |
11 |
ソ# |
415.3 |
154.11 |
77 |
38 |
12 |
ラ |
440 |
145.45 |
73(ra) |
36 |
[表1] 平均律音階の周波数
音階が1オクターブ高いときには,この分周比は,半分の値になります.また,1オクターブ低いときには,2倍の値になります.
ここでは,“Happy Birthday”の音楽を例に,楽譜の作成について説明します.音楽をまず,“ドレミ”の文字で表現します.“_”は音階と音階の間や休み記号として使います.この音階とその音階を発している長さ(時間)で表現します.製作したオルゴール向けの“Happy Birthday”の楽譜は,以下のようになります.
ソソ_ソ_ラララ_ソソソ_ドドド_シシシシシシ_
実際の楽譜で,いちばん短い音符を文字一つ分として考えます.つまり,文字一つ分の長さは,いちばん短い音の長さに合わせて決めた単位で,“Happy Birthday”では,0.25sとします.“ソソ”と2回続けば,0.5s間“ソ”の音(392Hz)が続くことを表します.
●回路の構成
全体の構成を図2に示します.
[図2] 全体の構成図
まず,音階テーブル(melody)に音楽のメロディになるデータを入れておきます.つまり楽譜の役割をしています.音の長さの最小単位である0.25sごとにこのテーブルからデータを読み出し,音階生成カウンタ(musicosc)に音階生成データとして与えます.カウント数を変化させることで(例えば,ソならば392Hz)音階の周波数を作り出します.
※Verilog HDLソース・コード(music.v)はここからダウンロードできます.
inclkは,64kHzのクロックを16000分周して,0.25s(4Hz)のタイミングを作っています.cts025は,音階テーブルのアドレスを作るカウンタで,4Hzで動作します.cts025の出力信号は,テーブルmelodyのアドレスになり,0.25sごとにインクリメントします.音階テーブルmelodyのアドレスは,0.25sごとに変化するので,出力のoutmusicも同様のタイミングで変化します.“Happy Birthday”は105個のデータで演奏されるので,cts025は,0から105までカウントします.
音階生成カウンタのmusicoscは,outmusicの値によって,カウントする値が可変できます.64kHzのクロックの分周比をoutmusicの値によって変えることで,カウンタ出力の周波数に変化をつけて,音程の周波数を作り出しています.
音の出力の原理を図3に示します.例えば,テーブルの値がsoのときには,outmusic=82となり,カウンタmusicoscは,82進のカウンタになります.この値は,outmusicの値が変わるまで続きます.カウンタmusicoscの値が,0になったときだけmusicflg=1になります.これを2分周すると,ちょうど,デューティ比50パーセントの音階の発振(392Hz)出力moutになります.
[図3]
moutは,圧電サウンダに接続されていて,その振動が音楽として聞こえます.テーブルの値がBrのときには,何も音を出さない状態です.outmusic=0となります.このときmusicosc=0なので,この間のmusicflgはHighになり,発振しません.
●HDLによる楽譜の記述
Verilog HDLでは,数値を人間が理解しやすい記号で表現できます.そこで音階をローマ字風に記述できるようにしました.define文を使って,あらかじめ分周比の数値を音階記号に定義しておきます.例えば,“ソ”は82なので,以下のようになります.
`define so 82
今回作成したソース・ファイル(music.v)には演奏に必要な部分だけを記述しています.データの定義を増やすほど出力可能な音の周波数は増えます.
楽譜は,以下のように記述していきます.
0:melody=`so;
これは,最初の音が“ソ”であることを示しています.この音階を書き換えれば,他の音楽を演奏させることができます.
●まとめ
人が見てわかりやすい記述で音符データを作るくふうをしました.楽譜を記号化するだけで,自分だけのオルゴールを設計できます.気軽に試してみてください.
※できあがった音楽のwaveファイル(happy.wav)はここからダウンロードできます.
参考文献
1)吉澤純夫,『VisualBasicで物理がわかる 音波シミュレーション入門』,CQ出版,2002年9月.
|