Word audio spacing params + handler cleanup

This commit is contained in:
Brandon Thomas committed 2016-09-20 05:19:16 -04:00
1 parent 4ce9909b4e
commit 7e302e7665
6 files changed
+114 -75

No files matched your search

+32 -63
View File
@@ -1,6 +1,7 @@
// Copyright (c) 2015 Brandon Thomas <bt@brand.io>
// TODO: This looks really bad now. Needs cleanup.
use std::collections::HashMap;
use config::Config;
use crypto::digest::Digest;
use crypto::sha1::Sha1;
@@ -43,6 +44,10 @@ const VOLUME_PARAM : &'static str = "vol";
const MONOPHONE_PADDING_START_PARAM : &'static str = "mps";
const MONOPHONE_PADDING_END_PARAM : &'static str = "mpe";
const POLYPHONE_PADDING_END_PARAM : &'static str = "ppe";
const WORD_PADDING_START_PARAM : &'static str = "wps";
const WORD_PADDING_END_PARAM : &'static str = "wpe";
type QueryParams = HashMap<String, Vec<String>>;
/// Represents a request to this endpoint.
#[derive(Clone, Debug)]
@@ -82,6 +87,12 @@ struct SpeakRequest {
/** Padding after a polyphone. */
pub polyphone_padding_end: Option<u16>,
/// Silent padding before a word (not one constructed from phones).
pub word_padding_start: Option<u16>,
/// Silent padding after a word (not one constructed from phones).
pub word_padding_end: Option<u16>,
}
enum SpeakerRequestError {
@@ -249,68 +260,11 @@ impl SpeakRequest {
},
};
let mps : Option<u16> = match map.get(MONOPHONE_PADDING_START_PARAM) {
None => { None },
Some(list) => {
match list.get(0) {
None => { None },
Some(s) => {
match s.trim().parse::<u16>() {
Err(_) => None,
Ok(i) => {
if i == 0 {
None
} else {
Some(i)
}
}
}
},
}
},
};
let mpe : Option<u16> = match map.get(MONOPHONE_PADDING_END_PARAM) {
None => { None },
Some(list) => {
match list.get(0) {
None => { None },
Some(s) => {
match s.trim().parse::<u16>() {
Err(_) => None,
Ok(i) => {
if i == 0 {
None
} else {
Some(i)
}
}
}
},
}
},
};
let ppe : Option<u16> = match map.get(POLYPHONE_PADDING_END_PARAM) {
None => { None },
Some(list) => {
match list.get(0) {
None => { None },
Some(s) => {
match s.trim().parse::<u16>() {
Err(_) => None,
Ok(i) => {
if i == 0 {
None
} else {
Some(i)
}
}
}
},
}
},
};
let mps = get_u16(map, MONOPHONE_PADDING_START_PARAM);
let mpe = get_u16(map, MONOPHONE_PADDING_END_PARAM);
let ppe = get_u16(map, POLYPHONE_PADDING_END_PARAM);
let wps = get_u16(map, WORD_PADDING_START_PARAM);
let wpe = get_u16(map, WORD_PADDING_END_PARAM);
Ok(SpeakRequest {
sentence: sen,
@@ -325,6 +279,8 @@ impl SpeakRequest {
monophone_padding_start: mps,
monophone_padding_end: mpe,
polyphone_padding_end: ppe,
word_padding_start: wps,
word_padding_end: wpe,
})
},
}
@@ -413,7 +369,9 @@ impl AudioSynthHandler {
request.speed,
request.monophone_padding_start,
request.monophone_padding_end,
request.polyphone_padding_end);
request.polyphone_padding_end,
request.word_padding_start,
request.word_padding_end);
match generated {
Err(e) => {
println!("Error synthesizing: {:?}", e);
@@ -475,3 +433,14 @@ impl AudioSynthHandler {
}
}
/** Parse an optional u16 out of query parameters. */
fn get_u16(params: &QueryParams, param_name: &str) -> Option<u16> {
params.get(param_name)
.and_then(|v| v.get(0))
.map(|s| s.trim())
.map(|s| s.parse::<u16>())
.and_then(|res| res.ok())
.and_then(|d| if d == 0 { None } else { Some(d) } )
}
+27 -7
View File
@@ -57,7 +57,9 @@ impl Synthesizer {
speed: Option<f32>,
monophone_padding_start: Option<u16>,
monophone_padding_end: Option<u16>,
polyphone_padding_end: Option<u16>)
polyphone_padding_end: Option<u16>,
word_padding_start: Option<u16>,
word_padding_end: Option<u16>)
-> Result<WavBytes, SynthError> {
let mut words = split_sentence(sentence);
@@ -83,7 +85,9 @@ impl Synthesizer {
if use_words {
word_added = self.concatenate_word(&mut concatenated_waveform,
speaker,
word);
word,
word_padding_start,
word_padding_end);
}
if !word_added && use_n_phones {
@@ -131,17 +135,33 @@ impl Synthesizer {
/// Concatenate a word to the waveform we're building. Returns
/// whether or not the word was successfully found and concatenated.
fn concatenate_word(&self, concatenated_waveform: &mut Vec<i16>,
speaker: &str, word: &str) -> bool {
fn concatenate_word(&self,
concatenated_waveform: &mut Vec<i16>,
speaker: &str,
word: &str,
word_padding_start: Option<u16>,
word_padding_end: Option<u16>) -> bool {
match self.audiobank.get_word(speaker, word) {
None => {
// The word does not exist in the database.
false
},
Some(waveform_data) => {
// The word exists in the database.
if word_padding_start.is_some() {
let pause = generate_pause(word_padding_start.unwrap());
concatenated_waveform.extend(pause);
}
concatenated_waveform.extend(waveform_data);
if word_padding_end.is_some() {
let pause = generate_pause(word_padding_end.unwrap());
concatenated_waveform.extend(pause);
}
true
},
None => {
false
},
}
}
+7 -1
View File
@@ -63,6 +63,8 @@
mps = $('input#monophone_padding_start').val(),
mpe = $('input#monophone_padding_end').val(),
ppe = $('input#polyphone_padding_end').val(),
wps = $('input#word_padding_start').val(),
wpe = $('input#word_padding_end').val(),
query = encodeURIComponent(sentence),
url = '/speak?v=' + speaker
+ '&s=' + query
@@ -71,6 +73,8 @@
+ '&mps=' + mps
+ '&mpe=' + mpe
+ '&ppe=' + ppe
+ '&wps=' + wps
+ '&wpe=' + wpe
+ '&up=' + up
+ '&ud=' + ud
+ '&un=' + un
@@ -90,7 +94,9 @@
ue,
mps,
mpe,
ppe);
ppe,
wps,
wpe);
Sound.play(url);
+4
View File
@@ -25,6 +25,8 @@
mps = Url.getMonophonePaddingStart() || 0,
mpe = Url.getMonophonePaddingEnd() || 0,
ppe = Url.getPolyphonePaddingEnd() || 600,
wps = Url.getWordPaddingStart() || 600,
wpe = Url.getWordPaddingEnd() || 600,
urlPreviousState = false;
if (usePhonemes === null) usePhonemes = true;
@@ -55,6 +57,8 @@
$('input#monophone_padding_start').val(mps);
$('input#monophone_padding_end').val(mpe);
$('input#polyphone_padding_end').val(ppe);
$('input#word_padding_start').val(wps);
$('input#word_padding_end').val(wpe);
Library.load(function(library) { Ui.libraryLoadCallback(library); });
Sound.install();
+32 -3
View File
@@ -34,6 +34,8 @@
_MONOPHONE_PADDING_START_KEY: 'mps',
_MONOPHONE_PADDING_END_KEY: 'mpe',
_POLYPHONE_PADDING_END_KEY: 'ppe',
_WORD_PADDING_START_KEY: 'wps',
_WORD_PADDING_END_KEY: 'wpe',
/** Get the sentence from the `window.location`. */
getSentence: function() {
@@ -157,6 +159,25 @@
}
},
getWordPaddingStart: function() {
var state = this.parseState(window.location);
if (!state || !(this._WORD_PADDING_START_KEY in state)) {
return null;
} else {
return state[this._WORD_PADDING_START_KEY];
}
},
getWordPaddingEnd: function() {
var state = this.parseState(window.location);
if (!state || !(this._WORD_PADDING_END_KEY in state)) {
return null;
} else {
return state[this._WORD_PADDING_END_KEY];
}
},
// TODO: Independent functions to set both speaker and sentence separately.
/** Set the `window.history` speaker, sentence, phoneme use, and word use. */
setState: function(speaker,
@@ -170,7 +191,9 @@
useEnds,
monophonePaddingStart,
monophonePaddingEnd,
polyphonePaddingEnd) {
polyphonePaddingEnd,
wordPaddingStart,
wordPaddingEnd) {
var urlHash = this.fromParams(speaker,
rawSentence,
@@ -183,7 +206,9 @@
useEnds,
monophonePaddingStart,
monophonePaddingEnd,
polyphonePaddingEnd);
polyphonePaddingEnd,
wordPaddingStart,
wordPaddingEnd);
console.log('set state, urlhash = ', urlHash);
window.history.replaceState(null, null, urlHash);
@@ -201,7 +226,9 @@
useEnds,
monophonePaddingStart,
monophonePaddingEnd,
polyphonePaddingEnd) {
polyphonePaddingEnd,
wordPaddingStart,
wordPaddingEnd) {
var cleanedSentence = SentenceHelper.cleanSentence(rawSentence),
cleanedSpeaker = speaker, // TODO: Check against speakers.
@@ -222,6 +249,8 @@
state[this._MONOPHONE_PADDING_START_KEY] = monophonePaddingStart;
state[this._MONOPHONE_PADDING_END_KEY] = monophonePaddingEnd;
state[this._POLYPHONE_PADDING_END_KEY] = polyphonePaddingEnd;
state[this._WORD_PADDING_START_KEY] = wordPaddingStart;
state[this._WORD_PADDING_END_KEY] = wordPaddingEnd;
json = JSON.stringify(state);
+12 -1
View File
@@ -51,7 +51,8 @@
<div>
<input type="checkbox" id="use_ends" name="use_ends"
checked="checked">
<label for="use_ends">Use ends of n-phones (new algorithm)</label>
<label for="use_ends">
Use ends of n-phones (new algorithm)</label>
</div>
</div>
@@ -75,6 +76,16 @@
<label for="polyphone_padding_end">
Polyphone Padding End</label>
</div>
<div>
<input id="word_padding_start" value="">
<label for="word_padding_start">
Word Padding Start</label>
</div>
<div>
<input id="word_padding_end" value="">
<label for="word_padding_end">
Word Padding End</label>
</div>
</div>
</form>