mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 01:18:34 +00:00
make a sub-mode: speaker info vs spectrogram
This commit is contained in:
1 parent
8ed7ffdf23
commit
ab6b3dcb96
8 files changed
+197
-58
No files matched your search
+13
-1
@@ -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} />;
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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 };
|
||||
Reference in new issue
Block a user