1.1.0版本
This commit is contained in:
271
UniTAP/common/audio_mode.py
Normal file
271
UniTAP/common/audio_mode.py
Normal 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"
|
||||
Reference in New Issue
Block a user