LoginSignup
4
7

More than 5 years have passed since last update.

Arduinoにしゃべらせてみたトレース&PCMデータの作り方

Last updated at Posted at 2016-12-13

この記事はIoTLT Advent Calendar 2016の14日目の記事です。

昨日は @narikei さんのElectronで作ったデスクトップアプリとArduinoでシリアル通信して遊ぼうでした。


はじめに(と言い訳)

今回、はやしよのすけさんの【冬休みの工作】Arduinoをしゃべらせてみたをトレースしつつ、Arduinoを単体でWebAPIサーバにしてAPI叩くとしゃべるオモチャを作ろうと思っていました。

が、結局間に合わなかったのでArduinoをしゃべらせるためのPCMデータのカンタンな作り方解説にしたいと思います。

とりあえず作ったもの

「がんばるぞい」

作り方

基本的には【冬休みの工作】Arduinoをしゃべらせてみたのままです。

zoi.ino
#include <avr/pgmspace.h>

// prog_ucharだと上手く行かなかったので、const unsigned charにした
const unsigned char VOICE[] PROGMEM ={
82,73,70,70,7,64,0,0,87,65,86,69,102,109,116,32,
16,0,0,0,1,0,1,0,64,31,0,0,64,31,0,0,
1,0,8,0,100,97,116,97,227,63,0,0,128,127,127,127,

// 中略、ここを作るのがめんどい

131,133,129,122,125,128,127,127,127,127,128,128,127,127,127,127,
127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
127,127,127,127,127,127,127,127,127,127,127,127,127,127,127
};

void setup() {
  pinMode( 3,OUTPUT);
  TCCR2A = 0b00100011;
  TCCR2B = 0b00011001; 
  OCR2A = 255;
  OCR2B = 0;

  for(int i=0; i<16399; i++){ // ココはVOICE[]の要素数にあわせる
    OCR2B = pgm_read_byte_near(&VOICE[i]);
    delayMicroseconds(125);
  }
}

void loop() {
}

VOICE[]には8bit/8kHzのPCMデータを格納します。

今回はコレの作り方を中心に説明。

PCMデータの作り方

  1. 適当に音声データを用意
    • UnoとかNanoのATmega328搭載のArduinoだとFlashROMが32kBなので約4秒まで
  2. Audacityとかで以下の設定&Microsoft PCM形式のwavファイルにして保存
    • 1ch(モノラル)
    • サンプリング周波数8kHz
    • サンプリングレート8bit
  3. wavファイルをコマンドラインで1バイトごとのunsigned型で表示する

wavファイルをコマンドラインで1バイトごとのunsigned型で表示する

ワンライナーが得意な方はコマンド一発で変換してしまってください。macOSでも使えるいいワンライナーが出来たら教えてください。

$ od -tu1 -An zoi.wav | perl -ple 's/^\s+//g' | perl -ple 's/\s+/ /g' > zoi.txt

でこんな感じのデータを出力する。

zoi.txt
82 73 70 70 7 64 0 0 87 65 86 69 102 109 116 32
16 0 0 0 1 0 1 0 64 31 0 0 64 31 0 0
1 0 8 0 100 97 116 97 227 63 0 0 128 127 127 127
128 128 127 127 128 128 127 127 128 128 127 127 128 128 127 127
128 128 127 127 128 128 128 128 128 128 128 128 129 128 128 127
128 128 128 128 128 128 128 128 127 128 127 127 127 128 127 127
127 128 127 127 127 127 127 127 127 127 127 127 127 127 126 127
127 127 127 127 127 128 127 127 127 127 128 127 127 127 127 128
128 127 127 128 128 128 128 128 128 128 128 128 128 128 128 128
128 127 128 128 128 128 128 128 128 128 127 127 128 128 127 127
127 128 127 127 127 127 127 127 127 127 127 127 127 127 127 127
(以下略)

空白と行末をカンマに置換して

zoi.txt
82,73,70,70,7,64,0,0,87,65,86,69,102,109,116,32,
16,0,0,0,1,0,1,0,64,31,0,0,64,31,0,0,
1,0,8,0,100,97,116,97,227,63,0,0,128,127,127,127,
128,128,127,127,128,128,127,127,128,128,127,127,128,128,127,127,
128,128,127,127,128,128,128,128,128,128,128,128,129,128,128,127,
128,128,128,128,128,128,128,128,127,128,127,127,127,128,127,127,
127,128,127,127,127,127,127,127,127,127,127,127,127,127,126,127,
(中略)
127,127,127,127,127,127,127,127,127,127,127,127,127,127,127

これで先述のVOICE[]の初期化に使えるようになりました。

あとは好きなようにしゃべらせましょう。

(IoTのI成分がない記事になってしまった……)

ちなみに回し者ではないですが、別の機会にボイス素材作る方法を検討していたときにココナラでわりと低価格でボイス素材の収録をお願いできそうな感じでした。ご参考までに。


明日は @iwata-n@github さんのマインクラフトのTNTを現実世界から爆発させてみる(Wio Nodeを使います)です。

4
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
7