Browse Source

Rework UAC/MIDI

* Split UAC from MIDI
* Split UAC into UAC1, UAC2, UAC3 as descriptors and
  other constants are often defined differently
main
Tobias Müller 3 years ago
parent
commit
ad2e7e7d89
10 changed files with 1478 additions and 640 deletions
  1. +0
    -67
      usb_protocol/emitters/descriptors/uac.py
  2. +10
    -0
      usb_protocol/emitters/descriptors/uac1.py
  3. +0
    -3
      usb_protocol/emitters/descriptors/uac2.py
  4. +15
    -0
      usb_protocol/emitters/descriptors/uac3.py
  5. +110
    -0
      usb_protocol/types/descriptors/midi1.py
  6. +88
    -0
      usb_protocol/types/descriptors/midi2.py
  7. +0
    -527
      usb_protocol/types/descriptors/uac.py
  8. +273
    -0
      usb_protocol/types/descriptors/uac1.py
  9. +481
    -37
      usb_protocol/types/descriptors/uac2.py
  10. +501
    -6
      usb_protocol/types/descriptors/uac3.py

+ 0
- 67
usb_protocol/emitters/descriptors/uac.py View File

@@ -1,67 +0,0 @@
#
# This file is part of usb_protocol.
#
""" Convenience emitters for USB Audio Class 2 descriptors. """

from contextlib import contextmanager

from .. import emitter_for_format
from ...types.descriptors.uac import *
from ...types.descriptors.uac2 import *
from ...emitters.descriptor import ComplexDescriptorEmitter

###################### MIDI #########################

StandardMidiStreamingInterfaceDescriptorEmitter = emitter_for_format(StandardMidiStreamingInterfaceDescriptor)
ClassSpecificMidiStreamingInterfaceHeaderDescriptorEmitter = emitter_for_format(ClassSpecificMidiStreamingInterfaceHeaderDescriptor)
StandardMidiStreamingDataEndpointDescriptorEmitter = emitter_for_format(StandardMidiStreamingDataEndpointDescriptor)
StandardMidiStreamingBulkDataEndpointDescriptorEmitter = emitter_for_format(StandardMidiStreamingBulkDataEndpointDescriptor)
MidiInJackDescriptorEmitter = emitter_for_format(MidiInJackDescriptor)
MidiOutJackDescriptorElementEmitter = emitter_for_format(MidiOutJackDescriptorElement)
MidiOutJackDescriptorFootEmitter = emitter_for_format(MidiOutJackDescriptorFoot)
ClassSpecificMidiStreamingBulkDataEndpointDescriptorHeadEmitter = emitter_for_format(ClassSpecificMidiStreamingBulkDataEndpointDescriptorHead)
ClassSpecificMidiStreamingBulkDataEndpointDescriptorElementEmitter = emitter_for_format(ClassSpecificMidiStreamingBulkDataEndpointDescriptorElement)

class ClassSpecificMidiStreamingInterfaceDescriptorEmitter(ComplexDescriptorEmitter):
DESCRIPTOR_FORMAT = ClassSpecificMidiStreamingInterfaceHeaderDescriptor

def _pre_emit(self):
# Figure out the total length of our descriptor, including subordinates.
subordinate_length = sum(len(sub) for sub in self._subordinates)
self.wTotalLength = subordinate_length + self.DESCRIPTOR_FORMAT.sizeof()

class MidiOutJackDescriptorEmitter(ComplexDescriptorEmitter):
DESCRIPTOR_FORMAT = MidiOutJackDescriptorHead

def add_subordinate_descriptor(self, subordinate):
subordinate = subordinate.emit()
self._subordinates.append(subordinate)

def add_source(self, sourceId, sourcePin=1):
sourceDescriptor = MidiOutJackDescriptorElementEmitter()
sourceDescriptor.baSourceID = sourceId
sourceDescriptor.BaSourcePin = sourcePin
self.add_subordinate_descriptor(sourceDescriptor)

def _pre_emit(self):
self.add_subordinate_descriptor(MidiOutJackDescriptorFootEmitter())
# Figure out the total length of our descriptor, including subordinates.
subordinate_length = sum(len(sub) for sub in self._subordinates)
self.bLength = subordinate_length + self.DESCRIPTOR_FORMAT.sizeof()

class ClassSpecificMidiStreamingBulkDataEndpointDescriptorEmitter(ComplexDescriptorEmitter):
DESCRIPTOR_FORMAT = ClassSpecificMidiStreamingBulkDataEndpointDescriptorHead

def add_subordinate_descriptor(self, subordinate):
subordinate = subordinate.emit()
self._subordinates.append(subordinate)

def add_associated_jack(self, jackID):
jackDescriptor = ClassSpecificMidiStreamingBulkDataEndpointDescriptorElementEmitter()
jackDescriptor.baAssocJackID = jackID
self.add_subordinate_descriptor(jackDescriptor)

def _pre_emit(self):
# Figure out the total length of our descriptor, including subordinates.
subordinate_length = sum(len(sub) for sub in self._subordinates)
self.bLength = subordinate_length + self.DESCRIPTOR_FORMAT.sizeof()

+ 10
- 0
usb_protocol/emitters/descriptors/uac1.py View File

@@ -0,0 +1,10 @@
#
# This file is part of usb_protocol.
#
""" Convenience emitters for USB Audio Class 1 descriptors. """

from contextlib import contextmanager

from ...types.descriptors.uac1 import *

AudioControlInterruptEndpointDescriptorEmitter = emitter_for_format(AudioControlInterruptEndpointDescriptor)

+ 0
- 3
usb_protocol/emitters/descriptors/uac2.py View File

@@ -6,12 +6,9 @@
from contextlib import contextmanager

from .. import emitter_for_format
from ...types.descriptors.uac import *
from ...types.descriptors.uac2 import *
from ...emitters.descriptor import ComplexDescriptorEmitter

###################### Audio #########################

# Create our emitters.
InterfaceAssociationDescriptorEmitter = emitter_for_format(InterfaceAssociationDescriptor)
StandardAudioControlInterfaceDescriptorEmitter = emitter_for_format(StandardAudioControlInterfaceDescriptor)


+ 15
- 0
usb_protocol/emitters/descriptors/uac3.py View File

@@ -0,0 +1,15 @@
#
# This file is part of usb_protocol.
#
""" Convenience emitters for USB Audio Class 3 descriptors. """

from .. import emitter_for_format
from ...types.descriptors.uac3 import *

InputTerminalDescriptorEmitter = emitter_for_format(InputTerminalDescriptor)
OutputTerminalDescriptorEmitter = emitter_for_format(OutputTerminalDescriptor)
AudioStreamingInterfaceDescriptorEmitter = emitter_for_format(AudioStreamingInterfaceDescriptor)
ClassSpecificAudioStreamingInterfaceDescriptorEmitter = emitter_for_format(ClassSpecificAudioStreamingInterfaceDescriptor)
AudioControlInterruptEndpointDescriptorEmitter = emitter_for_format(AudioControlInterruptEndpointDescriptor)
AudioStreamingIsochronousEndpointDescriptorEmitter = emitter_for_format(AudioStreamingIsochronousEndpointDescriptor)
AudioStreamingIsochronousFeedbackEndpointDescriptorEmitter = emitter_for_format(AudioStreamingIsochronousFeedbackEndpointDescriptor)

+ 110
- 0
usb_protocol/types/descriptors/midi1.py View File

@@ -0,0 +1,110 @@
#
# This file is part of usb-protocol.
#
"""
Descriptors for USB MIDI Class Devices

[Midi10] refers to "Universal Serial Bus Device Class Definition for MIDI Devices", Release 1.0, November 1, 1999
"""

from enum import IntEnum

from .standard import StandardDescriptorNumbers


class MidiStreamingInterfaceDescriptorSubtypes(IntEnum):
# As defined in [Midi10], A.1
MS_DESCRIPTOR_UNDEFINED = 0x00
MS_HEADER = 0x01
MIDI_IN_JACK = 0x02
MIDI_OUT_JACK = 0x03
ELEMENT = 0x04


class MidiStreamingEndpointDescriptorSubtypes(IntEnum):
# As defined in [Midi10], A.2
DESCRIPTOR_UNDEFINED = 0x00
MS_GENERAL = 0x01


class MidiStreamingJackTypes(IntEnum):
# As defined in [Midi10], A.3
JACK_TYPE_UNDEFINED = 0x00
EMBEDDED = 0x01
EXTERNAL = 0x02


