🤖

【Raspberry Pi】 音を鳴らしてみる。

2022/09/18に公開

音を鳴らそう

戦車のエンジン音とか、砲撃音とか、そういったモノを
鳴らしてみたいと思い、音を鳴らすことにしました。

ラズパイで音を鳴らす方法は2つ。
- 圧電スピーカーを使う。(ビープ音) - アンプモジュールを使う。(サウンド)

今回鳴らしたい音は、当然後者となります。

いつもの秋月商店で購入してきました。
- PAM8012使用2ワットD級アンプモジュール
- スピーカー 8Ω8W
- 3.5mmステレオミニプラグ⇔スクリュー端子台

アンプとスピーカーは1個だとモノラルになるので、2つずつ購入しました。

そして組み立て(半田付け)
アンプモジュール (半田付けスキルについては言及不要です・・・)

これを2つ用意し、ラズパイと繋ぎます。
いつもと違うのは、GPIOピンを使わないという点。
ステレオミニプラグをラズパイに刺し、端子とアンプモジュールを接続します。
今回購入したようなスクリュー端子台があると、お試しには便利です。

ステレオミニプラグのL R を別々のアンプモジュールに繋ぎ、別々のスピーカーに接続します。

アンプモジュール

コンパクトになるよう配線を一部工夫してみました。
結局ミニブレッドボード1つ占有してますが・・・。

小さなステレオスピーカーの完成です。
ちなみに電池などで電源を供給すれば、ラズパイが無くても再生可能です。
ステレオミニプラグをiphoneに刺せば音楽再生出来ます。
また左右で別々の音を流すステレオ用の音源を用意すれば、配線のテストも行えます。
(YouTube等で試しました。)

プログラムですが、今回は pygame というライブラリを使用します。
ドキュメントとしては、下記のようなものがあります。
http://www.pygame.org/docs/

では、音を鳴らすためのソースです。

#coding:utf-8

import pygame.mixer
from pygame.locals import *

PLAY_END = pygame.USEREVENT
pygame.init()
pygame.mixer.init()
pygame.mixer.music.load('test.wav')
pygame.mixer.music.play() # roopnum : -1 == endress
print ("PLAY")
pygame.mixer.music.set_endevent(PLAY_END)

loop = True;

while loop:

    for event in pygame.event.get():
        if event.type == PLAY_END:
            loop = False
            break
print ("END")


test.wav が音源リソースです。
拡張子は、wav,ogg,mp3に対応しているとのこと。

単に再生したいだけの場合は、line 7,8,9行目だけで良いのですが、
そのまま実行するとプログラムの終端に達して終了してしまいますので、
sleep等の処理が必要です。再生開始からの時間は取得できそうですが、
全体の時間は取得出来るか不明です。

今回は、再生終了後に、プログラムが終了するようなモノを考えます。
pygame.mixer.music.set_endeventにて、 終了時にイベント設定が出来るようなので、それを利用します。
ドキュメントを見たところ、USEREVENT以上の定数であれば、独自のイベントとして 設定できるようです。それ未満の定数はpygameで定義済みなのでしょう。

上記ソースは、無限ループで終了イベントを待ち、終了イベントが来たらループを終了し プログラムを終了するというソースです。
sleepも入れず無限ループさせているので、CPU負荷がやや高くなりました。
いろいろ組み合わせた場合には、その辺りのケアも必要になります。

ちなみに9行目のplayで引数を指定するとリピート回数を設定できるそうです。
(1で1回、2で3回再生されました・・・謎です) -1を指定すると、無限ループとなります。

まとめ

停止やポーズ、再開や次の音源を追加するインタフェースもあるようです。
ゲーム用のライブラリなので、いろいろなことが出来そうですが、
現在の用途としては、単発と無限ループが出来れば十分でしょうか。

GitHubで編集を提案

Discussion