2017-07-18 8:47 GMT+02:00 Clemens Ladisch <clemens@xxxxxxxxxx>:
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.
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 <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 = "" << 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 = ""> 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="" 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;
}
[root@speaker cm106spdif]# gcc cm106spdif.c -l hidapi-libusb
[root@speaker cm106spdif]# ./a.out
44.1K
[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 = "" << 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 = ""> 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="" 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;
}
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@xxxxxxxxxxxxxxxxxxxxx https://lists.sourceforge.net/lists/listinfo/alsa-user