diff --git a/vocodes/src/model/Speakers.ts b/vocodes/src/model/Speakers.ts index e8bb980831..ab7070e488 100644 --- a/vocodes/src/model/Speakers.ts +++ b/vocodes/src/model/Speakers.ts @@ -77,7 +77,7 @@ const SPEAKERS : Speaker[] = [ voiceQuality: 7.6, }), Speaker.fromJson({ - name: "Bill Gates (needs work)", + name: "Bill Gates", slug: "bill-gates", description: "Microsoft.", avatarUrl: "bill-gates.jpg", diff --git a/vocodes/src/model/utterance.ts b/vocodes/src/model/utterance.ts index 3987bac74b..728d444e9d 100644 --- a/vocodes/src/model/utterance.ts +++ b/vocodes/src/model/utterance.ts @@ -7,14 +7,23 @@ class Utterance { originalText: string; speaker: Speaker; howl: Howl; - base64data: string; + base64data?: string; + audioUrl?: string - constructor(originalText: string, speaker: Speaker, howl: Howl, base64data: string) { + constructor(originalText: string, speaker: Speaker, howl: Howl, base64data?: string, audioUrl?: string) { this.id = Utterance.counter++; this.originalText = originalText; this.speaker = speaker; this.howl = howl; this.base64data = base64data; + this.audioUrl = audioUrl; + } + + public getUrl(): string { + if (this.audioUrl !== undefined) { + return this.audioUrl; + } + return `data:audio/wav;base64,${this.base64data}`; } } diff --git a/vocodes/src/modes/history/PastUtterance.tsx b/vocodes/src/modes/history/PastUtterance.tsx index 2d0d6fd89a..0fcae6c5b5 100644 --- a/vocodes/src/modes/history/PastUtterance.tsx +++ b/vocodes/src/modes/history/PastUtterance.tsx @@ -22,7 +22,6 @@ class PastUtterance extends React.Component { } public render() { - let url = `data:audio/wav;base64,${this.props.utterance.base64data}`; let number = this.props.utterance.id + 1; let filename = `vocodes_${this.props.utterance.speaker.slug}_${number}.wav`; @@ -48,7 +47,9 @@ class PastUtterance extends React.Component {
- Download + Download
diff --git a/vocodes/src/modes/speak/Form.tsx b/vocodes/src/modes/speak/Form.tsx index 44d3a0eb6e..7dcfe490e3 100644 --- a/vocodes/src/modes/speak/Form.tsx +++ b/vocodes/src/modes/speak/Form.tsx @@ -12,6 +12,7 @@ interface Props { currentSpeaker: Speaker, spectrogramMode: SpectrogramMode, currentText: string, + enableSpectrograms: boolean, clearStatusCallback: () => void, setHintMessage: (message: string) => void, onSpeakRequestCallback: () => void, @@ -42,11 +43,19 @@ class Form extends React.Component { console.log("Making SpeakRequest:", request); + this.props.onSpeakRequestCallback(); + + if (this.props.enableSpectrograms) { + this.speakWithSpectrogram(sentence, speaker, request); + } else { + this.speakWithoutSpectrogram(sentence, speaker, request); + } + } + + speakWithSpectrogram(sentence: string, speaker: Speaker, request: SpeakRequest) { //const url = this.props.apiConfig.getEndpoint('/speak_spectrogram'); const url = 'https://mumble.stream/speak_spectrogram'; - this.props.onSpeakRequestCallback(); - fetch(url, { method: 'POST', headers: { @@ -112,7 +121,47 @@ class Form extends React.Component { sound.play(); - const utterance = new Utterance(sentence, speaker, sound, res.audio_base64); + const utterance = new Utterance(sentence, speaker, sound, res.audio_base64, undefined); + this.props.appendUtteranceCallback(utterance); + + (window as any).sound = sound; + }) + .catch(e => { + this.props.onSpeakErrorCallback(); + }); + } + + speakWithoutSpectrogram(sentence: string, speaker: Speaker, request: SpeakRequest) { + //const url = this.props.apiConfig.getEndpoint('/speak_spectrogram'); + const url = 'https://mumble.stream/speak'; + + fetch(url, { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify(request), + }) + .then(res => res.blob()) + .then(blob => { + const audioUrl = window.URL.createObjectURL(blob); + //console.log(url); + + const sound = new Howl.Howl({ + src: [audioUrl], + format: 'wav', + // NB: Attempting to get this working on iPhone Safari + // https://github.com/goldfire/howler.js/issues/1093 + // Other issues cite needing to cache a single player + // across all user interaction events. + html5: true, + }); + + this.setState({howl: sound}); + sound.play(); + + const utterance = new Utterance(sentence, speaker, sound, undefined, audioUrl); this.props.appendUtteranceCallback(utterance); (window as any).sound = sound; diff --git a/vocodes/src/modes/speak/SpeakComponent.tsx b/vocodes/src/modes/speak/SpeakComponent.tsx index aae944da53..3c44aa6a8c 100644 --- a/vocodes/src/modes/speak/SpeakComponent.tsx +++ b/vocodes/src/modes/speak/SpeakComponent.tsx @@ -252,6 +252,7 @@ class SpeakComponent extends React.Component { clearStatusCallback={this.clearMessage} setHintMessage={this.setHintMessage} spectrogramMode={this.props.spectrogramMode} + enableSpectrograms={this.props.enableSpectrograms} onSpeakRequestCallback={this.onSpeakRequest} onSpeakSuccessCallback={this.onSpeakSuccess} onSpeakErrorCallback={this.onSpeakError}