Intel EdisonをUSBオーディオで喋らせる

はじめに

今日は札幌オフィスで「Edisonもくもく会」が開催されました!社外の方も含め、7人でもくもくとEdisonを弄り倒しました。超楽しかったです。もし次回遊びに来たい!という方がいらっしゃいましたら、ぜひご連絡下さい。

僕はIntel EdisonにUSBオーディオを接続し、喋らせてみました!

やってみた

デバイスの準備

今回使ったUSBオーディオはBuffaloのUSBオーディオ変換ケーブル BSHSAU01BKです。特にカーネルのリビルドなどは特に必要なく、USBポートに繋ぐだけで認識しました。opkg install alsa-utilsで必要なパッケージをどーんと入れてます。

またベースの機材はIntel Edison Kit for Arduino + Grove Starter Kitで、A0にGrove - Rotary Angle Sensor、D2にGrove - Touch Sensorを接続しました。

IMG_0614

ソースコード

gobotを使ってGo言語で書いてます。またVoice Text Web APIを利用するために、yosssi/go-voicetextを使いました。

package main

import (
	"fmt"
	"os"
	"os/exec"

	"github.com/yosssi/go-voicetext"

	"github.com/hybridgroup/gobot"
	"github.com/hybridgroup/gobot/platforms/gpio"
	"github.com/hybridgroup/gobot/platforms/intel-iot/edison"
)

func getVoice(pitch int) (path string) {
	cli := voicetext.NewClient(os.Getenv("VOICETEXT_API_KEY"), nil)
	result, err := cli.TTS("エジソンもくもく会", &voicetext.TTSOptions{
		Speaker: voicetext.SpeakerHikari,
		Pitch:   pitch,
		Volume:  200,
	})
	if err != nil {
		panic(err)
	}

	f, err := os.Create("edison.wav")
	if err != nil {
		panic(err)
	}

	defer func() {
		if err := f.Close(); err != nil {
			panic(err)
		}
	}()

	if _, err := f.Write(result.Sound); err != nil {
		panic(err)
	}
	return "./edison.wav"
}

func main() {
	gbot := gobot.NewGobot()
	flg := 0

	e := edison.NewEdisonAdaptor("edison")
	touch := gpio.NewButtonDriver(e, "touch", "2")
	rotary := gpio.NewAnalogSensorDriver(e, "rotary", "0")

	work := func() {
		gobot.On(touch.Event("push"), func(data interface{}) {
			fmt.Println("pushing...")
			if flg == 0 {
				fmt.Println("start.")
				flg = 1
				angle, _ := rotary.Read()
				pitch := int(
					gobot.ToScale(gobot.FromScale(float64(angle), 0, 3000), 0, 200),
				)
				fmt.Println(angle)
				fmt.Println(pitch)
				path := getVoice(pitch)
				cmd := exec.Command("aplay")
				cmd.Args = []string{"aplay", "-D", "plughw:1", path}
				cmd.Dir = "."
				err := cmd.Run()
				if err != nil {
					panic(err)
				}
				flg = 0
				fmt.Println("end.")
			}
		})
		gobot.On(touch.Event("release"), func(data interface{}) {
			fmt.Println("released.")
		})
	}

	robot := gobot.NewRobot("audioBot",
		[]gobot.Connection{e},
		[]gobot.Device{touch, rotary},
		work,
	)

	gbot.AddRobot(robot)

	gbot.Start()
}

結果

go buildして作成されたバイナリファイルをIntel Edisonに転送します。環境変数VOICETEXT_API_KEYに、Voice Text Web APIのAPIキーを入れておきます。

タッチセンサーに触れると、ロータリースイッチの角度を取得してピッチを設定し、Voice Text Web APIからWAVファイルを取得して、USBオーディオから喋ります。

さいごに

こういったUSB周辺機器が簡単に使えるのもEdisonの強みだなーと思います。USBカメラなども繋げてみると楽しそうですね。今度チャレンジしてみたいと思います。