Re: [Alsa-user] Get SPDIF-in sample rate

2017-07-18 Thread Denis Shulyaka
2017-07-18 8:47 GMT+02:00 Clemens Ladisch :

> 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
44.1K
[root@speaker cm106spdif]# cat cm106spdif.c
#include 
#include 
#include 
#include 
#include 

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;

switch(SPDFI_FREQ)
{
case 0:
printf("44.1K\n");
break;

case 2:
printf("48K\n");
break;

case 3:
printf("32K\n");
break;
default:
printf("reserved\n");
}

hid_close(handle);
hid_exit();
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
Alsa-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-user


Re: [Alsa-user] Get SPDIF-in sample rate

2017-07-18 Thread Clemens Ladisch
Denis Shulyaka wrote:
> 2017-07-18 8:47 GMT+02:00 Clemens Ladisch:
> > > 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?

There would be a mixer control "IEC958 Capture Default" associated with
the PCM device (i.e., not a real mixer control visible in alsamixer),
containing the channel status bits; the "IEC958 Capture Mask" control
defines which bits are valid.

> > 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 HID interface is managed by another driver.  The kernel driver
already knows how to write to these registers with a control request
instead (see below).  Could you check if a control read request works,
or if the response still goes through the HID pipe?


Regards,
Clemens
-- 

static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 
value)
{
u8 buf[4];
buf[0] = 0x20;
buf[1] = value & 0xff;
buf[2] = (value >> 8) & 0xff;
buf[3] = reg;
return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 
USB_REQ_SET_CONFIGURATION,
   USB_DIR_OUT | USB_TYPE_CLASS | 
USB_RECIP_ENDPOINT,
   0, 0, &buf, 4);
}

--
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
Alsa-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-user