NAM A2 Calibration

This commit is contained in:
Robin E.R. Davies
2026-05-13 11:22:42 -04:00
parent c456e5187b
commit 7343ced278
13 changed files with 243 additions and 72 deletions
+3 -1
View File
@@ -33,7 +33,9 @@
"logLevel": 3, "logLevel": 3,
/* Maximum filesize to allow when uploading */ /* Maximum filesize to allow when uploading */
"maxUploadSize": 536870912 // 512MiB "maxUploadSize": 536870912, // 512MiB
/* false-> Download A1 models; true -> Download A2 models */
"tone3000A2Models": true
} }
+1
View File
@@ -101,6 +101,7 @@ JSON_MAP_REFERENCE(PiPedalConfiguration, threads)
JSON_MAP_REFERENCE(PiPedalConfiguration, logLevel) JSON_MAP_REFERENCE(PiPedalConfiguration, logLevel)
JSON_MAP_REFERENCE(PiPedalConfiguration, logHttpRequests) JSON_MAP_REFERENCE(PiPedalConfiguration, logHttpRequests)
JSON_MAP_REFERENCE(PiPedalConfiguration, maxUploadSize) JSON_MAP_REFERENCE(PiPedalConfiguration, maxUploadSize)
JSON_MAP_REFERENCE(PiPedalConfiguration, tone3000A2Models)
JSON_MAP_REFERENCE(PiPedalConfiguration, accessPointGateway) JSON_MAP_REFERENCE(PiPedalConfiguration, accessPointGateway)
JSON_MAP_REFERENCE(PiPedalConfiguration, accessPointServerAddress) JSON_MAP_REFERENCE(PiPedalConfiguration, accessPointServerAddress)
JSON_MAP_REFERENCE(PiPedalConfiguration, isVst3Enabled) JSON_MAP_REFERENCE(PiPedalConfiguration, isVst3Enabled)
+2
View File
@@ -45,6 +45,7 @@ private:
bool logHttpRequests_ = false; bool logHttpRequests_ = false;
int logLevel_ = 0; int logLevel_ = 0;
uint64_t maxUploadSize_ = 1024*1024; uint64_t maxUploadSize_ = 1024*1024;
bool tone3000A2Models_ = true;
std::string accessPointGateway_; std::string accessPointGateway_;
std::string accessPointServerAddress_; std::string accessPointServerAddress_;
bool isVst3Enabled_ = true; bool isVst3Enabled_ = true;
@@ -67,6 +68,7 @@ public:
bool GetMLock() const { return mlock_; } bool GetMLock() const { return mlock_; }
uint64_t GetMaxUploadSize() const { return maxUploadSize_; } uint64_t GetMaxUploadSize() const { return maxUploadSize_; }
bool GetTone3000A2Models() const { return tone3000A2Models_; }
LogLevel GetLogLevel() const { return (LogLevel)this->logLevel_; } LogLevel GetLogLevel() const { return (LogLevel)this->logLevel_; }
bool LogHttpRequests() const { return this->logHttpRequests_; } bool LogHttpRequests() const { return this->logHttpRequests_; }
+2
View File
@@ -364,6 +364,8 @@ namespace pipedal
void Init(const PiPedalConfiguration &configuration); void Init(const PiPedalConfiguration &configuration);
const PiPedalConfiguration &Configuration() const { return configuration; }
void LoadLv2PluginInfo(); void LoadLv2PluginInfo();
void Load(); void Load();
+5 -2
View File
@@ -1315,12 +1315,14 @@ static std::string StripPortNumber(const std::string &fromAddress)
class InterceptConfig : public RequestHandler class InterceptConfig : public RequestHandler
{ {
private: private:
PiPedalModel&model;
uint64_t maxUploadSize; uint64_t maxUploadSize;
int portNumber; int portNumber;
public: public:
InterceptConfig(int portNumber, uint64_t maxUploadSize) InterceptConfig(PiPedalModel&model,int portNumber, uint64_t maxUploadSize)
: RequestHandler("/var/config.json"), : RequestHandler("/var/config.json"),
model(model),
maxUploadSize(maxUploadSize), maxUploadSize(maxUploadSize),
portNumber(portNumber) portNumber(portNumber)
{ {
@@ -1337,6 +1339,7 @@ public:
<< "\", \"ui_plugins\": [ ], \"max_upload_size\": " << maxUploadSize << "\", \"ui_plugins\": [ ], \"max_upload_size\": " << maxUploadSize
<< ", \"enable_auto_update\": " << (ENABLE_AUTO_UPDATE ? " true" : "false") << ", \"enable_auto_update\": " << (ENABLE_AUTO_UPDATE ? " true" : "false")
<< ", \"has_wifi_device\": " << (HotspotManager::HasWifiDevice() ? " true" : "false") << ", \"has_wifi_device\": " << (HotspotManager::HasWifiDevice() ? " true" : "false")
<< ", \"tone3000_A2_models\": " << (model.Configuration().GetTone3000A2Models() ? " true" : "false")
<< " }"; << " }";
return s.str(); return s.str();
@@ -1396,7 +1399,7 @@ void pipedal::ConfigureWebServer(
int port, int port,
size_t maxUploadSize) size_t maxUploadSize)
{ {
std::shared_ptr<RequestHandler> interceptConfig{new InterceptConfig(port, maxUploadSize)}; std::shared_ptr<RequestHandler> interceptConfig{new InterceptConfig(model,port, maxUploadSize)};
server.AddRequestHandler(interceptConfig); server.AddRequestHandler(interceptConfig);
std::shared_ptr<DownloadIntercept> downloadIntercept = std::make_shared<DownloadIntercept>(&model); std::shared_ptr<DownloadIntercept> downloadIntercept = std::make_shared<DownloadIntercept>(&model);
+14 -1
View File
@@ -1,4 +1,17 @@
Benchmark Results: A2 Questions
Does A2 support Callibration?
input_level_dbu, output_level_dbu accessors on NeuralAmpModelerCore DSP
slimmable_weights accessors on NeuralAmpModelerCore DSP
standard values for slimmable_weights?
Implement NAM Model Weight selection UI
NAM INput VU is f*ed up.
File Player Underrun is NOT CPU use related. There's an underrun somewhere.
Update Pi 4 Benchmark Results:
The benchmark is to run TooB Neural Amp Modeler with an A1 model to generate 100s of audio. Lower times are better. The benchmark is to run TooB Neural Amp Modeler with an A1 model to generate 100s of audio. Lower times are better.
+3 -1
View File
@@ -6,5 +6,7 @@
"fakeAndroid": false, "fakeAndroid": false,
"ui_plugins": [], "ui_plugins": [],
"enable_auto_update": true, "enable_auto_update": true,
"has_wifi_device": false "has_wifi_device": false,
"tone3000_A2_models": true,
"end": true
} }
+1 -1
View File
@@ -949,7 +949,7 @@ export class UiControl implements Deserializable<UiControl> {
return scale_point.label; return scale_point.label;
} }
} }
return "#invalid"; return value.toString();
} else if (this.integer_property) { } else if (this.integer_property) {
return value.toFixed(0); return value.toFixed(0);
} else { } else {
+2
View File
@@ -1316,6 +1316,7 @@ export class PiPedalModel //implements PiPedalModel
maxFileUploadSize: number = 512 * 1024 * 1024; maxFileUploadSize: number = 512 * 1024 * 1024;
maxPresetUploadSize: number = 1024 * 1024; maxPresetUploadSize: number = 1024 * 1024;
debug: boolean = false; debug: boolean = false;
tone3000_A2_models: boolean = true;
enableAutoUpdate: boolean = false; enableAutoUpdate: boolean = false;
@@ -1326,6 +1327,7 @@ export class PiPedalModel //implements PiPedalModel
let response: Response = await fetch(myRequest); let response: Response = await fetch(myRequest);
let data = await response.json(); let data = await response.json();
this.tone3000_A2_models = data.tone3000_A2_models ?? true;
this.enableAutoUpdate = !!data.enable_auto_update; this.enableAutoUpdate = !!data.enable_auto_update;
this.hasWifiDevice.set(!!data.has_wifi_device); this.hasWifiDevice.set(!!data.has_wifi_device);
if (data.max_upload_size) { if (data.max_upload_size) {
+60
View File
@@ -154,6 +154,66 @@ export type PluginControlState = {
previewValue?: string; previewValue?: string;
}; };
export interface CustomPluginControlProps extends WithStyles<typeof pluginControlStyles> {
title: string;
isSelect?: boolean;
isButton?: boolean;
item_width?: number;
mainControl: React.ReactNode;
editControl?: React.ReactNode;
};
export interface CustomPluginControlState {
};
const CustomPluginControl =
withStyles(
class extends Component<CustomPluginControlProps, CustomPluginControlState> {
constructor(props: CustomPluginControlProps) {
super(props);
}
render() {
let classes = withStyles.getClasses(this.props);
return (
<div
className={classes.controlFrame}
style={{ width: this.props.item_width }}
>
{/* TITLE SECTION */}
<div className={classes.titleSection}
style={
{
alignSelf: "stretch", marginBottom: 8, marginLeft: this.props.isSelect ? 8 : 0, marginRight: 0
}}>
<Typography variant="caption" display="block" noWrap style={{
width: "100%",
textAlign: this.props.isSelect ? "left" : "center"
}}> {this.props.isButton ? "\u00A0" : this.props.title}</Typography>
</div>
{/* CONTROL SECTION */}
<div className={classes.midSection}>
{this.props.mainControl}
</div>
{/* LABEL/EDIT SECTION*/}
<div className={classes.editSection} >
{this.props.editControl}
</div>
</div>
);
return (<div />);
}
},
pluginControlStyles
);
export { CustomPluginControl };
const PluginControl = const PluginControl =
withTheme(withStyles( withTheme(withStyles(
class extends Component<PluginControlProps, PluginControlState> { class extends Component<PluginControlProps, PluginControlState> {
+9 -2
View File
@@ -38,7 +38,7 @@ import { UiPlugin, UiControl, UiFileProperty, UiFrequencyPlot, ScalePoint } from
import { import {
Pedalboard, PedalboardItem, ControlValue Pedalboard, PedalboardItem, ControlValue
} from './Pedalboard'; } from './Pedalboard';
import PluginControl from './PluginControl'; import PluginControl, {CustomPluginControl} from './PluginControl';
import ResizeResponsiveComponent from './ResizeResponsiveComponent'; import ResizeResponsiveComponent from './ResizeResponsiveComponent';
import SideChainSelectControl, { SideChainSelectDialog } from './SideChainSelectControl'; import SideChainSelectControl, { SideChainSelectDialog } from './SideChainSelectControl';
import VuMeter from './VuMeter'; import VuMeter from './VuMeter';
@@ -66,6 +66,7 @@ const LANDSCAPE_HEIGHT_BREAK = 500;
export interface ICustomizationHost { export interface ICustomizationHost {
makeStandardControl(uiControl: UiControl, controlValues: ControlValue[]): ReactNode; makeStandardControl(uiControl: UiControl, controlValues: ControlValue[]): ReactNode;
makeCustomControl(title: string, mainControl: ReactNode, editControl?: ReactNode): ReactNode;
renderControlGroup(controlGroup: ControlGroup, key: string): ReactNode; renderControlGroup(controlGroup: ControlGroup, key: string): ReactNode;
isLandscapeGrid(): boolean; isLandscapeGrid(): boolean;
} }
@@ -379,6 +380,7 @@ type PluginControlViewState = {
sidechainDialogOpen: boolean sidechainDialogOpen: boolean
}; };
const PluginControlView = const PluginControlView =
withTheme(withStyles( withTheme(withStyles(
class extends ResizeResponsiveComponent<PluginControlViewProps, PluginControlViewState> { class extends ResizeResponsiveComponent<PluginControlViewProps, PluginControlViewState> {
@@ -495,6 +497,7 @@ const PluginControlView =
} }
private ixKey: number = 1; private ixKey: number = 1;
makeStandardControl(uiControl: UiControl, controlValues: ControlValue[]): ReactNode { makeStandardControl(uiControl: UiControl, controlValues: ControlValue[]): ReactNode {
let symbol = uiControl.symbol; let symbol = uiControl.symbol;
if (!uiControl.is_input) { if (!uiControl.is_input) {
@@ -963,7 +966,9 @@ const PluginControlView =
) )
} }
makeCustomControl(title: string, mainControl: ReactNode, editControl?: ReactNode): ReactNode {
return (<CustomPluginControl title={title} mainControl={mainControl} editControl={editControl} />);
}
renderPiPedalControl(pedalboardItem?: PedalboardItem): ReactNode { renderPiPedalControl(pedalboardItem?: PedalboardItem): ReactNode {
this.controlKeyIndex = 0; this.controlKeyIndex = 0;
@@ -1142,3 +1147,5 @@ const PluginControlView =
export default PluginControlView; export default PluginControlView;
+2 -7
View File
@@ -28,7 +28,6 @@ const THROTTLING_TRIGGGER_LEVEL = Math.floor(ALLOWED_DOWNLOADS_PER_MINUTE/2);
class DownloadThrottler { class DownloadThrottler {
private throttleActive: boolean = false;
private fifo: number[] = []; private fifo: number[] = [];
private downloadCount: number = 0; private downloadCount: number = 0;
@@ -39,11 +38,7 @@ class DownloadThrottler {
this.fifo.shift(); this.fifo.shift();
} }
if (this.fifo.length > THROTTLING_TRIGGGER_LEVEL) { this.downloadCount = this.fifo.length;
this.throttleActive = true;
} else {
this.throttleActive = false;
}
} }
getThrottleDelay(now : number = Date.now()): number { getThrottleDelay(now : number = Date.now()): number {
while (this.fifo.length > 0 && this.fifo[0] + 60000 <= now) { while (this.fifo.length > 0 && this.fifo[0] + 60000 <= now) {
@@ -264,7 +259,7 @@ export class Tone3000DownloadHandler {
let models: Model[] = []; let models: Model[] = [];
let architectureFilter: number | undefined = undefined; let architectureFilter: number | undefined = undefined;
// Take A2 models only for NAM downloads, and only if the tone actually has A2 models. // Take A2 models only for NAM downloads, and only if the tone actually has A2 models.
if (downloadType === Tone3000DownloadType.Nam && !!tone.a2_models_count) { if (downloadType === Tone3000DownloadType.Nam && !!tone.a2_models_count && this.model.tone3000_A2_models) {
architectureFilter = 2; // NAM models only architectureFilter = 2; // NAM models only
} }
+102 -20
View File
@@ -30,11 +30,17 @@ import { PiPedalModelFactory, PiPedalModel, ListenHandle, State } from "./PiPeda
import { PedalboardItem, ControlValue } from './Pedalboard'; import { PedalboardItem, ControlValue } from './Pedalboard';
import PluginControlView, { ICustomizationHost, ControlGroup, ControlViewCustomization } from './PluginControlView'; import PluginControlView, { ICustomizationHost, ControlGroup, ControlViewCustomization } from './PluginControlView';
import { UiPlugin, UiControl, ControlType } from './Lv2Plugin'; import { UiPlugin, UiControl, ControlType } from './Lv2Plugin';
import Select from '@mui/material/Select/Select';
import MenuItem from '@mui/material/MenuItem/MenuItem';
import { CustomPluginControl } from './PluginControl';
const TOOB_NAM__MODEL_METADATA = "http://two-play.com/plugins/toob-nam#model_metadata"; const TOOB_NAM__MODEL_METADATA_URI = "http://two-play.com/plugins/toob-nam#model_metadata";
const TOOB_NAM__MODEL_WEIGHT_URI = "http://two-play.com/plugins/toob-nam#modelWeight";
// offset 0: an integer with the folloing bits set. // offset 0: an integer with the folloing bits set.
// Must match ToobAmp/src/NeuralAmpModeler_Lv2Extensions.hpp enum TOOB_NAM_METADATA_OFFSETS
const MAX_SLIMMABLE_WEIGHTS = 16;
class TOOB_NAM_METADATA_OFFSETS { class TOOB_NAM_METADATA_OFFSETS {
static readonly flags = 0; static readonly flags = 0;
static readonly preset_version = 1; static readonly preset_version = 1;
@@ -42,7 +48,11 @@ class TOOB_NAM_METADATA_OFFSETS {
static readonly gain = 3; static readonly gain = 3;
static readonly input_level_dbu = 4; static readonly input_level_dbu = 4;
static readonly output_level_dbu = 5; static readonly output_level_dbu = 5;
static readonly max_medatadata = 6; static readonly is_a2 = 6;
static readonly model_weight = 7;
static readonly slimmable_weights_size = 8;
static readonly slimmable_weights = 9;
static readonly max_medatadata = TOOB_NAM_METADATA_OFFSETS.slimmable_weights + MAX_SLIMMABLE_WEIGHTS;
}; };
@@ -55,8 +65,7 @@ class TOOB_NAM_METADATA_FLAGS {
}; };
class ModelMetadata { class ModelMetadata {
constructor(metadataValues?: number[]) constructor(metadataValues?: number[]) {
{
if (metadataValues) { if (metadataValues) {
@@ -72,6 +81,12 @@ class ModelMetadata {
this.inputlevelDBU = metadataValues[TOOB_NAM_METADATA_OFFSETS.input_level_dbu]; this.inputlevelDBU = metadataValues[TOOB_NAM_METADATA_OFFSETS.input_level_dbu];
this.outputlevelDBU = metadataValues[TOOB_NAM_METADATA_OFFSETS.output_level_dbu]; this.outputlevelDBU = metadataValues[TOOB_NAM_METADATA_OFFSETS.output_level_dbu];
this.preset_version = metadataValues[TOOB_NAM_METADATA_OFFSETS.preset_version]; this.preset_version = metadataValues[TOOB_NAM_METADATA_OFFSETS.preset_version];
this.isA2 = metadataValues[TOOB_NAM_METADATA_OFFSETS.is_a2] !== 0;
this.modelWeight = metadataValues[TOOB_NAM_METADATA_OFFSETS.model_weight];
let slimmableWeightsSize = metadataValues[TOOB_NAM_METADATA_OFFSETS.slimmable_weights_size];
for (let i = 0; i < slimmableWeightsSize && i < 16; ++i) {
this.slimmable_weights.push(metadataValues[TOOB_NAM_METADATA_OFFSETS.slimmable_weights + i]);
}
} else { } else {
this.hasModel = false; this.hasModel = false;
this.hasLoudness = false; this.hasLoudness = false;
@@ -84,11 +99,16 @@ class ModelMetadata {
this.inputlevelDBU = 0; this.inputlevelDBU = 0;
this.outputlevelDBU = 0; this.outputlevelDBU = 0;
this.preset_version = 1; this.preset_version = 1;
this.modelWeight = -1;
this.isA2 = false;
this.slimmable_weights = [];
} }
} }
preset_version: number; preset_version: number;
isA2: boolean = false;
modelWeight: number = 1.0;
slimmable_weights: number[] = [];
hasModel: boolean; hasModel: boolean;
hasLoudness: boolean; hasLoudness: boolean;
hasGain: boolean; hasGain: boolean;
@@ -100,6 +120,10 @@ class ModelMetadata {
inputlevelDBU: number; inputlevelDBU: number;
outputlevelDBU: number; outputlevelDBU: number;
hasSlimmableWeights(): boolean {
return this.slimmable_weights.length > 0;
}
} }
@@ -114,8 +138,10 @@ interface ToobNamViewProps extends WithStyles<typeof styles> {
interface ToobNamViewState { interface ToobNamViewState {
showEqSection: boolean; showEqSection: boolean;
enableCalibration: boolean; enableCalibration: boolean;
showCalibration: boolean;
enableOutputNormalization: boolean; enableOutputNormalization: boolean;
modelMetadata: ModelMetadata; modelMetadata: ModelMetadata;
modelWeight: number,
} }
const ToobNamView = const ToobNamView =
@@ -133,18 +159,18 @@ const ToobNamView =
this.model = PiPedalModelFactory.getInstance(); this.model = PiPedalModelFactory.getInstance();
this.state = { this.state = {
showEqSection: false, showEqSection: false,
showCalibration: false,
enableCalibration: false, enableCalibration: false,
enableOutputNormalization: false, enableOutputNormalization: false,
modelMetadata: new ModelMetadata() modelMetadata: new ModelMetadata(),
modelWeight: -1
} }
let pluginInfo: UiPlugin | null = this.model.getUiPlugin(this.props.item.uri); let pluginInfo: UiPlugin | null = this.model.getUiPlugin(this.props.item.uri);
if (pluginInfo === null) if (pluginInfo === null) {
{
throw new Error("Plugin not fouund."); throw new Error("Plugin not fouund.");
} }
let inputCalibrationControl = pluginInfo.getControl("inputCalibrationMode"); let inputCalibrationControl = pluginInfo.getControl("inputCalibrationMode");
if (!inputCalibrationControl) if (!inputCalibrationControl) {
{
throw new Error("Control not found."); throw new Error("Control not found.");
} }
let patchedInputControl = new UiControl().deserialize(inputCalibrationControl); let patchedInputControl = new UiControl().deserialize(inputCalibrationControl);
@@ -152,8 +178,7 @@ const ToobNamView =
this.patchedInputControl = patchedInputControl this.patchedInputControl = patchedInputControl
let outputCalibrationControl = pluginInfo.getControl("outputCalibration"); let outputCalibrationControl = pluginInfo.getControl("outputCalibration");
if (!outputCalibrationControl) if (!outputCalibrationControl) {
{
throw new Error("Control not found."); throw new Error("Control not found.");
} }
let patchedOutputControl = new UiControl().deserialize(outputCalibrationControl); let patchedOutputControl = new UiControl().deserialize(outputCalibrationControl);
@@ -189,14 +214,18 @@ const ToobNamView =
modifyControls(host: ICustomizationHost, controls: (React.ReactNode | ControlGroup)[]): (React.ReactNode | ControlGroup)[] { modifyControls(host: ICustomizationHost, controls: (React.ReactNode | ControlGroup)[]): (React.ReactNode | ControlGroup)[] {
let EqPos = 7; let EqPos = 7;
let CalibrationGroupPos = 8; const CalibrationGroupPos = 8;
const ModelSizeControlPos = 9;
const ModelWeightControlPos = 10;
let calibrationGroup = controls[CalibrationGroupPos] as ControlGroup; let calibrationGroup = controls[CalibrationGroupPos] as ControlGroup;
if (this.state.showCalibration) {
calibrationGroup.controls[0] = host.makeStandardControl(this.patchedInputControl, this.props.item.controlValues); calibrationGroup.controls[0] = host.makeStandardControl(this.patchedInputControl, this.props.item.controlValues);
if (this.state.enableCalibration) if (this.state.enableCalibration) {
{
calibrationGroup.controls[0] = host.makeStandardControl(this.patchedInputControl, this.props.item.controlValues); calibrationGroup.controls[0] = host.makeStandardControl(this.patchedInputControl, this.props.item.controlValues);
} else { } else {
@@ -206,8 +235,7 @@ const ToobNamView =
calibrationGroup.controls[0] = this.disableControl(calibrationGroup.controls[0], "cg_01d"); calibrationGroup.controls[0] = this.disableControl(calibrationGroup.controls[0], "cg_01d");
calibrationGroup.controls[1] = this.disableControl(calibrationGroup.controls[1], "cg_02d"); calibrationGroup.controls[1] = this.disableControl(calibrationGroup.controls[1], "cg_02d");
if (this.state.enableOutputNormalization) if (this.state.enableOutputNormalization) {
{
calibrationGroup.controls[2] = host.makeStandardControl(this.noCalibrationOutputControl, this.props.item.controlValues); calibrationGroup.controls[2] = host.makeStandardControl(this.noCalibrationOutputControl, this.props.item.controlValues);
} else { } else {
let tControl: UiControl = this.noCalibrationOutputControl.clone(); let tControl: UiControl = this.noCalibrationOutputControl.clone();
@@ -219,12 +247,61 @@ const ToobNamView =
} }
} }
} else {
controls[CalibrationGroupPos] = null;
}
controls[ModelSizeControlPos] = null;
controls[ModelWeightControlPos] = null;
if (!this.state.showEqSection) { if (!this.state.showEqSection) {
controls.splice(EqPos, 1); controls.splice(EqPos, 1);
} }
if (this.state.modelMetadata.hasSlimmableWeights()) {
controls.splice(3, 0, this.MakeModelWeightSelector(host));
}
return controls; return controls;
} }
ModelWeightToString(weight: number): string {
switch (weight) {
case 1.0: return "Standard";
case 0.5: return "Lite";
case 0.25: return "Feather";
default: return weight.toString();
}
}
SelectModelWeight(weight: number) {
this.setState({ modelWeight: weight });
this.model.setPatchProperty(this.props.instanceId, TOOB_NAM__MODEL_WEIGHT_URI, weight);
}
MakeModelWeightSelector(host: ICustomizationHost): React.ReactNode {
if ((this.state.modelMetadata.modelWeight === undefined || this.state.modelMetadata.modelWeight || this.state.modelMetadata.hasSlimmableWeights()) === false) {
return null;
}
let selectControl = (
<Select key="model_weight_control" variant="standard" size="small" value={this.state.modelMetadata.modelWeight}
onChange={(e) => { this.SelectModelWeight(Number(e.target.value)) }}
style={{ marginLeft: 4, marginRight: 4, width: 140, fontSize: 12, marginTop: 4 }}
>
{this.state.modelMetadata.slimmable_weights.map((weight, index) => {
return (
<MenuItem key={weight.toString()} value={weight}
style={{ fontSize: 14 }}
>
{this.ModelWeightToString(weight)}
</MenuItem>
);
})}
</Select>
);
return (
<div style={{ marginLeft: 12 }}>
<CustomPluginControl title="Model Weight" mainControl={selectControl} isSelect={true} />
</div>);
}
private handleConnectionStateChanged(state: State) { private handleConnectionStateChanged(state: State) {
if (state === State.Ready) { if (state === State.Ready) {
this.unsubscribeFromMetadata(); this.unsubscribeFromMetadata();
@@ -235,11 +312,16 @@ const ToobNamView =
handleModelMetadata(atomData: any) { handleModelMetadata(atomData: any) {
if (atomData && atomData.otype_ === "Vector" && atomData.value) { if (atomData && atomData.otype_ === "Vector" && atomData.value) {
let metadata = new ModelMetadata(atomData.value as number[]); let metadata = new ModelMetadata(atomData.value as number[]);
metadata.hasInputLevelDBU || metadata.hasOutputLevelDBU
this.setState({ this.setState({
modelMetadata: metadata, modelMetadata: metadata,
showEqSection: metadata.preset_version === 0, showEqSection: metadata.preset_version === 0,
showCalibration: (
metadata.hasInputLevelDBU || metadata.hasOutputLevelDBU ||
(metadata.hasLoudness && metadata.hasGain)) && metadata.hasModel,
enableCalibration: metadata.hasInputLevelDBU && metadata.hasModel, enableCalibration: metadata.hasInputLevelDBU && metadata.hasModel,
enableOutputNormalization: metadata.hasLoudness && metadata.hasModel enableOutputNormalization: metadata.hasLoudness && metadata.hasModel,
modelWeight: metadata.modelWeight
}); });
} }
} }
@@ -248,13 +330,13 @@ const ToobNamView =
this.subscribedId = this.props.instanceId; this.subscribedId = this.props.instanceId;
this.listenHandle = this.model.monitorPatchProperty( this.listenHandle = this.model.monitorPatchProperty(
this.props.instanceId, this.props.instanceId,
TOOB_NAM__MODEL_METADATA, TOOB_NAM__MODEL_METADATA_URI,
(instanceId, propertyUri, atomData) => { (instanceId, propertyUri, atomData) => {
this.handleModelMetadata(atomData); this.handleModelMetadata(atomData);
}); });
this.model.getPatchProperty( this.model.getPatchProperty(
this.props.instanceId, this.props.instanceId,
TOOB_NAM__MODEL_METADATA TOOB_NAM__MODEL_METADATA_URI
).then((atomData) => { ).then((atomData) => {
this.handleModelMetadata(atomData); this.handleModelMetadata(atomData);
}).catch((e) => { }).catch((e) => {