Problem with TEAC USB UD-H01 and ALSA

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello list,

I own a TEAC UD-H01 DAC. I'm aware that the UD-H01 has a strange/faulty feedback frequency behaviour which is fortunately already handled by a quirk in ALSA snd-usb-audio kernel module (git commit 7040b6d1febfdbd9c1595efb751d492cd2503f96). So first of all many thanks to Clemens Ladisch, Julien Benoist, Daniel Mack et al. who initially debugged the issue and patched the kernel.

Unfortunately I still have problems which clicks and crackles even with patched kernels when playing distinct sound files on the TEAC and I'm curious if I'm the only one.

I was able to reproduce the audio problems on different Linux distributions (Ubuntu, Debian, OpenELEC, Kodibuntu all running Kernels >= 3.13), host PCs (as well tested via Linux life CDs on my Windows machine which runs the TEAC on Windows 10 at least at 16bit/44.1 kHz without sound problems) and different input formats (using 16/24 bit 44.1/192 kHz sine wave signal stored in WAV file format and played via aplay). o I tried to debug the problem.

At least my UD-H01 always seems to return "feedback frequency" values (which is actually the expected number of samples per data out transfer, right?) around the nominal value.

When playing back 16/44.1 I receive e. g. feedback value 0x58320, which is (shifted right by 16 bit) 5,51 Samples per Microframe (each 125 us) or 44.099 kHz.

I assume if the pcm buffer of the UD-H01 tends to underrun or overflow, its firmware simply increases or decreases feedback value by (integer) one sample which is represented by feedback value +/- 0x10000.

The workaround introduced with commit 7040b6d1febfdbd9c1595efb751d492cd2503f96 by Clemens Ladisch fully eliminates(!) this +/- 0x10000 feedback response of the UD-H01:

+       if (unlikely(sender->udh01_fb_quirk)) {
+               /*
+                * The TEAC UD-H01 firmware sometimes changes the feedback value
+                * by +/- 0x1.0000.
+                */
+               if (f < ep->freqn - 0x8000)
+                       f += 0x10000;
+               else if (f > ep->freqn + 0x8000)
+                       f -= 0x10000;
+       } else if (unlikely(ep->freqshift == INT_MIN)) {

Consequence for at least my copy of the TEAC DAC is that at buffer underruns still occur. I was able to confirm this using printk debugging in the the snd-usb-audio kernel module.

I fixed my sound problems by replacing +/- 0x10000 in the code above by e.g. +/- 0x0F000. Other values might work as well of course (or might be even better for other copies/models of the TEAC DACs). This patch reactivates the feedback loop by mapping the hefty feedback of the UD-H01 back into a range which can be handled safely by the ALSA/USB isochronous feedback control loop. Here is the modified code (see: attached patch):

+       if (unlikely(sender->udh01_fb_quirk)) {
+               /*
+                * The TEAC UD-H01 firmware sometimes changes the feedback value
+                * by +/- 0x1.0000.
+                */
+               if (f < ep->freqn - 0x8000)
+                       f += 0x0F000;
+               else if (f > ep->freqn + 0x8000)
+                       f -= 0x0F000;
+       } else if (unlikely(ep->freqshift == INT_MIN)) {

I have verified my modification on Debian 8.5.0 AMD64 by patching the stock kernel linux-image-3.16.0-4-amd64 and also on latest Kodibuntu (kodibuntu-14.0~helix_amd64.iso) with stock kernel linux-image-3.13.0-92-generic. Sound output of 16 bit/44.1 kHz and 24 bit/192 kHz WAV files via aplay and kodi works fine for me now. So maybe this patch if useful for other TEAC device owners as well.

If someone who has sound issues with the TEAC is willing to test it, I can also provide .deb packages of the kernels for Debian 8.5.0 and Kodibuntu 14.0.

Currently the patch is only activated for UD-H01 and other models sharing the same usb product id but it is possible that this patch might be useful for other TEAC DAC models (i.e. UD-501) as well.

Best regards,
Norman



--- sound/usb/endpoint.c.orig	2016-07-17 22:27:46.010145241 +0200
+++ sound/usb/endpoint.c	2016-07-18 19:32:51.238432257 +0200
@@ -1129,9 +1129,9 @@ void snd_usb_handle_sync_urb(struct snd_
 		 * by +/- 0x1.0000.
 		 */
 		if (f < ep->freqn - 0x8000)
-			f += 0x10000;
+			f += 0x0F000;
 		else if (f > ep->freqn + 0x8000)
-			f -= 0x10000;
+			f -= 0x0F000;
 	} else if (unlikely(ep->freqshift == INT_MIN)) {
 		/*
 		 * The first time we see a feedback value, determine its format
------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are 
consuming the most bandwidth. Provides multi-vendor support for NetFlow, 
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports.http://sdm.link/zohodev2dev
_______________________________________________
Alsa-user mailing list
Alsa-user@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/alsa-user

[Index of Archives]     [ALSA Devel]     [Linux Audio Users]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]

  Powered by Linux