make a sub-mode: speaker info vs spectrogram

This commit is contained in:
Brandon Thomas committed 2020-06-23 05:21:35 -04:00
1 parent 8ed7ffdf23
commit ab6b3dcb96
8 files changed
+197 -58

No files matched your search

+13 -1
View File
@@ -9,11 +9,13 @@ import { TermsComponent } from './modes/terms/TermsComponent';
import { TopNav } from './navigation/TopNav';
import { UsageComponent } from './modes/usage/UsageComponent';
import { Speaker, SPEAKERS } from './Speakers';
import { ExtrasMode } from './modes/speak/extras/ExtrasComponent';
interface Props {}
interface State {
mode: Mode,
extrasMode: ExtrasMode,
speaker: Speaker,
}
@@ -23,6 +25,7 @@ class App extends React.Component<Props, State> {
super(props);
this.state = {
mode: Mode.SPEAK_MODE,
extrasMode: ExtrasMode.SPEAKER_INFO,
speaker: SPEAKERS[0],
};
}
@@ -35,6 +38,10 @@ class App extends React.Component<Props, State> {
this.setState({ mode: Mode.SPEAK_MODE });
}
switchExtrasMode = (extrasMode: ExtrasMode) => {
this.setState({ extrasMode: extrasMode });
}
setSpeaker = (speaker: Speaker) : void => {
this.setState({ speaker: speaker });
}
@@ -52,7 +59,12 @@ class App extends React.Component<Props, State> {
let component;
switch (this.state.mode) {
case Mode.SPEAK_MODE:
component = <SpeakComponent currentSpeaker={this.state.speaker} changeSpeakerCallback={this.setSpeakerBySlug} />;
component = <SpeakComponent
currentSpeaker={this.state.speaker}
changeSpeakerCallback={this.setSpeakerBySlug}
extrasMode={this.state.extrasMode}
changeExtrasModeCallback={this.switchExtrasMode}
/>;
break;
case Mode.USAGE_MODE:
component = <UsageComponent resetModeCallback={this.resetMode} />;
+3 -51
View File
@@ -5,18 +5,7 @@ import { Speaker } from '../../Speakers';
import { createColorMap, linearScale } from "@colormap/core";
//import { VIRIDIS, CIVIDIS, PLASMA, INFERNO, MAGMA, BLACK_WHITE, } from "@colormap/presets";
import { MAGMA } from "@colormap/presets";
class Spectrogram {
pixels: Uint8ClampedArray;
width: number;
height: number;
constructor(pixels: Uint8ClampedArray, width: number, height: number) {
this.pixels = pixels;
this.width = width;
this.height = height;
}
}
import { Spectrogram } from './extras/Spectrogram';
interface Props {
currentSpeaker: Speaker,
@@ -27,12 +16,12 @@ interface Props {
onSpeakErrorCallback: () => void,
onPlayCallback: () => void,
onStopCallback: () => void,
updateSpectrogramCallback: (spectrogram: Spectrogram) => void,
}
interface State {
text: string,
howl?: Howl,
spectrogram?: Spectrogram,
}
class Form extends React.Component<Props, State> {
@@ -149,6 +138,7 @@ class Form extends React.Component<Props, State> {
let bytes = base64ToArrayBuffer(res.spectrogram.bytes_base64);
const spectrogram = new Spectrogram(bytes, res.spectrogram.width, res.spectrogram.height);
this.props.updateSpectrogramCallback(spectrogram);
const sound = new Howl.Howl({
src: [data],
@@ -162,7 +152,6 @@ class Form extends React.Component<Props, State> {
this.setState({
howl: sound,
spectrogram: spectrogram,
});
sound.play();
@@ -219,48 +208,11 @@ class Form extends React.Component<Props, State> {
componentDidMount() {
this.textarea?.focus();
this.updateCanvas();
}
componentDidUpdate() {
this.updateCanvas();
}
updateCanvas() {
const ctx = (this.refs.canvas as any).getContext('2d');
// let width = 300;
// let height = 80;
// ctx.clearRect(0,0, width, height);
if (this.state.spectrogram !== undefined) {
let width = this.state.spectrogram!.width;
let height = this.state.spectrogram!.height;
var image = new ImageData(this.state.spectrogram!.pixels, width, height);
createImageBitmap(image).then(renderer => {
ctx.drawImage(renderer, 0, 0, width * 3, height * 3)
});
}
}
public render() {
let width = 150 * 3;
let height = 80 * 3;
if (this.state.spectrogram !== undefined) {
width = this.state.spectrogram.width * 3;
height = this.state.spectrogram.height * 3;
}
// TODO: This needs to go way up the tree.
let canvas = <canvas ref="canvas" width={width} height={height} id="spectrogram" />
return (
<div>
{canvas}
<form onSubmit={this.handleFormSubmit}>
<textarea
onChange={this.handleTextChange}
+19 -5
View File
@@ -2,9 +2,11 @@ import React from 'react';
import { Form } from './Form';
import { StatusText } from './StatusText';
import { getRandomInt } from '../../Utils';
import { Avatar } from './Avatar';
import { Avatar } from './extras/Avatar';
import { SpeakerDropdown } from './SpeakerDropdown';
import { Speaker } from '../../Speakers';
import { ExtrasComponent, ExtrasMode } from './extras/ExtrasComponent';
import { Spectrogram } from './extras/Spectrogram';
enum StatusState {
NONE,
@@ -14,14 +16,17 @@ enum StatusState {
}
interface Props {
currentSpeaker: Speaker;
currentSpeaker: Speaker,
extrasMode: ExtrasMode,
changeSpeakerCallback: (slug: string) => void,
changeExtrasModeCallback: (extrasMode: ExtrasMode) => void,
}
interface State {
statusState: StatusState;
statusMessage: string,
isTalking: boolean,
currentSpectrogram?: Spectrogram,
}
class SpeakComponent extends React.Component<Props, State> {
@@ -32,6 +37,7 @@ class SpeakComponent extends React.Component<Props, State> {
statusState: StatusState.NONE,
statusMessage: '',
isTalking: false,
currentSpectrogram: undefined,
};
}
@@ -105,6 +111,10 @@ class SpeakComponent extends React.Component<Props, State> {
this.setState({ isTalking: false });
}
updateSpectrogram = (spectrogram: Spectrogram) => {
this.setState({ currentSpectrogram: spectrogram });
}
public render() {
return (
<div>
@@ -114,9 +124,12 @@ class SpeakComponent extends React.Component<Props, State> {
/>
<div>
<Avatar currentSpeaker={this.props.currentSpeaker} />
<p>{this.props.currentSpeaker.getDescription()}</p>
<ExtrasComponent
extrasMode={this.props.extrasMode}
currentSpeaker={this.props.currentSpeaker}
currentSpectrogram={this.state.currentSpectrogram}
changeExtrasModeCallback={this.props.changeExtrasModeCallback}
/>
</div>
<StatusText
@@ -132,6 +145,7 @@ class SpeakComponent extends React.Component<Props, State> {
onSpeakErrorCallback={this.onSpeakError}
onPlayCallback={this.onPlay}
onStopCallback={this.onStop}
updateSpectrogramCallback={this.updateSpectrogram}
/>
</div>
);
@@ -1,5 +1,5 @@
import React from 'react';
import { Speaker } from '../../Speakers';
import { Speaker } from '../../../Speakers';
interface Props {
currentSpeaker: Speaker;
@@ -0,0 +1,52 @@
import React from 'react';
import { Speaker } from '../../../Speakers';
import { SpeakerInfo } from './SpeakerInfo';
import { Spectrogram } from './Spectrogram';
import { SpectrogramComponent } from './SpectrogramComponent';
enum ExtrasMode {
SPEAKER_INFO,
SPECTROGRAM,
}
interface Props {
extrasMode: ExtrasMode,
currentSpeaker: Speaker,
currentSpectrogram?: Spectrogram,
changeExtrasModeCallback: (extrasMode: ExtrasMode) => void,
}
interface State {
}
class ExtrasComponent extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
};
}
public render() {
let modeComponent;
switch (this.props.extrasMode) {
case ExtrasMode.SPEAKER_INFO:
modeComponent = <SpeakerInfo currentSpeaker={this.props.currentSpeaker} />
break;
case ExtrasMode.SPECTROGRAM:
modeComponent = <SpectrogramComponent currentSpectrogram={this.props.currentSpectrogram} />
break;
}
return (
<div>
<div>
<button onClick={() => this.props.changeExtrasModeCallback(ExtrasMode.SPEAKER_INFO)}>Speaker Info</button>
<button onClick={() => this.props.changeExtrasModeCallback(ExtrasMode.SPECTROGRAM)}>Spectrogram</button>
</div>
{modeComponent}
</div>
)
}
}
export { ExtrasComponent, ExtrasMode };
@@ -0,0 +1,29 @@
import React from 'react';
import { Speaker } from '../../../Speakers';
import { Avatar } from './Avatar';
interface Props {
currentSpeaker: Speaker,
}
interface State {
}
class SpeakerInfo extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {};
}
public render() {
return (
<div>
Speaker Info
<Avatar currentSpeaker={this.props.currentSpeaker} />
</div>
)
}
}
export { SpeakerInfo };
@@ -0,0 +1,14 @@
class Spectrogram {
pixels: Uint8ClampedArray;
width: number;
height: number;
constructor(pixels: Uint8ClampedArray, width: number, height: number) {
this.pixels = pixels;
this.width = width;
this.height = height;
}
}
export { Spectrogram };
@@ -0,0 +1,66 @@
import React from 'react';
import { Spectrogram } from './Spectrogram';
interface Props {
currentSpectrogram?: Spectrogram,
}
interface State {
}
class SpectrogramComponent extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
};
}
componentDidMount() {
this.updateCanvas();
}
componentDidUpdate() {
this.updateCanvas();
}
updateCanvas() {
const ctx = (this.refs.canvas as any).getContext('2d');
// let width = 300;
// let height = 80;
// ctx.clearRect(0,0, width, height);
if (this.props.currentSpectrogram !== undefined) {
let width = this.props.currentSpectrogram!.width;
let height = this.props.currentSpectrogram!.height;
var image = new ImageData(this.props.currentSpectrogram!.pixels, width, height);
createImageBitmap(image).then(renderer => {
ctx.drawImage(renderer, 0, 0, width * 3, height * 3)
});
}
}
public render() {
let width = 150 * 3;
let height = 80 * 3;
if (this.props.currentSpectrogram !== undefined) {
width = this.props.currentSpectrogram.width * 3;
height = this.props.currentSpectrogram.height * 3;
}
// TODO: This needs to go way up the tree.
let canvas = <canvas ref="canvas" width={width} height={height} id="spectrogram" />
return (
<div>
{canvas}
</div>
)
}
}
export { SpectrogramComponent };