From 05200284d2149abe9bbb17cc883b9b9a2ffd42de Mon Sep 17 00:00:00 2001 From: uael Date: Thu, 23 Feb 2023 20:58:28 +0000 Subject: [PATCH] a2dp: get rid of `construct` dependency --- bumble/a2dp.py | 75 ++++++++++++++++++++++++++++++-------------------- setup.cfg | 1 - 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/bumble/a2dp.py b/bumble/a2dp.py index de9f5f4..772846a 100644 --- a/bumble/a2dp.py +++ b/bumble/a2dp.py @@ -18,7 +18,6 @@ import struct import logging from collections import namedtuple -import construct from .company_ids import COMPANY_IDENTIFIERS from .sdp import ( @@ -258,17 +257,6 @@ class SbcMediaCodecInformation( A2DP spec - 4.3.2 Codec Specific Information Elements ''' - BIT_FIELDS = construct.Bitwise( - construct.Sequence( - construct.BitsInteger(4), - construct.BitsInteger(4), - construct.BitsInteger(4), - construct.BitsInteger(2), - construct.BitsInteger(2), - construct.BitsInteger(8), - construct.BitsInteger(8), - ) - ) SAMPLING_FREQUENCY_BITS = {16000: 1 << 3, 32000: 1 << 2, 44100: 1 << 1, 48000: 1} CHANNEL_MODE_BITS = { SBC_MONO_CHANNEL_MODE: 1 << 3, @@ -284,9 +272,22 @@ class SbcMediaCodecInformation( } @staticmethod - def from_bytes(data): + def from_bytes(data: bytes) -> 'SbcMediaCodecInformation': + sampling_frequency = (data[0] >> 4) & 0x0F + channel_mode = (data[0] >> 0) & 0x0F + block_length = (data[1] >> 4) & 0x0F + subbands = (data[1] >> 2) & 0x03 + allocation_method = (data[1] >> 0) & 0x03 + minimum_bitpool_value = (data[2] >> 0) & 0xFF + maximum_bitpool_value = (data[3] >> 0) & 0xFF return SbcMediaCodecInformation( - *SbcMediaCodecInformation.BIT_FIELDS.parse(data) + sampling_frequency, + channel_mode, + block_length, + subbands, + allocation_method, + minimum_bitpool_value, + maximum_bitpool_value, ) @classmethod @@ -335,8 +336,17 @@ class SbcMediaCodecInformation( maximum_bitpool_value=maximum_bitpool_value, ) - def __bytes__(self): - return self.BIT_FIELDS.build(self) + def __bytes__(self) -> bytes: + return bytes( + [ + (self.sampling_frequency << 4) | self.channel_mode, + (self.block_length << 4) + | (self.subbands << 2) + | self.allocation_method, + self.minimum_bitpool_value, + self.maximum_bitpool_value, + ] + ) def __str__(self): channel_modes = ['MONO', 'DUAL_CHANNEL', 'STEREO', 'JOINT_STEREO'] @@ -367,16 +377,6 @@ class AacMediaCodecInformation( A2DP spec - 4.5.2 Codec Specific Information Elements ''' - BIT_FIELDS = construct.Bitwise( - construct.Sequence( - construct.BitsInteger(8), - construct.BitsInteger(12), - construct.BitsInteger(2), - construct.BitsInteger(2), - construct.BitsInteger(1), - construct.BitsInteger(23), - ) - ) OBJECT_TYPE_BITS = { MPEG_2_AAC_LC_OBJECT_TYPE: 1 << 7, MPEG_4_AAC_LC_OBJECT_TYPE: 1 << 6, @@ -400,9 +400,15 @@ class AacMediaCodecInformation( CHANNELS_BITS = {1: 1 << 1, 2: 1} @staticmethod - def from_bytes(data): + def from_bytes(data: bytes) -> 'AacMediaCodecInformation': + object_type = data[0] + sampling_frequency = (data[1] << 4) | ((data[2] >> 4) & 0x0F) + channels = (data[2] >> 2) & 0x03 + rfa = 0 + vbr = (data[3] >> 7) & 0x01 + bitrate = ((data[3] & 0x7F) << 16) | (data[4] << 8) | data[5] return AacMediaCodecInformation( - *AacMediaCodecInformation.BIT_FIELDS.parse(data) + object_type, sampling_frequency, channels, rfa, vbr, bitrate ) @classmethod @@ -430,8 +436,17 @@ class AacMediaCodecInformation( bitrate=bitrate, ) - def __bytes__(self): - return self.BIT_FIELDS.build(self) + def __bytes__(self) -> bytes: + return bytes( + [ + self.object_type & 0xFF, + (self.sampling_frequency >> 4) & 0xFF, + (((self.sampling_frequency & 0x0F) << 4) | (self.channels << 2)) & 0xFF, + ((self.vbr << 7) | ((self.bitrate >> 16) & 0x7F)) & 0xFF, + ((self.bitrate >> 8) & 0xFF) & 0xFF, + self.bitrate & 0xFF, + ] + ) def __str__(self): object_types = [ diff --git a/setup.cfg b/setup.cfg index 3be6bcc..ef3dbdf 100644 --- a/setup.cfg +++ b/setup.cfg @@ -32,7 +32,6 @@ include-package-data = True install_requires = appdirs >= 1.4 click >= 7.1.2; platform_system!='Emscripten' - construct >= 2.10 cryptography == 35; platform_system!='Emscripten' grpcio >= 1.46; platform_system!='Emscripten' libusb1 >= 2.0.1; platform_system!='Emscripten'