primary color and shadows
This commit is contained in:
@ -31,6 +31,7 @@ import * as Juce from "juce-framework-frontend";
|
|||||||
import JuceSlider from "./Components/JuceSlider.js";
|
import JuceSlider from "./Components/JuceSlider.js";
|
||||||
import JuceCheckbox from "./Components/JuceCheckbox.js";
|
import JuceCheckbox from "./Components/JuceCheckbox.js";
|
||||||
import MidiNoteInfo from "./Components/MidiNoteInfo.js";
|
import MidiNoteInfo from "./Components/MidiNoteInfo.js";
|
||||||
|
import AutoTuneInfo from "./Components/AutoTuneInfo.js";
|
||||||
import { controlParameterIndexAnnotation } from "./types/JuceTypes.js";
|
import { controlParameterIndexAnnotation } from "./types/JuceTypes.js";
|
||||||
|
|
||||||
import { React } from "react";
|
import { React } from "react";
|
||||||
@ -70,8 +71,15 @@ function App() {
|
|||||||
|
|
||||||
<div className="border border-[#2a2a2a] rounded-lg p-4">
|
<div className="border border-[#2a2a2a] rounded-lg p-4">
|
||||||
<div className="grid grid-cols-2 grid-rows-2 gap-4 items-end ">
|
<div className="grid grid-cols-2 grid-rows-2 gap-4 items-end ">
|
||||||
<div className="col-span-2 self-center flex justify-center">
|
<div className="col-span-2">
|
||||||
<JuceCheckbox identifier="autoTuneEnabled" />
|
<div className="grid grid-rows-2 self-center flex justify-center items-start">
|
||||||
|
<div className="self-center justify-center items-center flex">
|
||||||
|
<JuceCheckbox identifier="autoTuneEnabled" />
|
||||||
|
</div>
|
||||||
|
<div className="mt-1">
|
||||||
|
<AutoTuneInfo />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<JuceSlider identifier="autoTuneSpeed" title="Auto Tune Speed" />
|
<JuceSlider identifier="autoTuneSpeed" title="Auto Tune Speed" />
|
||||||
@ -84,7 +92,7 @@ function App() {
|
|||||||
|
|
||||||
<div className="border border-[#2a2a2a] rounded-lg p-4">
|
<div className="border border-[#2a2a2a] rounded-lg p-4">
|
||||||
<div className="grid grid-cols-2 grid-rows-2 gap-4 items-end">
|
<div className="grid grid-cols-2 grid-rows-2 gap-4 items-end">
|
||||||
<div className="mt-0 pt-0 col-span-2 self-center flex justify-center">
|
<div className="mt-0 pt-0 col-span-2 self-start flex justify-center ">
|
||||||
<JuceCheckbox identifier="freezeEnabled" />
|
<JuceCheckbox identifier="freezeEnabled" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@ -97,7 +105,9 @@ function App() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Container></Container>
|
<Container></Container>
|
||||||
<MidiNoteInfo />
|
<div className="rounded-lg">
|
||||||
|
<MidiNoteInfo />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
1
Assets/web/src/Colors.js
Normal file
1
Assets/web/src/Colors.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const HIGHLIGHT_COLOR = "#5242cdff";
|
||||||
76
Assets/web/src/Components/AutoTuneInfo.js
Normal file
76
Assets/web/src/Components/AutoTuneInfo.js
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/* eslint-disable no-unused-vars */
|
||||||
|
import React, { useState, useEffect, useRef } from "react";
|
||||||
|
import CenterGrowSlider from "./CenterGrowSlider.js";
|
||||||
|
import AutoTuneDataReceiver from "../DataRecievers/AutoTuneDataReceiver.js";
|
||||||
|
// import { Slider } from "@mui/material";
|
||||||
|
// import { styled } from "@mui/material/styles";
|
||||||
|
|
||||||
|
// eslint-disable-next-line react/prop-types
|
||||||
|
|
||||||
|
export default function AutoTuneInfo() {
|
||||||
|
const [inputCents, setInputCents] = useState(0);
|
||||||
|
const [outputCents, setOutputCents] = useState(0);
|
||||||
|
const [autotuneNote, setAutotuneNote] = useState(0);
|
||||||
|
const dataReceiverRef = useRef(null);
|
||||||
|
const isActiveRef = useRef(true);
|
||||||
|
|
||||||
|
function getCharfromNoteIndex(index) {
|
||||||
|
if (index === -1) return "-";
|
||||||
|
const NOTE_NAMES = [
|
||||||
|
"C",
|
||||||
|
"C♯",
|
||||||
|
"D",
|
||||||
|
"D♯",
|
||||||
|
"E",
|
||||||
|
"F",
|
||||||
|
"F♯",
|
||||||
|
"G",
|
||||||
|
"G♯",
|
||||||
|
"A",
|
||||||
|
"A♯",
|
||||||
|
"B",
|
||||||
|
];
|
||||||
|
if (typeof index !== "number" || isNaN(index)) return "";
|
||||||
|
return NOTE_NAMES[index % NOTE_NAMES.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
dataReceiverRef.current = new AutoTuneDataReceiver();
|
||||||
|
isActiveRef.current = true;
|
||||||
|
|
||||||
|
function render() {
|
||||||
|
if (!isActiveRef.current) return;
|
||||||
|
if (dataReceiverRef.current) {
|
||||||
|
setInputCents(dataReceiverRef.current.getInputCents());
|
||||||
|
setOutputCents(dataReceiverRef.current.getOutputCents());
|
||||||
|
setAutotuneNote(dataReceiverRef.current.getAutotuneNote());
|
||||||
|
}
|
||||||
|
window.requestAnimationFrame(render);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.requestAnimationFrame(render);
|
||||||
|
return function cleanup() {
|
||||||
|
isActiveRef.current = false;
|
||||||
|
if (dataReceiverRef.current) dataReceiverRef.current.unregister();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex">
|
||||||
|
<h1
|
||||||
|
className="w-8 flex-initial py-2 px-1 text-xl"
|
||||||
|
style={{ color: "#666" }}
|
||||||
|
>
|
||||||
|
{getCharfromNoteIndex(autotuneNote)}
|
||||||
|
</h1>
|
||||||
|
<div className=" py-2 px-1 flex-1">
|
||||||
|
<div className="py-1">
|
||||||
|
<CenterGrowSlider value={inputCents} />
|
||||||
|
</div>
|
||||||
|
<div className="py-1">
|
||||||
|
<CenterGrowSlider value={outputCents} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,12 +1,9 @@
|
|||||||
/* eslint-disable react/prop-types */
|
/* eslint-disable react/prop-types */
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
export default function CenterGrowSlider({
|
export default function CenterGrowSlider({
|
||||||
value,
|
value,
|
||||||
min = -50,
|
min = -50,
|
||||||
max = 50,
|
max = 50,
|
||||||
positiveColor = "#4caf50",
|
|
||||||
negativeColor = "#f44336",
|
|
||||||
backgroundColor = "rgba(150,150,150,0.3)",
|
backgroundColor = "rgba(150,150,150,0.3)",
|
||||||
height = 8,
|
height = 8,
|
||||||
}) {
|
}) {
|
||||||
@ -39,21 +36,21 @@ export default function CenterGrowSlider({
|
|||||||
>
|
>
|
||||||
{/* Negative (left) bar */}
|
{/* Negative (left) bar */}
|
||||||
<div
|
<div
|
||||||
|
className="bg-primary shadow-primary/40 shadow-[0_0_16px,inset_0_1px_2px_rgba(255,255,255,0.3)]"
|
||||||
style={{
|
style={{
|
||||||
...baseStyle,
|
...baseStyle,
|
||||||
right: "50%", // anchored to the center
|
right: "50%", // anchored to the center
|
||||||
width: `${negativeWidth}%`,
|
width: `${negativeWidth}%`,
|
||||||
backgroundColor: negativeColor,
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Positive (right) bar */}
|
{/* Positive (right) bar */}
|
||||||
<div
|
<div
|
||||||
|
className="bg-primary shadow-primary/40 shadow-[0_0_16px,inset_0_1px_2px_rgba(255,255,255,0.3)]"
|
||||||
style={{
|
style={{
|
||||||
...baseStyle,
|
...baseStyle,
|
||||||
left: "50%", // anchored to the center
|
left: "50%", // anchored to the center
|
||||||
width: `${positiveWidth}%`,
|
width: `${positiveWidth}%`,
|
||||||
backgroundColor: positiveColor,
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
/* eslint-disable react/prop-types */
|
/* eslint-disable react/prop-types */
|
||||||
import React, { useState, useRef, useEffect } from "react";
|
import React, { useState, useRef, useEffect } from "react";
|
||||||
|
import { HIGHLIGHT_COLOR } from "../Colors.js";
|
||||||
|
|
||||||
export function HorizontalSlider({
|
export function HorizontalSlider({
|
||||||
value = 50,
|
value = 50,
|
||||||
@ -70,7 +71,7 @@ export function HorizontalSlider({
|
|||||||
|
|
||||||
{showFill && (
|
{showFill && (
|
||||||
<div
|
<div
|
||||||
className="absolute left-0 top-0 h-full bg-[#7FFF7F] rounded-full shadow-[0_0_8px_rgba(127,255,127,0.4)]"
|
className={`absolute left-0 top-0 h-full bg-primary rounded-full shadow-primary/40 shadow-[0_0_8px]`}
|
||||||
style={{ width: `${percentage}%` }}
|
style={{ width: `${percentage}%` }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import React, { useState, useEffect, useRef } from "react";
|
import React, { useState, useEffect, useRef } from "react";
|
||||||
import PianoKeyboard from "./PianoKeyboard";
|
import PianoKeyboard from "./PianoKeyboard";
|
||||||
import MidNoteDataReceiver from "../DataRecievers/MidiNoteDataReceiver.js";
|
import MidNoteDataReceiver from "../DataRecievers/MidiNoteDataReceiver.js";
|
||||||
import CenterGrowSlider from "./CenterGrowSlider.js";
|
|
||||||
// import { Slider } from "@mui/material";
|
// import { Slider } from "@mui/material";
|
||||||
// import { styled } from "@mui/material/styles";
|
// import { styled } from "@mui/material/styles";
|
||||||
|
|
||||||
@ -9,31 +8,9 @@ import CenterGrowSlider from "./CenterGrowSlider.js";
|
|||||||
|
|
||||||
export default function MidiNoteInfo() {
|
export default function MidiNoteInfo() {
|
||||||
const [notes, setNotes] = useState([]);
|
const [notes, setNotes] = useState([]);
|
||||||
const [inputCents, setInputCents] = useState(0);
|
|
||||||
const [outputCents, setOutputCents] = useState(0);
|
|
||||||
const [autotuneNote, setAutotuneNote] = useState(0);
|
|
||||||
const dataReceiverRef = useRef(null);
|
const dataReceiverRef = useRef(null);
|
||||||
const isActiveRef = useRef(true);
|
const isActiveRef = useRef(true);
|
||||||
|
|
||||||
function getCharfromNoteIndex(index) {
|
|
||||||
const NOTE_NAMES = [
|
|
||||||
"C",
|
|
||||||
"C♯",
|
|
||||||
"D",
|
|
||||||
"D♯",
|
|
||||||
"E",
|
|
||||||
"F",
|
|
||||||
"F♯",
|
|
||||||
"G",
|
|
||||||
"G♯",
|
|
||||||
"A",
|
|
||||||
"A♯",
|
|
||||||
"B",
|
|
||||||
];
|
|
||||||
if (typeof index !== "number" || isNaN(index)) return "";
|
|
||||||
return NOTE_NAMES[index % NOTE_NAMES.length];
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dataReceiverRef.current = new MidNoteDataReceiver();
|
dataReceiverRef.current = new MidNoteDataReceiver();
|
||||||
isActiveRef.current = true;
|
isActiveRef.current = true;
|
||||||
@ -42,9 +19,6 @@ export default function MidiNoteInfo() {
|
|||||||
if (!isActiveRef.current) return;
|
if (!isActiveRef.current) return;
|
||||||
if (dataReceiverRef.current) {
|
if (dataReceiverRef.current) {
|
||||||
setNotes(dataReceiverRef.current.getNotes());
|
setNotes(dataReceiverRef.current.getNotes());
|
||||||
setInputCents(dataReceiverRef.current.getInputCents());
|
|
||||||
setOutputCents(dataReceiverRef.current.getOutputCents());
|
|
||||||
setAutotuneNote(dataReceiverRef.current.getAutotuneNote());
|
|
||||||
}
|
}
|
||||||
window.requestAnimationFrame(render);
|
window.requestAnimationFrame(render);
|
||||||
}
|
}
|
||||||
@ -57,13 +31,8 @@ export default function MidiNoteInfo() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ marginTop: "1rem" }}>
|
<div className="rounded-lg" style={{ marginTop: "1rem" }}>
|
||||||
<PianoKeyboard heldNotes={notes} />
|
<PianoKeyboard heldNotes={notes} />
|
||||||
<h1>Autotune Note: {getCharfromNoteIndex(autotuneNote)}</h1>
|
|
||||||
<label>Input cents</label>
|
|
||||||
<CenterGrowSlider value={inputCents} />
|
|
||||||
<label>Output cents</label>
|
|
||||||
<CenterGrowSlider value={outputCents} />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
/* eslint-disable react/prop-types */
|
/* eslint-disable react/prop-types */
|
||||||
import React /*, { useRef, useEffect, useState }*/ from "react";
|
import React /*, { useRef, useEffect, useState }*/ from "react";
|
||||||
|
|
||||||
const NOTE_NAMES = [
|
const NOTE_NAMES = [
|
||||||
"C",
|
"C",
|
||||||
"C♯",
|
"C♯",
|
||||||
@ -96,14 +95,18 @@ export default function PianoKeyboard({ heldNotes }) {
|
|||||||
height: "100%",
|
height: "100%",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{whiteKeys.map((k) => (
|
{whiteKeys.map((k, i) => (
|
||||||
<div
|
<div
|
||||||
key={k.midi}
|
key={k.midi}
|
||||||
|
className={
|
||||||
|
k.held
|
||||||
|
? "bg-primary shadow-primary/30 shadow-[0_0_16px,inset_0_1px_2px_rgba(255,255,255,0.2)]"
|
||||||
|
: "bg-[#222]"
|
||||||
|
}
|
||||||
style={{
|
style={{
|
||||||
flex: "1 1 0",
|
flex: "1 1 0",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
border: "1px solid #2a2a2a",
|
border: "1px solid #2a2a2a",
|
||||||
background: k.held ? "#7fff7f" : "#222",
|
|
||||||
position: "relative",
|
position: "relative",
|
||||||
boxSizing: "border-box",
|
boxSizing: "border-box",
|
||||||
marginRight: -1,
|
marginRight: -1,
|
||||||
@ -114,6 +117,10 @@ export default function PianoKeyboard({ heldNotes }) {
|
|||||||
fontSize: 10,
|
fontSize: 10,
|
||||||
fontFamily: "monospace",
|
fontFamily: "monospace",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
|
borderTopLeftRadius: i === 0 ? 6 : 0, // round left edge of first key
|
||||||
|
borderBottomLeftRadius: i === 0 ? 6 : 0,
|
||||||
|
borderTopRightRadius: i === whiteKeys.length - 1 ? 6 : 0, // round right edge of last key
|
||||||
|
borderBottomRightRadius: i === whiteKeys.length - 1 ? 6 : 0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -156,12 +163,16 @@ export default function PianoKeyboard({ heldNotes }) {
|
|||||||
{blackKeys.map((k) => (
|
{blackKeys.map((k) => (
|
||||||
<div
|
<div
|
||||||
key={k.midi}
|
key={k.midi}
|
||||||
|
className={
|
||||||
|
k.held
|
||||||
|
? "bg-primary shadow-primary/30 shadow-[0_0_16px,inset_0_1px_2px_rgba(255,255,255,0.2)]"
|
||||||
|
: "bg-[#111]"
|
||||||
|
}
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
left: `${getBlackKeyPercent(k.midi)}%`,
|
left: `${getBlackKeyPercent(k.midi)}%`,
|
||||||
width: `${(100 / numWhite) * 0.65}%`,
|
width: `${(100 / numWhite) * 0.65}%`,
|
||||||
height: "100%",
|
height: "100%",
|
||||||
background: k.held ? "#7fff7f" : "#111",
|
|
||||||
border: "1px solid #333",
|
border: "1px solid #333",
|
||||||
borderRadius: 3,
|
borderRadius: 3,
|
||||||
display: "flex",
|
display: "flex",
|
||||||
|
|||||||
@ -13,10 +13,10 @@ export function ToggleSwitch({ value = true, onChange }) {
|
|||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<button
|
<button
|
||||||
onClick={() => handleToggle(true)}
|
onClick={() => handleToggle(true)}
|
||||||
className={`px-8 py-3 rounded transition-all relative overflow-hidden ${
|
className={`px-8 py-3 rounded transition-colors transition-shadow relative overflow-hidden ${
|
||||||
isOn
|
isOn
|
||||||
? "bg-[#7FFF7F] text-[#1a1a1a] shadow-[0_0_16px_rgba(127,255,127,0.4),inset_0_1px_2px_rgba(255,255,255,0.3)]"
|
? `bg-primary text-[#1a1a1a] shadow-primary/40 shadow-[0_0_16px,inset_0_1px_2px_rgba(255,255,255,0.3)]`
|
||||||
: "bg-[#1a1a1a] text-[#7FFF7F] border-2 border-[#2a2a2a] shadow-[inset_0_2px_4px_rgba(0,0,0,0.3)]"
|
: `bg-[#1a1a1a] text-primary border-2 border-[#2a2a2a] shadow-[inset_0_2px_4px_rgba(0,0,0,0.3)]`
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{!isOn && (
|
{!isOn && (
|
||||||
@ -26,10 +26,10 @@ export function ToggleSwitch({ value = true, onChange }) {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleToggle(false)}
|
onClick={() => handleToggle(false)}
|
||||||
className={`px-8 py-3 rounded transition-all relative overflow-hidden ${
|
className={`px-8 py-3 rounded transition-colors transition-shadow relative overflow-hidden ${
|
||||||
!isOn
|
!isOn
|
||||||
? "bg-[#7FFF7F] text-[#1a1a1a] shadow-[0_0_16px_rgba(127,255,127,0.4),inset_0_1px_2px_rgba(255,255,255,0.3)]"
|
? `bg-primary text-[#1a1a1a] shadow-primary/40 shadow-[0_0_16px,inset_0_1px_2px_rgba(255,255,255,0.3)]`
|
||||||
: "bg-[#1a1a1a] text-[#7FFF7F] border-2 border-[#2a2a2a] shadow-[inset_0_2px_4px_rgba(0,0,0,0.3)]"
|
: `bg-[#1a1a1a] text-primary border-2 border-[#2a2a2a] shadow-[inset_0_2px_4px_rgba(0,0,0,0.3)]`
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{isOn && (
|
{isOn && (
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
/* eslint-disable react/prop-types */
|
/* eslint-disable react/prop-types */
|
||||||
import React, { useState, useRef, useEffect } from "react";
|
import React, { useState, useRef, useEffect } from "react";
|
||||||
|
|
||||||
// interface KnobProps {
|
// interface KnobProps {
|
||||||
// value?: number;
|
// value?: number;
|
||||||
// onChange?: (value: number) => void;
|
// onChange?: (value: number) => void;
|
||||||
@ -87,7 +86,7 @@ export function Knob({ value = 0, onChange, min = 0, max = 100, size = "md" }) {
|
|||||||
style={{ transform: `rotate(${rotation}deg)` }}
|
style={{ transform: `rotate(${rotation}deg)` }}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`${dotSize[size]} rounded-full bg-[#7FFF7F] shadow-[0_0_12px_rgba(127,255,127,0.9),0_0_4px_rgba(127,255,127,1)]`}
|
className={`${dotSize[size]} rounded-full bg-primary shadow-primary/90 shadow-[0_0_12px]`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
42
Assets/web/src/DataRecievers/AutoTuneDataReceiver.js
Normal file
42
Assets/web/src/DataRecievers/AutoTuneDataReceiver.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// import * as Juce from "juce-framework-frontend";
|
||||||
|
// import reportWebVitals from "../reportWebVitals";
|
||||||
|
|
||||||
|
const AutoTuneDataReceiver_eventId = "autoTuneData";
|
||||||
|
export default class AutoTuneDataReceiver {
|
||||||
|
constructor() {
|
||||||
|
this.input_pitch = 0;
|
||||||
|
this.output_pitch = 0;
|
||||||
|
let self = this;
|
||||||
|
this.autoTuneDataRegistrationId = window.__JUCE__.backend.addEventListener(
|
||||||
|
AutoTuneDataReceiver_eventId,
|
||||||
|
(event) => {
|
||||||
|
self.input_pitch = event.input_pitch;
|
||||||
|
self.output_pitch = event.output_pitch;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
frequencytoMidi(frequency) {
|
||||||
|
return 69 + 12 * Math.log2(frequency / 440);
|
||||||
|
}
|
||||||
|
|
||||||
|
getAutotuneNote() {
|
||||||
|
if (this.output_pitch <= 0) return -1;
|
||||||
|
const midi = this.frequencytoMidi(this.output_pitch);
|
||||||
|
return Math.round(midi % 12);
|
||||||
|
}
|
||||||
|
getInputCents() {
|
||||||
|
const midi = this.frequencytoMidi(this.input_pitch);
|
||||||
|
return Math.round((midi - Math.round(midi)) * 100);
|
||||||
|
}
|
||||||
|
getOutputCents() {
|
||||||
|
const midi = this.frequencytoMidi(this.output_pitch);
|
||||||
|
return Math.round((midi - Math.round(midi)) * 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
unregister() {
|
||||||
|
window.__JUCE__.backend.removeEventListener(
|
||||||
|
this.autoTuneDataRegistrationId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,17 +12,6 @@ export default class MidNoteDataReceiver {
|
|||||||
MidNoteDataReceiver_eventId,
|
MidNoteDataReceiver_eventId,
|
||||||
(event) => {
|
(event) => {
|
||||||
self.notes = event.notes;
|
self.notes = event.notes;
|
||||||
self.input_pitch = event.input_pitch;
|
|
||||||
self.output_pitch = event.output_pitch;
|
|
||||||
console.log("in: " + self.input_pitch);
|
|
||||||
console.log("out: " + self.output_pitch);
|
|
||||||
// reportWebVitals(console.log(event));
|
|
||||||
// fetch(Juce.getBackendResourceAddress("midNoteData.json"))
|
|
||||||
// .then((response) => response.text())
|
|
||||||
// .then((text) => {
|
|
||||||
// const data = JSON.parse(text);
|
|
||||||
// self.notes = data.notes;
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -31,23 +20,6 @@ export default class MidNoteDataReceiver {
|
|||||||
return this.notes;
|
return this.notes;
|
||||||
}
|
}
|
||||||
|
|
||||||
frequencytoMidi(frequency) {
|
|
||||||
return 69 + 12 * Math.log2(frequency / 440);
|
|
||||||
}
|
|
||||||
|
|
||||||
getAutotuneNote() {
|
|
||||||
const midi = this.frequencytoMidi(this.output_pitch);
|
|
||||||
return Math.round(midi % 12);
|
|
||||||
}
|
|
||||||
getInputCents() {
|
|
||||||
const midi = this.frequencytoMidi(this.input_pitch);
|
|
||||||
return Math.round((midi - Math.round(midi)) * 100);
|
|
||||||
}
|
|
||||||
getOutputCents() {
|
|
||||||
const midi = this.frequencytoMidi(this.output_pitch);
|
|
||||||
return Math.round((midi - Math.round(midi)) * 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
unregister() {
|
unregister() {
|
||||||
window.__JUCE__.backend.removeEventListener(this.midNoteDataRegistrationId);
|
window.__JUCE__.backend.removeEventListener(this.midNoteDataRegistrationId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -95,6 +95,7 @@ code {
|
|||||||
--sidebar-accent-foreground: oklch(0.985 0 0);
|
--sidebar-accent-foreground: oklch(0.985 0 0);
|
||||||
--sidebar-border: oklch(0.269 0 0);
|
--sidebar-border: oklch(0.269 0 0);
|
||||||
--sidebar-ring: oklch(0.439 0 0);
|
--sidebar-ring: oklch(0.439 0 0);
|
||||||
|
--color-primary-rgb: 127,255,127;
|
||||||
}
|
}
|
||||||
|
|
||||||
@theme inline {
|
@theme inline {
|
||||||
|
|||||||
@ -2,7 +2,12 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
content: ["./src/*.{js,jsx,ts,tsx}", "./src/**/*.{js,jsx,ts,tsx}"],
|
content: ["./src/*.{js,jsx,ts,tsx}", "./src/**/*.{js,jsx,ts,tsx}"],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {},
|
extend: {
|
||||||
|
colors: {
|
||||||
|
//primary: "#7FFF7F",
|
||||||
|
primary: "#2ccaffff",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
plugins: [],
|
plugins: [],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -177,7 +177,7 @@ WebViewPluginAudioProcessorEditor::WebViewPluginAudioProcessorEditor(WebViewPlug
|
|||||||
webComponent->goToURL(localDevServerAddress);
|
webComponent->goToURL(localDevServerAddress);
|
||||||
//webComponent.goToURL (WebBrowserComponent::getResourceProviderRoot());
|
//webComponent.goToURL (WebBrowserComponent::getResourceProviderRoot());
|
||||||
|
|
||||||
setSize(800, 500);
|
setSize(800, 390);
|
||||||
|
|
||||||
startTimerHz(60);
|
startTimerHz(60);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -80,9 +80,19 @@ public:
|
|||||||
|
|
||||||
DynamicObject::Ptr d(new DynamicObject());
|
DynamicObject::Ptr d(new DynamicObject());
|
||||||
d->setProperty("notes", notes);
|
d->setProperty("notes", notes);
|
||||||
d->setProperty("input_pitch", processorRef.shifter.getInputPitch());
|
|
||||||
d->setProperty("output_pitch", processorRef.shifter.getOutputPitch());
|
|
||||||
webComponent->emitEventIfBrowserIsVisible("midNoteData", d.get());
|
webComponent->emitEventIfBrowserIsVisible("midNoteData", d.get());
|
||||||
|
|
||||||
|
d->clear();
|
||||||
|
if (processorRef.shifter.GetAutoTuneEnable()) {
|
||||||
|
d->setProperty("input_pitch", processorRef.shifter.getInputPitch());
|
||||||
|
d->setProperty("output_pitch", processorRef.shifter.getOutputPitch());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
d->setProperty("input_pitch", -1);
|
||||||
|
d->setProperty("output_pitch", -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
webComponent->emitEventIfBrowserIsVisible("autoTuneData", d.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -159,6 +159,7 @@ public:
|
|||||||
float getOutputPitch() const { return sample_rate_ / out_period; }
|
float getOutputPitch() const { return sample_rate_ / out_period; }
|
||||||
void SetHarmonyMix(float mix);
|
void SetHarmonyMix(float mix);
|
||||||
void SetAutoTuneEnable(bool enable) { enable_autotune = enable; }
|
void SetAutoTuneEnable(bool enable) { enable_autotune = enable; }
|
||||||
|
bool GetAutoTuneEnable() { return enable_autotune; }
|
||||||
void SetFreeze(bool);
|
void SetFreeze(bool);
|
||||||
void SetFreezePitchAdjust(float val);
|
void SetFreezePitchAdjust(float val);
|
||||||
void SetFreezeVolume(float val) { freeze_volume = val; }
|
void SetFreezeVolume(float val) { freeze_volume = val; }
|
||||||
|
|||||||
Reference in New Issue
Block a user