maybe you've seen such a line in your dmesg after plugging in USB
audio devices:

uaudio0: ignored input endpoint of type adaptive
or
uaudio0: ignored output endpoint of type async

these input/adaptive and output/async endpoints need external help to
"synchronize" them, or more accurately, to keep their data rate as
constant as possible.  in the USB specification literature, the
synchronization method is referred to as "feedback" (USB 2.0 Spec.,
Section 5.2.14.2).  usually, it is the responsibility of the driver
to facilitate this feedback, but uaudio(4) does not do this yet, and
that is why you may see the above messages in your dmesg.

however, it is possible that the device is providing the synchronization
on it's own.  consider the following specification excerpts:

from USB Audio Specification 1.0, Section 3.7.2 AudioStreaming Interface:
  [...] Each AudioStreaming interface can have at most one isochronous
  data endpoint.  [...]  In some cases, the isochronous data endpoint
  is accompanied by an associated isochronous synch endpoint for
  synchronisation purposes.  The isochronous data endpoint is required
  to be the first endpoint in the AudioStreaming interface.  The synch
  endpoint always follows its associated data endpoint.

from USB 2.0 Specification, Section 5.12.4.3 Implicit Feedback
  In some cases, implementing a separate explicit feedback endpoint
  can be avoided.  If a device implements a group of isochronous data
  endpoints that are closely related and if:
    * All the endpoints in the group are synchronized (i.e. use
      sample clocks that are derived from a common master clock)
    * The group contains one or more isochronous data endpoints in one
      direction that normally would need explicit feedback
    * The group contains at least one isochronous data endpoint in the
      opposite direction
  Under these circumstances, the device may elect not to implement
  a separate isochronous explicit feedback endpoint.  Instead, feedback
  information can be derived from the data endpoint in the opposite
  direction by observing its data rate.


I have two different audio devices that have input/async endpoints
in their AudioStreaming interface.  these devices should require a
synchronisation endpoint, as the first excerpt says.  however, they
do not provide any such endpoint.  both these audio devices do
provide both recording and playback capabilities (endpoints in both
directions), and as with most audio devices, both playback and
recording very likely use the same clock source.

so, it seems likely to me that these devices are using "implicit
feedback" and don't really need anything special from the driver.
the patch below allows input/adaptive and output/async endpoints
that have no corresponding "synch endpoint" to be used.

this lets me record with:

uaudio0 at uhub1 port 2 configuration 1 interface 0 "Logitech Logitech USB 
Headset" rev 1.10/10.12 addr 2
uaudio0: audio rev 1.00, 6 mixer controls
audio1 at uaudio0

and

uaudio0 at uhub1 port 2 configuration 1 interface 0 "Ten X Technology, Inc. USB 
 AUDIO" rev 1.10/1.0b addr 2
uaudio0: audio rev 1.00, 4 mixer controls
audio1 at uaudio0
(though this thing still has other issues)


Linux (well, ALSA) does the same thing, their comment is, "check the
number of EP, since some devices have broken descriptors which fool us.
if it has only one EP, assume it as adaptive-out or async-in."

please test with any and all USB audio devices.

-- 
[email protected]
SDF Public Access UNIX System - http://sdf.lonestar.org

Index: uaudio.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uaudio.c,v
retrieving revision 1.61
diff -u -p uaudio.c
--- uaudio.c    21 Nov 2008 17:55:02 -0000      1.61
+++ uaudio.c    10 Oct 2009 14:48:30 -0000
@@ -1555,21 +1555,27 @@ uaudio_process_as(struct uaudio_softc *sc, const char 
 
        /* We can't handle endpoints that need a sync pipe yet. */
        sync = FALSE;
-       if (dir == UE_DIR_IN && type == UE_ISO_ADAPT) {
-               sync = TRUE;
+       /* If there's only one endpoint, then the device is implementing
+        * implicit feedback (USB Specification 2.0, Section 5.12.4.3),
+        * and we don't have to configure a sync pipe.
+        */
+       if (id->bNumEndpoints > 1) {
+               if (dir == UE_DIR_IN && type == UE_ISO_ADAPT) {
+                       sync = TRUE;
 #ifndef UAUDIO_MULTIPLE_ENDPOINTS
-               printf("%s: ignored input endpoint of type adaptive\n",
-                      sc->sc_dev.dv_xname);
-               return (USBD_NORMAL_COMPLETION);
+                       printf("%s: ignored input endpoint of type adaptive\n",
+                              sc->sc_dev.dv_xname);
+                       return (USBD_NORMAL_COMPLETION);
 #endif
-       }
-       if (dir != UE_DIR_IN && type == UE_ISO_ASYNC) {
-               sync = TRUE;
+               }
+               if (dir != UE_DIR_IN && type == UE_ISO_ASYNC) {
+                       sync = TRUE;
 #ifndef UAUDIO_MULTIPLE_ENDPOINTS
-               printf("%s: ignored output endpoint of type async\n",
-                      sc->sc_dev.dv_xname);
-               return (USBD_NORMAL_COMPLETION);
+                       printf("%s: ignored output endpoint of type async\n",
+                              sc->sc_dev.dv_xname);
+                       return (USBD_NORMAL_COMPLETION);
 #endif
+               }
        }
 
        sed = (const void *)(buf + offs);
@@ -1581,18 +1587,9 @@ uaudio_process_as(struct uaudio_softc *sc, const char 
        if (offs > size)
                return (USBD_INVAL);
 
-       if (sync && id->bNumEndpoints <= 1) {
-               printf("%s: a sync-pipe endpoint but no other endpoint\n",
-                      sc->sc_dev.dv_xname);
-               return USBD_INVAL;
-       }
-       if (!sync && id->bNumEndpoints > 1) {
-               printf("%s: non sync-pipe endpoint but multiple endpoints\n",
-                      sc->sc_dev.dv_xname);
-               return USBD_INVAL;
-       }
        epdesc1 = NULL;
-       if (id->bNumEndpoints > 1) {
+#ifdef UAUDIO_MULTIPLE_ENDPOINTS
+       if (sync && id->bNumEndpoints > 1) {
                epdesc1 = (const void*)(buf + offs);
                if (epdesc1->bDescriptorType != UDESC_ENDPOINT)
                        return USBD_INVAL;
@@ -1627,6 +1624,7 @@ uaudio_process_as(struct uaudio_softc *sc, const char 
                }
                /* UE_GET_ADDR(epdesc1->bEndpointAddress), and 
epdesc1->bRefresh */
        }
+#endif
 
        format = UGETW(asid->wFormatTag);
        chan = asf1d->bNrChannels;

Reply via email to