Read CPU Arpabet dictionary

This commit is contained in:
Brandon Thomas
2016-08-23 03:04:07 -04:00
parent 32a6d5f259
commit ae55dd9514
4 changed files with 113 additions and 8 deletions
+1 -1
View File
@@ -35471,7 +35471,7 @@ DZIUBA JH IY0 UW1 B AH0
DZIUK JH IY0 UW1 K
DZOKHAR JH OW2 K AA1 R
D_C D IY1 S IY1
DÉJÀ D EY2 JH AA1
DEJA D EY2 JH AA1
E IY1
E'S IY1 Z
E-MAIL IY1 M EY2 L
+68
View File
@@ -0,0 +1,68 @@
// Copyright (c) 2016 Brandon Thomas <bt@brand.io, echelon@gmail.com>
use error::Error;
use std::collections::HashMap;
use regex::Regex;
use std::fs::File;
use std::io::BufReader;
use std::io::BufRead;
use std::io::Read;
pub type Word = String;
pub type Phoneme = String;
pub type Polyphone = Vec<Phoneme>;
pub struct ArpabetDictionary {
/// A map of lowercase words to polyphone breakdown (phones are uppercase).
/// eg. 'jungle' -> [JH, AH1, NG, G, AH0, L]
dictionary: HashMap<Word, Polyphone>
}
impl ArpabetDictionary {
/// Read CMU's Arpabet Dictionary.
/// See http://www.speech.cs.cmu.edu/cgi-bin/cmudict
pub fn load_from_file(filename: &str) -> Result<ArpabetDictionary, Error> {
let mut f = try!(File::open(filename));
let mut reader = BufReader::new(f);
let mut map = HashMap::new();
let mut buffer = String::new();
// Format resembles the following,
// ABBREVIATE AH0 B R IY1 V IY0 EY2 T
let re = Regex::new(r"^(\w+)\s+(.*)\n$").unwrap();
while try!(reader.read_line(&mut buffer)) > 0 {
match re.captures(&buffer) {
None => {},
Some(caps) => {
let word_match = caps.at(1);
let phonemes_match = caps.at(2);
if word_match.is_some() && phonemes_match.is_some() {
let word = word_match.unwrap().to_lowercase();
let split = phonemes_match.unwrap().split(" ");
let v1 = split.collect::<Vec<&str>>();
let v2 = v1.iter().map(|s| s.to_string()).collect::<Vec<String>>();
map.insert(word, v2);
}
},
}
buffer.clear();
}
if map.is_empty() {
Err(Error::EmptyFile)
} else {
Ok(ArpabetDictionary { dictionary: map })
}
}
/// Get a polyphone from the dictionary.
pub fn get(&self, word: &str) -> Option<Polyphone> {
self.dictionary.get(word).and_then(|p| {
Some(p.iter().map(|s| s.to_string()).collect::<Vec<String>>())
})
}
}
+22
View File
@@ -0,0 +1,22 @@
// Copyright (c) 2016 Brandon Thomas <bt@brand.io, echelon@gmail.com>
use std::error;
use std::io;
use std::fmt;
use std::convert::From;
#[derive(Debug)]
pub enum Error {
/// The file was empty or did not have parsable contents.
EmptyFile,
/// Wraps an IoError.
IoError { cause: io::Error },
}
impl From<io::Error> for Error {
fn from(error: io::Error) -> Error {
Error::IoError { cause: error }
}
}
+22 -7
View File
@@ -6,6 +6,7 @@ extern crate hound;
extern crate iron;
#[macro_use]
extern crate log;
extern crate regex;
extern crate resolve;
extern crate router;
extern crate rustc_serialize;
@@ -13,26 +14,28 @@ extern crate time;
extern crate toml;
extern crate urlencoded;
pub mod arpabet;
pub mod atom;
pub mod error;
pub mod config;
pub mod dictionary;
pub mod handlers;
pub mod logger;
pub mod words;
use std::path::{Path, PathBuf};
use arpabet::ArpabetDictionary;
use clap::{App, Arg, ArgMatches};
use iron::prelude::*;
use router::Router;
use resolve::hostname;
use config::Config;
use dictionary::VocabularyLibrary;
use handlers::audio_synth_handler::AudioSynthHandler;
use handlers::error_filter::ErrorFilter;
use handlers::file_server_handler::FileServerHandler;
use handlers::vocab_list_handler::VocabListHandler;
use iron::prelude::*;
use logger::SimpleLogger;
use dictionary::VocabularyLibrary;
use resolve::hostname;
use router::Router;
use std::path::{Path, PathBuf};
fn main() {
SimpleLogger::init().unwrap();
@@ -56,6 +59,8 @@ fn main() {
get_hostname();
read_arpabet();
start_server(&config, port);
}
@@ -105,3 +110,13 @@ fn get_hostname() {
let err = unsafe {gethostname (vec::raw::to_mut_ptr(buf) as *mut i8, len as u64)};
if err != 0 { println("oops, gethostname failed"); return; }*/
}
fn read_arpabet() {
// TODO: Configurable path.
let dict = ArpabetDictionary::load_from_file("./dictionary/cmudict-0.7b").unwrap();
let result = dict.get("nintendo");
println!("Result: {:?}", result);
}