Attiny85 でオーディオピッチシフターを作る


やりたいこと

マイクで録った音に連動して、ウーファーを動かしたい。
中音域の音でも、ウーファーを振動させるようにするため、1オクターブ下げる。
ウーファーに入力される中高音域とノイズを除去するために、LPFを通す。

必要なもの

セットアップ

  • Arduino上で、'Preferences'-> Additional Boards Manager URLs にURLをコピペする.Windowsの場合は、ファイル→環境設定
http://digistump.com/package_digistump_index.json

Toolsで以下の様に設定。

  • Macの場合のみ? USB Hub経由じゃないとデバイスを認識せずエラーとなる。
  • uploadボタンを押下後60秒以内に、ATtiny を挿入
  • なぜか途中で失敗するが、Deviceをつないだまま、再度Uploadボタンを押すとうまく行った

コード

リファレンスコードのビルド

1オクターブ下げる

上記のコードと異なり、今回作りたいのは、ざっくり1オクターブ下げるものを作りたい。
てことで、OCR0Aを変更し、決め打ちに。

  // OCR0A = 55;                             // 17.9kHz interrupt
  OCR0A = 28; // 約1オクターブ下げる

また、ボタンの割り込みをコメントアウト


//// Pin change interrupt adjusts shift
//ISR (PCINT0_vect) {
//  int Buttons = PINB;
//  if ((Buttons & 0x01) == 0) OCR0A++;
//  else if ((Buttons & 0x04) == 0) OCR0A--;
//}
//////////// 中略 //////
  // Set up buttons on PB0 and PB2
  // pinMode(0, INPUT_PULLUP);
  // pinMode(2, INPUT_PULLUP);
  // PCMSK = 1<<PINB0 | 1<<PINB2;            // Pin change interrupts on PB0 and PB2
  // GIMSK = GIMSK | 1<<PCIE;                // Enable pin change interrupt

ローパスフィルタを作る

簡単な一次のLPFを作り、不要な音を除外


volatile uint16_t alpha = 10;
volatile uint16_t alpha_max = 255;
volatile uint8_t previous_output = 0;

uint8_t lpf (uint8_t input){
  uint8_t output = alpha * input / alpha_max  + (alpha_max - alpha) * previous_output / alpha_max;
  previous_output = output;
  return output;
}

そして、DACにわたす値をLPF通過後の値にする。

  OCR1A = lpf(Buffer[ReadPtr]);

参考