export default function MicrophoneIcon()

in app/src/components/MicrophoneIcon.js [6:70]


export default function MicrophoneIcon({
  stream,
  big,
  visible,
  onStop
}) {
  const [ vu, setVu ] = useState(0);

  const ctx = useRef(null);
  const analyser = useRef(null);
  if (!ctx.current) {
    ctx.current = new AudioContext();

    // If for whatever reason the context is suspended (usually because the browser is waiting
    // for a user interaction before allowing audio) - wait for a click then try to reenable it
    if (ctx.current.state === 'suspended') {
      function resumeIt() {
        ctx.current.resume();
        document.removeEventListener('click', resumeIt);
      }
      document.addEventListener('click', resumeIt);
    }

    analyser.current = ctx.current.createAnalyser();
  }

  const source = useMemo(() => stream && ctx.current.createMediaStreamSource(stream), [ stream ]);

  useEffect(() => {
    if (!source) return;
    source.connect(analyser.current);

    return () => {
      source.disconnect();
    };
  }, [ source ]);


  useEffect(() => {
    const int = setInterval(() => {
      // Use just a single frequency bucket to get a rough volume level
      const fd = new Uint8Array(1);
      analyser.current.getByteFrequencyData(fd);
      setVu(fd[0])
    }, 50);

    return () => {
      clearInterval(int);
    }
  }, []);

  const boost = (stream && stream.__boost) || 1;

  return (
    <>
      <div className={cs(s.base, big && s.big, visible && s.visible)} onClick={onStop}>
        <div className={s.levels}>
          <div className={s.meter} style={{ height: Math.min(100, vu / 256 * 100 * boost) + '%' }} />
        </div>
      </div>

      <div className={cs(s.stopButton, visible && !big && s.visible)} onClick={onStop} />
    </>
  )
}