Prepping TIMIT for Fairseq (for PSST)
For use with PSST
from datasets import load_dataset, concatenate_datasets
import soundfile as sf
PAD = "<pad>"
UNK = "<unk>"
SIL = "<sil>"
SPN = "<spn>"
VOCAB_ITEMS ="""
AA
AE
AH
AO
AW
AX
AY
EH
ER
EY
IH
IY
OW
OY
UH
UW
UX
B
CH
D
DH
DX
EL
EM
EN
F
G
HH
JH
K
L
M
N
NG
NX
P
Q
R
S
SH
T
TH
V
W
WH
Y
Z
ZH
.
,
?
!
"""
_VOCAB_SPLIT = VOCAB_ITEMS.split("\n")[1:-1]
VOCAB = {e[1]:e[0] for e in enumerate(_VOCAB_SPLIT)}
TIMIT_MAPPING = {
'ax': 'AH',
'ax-h': 'AH',
'axr': 'ER',
'dx': 'T',
'el': ['AH', 'L'],
'em': ['AH', 'M'],
'en': ['AH', 'N'],
'eng': ['IH', 'NG'],
'hv': 'HH',
'ix': 'IH',
'nx': ['N', 'T'],
'pau': '<sil>',
'epi': '<sil>',
'ux': 'UW'
}
TIMIT_IGNORE = ['bcl', 'dcl', 'gcl', 'kcl', 'pcl', 'tcl']
TIMIT_DISCARD = ['dx', 'nx', 'q']
def map_timit_to_cmudict(timit):
output = []
start = 1 if timit[0] == "h#" else 0
end = -1 if timit[-1] == "h#" else None
timit = timit[start:end]
for phone in timit:
if phone in TIMIT_MAPPING:
if type(TIMIT_MAPPING[phone]) == list:
output += TIMIT_MAPPING[phone]
else:
output.append(TIMIT_MAPPING[phone])
elif phone in TIMIT_IGNORE:
pass
else:
if not phone.upper() in VOCAB:
print("Invalid phone", phone.upper())
output.append(phone.upper())
return output
timit = load_dataset('timit_asr')
def is_discardable(batch):
for phoneme in batch["phonetic_detail"]["utterance"]:
if phoneme in TIMIT_DISCARD:
return False
return True
timit_filt = timit["train"].filter(lambda eg: is_discardable(eg))
timit_filt2 = timit["test"].filter(lambda eg: is_discardable(eg))
timit = concatenate_datasets([timit_filt, timit_filt2])
MAX_TOKENS = 1120000
manifest_path = "manifest.tsv"
transcript_path = "transcript"
BASE = timit[0]["file"].split("/data/")[0] + "/data/"
resplit = timit.train_test_split(test_size=0.1)
for split in ["train", "test"]:
fsplit = split
if fsplit == "test":
fsplit = "valid"
with open(f"{fsplit}.tsv", "w") as manifest, open(f"{fsplit}.ltr", "w") as transcript:
manifest.write(BASE + "\n")
for item in resplit[split]:
frames, sr = sf.read(item["file"])
manifest.write(f"{item['file'].replace(BASE, '')}\t{len(frames)}\n")
utt = item['phonetic_detail']['utterance']
mapped = map_timit_to_cmudict(utt)
transcript.write(f"{' '.join(mapped)}\n")