Skip to content

Commit

Permalink
Change scale according to gain input
Browse files Browse the repository at this point in the history
  • Loading branch information
0xpolarzero committed Dec 18, 2022
1 parent ed5ad5d commit a2da213
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 20 deletions.
9 changes: 8 additions & 1 deletion src/World/Audio/AudioSystem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,14 @@ const AudioSystem = () => {
<>
<AudioControls />
{sources.map((source, i) => {
return <AudioSphere key={i} audio={source.audio} info={source.info} />;
return (
<AudioSphere
key={i}
audio={source.audio}
info={source.info}
analyser={source.analyser}
/>
);
})}
</>
);
Expand Down
29 changes: 13 additions & 16 deletions src/World/Audio/components/AudioSphere.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import useInterface from '../../../stores/Interface';

Globals.assign({ frameLoop: 'always' });

const AudioSphere = ({ audio, info }) => {
const AudioSphere = ({ audio, info, analyser }) => {
const [isHovered, setIsHovered] = useState(false);
const [gain, setGain] = useState(0);
const { hovered } = useInterface();
const ref = useRef();
const rotationSpeed = useMemo(() => Math.random() - 0.5, []);

const { scale } = useSpring({
scale: isHovered ? 1.2 : 1,
scale: isHovered ? 1.2 : 1 + gain,
config: config.wobbly,
});

Expand All @@ -25,6 +26,9 @@ const AudioSphere = ({ audio, info }) => {

useFrame(({ clock }) => {
ref.current.rotation.y = clock.getElapsedTime() * rotationSpeed;

// The value will be between 0 and 255
setGain(analyser.gain / 255);
});

useEffect(() => {
Expand All @@ -40,14 +44,13 @@ const AudioSphere = ({ audio, info }) => {
}, [hovered, info.id]);

return (
<animated.mesh
ref={ref}
position={[info.position.x, info.position.y, info.position.z]}
onClick={handleClick}
scale={scale}
>
<group position={[info.position.x, info.position.y, info.position.z]}>
<animated.mesh ref={ref} onClick={handleClick} scale={scale}>
<sphereGeometry args={[1, 32, 32]} />
<meshBasicMaterial color={info.color} wireframe />
</animated.mesh>
<DREI.Html
position-y={info.position.y < 2 ? 1.5 : -1.5}
position-y={info.position.y < 2 ? 1.7 : -1.7}
center
distanceFactor={10}
>
Expand All @@ -64,13 +67,7 @@ const AudioSphere = ({ audio, info }) => {
<h3>{info.name}</h3>
</div>
</DREI.Html>

{/* <DREI.Text position-y={1.5} fontSize={0.4}>
{info.name}
</DREI.Text> */}
<sphereGeometry args={[1, 32, 32]} />
<meshBasicMaterial color={info.color} wireframe />
</animated.mesh>
</group>
);
};

Expand Down
67 changes: 64 additions & 3 deletions src/stores/Atmoky.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ export default create((set, get) => ({
renderer.externalizer.character.value = externalizerIntensity;
},

// Create source
createSource: (source, index) => {
const { audioContext, renderer, addSource } = get();
const { audioContext, renderer, addSource, createAnalyser } = get();
const position = source.info.position;
const audioElem = new Audio(source.src);
audioElem.crossOrigin = 'anonymous';
Expand All @@ -105,15 +106,16 @@ export default create((set, get) => ({

const audioElemSrc = audioContext.createMediaElementSource(audioElem);

const analyser = createAnalyser(audioElemSrc);

let atmSource = renderer.createSource();
atmSource.setInput(audioElemSrc);
atmSource.setPosition(position.x, position.y, position.z);

// audioElem.play();

addSource({
audio: atmSource,
audioElem: audioElem,
analyser: analyser,
info: { ...source.info, id: index },
});
},
Expand Down Expand Up @@ -152,6 +154,7 @@ export default create((set, get) => ({
}
},

// Resume audio
resumeAudio: () => {
const { audioContext } = get();
if (!audioContext) return;
Expand All @@ -162,6 +165,7 @@ export default create((set, get) => ({
});
},

// Pause audio
pauseAudio: () => {
const { audioContext } = get();
if (audioContext.state === 'running')
Expand All @@ -177,6 +181,7 @@ export default create((set, get) => ({
}
},

// Randomize position for all sources
randomizePositions: () => {
const { sources, setSources } = get();

Expand All @@ -189,4 +194,60 @@ export default create((set, get) => ({
});
setSources(newSources);
},

// Get an analyser for a source
createAnalyser: (source) => {
const { audioContext } = get();
const analyser = audioContext.createAnalyser();
const gainNode = audioContext.createGain();
analyser.fftSize = 64;
source.connect(analyser);
analyser.connect(gainNode);

// Create a script processor
let info = {};
const scriptProcessor = audioContext.createScriptProcessor(2048, 1, 1);
scriptProcessor.onaudioprocess = () => {
// const buffer = new Float32Array(analyser.frequencyBinCount);
// analyser.getFloatFrequencyData(buffer);
// const gain = buffer.reduce((a, b) => a + b) / buffer.length;
// info.gain = gain;

const data = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(data);
const gain = data.reduce((a, b) => a + b) / data.length;
info.gain = gain;
};
gainNode.connect(scriptProcessor);
scriptProcessor.connect(audioContext.destination);

return info;
},

getAnalyser: (source) => {
console.log(source);
// Create an analyser with the Audio API
const { audioContext } = get();
const analyser = audioContext.createAnalyser();
analyser.fftSize = 2048;
source.connect(analyser);

// Create a gain node
const gainNode = audioContext.createGain();
analyser.connect(gainNode);

// Create a script processor
const scriptProcessor = audioContext.createScriptProcessor(2048, 1, 1);
scriptProcessor.onaudioprocess = () => {
const buffer = new Float32Array(analyser.frequencyBinCount);
analyser.getFloatFrequencyData(buffer);
const gain = buffer.reduce((a, b) => a + b) / buffer.length;
gainNode.gain.value = gain;
source.info.frequency = frequency;
};
gainNode.connect(scriptProcessor);
scriptProcessor.connect(audioContext.destination);

return gainNode;
},
}));

0 comments on commit a2da213

Please sign in to comment.