// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { useEffect } from 'react'; import { useAudioVideo } from '../../providers/AudioVideoProvider'; import { useAudioInputs } from '../../providers/DevicesProvider'; export const useLocalAudioInputActivity = (cb: (decimal: number) => void) => { const audioVideo = useAudioVideo(); const { selectedDevice } = useAudioInputs(); useEffect(() => { if (!audioVideo) { return; } let analyserNode: AnalyserNode | null; let restart = false; let data: Uint8Array; let frameIndex: number; let isMounted = true; let lastDecimal: number; audioVideo.addDeviceChangeObserver({ audioInputsChanged: () => { restart = true; }, }); function initializePreview() { if (!audioVideo || !isMounted) return; analyserNode = audioVideo.createAnalyserNodeForAudioInput(); if (!analyserNode?.getByteTimeDomainData) { return; } data = new Uint8Array(analyserNode.fftSize); frameIndex = 0; restart = false; requestAnimationFrame(analyserNodeCallback); } function analyserNodeCallback() { if (!analyserNode) { return; } if (frameIndex === 0) { analyserNode.getByteTimeDomainData(data); const lowest = 0.01; let max = lowest; for (const f of data as any) { max = Math.max(max, (f - 128) / 128); } const decimal = (Math.log(lowest) - Math.log(max)) / Math.log(lowest); if (lastDecimal !== decimal) { lastDecimal = decimal; if (cb) { cb(decimal); } } } frameIndex = (frameIndex + 1) % 2; if (restart) { setTimeout(initializePreview, 500); } else if (isMounted) { requestAnimationFrame(analyserNodeCallback); } } initializePreview(); return () => { isMounted = false; }; }, [audioVideo, selectedDevice, cb]); }; export default useLocalAudioInputActivity;