PyGameでサウンド再生

RaspberryPiでPythonを使ってサウンドを再生してみようと思い、調べてみるとPyGameに含まれるサウンド機能を使うのが簡単そうだったので試してみたのだが、意外と手間取ってしまった。

テスト用にフリーの音源サイトからダウンロードしたwavファイルを、Raspbianの最新版にはデフォルトで入っているaplayで再生してみると、特に問題無く再生される。この時にwavファイルのビットやレートも表示されるので、それに合わせてテストプログラムを作ってみた。

aplay

import pygame
from pygame.locals import *

pygame.mixer.init(frequency = 22050, size = 8, channels = 1, buffer = 1024)
sound = pygame.mixer.Sound("se.wav")
sound.play()
try:
    while True:
        pass
except KeyboardInterrupt:
    pygame.mixer.quit()

ところがこれでは全く再生されない。音声はHDMI経由でモニタのスピーカーから出るようにしてあって、ボリュームを最大に上げると一瞬ノイズのような音が聞こえるのだが、それっきり。

色々と試してみると、再生しようとするwavファイルとは異なる周波数に初期化すると再生される事が分かったのだが、なぜそうなるのかは不明。以下のプログラムなら正しく再生される。

import pygame
from pygame.locals import *

pygame.mixer.init(frequency = 44100, size = -16, channels = 2, buffer = 1024)
sound = pygame.mixer.Sound("se.wav")
sound.play()
try:
    while True:
        pass
except KeyboardInterrupt:
    pygame.mixer.quit()

PyGameのサウンド再生はwavファイルだけではなく、mp3ファイルをエンドレスで再生する機能もあって、wavファイルと同時に再生できるのでその機能を使ってこんなプログラムを作ってみた。デフォルトで入っているmp3を再生しながら、キーボードの1~4を押した時に対応するwavを再生するだけ。PyGameでウィンドウを作り、そこに文字を表示させるのも一緒に試してみた。

#!/usr/bin/env python

import sys, pygame
from pygame.locals import *

if __name__ == "__main__":
    pygame.init()
    pygame.mixer.quit()
    pygame.mixer.init(frequency = 48000, size = -16, channels = 2, buffer = 1024)
    pygame.mixer.music.load("/usr/share/scratch/Media/Sounds/Music Loops/Xylo1.mp3")
    p1 = pygame.mixer.Sound("/usr/share/scratch/Media/Sounds/Percussion/Gong.wav")
    p2 = pygame.mixer.Sound("/usr/share/scratch/Media/Sounds/Percussion/HandClap.wav")
    p3 = pygame.mixer.Sound("/usr/share/scratch/Media/Sounds/Percussion/CymbalCrash.wav")
    p4 = pygame.mixer.Sound("/usr/share/scratch/Media/Sounds/Percussion/DrumBuzz.wav")
    size = width, height = 200, 200
    screen = pygame.display.set_mode(size)
    font = pygame.font.Font(None, 40)
    text = font.render('Sound Test', True, (255, 255, 255))
    screen.blit(text, (20, 80))
    pygame.display.update()
    pygame.event.set_allowed([QUIT, KEYDOWN])
    pygame.mixer.music.play(-1)
    try:
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.mixer.quit()
                    pygame.quit()
                    sys.exit()
                if event.type == KEYDOWN:
                    if event.key == K_1:
                        p1.stop()
                        p1.play()
                    elif event.key == K_2:
                        p2.stop()
                        p2.play()
                    elif event.key == K_3:
                        p3.stop()
                        p3.play()
                    elif event.key == K_4:
                        p4.stop()
                        p4.play()
    except KeyboardInterrupt:
        pygame.mixer.quit()
        pygame.quit
        sys.exit()

デスクトップ画面にウィンドウを表示するので、これはリモートでは実行できない。VNCのリモートデスクトップでなら動かせるが、サウンドがHDMIモニタに出力されるのでVNCでは意味がない。
soundtstPyGameは初めて使ってみたのだが、昔のBASICパソコン時代のようなゲームなら割と簡単に作れそうだ。Pythonがあまり速くないので今風のゲームは無理だろうけど、チュートリアルサイトを見るとスーパーファミコン時代のゲームなら作成可能という説明があって、確かにそんな感じがする。

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中