電音の工場ブログ

当ブログは…

自作エフェクターシンセサイザ製作のネタや開発覚え書きなど、筆者の電音活動を記録しています。お探しの記事が見つからない方は、検索カテゴリ一覧をご利用ください。

スパマーが来訪すると、ときどきコメントをはてなユーザのみに絞ったり開放したりすることがあります。

2008-06-06

さらに進捗

| さらに進捗 - 電音の工場ブログ を含むブックマーク はてなブックマーク - さらに進捗 - 電音の工場ブログ さらに進捗 - 電音の工場ブログ のブックマークコメント

昨日の問題「※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!

通りすがり通りすがり2008/06/09 12:15avr-gccではlong型は使えないのでしょうか?
int型が16bitの処理系では、long型は32bitが一般的です。

ChuckChuck2008/06/09 12:55ごめんなさい、書き方が悪かったです。
avr-gcc のコンパイラの内部動作仕様として定数は32767までと数えているのではないかと考え、デフォルトintのビット数が増やせるなら増やすことでコンパイラの内部動作が変わらないだろうかと妄想して上記のように書いてしまいました。
結局 uint_8の配列は32767まで、uint16_t の配列は16383まで、uint32_t の配列は8191までなら "too large"エラーは出ないようです。

トラックバック - http://emusic.g.hatena.ne.jp/Chuck/20080606