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