cleanup, minor safety improvements

This commit is contained in:
Brandon Thomas committed 2016-08-24 03:25:52 -04:00
1 parent f90fe671ff
commit 9f3b0b8059
7 files changed
+36 -82

No files matched your search

+25 -8
View File
@@ -41,15 +41,14 @@ impl Audiobank {
* Get the wav data for the (speaker,word), or None if it does not exist.
*/
pub fn get_word(&self, speaker: &str, word: &str) -> Option<Vec<i16>> {
println!("Audio Path: {:?}", self.audio_path);
if check_path(speaker).is_err() || check_path(word).is_err() {
return None;
}
let path = self.audio_path.join(format!("{}/", speaker))
.join("_words/")
.join(format!("{}.wav", word));
println!("Path: {:?}", path);
let mut reader = match WavReader::open(path) {
Err(_) => { return None; },
Ok(reader) => reader,
@@ -69,12 +68,14 @@ impl Audiobank {
* Get the wav data for the (speaker,phoneme), or None if it does not exist.
*/
pub fn get_phoneme(&self, speaker: &str, phoneme: &str) -> Option<Vec<i16>> {
if check_path(speaker).is_err() || check_path(phoneme).is_err() {
return None;
}
let path = self.audio_path.join(format!("{}/", speaker))
.join("_phonemes/")
.join(format!("{}.wav", phoneme));
println!("Path: {:?}", path);
let mut reader = match WavReader::open(path) {
Err(_) => { return None; },
Ok(reader) => reader,
@@ -92,14 +93,30 @@ impl Audiobank {
// TODO: This should be removed. We should cache the wav headers.
pub fn get_spec(&self, speaker: &str, word: &str) -> Result<WavSpec, SynthError> {
try!(check_path(speaker));
try!(check_path(word));
let path = self.audio_path.join(format!("{}/", speaker))
.join("_words/")
.join(format!("{}.wav", word));
println!("Path: {:?}", path);
let reader = try!(WavReader::open(path));
Ok(reader.spec())
}
}
fn check_path(path: &str) -> Result<(), SynthError> {
// FIXME: Hack so I can release soon. Rewrite this whole logic plz.
if path.contains("..") ||
path.contains("/") ||
path.contains("$") ||
path.contains("~")
{
Err(SynthError::BadInput { description: "invalid path" })
} else {
Ok(())
}
}
+2 -1
View File
@@ -67,7 +67,8 @@ impl Vocabulary {
pub fn read_from_directory(directory: &Path) ->
Result<Vocabulary, io::Error> {
let paths = try!(fs::read_dir(directory));
let word_directory = directory.join("_words/");
let paths = try!(fs::read_dir(word_directory));
let mut words = Vec::new();
for path in paths {
-51
View File
@@ -226,56 +226,5 @@ impl AudioSynthHandler {
}
Ok(speaker_path)
}
fn get_file_path(&self, speaker_path: &Path, word: &str) -> PathBuf {
speaker_path.join(format!("{}.wav", word))
}
fn get_spec(&self, speaker_path: &Path, word: &str) -> WavSpec {
let filename = self.get_file_path(speaker_path, word);
let reader = WavReader::open(filename).unwrap();
reader.spec()
}
fn write_buffer(&self, spec: &WavSpec, samples: Vec<i16>) -> Vec<u8> {
let mut bytes : Vec<u8> = Vec::new();
let mut seek : Cursor<Vec<u8>> = Cursor::new(bytes);
let mut buffer = BufWriter::new(seek);
{
let mut writer = WavWriter::new(&mut buffer, *spec);
for s in samples {
writer.write_sample(s).unwrap();
}
writer.finalize().unwrap(); // TODO: Error
}
match buffer.into_inner() {
Err(_) => { Vec::new() }, // TODO: Error
Ok(r) => { r.get_ref().to_vec() },
}
}
}
/// Raise the volume of a sample by changing its amplitude.
fn raise_volume(data: i16, volume: Option<f32>) -> i16 {
// TODO: Cleanup, make more efficient.
match volume {
None => data,
Some(vol) => {
let f : f32 = data as f32 * vol;
let g = f as i32;
let h : i16 = if g > i16::MAX as i32 {
i16::MAX
} else if g < i16::MIN as i32 {
i16::MIN
} else {
g as i16
};
h
},
}
}
+3 -7
View File
@@ -5,13 +5,9 @@ use iron::Handler;
use iron::mime::Mime;
use iron::prelude::*;
use iron::status;
use router::Router;
use rustc_serialize::json;
use std::fs::File;
use std::fs;
use std::io::Read;
use std::path::{Path, PathBuf};
use std::path::Path;
use std::path::PathBuf;
#[derive(RustcDecodable, RustcEncodable)]
struct WordsResponse {
@@ -26,7 +22,7 @@ pub struct VocabListHandler {
}
impl Handler for VocabListHandler {
fn handle(&self, req: &mut Request) -> IronResult<Response> {
fn handle(&self, _req: &mut Request) -> IronResult<Response> {
// FIXME: This is inefficient to re-read on every request.
match VocabularyLibrary::read_from_directory(
self.directory.as_path()) {
+1 -1
View File
@@ -37,7 +37,7 @@ use iron::prelude::*;
use logger::SimpleLogger;
use resolve::hostname;
use router::Router;
use std::path::{Path, PathBuf};
use std::path::Path;
use std::sync::Arc;
use std::sync::RwLock;
use synthesizer::Synthesizer;
+4 -13
View File
@@ -2,23 +2,12 @@
use arpabet::ArpabetDictionary;
use audiobank::Audiobank;
use dictionary::Vocabulary;
use dictionary::VocabularyLibrary;
use error::SynthError;
use hound::WavReader;
use hound::WavSpec;
use hound::WavWriter;
use std::error::Error;
use std::fs::File;
use std::fs;
use std::i16;
use std::io::BufReader;
use std::io::BufWriter;
use std::io::Cursor;
use std::io::Read;
use std::io;
use std::path::Path;
use std::path::PathBuf;
use words::split_sentence;
pub type WavBytes = Vec<u8>;
@@ -83,6 +72,8 @@ impl Synthesizer {
continue;
},
Some(polyphone) => {
info!("Word '{}' maps to polyphone '{:?}'", word, polyphone);
for phoneme in polyphone {
match self.audiobank.get_phoneme(speaker, &phoneme) {
None => {
@@ -115,8 +106,8 @@ impl Synthesizer {
}
fn write_buffer(&self, spec: &WavSpec, samples: Vec<i16>) -> Vec<u8> {
let mut bytes : Vec<u8> = Vec::new();
let mut seek : Cursor<Vec<u8>> = Cursor::new(bytes);
let bytes : Vec<u8> = Vec::new();
let seek : Cursor<Vec<u8>> = Cursor::new(bytes);
let mut buffer = BufWriter::new(seek);
{
+1 -1
View File
@@ -3,7 +3,7 @@
/// Split a sentence into words. Remove extra padding, etc.
pub fn split_sentence(sentence: &str) -> Vec<String> {
let mut words = Vec::new();
let mut split = sentence.split(" ");
let split = sentence.split(" ");
// TODO: Keep only \w, '-', '.', and apostrophe.
for s in split {