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.

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.

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

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.

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.

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.