Skip to content

Commit

Permalink
useState -> useMemo
Browse files Browse the repository at this point in the history
  • Loading branch information
TiagoCavalcante committed Mar 1, 2022
1 parent aa35676 commit ed36206
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 29 deletions.
12 changes: 7 additions & 5 deletions src/analyzerLivestream.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import AudioMotionAnalyzer from "audiomotion-analyzer";

function AnaylzerLivestream({ audioRef, setData }) {
function AnaylzerLivestream({ audioRef, data }) {
return new AudioMotionAnalyzer(null, {
source: audioRef.current,
mode: 2,
useCanvas: false, // don't use the canvas
useCanvas: false,
volume: 1,
onCanvasDraw: ({ getBars }) => setData(
getBars().map(({ value }) => value[0])
)
onCanvasDraw: (instance) => {
instance
.getBars()
.forEach(({ value }, index) => data[index] = value[0]);
}
});
}

Expand Down
41 changes: 21 additions & 20 deletions src/dataReactiveGrid.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { useEffect, useMemo, useRef, useState } from "react";
import React, { useEffect, useMemo, useRef } from "react";
import AnaylzerLivestream from "./analyzerLivestream";
import { Lut } from "three/examples/jsm/math/Lut.js";
import { Matrix4 } from "three";
import PropTypes from "prop-types";
import { useFrame } from "@react-three/fiber";

const nGridRows = 12, nGridCols = 100, cubeSideLength = 0.03, cubeSpacingScalar = 4.5;
const cubeSideLength = 0.03, cubeSpacingScalar = 4.5;

function getValueForNormalizedCoord(data, normalizedCoordinate) {
if (!data) return 0;
Expand All @@ -17,43 +17,42 @@ function getValueForNormalizedCoord(data, normalizedCoordinate) {
return valueBelow + (rawIndex % 1) * (valueAbove - valueBelow);
}

function DataReactiveGrid({ audioRef }) {
function DataReactiveGrid({ audioRef, gridCols, gridRows }) {
const mesh = useRef();

const [data, setData] = useState([]);

const data = useMemo(() => new Array(121), []);
const matrix = useMemo(() => new Matrix4(), []);
const lut = useMemo(() => new Lut("cooltowarm"), []);

useEffect(() => {
if (!audioRef.current) return;
if (!audioRef.current || !data) return;

AnaylzerLivestream({ audioRef, setData });
AnaylzerLivestream({ audioRef, data });

const normQuadrantHypotenuse = Math.hypot(0.5, 0.5);

for (let index = 0, row = 0; row < nGridRows; row++) {
for (let col = 0; col < nGridCols; col++) {
const normGridX = row / nGridRows;
const normGridY = col / nGridCols;
for (let index = 0, row = 0; row < gridCols; row++) {
for (let col = 0; col < gridRows; col++) {
const normGridX = row / gridCols;
const normGridY = col / gridRows;
const normRadialOffset = Math.hypot(normGridX - 0.5, normGridY - 0.5) / normQuadrantHypotenuse;

mesh.current.setColorAt(index++, lut.getColor(normRadialOffset));
}
}

mesh.current.instanceColor.needsUpdate = true;
}, [audioRef, lut]);
}, [audioRef, data, gridRows, gridCols, lut]);

useFrame(() => {
const gridSizeX = nGridRows * cubeSpacingScalar * cubeSideLength;
const gridSizeY = nGridCols * cubeSpacingScalar * cubeSideLength;
const gridSizeX = gridRows * cubeSpacingScalar * cubeSideLength;
const gridSizeY = gridRows * cubeSpacingScalar * cubeSideLength;
const normQuadrantHypotenuse = Math.hypot(0.5, 0.5);

for (let index = 0, row = 0; row < nGridRows; row++) {
for (let col = 0; col < nGridCols; col++) {
const normGridX = row / nGridRows;
const normGridY = col / nGridCols;
for (let index = 0, row = 0; row < gridRows; row++) {
for (let col = 0; col < gridCols; col++) {
const normGridX = row / gridRows;
const normGridY = col / gridCols;
const normRadialOffset = Math.hypot(normGridX - 0.5, normGridY - 0.5) / normQuadrantHypotenuse;

mesh.current.setMatrixAt(
Expand All @@ -75,7 +74,7 @@ function DataReactiveGrid({ audioRef }) {
ref={mesh}
castShadow={true}
receiveShadow={true}
args={[null, null, nGridRows * nGridCols]}
args={[null, null, gridRows * gridCols]}
>
<boxGeometry args={[cubeSideLength, cubeSideLength, cubeSideLength]} />
<meshBasicMaterial />
Expand All @@ -84,7 +83,9 @@ function DataReactiveGrid({ audioRef }) {
}

DataReactiveGrid.propTypes = {
audioRef: PropTypes.any.isRequired
audioRef: PropTypes.any.isRequired,
gridCols: PropTypes.number,
gridRows: PropTypes.number
};

export default DataReactiveGrid;
21 changes: 17 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,30 @@ import { Canvas } from "@react-three/fiber";
import DataReactiveGrid from "./dataReactiveGrid";
import PropTypes from "prop-types";

function Equalizer({ audioRef, cameraPosition }) {
function Equalizer({
audioRef,
cameraFov = 45,
cameraPosition,
gridCols = 80,
gridRows = 12
}) {
return (
<Suspense fallback={null}>
<Canvas
mode="concurrent"
camera={{
fov: 45,
fov: cameraFov,
position: cameraPosition,
up: [0, 0, 1]
}}
>
<color attach="background" args={["black"]} />

<DataReactiveGrid audioRef={audioRef} />
<DataReactiveGrid
audioRef={audioRef}
gridCols={gridCols}
gridRows={gridRows}
/>

<EffectComposer>
<Bloom
Expand All @@ -34,7 +44,10 @@ function Equalizer({ audioRef, cameraPosition }) {

Equalizer.propTypes = {
audioRef: PropTypes.any.isRequired,
cameraPosition: PropTypes.array.isRequired
cameraFov: PropTypes.number,
cameraPosition: PropTypes.array.isRequired,
gridCols: PropTypes.number,
gridRows: PropTypes.number
};

export default Equalizer;

0 comments on commit ed36206

Please sign in to comment.