A StackOverflow question leads to an old question about error message when using PyAudio library, wrapper of PortAudio, when running
import pyaudio pyaudio.PyAudio()
, which results the similar messages as follows:
ALSA lib pcm_dsnoop.c:612:(snd_pcm_dsnoop_open) unable to open slave ALSA lib pcm_dmix.c:1018:(snd_pcm_dmix_open) unable to open slave ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side ALSA lib pcm_dmix.c:957:(snd_pcm_dmix_open) The dmix plugin supports only playback stream ALSA lib pcm_dmix.c:1018:(snd_pcm_dmix_open) unable to open slave
Some developers who use PyAudio or PortAudio do not like these messages, even though their programs do work well regardless of these message.
Contents
1 Who actually blah those?
First, you need to know where is the source and the answer is alsa-lib. Line 74, from error.c, the default error handler:
static void snd_lib_error_default(const char *file, int line, const char *function, int err, const char *fmt, ...) { va_list arg; va_start(arg, fmt); fprintf(stderr, "ALSA lib %s:%i:(%s) ", file, line, function); vfprintf(stderr, fmt, arg); if (err) fprintf(stderr, ": %s", snd_strerror(err)); putc('\n', stderr); va_end(arg); }
The message is printed out via the function by the code mentioned in the message.
2 Why the message?
Because there is something wrong with ALSA configuration, I am only talking about the message shows during ALSA initialization for your program, not what your code does wrong.
Every time, ALSA is used by a program, configuration will be parsed. There are two typical locations:
~/.asoundrc /etc/asound.conf
There are sourced from /usr/share/alsa/alsa.conf. You may need to test where the problem configuration locates. In my case, it’s actually in alsa.conf. If I remove:
pcm.rear cards.pcm.rear
The following message is gone:
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
3 Solution
Do nothing.
First of all, it doesn’t affect anything, even the configuration isn’t perfect. If you are not familiar with ALSA configuration, you may break something. Just let the message be there.
4 Gotta get rid of them, seriously!
If you insist, there is a way. But we have to bypass PyAudio and PortAudio since they provide no ways to deal with errors. Actually, there seemed to be one in PortAudio, but the code was commented out.
Using snd_lib_error_set_handler() of alsa-lib to set a new error handler instead of default one as shown above. Since it’s C, we need to use ctypes. I have look into pyalsa, official Python bindings, and PyAlsaAudio, both do not support setting error handler. I think it’s because of Variable Arguments.
Anyway, I have wrote a simple code to demonstrate:
#!/usr/bin/env python from ctypes import * # From alsa-lib Git 3fd4ab9be0db7c7430ebd258f2717a976381715d # $ grep -rn snd_lib_error_handler_t # include/error.h:59:typedef void (*snd_lib_error_handler_t)(const char *file, int line, const char *function, int err, const char *fmt, ...) /* __attribute__ ((format (printf, 5, 6))) */; # Define our error handler type ERROR_HANDLER_FUNC = CFUNCTYPE(None, c_char_p, c_int, c_char_p, c_int, c_char_p) def py_error_handler(filename, line, function, err, fmt): print 'messages are yummy' c_error_handler = ERROR_HANDLER_FUNC(py_error_handler) asound = cdll.LoadLibrary('libasound.so') # Set error handler asound.snd_lib_error_set_handler(c_error_handler) # Initialize PyAudio import pyaudio p = pyaudio.PyAudio() p.terminate() print '-'*40 # Reset to default error handler asound.snd_lib_error_set_handler(None) # Re-initialize p = pyaudio.PyAudio() p.terminate()
It outputs:
messages are yummy messages are yummy messages are yummy messages are yummy messages are yummy messages are yummy ---------------------------------------- ALSA lib pcm_dmix.c:1018:(snd_pcm_dmix_open) unable to open slave ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side ALSA lib pcm_dmix.c:957:(snd_pcm_dmix_open) The dmix plugin supports only playback stream ALSA lib pcm_dmix.c:1018:(snd_pcm_dmix_open) unable to open slave
The code can’t take variable arguments, they are just dropped. We are looking a way to silence, so those don’t matter.
5 But don’t, really!
Don’t do it, just let the messages be. If you worry about confusions in users, just do something like:
print "Initializing PyAudio..." p = pyaudio.PyAudio() print "(If you see messages above, it's not [Program name]'s fault.)" print "End of PyAudio initialization."
There is a reason for those messages and there probably is no bugs in your code.
If nothing is broken in your code, then fix nothing.
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.