spatialaudio / python-sounddevice

:sound: Play and Record Sound with Python :snake:
https://python-sounddevice.readthedocs.io/
MIT License
982 stars 145 forks source link

how to get channel name of audio device with ASIO driver? #348

Open bactone opened 3 years ago

bactone commented 3 years ago

hi, could anyone tell me how to get channel name of audio device with ASIO driver? or is it possible to do it with sounddevice?

for example, if we use:

sounddevice.query_devices()

to get device list, we can obtain all available devices , including those with ASIO driver: 69 Cube 6Nano, ASIO (20 in, 20 out) we can see the above device contains 20 input channels and 20 output channels, we can use these channels with the corresponding channels index from 1 to 20, for example:

sd.play(data=pt, device='Cube 6Nano', samplerate=fs, blocking=True, mapping=[1], loop=False)

but one step further, how to get the corresponding channel names? in soundcheck, the channels of device with ASIO driver can be obtained as: image

besides those channel names are also listed in the Built-in software of soundcard ICON nano6: image

so how to get the channel names of audio devices ? pls help, thanks

mgeier commented 3 years ago

This is currently not implemented.

See https://github.com/spatialaudio/python-sounddevice/issues/4#issuecomment-298019776 and #85 for a possible implementation.

bactone commented 3 years ago

@mgeier hi, i have try to rebuild the .dll lib, including the following method:

PaAsio_GetInputChannelName          @53
PaAsio_GetOutputChannelName         @54

then i replace the intial libportaudio64bit.dll locates at _C:\Program Files\Python\Python38\Lib\site-packages_sounddevicedata\portaudio-binaries

then i add a method to the sounddevice.py, reference to rholl:

def asio_get_input_channel_name(device, channel):
    """Retrieve the name of the specified output channel.

    Parameters
    ----------
    device : int
        Device ID.  (aka The global index of the PortAudio device.)
    channel : int
        Channel number from 0 to max_*_channels-1.

    Returns
    -------
    The channel's name : str

    """
    channel_name = _ffi.new('char*[1]')
    _check(_lib.PaAsio_GetInputChannelName(device, channel, channel_name))
    return _ffi.string(channel_name[0]).decode()

finally I write a demo code:

import sounddevice as sd
# from sounddevice_GitHub import sounddevice as sd

print(sd.query_devices())
print(sd.asio_get_input_channel_name(68, 0))
print(sd.asio_get_input_channel_name(68, 1))

print(sd.asio_get_input_channel_name(69, 0))
print(sd.asio_get_input_channel_name(69, 1))

sd.query_devices() is ok, but sd.asio_get_input_channel_name() is wrong, the error feedback is :

Traceback (most recent call last):
  File "D:/working/Python/2 library/Sounddevice/test/demo_channelname_1.py", line 5, in <module>
    print(sd.asio_get_input_channel_name(68, 0))
  File "D:\working\Python\2 library\Sounddevice\sounddevice_GitHub\sounddevice.py", line 2341, in asio_get_input_channel_name
    _check(_lib.PaAsio_GetInputChannelName(device, channel, channel_name))
AttributeError: cffi library 'C:\Program Files\Python\Python38\lib\site-packages\_sounddevice_data\portaudio-binaries\libportaudio64bit.dll' has no function, constant or global variable named 'PaAsio_GetInputChannelName'

so how to make the method 'PaAsio_GetInputChannelName' callable in python? thanks.

mgeier commented 3 years ago

You'll have to copy the missing function definitions from the PortAudio header files to sounddevice_build.py.

TheArpeggiator commented 11 months ago

Any luck with your script @bactone? I'm also highly interested in being able to list ASIO channel names using PySounddevice.