2017-07-18 8:47 GMT+02:00 Clemens Ladisch <clem...@ladisch.de>:

> In general, SPDIF inputs do not resample, and if you try to record with
> the wrong sample rate, the result has the original sample rate and is
> just labelled wrong.

That is a good news, but I would still prefer to know the sample rate
because if I want to output it, I would need to open the output device with
the correct sample rate, or I will still have a resampling.

> Does ALSA provide any general interface for the userspace applications
> > that indicates the SPDIF source sample rate?
> Yes, but the USB audio driver does not implement it because the USB
> audio specification does not define such an interface between the driver
> and the device.

What could I use if I had a non-USB sound card with SPDIF-in?

> At the moment, you have to write the code yourself.  But if you've
> tested it, we would be interested in integrating it into the kernel
> driver.

The below program outputs the current SPDIF-In sample rate of my card. The
only problem with it is that my sense of perfection hurts when I'm working
around the driver like that. All device-specific parts should be in kernel.

[root@speaker cm106spdif]# gcc cm106spdif.c -l hidapi-libusb
[root@speaker cm106spdif]# ./a.out
[root@speaker cm106spdif]# cat cm106spdif.c
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <err.h>
#include <hidapi/hidapi.h>

int cm106_read(hid_device *handle, char reg, uint16_t *data)
    unsigned char buf[5] = {0x00,    // report id for hidapi
                0x30,    // 0x20 to write, 0x30 to read
                0x00,    // DATAL
                0x00,    // DATAH
                reg};    // Register address

    if (hid_write(handle, buf, 5) != 5)
        return -1;

    if (hid_read(handle, buf, 5) != 3)
        return -2;

    if (buf[0] & 0xe0 != 0x20)    // No register data in the input report
        return -3;

    *data = (((uint16_t)buf[2]) << 8) + buf[1];
    return 0;

int cm106_write(hid_device *handle, char reg, uint16_t data)
    unsigned char buf[5] = {0x00,        // report id for hidapi
                0x20,        // 0x20 to write, 0x30 to read
                data & 0xff,    // DATAL
                (data >> 8),    // DATAH
                reg};        // Register address

    if (hid_write(handle, buf, 5) != 5)
        return -1;

    return 0;

int main(void)
    hid_device *handle;
    uint16_t data = 0;
    unsigned char SPDFI_FREQ;

    if ( !(handle = hid_open(0xd8c, 0x102, NULL)) )
        err(1, "hid_open: %ls", hid_error(handle));

    if (cm106_read(handle, 3, &data) < 0)
        err(2, "read: %ls", hid_error(handle));

    //printf("data=%04X\n", data);

    SPDFI_FREQ = (data & 0x0180) >> 7;

        case 0:

        case 2:

        case 3:

    return 0;

Best regards,
Denis Shulyaka
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
Alsa-user mailing list

Reply via email to