# As defined in [Midi10], Table 6-1
StandardMidiStreamingInterfaceDescriptor = DescriptorFormat(
"bLength" / construct.Const(9, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(DescriptorTypes.INTERFACE),
"bInterfaceNumber" / DescriptorField(description="ID of the streaming interface"),
"bAlternateSetting" / DescriptorField(description="alternate setting number for the interface", default=0),
"bNumEndpoints" / DescriptorField(description="Number of data endpoints used (excluding endpoint 0). Can be: 0 (no data endpoint); 1 (data endpoint); 2 (data + explicit feedback endpoint)", default=0),
"bInterfaceClass" / DescriptorNumber(AudioInterfaceClassCode.AUDIO),
"bInterfaceSubClass" / DescriptorNumber(AudioInterfaceSubclassCodes.MIDI_STREAMING),
"bInterfaceProtocol" / DescriptorNumber(0),
"iInterface" / DescriptorField(description="index of a string descriptor describing this interface (0 = unused)", default=0)
)

# As defined in [Midi10], Table 6-2
ClassSpecificMidiStreamingInterfaceHeaderDescriptor = DescriptorFormat(
"bLength" / construct.Const(7, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificACInterfaceDescriptorSubtypes.HEADER),
"bcdADC" / DescriptorField(description="Midi Streaming Class specification release version", default=1.0),
"wTotalLength" / DescriptorField(description="Total number of bytes of the class-specific MIDIStreaming interface descriptor. Includes the combined length of this descriptor header and all Jack and Element descriptors."),
)

# As defined in [Midi10], Table 6-3
MidiInJackDescriptor = DescriptorFormat(
"bLength" / construct.Const(6, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(MidiStreamingInterfaceDescriptorSubtypes.MIDI_IN_JACK),
"bJackType" / DescriptorField(description="see MidiStreamingJackTypes"),
"bJackID" / DescriptorField(description="Constant uniquely identifying the MIDI IN Jack within the USB-MIDI function"),
"iJack" / DescriptorField(description="index of a string descriptor describing this jack (0 = unused)", default=0)
)

# As defined in [Midi10], Table 6-4
MidiOutJackDescriptorHead = DescriptorFormat(
"bLength" / DescriptorField(description="Size of this descriptor, in bytes: 6+2*p"),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(MidiStreamingInterfaceDescriptorSubtypes.MIDI_OUT_JACK),
"bJackType" / DescriptorField(description="see MidiStreamingJackTypes"),
"bJackID" / DescriptorField(description="Constant uniquely identifying the MIDI IN Jack within the USB-MIDI function"),
"bNrInputPins" / DescriptorField(description="Number of Input Pins of this MIDI OUT Jack: p", default=1)
)

MidiOutJackDescriptorElement = DescriptorFormat(
"baSourceID" / construct.Int8ul, # ID of the Entity to which the first Input Pin of this MIDI OUT Jack is connected
"BaSourcePin" / construct.Int8ul, #Output Pin number of the Entity to which the first Input Pin of this MIDI OUT Jack is connected
)

MidiOutJackDescriptorFoot = DescriptorFormat(
"iJack" / DescriptorField(description="index of a string descriptor describing this jack (0 = unused)", default=0)
)

# As defined in [Midi10], Table 6-6
StandardMidiStreamingBulkDataEndpointDescriptor = DescriptorFormat(
"bLength" / construct.Const(9, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(DescriptorTypes.ENDPOINT),
"bEndpointAddress" / DescriptorField(description="The address of the endpoint, use USBDirection.*.from_endpoint_address()"),
"bmAttributes" / DescriptorField(description="D1..0: transfer type (10=bulk), D3..2: synchronization type (00=no sync);", default=USBTransferType.BULK | USBSynchronizationType.NONE | USBUsageType.DATA),
"wMaxPacketSize" / DescriptorField(description="Maximum packet size this endpoint is capable of", default=512),
"bInterval" / DescriptorField(description="Interval for polling endpoint for data transfers expressed in milliseconds. This field is ignored for bulk endpoints. Must be set to 0", default=0),
"bRefresh" / DescriptorField(description="must be set to 0", default=0),
"bSynchAddress" / DescriptorField(description="The address of the endpoint used to communicate synchronization information if required by this endpoint. Must be set to 0", default=0)
)

# As defined in [Midi10], Table 6-7
ClassSpecificMidiStreamingBulkDataEndpointDescriptorHead = DescriptorFormat(
"bLength" / DescriptorField(description="Size of this descriptor, in bytes: 4+n"),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_ENDPOINT),
"bDescriptorSubtype" / DescriptorField(description="see MidiStreamingEndpointDescriptorSubtypes", default=MidiStreamingEndpointDescriptorSubtypes.MS_GENERAL),
"bNumEmbMIDIJack" / DescriptorField(description="Number of Embedded MIDI Jacks: n", default=1)
)

ClassSpecificMidiStreamingBulkDataEndpointDescriptorElement = DescriptorFormat(
"baAssocJackID" / construct.Int8ul # ID of the embedded eack that is associated with this endpoint
)

+ 88
- 0
usb_protocol/types/descriptors/midi2.py View File

@@ -0,0 +1,88 @@
#
# This file is part of usb-protocol.
#
"""
Descriptors for USB MIDI Class Devices

[Midi20] refers to "Universal Serial Bus Device Class Definition for MIDI Devices", Release 2.0, May 5, 2020
"""

from enum import IntEnum

from .standard import StandardDescriptorNumbers


class MidiStreamingInterfaceDescriptorTypes(IntEnum):
# As defined in [Midi20], A.1
CS_UNDEFINED = 0x20
CS_DEVICE = 0x21
CS_CONFIGURATION = 0x22
CS_STRING = 0x23
CS_INTERFACE = 0x24
CS_ENDPOINT = 0x25
CS_GR_TRM_BLOCK = 0x26


class MidiStreamingInterfaceDescriptorSubtypes(IntEnum):
# As defined in [Midi20], A.1
MS_DESCRIPTOR_UNDEFINED = 0x00
MS_HEADER = 0x01
MIDI_IN_JACK = 0x02
MIDI_OUT_JACK = 0x03
ELEMENT = 0x04


class MidiStreamingEndpointDescriptorSubtypes(IntEnum):
# As defined in [Midi20], A.2
DESCRIPTOR_UNDEFINED = 0x00
MS_GENERAL = 0x01
MS_GENERAL_2_0 = 0x02


class MidiStreamingInterfaceHeaderClassRevision(IntEnum):
# As defined in [Midi20], A.4
MS_MIDI_1_0 = 0x0100
MS_MIDI_2_0 = 0x0200


class MidiStreamingJackTypes(IntEnum):
# As defined in [Midi20], A.5
JACK_TYPE_UNDEFINED = 0x00
EMBEDDED = 0x01
EXTERNAL = 0x02


# As defined in [Midi20], Table B-5
StandardMidiStreamingInterfaceDescriptor = DescriptorFormat(
"bLength" / construct.Const(9, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(DescriptorTypes.INTERFACE),
"bInterfaceNumber" / DescriptorField(description="ID of the streaming interface"),
"bAlternateSetting" / DescriptorField(description="alternate setting number for the interface", default=0),
"bNumEndpoints" / DescriptorField(description="Number of data endpoints used (excluding endpoint 0). Can be: 0 (no data endpoint); 1 (data endpoint); 2 (data + explicit feedback endpoint)", default=0),
"bInterfaceClass" / DescriptorNumber(AudioInterfaceClassCode.AUDIO),
"bInterfaceSubClass" / DescriptorNumber(AudioInterfaceSubclassCodes.MIDI_STREAMING),
"bInterfaceProtocol" / DescriptorNumber(0),
"iInterface" / DescriptorField(description="index of a string descriptor describing this interface (0 = unused)", default=0)
)

# As defined in [Midi20], Table B-6
ClassSpecificMidiStreamingInterfaceHeaderDescriptor = DescriptorFormat(
"bLength" / construct.Const(7, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificACInterfaceDescriptorSubtypes.HEADER),
"bcdADC" / DescriptorField(description="Midi Streaming Class specification release version", default=1.0),
"wTotalLength" / DescriptorField(description="Total number of bytes of the class-specific MIDIStreaming interface descriptor. Includes the combined length of this descriptor header and all Jack and Element descriptors."),
)

# As defined in [Midi20], Table 5-3
StandardMidiStreamingDataEndpointDescriptor = DescriptorFormat(
"bLength" / construct.Const(7, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_ENDPOINT),
"bEndpointAddress" / DescriptorField(description="endpoint address, use USBDirection.*.from_endpoint_address()"),
"bmAttributes" / DescriptorField(description="endpoint type, see USBTransferType (only NONE, BULK or INTERRUPT allowed)", default=USBTransferType.BULK),
"wMaxPacketSize" / DescriptorField(description="Maximum packet size this endpoint is capable of sending or receiving"),
"bInterval" / DescriptorField(description="Interval for polling endpoint for Interrupt data transfers. For bulk endpoints this field is ignored and must be reset to 0", default=0)
)




+ 0
- 527
usb_protocol/types/descriptors/uac.py View File

@@ -1,527 +0,0 @@
#
# This file is part of usb-protocol.
#
""" common USB audio enums and descriptors """

from usb_protocol.types import USBSynchronizationType, USBUsageType
from enum import IntEnum

import construct

from .. import USBTransferType
from ..descriptor import \
DescriptorField, DescriptorNumber, DescriptorFormat

class AudioInterfaceClassCode(IntEnum):
AUDIO = 0x01

class AudioFunctionClassCode(IntEnum):
AUDIO_FUNCTION = AudioInterfaceClassCode.AUDIO

class AudioInterfaceProtocolCodes(IntEnum):
IP_VERSION_01_00 = 0x00
IP_VERSION_02_00 = 0x20
IP_VERSION_03_00 = 0x30

class AudioFunctionProtocolCodes(IntEnum):
FUNCTION_PROTOCOL_UNDEFINED = 0x00
AF_VERSION_01_00 = AudioInterfaceProtocolCodes.IP_VERSION_01_00
AF_VERSION_02_00 = AudioInterfaceProtocolCodes.IP_VERSION_02_00
AF_VERSION_03_00 = AudioInterfaceProtocolCodes.IP_VERSION_03_00

class AudioFunctionSubclassCodes(IntEnum):
FUNCTION_SUBCLASS_UNDEFINED = 0x00
FULL_ADC_3_0 = 0x01
GENERIC_IO = 0x20
HEADPHONE = 0x21
SPEAKER = 0x22
MICROPHONE = 0x23
HEADSET = 0x24
HEADSET_ADAPTER = 0x25
SPEAKERPHONE = 0x26

class AudioInterfaceSubclassCodes(IntEnum):
INTERFACE_SUBCLASS_UNDEFINED = 0x00
AUDIO_CONTROL = 0x01
AUDIO_STREAMING = 0x02
MIDI_STREAMING = 0x03

class AudioFunctionCategoryCodes(IntEnum):
FUNCTION_SUBCLASS_UNDEFINED = 0x00
DESKTOP_SPEAKER = 0x01
HOME_THEATER = 0x02
MICROPHONE = 0x03
HEADSET = 0x04
TELEPHONE = 0x05
CONVERTER = 0x06
VOICE_SOUND_RECORDER = 0x07
IO_BOX = 0x08
MUSICAL_INSTRUMENT = 0x09
PRO_AUDIO = 0x0A
AUDIO_VIDEO = 0x0B
CONTROL_PANEL = 0x0C
HEADPHONE = 0x0D
GENERIC_SPEAKER = 0x0E
HEADSET_ADAPTER = 0x0F
SPEAKERPHONE = 0x10
OTHER = 0xFF


class DescriptorTypes(IntEnum):
INTERFACE = 0x04
ENDPOINT = 0x05
INTERFACE_ASSOCIATION = 0x0B

class AudioClassSpecificDescriptorTypes(IntEnum):
CS_UNDEFINED = 0x20
CS_DEVICE = 0x21
CS_CONFIGURATION = 0x22
CS_STRING = 0x23
CS_INTERFACE = 0x24
CS_ENDPOINT = 0x25
CS_CLUSTER = 0x26

class ClusterDescriptorSubtypes(IntEnum):
SUBTYPE_UNDEFINED = 0x00

class ClusterDescriptorSegmentTypes(IntEnum):
SEGMENT_UNDEFINED = 0x00
CLUSTER_DESCRIPTION = 0x01
CLUSTER_VENDOR_DEFINED = 0x1F
CHANNEL_INFORMATION = 0x20
CHANNEL_AMBISONIC = 0x21
CHANNEL_DESCRIPTION = 0x22
CHANNEL_VENDOR_DEFINED = 0xFE
END_SEGMENT = 0xFF

class ChannelPurposeDefinitions(IntEnum):
PURPOSE_UNDEFINED = 0x00
GENERIC_AUDIO = 0x01
VOICE = 0x02
SPEECH = 0x03
AMBIENT = 0x04
REFERENCE = 0x05
ULTRASONIC = 0x06
VIBROKINETIC = 0x07
NON_AUDIO = 0xFF

class AmbisonicComponentOrderingConventionTypes(IntEnum):
ORD_TYPE_UNDEFINED = 0x00
AMBISONIC_CHANNEL_NUMBER_ACN = 0x01
FURSE_MALHAM = 0x02
SINGLE_INDEX_DESIGNATION_SID = 0x03

class AmbisonicNormalizatioTypes(IntEnum):
NORM_TYPE_UNDEFINED = 0x00
MAX_N = 0x01
SN3D = 0x02
N3D = 0x03
SN2D = 0x04
N2D = 0x05

class AudioClassSpecificACInterfaceDescriptorSubtypes(IntEnum):
AC_DESCRIPTOR_UNDEFINED = 0x00
HEADER = 0x01
INPUT_TERMINAL = 0x02
OUTPUT_TERMINAL = 0x03
EXTENDED_TERMINAL = 0x04
MIXER_UNIT = 0x05
SELECTOR_UNIT = 0x06
FEATURE_UNIT = 0x07
EFFECT_UNIT = 0x08
PROCESSING_UNIT = 0x09
EXTENSION_UNIT = 0x0A
CLOCK_SOURCE = 0x0B
CLOCK_SELECTOR = 0x0C
CLOCK_MULTIPLIER = 0x0D
SAMPLE_RATE_CONVERTER = 0x0E
CONNECTORS = 0x0F
POWER_DOMAIN = 0x10
class AudioClassSpecificStringDescriptorSubtypes(IntEnum):
SUBTYPE_UNDEFINED = 0x00

class ExtendedTerminalSegmentTypes(IntEnum):
SEGMENT_UNDEFINED = 0x00
TERMINAL_VENDOR_DEFINED = 0x1F
CHANNEL_BANDWIDTH = 0x20
CHANNEL_MAGNITUDE_RESPONSE = 0x21
CHANNEL_MAGNITUDE_PHASE_RESPONSE = 0x22
CHANNEL_POSITION_XYZ = 0x23
CHANNEL_POSITION_R_THETA_PHI = 0x24
CHANNEL_VENDOR_DEFINED = 0xFE
END_SEGMENT = 0xFF

class EffectUnitEffectTypes(IntEnum):
EFFECT_UNDEFINED = 0x0000
PARAM_EQ_SECTION_EFFECT = 0x0001
REVERBERATION_EFFECT = 0x0002
MOD_DELAY_EFFECT = 0x0003
DYN_RANGE_COMP_EFFECT = 0x0004

class ProcessingUnitProcessTypes(IntEnum):
PROCESS_UNDEFINED = 0x0000
UP_DOWNMIX_PROCESS = 0x0001
STEREO_EXTENDER_PROCESS = 0x0002
MULTI_FUNCTION_PROCESS = 0x0003

class AudioClassSpecificEndpointDescriptorSubtypes(IntEnum):
DESCRIPTOR_UNDEFINED = 0x00
EP_GENERAL = 0x01

class AudioClassSpecificRequestCodes(IntEnum):
REQUEST_CODE_UNDEFINED = 0x00
CUR = 0x01
RANGE = 0x02
MEM = 0x03
INTEN = 0x04
STRING = 0x05
HIGH_CAPABILITY_DESCRIPTOR = 0x06

class AudioControlInterfaceControlSelectors(IntEnum):
AC_CONTROL_UNDEFINED = 0x00
AC_ACTIVE_INTERFACE_CONTROL = 0x01
AC_POWER_DOMAIN_CONTROL = 0x02

class ClockSourceControlSelectors(IntEnum):
CS_CONTROL_UNDEFINED = 0x00
CS_SAM_FREQ_CONTROL = 0x01
CS_CLOCK_VALID_CONTROL = 0x02

class ClockSelectorControlSelectors(IntEnum):
CX_CONTROL_UNDEFINED = 0x00
CX_CLOCK_SELECTOR_CONTROL = 0x01

class ClockMultiplierControlSelectors(IntEnum):
CM_CONTROL_UNDEFINED = 0x00
CM_NUMERATOR_CONTROL = 0x01
CM_DENOMINATOR_CONTROL = 0x02

class TerminalControlSelectors(IntEnum):
TE_CONTROL_UNDEFINED = 0x00
TE_INSERTION_CONTROL = 0x01
TE_OVERLOAD_CONTROL = 0x02
TE_UNDERFLOW_CONTROL = 0x03
TE_OVERFLOW_CONTROL = 0x04
TE_LATENCY_CONTROL = 0x05

class MixerControlSelectors(IntEnum):
MU_CONTROL_UNDEFINED = 0x00
MU_MIXER_CONTROL = 0x01
MU_UNDERFLOW_CONTROL = 0x02
MU_OVERFLOW_CONTROL = 0x03
MU_LATENCY_CONTROL = 0x04

class SelectorControlSelectors(IntEnum):
SU_CONTROL_UNDEFINED = 0x00
SU_SELECTOR_CONTROL = 0x01
SU_LATENCY_CONTROL = 0x02

class FeatureUnitControlSelectors(IntEnum):
FU_CONTROL_UNDEFINED = 0x00
FU_MUTE_CONTROL = 0x01
FU_VOLUME_CONTROL = 0x02
FU_BASS_CONTROL = 0x03
FU_MID_CONTROL = 0x04
FU_TREBLE_CONTROL = 0x05
FU_GRAPHIC_EQUALIZER_CONTROL = 0x06
FU_AUTOMATIC_GAIN_CONTROL = 0x07
FU_DELAY_CONTROL = 0x08
FU_BASS_BOOST_CONTROL = 0x09
FU_LOUDNESS_CONTROL = 0x0A
FU_INPUT_GAIN_CONTROL = 0x0B
FU_INPUT_GAIN_PAD_CONTROL = 0x0C
FU_PHASE_INVERTER_CONTROL = 0x0D
FU_UNDERFLOW_CONTROL = 0x0E
FU_OVERFLOW_CONTROL = 0x0F
FU_LATENCY_CONTROL = 0x10

class ParametricEqualizerSectionEffectUnitControlSelectors(IntEnum):
PE_CONTROL_UNDEFINED = 0x00
PE_ENABLE_CONTROL = 0x01
PE_CENTERFREQ_CONTROL = 0x02
PE_QFACTOR_CONTROL = 0x03
PE_GAIN_CONTROL = 0x04
PE_UNDERFLOW_CONTROL = 0x05
PE_OVERFLOW_CONTROL = 0x06
PE_LATENCY_CONTROL = 0x07

class ReverberationEffectUnitControlSelectors(IntEnum):
RV_CONTROL_UNDEFINED = 0x00
RV_ENABLE_CONTROL = 0x01
RV_TYPE_CONTROL = 0x02
RV_LEVEL_CONTROL = 0x03
RV_TIME_CONTROL = 0x04
RV_FEEDBACK_CONTROL = 0x05
RV_PREDELAY_CONTROL = 0x06
RV_DENSITY_CONTROL = 0x07
RV_HIFREQ_ROLLOFF_CONTROL = 0x08
RV_UNDERFLOW_CONTROL = 0x09
RV_OVERFLOW_CONTROL = 0x0A
RV_LATENCY_CONTROL = 0x0B

class ModulationDelayEffectUnitControlSelectors(IntEnum):
MD_CONTROL_UNDEFINED = 0x00
MD_ENABLE_CONTROL = 0x01
MD_BALANCE_CONTROL = 0x02
MD_RATE_CONTROL = 0x03
MD_DEPTH_CONTROL = 0x04
MD_TIME_CONTROL = 0x05
MD_FEEDBACK_CONTROL = 0x06
MD_UNDERFLOW_CONTROL = 0x07
MD_OVERFLOW_CONTROL = 0x08
MD_LATENCY_CONTROL = 0x09

class DynamicRangeCompressorEffectUnitControlSelectors(IntEnum):
DR_CONTROL_UNDEFINED = 0x00
DR_ENABLE_CONTROL = 0x01
DR_COMPRESSION_RATE_CONTROL = 0x02
DR_MAXAMPL_CONTROL = 0x03
DR_THRESHOLD_CONTROL = 0x04
DR_ATTACK_TIME_CONTROL = 0x05
DR_RELEASE_TIME_CONTROL = 0x06
DR_UNDERFLOW_CONTROL = 0x07
DR_OVERFLOW_CONTROL = 0x08
DR_LATENCY_CONTROL = 0x09

class UpDownMixProcessingUnitControlSelectors(IntEnum):
UD_CONTROL_UNDEFINED = 0x00
UD_MODE_SELECT_CONTROL = 0x01
UD_UNDERFLOW_CONTROL = 0x02
UD_OVERFLOW_CONTROL = 0x03
UD_LATENCY_CONTROL = 0x04

class StereoExtenderProcessingUnitControlSelectors(IntEnum):
ST_EXT_CONTROL_UNDEFINED = 0x00
ST_EXT_WIDTH_CONTROL = 0x01
ST_EXT_UNDERFLOW_CONTROL = 0x02
ST_EXT_OVERFLOW_CONTROL = 0x03
ST_EXT_LATENCY_CONTROL = 0x04

class ExtensionUnitControlSelectors(IntEnum):
XU_CONTROL_UNDEFINED = 0x00
XU_UNDERFLOW_CONTROL = 0x01
XU_OVERFLOW_CONTROL = 0x02
XU_LATENCY_CONTROL = 0x03

class AudioStreamingInterfaceControlSelectors(IntEnum):
AS_CONTROL_UNDEFINED = 0x00
AS_ACT_ALT_SETTING_CONTROL = 0x01
AS_VAL_ALT_SETTINGS_CONTROL = 0x02
AS_AUDIO_DATA_FORMAT_CONTROL = 0x03

class EndpointControlSelectors(IntEnum):
EP_CONTROL_UNDEFINED = 0x00
EP_PITCH_CONTROL = 0x01
EP_DATA_OVERRUN_CONTROL = 0x02
EP_DATA_UNDERRUN_CONTROL = 0x03

###################### Terminal Types #########################

class USBTerminalTypes(IntEnum):
USB_UNDEFINED = 0x0100
USB_STREAMING = 0x0101
USB_VENDOR_SPECIFIC = 0x01FF

class InputTerminalTypes(IntEnum):
INPUT_UNDEFINED = 0x0200
MICROPHONE = 0x0201
DESKTOP_MICROPHONE = 0x0202
PERSONAL_MICROPHONE = 0x0203
OMNI_DIRECTIONAL_MICROPHONE = 0x0204
MICROPHONE_ARRAY = 0x0205
PROCESSING_MICROPHONE_ARRAY = 0x0206

class OutputTerminalTypes(IntEnum):
OUTPUT_UNDEFINED = 0x0300
SPEAKER = 0x0301
HEADPHONES = 0x0302
DESKTOP_SPEAKER = 0x0304
ROOM_SPEAKER = 0x0305
COMMUNICATION_SPEAKER = 0x0306
LOW_FREQUENCY_EFFECTS_SPEAKER = 0x0307

class BidirectionalTerminalTypes(IntEnum):
BIDIRECTIONAL_UNDEFINED = 0x0400
HANDSET = 0x0401
HEADSET = 0x0402
ECHO_SUPPRESSING_SPEAKERPHONE = 0x0404
ECHO_CANCELING_SPEAKERPHONE = 0x0405

class TelephonyTerminalTypes(IntEnum):
TELEPHONY_UNDEFINED = 0x0500
PHONE_LINE = 0x0501
TELEPHONE = 0x0502
DOWN_LINE_PHONE = 0x0503

class ExternalTerminalTypes(IntEnum):
EXTERNAL_UNDEFINED = 0x0600
ANALOG_CONNECTOR = 0x0601
DIGITAL_AUDIO_INTERFACE = 0x0602
LINE_CONNECTOR = 0x0603
SPDIF_INTERFACE = 0x0605
IEEE_1394_DA_STREAM = 0x0606
IEEE_1394_DV_STREAM_SOUNDTRACK = 0x0607
ADAT_LIGHTPIPE = 0x0608
TDIF = 0x0609
MADI = 0x060A

class EmbeddedFunctionTerminalTypes(IntEnum):
EMBEDDED_UNDEFINED = 0x0700
EQUALIZATION_NOISE = 0x0702
CD_PLAYER = 0x0703
DAT = 0x0704
DCC = 0x0705
ANALOG_TAPE = 0x0707
PHONOGRAPH = 0x0708
VCR_AUDIO = 0x0709
VIDEO_DISC_AUDIO = 0x070A
DVD_AUDIO = 0x070B
TV_TUNER_AUDIO = 0x070C
SATELLITE_RECEIVER_AUDIO = 0x070D
CABLE_TUNER_AUDIO = 0x070E
DSS_AUDIO = 0x070F
RADIO_RECEIVER = 0x0710
RADIO_TRANSMITTER = 0x0711
MULTI_TRACK_RECORDER = 0x0712
SYNTHESIZER = 0x0713
PIANO = 0x0714
GUITAR = 0x0715
DRUMS_RHYTHM = 0x0716
OTHER_MUSICAL_INSTRUMENT = 0x0717

AudioControlInterruptEndpointDescriptor = DescriptorFormat(
"bLength" / construct.Const(7, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_ENDPOINT),
"bEndpointAddress" / DescriptorField(description="The address of the endpoint, use USBDirection.*.from_endpoint_address()"),
"bmAttributes" / DescriptorField(description="D1..0: Transfer type (0b11 = Interrupt)", default=0b11),
"wMaxPacketSize" / DescriptorField(description="Maximum packet size this endpoint is capable of. Used here to pass 6-byte interrupt information.", default=6),
"bInterval" / DescriptorField(description="Interval for polling the Interrupt endpoint")
)

AudioStreamingIsochronousEndpointDescriptor = DescriptorFormat(
"bLength" / construct.Const(7, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(DescriptorTypes.ENDPOINT),
"bEndpointAddress" / DescriptorField(description="The address of the endpoint, use USBDirection.*.from_endpoint_address()"),
"bmAttributes" / DescriptorField(description="D1..0: transfer type (01=isochronous); D3..2: synchronization type (01=asynchronous/10=adaptive/11=synchronous); D5..4: usage (00=data/10=feedback)", default=0b000101),
"wMaxPacketSize" / DescriptorField(description="Maximum packet size this endpoint is capable of. Used here to pass 6-byte interrupt information.", default=6),
"bInterval" / DescriptorField(description="Interval for polling the Interrupt endpoint")
)

AudioStreamingIsochronousFeedbackEndpointDescriptor = DescriptorFormat(
"bLength" / construct.Const(7, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(DescriptorTypes.ENDPOINT),
"bEndpointAddress" / DescriptorField(description="The address of the endpoint, use USBDirection.*.from_endpoint_address()"),
"bmAttributes" / DescriptorField(description="D1..0: transfer type (01=isochronous); D3..2: synchronization type (00=no sync); D5..4: usage (10=feedback)", default=0b00100001),
"wMaxPacketSize" / DescriptorField(description="Maximum packet size this endpoint is capable of. Used here to pass 6-byte interrupt information.", default=6),
"bInterval" / DescriptorField(description="Interval for polling the Interrupt endpoint")
)

###################### MIDI #########################
class MidiStreamingInterfaceDescriptorTypes(IntEnum):
CS_UNDEFINED = 0x20
CS_DEVICE = 0x21
CS_CONFIGURATION = 0x22
CS_STRING = 0x23
CS_INTERFACE = 0x24
CS_ENDPOINT = 0x25
CS_GR_TRM_BLOCK = 0x26

class MidiStreamingInterfaceDescriptorSubtypes(IntEnum):
MS_DESCRIPTOR_UNDEFINED = 0x00
MS_HEADER = 0x01
MIDI_IN_JACK = 0x02
MIDI_OUT_JACK = 0x03
ELEMENT = 0x04

class MidiStreamingEndpointDescriptorSubtypes(IntEnum):
DESCRIPTOR_UNDEFINED = 0x00
MS_GENERAL = 0x01
MS_GENERAL_2_0 = 0x02

class MidiStreamingInterfaceHeaderClassRevision(IntEnum):
MS_MIDI_1_0 = 0x0100
MS_MIDI_2_0 = 0x0200

class MidiStreamingJackTypes(IntEnum):
JACK_TYPE_UNDEFINED = 0x00
EMBEDDED = 0x01
EXTERNAL = 0x02

StandardMidiStreamingInterfaceDescriptor = DescriptorFormat(
"bLength" / construct.Const(9, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(DescriptorTypes.INTERFACE),
"bInterfaceNumber" / DescriptorField(description="ID of the streaming interface"),
"bAlternateSetting" / DescriptorField(description="alternate setting number for the interface", default=0),
"bNumEndpoints" / DescriptorField(description="Number of data endpoints used (excluding endpoint 0). Can be: 0 (no data endpoint); 1 (data endpoint); 2 (data + explicit feedback endpoint)", default=0),
"bInterfaceClass" / DescriptorNumber(AudioInterfaceClassCode.AUDIO),
"bInterfaceSubClass" / DescriptorNumber(AudioInterfaceSubclassCodes.MIDI_STREAMING),
"bInterfaceProtocol" / DescriptorNumber(0),
"iInterface" / DescriptorField(description="index of a string descriptor describing this interface (0 = unused)", default=0)
)

ClassSpecificMidiStreamingInterfaceHeaderDescriptor = DescriptorFormat(
"bLength" / construct.Const(7, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificACInterfaceDescriptorSubtypes.HEADER),
"bcdADC" / DescriptorField(description="Midi Streaming Class specification release version", default=1.0),
"wTotalLength" / DescriptorField(description="Total number of bytes of the class-specific MIDIStreaming interface descriptor. Includes the combined length of this descriptor header and all Jack and Element descriptors."),
)

StandardMidiStreamingDataEndpointDescriptor = DescriptorFormat(
"bLength" / construct.Const(7, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_ENDPOINT),
"bEndpointAddress" / DescriptorField(description="endpoint address, use USBDirection.*.from_endpoint_address()"),
"bmAttributes" / DescriptorField(description="endpoint type, see USBTransferType (only NONE, BULK or INTERRUPT allowed)", default=USBTransferType.BULK),
"wMaxPacketSize" / DescriptorField(description="Maximum packet size this endpoint is capable of sending or receiving"),
"bInterval" / DescriptorField(description="Interval for polling endpoint for Interrupt data transfers. For bulk endpoints this field is ignored and must be reset to 0", default=0)
)

MidiInJackDescriptor = DescriptorFormat(
"bLength" / construct.Const(6, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(MidiStreamingInterfaceDescriptorSubtypes.MIDI_IN_JACK),
"bJackType" / DescriptorField(description="see MidiStreamingJackTypes"),
"bJackID" / DescriptorField(description="Constant uniquely identifying the MIDI IN Jack within the USB-MIDI function"),
"iJack" / DescriptorField(description="index of a string descriptor describing this jack (0 = unused)", default=0)
)

MidiOutJackDescriptorHead = DescriptorFormat(
"bLength" / DescriptorField(description="Size of this descriptor, in bytes: 6+2*p"),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(MidiStreamingInterfaceDescriptorSubtypes.MIDI_OUT_JACK),
"bJackType" / DescriptorField(description="see MidiStreamingJackTypes"),
"bJackID" / DescriptorField(description="Constant uniquely identifying the MIDI IN Jack within the USB-MIDI function"),
"bNrInputPins" / DescriptorField(description="Number of Input Pins of this MIDI OUT Jack: p", default=1)
)

MidiOutJackDescriptorElement = DescriptorFormat(
"baSourceID" / construct.Int8ul, # ID of the Entity to which the first Input Pin of this MIDI OUT Jack is connected
"BaSourcePin" / construct.Int8ul, #Output Pin number of the Entity to which the first Input Pin of this MIDI OUT Jack is connected
)

MidiOutJackDescriptorFoot = DescriptorFormat(
"iJack" / DescriptorField(description="index of a string descriptor describing this jack (0 = unused)", default=0)
)

StandardMidiStreamingBulkDataEndpointDescriptor = DescriptorFormat(
"bLength" / construct.Const(9, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(DescriptorTypes.ENDPOINT),
"bEndpointAddress" / DescriptorField(description="The address of the endpoint, use USBDirection.*.from_endpoint_address()"),
"bmAttributes" / DescriptorField(description="D1..0: transfer type (10=bulk), D3..2: synchronization type (00=no sync);", default=USBTransferType.BULK | USBSynchronizationType.NONE | USBUsageType.DATA),
"wMaxPacketSize" / DescriptorField(description="Maximum packet size this endpoint is capable of", default=512),
"bInterval" / DescriptorField(description="Interval for polling endpoint for data transfers expressed in milliseconds. This field is ignored for bulk endpoints. Must be set to 0", default=0),
"bRefresh" / DescriptorField(description="must be set to 0", default=0),
"bSynchAddress" / DescriptorField(description="The address of the endpoint used to communicate synchronization information if required by this endpoint. Must be set to 0", default=0)
)

ClassSpecificMidiStreamingBulkDataEndpointDescriptorHead = DescriptorFormat(
"bLength" / DescriptorField(description="Size of this descriptor, in bytes: 4+n"),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_ENDPOINT),
"bDescriptorSubtype" / DescriptorField(description="see MidiStreamingEndpointDescriptorSubtypes", default=MidiStreamingEndpointDescriptorSubtypes.MS_GENERAL),
"bNumEmbMIDIJack" / DescriptorField(description="Number of Embedded MIDI Jacks: n", default=1)
)

ClassSpecificMidiStreamingBulkDataEndpointDescriptorElement = DescriptorFormat(
"baAssocJackID" / construct.Int8ul # ID of the embedded eack that is associated with this endpoint
)

+ 273
- 0
usb_protocol/types/descriptors/uac1.py View File

@@ -0,0 +1,273 @@
#
# This file is part of usb-protocol.
#
"""
Descriptors for USB Audio Class Devices (UAC), Release 1

[Audio10] refers to "Universal Serial Bus Device Class Definition for Audio Devices", Release 1.0, March 18, 1998
[Frmts10] refers to "Universal Serial Bus Device Class Definition for Audio Data Formats", Release 1.0, March 18, 1998
[TermT10] refers to "Universal Serial Bus Device Class Definition for Terminal Types", Release 1.0, March 18, 1998
"""

from enum import IntEnum

from .standard import StandardDescriptorNumbers


class AudioInterfaceClassCode(IntEnum):
# As defined in [Audio10], Table A-1
AUDIO = 0x01


class AudioInterfaceSubclassCodes(IntEnum):
# As defined in [Audio10], Table A-2
INTERFACE_SUBCLASS_UNDEFINED = 0x00
AUDIO_CONTROL = 0x01
AUDIO_STREAMING = 0x02
MIDI_STREAMING = 0x03


class AudioInterfaceProtocolCodes(IntEnum):
# As defined in [Audio10], Table A-3
PR_PROTOCOL_UNDEFINED = 0x00


class AudioClassSpecificDescriptorTypes(IntEnum):
# As defined in [Audio10], Table A-4
CS_UNDEFINED = 0x20
CS_DEVICE = 0x21
CS_CONFIGURATION = 0x22
CS_STRING = 0x23
CS_INTERFACE = 0x24
CS_ENDPOINT = 0x25


class AudioClassSpecificACInterfaceDescriptorSubtypes(IntEnum):
# As defined in [Audio10], Table A-5
AC_DESCRIPTOR_UNDEFINED = 0x00
HEADER = 0x01
INPUT_TERMINAL = 0x02
OUTPUT_TERMINAL = 0x03
MIXER_UNIT = 0x04
SELECTOR_UNIT = 0x05
FEATURE_UNIT = 0x06
PROCESSING_UNIT = 0x07
EXTENSION_UNIT = 0x08


class AudioClassSpecificASInterfaceDescriptorSubtypes(IntEnum):
# As defined in [Audio10], Table A-6
AS_DESCRIPTOR_UNDEFINED = 0x00
AS_GENERAL = 0x01
FORMAT_TYPE = 0x02
FORMAT_SPECIFIC = 0x03


class ProcessingUnitProcessTypes(IntEnum):
# As defined in [Audio10], Table A-7
PROCESS_UNDEFINED = 0x00
UP_DOWNMIX_PROCESS = 0x01
DOLBY_PROLOGIC_PROCESS = 0x02
3D_STEREO_EXTENDER_PROCESS = 0x03
REVERBERATION_PROCESS = 0x04
CHORUS_PROCESS = 0x05
DYN_RANGE_COMP_PROCESS = 0x06


class AudioClassSpecificEndpointDescriptorSubtypes(IntEnum):
# As defined in [Audio10], Table A-8
DESCRIPTOR_UNDEFINED = 0x00
EP_GENERAL = 0x01


class AudioClassSpecificRequestCodes(IntEnum):
# As defined in [Audio10], Table A-9
REQUEST_CODE_UNDEFINED = 0x00
SET_CUR = 0x01
GET_CUR = 0x81
SET_MIN = 0x02
GET_MIN = 0x82
SET_MAX = 0x03
GET_MAX = 0x83
SET_RES = 0x04
GET_RES = 0x84
SET_MEM = 0x05
GET_MEM = 0x85
GET_STAT = 0xFF


class TerminalControlSelectors(IntEnum):
# As defined in [Audio10], Table A-10
TE_CONTROL_UNDEFINED = 0x00
COPY_PROTECT_CONTROL = 0x01


class FeatureUnitControlSelectors(IntEnum):
# As defined in [Audio10], Table A-11
FU_CONTROL_UNDEFINED = 0x00
MUTE_CONTROL = 0x01
VOLUME_CONTROL = 0x02
BASS_CONTROL = 0x03
MID_CONTROL = 0x04
TREBLE_CONTROL = 0x05
GRAPHIC_EQUALIZER_CONTROL = 0x06
AUTOMATIC_GAIN_CONTROL = 0x07
DELAY_CONTROL = 0x08
BASS_BOOST_CONTROL = 0x09
LOUDNESS_CONTROL = 0x0A


class UpDownMixProcessingUnitControlSelectors(IntEnum):
# As defined in [Audio10], Table A-12
UD_CONTROL_UNDEFINED = 0x00
UD_ENABLE_CONTROL = 0x01
UD_MODE_SELECT_CONTROL = 0x02


class DolbyProLogicProcessingUnitControlSelectors(IntEnum):
# As defined in [Audio10], Table A-13
DP_CONTROL_UNDEFINED = 0x00
DP_ENABLE_CONTROL = 0x01
DP_MODE_SELECT_CONTROL = 0x02


class _3DStereoExtenderProcessingUnitControlSelectors(IntEnum):
# As defined in [Audio10], Table A-14
_3D_CONTROL_UNDEFINED = 0x00
_3D_ENABLE_CONTROL = 0x01
SPACIOUSNESS_CONTROL = 0x02


class ReverberationProcessingUnitControlSelectors(IntEnum):
# As defined in [Audio10], Table A-15
RV_CONTROL_UNDEFINED = 0x00
RV_ENABLE_CONTROL = 0x01
REVERB_LEVEL_CONTROL = 0x02
REVERB_TIME_CONTROL = 0x03
REVERB_FEEDBACK_CONTROL = 0x04


class ChorusProcessingUnitControlSelectors(IntEnum):
# As defined in [Audio10], Table A-16
CH_CONTROL_UNDEFINED = 0x00
CH_ENABLE_CONTROL = 0x01
CHORUS_LEVEL_CONTROL = 0x02
CHORUS_RATE_CONTROL = 0x03
CHORUS_DEPTH_CONTROL = 0x04


class DynamicRangeCompressorProcessingUnitControlSelectors(IntEnum):
# As defined in [Audio10], Table A-17
DR_CONTROL_UNDEFINED = 0x00
DR_ENABLE_CONTROL = 0x01
COMPRESSION_RATE_CONTROL = 0x02
MAXAMPL_CONTROL = 0x03
THRESHOLD_CONTROL = 0x04
ATTACK_TIME = 0x05
RELEASE_TIME = 0x06


class ExtensionUnitControlSelectors(IntEnum):
# As defined in [Audio10], Table A-18
XU_CONTROL_UNDEFINED = 0x00
XU_ENABLE_CONTROL = 0x01


class EndpointsControlSelectors(IntEnum):
# As defined in [Audio10], Table A-19
EP_CONTROL_UNDEFINED = 0x00
SAMPLING_FREQ_CONTROL = 0x01
PITCH_CONTROL = 0x02


class USBTerminalTypes(IntEnum):
# As defined in [TermT10], Table 2-1
USB_UNDEFINED = 0x0100
USB_STREAMING = 0x0101
USB_VENDOR_SPECIFIC = 0x01FF


class InputTerminalTypes(IntEnum):
# As defined in [TermT10], Table 2-2
INPUT_UNDEFINED = 0x0200
MICROPHONE = 0x0201
DESKTOP_MICROPHONE = 0x0202
PERSONAL_MICROPHONE = 0x0203
OMNI_DIRECTIONAL_MICROPHONE = 0x0204
MICROPHONE_ARRAY = 0x0205
PROCESSING_MICROPHONE_ARRAY = 0x0206


class OutputTerminalTypes(IntEnum):
# As defined in [TermT10], Table 2-3
OUTPUT_UNDEFINED = 0x0300
SPEAKER = 0x0301
HEADPHONES = 0x0302
DESKTOP_SPEAKER = 0x0304
ROOM_SPEAKER = 0x0305
COMMUNICATION_SPEAKER = 0x0306
LOW_FREQUENCY_EFFECTS_SPEAKER = 0x0307


class BidirectionalTerminalTypes(IntEnum):
# As defined in [TermT10], Table 2-4
BIDIRECTIONAL_UNDEFINED = 0x0400
HANDSET = 0x0401
HEADSET = 0x0402
ECHO_SUPPRESSING_SPEAKERPHONE = 0x0404
ECHO_CANCELING_SPEAKERPHONE = 0x0405


class TelephonyTerminalTypes(IntEnum):
# As defined in [TermT10], Table 2-5
TELEPHONY_UNDEFINED = 0x0500
PHONE_LINE = 0x0501
TELEPHONE = 0x0502
DOWN_LINE_PHONE = 0x0503


class ExternalTerminalTypes(IntEnum):
# As defined in [TermT10], Table 2-6
EXTERNAL_UNDEFINED = 0x0600
ANALOG_CONNECTOR = 0x0601
DIGITAL_AUDIO_INTERFACE = 0x0602
LINE_CONNECTOR = 0x0603
SPDIF_INTERFACE = 0x0605
IEEE_1394_DA_STREAM = 0x0606
IEEE_1394_DV_STREAM_SOUNDTRACK = 0x0607


class EmbeddedFunctionTerminalTypes(IntEnum):
# As defined in [TermT10], Table 2-7
EMBEDDED_UNDEFINED = 0x0700
EQUALIZATION_NOISE = 0x0702
CD_PLAYER = 0x0703
DAT = 0x0704
DCC = 0x0705
ANALOG_TAPE = 0x0707
PHONOGRAPH = 0x0708
VCR_AUDIO = 0x0709
VIDEO_DISC_AUDIO = 0x070A
DVD_AUDIO = 0x070B
TV_TUNER_AUDIO = 0x070C
SATELLITE_RECEIVER_AUDIO = 0x070D
CABLE_TUNER_AUDIO = 0x070E
DSS_AUDIO = 0x070F
RADIO_RECEIVER = 0x0710
RADIO_TRANSMITTER = 0x0711
MULTI_TRACK_RECORDER = 0x0712
SYNTHESIZER = 0x0713


# As defined in [Audio10], Table 4-17
AudioControlInterruptEndpointDescriptor = DescriptorFormat(
"bLength" / construct.Const(9, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_ENDPOINT),
"bEndpointAddress" / DescriptorField(description="The address of the endpoint, use USBDirection.*.from_endpoint_address()"),
"bmAttributes" / DescriptorField(description="D1..0: Transfer type (0b11 = Interrupt)", default=0b11),
"wMaxPacketSize" / DescriptorField(description="Maximum packet size this endpoint is capable of. Used here to pass 6-byte interrupt information.", default=6),
"bInterval" / DescriptorField(description="Interval for polling the Interrupt endpoint")
"bRefresh" / DescriptorField(description="Reset to 0")
"bSynchAddress" / DescriptorField(description="Reset to 0")
)


+ 481
- 37
usb_protocol/types/descriptors/uac2.py View File

@@ -1,7 +1,13 @@
#
# This file is part of usb-protocol.
#
""" descriptors specific to USB version 2
"""
Descriptors for USB Audio Class Devices (UAC), Release 2

[Audio20] refers to "Universal Serial Bus Device Class Definition for Audio Devices", Release 2.0, May 31, 2006
[Frmts20] refers to "Universal Serial Bus Device Class Definition for Audio Data Formats", Release 2.0, May 31, 2006
[TermT20] refers to "Universal Serial Bus Device Class Definition for Terminal Types", Release 2.0, May 31, 2006

NOTE: This is not complete yet and will be extended as needed
"""

@@ -11,10 +17,412 @@ from enum import IntEnum

import construct

from .standard import StandardDescriptorNumbers
from ..descriptor import \
DescriptorField, DescriptorNumber, DescriptorFormat

from .uac import *

class AudioInterfaceClassCode(IntEnum):
# As defined in [Audio20], Table A-4
AUDIO = 0x01


class AudioFunctionClassCode(IntEnum):
# As defined in [Audio20], Table A-1
AUDIO_FUNCTION = AudioInterfaceClassCode.AUDIO


class AudioFunctionSubclassCodes(IntEnum):
# As defined in [Audio20], Table A-2
FUNCTION_SUBCLASS_UNDEFINED = 0x00


class AudioInterfaceProtocolCodes(IntEnum):
# As defined in [Audio20], Table A-6
INTERFACE_PROTOCOL_UNDEFINED = 0x00
IP_VERSION_02_00 = 0x20


class AudioFunctionProtocolCodes(IntEnum):
# As defined in [Audio20], Table A-3
FUNCTION_PROTOCOL_UNDEFINED = 0x00
AF_VERSION_02_00 = AudioInterfaceProtocolCodes.IP_VERSION_02_00


class AudioInterfaceSubclassCodes(IntEnum):
# As defined in [Audio20], Table A-5
INTERFACE_SUBCLASS_UNDEFINED = 0x00
AUDIO_CONTROL = 0x01
AUDIO_STREAMING = 0x02
MIDI_STREAMING = 0x03


class AudioFunctionCategoryCodes(IntEnum):
# As defined in [Audio20], Table A-7
FUNCTION_SUBCLASS_UNDEFINED = 0x00
DESKTOP_SPEAKER = 0x01
HOME_THEATER = 0x02
MICROPHONE = 0x03
HEADSET = 0x04
TELEPHONE = 0x05
CONVERTER = 0x06
VOICE_SOUND_RECORDER = 0x07
IO_BOX = 0x08
MUSICAL_INSTRUMENT = 0x09
PRO_AUDIO = 0x0A
AUDIO_VIDEO = 0x0B
CONTROL_PANEL = 0x0C
OTHER = 0xFF


class AudioClassSpecificStandardDescriptorNumbers(IntEnum):
# As defined in [Audio20], Table A-8
CS_UNDEFINED = 0x20
CS_DEVICE = 0x21
CS_CONFIGURATION = 0x22
CS_STRING = 0x23
CS_INTERFACE = 0x24
CS_ENDPOINT = 0x25


class AudioClassSpecificACInterfaceDescriptorSubtypes(IntEnum):
# As defined in [Audio20], Table A-9
AC_DESCRIPTOR_UNDEFINED = 0x00
HEADER = 0x01
INPUT_TERMINAL = 0x02
OUTPUT_TERMINAL = 0x03
MIXER_UNIT = 0x04
SELECTOR_UNIT = 0x05
FEATURE_UNIT = 0x06
EFFECT_UNIT = 0x07
PROCESSING_UNIT = 0x08
EXTENSION_UNIT = 0x09
CLOCK_SOURCE = 0x0A
CLOCK_SELECTOR = 0x0B
CLOCK_MULTIPLIER = 0x0C
SAMPLE_RATE_CONVERTER = 0x0D


class AudioClassSpecificASInterfaceDescriptorSubtypes(IntEnum):
# As defined in [Audio20], Table A-10
AS_DESCRIPTOR_UNDEFINED = 0x00
AS_GENERAL = 0x01
FORMAT_TYPE = 0x02
ENCODER = 0x03
DECODER = 0x04


class EffectUnitEffectTypes(IntEnum):
# As defined in [Audio20], Table A-11
EFFECT_UNDEFINED = 0x00
PARAM_EQ_SECTION_EFFECT = 0x01
REVERBERATION_EFFECT = 0x02
MOD_DELAY_EFFECT = 0x03
DYN_RANGE_COMP_EFFECT = 0x04


class ProcessingUnitProcessTypes(IntEnum):
# As defined in [Audio20], Table A-12
PROCESS_UNDEFINED = 0x00
UP_DOWNMIX_PROCESS = 0x01
DOLBY_PROLOGIC_PROCESS = 0x02
STEREO_EXTENDER_PROCESS = 0x03


class AudioClassSpecificEndpointDescriptorSubtypes(IntEnum):
# As defined in [Audio20], Table A-13
DESCRIPTOR_UNDEFINED = 0x00
EP_GENERAL = 0x01


class AudioClassSpecificRequestCodes(IntEnum):
# As defined in [Audio20], Table A-14
REQUEST_CODE_UNDEFINED = 0x00
CUR = 0x01
RANGE = 0x02
MEM = 0x03


class ClockSourceControlSelectors(IntEnum):
# As defined in [Audio20], Table A-17
CS_CONTROL_UNDEFINED = 0x00
CS_SAM_FREQ_CONTROL = 0x01
CS_CLOCK_VALID_CONTROL = 0x02


class ClockSelectorControlSelectors(IntEnum):
# As defined in [Audio20], Table A-18
CX_CONTROL_UNDEFINED = 0x00
CX_CLOCK_SELECTOR_CONTROL = 0x01


class ClockMultiplierControlSelectors(IntEnum):
# As defined in [Audio20], Table A-19
CM_CONTROL_UNDEFINED = 0x00
CM_NUMERATOR_CONTROL = 0x01
CM_DENOMINATOR_CONTROL = 0x02


class TerminalControlSelectors(IntEnum):
# As defined in [Audio20], Table A-20
TE_CONTROL_UNDEFINED = 0x00
TE_COPY_PROTECT_CONTROL = 0x01
TE_CONNECTOR_CONTROL = 0x02
TE_OVERLOAD_CONTROL = 0x03
TE_CLUSTER_CONTROL = 0x04
TE_UNDERFLOW_CONTROL = 0x05
TE_OVERFLOW_CONTROL = 0x06
TE_LATENCY_CONTROL = 0x07


class MixerControlSelectors(IntEnum):
# As defined in [Audio20], Table A-21
MU_CONTROL_UNDEFINED = 0x00
MU_MIXER_CONTROL = 0x01
MU_CLUSTER_CONTROL = 0x02
MU_UNDERFLOW_CONTROL = 0x03
MU_OVERFLOW_CONTROL = 0x04
MU_LATENCY_CONTROL = 0x05


class SelectorControlSelectors(IntEnum):
# As defined in [Audio20], Table A-22
SU_CONTROL_UNDEFINED = 0x00
SU_SELECTOR_CONTROL = 0x01
SU_LATENCY_CONTROL = 0x02


class FeatureUnitControlSelectors(IntEnum):
# As defined in [Audio20], Table A-23
FU_CONTROL_UNDEFINED = 0x00
FU_MUTE_CONTROL = 0x01
FU_VOLUME_CONTROL = 0x02
FU_BASS_CONTROL = 0x03
FU_MID_CONTROL = 0x04
FU_TREBLE_CONTROL = 0x05
FU_GRAPHIC_EQUALIZER_CONTROL = 0x06
FU_AUTOMATIC_GAIN_CONTROL = 0x07
FU_DELAY_CONTROL = 0x08
FU_BASS_BOOST_CONTROL = 0x09
FU_LOUDNESS_CONTROL = 0x0A
FU_INPUT_GAIN_CONTROL = 0x0B
FU_INPUT_GAIN_PAD_CONTROL = 0x0C
FU_PHASE_INVERTER_CONTROL = 0x0D
FU_UNDERFLOW_CONTROL = 0x0E
FU_OVERFLOW_CONTROL = 0x0F
FU_LATENCY_CONTROL = 0x10


class ParametricEqualizerSectionEffectUnitControlSelectors(IntEnum):
# As defined in [Audio20], Table A-24
PE_CONTROL_UNDEFINED = 0x00
PE_ENABLE_CONTROL = 0x01
PE_CENTERFREQ_CONTROL = 0x02
PE_QFACTOR_CONTROL = 0x03
PE_GAIN_CONTROL = 0x04
PE_UNDERFLOW_CONTROL = 0x05
PE_OVERFLOW_CONTROL = 0x06
PE_LATENCY_CONTROL = 0x07


class ReverberationEffectUnitControlSelectors(IntEnum):
# As defined in [Audio20], Table A-25
RV_CONTROL_UNDEFINED = 0x00
RV_ENABLE_CONTROL = 0x01
RV_TYPE_CONTROL = 0x02
RV_LEVEL_CONTROL = 0x03
RV_TIME_CONTROL = 0x04
RV_FEEDBACK_CONTROL = 0x05
RV_PREDELAY_CONTROL = 0x06
RV_DENSITY_CONTROL = 0x07
RV_HIFREQ_ROLLOFF_CONTROL = 0x08
RV_UNDERFLOW_CONTROL = 0x09
RV_OVERFLOW_CONTROL = 0x0A
RV_LATENCY_CONTROL = 0x0B


class ModulationDelayEffectUnitControlSelectors(IntEnum):
# As defined in [Audio20], Table A-26
MD_CONTROL_UNDEFINED = 0x00
MD_ENABLE_CONTROL = 0x01
MD_BALANCE_CONTROL = 0x02
MD_RATE_CONTROL = 0x03
MD_DEPTH_CONTROL = 0x04
MD_TIME_CONTROL = 0x05
MD_FEEDBACK_CONTROL = 0x06
MD_UNDERFLOW_CONTROL = 0x07
MD_OVERFLOW_CONTROL = 0x08
MD_LATENCY_CONTROL = 0x09


class DynamicRangeCompressorEffectUnitControlSelectors(IntEnum):
# As defined in [Audio20], Table A-27
DR_CONTROL_UNDEFINED = 0x00
DR_ENABLE_CONTROL = 0x01
DR_COMPRESSION_RATE_CONTROL = 0x02
DR_MAXAMPL_CONTROL = 0x03
DR_THRESHOLD_CONTROL = 0x04
DR_ATTACK_TIME_CONTROL = 0x05
DR_RELEASE_TIME_CONTROL = 0x06
DR_UNDERFLOW_CONTROL = 0x07
DR_OVERFLOW_CONTROL = 0x08
DR_LATENCY_CONTROL = 0x09


class UpDownMixProcessingUnitControlSelectors(IntEnum):
# As defined in [Audio20], Table A-28
UD_CONTROL_UNDEFINED = 0x00
UD_ENABLE_CONTROL = 0x01
UD_MODE_SELECT_CONTROL = 0x02
UD_CLUSTER_CONTROL = 0x03
UD_UNDERFLOW_CONTROL = 0x04
UD_OVERFLOW_CONTROL = 0x05
UD_LATENCY_CONTROL = 0x06


class DolbyProLogicProcessingUnitControlSelectors(IntEnum):
# As defined in [Audio20], Table A-29
DP_CONTROL_UNDEFINED = 0x00
DP_ENABLE_CONTROL = 0x01
DP_MODE_SELECT_CONTROL = 0x02
DP_CLUSTER_CONTROL = 0x03
DP_UNDERFLOW_CONTROL = 0x04
DP_OVERFLOW_CONTROL = 0x05
DP_LATENCY_CONTROL = 0x06


class StereoExtenderProcessingUnitControlSelectors(IntEnum):
# As defined in [Audio20], Table A-30
ST_EXT_CONTROL_UNDEFINED = 0x00
ST_EXT_ENABLE_CONTROL = 0x01
ST_EXT_UNDERFLOW_CONTROL = 0x03
ST_EXT_OVERFLOW_CONTROL = 0x04
ST_EXT_LATENCY_CONTROL = 0x05


class ExtensionUnitControlSelectors(IntEnum):
# As defined in [Audio20], Table A-31
XU_CONTROL_UNDEFINED = 0x00
XU_ENABLE_CONTROL = 0x01
XU_CLUSTER_CONTROL = 0x02
XU_UNDERFLOW_CONTROL = 0x03
XU_OVERFLOW_CONTROL = 0x04
XU_LATENCY_CONTROL = 0x05


class AudioStreamingInterfaceControlSelectors(IntEnum):
# As defined in [Audio20], Table A-32
AS_CONTROL_UNDEFINED = 0x00
AS_ACT_ALT_SETTING_CONTROL = 0x01
AS_VAL_ALT_SETTINGS_CONTROL = 0x02
AS_AUDIO_DATA_FORMAT_CONTROL = 0x03


class EndpointControlSelectors(IntEnum):
# As defined in [Audio20], Table A-33
EP_CONTROL_UNDEFINED = 0x00
EN_BIT_RATE_CONTROL = 0x01
EN_QUALITY_CONTROL = 0x02
EN_VBR_CONTROL = 0x03
EN_TYPE_CONTROL = 0x04
EN_UNDERFLOW_CONTROL = 0x05
EN_OVERFLOW_CONTROL = 0x06
EN_ENCODER_ERROR_CONTROL = 0x07
EN_PARAM1_CONTROL = 0x08
EN_PARAM2_CONTROL = 0x09
EN_PARAM3_CONTROL = 0x0A
EN_PARAM4_CONTROL = 0x0B
EN_PARAM5_CONTROL = 0x0C
EN_PARAM6_CONTROL = 0x0D
EN_PARAM7_CONTROL = 0x0E
EN_PARAM8_CONTROL = 0x0F


class USBTerminalTypes(IntEnum):
# As defined in [TermT20], Table 2-1
USB_UNDEFINED = 0x0100
USB_STREAMING = 0x0101
USB_VENDOR_SPECIFIC = 0x01FF


class InputTerminalTypes(IntEnum):
# As defined in [TermT20], Table 2-2
INPUT_UNDEFINED = 0x0200
MICROPHONE = 0x0201
DESKTOP_MICROPHONE = 0x0202
PERSONAL_MICROPHONE = 0x0203
OMNI_DIRECTIONAL_MICROPHONE = 0x0204
MICROPHONE_ARRAY = 0x0205
PROCESSING_MICROPHONE_ARRAY = 0x0206


class OutputTerminalTypes(IntEnum):
# As defined in [TermT20], Table 2-3
OUTPUT_UNDEFINED = 0x0300
SPEAKER = 0x0301
HEADPHONES = 0x0302
DESKTOP_SPEAKER = 0x0304
ROOM_SPEAKER = 0x0305
COMMUNICATION_SPEAKER = 0x0306
LOW_FREQUENCY_EFFECTS_SPEAKER = 0x0307


class BidirectionalTerminalTypes(IntEnum):
# As defined in [TermT20], Table 2-4
BIDIRECTIONAL_UNDEFINED = 0x0400
HANDSET = 0x0401
HEADSET = 0x0402
ECHO_SUPPRESSING_SPEAKERPHONE = 0x0404
ECHO_CANCELING_SPEAKERPHONE = 0x0405


class TelephonyTerminalTypes(IntEnum):
# As defined in [TermT20], Table 2-5
TELEPHONY_UNDEFINED = 0x0500
PHONE_LINE = 0x0501
TELEPHONE = 0x0502
DOWN_LINE_PHONE = 0x0503


class ExternalTerminalTypes(IntEnum):
# As defined in [TermT20], Table 2-6
EXTERNAL_UNDEFINED = 0x0600
ANALOG_CONNECTOR = 0x0601
DIGITAL_AUDIO_INTERFACE = 0x0602
LINE_CONNECTOR = 0x0603
SPDIF_INTERFACE = 0x0605
IEEE_1394_DA_STREAM = 0x0606
IEEE_1394_DV_STREAM_SOUNDTRACK = 0x0607
ADAT_LIGHTPIPE = 0x0608
TDIF = 0x0609
MADI = 0x060A


class EmbeddedFunctionTerminalTypes(IntEnum):
# As defined in [TermT20], Table 2-7
EMBEDDED_UNDEFINED = 0x0700
EQUALIZATION_NOISE = 0x0702
CD_PLAYER = 0x0703
DAT = 0x0704
DCC = 0x0705
ANALOG_TAPE = 0x0707
PHONOGRAPH = 0x0708
VCR_AUDIO = 0x0709
VIDEO_DISC_AUDIO = 0x070A
DVD_AUDIO = 0x070B
TV_TUNER_AUDIO = 0x070C
SATELLITE_RECEIVER_AUDIO = 0x070D
CABLE_TUNER_AUDIO = 0x070E
DSS_AUDIO = 0x070F
RADIO_RECEIVER = 0x0710
RADIO_TRANSMITTER = 0x0711
MULTI_TRACK_RECORDER = 0x0712
SYNTHESIZER = 0x0713
PIANO = 0x0714
GUITAR = 0x0715
DRUMS_RHYTHM = 0x0716
OTHER_MUSICAL_INSTRUMENT = 0x0717


class ClockAttributes(IntEnum):
EXTERNAL_CLOCK = 0b00
@@ -22,36 +430,43 @@ class ClockAttributes(IntEnum):
INTERNAL_VARIABLE_CLOCK = 0b10
INTERNAL_PROGRAMMABLE_CLOCK = 0b11


class ClockFrequencyControl(IntEnum):
NOT_PRESENT = 0b00
HOST_READ_ONLY = 0b01
HOST_PROGRAMMABLE = 0b11


class CopyProtectControl(IntEnum):
NOT_PRESENT = 0b00
HOST_READ_ONLY = 0b10
HOST_PROGRAMMABLE = 0b11


class ConnectorControl(IntEnum):
NOT_PRESENT = (0b00) << 2
HOST_READ_ONLY = (0b10) << 2
HOST_PROGRAMMABLE = (0b11) << 2


class OverloadControl(IntEnum):
NOT_PRESENT = (0b00) << 4
HOST_READ_ONLY = (0b10) << 4
HOST_PROGRAMMABLE = (0b11) << 4


class ClusterControl(IntEnum):
NOT_PRESENT = (0b00) << 6
HOST_READ_ONLY = (0b10) << 6
HOST_PROGRAMMABLE = (0b11) << 6


class UnderflowControl(IntEnum):
NOT_PRESENT = (0b00) << 8
HOST_READ_ONLY = (0b10) << 8
HOST_PROGRAMMABLE = (0b11) << 8


class OverflowControl(IntEnum):
NOT_PRESENT = (0b00) << 10
HOST_READ_ONLY = (0b10) << 10
@@ -68,6 +483,7 @@ class FormatTypes(IntEnum):
EXT_FORMAT_TYPE_II = 0x82
EXT_FORMAT_TYPE_III = 0x83


class TypeIFormats(IntEnum):
PCM = (1 << 0)
PCM8 = (1 << 1)
@@ -76,6 +492,7 @@ class TypeIFormats(IntEnum):
MULAW = (1 << 4)
TYPE_I_RAW_DATA = (1 << 31)


class TypeIIFormats(IntEnum):
MPEG = (1 << 0)
AC_3 = (1 << 1)
@@ -83,6 +500,7 @@ class TypeIIFormats(IntEnum):
DTS = (1 << 3)
TYPE_II_RAW_DATA = (1 << 31)


class TypeIIIFormats(IntEnum):
IEC61937_AC_3 = (1 << 0)
IEC61937_MPEG_1_Layer1 = (1 << 1)
@@ -99,6 +517,7 @@ class TypeIIIFormats(IntEnum):
IEC61937_ATRAC2_3 = (1 << 11)
TYPE_III_WMA = (1 << 12)


class TypeIVFormats(IntEnum):
PCM = (1 << 0)
PCM8 = (1 << 1)
@@ -124,20 +543,45 @@ class TypeIVFormats(IntEnum):
TYPE_III_WMA = (1 << 20)
IEC60958_PCM = (1 << 21)


class SidebandProtocols(IntEnum):
PROTOCOL_UNDEFINED = 0x00
PRES_TIMESTAMP_PROTOCOL = 0x02

class AudioClassSpecificASInterfaceDescriptorSubtypes(IntEnum):
AS_DESCRIPTOR_UNDEFINED = 0x00
AS_GENERAL = 0x01
FORMAT_TYPE = 0x02
ENCODER = 0x03
DECODER = 0x04

# As defined in [Audio20], Table 4-25
AudioControlInterruptEndpointDescriptor = DescriptorFormat(
"bLength" / construct.Const(7, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_ENDPOINT),
"bEndpointAddress" / DescriptorField(description="The address of the endpoint, use USBDirection.*.from_endpoint_address()"),
"bmAttributes" / DescriptorField(description="D1..0: Transfer type (0b11 = Interrupt)", default=0b11),
"wMaxPacketSize" / DescriptorField(description="Maximum packet size this endpoint is capable of. Used here to pass 6-byte interrupt information.", default=6),
"bInterval" / DescriptorField(description="Interval for polling the Interrupt endpoint")
)

# As defined in [Audio30], Table 4-33
AudioStreamingIsochronousEndpointDescriptor = DescriptorFormat(
"bLength" / construct.Const(7, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(StandardDescriptorNumbers.ENDPOINT),
"bEndpointAddress" / DescriptorField(description="The address of the endpoint, use USBDirection.*.from_endpoint_address()"),
"bmAttributes" / DescriptorField(description="D1..0: transfer type (01=isochronous); D3..2: synchronization type (01=asynchronous/10=adaptive/11=synchronous); D5..4: usage (00=data/10=feedback)", default=0b000101),
"wMaxPacketSize" / DescriptorField(description="Maximum packet size this endpoint is capable of. Used here to pass 6-byte interrupt information.", default=6),
"bInterval" / DescriptorField(description="Interval for polling the Interrupt endpoint")
)

# As defined in [Audio30], Table 4-35
AudioStreamingIsochronousFeedbackEndpointDescriptor = DescriptorFormat(
"bLength" / construct.Const(7, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(StandardDescriptorNumbers.ENDPOINT),
"bEndpointAddress" / DescriptorField(description="The address of the endpoint, use USBDirection.*.from_endpoint_address()"),
"bmAttributes" / DescriptorField(description="D1..0: transfer type (01=isochronous); D3..2: synchronization type (00=no sync); D5..4: usage (10=feedback)", default=0b00100001),
"wMaxPacketSize" / DescriptorField(description="Maximum packet size this endpoint is capable of. Used here to pass 6-byte interrupt information.", default=6),
"bInterval" / DescriptorField(description="Interval for polling the Interrupt endpoint")
)

InterfaceAssociationDescriptor = DescriptorFormat(
"bLength" / construct.Const(8, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(DescriptorTypes.INTERFACE_ASSOCIATION),
"bDescriptorType" / DescriptorNumber(StandardDescriptorNumbers.INTERFACE_ASSOCIATION),
"bFirstInterface" / DescriptorField(description="Interface number of the first interface that is associated with this function.", default=0),
"bInterfaceCount" / DescriptorField(description="Number of contiguous interfaces that are associated with this function"),
"bFunctionClass" / DescriptorNumber(AudioFunctionClassCode.AUDIO_FUNCTION),
@@ -148,7 +592,7 @@ InterfaceAssociationDescriptor = DescriptorFormat(

StandardAudioControlInterfaceDescriptor = DescriptorFormat(
"bLength" / construct.Const(9, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(DescriptorTypes.INTERFACE),
"bDescriptorType" / DescriptorNumber(StandardDescriptorNumbers.INTERFACE),
"bInterfaceNumber" / DescriptorField(description="ID of the control interface"),
"bAlternateSetting" / DescriptorField(description="alternate setting for the interface (must be 0)", default=0),
"bNumEndpoints" / DescriptorField(description="number of endpoints used by this interface (excluding endpoint 0). This number is either 0 or 1 if the optional interrupt endpoint is present", default=0),
@@ -160,7 +604,7 @@ StandardAudioControlInterfaceDescriptor = DescriptorFormat(

ClassSpecificAudioControlInterfaceDescriptor = DescriptorFormat(
"bLength" / construct.Const(9, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificACInterfaceDescriptorSubtypes.HEADER),
"bcdADC" / DescriptorField(description="Audio Device Class specification release version", default=2.0),
"bCategory" / DescriptorField(description="primary use of this audio function (see AudioFunctionCategoryCodes)", default=AudioFunctionCategoryCodes.IO_BOX),
@@ -170,7 +614,7 @@ ClassSpecificAudioControlInterfaceDescriptor = DescriptorFormat(

ClockSourceDescriptor = DescriptorFormat(
"bLength" / construct.Const(8, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificACInterfaceDescriptorSubtypes.CLOCK_SOURCE),
"bClockID" / DescriptorField(description="ID of the clock source entity within the audio function (used in requests)"),
"bmAttributes" / DescriptorField(description="D1..0: clock type (see ClockAttributs)"),
@@ -181,7 +625,7 @@ ClockSourceDescriptor = DescriptorFormat(

InputTerminalDescriptor = DescriptorFormat(
"bLength" / construct.Const(17, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificACInterfaceDescriptorSubtypes.INPUT_TERMINAL),
"bTerminalID" / DescriptorField(description="unique identifier for the terminal within the audio function (used in requests)"),
"wTerminalType" / DescriptorField(description="a value of one of the terminal types Enums (eg InputTerminaTypes, ExternalTerminalTypes)"),
@@ -196,7 +640,7 @@ InputTerminalDescriptor = DescriptorFormat(

OutputTerminalDescriptor = DescriptorFormat(
"bLength" / construct.Const(12, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificACInterfaceDescriptorSubtypes.OUTPUT_TERMINAL),
"bTerminalID" / DescriptorField(description="unique identifier for the terminal within the audio function."),
"wTerminalType" / DescriptorField(description="a value of one of the terminal types Enums (eg OutputTerminaTypes, ExternalTerminalTypes)"),
@@ -209,7 +653,7 @@ OutputTerminalDescriptor = DescriptorFormat(

AudioStreamingInterfaceDescriptor = DescriptorFormat(
"bLength" / construct.Const(9, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(DescriptorTypes.INTERFACE),
"bDescriptorType" / DescriptorNumber(StandardDescriptorNumbers.INTERFACE),
"bInterfaceNumber" / DescriptorField(description="ID of the streaming interface"),
"bAlternateSetting" / DescriptorField(description="alternate setting number for the interface", default=0),
"bNumEndpoints" / DescriptorField(description="Number of data endpoints used (excluding endpoint 0). Can be: 0 (no data endpoint); 1 (data endpoint); 2 (data + explicit feedback endpoint)", default=0),
@@ -221,7 +665,7 @@ AudioStreamingInterfaceDescriptor = DescriptorFormat(

ClassSpecificAudioStreamingInterfaceDescriptor = DescriptorFormat(
"bLength" / construct.Const(16, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificASInterfaceDescriptorSubtypes.AS_GENERAL),
"bTerminalLink" / DescriptorField(description="the ID of the terminal to which this interface is connected"),
"bmControls" / DescriptorField(description="D1..0: active alternate setting control; D3..2: valid alternate settings control; D7..4: reserved, must be 0", default=0),
@@ -234,7 +678,7 @@ ClassSpecificAudioStreamingInterfaceDescriptor = DescriptorFormat(

TypeIFormatTypeDescriptor = DescriptorFormat(
"bLength" / construct.Const(6, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificASInterfaceDescriptorSubtypes.FORMAT_TYPE),
"bFormatType" / DescriptorNumber(FormatTypes.FORMAT_TYPE_I),
"bSubslotSize" / DescriptorField(description="number of bytes occupied by one audio subslot (1, 2, 3 or 4)"),
@@ -243,7 +687,7 @@ TypeIFormatTypeDescriptor = DescriptorFormat(

ExtendedTypeIFormatTypeDescriptor = DescriptorFormat(
"bLength" / construct.Const(9, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificASInterfaceDescriptorSubtypes.FORMAT_TYPE),
"bFormatType" / DescriptorNumber(FormatTypes.EXT_FORMAT_TYPE_I),
"bSubslotSize" / DescriptorField(description="number of bytes occupied by one audio subslot (1, 2, 3 or 4)"),
@@ -255,7 +699,7 @@ ExtendedTypeIFormatTypeDescriptor = DescriptorFormat(

TypeIIFormatTypeDescriptor = DescriptorFormat(
"bLength" / construct.Const(8, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificASInterfaceDescriptorSubtypes.FORMAT_TYPE),
"bFormatType" / DescriptorNumber(FormatTypes.FORMAT_TYPE_II),
"wMaxBitRate" / DescriptorField(description="maximum bitrate of this interface in kbits/s"),
@@ -264,7 +708,7 @@ TypeIIFormatTypeDescriptor = DescriptorFormat(

ExtendedTypeIIFormatTypeDescriptor = DescriptorFormat(
"bLength" / construct.Const(10, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificASInterfaceDescriptorSubtypes.FORMAT_TYPE),
"bFormatType" / DescriptorNumber(FormatTypes.EXT_FORMAT_TYPE_II),
"wMaxBitRate" / DescriptorField(description="maximum bitrate of this interface in kbits/s"),
@@ -275,7 +719,7 @@ ExtendedTypeIIFormatTypeDescriptor = DescriptorFormat(

TypeIIIFormatTypeDescriptor = DescriptorFormat(
"bLength" / construct.Const(6, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificASInterfaceDescriptorSubtypes.FORMAT_TYPE),
"bFormatType" / DescriptorNumber(FormatTypes.FORMAT_TYPE_III),
"bSubslotSize" / DescriptorField(description="number of bytes occupied by one audio subslot (must be 2)", default=2),
@@ -284,7 +728,7 @@ TypeIIIFormatTypeDescriptor = DescriptorFormat(

ExtendedTypeIIIFormatTypeDescriptor = DescriptorFormat(
"bLength" / construct.Const(8, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificASInterfaceDescriptorSubtypes.FORMAT_TYPE),
"bFormatType" / DescriptorNumber(FormatTypes.EXT_FORMAT_TYPE_III),
"bSubslotSize" / DescriptorField(description="number of bytes occupied by one audio subslot (must be 2)", default=2),
@@ -295,7 +739,7 @@ ExtendedTypeIIIFormatTypeDescriptor = DescriptorFormat(

ClassSpecificAudioStreamingIsochronousAudioDataEndpointDescriptor = DescriptorFormat(
"bLength" / construct.Const(8, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_ENDPOINT),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_ENDPOINT),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificEndpointDescriptorSubtypes.EP_GENERAL),
"bmAttributes" / DescriptorField(description="bit D7 = 1: only packets with size wMaxPacketSize allowed", default=0),
"bmControls" / DescriptorField(description="D1..0: pitch control D3..2: data overrun control; D5..4: data underrun control;", default=0),
@@ -360,7 +804,7 @@ class UAC2Cases(unittest.TestCase):

# ... and check the descriptor's fields.
self.assertEqual(parsed.bLength, 8)
self.assertEqual(parsed.bDescriptorType, DescriptorTypes.INTERFACE_ASSOCIATION)
self.assertEqual(parsed.bDescriptorType, StandardDescriptorNumbers.INTERFACE_ASSOCIATION)
self.assertEqual(parsed.bFirstInterface, 1)
self.assertEqual(parsed.bInterfaceCount, 2)
self.assertEqual(parsed.bFunctionClass, AudioFunctionClassCode.AUDIO_FUNCTION)
@@ -404,7 +848,7 @@ class UAC2Cases(unittest.TestCase):

# ... and check the descriptor's fields.
self.assertEqual(parsed.bLength, 9)
self.assertEqual(parsed.bDescriptorType, DescriptorTypes.INTERFACE)
self.assertEqual(parsed.bDescriptorType, StandardDescriptorNumbers.INTERFACE)
self.assertEqual(parsed.bInterfaceNumber, 1)
self.assertEqual(parsed.bAlternateSetting, 2)
self.assertEqual(parsed.bNumEndpoints, 0)
@@ -450,7 +894,7 @@ class UAC2Cases(unittest.TestCase):

# ... and check the descriptor's fields.
self.assertEqual(parsed.bLength, 8)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificDescriptorTypes.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorSubtype, AudioClassSpecificACInterfaceDescriptorSubtypes.CLOCK_SOURCE)
self.assertEqual(parsed.bClockID, 0x01)
self.assertEqual(parsed.bmAttributes, ClockAttributes.INTERNAL_FIXED_CLOCK)
@@ -499,7 +943,7 @@ class UAC2Cases(unittest.TestCase):

# ... and check the descriptor's fields.
self.assertEqual(parsed.bLength, 17)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificDescriptorTypes.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorSubtype, AudioClassSpecificACInterfaceDescriptorSubtypes.INPUT_TERMINAL)
self.assertEqual(parsed.bTerminalID, 0x01)
self.assertEqual(parsed.wTerminalType, USBTerminalTypes.USB_STREAMING)
@@ -554,7 +998,7 @@ class UAC2Cases(unittest.TestCase):

# ... and check the descriptor's fields.
self.assertEqual(parsed.bLength, 12)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificDescriptorTypes.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorSubtype, AudioClassSpecificACInterfaceDescriptorSubtypes.OUTPUT_TERMINAL)
self.assertEqual(parsed.bTerminalID, 0x06)
self.assertEqual(parsed.wTerminalType, OutputTerminalTypes.SPEAKER)
@@ -604,7 +1048,7 @@ class UAC2Cases(unittest.TestCase):

# ... and check the descriptor's fields.
self.assertEqual(parsed.bLength, 9)
self.assertEqual(parsed.bDescriptorType, DescriptorTypes.INTERFACE)
self.assertEqual(parsed.bDescriptorType, StandardDescriptorNumbers.INTERFACE)
self.assertEqual(parsed.bInterfaceNumber, 2)
self.assertEqual(parsed.bAlternateSetting, 3)
self.assertEqual(parsed.bNumEndpoints, 1)
@@ -652,7 +1096,7 @@ class UAC2Cases(unittest.TestCase):

# ... and check the descriptor's fields.
self.assertEqual(parsed.bLength, 16)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificDescriptorTypes.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorSubtype, AudioClassSpecificASInterfaceDescriptorSubtypes.AS_GENERAL)
self.assertEqual(parsed.bTerminalLink, 3)
self.assertEqual(parsed.bmControls, 0)
@@ -701,7 +1145,7 @@ class UAC2Cases(unittest.TestCase):

# ... and check the descriptor's fields.
self.assertEqual(parsed.bLength, 6)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificDescriptorTypes.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorSubtype, AudioClassSpecificASInterfaceDescriptorSubtypes.FORMAT_TYPE)
self.assertEqual(parsed.bFormatType, FormatTypes.FORMAT_TYPE_I)
self.assertEqual(parsed.bSubslotSize, 2)
@@ -740,7 +1184,7 @@ class UAC2Cases(unittest.TestCase):

# ... and check the descriptor's fields.
self.assertEqual(parsed.bLength, 9)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificDescriptorTypes.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorSubtype, AudioClassSpecificASInterfaceDescriptorSubtypes.FORMAT_TYPE)
self.assertEqual(parsed.bFormatType, FormatTypes.EXT_FORMAT_TYPE_I)
self.assertEqual(parsed.bSubslotSize, 2)
@@ -785,7 +1229,7 @@ class UAC2Cases(unittest.TestCase):

# ... and check the descriptor's fields.
self.assertEqual(parsed.bLength, 8)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificDescriptorTypes.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorSubtype, AudioClassSpecificASInterfaceDescriptorSubtypes.FORMAT_TYPE)
self.assertEqual(parsed.bFormatType, FormatTypes.FORMAT_TYPE_II)
self.assertEqual(parsed.wMaxBitRate, 64)
@@ -823,7 +1267,7 @@ class UAC2Cases(unittest.TestCase):

# ... and check the descriptor's fields.
self.assertEqual(parsed.bLength, 10)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificDescriptorTypes.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorSubtype, AudioClassSpecificASInterfaceDescriptorSubtypes.FORMAT_TYPE)
self.assertEqual(parsed.bFormatType, FormatTypes.EXT_FORMAT_TYPE_II)
self.assertEqual(parsed.wMaxBitRate, 64)
@@ -865,7 +1309,7 @@ class UAC2Cases(unittest.TestCase):

# ... and check the descriptor's fields.
self.assertEqual(parsed.bLength, 6)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificDescriptorTypes.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorSubtype, AudioClassSpecificASInterfaceDescriptorSubtypes.FORMAT_TYPE)
self.assertEqual(parsed.bFormatType, FormatTypes.FORMAT_TYPE_III)
self.assertEqual(parsed.bSubslotSize, 2)
@@ -902,7 +1346,7 @@ class UAC2Cases(unittest.TestCase):

# ... and check the descriptor's fields.
self.assertEqual(parsed.bLength, 8)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificDescriptorTypes.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE)
self.assertEqual(parsed.bDescriptorSubtype, AudioClassSpecificASInterfaceDescriptorSubtypes.FORMAT_TYPE)
self.assertEqual(parsed.bFormatType, FormatTypes.EXT_FORMAT_TYPE_III)
self.assertEqual(parsed.bSubslotSize, 2)
@@ -944,7 +1388,7 @@ class UAC2Cases(unittest.TestCase):

# ... and check the descriptor's fields.
self.assertEqual(parsed.bLength, 8)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificDescriptorTypes.CS_ENDPOINT)
self.assertEqual(parsed.bDescriptorType, AudioClassSpecificStandardDescriptorNumbers.CS_ENDPOINT)
self.assertEqual(parsed.bDescriptorSubtype, AudioClassSpecificEndpointDescriptorSubtypes.EP_GENERAL)
self.assertEqual(parsed.bmAttributes, 0)
self.assertEqual(parsed.bmControls, 0)


+ 501
- 6
usb_protocol/types/descriptors/uac3.py View File

@@ -2,7 +2,12 @@
# This file is part of usb-protocol.
#
"""
descriptors specific to USB version 2
Descriptors for USB Audio Class Devices (UAC), Release 3

[Audio30] refers to "Universal Serial Bus Device Class Definition for Audio Devices", Release 3.0, September 22, 2016
[Frmts30] refers to "Universal Serial Bus Device Class Definition for Audio Data Formats", Release 3.0, September 22, 2016
[TermT30] refers to "Universal Serial Bus Device Class Definition for Terminal Types", Release 3.0, May 31, 2006

NOTE: This is not complete yet and will be extended as needed
"""

@@ -14,17 +19,477 @@ import construct
from construct import this, Default

from .. import LanguageIDs
from .standard import StandardDescriptorNumbers
from ..descriptor import \
DescriptorField, DescriptorNumber, DescriptorFormat, \
BCDFieldAdapter, DescriptorLength

from .uac import *

class AudioInterfaceClassCode(IntEnum):
# As defined in [Audio30], Table A-4
AUDIO = 0x01


class AudioFunctionClassCode(IntEnum):
# As defined in [Audio30], Table A-1
AUDIO_FUNCTION = AudioInterfaceClassCode.AUDIO


class AudioFunctionSubclassCodes(IntEnum):
# As defined in [Audio30], Table A-2
FUNCTION_SUBCLASS_UNDEFINED = 0x00
FULL_ADC_3_0 = 0x01
GENERIC_IO = 0x20
HEADPHONE = 0x21
SPEAKER = 0x22
MICROPHONE = 0x23
HEADSET = 0x24
HEADSET_ADAPTER = 0x25
SPEAKERPHONE = 0x26


class AudioFunctionProtocolCodes(IntEnum):
# As defined in [Audio30], Table A-3
FUNCTION_PROTOCOL_UNDEFINED = 0x00
AF_VERSION_01_00 = AudioInterfaceProtocolCodes.IP_VERSION_01_00
AF_VERSION_02_00 = AudioInterfaceProtocolCodes.IP_VERSION_02_00
AF_VERSION_03_00 = AudioInterfaceProtocolCodes.IP_VERSION_03_00


class AudioInterfaceSubclassCodes(IntEnum):
# As defined in [Audio30], Table A-5
INTERFACE_SUBCLASS_UNDEFINED = 0x00
AUDIO_CONTROL = 0x01
AUDIO_STREAMING = 0x02
MIDI_STREAMING = 0x03


class AudioInterfaceProtocolCodes(IntEnum):
# As defined in [Audio30], Table A-6
IP_VERSION_01_00 = 0x00
IP_VERSION_02_00 = 0x20
IP_VERSION_03_00 = 0x30


class AudioFunctionCategoryCodes(IntEnum):
# As defined in [Audio30], Table A-7
FUNCTION_SUBCLASS_UNDEFINED = 0x00
DESKTOP_SPEAKER = 0x01
HOME_THEATER = 0x02
MICROPHONE = 0x03
HEADSET = 0x04
TELEPHONE = 0x05
CONVERTER = 0x06
VOICE_SOUND_RECORDER = 0x07
IO_BOX = 0x08
MUSICAL_INSTRUMENT = 0x09
PRO_AUDIO = 0x0A
AUDIO_VIDEO = 0x0B
CONTROL_PANEL = 0x0C
HEADPHONE = 0x0D
GENERIC_SPEAKER = 0x0E
HEADSET_ADAPTER = 0x0F
SPEAKERPHONE = 0x10
OTHER = 0xFF


class AudioClassSpecificDescriptorTypes(IntEnum):
# As defined in [Audio30], Table A-8
CS_UNDEFINED = 0x20
CS_DEVICE = 0x21
CS_CONFIGURATION = 0x22
CS_STRING = 0x23
CS_INTERFACE = 0x24
CS_ENDPOINT = 0x25
CS_CLUSTER = 0x26


class ClusterDescriptorSubtypes(IntEnum):
# As defined in [Audio30], Table A-9
SUBTYPE_UNDEFINED = 0x00


class ClusterDescriptorSegmentTypes(IntEnum):
# As defined in [Audio30], Table A-10
SEGMENT_UNDEFINED = 0x00
CLUSTER_DESCRIPTION = 0x01
CLUSTER_VENDOR_DEFINED = 0x1F
CHANNEL_INFORMATION = 0x20
CHANNEL_AMBISONIC = 0x21
CHANNEL_DESCRIPTION = 0x22
CHANNEL_VENDOR_DEFINED = 0xFE
END_SEGMENT = 0xFF


class ChannelPurposeDefinitions(IntEnum):
# As defined in [Audio30], Table A-11
PURPOSE_UNDEFINED = 0x00
GENERIC_AUDIO = 0x01
VOICE = 0x02
SPEECH = 0x03
AMBIENT = 0x04
REFERENCE = 0x05
ULTRASONIC = 0x06
VIBROKINETIC = 0x07
NON_AUDIO = 0xFF


class AmbisonicComponentOrderingConventionTypes(IntEnum):
# As defined in [Audio30], Table A-13
ORD_TYPE_UNDEFINED = 0x00
AMBISONIC_CHANNEL_NUMBER_ACN = 0x01
FURSE_MALHAM = 0x02
SINGLE_INDEX_DESIGNATION_SID = 0x03


class AmbisonicNormalizationTypes(IntEnum):
# As defined in [Audio30], Table A-14
NORM_TYPE_UNDEFINED = 0x00
MAX_N = 0x01
SN3D = 0x02
N3D = 0x03
SN2D = 0x04
N2D = 0x05


class AudioClassSpecificACInterfaceDescriptorSubtypes(IntEnum):
# As defined in [Audio30], Table A-15
AC_DESCRIPTOR_UNDEFINED = 0x00
HEADER = 0x01
INPUT_TERMINAL = 0x02
OUTPUT_TERMINAL = 0x03
EXTENDED_TERMINAL = 0x04
MIXER_UNIT = 0x05
SELECTOR_UNIT = 0x06
FEATURE_UNIT = 0x07
EFFECT_UNIT = 0x08
PROCESSING_UNIT = 0x09
EXTENSION_UNIT = 0x0A
CLOCK_SOURCE = 0x0B
CLOCK_SELECTOR = 0x0C
CLOCK_MULTIPLIER = 0x0D
SAMPLE_RATE_CONVERTER = 0x0E
CONNECTORS = 0x0F
POWER_DOMAIN = 0x10


class AudioClassSpecificASInterfaceDescriptorSubtypes(IntEnum):
# As defined in [Audio30], Table A-16
AS_DESCRIPTOR_UNDEFINED = 0x00
AS_GENERAL = 0x01
AS_VALID_FREQ_RANGE = 0x02


class AudioClassSpecificStringDescriptorSubtypes(IntEnum):
# As defined in [Audio30], Table A-17
SUBTYPE_UNDEFINED = 0x00


class ExtendedTerminalSegmentTypes(IntEnum):
# As defined in [Audio30], Table A-18
SEGMENT_UNDEFINED = 0x00
TERMINAL_VENDOR_DEFINED = 0x1F
CHANNEL_BANDWIDTH = 0x20
CHANNEL_MAGNITUDE_RESPONSE = 0x21
CHANNEL_MAGNITUDE_PHASE_RESPONSE = 0x22
CHANNEL_POSITION_XYZ = 0x23
CHANNEL_POSITION_R_THETA_PHI = 0x24
CHANNEL_VENDOR_DEFINED = 0xFE
END_SEGMENT = 0xFF


class EffectUnitEffectTypes(IntEnum):
# As defined in [Audio30], Table A-19
EFFECT_UNDEFINED = 0x00
PARAM_EQ_SECTION_EFFECT = 0x01
REVERBERATION_EFFECT = 0x02
MOD_DELAY_EFFECT = 0x03
DYN_RANGE_COMP_EFFECT = 0x04


class ProcessingUnitProcessTypes(IntEnum):
# As defined in [Audio30], Table A20
PROCESS_UNDEFINED = 0x0000
UP_DOWNMIX_PROCESS = 0x0001
STEREO_EXTENDER_PROCESS = 0x0002
MULTI_FUNCTION_PROCESS = 0x0003


class AudioClassSpecificEndpointDescriptorSubtypes(IntEnum):
# As defined in [Audio30], Table A-21
DESCRIPTOR_UNDEFINED = 0x00
EP_GENERAL = 0x01


class AudioClassSpecificRequestCodes(IntEnum):
# As defined in [Audio30], Table A-22
REQUEST_CODE_UNDEFINED = 0x00
CUR = 0x01
RANGE = 0x02
MEM = 0x03
INTEN = 0x04
STRING = 0x05
HIGH_CAPABILITY_DESCRIPTOR = 0x06


class AudioControlInterfaceControlSelectors(IntEnum):
# As defined in [Audio30], Table A-23
AC_CONTROL_UNDEFINED = 0x00
AC_ACTIVE_INTERFACE_CONTROL = 0x01
AC_POWER_DOMAIN_CONTROL = 0x02


class ClockSourceControlSelectors(IntEnum):
# As defined in [Audio30], Table A-24
CS_CONTROL_UNDEFINED = 0x00
CS_SAM_FREQ_CONTROL = 0x01
CS_CLOCK_VALID_CONTROL = 0x02


class ClockSelectorControlSelectors(IntEnum):
# As defined in [Audio30], Table A-24
CX_CONTROL_UNDEFINED = 0x00
CX_CLOCK_SELECTOR_CONTROL = 0x01


class ClockMultiplierControlSelectors(IntEnum):
# As defined in [Audio30], Table A-26
CM_CONTROL_UNDEFINED = 0x00
CM_NUMERATOR_CONTROL = 0x01
CM_DENOMINATOR_CONTROL = 0x02


class TerminalControlSelectors(IntEnum):
# As defined in [Audio30], Table A-27
TE_CONTROL_UNDEFINED = 0x00
TE_INSERTION_CONTROL = 0x01
TE_OVERLOAD_CONTROL = 0x02
TE_UNDERFLOW_CONTROL = 0x03
TE_OVERFLOW_CONTROL = 0x04
TE_LATENCY_CONTROL = 0x05


class MixerControlSelectors(IntEnum):
# As defined in [Audio30], Table A-28
MU_CONTROL_UNDEFINED = 0x00
MU_MIXER_CONTROL = 0x01
MU_UNDERFLOW_CONTROL = 0x02
MU_OVERFLOW_CONTROL = 0x03
MU_LATENCY_CONTROL = 0x04


class SelectorControlSelectors(IntEnum):
# As defined in [Audio30], Table A-29
SU_CONTROL_UNDEFINED = 0x00
SU_SELECTOR_CONTROL = 0x01
SU_LATENCY_CONTROL = 0x02


class FeatureUnitControlSelectors(IntEnum):
# As defined in [Audio30], Table A-30
FU_CONTROL_UNDEFINED = 0x00
FU_MUTE_CONTROL = 0x01
FU_VOLUME_CONTROL = 0x02
FU_BASS_CONTROL = 0x03
FU_MID_CONTROL = 0x04
FU_TREBLE_CONTROL = 0x05
FU_GRAPHIC_EQUALIZER_CONTROL = 0x06
FU_AUTOMATIC_GAIN_CONTROL = 0x07
FU_DELAY_CONTROL = 0x08
FU_BASS_BOOST_CONTROL = 0x09
FU_LOUDNESS_CONTROL = 0x0A
FU_INPUT_GAIN_CONTROL = 0x0B
FU_INPUT_GAIN_PAD_CONTROL = 0x0C
FU_PHASE_INVERTER_CONTROL = 0x0D
FU_UNDERFLOW_CONTROL = 0x0E
FU_OVERFLOW_CONTROL = 0x0F
FU_LATENCY_CONTROL = 0x10


class ParametricEqualizerSectionEffectUnitControlSelectors(IntEnum):
# As defined in [Audio30], Table A-31
PE_CONTROL_UNDEFINED = 0x00
PE_ENABLE_CONTROL = 0x01
PE_CENTERFREQ_CONTROL = 0x02
PE_QFACTOR_CONTROL = 0x03
PE_GAIN_CONTROL = 0x04
PE_UNDERFLOW_CONTROL = 0x05
PE_OVERFLOW_CONTROL = 0x06
PE_LATENCY_CONTROL = 0x07


class ReverberationEffectUnitControlSelectors(IntEnum):
# As defined in [Audio30], Table A-32
RV_CONTROL_UNDEFINED = 0x00
RV_ENABLE_CONTROL = 0x01
RV_TYPE_CONTROL = 0x02
RV_LEVEL_CONTROL = 0x03
RV_TIME_CONTROL = 0x04
RV_FEEDBACK_CONTROL = 0x05
RV_PREDELAY_CONTROL = 0x06
RV_DENSITY_CONTROL = 0x07
RV_HIFREQ_ROLLOFF_CONTROL = 0x08
RV_UNDERFLOW_CONTROL = 0x09
RV_OVERFLOW_CONTROL = 0x0A
RV_LATENCY_CONTROL = 0x0B


class ModulationDelayEffectUnitControlSelectors(IntEnum):
# As defined in [Audio30], Table A-33
MD_CONTROL_UNDEFINED = 0x00
MD_ENABLE_CONTROL = 0x01
MD_BALANCE_CONTROL = 0x02
MD_RATE_CONTROL = 0x03
MD_DEPTH_CONTROL = 0x04
MD_TIME_CONTROL = 0x05
MD_FEEDBACK_CONTROL = 0x06
MD_UNDERFLOW_CONTROL = 0x07
MD_OVERFLOW_CONTROL = 0x08
MD_LATENCY_CONTROL = 0x09


class DynamicRangeCompressorEffectUnitControlSelectors(IntEnum):
# As defined in [Audio30], Table A-34
DR_CONTROL_UNDEFINED = 0x00
DR_ENABLE_CONTROL = 0x01
DR_COMPRESSION_RATE_CONTROL = 0x02
DR_MAXAMPL_CONTROL = 0x03
DR_THRESHOLD_CONTROL = 0x04
DR_ATTACK_TIME_CONTROL = 0x05
DR_RELEASE_TIME_CONTROL = 0x06
DR_UNDERFLOW_CONTROL = 0x07
DR_OVERFLOW_CONTROL = 0x08
DR_LATENCY_CONTROL = 0x09


class UpDownMixProcessingUnitControlSelectors(IntEnum):
# As defined in [Audio30], Table A-35
UD_CONTROL_UNDEFINED = 0x00
UD_MODE_SELECT_CONTROL = 0x01
UD_UNDERFLOW_CONTROL = 0x02
UD_OVERFLOW_CONTROL = 0x03
UD_LATENCY_CONTROL = 0x04


class StereoExtenderProcessingUnitControlSelectors(IntEnum):
# As defined in [Audio30], Table A-36
ST_EXT_CONTROL_UNDEFINED = 0x00
ST_EXT_WIDTH_CONTROL = 0x01
ST_EXT_UNDERFLOW_CONTROL = 0x02
ST_EXT_OVERFLOW_CONTROL = 0x03
ST_EXT_LATENCY_CONTROL = 0x04


class ExtensionUnitControlSelectors(IntEnum):
# As defined in [Audio30], Table A-37
XU_CONTROL_UNDEFINED = 0x00
XU_UNDERFLOW_CONTROL = 0x01
XU_OVERFLOW_CONTROL = 0x02
XU_LATENCY_CONTROL = 0x03


class AudioStreamingInterfaceControlSelectors(IntEnum):
# As defined in [Audio30], Table A-38
AS_CONTROL_UNDEFINED = 0x00
AS_ACT_ALT_SETTING_CONTROL = 0x01
AS_VAL_ALT_SETTINGS_CONTROL = 0x02
AS_AUDIO_DATA_FORMAT_CONTROL = 0x03


class EndpointControlSelectors(IntEnum):
# As defined in [Audio30], Table A-39
EP_CONTROL_UNDEFINED = 0x00
EP_PITCH_CONTROL = 0x01
EP_DATA_OVERRUN_CONTROL = 0x02
EP_DATA_UNDERRUN_CONTROL = 0x03


class USBTerminalTypes(IntEnum):
# As defined in [TermT30], Table 2-1
USB_UNDEFINED = 0x0100
USB_STREAMING = 0x0101
USB_VENDOR_SPECIFIC = 0x01FF


class InputTerminalTypes(IntEnum):
# As defined in [TermT30], Table 2-2
INPUT_UNDEFINED = 0x0200
MICROPHONE = 0x0201
DESKTOP_MICROPHONE = 0x0202
PERSONAL_MICROPHONE = 0x0203
OMNI_DIRECTIONAL_MICROPHONE = 0x0204
MICROPHONE_ARRAY = 0x0205
PROCESSING_MICROPHONE_ARRAY = 0x0206


class OutputTerminalTypes(IntEnum):
# As defined in [TermT30], Table 2-3
OUTPUT_UNDEFINED = 0x0300
SPEAKER = 0x0301
HEADPHONES = 0x0302
DESKTOP_SPEAKER = 0x0304
ROOM_SPEAKER = 0x0305
COMMUNICATION_SPEAKER = 0x0306
LOW_FREQUENCY_EFFECTS_SPEAKER = 0x0307


class BidirectionalTerminalTypes(IntEnum):
# As defined in [TermT30], Table 2-4
BIDIRECTIONAL_UNDEFINED = 0x0400
HANDSET = 0x0401
HEADSET = 0x0402
ECHO_SUPPRESSING_SPEAKERPHONE = 0x0404
ECHO_CANCELING_SPEAKERPHONE = 0x0405


class TelephonyTerminalTypes(IntEnum):
# As defined in [TermT30], Table 2-5
TELEPHONY_UNDEFINED = 0x0500
PHONE_LINE = 0x0501
TELEPHONE = 0x0502
DOWN_LINE_PHONE = 0x0503


class ExternalTerminalTypes(IntEnum):
# As defined in [TermT30], Table 2-6
EXTERNAL_UNDEFINED = 0x0600
ANALOG_CONNECTOR = 0x0601
DIGITAL_AUDIO_INTERFACE = 0x0602
LINE_CONNECTOR = 0x0603
SPDIF_INTERFACE = 0x0605
IEEE_1394_DA_STREAM = 0x0606
IEEE_1394_DV_STREAM_SOUNDTRACK = 0x0607
ADAT_LIGHTPIPE = 0x0608
TDIF = 0x0609
MADI = 0x060A


class EmbeddedFunctionTerminalTypes(IntEnum):
# As defined in [TermT30], Table 2-7
EMBEDDED_UNDEFINED = 0x0700
EQUALIZATION_NOISE = 0x0702
CD_PLAYER = 0x0703
DAT = 0x0704
DCC = 0x0705
ANALOG_TAPE = 0x0707
PHONOGRAPH = 0x0708
VCR_AUDIO = 0x0709
VIDEO_DISC_AUDIO = 0x070A
DVD_AUDIO = 0x070B
TV_TUNER_AUDIO = 0x070C
SATELLITE_RECEIVER_AUDIO = 0x070D
CABLE_TUNER_AUDIO = 0x070E
DSS_AUDIO = 0x070F
RADIO_RECEIVER = 0x0710
RADIO_TRANSMITTER = 0x0711
MULTI_TRACK_RECORDER = 0x0712
SYNTHESIZER = 0x0713
PIANO = 0x0714
GUITAR = 0x0715
DRUMS_RHYTHM = 0x0716
OTHER_MUSICAL_INSTRUMENT = 0x0717


class ConnectorTypes(IntEnum):
UNDEFINED = 0x00
PHONE_CONNECTOR_2_5_MM = 0x01
@@ -100,9 +565,39 @@ class AudioDataFormats(IntEnum):
MPEG_4_AAC_ELD = (1 << 32)


# As defined in [Audio30], Table 4-47
AudioControlInterruptEndpointDescriptor = DescriptorFormat(
"bLength" / construct.Const(7, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_ENDPOINT),
"bEndpointAddress" / DescriptorField(description="The address of the endpoint, use USBDirection.*.from_endpoint_address()"),
"bmAttributes" / DescriptorField(description="D1..0: Transfer type (0b11 = Interrupt)", default=0b11),
"wMaxPacketSize" / DescriptorField(description="Maximum packet size this endpoint is capable of. Used here to pass 6-byte interrupt information.", default=6),
"bInterval" / DescriptorField(description="Interval for polling the Interrupt endpoint")
)

# As defined in [Audio30], Table 4-51
AudioStreamingIsochronousEndpointDescriptor = DescriptorFormat(
"bLength" / construct.Const(7, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(StandardDescriptorNumbers.ENDPOINT),
"bEndpointAddress" / DescriptorField(description="The address of the endpoint, use USBDirection.*.from_endpoint_address()"),
"bmAttributes" / DescriptorField(description="D1..0: transfer type (01=isochronous); D3..2: synchronization type (01=asynchronous/10=adaptive/11=synchronous); D5..4: usage (00=data/10=feedback)", default=0b000101),
"wMaxPacketSize" / DescriptorField(description="Maximum packet size this endpoint is capable of. Used here to pass 6-byte interrupt information.", default=6),
"bInterval" / DescriptorField(description="Interval for polling the Interrupt endpoint")
)

# As defined in [Audio30], Table 4-53
AudioStreamingIsochronousFeedbackEndpointDescriptor = DescriptorFormat(
"bLength" / construct.Const(7, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(StandardDescriptorNumbers.ENDPOINT),
"bEndpointAddress" / DescriptorField(description="The address of the endpoint, use USBDirection.*.from_endpoint_address()"),
"bmAttributes" / DescriptorField(description="D1..0: transfer type (01=isochronous); D3..2: synchronization type (00=no sync); D5..4: usage (10=feedback)", default=0b00100001),
"wMaxPacketSize" / DescriptorField(description="Maximum packet size this endpoint is capable of. Used here to pass 6-byte interrupt information.", default=6),
"bInterval" / DescriptorField(description="Interval for polling the Interrupt endpoint")
)

HeaderDescriptor = DescriptorFormat(
"bLength" / construct.Const(10, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificACInterfaceDescriptorSubtypes.HEADER),
"bCategory" / DescriptorField(description="Audio Function Category, see AudioFunctionCategoryCodes"),
"wTotalLength" / DescriptorField("Length including subordinates"),
@@ -123,7 +618,7 @@ AudioStreamingInterfaceDescriptor = DescriptorFormat(

ClassSpecificAudioStreamingInterfaceDescriptor = DescriptorFormat(
"bLength" / construct.Const(23, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificASInterfaceDescriptorSubtypes.AS_GENERAL),
"bTerminalLink" / DescriptorField(description="the ID of the terminal to which this interface is connected"),
"bmControls" / DescriptorField(description="D1..0: active alternate setting control; D3..2: valid alternate settings control; D5..4: audio data format control; D31..6: reserved"),
@@ -137,7 +632,7 @@ ClassSpecificAudioStreamingInterfaceDescriptor = DescriptorFormat(

InputTerminalDescriptor = DescriptorFormat(
"bLength" / construct.Const(20, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificACInterfaceDescriptorSubtypes.INPUT_TERMINAL),
"bTerminalID" / DescriptorField(description="unique identifier for the terminal within the audio function."),
"wTerminalType" / DescriptorField(description="a value of one of the terminal types Enums (eg InputTerminaTypes, ExternalTerminalTypes)"),
@@ -152,7 +647,7 @@ InputTerminalDescriptor = DescriptorFormat(

OutputTerminalDescriptor = DescriptorFormat(
"bLength" / construct.Const(19, construct.Int8ul),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificDescriptorTypes.CS_INTERFACE),
"bDescriptorType" / DescriptorNumber(AudioClassSpecificStandardDescriptorNumbers.CS_INTERFACE),
"bDescriptorSubtype" / DescriptorNumber(AudioClassSpecificACInterfaceDescriptorSubtypes.OUTPUT_TERMINAL),
"bTerminalID" / DescriptorField(description="unique identifier for the terminal within the audio function."),
"wTerminalType" / DescriptorField(description="a value of one of the terminal types Enums (eg OutputTerminaTypes, ExternalTerminalTypes)"),


Loading…
Cancel
Save