何かが1秒間に440回振動すると「ラ」の音、440Hz。
倍の880回だと1オクターブ高い「ラ」。220回だと1オクターブ低い「ラ」。
こちらがオクターブ1の「ド」からオクターブ5の「シ」までの、周期の半分の8bitに収まる数値、60コ、60byte。これをテレビ画面に1ライン引くために使っている、15.7068kHzで動くタイマーを流用して鳴らしています。 流用しないで別途タイマーを使うこともできますが、サーボやモーターの速度制御に使う分を確保するとあまりがありません。
240, 226, 213, 201, 190, 179, 169, 160, 151, 142, 134, 127, 120, 113, 106, 100, 95, 89, 84, 80, 75, 71, 67, 63, 60, 56, 53, 50, 47, 44, 42, 40, 37, 35, 33, 31, 30, 28, 26, 25, 23, 22, 21, 20, 18, 17, 16, 15, 15, 14, 13, 12, 11, 11, 10, 10, 9, 8, 8, 7
今回このタイマーをひとまず倍速で動かし精度を上げてみようと思いましたが、1ライン描画するタイマー処理と重なってしまうため、きれいな周期で鳴らすことができず断念。VIDEO0でビデオ出力を止めた時のみ音痴が直るという実装方法ならありかもしれません。 ひとまず今回は倍速化までで容量オーバー。
IchigoJam 1.3.2β16 - 「ichigojam-1.3b16.zip」
(VIDEO0にした際のサウンド倍速化(暫定版)、ビデオ表示調整(VIDEO3以降)、複雑な式でComplex expressionがでるように変更)
付属の圧電サウンダーから、「エイリアンスピーカー」や、ステレオ端子経由やアンプ経由でスピーカーにつなぐとだいぶ良く聞こえます。
SOUND端子ではなく、OUT5端子などに接続し、プログラムで音痴を回避する方法もあります。
IchigoJamのPLAY文と似ているMML風に書くとPWMを使って鳴らしてくれるプログラムが、KidsPod;に公開されています!(by イチゴジャムおじさん)
「ジングルベル PWM_MUSIC/Kidspod;」
「PWM_MUSICの検索結果/Kidspod;」
平均律に近い音階の周期データを計算するC言語のプログラムはこちら!
#include <stdio.h> #include <math.h> int main() { int vsync = 3056; int cpuhz = 48000000; int cnt = 0; for (int i = -33; i <= 26; i++) { double freq = pow(2, (double)i / 12) * 440; double len = 1.0 / freq; double d = len / ((double)vsync / cpuhz); int n = (int)(d + 0.5); //printf("%f %f %d\n", freq, d, n); printf("%d, ", n); cnt++; } printf("\nlen: %d\n", cnt); return 0; }