電音の工場ブログ

趣味の電子工作を中心としたブログです.音モノの工作が多いです.

さらに進捗

さらに進捗

昨日の問題「※2」

TIMER0で約200μs、TIMER1で32kHz(31.25μs)のタイマオーバーフロー割り込みを発生させていて、TIMER1 OVF割り込みが発生して割り込みベクタにジャンプしたときに、まだTCNT0がオーバーフローしていないにもかかわらず TIMER0 OVFのビットが立ってしまう。そのためTIMER1 ISR終了にTIMER0 ISRへジャンプして、ぜんぜん200μsのカウントにならない。http://emusic.g.hatena.ne.jp/Chuck/20080605/p1

アウトプットコンペアの割り込みにしたらこの問題は出なくなった。シミュレータの問題? 実チップ/ICEでは試していない。タイマカウンタをこちょこちょするよりアウトプットコンペア(CTCモード)のほうが正確に、というか割込みサービスルーチンのプロローグ部分の長さを考慮しなくていいぶん楽に、実装できるのです。

  • PCMデータを出力するときには31.25μs(32kHz)のタイマを動かす
  • PCMデータのピッチを可変に
    • 位相アキュームレータがテーブルをルックアップ
    • 位相アップデート幅はツマミをADCして決める
      • 設定値取得は急がない→ポーリング
  • シリアルDACでヴェロシティ値を出力するんだけど
    • もしかしたら時間かかるかも→ポーリング
  • 2ms幅のトリガを作るために200μsの割込みを10回カウント
    • タイマルーチンは軽くしておいてソフト割込みをキックしてそっちは多重許可で

という考えで割込みさんたちを配置した。

31.25μsではパラレルDACに最大4データを出力するのだけど、シミュレーションでは約17μsで通り抜けたのでたぶん大丈夫でしょう。200μsタイマではジッタ*1を持ちつつ10回も呼べばだいたい2msになるので良しと。

32KBの壁

webのwavを変換してテーブルにしてATmega128の広大な*2プログラムエリアに記録して読み出して音にしようという企て。変換プログラムを書こうと調べておいたのだけれどちょっと探したらこちらを発見した。奥村先生ありがとうございます。著作にはしばしばお世話になっております。

さっそく都合の良いフォーマットを出力するようにソースを改変して、

PROGMEM uint8_t tblRide[] = { ... };

などというヘッダファイルを作ってみた。データサイズは32768byte(=32Kbyte)。

コンパイルすると「variable too large」とエラー。うわそういえばanalogさんもそんなことを言っていたなぁ。データを一個削って 32767byteのテーブルを作るとコンパイルエラーにはならなかった。

avr-gcc は int が 16bit で、signed int なので 16bit = -32768~+32767 の数表現で、これ以上の数をコンパイラは数えることができないのではないか。他のCPUでは -mオプション int32 というものもあるのだけれど、avr-gcc ではダメな模様。-fshort-enums をはずしてもダメでした。

ということで、アセンブリ言語でテーブルを置いて、C言語から呼ぶ方法にしようかな、と。

<<続く>>

追記
64KBの壁もありそうだなぁ…

*1:より上位に31.25μs割込みが居て確率的に入ってくるので

*2:128Kbyte!