hiby: usb dac: fix crackling sound due to sample rate mismatch

rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]>
Newsgroups gmane.comp.systems.archos.rockbox.cvs
Message-ID <[email protected]>
commit 20f4f9539a8b56b60227eef9e23c9b5170d9078b
Author: Roman Artiukhin <[email protected]>
Date:   Thu Jul 30 22:09:31 2026 +0300

    hiby: usb dac: fix crackling sound due to sample rate mismatch
    
    Both Ubuntu and Windows fail to report the proper sample rate on my machines, causing crackling sound on my hiby r1. Since we explicitly specify the only supported sample rate (48 kHz), just ignore the reported value.
    
    Change-Id: Ie6e85bf94f9e15fca0c968441d5a8ce5a0088b77

diff --git a/firmware/target/hosted/hiby/usb-dac-hiby.c b/firmware/target/hosted/hiby/usb-dac-hiby.c
index 4b641a2314..469dc640b9 100644
--- a/firmware/target/hosted/hiby/usb-dac-hiby.c
+++ b/firmware/target/hosted/hiby/usb-dac-hiby.c
@@ -148,8 +148,6 @@ static void *dac_pump_thread(void *arg)
 bool usb_dac_start(void)
 {
     static const struct mixer_play_cbs cbs = { .get_more = dac_get_more };
-    int st[3] = {0, 0, 0};
-    unsigned int rate;
 
     /* The node is created asynchronously when the UDC binds; during boot
      * the hotplug helper can lag behind, so wait briefly for it. This runs
@@ -168,12 +166,20 @@ bool usb_dac_start(void)
         return false;
     }
 
-    /* Play at the rate the host negotiated (reported by the kernel). */
-    ioctl(dac_fd, UAC_SA_GET_STATUS, st);
-    if (st[1] >= SAMPR_8 && st[1] <= SAMPR_192)
-        rate = (unsigned int)st[1];
-    else
-        rate = SAMPR_44;
+    int rate = USB_DAC_SAMPLE_RATE;
+#ifdef LOGF_ENABLE
+    // Both on Windows and Linux it always returns 44100 instead of requested rate (which indicates some generic issue).
+    // But since we hardcoded the only supported rate with USB_DAC_SAMPLE_RATE in gadget config (see usb-hiby-gadget.c),
+    // it should be safe to ignore the mismatch and just log it for debugging purposes.
+    int st[3] = {0, 0, 0};
+    int status_ok = ioctl(dac_fd, UAC_SA_GET_STATUS, st);
+    int reported_rate = st[1];
+    if (reported_rate && reported_rate != rate)
+    {
+        logf("uac_sa rate mismatch: ioctl %d, reported %d, expected %d",
+             status_ok, reported_rate, rate);
+    }
+#endif
     mixer_set_frequency(rate);
 
     dac_head = dac_tail = 0;
diff --git a/firmware/target/hosted/hiby/usb-dac-hiby.h b/firmware/target/hosted/hiby/usb-dac-hiby.h
index 0e1c85d0a9..2d6f15007a 100644
--- a/firmware/target/hosted/hiby/usb-dac-hiby.h
+++ b/firmware/target/hosted/hiby/usb-dac-hiby.h
@@ -20,6 +20,8 @@
 #ifndef __USB_DAC_HIBY_H__
 #define __USB_DAC_HIBY_H__
 
+#define USB_DAC_SAMPLE_RATE SAMPR_48
+
 /**
  * Host-PCM pump for the HiBy USB DAC gadget mode: drains /dev/uac_sa
  * into the PCM mixer. Started/stopped by the USB gadget driver when the
diff --git a/firmware/target/hosted/hiby/usb-hiby-gadget.c b/firmware/target/hosted/hiby/usb-hiby-gadget.c
index 5f9f055c0c..c252f6d64e 100644
--- a/firmware/target/hosted/hiby/usb-hiby-gadget.c
+++ b/firmware/target/hosted/hiby/usb-hiby-gadget.c
@@ -159,7 +159,7 @@ static bool adb_compose_dac(void)
     system("mkdir -p " USB_GADGET_PATH "/functions/uac_sa.a");
     sysfs_set_int(USB_GADGET_PATH "/functions/uac_sa.a/c_chmask", 3);
     sysfs_set_int(USB_GADGET_PATH "/functions/uac_sa.a/c_ssize", 2);
-    sysfs_set_int(USB_GADGET_PATH "/functions/uac_sa.a/c_srate", SAMPR_48);
+    sysfs_set_int(USB_GADGET_PATH "/functions/uac_sa.a/c_srate", USB_DAC_SAMPLE_RATE);
     system("ln -sf " USB_GADGET_PATH "/functions/uac_sa.a " USB_GADGET_PATH "/configs/c.1/");
     sysfs_set_string(USB_GADGET_PATH "/configs/c.1/strings/0x409/configuration", "uac,adb");
     return true;
@@ -422,7 +422,7 @@ bool enable_usb_audio(void)
     system("mkdir -p " USB_GADGET_PATH "/functions/uac_sa.a");
     sysfs_set_int(USB_GADGET_PATH "/functions/uac_sa.a/c_chmask", 3);
     sysfs_set_int(USB_GADGET_PATH "/functions/uac_sa.a/c_ssize", 2);
-    sysfs_set_int(USB_GADGET_PATH "/functions/uac_sa.a/c_srate", SAMPR_48);
+    sysfs_set_int(USB_GADGET_PATH "/functions/uac_sa.a/c_srate", USB_DAC_SAMPLE_RATE);
 
     /* Present an IAD audio device with the HiBy DAC VID/PID so the host
      * recognises it as a USB DAC. */
-- 
rockbox-cvs mailing list
[email protected]
https://lists.haxx.se/mailman/listinfo/rockbox-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.