components send request state to backend

This commit is contained in:
Brandon Thomas committed 2023-05-18 23:49:56 -07:00
1 parent 73df04bd3a
commit aa4fc620e7
3 files changed
+129 -50

No files matched your search

@@ -35,6 +35,7 @@ import {
import { SessionVoiceConversionResultsList } from "../../../_common/SessionVoiceConversionResultsList";
import { Link } from "react-router-dom";
import PitchShiftComponent from "./components/PitchShiftComponent";
import PitchEstimateMethodComponent from "./components/PitchEstimateMethodComponent";
interface Props {
sessionWrapper: SessionWrapper;
@@ -63,7 +64,6 @@ function VcModelListPage(props: Props) {
const [convertLoading, setConvertLoading] = useState(false);
const [canConvert, setCanConvert] = useState(false);
const [semitones, setSemitones] = useState(0);
const [mediaUploadToken, setMediaUploadToken] = useState<string | undefined>(
undefined
@@ -76,7 +76,7 @@ function VcModelListPage(props: Props) {
const [maybeF0MethodOverride, setMaybeF0MethodOverride] =
useState<EnqueueVoiceConversionFrequencyMethod | undefined>(undefined);
const [maybePitchTranspose, setMaybePitchTranspose] = useState<number>(0);
const [semitones, setSemitones] = useState(0);
// NB: Something of a UI hack here.
// The 3rd party microphone component doesn't let you clear it, so we emulate form clearing
@@ -156,6 +156,14 @@ function VcModelListPage(props: Props) {
source_media_upload_token: mediaUploadToken,
};
if (semitones !== 0) {
request.transpose = semitones;
}
if (maybeF0MethodOverride !== undefined) {
request.override_f0_method = maybeF0MethodOverride;
}
Analytics.voiceConversionGenerate(
props.maybeSelectedVoiceConversionModel.token
);
@@ -178,6 +186,12 @@ function VcModelListPage(props: Props) {
const handlePitchChange = (value: any) => {
setSemitones(value);
changeConvertIdempotencyToken();
};
const handlePitchMethodChange = (value: any) => {
setMaybeF0MethodOverride(value);
changeConvertIdempotencyToken();
};
const speakButtonClass = convertLoading
@@ -296,13 +310,21 @@ function VcModelListPage(props: Props) {
<div>
<label className="sub-title">Pitch Control</label>
<div className="d-flex flex-column gap-3">
<PitchShiftComponent
min={-36}
max={36}
step={1}
value={semitones}
onChange={handlePitchChange}
/>
<div>
<PitchEstimateMethodComponent
pitchMethod={maybeF0MethodOverride}
onMethodChange={handlePitchMethodChange}
/>
</div>
<div>
<PitchShiftComponent
min={-36}
max={36}
step={1}
value={semitones}
onPitchChange={handlePitchChange}
/>
</div>
</div>
</div>
{/*<div>
@@ -377,13 +399,21 @@ function VcModelListPage(props: Props) {
<div>
<label className="sub-title">Pitch Control</label>
<div className="d-flex flex-column gap-3">
<PitchShiftComponent
min={-36}
max={36}
step={1}
value={semitones}
onChange={handlePitchChange}
/>
<div>
<PitchEstimateMethodComponent
pitchMethod={maybeF0MethodOverride}
onMethodChange={handlePitchMethodChange}
/>
</div>
<div>
<PitchShiftComponent
min={-36}
max={36}
step={1}
value={semitones}
onPitchChange={handlePitchChange}
/>
</div>
</div>
</div>
@@ -0,0 +1,77 @@
import React from "react";
import Select from "react-select";
import { EnqueueVoiceConversionFrequencyMethod } from "@storyteller/components/src/api/voice_conversion/EnqueueVoiceConversion";
interface PitchShiftProps {
pitchMethod?: EnqueueVoiceConversionFrequencyMethod,
onMethodChange: (newMethod?: EnqueueVoiceConversionFrequencyMethod) => void;
}
const dropdownFieldClass = {
control: (state: any) =>
state.isFocused
? "select-search no-padding focused rounded"
: "select-search no-padding rounded",
option: (state: any) => (state.isFocused ? "select-option" : "select-option"),
input: (state: any) => (state.isFocused ? "select-input" : "select-input"),
placeholder: (state: any) =>
state.isFocused ? "select-placeholder" : "select-placeholder",
singleValue: (state: any) =>
state.isFocused ? "select-value" : "select-value",
menu: (state: any) =>
state.isFocused ? "select-container" : "select-container",
indicatorSeparator: (state: any) =>
state.isFocused ? "select-separator" : "select-separator",
};
function PitchEstimateMethodComponent(props: PitchShiftProps) {
const handleMethodChange = (option: any, actionMeta: any) => {
const pitchMethodName = option?.value;
let pitchMethod = undefined;
switch (pitchMethodName) {
case "crepe":
pitchMethod = EnqueueVoiceConversionFrequencyMethod.Crepe;
break;
case "harvest":
pitchMethod = EnqueueVoiceConversionFrequencyMethod.Harvest;
break;
case "dio":
pitchMethod = EnqueueVoiceConversionFrequencyMethod.Dio;
break;
}
props.onMethodChange(pitchMethod);
};
interface DropdownOption {
label: string;
value: EnqueueVoiceConversionFrequencyMethod;
}
const options : DropdownOption[] = [
{ label: "CREPE", value: EnqueueVoiceConversionFrequencyMethod.Crepe },
{ label: "Harvest", value: EnqueueVoiceConversionFrequencyMethod.Harvest },
{ label: "DIO", value: EnqueueVoiceConversionFrequencyMethod.Dio },
];
const selectedOption = options.find((option) => option.value === props.pitchMethod) || options[0];
return (
<>
<div>
<Select
value={selectedOption} // Controlled components use "value" instead of "defaultValue".
options={options}
classNames={dropdownFieldClass}
//placeholder={options[0]}
isSearchable={false}
onChange={handleMethodChange}
/>
</div>
</>
);
}
export default PitchEstimateMethodComponent;
@@ -1,6 +1,5 @@
import React from "react";
import { Range } from "react-range";
import Select from "react-select";
import Tippy from "@tippyjs/react";
interface PitchShiftProps {
@@ -8,37 +7,19 @@ interface PitchShiftProps {
max: number;
step: number;
value: number;
onChange: (value: number) => void;
onPitchChange: (value: number) => void;
}
const dropdownFieldClass = {
control: (state: any) =>
state.isFocused
? "select-search no-padding focused rounded"
: "select-search no-padding rounded",
option: (state: any) => (state.isFocused ? "select-option" : "select-option"),
input: (state: any) => (state.isFocused ? "select-input" : "select-input"),
placeholder: (state: any) =>
state.isFocused ? "select-placeholder" : "select-placeholder",
singleValue: (state: any) =>
state.isFocused ? "select-value" : "select-value",
menu: (state: any) =>
state.isFocused ? "select-container" : "select-container",
indicatorSeparator: (state: any) =>
state.isFocused ? "select-separator" : "select-separator",
};
const options = ["CREPE", "Harvest", "DIO"];
function PitchShiftComponent({
min,
max,
step,
value,
onChange,
onPitchChange,
}: PitchShiftProps) {
const handleChange = (newValue: number[]) => {
onChange(newValue[0]);
const handlePitchChange = (newValue: number[]) => {
onPitchChange(newValue[0]);
};
const renderTrack = ({ props, children }: any) => (
@@ -83,15 +64,6 @@ function PitchShiftComponent({
return (
<>
<div>
<Select
value={options[0]} // Controlled components use "value" instead of "defaultValue".
options={options}
classNames={dropdownFieldClass}
placeholder={options[0]}
isSearchable={false}
/>
</div>
<div className="d-flex gap-3 align-items-center">
<div className="flex-grow-1">
<Range
@@ -99,7 +71,7 @@ function PitchShiftComponent({
min={min}
max={max}
values={[value]} // Changed from `values` to `[value]`
onChange={handleChange}
onChange={handlePitchChange}
renderTrack={renderTrack}
renderThumb={renderThumb}
/>