From ad2e7e7d891345c91195e4442dac2ce83fc6af0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20M=C3=BCller?= Date: Sun, 18 Apr 2021 21:06:58 +0200 Subject: [PATCH] Rework UAC/MIDI * Split UAC from MIDI * Split UAC into UAC1, UAC2, UAC3 as descriptors and other constants are often defined differently --- usb_protocol/emitters/descriptors/uac.py | 67 --- usb_protocol/emitters/descriptors/uac1.py | 10 + usb_protocol/emitters/descriptors/uac2.py | 3 - usb_protocol/emitters/descriptors/uac3.py | 15 + usb_protocol/types/descriptors/midi1.py | 110 +++++ usb_protocol/types/descriptors/midi2.py | 88 ++++ usb_protocol/types/descriptors/uac.py | 527 ---------------------- usb_protocol/types/descriptors/uac1.py | 273 +++++++++++ usb_protocol/types/descriptors/uac2.py | 518 +++++++++++++++++++-- usb_protocol/types/descriptors/uac3.py | 507 ++++++++++++++++++++- 10 files changed, 1478 insertions(+), 640 deletions(-) delete mode 100644 usb_protocol/emitters/descriptors/uac.py create mode 100644 usb_protocol/emitters/descriptors/uac1.py create mode 100644 usb_protocol/emitters/descriptors/uac3.py create mode 100644 usb_protocol/types/descriptors/midi1.py create mode 100644 usb_protocol/types/descriptors/midi2.py delete mode 100644 usb_protocol/types/descriptors/uac.py create mode 100644 usb_protocol/types/descriptors/uac1.py diff --git a/usb_protocol/emitters/descriptors/uac.py b/usb_protocol/emitters/descriptors/uac.py deleted file mode 100644 index 0798e87..0000000 --- a/usb_protocol/emitters/descriptors/uac.py +++ /dev/null @@ -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() \ No newline at end of file diff --git a/usb_protocol/emitters/descriptors/uac1.py b/usb_protocol/emitters/descriptors/uac1.py new file mode 100644 index 0000000..7e7b16b --- /dev/null +++ b/usb_protocol/emitters/descriptors/uac1.py @@ -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) diff --git a/usb_protocol/emitters/descriptors/uac2.py b/usb_protocol/emitters/descriptors/uac2.py index 4a46009..e9d4de4 100644 --- a/usb_protocol/emitters/descriptors/uac2.py +++ b/usb_protocol/emitters/descriptors/uac2.py @@ -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) diff --git a/usb_protocol/emitters/descriptors/uac3.py b/usb_protocol/emitters/descriptors/uac3.py new file mode 100644 index 0000000..40fcf79 --- /dev/null +++ b/usb_protocol/emitters/descriptors/uac3.py @@ -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) \ No newline at end of file diff --git a/usb_protocol/types/descriptors/midi1.py b/usb_protocol/types/descriptors/midi1.py new file mode 100644 index 0000000..f41cdc9 --- /dev/null +++ b/usb_protocol/types/descriptors/midi1.py @@ -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 +) diff --git a/usb_protocol/types/descriptors/midi2.py b/usb_protocol/types/descriptors/midi2.py new file mode 100644 index 0000000..8c86cb5 --- /dev/null +++ b/usb_protocol/types/descriptors/midi2.py @@ -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) +) + + + diff --git a/usb_protocol/types/descriptors/uac.py b/usb_protocol/types/descriptors/uac.py deleted file mode 100644 index 497a5a6..0000000 --- a/usb_protocol/types/descriptors/uac.py +++ /dev/null @@ -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 -) \ No newline at end of file diff --git a/usb_protocol/types/descriptors/uac1.py b/usb_protocol/types/descriptors/uac1.py new file mode 100644 index 0000000..4ee2897 --- /dev/null +++ b/usb_protocol/types/descriptors/uac1.py @@ -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") +) + diff --git a/usb_protocol/types/descriptors/uac2.py b/usb_protocol/types/descriptors/uac2.py index 589a9f5..5dd7988 100644 --- a/usb_protocol/types/descriptors/uac2.py +++ b/usb_protocol/types/descriptors/uac2.py @@ -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) diff --git a/usb_protocol/types/descriptors/uac3.py b/usb_protocol/types/descriptors/uac3.py index e1b4646..fc73100 100644 --- a/usb_protocol/types/descriptors/uac3.py +++ b/usb_protocol/types/descriptors/uac3.py @@ -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)"),