Files
xinzhu.yin c157e774e5 1.1.0版本
2026-04-16 16:51:05 +08:00

110 lines
3.3 KiB
Python

import os.path
import warnings
import wave
import pickle
from collections import deque
from UniTAP.common.audio_mode import AudioMode, AudioFileFormat
from UniTAP.libs.lib_tsi.tsi import sizeof, c_uint32
def save_to_wave_file(path: str, audio_mode: AudioMode, data: bytearray):
if len(data) <= 0:
raise ValueError(f"Audio data must not be empty! Current size {len(data)}")
file = wave.Wave_write(path + ".wav")
file.setframerate(audio_mode.sample_rate)
file.setnchannels(audio_mode.channel_count)
file.setsampwidth(int(audio_mode.bits / 8))
file.writeframesraw(data)
file.close()
def save_to_bin_file(path: str, data: bytearray):
if len(data) <= 0:
raise ValueError(f"Audio data must not be empty! Current size {len(data)}")
bin_file = open(path + '.bin', 'wb')
bin_file.write(data)
bin_file.close()
def load_from_bin_file(path: str):
file = open(path, "rb")
data = pickle.load(file)
file.close()
return data, AudioMode(), len(data)
def load_from_wave_file(path: str):
try:
data = wave.open(path, 'rb')
except wave.Error:
raise NotImplementedError("Python Wave package doesn't support not PCM formats. Please, use PCM format WAV "
"file.")
channels = 2 if data.getnchannels() <= 2 else 8
size = data.getnframes() * channels * sizeof(c_uint32) + sizeof(c_uint32)
channel_count = data.getnchannels()
sample_rate = data.getframerate()
bits = data.getsampwidth() * 8
bytes_block = data.readframes(size)
data.close()
ret_list = [0] * size
list_of_data = deque(list(bytes_block))
for i in range(0, len(ret_list), (channels * sizeof(c_uint32))):
for j in range(data.getsampwidth() * channel_count):
if len(list_of_data) == 0:
break
idx = i // (channels * sizeof(c_uint32)) * channels * sizeof(c_uint32) + j
chunk_num = j // data.getsampwidth()
addition = chunk_num * data.getsampwidth()
if data.getsampwidth() == 2:
ret_list[idx + addition + 1] = list_of_data.popleft()
else:
ret_list[idx + addition] = list_of_data.popleft()
audio_mode = AudioMode()
audio_mode.channel_count = channel_count
audio_mode.sample_rate = sample_rate
audio_mode.bits = bits
return bytes(ret_list), audio_mode, len(ret_list)
def check_file_format(path: str):
if not os.path.exists(path):
return AudioFileFormat.UNKNOWN
filename, file_extension = os.path.splitext(path)
if file_extension.lower() == 'bin':
return AudioFileFormat.BIN
elif file_extension.lower() not in ["wav", "wave"]:
return AudioFileFormat.WAV
else:
return AudioFileFormat.UNKNOWN
def create_audio_sts(audio_mode: AudioMode):
sts_b = [0] * 48
sts_b[0] = 0
sts_b[0] |= 4
sts_b[24] = sts_b[0]
rate = audio_mode.sample_rate
bits = audio_mode.bits
dict_sample_rate = {22050: 4, 44100: 0, 88200: 8, 176400: 12, 24000: 6, 48000: 2, 96000: 10, 192000: 14,
32000: 3,
768000: 9}
dict_bits = {16: 2, 20: 10, 24: 11}
smpl = dict_sample_rate.get(rate)
sts_b[3] = smpl
sts_b[27] = sts_b[3]
smlen = dict_bits.get(bits)
sts_b[4] = smlen
sts_b[28] = sts_b[4]
return sts_b