forgot to parse replacement diphones. woops.
This commit is contained in:
+41
-25
@@ -1,4 +1,5 @@
|
||||
import argparse
|
||||
import struct
|
||||
from dataclasses import dataclass, field
|
||||
from io import SEEK_SET
|
||||
from pathlib import Path
|
||||
@@ -20,10 +21,10 @@ def read_str(io: BinaryIO):
|
||||
output_str = ""
|
||||
while True:
|
||||
char = unpack_from("<c", io.read(1))[0]
|
||||
if char == "\x00": # null char at the end of string
|
||||
if char == b"\x00": # null char at the end of string
|
||||
break
|
||||
else:
|
||||
output_str += char
|
||||
output_str += char.decode('latin1')
|
||||
return output_str
|
||||
|
||||
|
||||
@@ -71,8 +72,15 @@ class MbrolaDatabase:
|
||||
silence_phone: str = "_" # silence symbol in the database
|
||||
|
||||
diphone_table: Dict[Diphone, DiphoneInfo] = field(default_factory=dict)
|
||||
remapped_diphones: Dict[Diphone, Diphone] = field(default_factory=dict)
|
||||
pitch_marks: np.ndarray = None
|
||||
|
||||
def __getitem__(self, diph: Diphone):
|
||||
try:
|
||||
return self.diphone_table[diph]
|
||||
except KeyError:
|
||||
return self.diphone_table[self.remapped_diphones[diph]]
|
||||
|
||||
def read_header(self, db_file: BinaryIO):
|
||||
"""Reads the database header"""
|
||||
self.magic_header = db_file.read(6).decode()
|
||||
@@ -113,6 +121,8 @@ class MbrolaDatabase:
|
||||
halfseg=half_segment,
|
||||
pos_pm=position_pm,
|
||||
nb_frame=nb_frames)
|
||||
if (left_phone, right_phone) in self.diphone_table:
|
||||
print((left_phone, right_phone), " already in table")
|
||||
self.diphone_table[(left_phone, right_phone)] = new_diph
|
||||
|
||||
# keep track of the phoneme with the biggest number of frames
|
||||
@@ -120,18 +130,42 @@ class MbrolaDatabase:
|
||||
self.max_frame = nb_wframe
|
||||
i += 1
|
||||
|
||||
# retrieving all phonemes remaps
|
||||
while i < self.nb_diphone:
|
||||
left_phone = read_str(db_file)
|
||||
right_phone = read_str(db_file)
|
||||
repl_diph = (left_phone, right_phone)
|
||||
|
||||
if repl_diph not in self.diphone_table:
|
||||
print(f"({repl_diph[0]}, {repl_diph[1]}) were not present in the database!")
|
||||
continue
|
||||
|
||||
left_phone = read_str(db_file)
|
||||
right_phone = read_str(db_file)
|
||||
remapped_diph = (left_phone, right_phone)
|
||||
|
||||
self.remapped_diphones[remapped_diph] = repl_diph
|
||||
i += 1
|
||||
|
||||
# sanity check
|
||||
assert len(self.diphone_table) + len(self.remapped_diphones) == self.nb_diphone
|
||||
|
||||
|
||||
def read_pitchmarks(self, db_file: BinaryIO):
|
||||
round_size = (self.size_mark + 3) // 4
|
||||
self.pitch_marks = np.array(f"<{round_size}B", db_file.read(round_size))
|
||||
offsets = unpack(f"<{round_size}B", db_file.read(round_size))
|
||||
self.pitch_marks = np.array(offsets)
|
||||
self.raw_offset = db_file.tell()
|
||||
|
||||
def read_info(self, db_file: BinaryIO):
|
||||
db_file.seek(self.raw_offset + self.size_raw, whence=SEEK_SET)
|
||||
db_file.seek(self.raw_offset + self.size_raw, SEEK_SET)
|
||||
self.info = []
|
||||
while True:
|
||||
try:
|
||||
self.info.append(read_str(db_file))
|
||||
except EOFError:
|
||||
s = read_str(db_file)
|
||||
if s:
|
||||
self.info.append(s)
|
||||
except (EOFError, struct.error):
|
||||
break
|
||||
|
||||
def read_database(self):
|
||||
@@ -154,23 +188,5 @@ if __name__ == "__main__":
|
||||
raise ValueError("Can't find database file")
|
||||
|
||||
mbr_db = MbrolaDatabase(db_path=db_path)
|
||||
mbr_db.read_database()
|
||||
|
||||
with open(db_path, "rb") as db_file:
|
||||
# should read "mbrola"
|
||||
mbr_db.magic_header = db_file.read(6).decode()
|
||||
mbr_db.version = db_file.read(5).decode()
|
||||
mbr_db.nb_diphone = unpack_from("<h", db_file)[0]
|
||||
old_size_mark = unpack_from("<H", db_file)[0]
|
||||
if old_size_mark == 0:
|
||||
mbr_db.size_mark = unpack_from("<i", db_file)
|
||||
else:
|
||||
mbr_db.size_mark = old_size_mark
|
||||
mbr_db.size_raw = unpack_from("<i", db_file)
|
||||
mbr_db.freq = unpack_from("<h", db_file)
|
||||
mbr_db.mbr_period = unpack_from("<B", db_file)
|
||||
mbr_db.coding = unpack_from("<B", db_file)
|
||||
|
||||
# TODO:
|
||||
# ReadDatabaseIndex(dba) ||
|
||||
# !ReadDatabasePitchMark(dba) ||
|
||||
# !ReadDatabaseInfo(dba)
|
||||
|
||||
Reference in New Issue
Block a user