Raspberry Pi に USB スピーカーを接続しテキストを音声変換しお話しさせる

Raspberry Pi に USB スピーカーを接続しテキストを音声変換しお話しさせる


概要

Raspberry Pi と OpenAI を通じて英会話しよう!という動機から
最初の一歩として USB スピーカーから指定したテキストを読み上げる様にしてみました。

環境

Marstudy Raspberry Pi 4 Model B Starter キット
プリインストールされた Raspbian OS を利用しています。

1
2
3
4
5
6
7
8
9
10
11
12
$ cat /etc/os-release

PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

usb スピーカー接続

サンワサプライ コンパクト PC スピーカー MS-P08UBK を利用します。

自分が購入した 2023-05-10 は ¥857 でした。

接続先の USB スピーカーのカード番号・デバイス番号を確認

1
2
3
4
5
6
7
8
9
10
11
12
$ aplay -l
**** ハードウェアデバイス PLAYBACK のリスト ****
カード 1: Headphones [bcm2835 Headphones], デバイス 0: bcm2835 Headphones [bcm2835 Headphones]
サブデバイス: 8/8
サブデバイス #0: subdevice #0
サブデバイス #1: subdevice #1
サブデバイス #2: subdevice #2
サブデバイス #3: subdevice #3
サブデバイス #4: subdevice #4
サブデバイス #5: subdevice #5
サブデバイス #6: subdevice #6
サブデバイス #7: subdevice #7
  • カード番号 = 1
  • デバイス番号 = 0

音がスピーカーから聞こえるかテスト

1
2
3
4
// plughw:<カード>,<デバイス>
$ speaker-test -D plughw:1,0 -t wav

// Ctrl+c で中断し終了します

python スクリプトから再生してみる

1
$ pip3 install pygame
1
$ curl https://www.soundjay.com/buttons/button-3.mp3 -o button.mp3
  • play_sound.py
1
2
3
4
5
6
7
8
9
10
11
12
13
import pygame


def play_sound_file(file_path):
pygame.mixer.init()
pygame.mixer.music.load(file_path)
pygame.mixer.music.play()

while pygame.mixer.music.get_busy() == True:
continue

if __name__ == "__main__":
play_sound_file('button.mp3')

以下実行し mp3 が再生されることが確認できます。

1
$ python3 play_sound.py

テキストから音声ファイルを作成し読み上げる

  • speech.py
1
2
$ pip3 install gTTS
$ pip3 install pydub
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from gtts import gTTS
from pydub import AudioSegment
from pydub.playback import play
import sys


def speechja(stext):
tts = gTTS(stext, lang="ja")
tts.save("/tmp/out.mp3")

sound = AudioSegment.from_mp3("/tmp/out.mp3")
play(sound)


if __name__ == "__main__":
msg = "はい、お元気ですか?"
speechja(msg)

以下実行しスピーカーから「はい、お元気ですか?」と再生されます。

1
$ python3 speech.py

以上
参考になれば幸いです。

次回はマイクから音声認識させる設定を執筆したいと思います。

alpine イメージに awscli をインストールする


alpine イメージで awscli をインストールする際の備忘録です。

1
2
3
4
5
6
7
RUN apk add --no-cache \
python3 \
py3-pip \
&& pip3 install --upgrade pip \
&& pip3 install --no-cache-dir \
awscli \
&& rm -rf /var/cache/apk/*

AWS Bot 対策


AWS で CloudFront + ECS で Web サービスを配信していますが、
Bot が多く、その対策を WAF で実行しようとしたい際にいくつかつまづきましたので、その備忘録になります。

以下 2 点を試しました。

  1. WAF v2 で GEO マッチステートメントで Bot のリクエスト元の海外 IP をブロック
  2. WAF v2 Bot Control で Bot 対策
続きを読む
JavaScript で日付計算の妙

JavaScript で日付計算の妙

問題です。以下コードを実行した際に何と出力されるでしょう?
先月の 1 日を取得したい気持ちです。

1
2
3
4
let dt = new Date('2022-10-31T15:00:00+0900');
dt.setMonth(dt.getMonth() - 1);
dt.setDate(1)
console.log(dt); // => ?
続きを読む
terraform で map 型の値を key 順にソートした上で value のリストを取得する

terraform で map 型の値を key 順にソートした上で value のリストを取得する

terraform で map 型を for で整形した際に key を昇順にソートして並べてくれます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> {for k, v in {"a":3, "c":2, "d":1}: v => k}

{
"1" = "d"
"2" = "c"
"3" = "a"
}

> values({for k, v in {"a":3, "c":2, "d":1}: v => k})

[
"d",
"c",
"a",
]

これを利用し、data リソースで取得した Subnet ID を AZ 順 (a → c → d) に list で取得してみます。

続きを読む