mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-02 00:18:17 +00:00
n-phones comprise monophones, diphones, 3-phones, and more. This algorithm allows for smoother sounding synthesis. Also updates the UI for a new n-phones option and adds/updates scripts related to the arpabet with respect to n-phones.
78 lines
2.1 KiB
Python
Executable File
78 lines
2.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Print a histogram of top monophones, diphones, triphones, and n-phones.
|
|
|
|
from os import path
|
|
import os
|
|
import re
|
|
|
|
DICTIONARY_FILE = '/home/bt/dev/trumpet/dictionary/cmudict-0.7b'
|
|
|
|
def phoneme_dictionary():
|
|
"""
|
|
Read the CMU Word-Phoneme dictionary and extract the phoneme map.
|
|
Returns a map of {word => monophone list}
|
|
"""
|
|
lines = []
|
|
with open(DICTIONARY_FILE) as f:
|
|
lines = f.readlines()
|
|
|
|
lines = [l for l in lines if re.match("^\w+", l)]
|
|
dictionary = {}
|
|
|
|
for l in lines:
|
|
word, *word_phones = l.split()
|
|
dictionary[word] = word_phones
|
|
|
|
return dictionary
|
|
|
|
def get_n_phones(phoneme_list, n):
|
|
"""
|
|
Return a list of n-phones within a phoneme list.
|
|
Returns a list of lists of strings or an empty list.
|
|
"""
|
|
if n < 1 or n > len(phoneme_list):
|
|
return []
|
|
elif n == len(phoneme_list):
|
|
return [phoneme_list[:]]
|
|
else:
|
|
span = len(phoneme_list) - n + 1
|
|
n_phones = []
|
|
for i in range(span):
|
|
n_phone = [phoneme_list[j] for j in range(i, i+n)]
|
|
n_phones.append(n_phone)
|
|
return n_phones
|
|
|
|
def print_histogram(n, print_length = 20):
|
|
"""
|
|
Build and print the histogram for the given size
|
|
"""
|
|
dictionary = phoneme_dictionary()
|
|
n_phone_map = {}
|
|
for word, phoneme in dictionary.items():
|
|
n_phones = get_n_phones(phoneme, n)
|
|
for n_phone in n_phones:
|
|
key = str(n_phone)
|
|
if key not in n_phone_map:
|
|
n_phone_map[key] = []
|
|
n_phone_map[key].append(word)
|
|
|
|
ordered = sorted(n_phone_map.items(), key=lambda x: len(x[1]), reverse=True)
|
|
|
|
title = "MOST FREQUENT {}-PHONES:".format(n)
|
|
print("\n" + title)
|
|
print("="*len(title) + "\n")
|
|
|
|
for it in ordered[0:print_length]:
|
|
line = "{}, {} - eg.{}".format(it[0], len(it[1]), it[1][0])
|
|
print(line)
|
|
|
|
print_histogram(2)
|
|
print_histogram(3)
|
|
print_histogram(4)
|
|
|
|
# Beyond 4-phones, it becomes computationally expensive
|
|
# if we try to guarantee best fit (exponential-time).
|
|
#print_histogram(5)
|
|
#print_histogram(6)
|
|
|