sound with arduino

arduinoで音を制御(録音, 再生etc)したい時用の個人的まとめです. 

最終的には[録音/再生](
https://qiita.com/keitasumiya/items/5cbbe64bf4aa143faa6b#4-%E5%86%8D%E7%94%9F%E3%81%A8%E9%8C%B2%E9%9F%B3%E3%82%92%E3%82%B9%E3%82%A4%E3%83%83%E3%83%81%E3%81%A7%E5%88%B6%E5%BE%A1
)ができるようにしています. 
[動画](https://www.youtube.com/watch?v=UrobzOrxhTw)

[![setting_rec-play.jpg](https://qiita-image-store.s3.amazonaws.com/0/102253/2ea203b9-8008-6a21-30b9-f079ac4aaa71.jpeg)](
https://qiita.com/keitasumiya/items/5cbbe64bf4aa143faa6b#4-%E5%86%8D%E7%94%9F%E3%81%A8%E9%8C%B2%E9%9F%B3%E3%82%92%E3%82%B9%E3%82%A4%E3%83%83%E3%83%81%E3%81%A7%E5%88%B6%E5%BE%A1
)


# 1. 再生
## 1-1. mp3を再生する
SDカードにmp3の音源を入れ, moduleを使用して再生します. 

- 良: moduleのおかげで簡単に再生できる
- 悪: moduleが必要
- 悪: 用意した音源しか再生できない

### 参照
[『FN-M16P(DFPlayer Mini)』電子工作で音楽（MP3）を鳴らすなら、これ。Arduinoから制御もできるよ。](http://www.noboyu.com/entry/2016/10/30/213604)

### 使用したmodule
[FN-M16P Embedded MP3 Audio Module（DFPlayer Mini）](http://akizukidenshi.com/catalog/g/gM-12544/)

### code
```FN-M16P_test.ino
//『 FN-M16P Embedded MP3 Audio Module 』（DFPlayer Mini）のテスト。
//start(pin8)で再生start、next(pin9)で次の曲、stop(pin10)で停止
//シリアルコマンドを送る試験


#include <SoftwareSerial.h>

#define start 8        // 置き換え（start→ ”8”)
#define next 9        // 置き換え（next→ ”9”)
#define stop 10       // 置き換え（stop→ ”10”)
#define play 11       // 置き換え（play→ ”11”)

int s1=0,s2=0,s3=0,s4=0;

void setup() {
  Serial.begin (9600);    //シリアルポートを開き、転送速度を9600bpsに設定
  delay(1);                     // delay 1ms to set volume
  pinMode(start,INPUT);   // start(ピン8)を入力に設定
  pinMode(next,INPUT);    // next(ピン9)を入力に設定
  pinMode(stop,INPUT);    // stop(ピン10)を入力に設定
  pinMode(play,INPUT);    // play(ピン11)を入力に設定
  //pinMode(13,OUTPUT);   // 13を出力に設定
}

void loop(){
  s1=digitalRead(start);
  if(s1==0){        // startが押されるまで待つ
    //ファイル指定再生
    Serial.write(0x7E);
    Serial.write(0xFF);
    Serial.write(0x06);
    Serial.write(0x0F);  //「フォルダ指定再生」コマンド
    Serial.write(0x00);
    Serial.write(2);  //この例では、「02」というFOLDER名が指定される
    Serial.write(1);  //この例では、「001.mp3」というファイル名のmp3が指定される
    Serial.write(0xEF);
    delay(10);
    while(1){
      s2=digitalRead(next);
      s3=digitalRead(stop);
      s4=digitalRead(play);
      if(s4==0){        // playが押されるまで待つ
        delay(100);
        Serial.write(0x7E);
        Serial.write(0xFF);
        Serial.write(0x06);
        Serial.write(0x0D); //再生コマンド
        Serial.write(0x00);
        Serial.write(0x00); //
        Serial.write(0x00); //
        Serial.write(0xEF);
        delay(100);
      }
      if(s2==0){        // nextが押されるまで待つ
        //次の曲へ
        delay(100);
        Serial.write(0x7E);
        Serial.write(0xFF);
        Serial.write(0x06);
        Serial.write(0x01); //次曲再生コマンド
        Serial.write(0x00);
        Serial.write(0x00); //
        Serial.write(0x00); //
        Serial.write(0xEF);
        delay(1000);
      }
      if(s3==0){        // stopが押されるまで待つ
        //停止
        Serial.write(0x7E);
        Serial.write(0xFF);
        Serial.write(0x06);
        Serial.write(0x0E); //ポーズCMD
        Serial.write(0x00);
        Serial.write(0x00); //
        Serial.write(0x00); //
        Serial.write(0xEF);
        delay(10);
        //break;
      }
    }
  }
}
```



## 1-2. arduinoのみで再生する
- PWMのピンを利用し, 2.5Vを中心に0~5Vで電圧を揺らすことで, PWMピンから直接再生する
- そのままのPWMだと遅くて(?)不適なのでFastPWMを利用
- PROGMEMを使用してフラッシュメモリーに書き込みます(32KBなのでプログラム部分を除くと8000Hzで最大約4秒)
- PWMなので音の振幅の解像度は8bit(256)
- 音の波形を[0,255]で表現できれば良い. 作成方法は自由(WAV音源を変換する方法を下記では紹介). 
- 音源のサンプリングレートはdelayMicrosecondsで調整(例:8000Hzなら125[=1/8000]). ただし, プログラム内容によっては微調整が必要そう. 
- 悪: フラッシュメモリにはconstで事前に書き込むので録音等はできない

### 参照
FastPWM
[Arduino Nano の PWM 機能を使ってみた（FastPWM 編 その２）　[Arduino]](http://makers-with-myson.blog.so-net.ne.jp/2016-02-16)
[Secrets of Arduino PWM](http://www.righto.com/2009/07/secrets-of-arduino-pwm.html)
[DelayからTimer割り込みに変更](http://us360.jp/mugbot/mug160703/)

arduinoとスピーカーだけで音を出す方法
[Arduinoとスピーカだけで音声を出す　[Arduino]](http://hello-world.blog.so-net.ne.jp/2016-10-18)
[【Arduino】WAVまたはMP3ファイルを再生する](http://nn-hokuson.hatenablog.com/entry/2017/09/01/092945)

program memoryについて
[avr/pgmspace.h : Program Space Utilities](http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html)

### 配線
```スピーカー.
GND: スピーカーの-
  3: スピーカーの+
```

### 256の音源を作る

>
作成例
1. test.wavを用意する
2. rawにformat変換
audacityで`サンプリング周波数8000Hz`, `その他の非圧縮ファイル`, `RAW(header-less)`, `Unsigned 8-bit PCM`と指定して`test.raw`を作る
3. ターミナルで`xxd -i sample.raw`を実行して数値に変換する
4. `0x7f, 0x80, 0x7f, ...`みたいな数値列(16進数)ができた

最終的な数値は`127, 128, 127, ...`のように10進数であってもOK

### code
(私の「あいう」の声が無限に流れますが悪しからず...)

```sound-out_arduino.ino
#include <avr/pgmspace.h>
const unsigned char sample_raw[] PROGMEM = {
108,108,108,108,108,118,108,118,118,118,118,128,118,118,128,118,118,128,138,128,138,128,128,128,128,128,128,128,128,128,128,128,128,128,118,118,118,128,128,118,118,118,128,118,128,128,128,118,118,118,118,128,128,118,118,128,128,128,118,118,128,138,158,148,138,128,128,128,138,148,138,148,138,128,118,118,108,118,108,98,98,98,108,108,118,108,118,138,118,108,98,88,98,128,128,128,128,128,118,118,108,108,118,118,118,128,128,128,138,128,128,128,118,118,128,128,128,128,128,128,128,118,118,118,118,118,128,128,138,138,138,128,118,128,128,138,138,148,138,118,108,128,118,128,118,108,108,118,118,98,108,108,128,138,148,128,128,128,118,128,138,138,138,148,138,138,128,118,118,118,118,118,118,118,118,118,118,118,108,108,108,108,108,128,118,118,118,108,118,118,118,118,118,118,118,128,128,118,128,118,118,128,118,128,128,128,118,118,118,118,128,128,128,128,128,108,128,118,118,138,138,128,138,138,118,138,128,128,138,148,148,158,118,98,98,98,118,148,158,148,158,118,128,118,128,128,138,118,118,128,128,128,128,108,98,108,98,108,118,108,108,108,98,98,108,108,108,108,118,118,118,118,128,128,118,128,128,128,128,128,128,128,128,128,118,128,118,128,128,118,118,128,128,128,138,128,128,128,128,138,138,118,128,128,128,128,148,108,128,128,118,108,118,148,128,158,128,118,108,138,118,118,118,98,128,148,128,108,128,108,118,138,128,108,128,128,128,128,118,118,128,128,118,118,118,118,118,118,108,108,108,108,108,108,108,108,118,118,108,118,118,118,118,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,118,108,118,128,138,138,128,118,118,138,128,128,128,128,138,138,138,118,98,128,148,158,138,118,118,128,128,108,118,118,118,138,128,118,138,138,128,128,128,118,128,138,128,118,128,128,128,118,108,108,108,108,108,108,108,108,108,108,108,108,108,118,108,118,118,118,118,128,128,128,128,128,118,128,128,128,128,118,118,128,128,118,128,128,128,128,128,118,128,128,138,128,128,128,138,138,138,128,108,138,148,128,98,128,148,128,118,128,138,118,118,108,98,128,148,118,108,128,128,128,148,128,128,148,158,128,128,118,118,128,128,108,108,118,108,118,118,98,88,108,118,108,108,98,108,118,118,108,108,108,118,128,128,118,118,138,128,128,128,128,128,138,128,118,118,128,128,128,118,118,118,128,128,128,128,128,138,128,128,128,118,128,148,138,138,118,148,118,128,138,118,108,138,158,88,118,128,128,118,148,88,98,148,168,158,148,158,138,178,138,108,88,118,98,108,98,78,98,128,128,88,98,98,128,118,108,88,118,128,138,118,88,108,138,138,108,108,108,138,138,118,98,118,138,138,128,108,118,138,148,118,118,118,138,138,118,108,118,138,138,128,108,108,138,148,128,98,118,148,148,128,128,118,138,158,138,108,138,158,128,118,118,118,98,128,98,118,168,158,138,148,178,148,158,98,98,108,128,88,68,88,108,128,98,98,88,128,128,118,98,108,128,128,118,98,108,128,138,118,108,118,138,138,118,108,108,138,128,118,108,118,138,148,128,118,128,138,138,118,118,128,138,128,118,118,128,138,128,128,128,128,128,128,118,118,128,118,128,118,148,148,138,138,138,128,118,118,118,108,108,138,138,168,158,158,148,168,158,128,108,98,108,78,78,68,88,88,98,88,98,118,128,128,128,148,118,128,118,118,108,108,108,108,108,108,128,118,128,128,128,128,128,128,118,128,118,128,118,128,128,128,128,118,128,128,138,128,128,128,128,128,128,118,118,128,118,128,118,128,138,138,118,148,128,118,148,138,108,128,128,108,158,128,148,168,158,158,178,148,138,158,108,108,88,68,68,68,58,58,78,68,98,108,118,138,148,138,158,158,128,138,128,118,118,108,98,108,108,98,118,108,118,128,128,128,138,138,138,138,128,128,128,128,118,118,118,118,118,118,118,118,128,118,128,138,118,128,138,118,128,128,138,118,138,128,128,128,128,118,138,148,148,158,148,168,168,168,148,158,138,128,118,88,88,68,58,48,58,48,68,78,88,108,118,138,148,158,158,168,148,158,148,128,128,118,98,98,108,78,98,98,108,108,118,118,128,128,128,148,128,138,138,138,128,128,128,118,118,118,118,118,118,118,118,118,128,128,138,128,138,138,128,148,128,138,148,138,158,148,148,168,178,158,168,158,138,138,108,108,88,68,58,58,38,48,58,58,78,98,118,128,148,148,168,168,168,158,158,148,148,118,118,118,98,98,88,88,88,98,98,98,108,118,128,138,138,138,148,138,148,138,138,128,128,118,118,108,108,108,108,108,108,118,118,118,138,118,138,148,128,148,148,168,148,168,168,178,168,168,168,158,148,128,128,98,88,78,58,48,48,48,48,58,68,88,108,128,138,158,168,168,178,178,168,158,148,138,138,128,98,108,108,88,88,98,98,88,108,108,128,118,128,138,138,128,138,138,128,128,128,128,118,118,118,108,108,118,108,118,108,128,118,128,128,138,138,148,158,158,178,168,188,178,188,168,178,148,148,118,108,88,68,58,38,48,28,48,38,68,68,98,108,128,148,158,168,178,178,178,178,168,158,148,138,118,138,88,98,108,78,88,108,88,88,118,98,118,108,128,128,128,128,138,128,128,138,118,128,118,128,118,118,108,128,98,128,118,118,138,128,128,158,138,148,188,138,198,158,178,168,168,148,148,128,108,118,78,88,58,68,48,48,48,58,68,78,98,108,128,128,148,158,158,168,168,158,168,158,158,138,148,128,118,118,108,98,98,98,88,108,88,108,98,108,108,128,108,118,128,128,128,128,138,118,128,118,128,118,128,118,118,118,118,118,128,128,148,128,168,168,148,198,158,198,168,188,158,168,128,128,118,78,88,58,68,38,48,48,58,48,78,88,98,118,128,138,148,158,168,168,168,168,168,168,158,148,138,148,108,118,118,98,98,108,88,98,98,88,108,98,108,108,118,108,128,118,138,128,128,128,138,128,128,138,118,128,118,128,108,128,118,118,138,138,128,168,148,158,188,158,188,168,168,158,158,128,138,108,88,88,58,68,48,58,48,58,58,78,88,98,118,128,138,148,158,168,158,168,158,168,158,158,138,148,138,108,138,108,98,108,118,78,108,88,98,88,98,108,98,108,118,128,108,138,118,138,118,138,128,128,138,118,138,118,128,118,128,118,128,138,128,148,168,138,178,168,168,178,168,168,158,148,128,128,98,98,78,68,58,48,58,58,58,68,88,88,108,118,128,138,138,158,158,168,168,178,158,178,158,138,168,118,128,118,108,98,108,88,88,88,78,98,78,98,98,108,108,128,118,138,138,138,148,128,148,128,138,128,128,128,118,118,128,118,118,128,128,138,158,138,168,168,158,178,168,168,158,158,138,128,108,98,88,68,68,48,58,48,58,58,68,78,88,108,118,138,138,158,148,178,168,168,168,168,158,148,158,118,138,108,118,98,108,88,88,98,88,98,88,108,98,118,108,128,118,128,128,128,138,128,138,128,138,118,138,128,128,128,128,128,118,148,128,158,138,148,168,158,168,168,178,158,158,148,138,118,108,98,78,68,58,58,48,48,58,68,78,78,98,108,118,138,148,158,158,168,168,168,158,188,138,158,158,128,128,118,108,88,108,78,98,68,98,88,88,98,108,108,108,138,128,148,128,158,138,138,148,138,128,128,138,118,128,118,128,118,118,12,128,148,128,158,168,158,168,168,178,148,158,148,138,108,108,88,78,58,58,58,38,58,58,68,68,98,108,118,118,138,148,148,168,168,168,168,158,168,158,138,148,138,128,118,108,108,98,88,98,88,78,98,88,88,108,108,108,128,128,138,138,148,148,148,138,148,148,138,128,138,128,118,138,118,118,148,128,138,158,158,158,168,158,168,158,148,148,128,118,108,88,68,68,58,48,48,48,58,68,68,88,98,108,128,138,148,148,168,168,168,168,178,168,158,168,148,138,128,128,98,108,98,88,78,78,88,78,88,88,98,98,118,118,128,138,148,148,148,158,148,148,138,148,128,138,118,128,128,118,138,138,128,148,158,148,168,168,168,168,158,148,138,118,108,98,78,68,58,48,48,48,58,58,68,78,98,108,118,138,148,158,158,178,168,168,178,178,158,158,158,138,128,118,118,88,98,88,78,78,78,88,78,88,98,108,108,128,128,138,148,148,158,148,158,158,138,148,138,138,118,118,138,108,118,148,118,128,158,148,158,168,168,158,168,148,158,128,108,118,88,78,68,68,48,58,48,58,68,68,88,98,108,118,148,138,158,158,168,178,168,168,178,158,148,158,118,128,118,98,88,88,78,78,78,78,88,78,98,108,108,118,138,138,138,158,158,158,158,158,148,148,148,128,128,128,128,108,138,128,118,158,148,148,158,168,148,168,158,148,138,118,118,98,78,68,68,48,48,58,58,58,68,88,98,108,118,138,148,148,178,158,188,168,178,178,158,148,148,138,108,138,98,98,88,88,68,78,88,78,98,88,118,108,118,128,148,138,148,158,148,158,148,148,138,148,128,128,128,118,128,108,138,128,128,148,158,148,148,178,148,158,158,148,138,118,108,98,78,68,78,48,48,58,58,58,78,88,98,108,118,138,148,148,178,158,178,178,158,178,168,148,148,148,108,118,118,88,78,88,78,68,88,78,88,88,108,108,118,128,138,138,138,168,148,148,158,158,138,138,148,128,128,128,118,138,128,128,148,148,148,158,168,148,158,158,138,128,128,108,88,88,68,68,48,48,58,58,58,78,88,98,108,128,138,148,158,168,168,178,198,148,178,178,138,138,158,118,88,138,78,78,88,88,48,88,88,68,98,98,118,108,138,138,158,148,158,158,158,158,158,148,128,138,138,128,108,158,118,108,158,158,128,158,188,138,148,168,148,118,128,118,88,78,68,68,48,48,58,58,58,68,98,98,108,128,148,138,158,178,168,178,198,168,168,188,148,128,148,128,78,108,108,48,68,88,58,48,98,78,78,108,128,108,138,168,148,158,168,168,148,158,158,138,138,148,128,108,148,128,108,148,158,128,138,188,148,128,168,158,108,118,128,88,68,78,78,48,48,68,58,58,78,88,88,108,128,138,148,158,168,168,178,198,168,168,178,158,128,148,128,78,98,98,58,48,88,58,48,88,98,78,98,138,128,138,168,168,158,168,178,158,158,158,148,128,138,128,128,128,128,128,148,158,138,158,168,148,138,158,138,108,108,108,78,58,78,58,48,48,68,58,68,88,98,98,118,148,148,158,168,178,188,178,178,188,168,148,158,138,98,108,108,68,58,78,68,48,68,88,78,88,118,118,128,148,158,158,168,168,168,168,158,148,148,148,128,128,128,128,118,128,138,138,138,148,158,148,148,148,148,118,118,108,88,78,68,58,48,58,58,58,68,78,88,108,118,128,148,158,168,168,188,188,168,178,178,148,138,148,118,88,98,88,58,68,68,58,58,78,88,88,108,118,138,148,158,158,168,178,168,168,168,158,148,138,138,128,118,128,118,118,128,138,138,148,158,148,148,148,138,128,118,108,98,78,78,68,58,58,58,58,68,78,88,98,118,128,138,148,168,178,168,178,188,168,158,158,148,118,108,108,88,68,78,58,58,68,78,78,98,108,118,138,148,148,158,168,168,168,168,168,158,148,148,138,128,118,118,118,118,128,128,138,138,148,158,158,148,148,148,128,118,108,98,78,68,68,58,58,58,58,68,78,88,108,118,128,148,158,168,178,188,178,178,178,168,148,138,128,108,98,88,78,58,58,58,58,68,78,88,108,118,128,148,158,168,168,178,178,178,168,168,148,138,128,118,118,118,118,118,128,138,138,148,158,158,148,158,148,138,128,118,98,88,78,68,58,58,58,58,68,78,88,98,118,128,148,158,168,178,178,188,188,178,168,158,148,128,108,98,88,68,68,58,58,58,68,78,88,98,118,138,148,158,168,178,178,178,178,168,158,158,148,128,128,118,118,118,118,118,128,138,148,148,158,158,158,148,138,128,118,108,88,78,68,58,48,48,58,58,68,78,98,108,128,138,158,168,178,188,198,188,188,178,158,148,138,118,98,78,68,58,58,48,58,58,68,78,98,118,128,148,158,168,178,178,188,178,178,168,158,148,138,128,118,108,108,118,118,128,128,138,148,158,158,158,158,148,138,128,118,98,88,68,58,48,48,48,48,58,68,78,98,118,138,148,168,178,188,198,198,188,188,178,158,138,128,98,88,68,58,48,48,48,48,68,78,88,108,128,148,158,178,178,188,188,188,178,168,158,148,138,118,108,108,98,108,108,118,128,128,148,148,158,168,168,158,148,138,128,108
};
const unsigned int sample_raw_len = sizeof(sample_raw);

void setup() {
  pinMode(3, OUTPUT);
  TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(CS20);
  
}

void loop(){
  play();
  //delay(2000);
}

void play() {
  for (int i = 0; i < sample_raw_len; i++) {
    OCR2B = pgm_read_byte_near(&sample_raw[i]);
    delayMicroseconds(125);
  }
}
```


# 2. 録音
「録音する」といってもwavを作るとかではなく, 上記の「arduinoのみで再生する」を前提にした録音です. 必要であればPC等で適宜wav等に変換していただくということで...
ざっくりいって「analog-inの数値をSD-cardに記録するだけ」です. 

- micをanalog-inに接続して記録
- ECM等だとオペアンプ+電圧シフトで2.5V中心の[0V, 5V]で電圧が揺れるようにする必要がある. 
- analog-inの10bitの数値を8bit(1byteで記録するため)に変換してSD cardに記録
- printlnではなくwriteを利用しbyte(16進数. 00=0, 10=16 等)で記録する. 
- これは再生時に使用するreadが[ASCII](http://www9.plala.or.jp/sgwr-t/c_sub/ascii.html)で読み込むため. printlnで記録すると10進数で記録されるため1桁ずつreadした後に1つ数値として復元する処理が必要になってしまい, 再生速度に間に合わなくなってしまう. 

## マイク
ECM等のマイクだと本来, 音を0Vを中心に+/-で微振動するのみ. arduinoのanalog inに突っ込んでもノイズと変わらないので検知できない. 故に

- 信号増幅: マイクからの信号をオペアンプ等で100倍ほど増幅し, 振幅を5V程度にする
- 電圧シフト: analog inが正値のみを受け取るため, 2.5Vを中心に[0V, 5V]で揺れるようにレベルシフトする

を行う必要がある. 
自分で回路を組んでも良いが, 

- [秋月 高感度マイクアンプキット](http://akizukidenshi.com/catalog/g/gK-05757/)
- [スイッチサイエンス エレクトレット・コンデンサ・マイク・モジュール](https://www.switch-science.com/catalog/374/)
- [スイッチサイエンス ADMP401搭載MEMSマイクモジュール(一応, 5Vでも動いてます)](https://www.switch-science.com/catalog/419/)

等のオペアンプ付のマイクモジュールを利用すると楽. 
(というか, 電気回路を自分で組むのはまだ上手くいってないです... どなたか教えて欲しい)

## 参照
マイクモジュール
- [秋月 高感度マイクアンプキット](http://akizukidenshi.com/catalog/g/gK-05757/)
- [スイッチサイエンス エレクトレット・コンデンサ・マイク・モジュール](https://www.switch-science.com/catalog/374/)
- [スイッチサイエンス ADMP401搭載MEMSマイクモジュール (メモ: 私は5Vでも動いてます)](https://www.switch-science.com/catalog/419/)

回路全体
- [arduinoとマイク(ECM)のテスト1](http://isa.asablo.jp/blog/2010/04/19/5028403)
- [Arduinoで遊ぼう - エレクトレット・コンデンサ・マイクでオーディオレベルメータを作る](http://arms22.blog91.fc2.com/?tag=ECM)
- [ESP8266とコンデンサマイクを接続してAnalogReadで録音してBluemixで音声認識させてデバイスを制御する](https://qiita.com/matobaa/items/46f08312d20a3ef4d2a7)

マイク
- [デジタルマイクSPM0405HD4Hがデジタルで動いた！ (メモ: 私は上手く行かず...)](https://jiwashin.blogspot.jp/2016/06/finally-i-can-read-spm0405hd4h-by-esp8266.html)
- [秋月 SPM0405HD4H シリコンマイク](http://akizukidenshi.com/download/ds/akizuki/AE-SPM0405HD4H.pdf)

オペアンプ
- [オペアンプで始めるアナログ回路](http://www.mech.tohoku-gakuin.ac.jp/rde/contents/course/mechatronics/analog.html)
- [オペアンプ回路の基本設計法](http://www.picfun.com/partops.html)
- [DIY Tengu on a breadboard](https://tinkerlog.com/2007/10/22/diy-tengu-on-a-breadboard/)
- [マイクアンプ基本形](http://www002.upp.so-net.ne.jp/jsrc/densi/micamp.html)
- [386アンプをちょっと真剣に作ってみた](http://hpabegin.cocolog-nifty.com/blog/2012/02/386-1413.html)
- [ＬＭ３８６　パワーアンプＩＣ](http://www.iccraft.com/parts/ic/lm386.html)
- [秋月 LM386 オーディオアンプＩＣ　ＮＪＭ３８６ＢＤ](http://akizukidenshi.com/catalog/g/gI-00022/)

書き込み
- [println()](https://www.arduino.cc/en/Serial/Println)
- [serial.write()](https://www.arduino.cc/reference/en/language/functions/communication/serial/write/)
- [ASCII コード表](http://www9.plala.or.jp/sgwr-t/c_sub/ascii.html)

SDカード
- [HiLetgo Micro SD/ TF カードモジュール シールド モジュール 6 ピン SPI [並行輸入品] ](http://amzn.asia/9duwSG8)
- [ArduinoでSDメモリカードを読み書きする](http://arms22.blog91.fc2.com/blog-entry-502.html)
- [SPI library](https://www.arduino.cc/en/Reference/SPI)
- [Arduino で SPI 転送テスト](http://mkusunoki.net/?p=3307)
- [SD Library](https://www.arduino.cc/en/Reference/SD)
- [Using the SD library to retrieve information over a serial port](https://www.arduino.cc/en/Tutorial/CardInfo)
- [Using the SD library to read and write to a file on a SD card](https://www.arduino.cc/en/Tutorial/ReadWrite)

arduino
- [2.Arduinoのピン使用の基本を押さえよう](http://daisuki-arduino.com/arduino-pin/)
- [analogRead(pin)](http://daisuki-arduino.com/arduino-analogread/)

ノイズ
- [ローパスフィルタ](https://ja.wikipedia.org/wiki/%E3%83%AD%E3%83%BC%E3%83%91%E3%82%B9%E3%83%95%E3%82%A3%E3%83%AB%E3%82%BF)
- [ノイズ対策部品/EMI除去フィルタ](https://www.murata.com/ja-jp/products/emc/emifil/knowhow/basic/chapter02-p2)
- [第6回 コンデンサは最もシンプルなノイズフィルタ](http://www.tdk.co.jp/techmag/emc/200409/index.htm)
- [なるほどノイズ入門](http://www.tdk.co.jp/techmag/emc/index.htm)

## 配線
上記のモジュールであれば, 

```マイク.
 5V: VCC (arduino以外の5V電源[電池等]を使うとノイズが減ります)
GND: GND (arduino以外の5V電源[電池等]を使うとノイズが減ります)
 A0: AUDIO
```

でOKです. 
SD cardは, [以前の記事](https://qiita.com/keitasumiya/items/144f3326e63161d9d74d)のように

```SD_card.
 11: DI (MOSI)
 12: DO (MISO)
 13: CLK (SCK)
  9: CS (chip select)
GND: GND
 5V: VCC
```

で繋げばOKです(以前の記事とくらべて, 配線の並びを個人的美的感覚の関係でCSを4から9に変えました). 

## code

```rec.ino
#include <SD.h>
const int chipSelect = 9;
File dataFile;
int count = 0;

void setup(){
  pinMode(SS, OUTPUT);
  SD.begin(chipSelect);
}

void loop(){
  count++;
  if(count == 1){
    openSDToRecord();
  }else if(count >= 10000){
    closeSD();
    count = 0;
  }else{
    recordValue();
  }
}

//##########################################################
void openSDToRecord(){
  SD.remove("data.txt");
  dataFile = SD.open("data.txt", FILE_WRITE);
}

void recordValue(){
  int valuePre = analogRead(0);
  int value = int(float(valuePre)/4.0);
  dataFile.write(value);
}

void closeSD(){
  if (dataFile) {
    dataFile.close();
  }
}
```

## 録音したdataの形(確認)
DATA.TXTという形で録音したデータを保存していますが, それをPCのテキストエディタで開いてみると

```DATA.TXT
76a8 bc94 9e76 6c76 8a76 9476 626c 7680
948a 6c6c 626c 7680 7680 7680 8a9e 9e76
.
.
.
```

という感じで16進数で保存されているのがわかります. 

# 3. 録音した音声を再生

## 配線

```スピーカー.
GND: スピーカーの-
  3: スピーカーの+
```

```SD_card.
 11: DI (MOSI)
 12: DO (MISO)
 13: CLK (SCK)
  9: CS (chip select)
GND: GND
 5V: VCC
```


## code

```sound-out_sd-rec-data.ino
#include <SD.h>
const int chipSelect = 9;

void setup(){
  Serial.begin(9600);
  pinMode(3, OUTPUT);
  TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(CS20);
  pinMode(SS, OUTPUT);
  SD.begin(chipSelect);
  Serial.println(OCR2B);

}

void loop(){
  File dataFile = SD.open("data2.txt");
  if (dataFile) {
    while (dataFile.available()) {
      OCR2B = dataFile.read();
      delayMicroseconds(100);
    }
    //Serial.println(value);
    dataFile.close();
  }
  Serial.println(OCR2B);
  delay(2000);
}
```



# 4. 再生と録音をスイッチで制御
上記の再生と録音に加えてスイッチを組み合わせることで, 簡単なサンプラーを作ることができます. 
(チチチ...という謎のノイズがマイク, スピーカーにのってしまっています. 調べ中)

## 配線

```スピーカー.
GND: スピーカーの-
  3: スピーカーの+
```

```マイク.
 5V: VCC (arduino以外の5V電源[電池等]を使うとノイズが減ります)
GND: GND (arduino以外の5V電源[電池等]を使うとノイズが減ります)
 A0: AUDIO
```

```SD_card.
 11: DI (MOSI)
 12: DO (MISO)
 13: CLK (SCK)
  9: CS (chip select)
GND: GND
 5V: VCC
```

```スイッチ.
5V & GND & 5: 録音スイッチ
5V & GND & 6: 再生スイッチ
```

![setting_rec-play.jpg](https://qiita-image-store.s3.amazonaws.com/0/102253/2ea203b9-8008-6a21-30b9-f079ac4aaa71.jpeg)


## code
再生後に録音する際にFastPWMを直すために

```
  OCR2B = 0;
```
を追加しています. 

```rec-play.ino
#include <SD.h>
const int chipSelect = 9;
const int pinRecordSW = 5;
const int pinPlaySW  = 6;
const int pinPlaySound = 3;

int stateRecordSW;
int countRecordSW;
int statePlaySW;
int countPlaySW;
boolean isRecordMode;
boolean isPlayMode;
File dataFile;


void setup(){
  Serial.begin(9600);

  pinMode(pinPlaySound, OUTPUT);
  TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(CS20);

  pinMode(SS, OUTPUT);
  SD.begin(chipSelect);

  //pinMode(pinRecordSW,  INPUT_PULLUP);
  pinMode(pinRecordSW,  INPUT);
  pinMode(pinPlaySW,  INPUT);
  stateRecordSW = 0;
  countRecordSW = 0;
  isRecordMode = false;
  statePlaySW = 0;
  countPlaySW = 0;
  isPlayMode = false;
}

void loop(){
  readPIN();
  
  controlRecordMode();
  if (isRecordMode){
    recordValue();
    //delay(1000);
  }

  controlPlayMode();
  if (isPlayMode){
    playValue();
  }  
}

//##########################################################
//##########################################################
//##########################################################

void controlRecordMode(){
  if (stateRecordSW == 1){
    countRecordSW++;
    if (countRecordSW == 10){

      if (!isRecordMode){
        if (isPlayMode){
          isPlayMode = false;
          closeSD();
        }
        isRecordMode = true;
        openSDToRecord();
        if (!dataFile) {
          openSDToRecord();
        }
      } else if (isRecordMode){
        isRecordMode = false;
        closeSD();
      }
      
      delay(1000);
    }
  } else {
    countRecordSW = 0;
  }
}

void controlPlayMode(){
  if (statePlaySW == 1){
    countPlaySW++;
    if (countPlaySW == 10){

      if (!isPlayMode){
        if (isRecordMode){
          isRecordMode = false;
          closeSD();
        }
        isPlayMode = true;
        openSDToPlay();
        if (!dataFile) {
          openSDToPlay();
        }
      } else if (isPlayMode){
        isPlayMode = false;
        closeSD();
      }
      
      delay(1000);
    }
  } else {
    countPlaySW = 0;
  }
}

void readPIN(){
  stateRecordSW = digitalRead(pinRecordSW);
  statePlaySW  = digitalRead(pinPlaySW);
}

void openSDToRecord(){
  SD.remove("data.txt");
  dataFile = SD.open("data.txt", FILE_WRITE);
  Serial.println("SD was opened to Record");
}

void openSDToPlay(){
  dataFile = SD.open("data.txt");
  Serial.println("SD was opened to Play");
}

void recordValue(){
  //int value = analogRead(0);
  int valuePre = analogRead(0);
  int value = int(float(valuePre)/4.0);
  dataFile.write(value);
  //Serial.print("Record:");
  //Serial.println(value);
}

void playValue(){
  while (dataFile.available()) {
    OCR2B = dataFile.read();
    //delayMicroseconds(150);
    delayMicroseconds(150);
    //int value = dataFile.read();
    //Serial.println(value);
  }
  isPlayMode = false;
  closeSD();
}

void closeSD(){
  if (dataFile) {
    dataFile.close();
    Serial.println("SD was closed");
  }
  OCR2B = 0;
}
```

## 動画
https://www.youtube.com/watch?v=UrobzOrxhTw