A problem with audio behaviour in a Next.js project

20 views Asked by At

I have built a browser synthesizer with next.js. Everything seems to work ok but the oscillators act weird. Every time I initialize the oscillator after a refresh, it will play until I change something and then nothing. I thought that it had something to do with re-rendering and the audio context but I used a package called react-frequency and what i tried to do worked well in their example.

this is my page.tsx file -

"use client";

import H1 from "@/components/H1";
import SynthControls from "@/components/SynthControls";
import SynthLayout from "@/components/SynthLayout";
import { getFrequencyOfNoteInHz, synthNotes } from "@/lib/constants";
import { useEffect, useState } from "react";
import { Frequency } from "react-frequency";

export default function BassSynth() {
  const [isPlaying, setIsPlaying] = useState(false);
  const [currentPitch, setCurrentPitch] = useState("C1");
  const [isInitialized, setIsInitialized] = useState(false);
  const [osc1Waveform, setOsc1Waveform] = useState<TWaveForm>("sawtooth");
  const [osc2Waveform, setOsc2Waveform] = useState<TWaveForm>("sawtooth");
  const [oscMix, setOscMix] = useState(0.5);

  const currentHzPitch = getFrequencyOfNoteInHz(currentPitch);

  // event listener for the keyboard
  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      const keyPressed = synthNotes.find(
        (element) => element.keyboardKey === event.key.toUpperCase()
      );
      if (keyPressed) {
        setCurrentPitch(keyPressed.note);
        setIsPlaying(true);
      } else {
        return;
      }
    };
    const handleKeyUp = () => {
      setIsPlaying(false);
    };

    document.addEventListener("keydown", handleKeyDown);
    document.addEventListener("keyup", handleKeyUp);

    return () => {
      document.removeEventListener("keydown", handleKeyDown);
      document.removeEventListener("keyup", handleKeyUp);
    };
  }, []);

  return (
    <main className="flex flex-col items-center p-10">
      <H1 className="mb-4">SJS Bass-1</H1>
      <SynthLayout
        synthColor="red-900"
        setIsPlaying={setIsPlaying}
        setCurrentPitch={setCurrentPitch}
        currentPitch={currentPitch}
        isPlaying={isPlaying}
      />
      <SynthControls
        setIsInitialized={setIsInitialized}
        isInitialized={isInitialized}
        setOsc1Waveform={setOsc1Waveform}
        setOsc2Waveform={setOsc2Waveform}
        setOscMix={setOscMix}
      />
      {isInitialized && (
        <>
          <Frequency
            hz={currentHzPitch}
            gain={isPlaying ? 1 - oscMix : 0}
            oscillator={osc1Waveform}
          />
          <Frequency
            hz={currentHzPitch}
            gain={isPlaying ? oscMix : 0}
            oscillator={osc2Waveform}
          />
        </>
      )}
    </main>
  );
}

The other components simply do as their names suggest. there is an ON button in which sets isInitialized to true so the audio context won't complain about a user gesture

thanks a lot!

0

There are 0 answers