1.1.0版本

This commit is contained in:
xinzhu.yin
2026-04-16 16:51:05 +08:00
commit c157e774e5
333 changed files with 70759 additions and 0 deletions

271
UniTAP/common/audio_mode.py Normal file
View File

@@ -0,0 +1,271 @@
from enum import IntEnum
from UniTAP.common.timestamp import Timestamp
class AudioFileFormat(IntEnum):
"""
Describe all supported audio file formats for saving audio:
- BIN.
- WAV.
"""
UNKNOWN = -1
BIN = 0
WAV = 1
class AudioFormat(IntEnum):
"""
Describe all supported audio formats:
- PCMAudio.
"""
Unknown = -1
L_PCM = 0xFFFF
class AudioMode:
"""
Class `AudioMode` contains part information of audio: sample rate, count of bits and channel count.
"""
def __init__(self, sample_rate: int = 44100, bits: int = 16, channel_count: int = 2):
self.sample_rate = sample_rate
self.bits = bits
self.channel_count = channel_count
def __str__(self):
return f"Sample rate: {self.sample_rate}\n" \
f"Bits: {self.bits}\n" \
f"Channel count: {self.channel_count}\n"
def __eq__(self, other):
return self.sample_rate == other.sample_rate and \
self.bits == other.bits and \
self.channel_count == other.channel_count
def is_valid(self) -> bool:
"""
Check that information is valid (all values more than 0).
Returns:
object of bool type.
"""
return self.sample_rate > 0 and \
self.bits > 0 and \
self.channel_count > 0
class AudioFrameData:
"""
Class `AudioFrameData` describes captured frame from Sink (RX - receiver) side. Contains information of audio:
`AudioMode`, samples, `AudioFormat`, frame counter, `Timestamp`, audio data.
"""
def __init__(self, audio_mode: AudioMode = AudioMode(), samples: int = 0,
sample_format: AudioFormat = AudioFormat.Unknown, frame_counter: int = 0,
timestamp: Timestamp = Timestamp(0), data: bytearray = bytearray()):
self.__audio_mode = audio_mode
self.__samples = samples
self.__sample_format = sample_format
self.__frame_counter = frame_counter
self.__timestamp = timestamp
self.__data = data
@property
def channel_count(self) -> int:
"""
Returns channel count.
Returns:
object of int type.
"""
return self.__audio_mode.channel_count
@property
def samples(self) -> int:
"""
Returns samples.
Returns:
object of int type.
"""
return self.__samples
@property
def sample_size(self) -> int:
"""
Returns sample size.
Returns:
object of int type.
"""
return self.__audio_mode.bits
@property
def sample_rate(self) -> int:
"""
Returns sample rate.
Returns:
object of int type.
"""
return self.__audio_mode.sample_rate
@property
def sample_format(self) -> AudioFormat:
"""
Returns sample format.
Returns:
object of AudioFormat type.
"""
return self.__sample_format
@property
def frame_counter(self) -> int:
"""
Returns frame counter.
Returns:
object of int type.
"""
return self.__frame_counter
@property
def timestamp(self) -> Timestamp:
"""
Returns timestamp.
Returns:
object of Timestamp type.
"""
return self.__timestamp
@property
def data(self) -> bytearray:
"""
Returns data.
Returns:
object of bytearray type.
"""
return self.__data
@channel_count.setter
def channel_count(self, channel_count: int):
"""
Allows setting new value to channel count.
Args:
channel_count (int) - must be more than 0
"""
if channel_count <= 0:
raise ValueError(f"Channel count must be more than 0.")
self.__audio_mode.channel_count = channel_count
@samples.setter
def samples(self, samples: int):
"""
Allows setting new value to samples.
Args:
samples (int) - must be more than 0
"""
if samples <= 0:
raise ValueError(f"Samples must be more than 0.")
self.__samples = samples
@sample_size.setter
def sample_size(self, sample_size: int):
"""
Allows setting new value to sample size.
Args:
sample_size (int) - must be more than 0
"""
if sample_size <= 0:
raise ValueError(f"Sample size must be more than 0.")
self.__audio_mode.bits = sample_size
@sample_rate.setter
def sample_rate(self, sample_rate: int):
"""
Allows setting new value to sample rate.
Args:
sample_rate (int) - must be more than 0
"""
if sample_rate <= 0:
raise ValueError(f"Sample rate must be more than 0.")
self.__audio_mode.sample_rate = sample_rate
@sample_format.setter
def sample_format(self, sample_format: int):
"""
Allows setting new value to sample format.
Args:
sample_format (int) - must be more than 0
"""
if sample_format <= 0:
raise ValueError(f"Sample format must be more than 0.")
self.__sample_format = AudioFormat(sample_format)
@timestamp.setter
def timestamp(self, timestamp: int):
"""
Allows setting new value to timestamp.
Args:
timestamp (int) - must be more than 0
"""
if timestamp <= 0:
raise ValueError(f"Timestamp must be more than 0.")
self.__timestamp.value = timestamp
@frame_counter.setter
def frame_counter(self, frame_counter: int):
"""
Allows setting new value to frame counter.
Args:
frame_counter (int) - must be more than -1
"""
if frame_counter < 0:
raise ValueError(f"Frame counter must be more than 0.")
self.__frame_counter = frame_counter
@data.setter
def data(self, value: bytearray):
"""
Allows setting new value to data.
Args:
value (bytearray) - length of value must be more than 0
"""
if len(value) <= 0:
raise ValueError(f"Audio data length must be more than 0.")
self.__data = value
def __str__(self):
return f"Sample rate: {self.sample_rate}\n" \
f"Bits (Sample size): {self.sample_size}\n" \
f"Channel count: {self.channel_count}\n" \
f"Sample format: {self.sample_format.name}\n" \
f"Timestamp: {self.timestamp.to_n_sec} n sec\n" \
f"Frame counter: {self.frame_counter}\n" \
f"Length of data: {self.data} bytes\n"