タイマを使ったマイコンによる演奏
この記事はMice Advent Calendar 2017の18日目の記事です。
とても久しぶりにブログを更新する気がします、あやたかです。
(最後に更新したのは2016年12月16日...なんと1年前w)
さて、皆さん。
今年のマイクロマウスの大会で、"けものフレンズ"の曲をよく耳にしませんでしたか?
その音の正体、僕のAliCeちゃんです(`・ω・´)
ということで今回は僕がどんな感じで音を鳴らしているか書いていこうと思います!
音の三要素
音の三要素とは音の性質を決める最も基本的な要素のことです。
RX631のようなマイコンで音を鳴らす場合には矩形波と呼ばれる波形(Fig.1)を使用します。
Fig.1 矩形波
"音量"は電圧で、"音色"は波形で決まります。
したがって、マイコンでは"周波数"を制御することになります。
また、音をメロディにするにはその音をどのくらいの長さ鳴らすかも必要になります。
矩形波の用意
今回はRX631というマイコンを対象にして矩形波の用意を行います。
矩形波を生成するためにRX631のTPUという機能を使ってPWMモードを使用します。
※MTUという機能でもできます。
PWMモードの動作例です。
Fig.2 PWMモードの動作例
PWMモードの動作は以下の手順で行われます。
① 設定したTGRBの値とTCNTのカウント値が一致(コンペアマッチ)
→ TIOCAの出力がHigh
② 設定したTGRAの値とTCNTのカウント値が一致(コンペアマッチ)
→ TIOCAの出力がLow、TCNTの値リセット
※TCNTとはカウンタの値のことでこのカウンタは一定の周期で値が増えていきます。
※TIOCAとは出力状態を決めるレジスタのことです。PWMモード2では他にTIOCB~TIOCDを選択することもできます。
この機能を使うためにはTCNTの周期やTIOCAと出力端子の割り当てなどの初期設定を行う必要があります。以下にその例を示します。
初期設定例(TPU5のPWMモード2を使用。PWMの出力端子はPB7。)
例では、"MPC.PB7PFS.BIT.PSEL = 0x3u;"で出力端子をPB7、TIOCB5を出力状態を決めるレジスタとして設定しています。
TCNTの周期はTPSCレジスタで設定しています。周期はRX631の周辺モジュールクロックB(PCLKB)を4分周した値に設定しています。今回はPCLKBは50MHzなので周期は12.5MHzに相当します。
TGRAとTGRBの初期値も設定していますが、周波数制御の節で変更します。
※ PCLKA:ETHERC、EDMAC、DEU モジュール用の動作クロック
※ PCLKB:ETHERC、EDMAC、DEU 以外の周辺モジュール用の動作クロック
※ 初期設定はあくまで一例です。詳細はデータシートを参照してください。
音を鳴らす関数の作成
では、実際に音を鳴らす関数を作っていきます。
この際、必要になる要素は以下の2つです。
周波数制御
周波数を制御するにはどうすればよいでしょうか。
ヒントはFig.1とFig.2にあります。
わかりましたか?
TGRAの値を変えれば波形の周期が変わりますよね。
つまり、TGRAの値を変えて周波数を制御すればいいのです。
また、矩形波を扱うのでTGRAとTGRBの値は2:1の関係にしておけばよいですね。
時間制御
さて、これで周波数制御の見通しも立ちました。
最後は音をどのくらいの長さで鳴らすかを制御できれば音を鳴らすことができます。
音の時間単位を扱う際に便利なのは"音符"という考え方です。
"音符"についてはここのサイトがわかりやすいです。
時間管理に"音符"の長さを用いることでより汎用性の高いメロディの作成ができます。
上記の話を踏まえて以下のような音を鳴らす関数を作ってみました。
関数の仕様:
周波数は4行目の"TPU5.TGRA = (int) (12500000 / frq) - 1;"で制御しています。
矩形波なのでTGRBの値は5行目の"TPU5.TGRB = TPU5.TGRA / 2;"のようにTGRAの2分の1です。
音の長さは8行目の"wait_timer((int) (60000.0f / bpm * 4.0f / beat - 10.0f));"で制御しています。ただし、"wait_timer"の引数の単位は[ms]です。
各計算式については各自で考えてもらうこととして省略します。
使用例
使用例ではbpm120でA4の音を8分音符で鳴らしています。
周波数(音名)は英・米式表記で表すのが良いと思います。
なお、440Hz(A4:"ラ"の音)は国際標準ピッチとして知られています。
右は音名表記の一例です。
MIDIファイルを利用した演奏
前回の記事"MIDIを解析してマイコンから音を鳴らそう"で紹介したソフトを使ってMIDIファイルから演奏データを作ることができます。
MIDIについてはひなビタの記事がとても参考になります。
※他にも音楽理論についてわかりやすく書いてあっておすすめです。
以下はこのソフトを使って出力させた演奏データです。
曲はカービィダンスです。
※"REST"は休符で周波数"0"と定義しています。
ハード構成
最後にスピーカー周りの回路構成を載せておきます。
Fig.3 スピーカー周りの回路構成
スピーカーは秋月電子で売っているUGCT7525AN4を使用しています。
スピーカー選びのコツですが欲しい周波数帯の利得が80dB以上あるとそれなりに大きな音量が出る気がします(経験談)。
おわりに
この記事ではタイマを使った演奏法を紹介しました。
今回紹介したのはほんの一例です。
工夫次第で色んな方法が考えられるのも音を扱う楽しみの一つですよね。
また、走行しながら鳴らすには割り込みを使った演奏法を利用しています。
"wait_timer"で行っていた時間制御を割り込みに変えることで走行しながら演奏することができます。
明日はmintomato__氏の"地球の1/10"(を征服する話)です!
それでは!