pyalsaaudio icon indicating copy to clipboard operation
pyalsaaudio copied to clipboard

unable to install hw params

Open FSet89 opened this issue 2 years ago • 8 comments

I have the following error when trying to initialize PCM:

import alsaaudio as a
a.PCM(0)

ALSA lib ../../../alsa-lib-1.1.9/src/pcm/pcm_direct.c:1271:(snd1_pcm_direct_initialize_slave) unable to install hw params ALSA lib ../../../alsa-lib-1.1.9/src/pcm/pcm_dmix.c:1120:(snd_pcm_dmix_open) unable to initialize slave Traceback (most recent call last): File "", line 1, in alsaaudio.ALSAAudioError: Invalid argument [default]

However, arecord on the same device works well.

FSet89 avatar Mar 01 '23 09:03 FSet89

0 corresponds to PCM_PLAYBACK

Does your default device support playback? What does aplay do?

RonaldAJ avatar Mar 01 '23 12:03 RonaldAJ

I get the same error with p=alsaaudio.PCM(1) ALSA lib ../../../alsa-lib-1.1.9/src/pcm/pcm_direct.c:1271:(snd1_pcm_direct_initialize_slave) unable to install hw params ALSA lib ../../../alsa-lib-1.1.9/src/pcm/pcm_dsnoop.c:649:(snd_pcm_dsnoop_open) unable to initialize slave Traceback (most recent call last): File "", line 1, in alsaaudio.ALSAAudioError: Invalid argument [default]

If I specify the cardindex: p=alsaaudio.PCM(1, cardindex=0) Traceback (most recent call last): File "", line 1, in alsaaudio.ALSAAudioError: Invalid argument [hw:0]

Some useful outputs: alsaaudio.card_indexes() [0] alsaaudio.cards() ['imxaudiosph0645'] alsaaudio.card_name(0) ('imx-audio-sph0645', 'imx-audio-sph0645') alsaaudio.pcms() ['null', 'sysdefault:CARD=imxaudiosph0645']

FSet89 avatar Mar 01 '23 13:03 FSet89

What happens if you specify an existing device instead of the implicit 'default':

p=alsaaudio.PCM(1, device='null')

Other solution might be to add default device to the ALSA configuration.

RonaldAJ avatar Mar 01 '23 14:03 RonaldAJ

What happens if you specify an existing device instead of the implicit 'default':

p=alsaaudio.PCM(1, device='null')

Other solution might be to add default device to the ALSA configuration.

In this case I get no errors but I'm not sure this is the correct way:

import alsaaudio as a
p=a.PCM(1, device='null')
p.cardname()

'null' p.read() (32, b'b\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00J\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00>\x00\x00\x00?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F\x00\x00\x00Q\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')

FSet89 avatar Mar 02 '23 09:03 FSet89

This looks like correct output. It needs to be converted from a byte string to a numerical format.

I have a conversion dictionary for that purpose: conversion_dict = { alsaaudio.PCM_FORMAT_S8: {'dtype': np.int8, 'endianness': '', 'formatchar': 'h', 'bytewidth': 1}, alsaaudio.PCM_FORMAT_U8: {'dtype': np.uint8, 'endianness': '', 'formatchar': 'h', 'bytewidth': 1}, alsaaudio.PCM_FORMAT_S16_LE: {'dtype': np.int16, 'endianness': '<', 'formatchar': 'h', 'bytewidth': 2}, alsaaudio.PCM_FORMAT_S16_BE: {'dtype': np.int16, 'endianness': '>', 'formatchar': 'h', 'bytewidth': 2}, alsaaudio.PCM_FORMAT_U16_LE: {'dtype': np.uint16, 'endianness': '<', 'formatchar': 'H', 'bytewidth': 2}, alsaaudio.PCM_FORMAT_U16_BE: {'dtype': np.uint16, 'endianness': '>', 'formatchar': 'H', 'bytewidth': 2}, alsaaudio.PCM_FORMAT_S32_LE: {'dtype': np.int32, 'endianness': '<', 'formatchar': 'l', 'bytewidth': 4}, alsaaudio.PCM_FORMAT_S32_BE: {'dtype': np.int32, 'endianness': '>', 'formatchar': 'l', 'bytewidth': 4}, alsaaudio.PCM_FORMAT_U32_LE: {'dtype': np.uint32, 'endianness': '<', 'formatchar': 'L', 'bytewidth': 4}, alsaaudio.PCM_FORMAT_U32_BE: {'dtype': np.uint32, 'endianness': '>', 'formatchar': 'L', 'bytewidth': 4}, }

which is used with this function:

def get_conversion_string(audioformat, noofsamples, conversion_dict ): conversion_string = f"{conversion_dict['endianness']}{noofsamples}{conversion_dict['formatchar']}" return conversion_string

to find the parameters for the conversion: data = np.array(struct.unpack(conversion_string, rawdata), dtype=dtype)

Here rawdata is the second part returned by read, in your case: noofsamples, rawdata = p.read()

These are just some edited cuts, so the code is not fully working. But should give you the right direction.

RonaldAJ avatar Mar 02 '23 11:03 RonaldAJ

Thanks, I will give it a try. However, isn't 'null' the playback device? I'm expecting to see the card name when calling p.cardname()

FSet89 avatar Mar 02 '23 11:03 FSet89

You can call p.info() to get information about the PCM device you opened.

RonaldAJ avatar Mar 02 '23 17:03 RonaldAJ

@FSet89 If it works you can close this issue.

RonaldAJ avatar Mar 05 '23 11:03 RonaldAJ