pyaudioを使ってサイン波をリアルタイム再生するもエラー。
前回
参考
ソースコード
# -*- coding: utf-8 -*- import wave import numpy as np from matplotlib import pylab as plt import struct # サイン波を生成する class Sin: def __init__(self): self.__wave = [] @property def Wave(self): return self.__wave """ サイン波を生成する。 a: 振幅 fs: サンプリング周波数 f0: 周波数 sec: 秒 """ def Create(self, a=1, fs=8000, f0=440, sec=5): self.__wave.clear() for n in np.arange(fs * sec): s = a * np.sin(2.0 * np.pi * f0 * n / fs) # サンプリング(標本化)する self.__wave.append(s) return self.__wave #量子化する class Sampler: @staticmethod def Sampling(wav, bit=16): #16bit=-32768〜32767 q = 2**(bit-1)-1 # 符号付きのため-1乗。0で1つ分減るため-1。 return [int(x * q) for x in wav] def play (data, fs, bit): import pyaudio # ストリームを開く p = pyaudio.PyAudio() stream = p.open(format=pyaudio.paInt16, channels=1, rate=int(fs), output= True) # チャンク単位でストリームに出力し音声を再生 chunk = 1024 sp = 0 # 再生位置ポインタ buffer = data[sp:sp+chunk] while buffer != '': stream.write(buffer) sp = sp + chunk buffer = data[sp:sp+chunk] stream.close() p.terminate() if __name__ == "__main__" : s = Sin() s.Create(a=1, fs=8000, f0=440, sec=5) #サイン波を-32768から32767の整数値に変換(signed 16bit pcmへ) swav = Sampler.Sampling(s.Wave, bit=16) #バイナリ化 binwave = struct.pack("h" * len(swav), *swav) play(binwave, 8000, 16)
$ python play.py ALSA lib pcm_dmix.c:1022:(snd_pcm_dmix_open) unable to open slave ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side bt_audio_service_open: connect() failed: Connection refused (111) bt_audio_service_open: connect() failed: Connection refused (111) bt_audio_service_open: connect() failed: Connection refused (111) bt_audio_service_open: connect() failed: Connection refused (111) ALSA lib pcm_dmix.c:1022:(snd_pcm_dmix_open) unable to open slave
再生されたが、謎のエラーがでた。
ALSA lib pcm_dmix.c:1022:(snd_pcm_dmix_open) unable to open slave
http://seussnu.b.osdn.me/?p=150
デバイス確認
$ aplay -l **** ハードウェアデバイス PLAYBACK のリスト **** カード 0: Intel [HDA Intel], デバイス 0: STAC9200 Analog [STAC9200 Analog] サブデバイス: 0/1 サブデバイス #0: subdevice #0
音声の再生確認
(game) $ aplay -D hwplug:0,0 /usr/share/sounds/alsa/Front_Center.wav ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM hwplug:0,0 aplay: main:722: オーディオオープンエラー そのようなファイルやディレクトリはありません
エラー。音声ファイル自体は存在したのはファイラで確認したのだが。
さらにググる。
https://github.com/alexa-pi/AlexaPiDEPRECATED/issues/118
- 正:
plughw
- 誤:
hwplug
aplay -D plughw:0,0 /usr/share/sounds/alsa/Front_Center.wav
上記コマンドで音声ファイルが再生した。デバイス0は正常に音が鳴る。
/etc/asound.conf
/etc/asound.conf
ファイルを作成し、以下の内容にする。
# cat /etc/asound.conf defaluts.pcm.card 0 defaults.pcm.device 0 defaults.ctl.card 0 pcm.!default { type plug slave.pcm "hw:0,0" }
カードやデバイスなどがあるが、私の環境では0しかなかったため全部0にする。
http://seussnu.b.osdn.me/?p=150
ALSA再起動
ALSAとやらを再起動。
$ rc.d force-restart alsa rc.d: コマンドが見つかりません $ /etc/init.d/alsa-utils restart bash: /etc/init.d/alsa-utils: そのようなファイルやディレクトリはありません
どれもダメだったので、OS再起動。
$ reboot
2回目
実行するも1回目と同様。音は再生されるも、エラーメッセージが表示される。
$ python play.py ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side bt_audio_service_open: connect() failed: Connection refused (111) bt_audio_service_open: connect() failed: Connection refused (111) bt_audio_service_open: connect() failed: Connection refused (111) bt_audio_service_open: connect() failed: Connection refused (111)
さらにググる
- https://github.com/Katee/quietnet/issues/18
- Raspberry Pi 3 第09回 〜合成音声と会話〜: エンジニア奮闘録
- Raspberry Pi 3 第09回 〜合成音声と会話〜: エンジニア奮闘録
- http://hanpakousaku.tumblr.com/post/105771613672/raspberrypi-%E3%81%A8-pyaudio%E3%81%A7%E9%8C%B2%E9%9F%B3%E9%9F%B3%E5%A3%B0%E6%B3%A2%E5%BD%A2%E5%87%A6%E7%90%86
/etc/modprobe.d/alsa-base.conf
options snd-usb-audio index=-2
が存在した。-2
を0
にすればよさそう
- http://hanpakousaku.tumblr.com/post/105771613672/raspberrypi-%E3%81%A8-pyaudio%E3%81%A7%E9%8C%B2%E9%9F%B3%E9%9F%B3%E5%A3%B0%E6%B3%A2%E5%BD%A2%E5%87%A6%E7%90%86
/etc/modprobe.d/alsa-base.conf
options snd-usb-audio index=-2
の-2
を0
に変更する。0
は有効なデバイス番号、だと思う。
修正前
# autoloader aliases install sound-slot-0 /sbin/modprobe snd-card-0 install sound-slot-1 /sbin/modprobe snd-card-1 install sound-slot-2 /sbin/modprobe snd-card-2 install sound-slot-3 /sbin/modprobe snd-card-3 install sound-slot-4 /sbin/modprobe snd-card-4 install sound-slot-5 /sbin/modprobe snd-card-5 install sound-slot-6 /sbin/modprobe snd-card-6 install sound-slot-7 /sbin/modprobe snd-card-7 # Cause optional modules to be loaded above generic modules install snd /sbin/modprobe --ignore-install snd $CMDLINE_OPTS && { /sbin/modprobe --quiet --use-blacklist snd-ioctl32 ; /sbin/modprobe --quiet --use-blacklist snd-seq ; } # # Workaround at bug #499695 (reverted in Ubuntu see LP #319505) install snd-pcm /sbin/modprobe --ignore-install snd-pcm $CMDLINE_OPTS && { /sbin/modprobe --quiet --use-blacklist snd-pcm-oss ; : ; } install snd-mixer /sbin/modprobe --ignore-install snd-mixer $CMDLINE_OPTS && { /sbin/modprobe --quiet --use-blacklist snd-mixer-oss ; : ; } install snd-seq /sbin/modprobe --ignore-install snd-seq $CMDLINE_OPTS && { /sbin/modprobe --quiet --use-blacklist snd-seq-midi ; /sbin/modprobe --quiet --use-blacklist snd-seq-oss ; : ; } # install snd-rawmidi /sbin/modprobe --ignore-install snd-rawmidi $CMDLINE_OPTS && { /sbin/modprobe --quiet --use-blacklist snd-seq-midi ; : ; } # Cause optional modules to be loaded above sound card driver modules install snd-emu10k1 /sbin/modprobe --ignore-install snd-emu10k1 $CMDLINE_OPTS && { /sbin/modprobe --quiet --use-blacklist snd-emu10k1-synth ; } install snd-via82xx /sbin/modprobe --ignore-install snd-via82xx $CMDLINE_OPTS && { /sbin/modprobe --quiet --use-blacklist snd-seq ; } # Load saa7134-alsa instead of saa7134 (which gets dragged in by it anyway) install saa7134 /sbin/modprobe --ignore-install saa7134 $CMDLINE_OPTS && { /sbin/modprobe --quiet --use-blacklist saa7134-alsa ; : ; } # Prevent abnormal drivers from grabbing index 0 options bt87x index=-2 options cx88_alsa index=-2 options saa7134-alsa index=-2 options snd-atiixp-modem index=-2 options snd-intel8x0m index=-2 options snd-via82xx-modem index=-2 options snd-usb-audio index=-2 options snd-usb-caiaq index=-2 options snd-usb-ua101 index=-2 options snd-usb-us122l index=-2 options snd-usb-usx2y index=-2 # Ubuntu #62691, enable MPU for snd-cmipci options snd-cmipci mpu_port=0x330 fm_port=0x388 # Keep snd-pcsp from being loaded as first soundcard options snd-pcsp index=-2 # Keep snd-usb-audio from beeing loaded as first soundcard options snd-usb-audio index=-2
最終行のoptions snd-usb-audio index=-2
をoptions snd-usb-audio index=0
にする。
編集
権限の問題があるためsudo vi
で編集した。
$ sudo vi alsa-base.conf
J
キーで末端までカーソル移動L
キーで右へカーソル移動-
の文字のところでd
,w
とすると-
の文字が消える2
の文字のところでd
,w
とすると2
の文字が消えるa
キー押下して挿入モードに移行する0
キー押下すると0
の文字が入力されるESC
キーを押下して通常モードへ移行する:wp
を入力してファイル書込し終了する
3回目
再起動後に実行する。同様のエラーだった。
$ python play.py ALSA lib pcm_dmix.c:1022:(snd_pcm_dmix_open) unable to open slave ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe ALSA lib pcm.c:2239:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side bt_audio_service_open: connect() failed: Connection refused (111) bt_audio_service_open: connect() failed: Connection refused (111) bt_audio_service_open: connect() failed: Connection refused (111) bt_audio_service_open: connect() failed: Connection refused (111) ALSA lib pcm_dmix.c:1022:(snd_pcm_dmix_open) unable to open slave
所感
解決できなかった。プログラムが正常終了しないのでCtrl+Zで強制終了せねばならない。とりあえず音は鳴るので放置する。