Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to list and use ALSA's plughw: devices (env PA_ALSA_PLUGHW=1 already set)? #146

Open
AfterEight opened this issue Jul 12, 2018 · 3 comments

Comments

@AfterEight
Copy link

Hey everybody, first of all, thank you for the library and the amount of examples!
I wonder, if its possible to use ALSA's plugins to appear in 'list-devices' and to use those in the audiostream callback. Concretely, I'm using a Unix-based setup with ALSA and as cross-plattform audio library libportaudio2 installed via pip. According to PortAudio (which can be found in portaudio/src/hostapi/alsa/pa_linux_alsa.c, l. 1669: static PaError AlsaOpen), you just need to set a variable to list and use the plughw devices. I've set PA_ALSA_PLUGHW=1 it in both the user-based ~/.bashrc and the system-wide /etc/profile configuration files - however, under sounddevice it does not seem to be recognized (it still just shows the hw: devices).
I've also checked that PortAudio is installed in the latest release: dpkg -l |grep portaudio, shows v19.
Sure, it can be an issue with PortAudio, but before I'm going to debug using and compiling the PA code, I wanted to ask you in case someone knows a solution. Btw. PortAudio provides a debug logger - does someone know how to track those, when calling the C++ lib from a python code?

@mgeier
Copy link
Member

mgeier commented Jul 13, 2018

When I tried it (Debian Linux, using Pulse Audio) there was a little change in the device names and in the number of channels:

$ python3 -m sounddevice
   0 HDA Intel PCH: ALC269VC Analog (hw:0,0), ALSA (2 in, 2 out)
   1 HDA Intel PCH: HDMI 0 (hw:0,3), ALSA (0 in, 8 out)
   2 HDA Intel PCH: HDMI 1 (hw:0,7), ALSA (0 in, 8 out)
   3 HDA Intel PCH: HDMI 2 (hw:0,8), ALSA (0 in, 8 out)
   4 HDA Intel PCH: HDMI 3 (hw:0,9), ALSA (0 in, 8 out)
   5 sysdefault, ALSA (128 in, 128 out)
   6 front, ALSA (0 in, 2 out)
   7 surround40, ALSA (0 in, 2 out)
   8 surround51, ALSA (0 in, 2 out)
   9 surround71, ALSA (0 in, 2 out)
  10 hdmi, ALSA (0 in, 8 out)
  11 dmix, ALSA (0 in, 2 out)
* 12 default, ALSA (32 in, 32 out)
  13 /dev/dsp, OSS (16 in, 16 out)
$ export PA_ALSA_PLUGHW=1
$ python3 -m sounddevice
   0 HDA Intel PCH: ALC269VC Analog (plughw:0,0), ALSA (128 in, 128 out)
   1 HDA Intel PCH: HDMI 0 (plughw:0,3), ALSA (0 in, 128 out)
   2 HDA Intel PCH: HDMI 1 (plughw:0,7), ALSA (0 in, 128 out)
   3 HDA Intel PCH: HDMI 2 (plughw:0,8), ALSA (0 in, 128 out)
   4 HDA Intel PCH: HDMI 3 (plughw:0,9), ALSA (0 in, 128 out)
   5 sysdefault, ALSA (128 in, 128 out)
   6 front, ALSA (0 in, 2 out)
   7 surround40, ALSA (0 in, 2 out)
   8 surround51, ALSA (0 in, 2 out)
   9 surround71, ALSA (0 in, 2 out)
  10 hdmi, ALSA (0 in, 8 out)
  11 dmix, ALSA (0 in, 2 out)
* 12 default, ALSA (32 in, 32 out)
  13 /dev/dsp, OSS (16 in, 16 out)

So setting the environment variable definitely has some effect, but I don't know if this helps in your case?

I don't know anything about the debug logger, how would you use it from C++ code?

@PasStag
Copy link

PasStag commented Jan 17, 2019

Hey guys,
I'm going for the same goal as AfterEight. The benefit for using ALSA is from my point of view that i can use the ALSA implementations of sample rate conversions (upsampling downsampling).
Platform: Raspberry Pi (raspbian) with Debugging in MobaXterm and Python developpment in pycharm.

Here's my progress so far:

  1. I tried the environment above. Same result as the first comment:
    All hw changed to plughw.

  2. Use a generated sine wave to play back the signal on the audio source and vary its sample rate.
    There were no problems in playing back the files (as expected). After changing the environment variable back to 0, there were errors, because the sample rate is not support by my device. Out of this fact i would conclude that ALSA is doing a sampling in between, so that the device can read the data.

  3. By adding the environment var to the .bashrc the changes become permanent and the plughw can be triggered directly.

  4. Since I'm using pycharm, I tried to use a remote connection to debug my code. Unfortunatly there are no changes with respect to the environment variables, but i guess this is not a problem of sounddevice and more a problem of my remote ;)...


According to the first post of AfterEight I searched for the corresponding code in portaudio and found this (https://github.com/EddieRingle/portaudio/blob/master/src/hostapi/alsa/pa_linux_alsa.c):


 /* If device name starts with hw: and PA_ALSA_PLUGHW is 1, we open the plughw device instead */
        if( !strncmp( "hw:", deviceInfo->alsaName, 3 ) && getenv( "PA_ALSA_PLUGHW" ) )
            usePlug = atoi( getenv( "PA_ALSA_PLUGHW" ) );
        if( usePlug )
            snprintf( dnameArray, 50, "plug%s", deviceInfo->alsaName );
        else
deviceName = deviceInfo->alsaName; 

So at least i would guess:

  1. Search for your specfic device with default API code: sounddevice.query_devices()
  2. Remind the index of the hardware that you want.
  3. Activate the Environment variable
  4. Use Plughw device.

Hope this helps, if somebody is searching for a solution.

Best Regards.
P.

@imcomking
Copy link

imcomking commented Sep 7, 2020

Very Good!
So the conclusion is that just adding this line to .basrhc.

export PA_ALSA_PLUGHW=1

then all of your device listed will be changed to plughw, so now you can choose the sample rate which is not supported by hw device.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants