bumble 0.0.195__py3-none-any.whl → 0.0.199__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bumble/_version.py +2 -2
- bumble/apps/auracast.py +351 -66
- bumble/apps/console.py +5 -20
- bumble/apps/device_info.py +230 -0
- bumble/apps/gatt_dump.py +4 -0
- bumble/apps/lea_unicast/app.py +16 -17
- bumble/apps/pair.py +32 -5
- bumble/at.py +12 -6
- bumble/att.py +56 -40
- bumble/avc.py +8 -5
- bumble/avctp.py +3 -2
- bumble/avdtp.py +7 -3
- bumble/avrcp.py +2 -1
- bumble/codecs.py +17 -13
- bumble/colors.py +6 -2
- bumble/core.py +37 -7
- bumble/decoder.py +14 -10
- bumble/device.py +382 -111
- bumble/drivers/rtk.py +32 -13
- bumble/gatt.py +30 -20
- bumble/gatt_client.py +15 -29
- bumble/gatt_server.py +14 -6
- bumble/hci.py +322 -32
- bumble/hid.py +24 -28
- bumble/host.py +20 -6
- bumble/l2cap.py +24 -17
- bumble/link.py +8 -3
- bumble/pandora/__init__.py +3 -0
- bumble/pandora/l2cap.py +310 -0
- bumble/profiles/aics.py +520 -0
- bumble/profiles/ascs.py +739 -0
- bumble/profiles/asha.py +295 -0
- bumble/profiles/bap.py +1 -874
- bumble/profiles/bass.py +440 -0
- bumble/profiles/csip.py +4 -4
- bumble/profiles/gap.py +110 -0
- bumble/profiles/hap.py +665 -0
- bumble/profiles/heart_rate_service.py +4 -3
- bumble/profiles/le_audio.py +43 -9
- bumble/profiles/mcp.py +448 -0
- bumble/profiles/pacs.py +210 -0
- bumble/profiles/tmap.py +89 -0
- bumble/profiles/vcp.py +5 -3
- bumble/rfcomm.py +4 -2
- bumble/sdp.py +13 -11
- bumble/smp.py +43 -12
- bumble/snoop.py +5 -4
- bumble/transport/__init__.py +8 -2
- bumble/transport/android_emulator.py +9 -3
- bumble/transport/android_netsim.py +9 -7
- bumble/transport/common.py +46 -18
- bumble/transport/pyusb.py +21 -4
- bumble/transport/unix.py +56 -0
- bumble/transport/usb.py +57 -46
- {bumble-0.0.195.dist-info → bumble-0.0.199.dist-info}/METADATA +41 -41
- {bumble-0.0.195.dist-info → bumble-0.0.199.dist-info}/RECORD +60 -49
- {bumble-0.0.195.dist-info → bumble-0.0.199.dist-info}/WHEEL +1 -1
- bumble/profiles/asha_service.py +0 -193
- {bumble-0.0.195.dist-info → bumble-0.0.199.dist-info}/LICENSE +0 -0
- {bumble-0.0.195.dist-info → bumble-0.0.199.dist-info}/entry_points.txt +0 -0
- {bumble-0.0.195.dist-info → bumble-0.0.199.dist-info}/top_level.txt +0 -0
bumble/avc.py
CHANGED
|
@@ -20,6 +20,7 @@ import enum
|
|
|
20
20
|
import struct
|
|
21
21
|
from typing import Dict, Type, Union, Tuple
|
|
22
22
|
|
|
23
|
+
from bumble import core
|
|
23
24
|
from bumble.utils import OpenIntEnum
|
|
24
25
|
|
|
25
26
|
|
|
@@ -88,7 +89,9 @@ class Frame:
|
|
|
88
89
|
short_name = subclass.__name__.replace("ResponseFrame", "")
|
|
89
90
|
category_class = ResponseFrame
|
|
90
91
|
else:
|
|
91
|
-
raise
|
|
92
|
+
raise core.InvalidArgumentError(
|
|
93
|
+
f"invalid subclass name {subclass.__name__}"
|
|
94
|
+
)
|
|
92
95
|
|
|
93
96
|
uppercase_indexes = [
|
|
94
97
|
i for i in range(len(short_name)) if short_name[i].isupper()
|
|
@@ -106,7 +109,7 @@ class Frame:
|
|
|
106
109
|
@staticmethod
|
|
107
110
|
def from_bytes(data: bytes) -> Frame:
|
|
108
111
|
if data[0] >> 4 != 0:
|
|
109
|
-
raise
|
|
112
|
+
raise core.InvalidPacketError("first 4 bits must be 0s")
|
|
110
113
|
|
|
111
114
|
ctype_or_response = data[0] & 0xF
|
|
112
115
|
subunit_type = Frame.SubunitType(data[1] >> 3)
|
|
@@ -122,7 +125,7 @@ class Frame:
|
|
|
122
125
|
# Extended to the next byte
|
|
123
126
|
extension = data[2]
|
|
124
127
|
if extension == 0:
|
|
125
|
-
raise
|
|
128
|
+
raise core.InvalidPacketError("extended subunit ID value reserved")
|
|
126
129
|
if extension == 0xFF:
|
|
127
130
|
subunit_id = 5 + 254 + data[3]
|
|
128
131
|
opcode_offset = 4
|
|
@@ -131,7 +134,7 @@ class Frame:
|
|
|
131
134
|
opcode_offset = 3
|
|
132
135
|
|
|
133
136
|
elif subunit_id == 6:
|
|
134
|
-
raise
|
|
137
|
+
raise core.InvalidPacketError("reserved subunit ID")
|
|
135
138
|
|
|
136
139
|
opcode = Frame.OperationCode(data[opcode_offset])
|
|
137
140
|
operands = data[opcode_offset + 1 :]
|
|
@@ -448,7 +451,7 @@ class PassThroughFrame:
|
|
|
448
451
|
operation_data: bytes,
|
|
449
452
|
) -> None:
|
|
450
453
|
if len(operation_data) > 255:
|
|
451
|
-
raise
|
|
454
|
+
raise core.InvalidArgumentError("operation data must be <= 255 bytes")
|
|
452
455
|
self.state_flag = state_flag
|
|
453
456
|
self.operation_id = operation_id
|
|
454
457
|
self.operation_data = operation_data
|
bumble/avctp.py
CHANGED
|
@@ -23,6 +23,7 @@ from typing import Callable, cast, Dict, Optional
|
|
|
23
23
|
|
|
24
24
|
from bumble.colors import color
|
|
25
25
|
from bumble import avc
|
|
26
|
+
from bumble import core
|
|
26
27
|
from bumble import l2cap
|
|
27
28
|
|
|
28
29
|
# -----------------------------------------------------------------------------
|
|
@@ -275,7 +276,7 @@ class Protocol:
|
|
|
275
276
|
self, pid: int, handler: Protocol.CommandHandler
|
|
276
277
|
) -> None:
|
|
277
278
|
if pid not in self.command_handlers or self.command_handlers[pid] != handler:
|
|
278
|
-
raise
|
|
279
|
+
raise core.InvalidArgumentError("command handler not registered")
|
|
279
280
|
del self.command_handlers[pid]
|
|
280
281
|
|
|
281
282
|
def register_response_handler(
|
|
@@ -287,5 +288,5 @@ class Protocol:
|
|
|
287
288
|
self, pid: int, handler: Protocol.ResponseHandler
|
|
288
289
|
) -> None:
|
|
289
290
|
if pid not in self.response_handlers or self.response_handlers[pid] != handler:
|
|
290
|
-
raise
|
|
291
|
+
raise core.InvalidArgumentError("response handler not registered")
|
|
291
292
|
del self.response_handlers[pid]
|
bumble/avdtp.py
CHANGED
|
@@ -43,6 +43,7 @@ from .core import (
|
|
|
43
43
|
BT_ADVANCED_AUDIO_DISTRIBUTION_SERVICE,
|
|
44
44
|
InvalidStateError,
|
|
45
45
|
ProtocolError,
|
|
46
|
+
InvalidArgumentError,
|
|
46
47
|
name_or_number,
|
|
47
48
|
)
|
|
48
49
|
from .a2dp import (
|
|
@@ -579,10 +580,10 @@ class ServiceCapabilities:
|
|
|
579
580
|
self.service_category = service_category
|
|
580
581
|
self.service_capabilities_bytes = service_capabilities_bytes
|
|
581
582
|
|
|
582
|
-
def to_string(self, details: List[str] =
|
|
583
|
+
def to_string(self, details: Optional[List[str]] = None) -> str:
|
|
583
584
|
attributes = ','.join(
|
|
584
585
|
[name_or_number(AVDTP_SERVICE_CATEGORY_NAMES, self.service_category)]
|
|
585
|
-
+ details
|
|
586
|
+
+ (details or [])
|
|
586
587
|
)
|
|
587
588
|
return f'ServiceCapabilities({attributes})'
|
|
588
589
|
|
|
@@ -700,7 +701,7 @@ class Message: # pylint:disable=attribute-defined-outside-init
|
|
|
700
701
|
signal_identifier_str = name[:-7]
|
|
701
702
|
message_type = Message.MessageType.RESPONSE_REJECT
|
|
702
703
|
else:
|
|
703
|
-
raise
|
|
704
|
+
raise InvalidArgumentError('invalid class name')
|
|
704
705
|
|
|
705
706
|
subclass.message_type = message_type
|
|
706
707
|
|
|
@@ -2162,6 +2163,9 @@ class LocalStreamEndPoint(StreamEndPoint, EventEmitter):
|
|
|
2162
2163
|
def on_abort_command(self):
|
|
2163
2164
|
self.emit('abort')
|
|
2164
2165
|
|
|
2166
|
+
def on_delayreport_command(self, delay: int):
|
|
2167
|
+
self.emit('delay_report', delay)
|
|
2168
|
+
|
|
2165
2169
|
def on_rtp_channel_open(self):
|
|
2166
2170
|
self.emit('rtp_channel_open')
|
|
2167
2171
|
|
bumble/avrcp.py
CHANGED
|
@@ -55,6 +55,7 @@ from bumble.sdp import (
|
|
|
55
55
|
)
|
|
56
56
|
from bumble.utils import AsyncRunner, OpenIntEnum
|
|
57
57
|
from bumble.core import (
|
|
58
|
+
InvalidArgumentError,
|
|
58
59
|
ProtocolError,
|
|
59
60
|
BT_L2CAP_PROTOCOL_ID,
|
|
60
61
|
BT_AVCTP_PROTOCOL_ID,
|
|
@@ -1411,7 +1412,7 @@ class Protocol(pyee.EventEmitter):
|
|
|
1411
1412
|
def notify_track_changed(self, identifier: bytes) -> None:
|
|
1412
1413
|
"""Notify the connected peer of a Track change."""
|
|
1413
1414
|
if len(identifier) != 8:
|
|
1414
|
-
raise
|
|
1415
|
+
raise InvalidArgumentError("identifier must be 8 bytes")
|
|
1415
1416
|
self.notify_event(TrackChangedEvent(identifier))
|
|
1416
1417
|
|
|
1417
1418
|
def notify_playback_position_changed(self, position: int) -> None:
|
bumble/codecs.py
CHANGED
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
from dataclasses import dataclass
|
|
20
20
|
|
|
21
|
+
from bumble import core
|
|
22
|
+
|
|
21
23
|
|
|
22
24
|
# -----------------------------------------------------------------------------
|
|
23
25
|
class BitReader:
|
|
@@ -40,7 +42,7 @@ class BitReader:
|
|
|
40
42
|
""" "Read up to 32 bits."""
|
|
41
43
|
|
|
42
44
|
if bits > 32:
|
|
43
|
-
raise
|
|
45
|
+
raise core.InvalidArgumentError('maximum read size is 32')
|
|
44
46
|
|
|
45
47
|
if self.bits_cached >= bits:
|
|
46
48
|
# We have enough bits.
|
|
@@ -53,7 +55,7 @@ class BitReader:
|
|
|
53
55
|
feed_size = len(feed_bytes)
|
|
54
56
|
feed_int = int.from_bytes(feed_bytes, byteorder='big')
|
|
55
57
|
if 8 * feed_size + self.bits_cached < bits:
|
|
56
|
-
raise
|
|
58
|
+
raise core.InvalidArgumentError('trying to read past the data')
|
|
57
59
|
self.byte_position += feed_size
|
|
58
60
|
|
|
59
61
|
# Combine the new cache and the old cache
|
|
@@ -68,7 +70,7 @@ class BitReader:
|
|
|
68
70
|
|
|
69
71
|
def read_bytes(self, count: int):
|
|
70
72
|
if self.bit_position + 8 * count > 8 * len(self.data):
|
|
71
|
-
raise
|
|
73
|
+
raise core.InvalidArgumentError('not enough data')
|
|
72
74
|
|
|
73
75
|
if self.bit_position % 8:
|
|
74
76
|
# Not byte aligned
|
|
@@ -113,7 +115,7 @@ class AacAudioRtpPacket:
|
|
|
113
115
|
|
|
114
116
|
@staticmethod
|
|
115
117
|
def program_config_element(reader: BitReader):
|
|
116
|
-
raise
|
|
118
|
+
raise core.InvalidPacketError('program_config_element not supported')
|
|
117
119
|
|
|
118
120
|
@dataclass
|
|
119
121
|
class GASpecificConfig:
|
|
@@ -140,7 +142,7 @@ class AacAudioRtpPacket:
|
|
|
140
142
|
aac_spectral_data_resilience_flags = reader.read(1)
|
|
141
143
|
extension_flag_3 = reader.read(1)
|
|
142
144
|
if extension_flag_3 == 1:
|
|
143
|
-
raise
|
|
145
|
+
raise core.InvalidPacketError('extensionFlag3 == 1 not supported')
|
|
144
146
|
|
|
145
147
|
@staticmethod
|
|
146
148
|
def audio_object_type(reader: BitReader):
|
|
@@ -216,7 +218,7 @@ class AacAudioRtpPacket:
|
|
|
216
218
|
reader, self.channel_configuration, self.audio_object_type
|
|
217
219
|
)
|
|
218
220
|
else:
|
|
219
|
-
raise
|
|
221
|
+
raise core.InvalidPacketError(
|
|
220
222
|
f'audioObjectType {self.audio_object_type} not supported'
|
|
221
223
|
)
|
|
222
224
|
|
|
@@ -260,7 +262,7 @@ class AacAudioRtpPacket:
|
|
|
260
262
|
else:
|
|
261
263
|
audio_mux_version_a = 0
|
|
262
264
|
if audio_mux_version_a != 0:
|
|
263
|
-
raise
|
|
265
|
+
raise core.InvalidPacketError('audioMuxVersionA != 0 not supported')
|
|
264
266
|
if audio_mux_version == 1:
|
|
265
267
|
tara_buffer_fullness = AacAudioRtpPacket.latm_value(reader)
|
|
266
268
|
stream_cnt = 0
|
|
@@ -268,10 +270,10 @@ class AacAudioRtpPacket:
|
|
|
268
270
|
num_sub_frames = reader.read(6)
|
|
269
271
|
num_program = reader.read(4)
|
|
270
272
|
if num_program != 0:
|
|
271
|
-
raise
|
|
273
|
+
raise core.InvalidPacketError('num_program != 0 not supported')
|
|
272
274
|
num_layer = reader.read(3)
|
|
273
275
|
if num_layer != 0:
|
|
274
|
-
raise
|
|
276
|
+
raise core.InvalidPacketError('num_layer != 0 not supported')
|
|
275
277
|
if audio_mux_version == 0:
|
|
276
278
|
self.audio_specific_config = AacAudioRtpPacket.AudioSpecificConfig(
|
|
277
279
|
reader
|
|
@@ -284,7 +286,7 @@ class AacAudioRtpPacket:
|
|
|
284
286
|
)
|
|
285
287
|
audio_specific_config_len = reader.bit_position - marker
|
|
286
288
|
if asc_len < audio_specific_config_len:
|
|
287
|
-
raise
|
|
289
|
+
raise core.InvalidPacketError('audio_specific_config_len > asc_len')
|
|
288
290
|
asc_len -= audio_specific_config_len
|
|
289
291
|
reader.skip(asc_len)
|
|
290
292
|
frame_length_type = reader.read(3)
|
|
@@ -293,7 +295,9 @@ class AacAudioRtpPacket:
|
|
|
293
295
|
elif frame_length_type == 1:
|
|
294
296
|
frame_length = reader.read(9)
|
|
295
297
|
else:
|
|
296
|
-
raise
|
|
298
|
+
raise core.InvalidPacketError(
|
|
299
|
+
f'frame_length_type {frame_length_type} not supported'
|
|
300
|
+
)
|
|
297
301
|
|
|
298
302
|
self.other_data_present = reader.read(1)
|
|
299
303
|
if self.other_data_present:
|
|
@@ -318,12 +322,12 @@ class AacAudioRtpPacket:
|
|
|
318
322
|
|
|
319
323
|
def __init__(self, reader: BitReader, mux_config_present: int):
|
|
320
324
|
if mux_config_present == 0:
|
|
321
|
-
raise
|
|
325
|
+
raise core.InvalidPacketError('muxConfigPresent == 0 not supported')
|
|
322
326
|
|
|
323
327
|
# AudioMuxElement - ISO/EIC 14496-3 Table 1.41
|
|
324
328
|
use_same_stream_mux = reader.read(1)
|
|
325
329
|
if use_same_stream_mux:
|
|
326
|
-
raise
|
|
330
|
+
raise core.InvalidPacketError('useSameStreamMux == 1 not supported')
|
|
327
331
|
self.stream_mux_config = AacAudioRtpPacket.StreamMuxConfig(reader)
|
|
328
332
|
|
|
329
333
|
# We only support:
|
bumble/colors.py
CHANGED
|
@@ -16,6 +16,10 @@ from functools import partial
|
|
|
16
16
|
from typing import List, Optional, Union
|
|
17
17
|
|
|
18
18
|
|
|
19
|
+
class ColorError(ValueError):
|
|
20
|
+
"""Error raised when a color spec is invalid."""
|
|
21
|
+
|
|
22
|
+
|
|
19
23
|
# ANSI color names. There is also a "default"
|
|
20
24
|
COLORS = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white')
|
|
21
25
|
|
|
@@ -52,7 +56,7 @@ def _color_code(spec: ColorSpec, base: int) -> str:
|
|
|
52
56
|
elif isinstance(spec, int) and 0 <= spec <= 255:
|
|
53
57
|
return _join(base + 8, 5, spec)
|
|
54
58
|
else:
|
|
55
|
-
raise
|
|
59
|
+
raise ColorError('Invalid color spec "%s"' % spec)
|
|
56
60
|
|
|
57
61
|
|
|
58
62
|
def color(
|
|
@@ -72,7 +76,7 @@ def color(
|
|
|
72
76
|
if style_part in STYLES:
|
|
73
77
|
codes.append(STYLES.index(style_part))
|
|
74
78
|
else:
|
|
75
|
-
raise
|
|
79
|
+
raise ColorError('Invalid style "%s"' % style_part)
|
|
76
80
|
|
|
77
81
|
if codes:
|
|
78
82
|
return '\x1b[{0}m{1}\x1b[0m'.format(_join(*codes), s)
|
bumble/core.py
CHANGED
|
@@ -79,7 +79,13 @@ def get_dict_key_by_value(dictionary, value):
|
|
|
79
79
|
# -----------------------------------------------------------------------------
|
|
80
80
|
# Exceptions
|
|
81
81
|
# -----------------------------------------------------------------------------
|
|
82
|
-
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class BaseBumbleError(Exception):
|
|
85
|
+
"""Base Error raised by Bumble."""
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class BaseError(BaseBumbleError):
|
|
83
89
|
"""Base class for errors with an error code, error name and namespace"""
|
|
84
90
|
|
|
85
91
|
def __init__(
|
|
@@ -118,18 +124,42 @@ class ProtocolError(BaseError):
|
|
|
118
124
|
"""Protocol Error"""
|
|
119
125
|
|
|
120
126
|
|
|
121
|
-
class TimeoutError(
|
|
127
|
+
class TimeoutError(BaseBumbleError): # pylint: disable=redefined-builtin
|
|
122
128
|
"""Timeout Error"""
|
|
123
129
|
|
|
124
130
|
|
|
125
|
-
class CommandTimeoutError(
|
|
131
|
+
class CommandTimeoutError(BaseBumbleError):
|
|
126
132
|
"""Command Timeout Error"""
|
|
127
133
|
|
|
128
134
|
|
|
129
|
-
class InvalidStateError(
|
|
135
|
+
class InvalidStateError(BaseBumbleError):
|
|
130
136
|
"""Invalid State Error"""
|
|
131
137
|
|
|
132
138
|
|
|
139
|
+
class InvalidArgumentError(BaseBumbleError, ValueError):
|
|
140
|
+
"""Invalid Argument Error"""
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class InvalidPacketError(BaseBumbleError, ValueError):
|
|
144
|
+
"""Invalid Packet Error"""
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class InvalidOperationError(BaseBumbleError, RuntimeError):
|
|
148
|
+
"""Invalid Operation Error"""
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class NotSupportedError(BaseBumbleError, RuntimeError):
|
|
152
|
+
"""Not Supported"""
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class OutOfResourcesError(BaseBumbleError, RuntimeError):
|
|
156
|
+
"""Out of Resources Error"""
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class UnreachableError(BaseBumbleError):
|
|
160
|
+
"""The code path raising this error should be unreachable."""
|
|
161
|
+
|
|
162
|
+
|
|
133
163
|
class ConnectionError(BaseError): # pylint: disable=redefined-builtin
|
|
134
164
|
"""Connection Error"""
|
|
135
165
|
|
|
@@ -188,12 +218,12 @@ class UUID:
|
|
|
188
218
|
or uuid_str_or_int[18] != '-'
|
|
189
219
|
or uuid_str_or_int[23] != '-'
|
|
190
220
|
):
|
|
191
|
-
raise
|
|
221
|
+
raise InvalidArgumentError('invalid UUID format')
|
|
192
222
|
uuid_str = uuid_str_or_int.replace('-', '')
|
|
193
223
|
else:
|
|
194
224
|
uuid_str = uuid_str_or_int
|
|
195
225
|
if len(uuid_str) != 32 and len(uuid_str) != 8 and len(uuid_str) != 4:
|
|
196
|
-
raise
|
|
226
|
+
raise InvalidArgumentError(f"invalid UUID format: {uuid_str}")
|
|
197
227
|
self.uuid_bytes = bytes(reversed(bytes.fromhex(uuid_str)))
|
|
198
228
|
self.name = name
|
|
199
229
|
|
|
@@ -218,7 +248,7 @@ class UUID:
|
|
|
218
248
|
|
|
219
249
|
return self.register()
|
|
220
250
|
|
|
221
|
-
raise
|
|
251
|
+
raise InvalidArgumentError('only 2, 4 and 16 bytes are allowed')
|
|
222
252
|
|
|
223
253
|
@classmethod
|
|
224
254
|
def from_16_bits(cls, uuid_16: int, name: Optional[str] = None) -> UUID:
|
bumble/decoder.py
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from typing import Union
|
|
16
|
+
|
|
15
17
|
# -----------------------------------------------------------------------------
|
|
16
18
|
# Constants
|
|
17
19
|
# -----------------------------------------------------------------------------
|
|
@@ -149,7 +151,7 @@ QMF_COEFFS = [3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11]
|
|
|
149
151
|
# -----------------------------------------------------------------------------
|
|
150
152
|
# Classes
|
|
151
153
|
# -----------------------------------------------------------------------------
|
|
152
|
-
class G722Decoder
|
|
154
|
+
class G722Decoder:
|
|
153
155
|
"""G.722 decoder with bitrate 64kbit/s.
|
|
154
156
|
|
|
155
157
|
For the Blocks in the sub-band decoders, please refer to the G.722
|
|
@@ -157,7 +159,7 @@ class G722Decoder(object):
|
|
|
157
159
|
https://www.itu.int/rec/T-REC-G.722-201209-I
|
|
158
160
|
"""
|
|
159
161
|
|
|
160
|
-
def __init__(self):
|
|
162
|
+
def __init__(self) -> None:
|
|
161
163
|
self._x = [0] * 24
|
|
162
164
|
self._band = [Band(), Band()]
|
|
163
165
|
# The initial value in BLOCK 3L
|
|
@@ -165,12 +167,12 @@ class G722Decoder(object):
|
|
|
165
167
|
# The initial value in BLOCK 3H
|
|
166
168
|
self._band[1].det = 8
|
|
167
169
|
|
|
168
|
-
def decode_frame(self, encoded_data) -> bytearray:
|
|
170
|
+
def decode_frame(self, encoded_data: Union[bytes, bytearray]) -> bytearray:
|
|
169
171
|
result_array = bytearray(len(encoded_data) * 4)
|
|
170
172
|
self.g722_decode(result_array, encoded_data)
|
|
171
173
|
return result_array
|
|
172
174
|
|
|
173
|
-
def g722_decode(self, result_array, encoded_data) -> int:
|
|
175
|
+
def g722_decode(self, result_array, encoded_data: Union[bytes, bytearray]) -> int:
|
|
174
176
|
"""Decode the data frame using g722 decoder."""
|
|
175
177
|
result_length = 0
|
|
176
178
|
|
|
@@ -198,14 +200,16 @@ class G722Decoder(object):
|
|
|
198
200
|
|
|
199
201
|
return result_length
|
|
200
202
|
|
|
201
|
-
def update_decoded_result(
|
|
203
|
+
def update_decoded_result(
|
|
204
|
+
self, xout: int, byte_length: int, byte_array: bytearray
|
|
205
|
+
) -> int:
|
|
202
206
|
result = (int)(xout >> 11)
|
|
203
207
|
bytes_result = result.to_bytes(2, 'little', signed=True)
|
|
204
208
|
byte_array[byte_length] = bytes_result[0]
|
|
205
209
|
byte_array[byte_length + 1] = bytes_result[1]
|
|
206
210
|
return byte_length + 2
|
|
207
211
|
|
|
208
|
-
def lower_sub_band_decoder(self, lower_bits) -> int:
|
|
212
|
+
def lower_sub_band_decoder(self, lower_bits: int) -> int:
|
|
209
213
|
"""Lower sub-band decoder for last six bits."""
|
|
210
214
|
|
|
211
215
|
# Block 5L
|
|
@@ -258,7 +262,7 @@ class G722Decoder(object):
|
|
|
258
262
|
|
|
259
263
|
return rlow
|
|
260
264
|
|
|
261
|
-
def higher_sub_band_decoder(self, higher_bits) -> int:
|
|
265
|
+
def higher_sub_band_decoder(self, higher_bits: int) -> int:
|
|
262
266
|
"""Higher sub-band decoder for first two bits."""
|
|
263
267
|
|
|
264
268
|
# Block 2H
|
|
@@ -306,14 +310,14 @@ class G722Decoder(object):
|
|
|
306
310
|
|
|
307
311
|
|
|
308
312
|
# -----------------------------------------------------------------------------
|
|
309
|
-
class Band
|
|
310
|
-
"""Structure for G722 decode
|
|
313
|
+
class Band:
|
|
314
|
+
"""Structure for G722 decode processing."""
|
|
311
315
|
|
|
312
316
|
s: int = 0
|
|
313
317
|
nb: int = 0
|
|
314
318
|
det: int = 0
|
|
315
319
|
|
|
316
|
-
def __init__(self):
|
|
320
|
+
def __init__(self) -> None:
|
|
317
321
|
self._sp = 0
|
|
318
322
|
self._sz = 0
|
|
319
323
|
self._r = [0] * 3
|