goplus / builder

Go+ Builder
https://builder.goplus.org
19 stars 18 forks source link

Sound Wave refactor #599

Closed nighca closed 1 week ago

nighca commented 2 weeks ago
ComfyFluffy commented 2 weeks ago

To refactor, we need to:

For a regular audio file, we can get PCM data of channel directly with AudioBuffer.getChannelData().

For microphone streams, we can fetch PCM data in AudioWorklet and do processings in a separate thread:

const source = audioContext.createMediaStreamSource(stream)
await audioContext.audioWorklet.addModule('/logger-procesor.js')
const audioWorkletNode = new AudioWorkletNode(audioContext, 'logger-processor')
source.connect(audioWorkletNode)
...

// In logger-procesor.js:
class LoggerProcessor extends AudioWorkletProcessor {
  process(inputs, outputs) {
    const input = inputs[0]
    const output = outputs[0]

    const inputData = input[0]
    const outputData = output[0]

    console.log(inputData.length)

    for (let i = 0; i < inputData.length; ++i) {
      outputData[i] = inputData[i]
      // We can for example average the absolute value of data
      // in a channel and send the result to the main thread.
    }

    return true
  }
}

registerProcessor('logger-processor', LoggerProcessor)

Previously we use analyser.getFloatTimeDomainData() to get FFT transformed data of the waveform, which is not consistent with PCM-based rendering in wavesurfer.js.

nighca commented 2 weeks ago

We can potentially use a visualization library like d3 to achieve a better result.

It is probably unnecessary to involve another library like d3. The logic for wave-rendering is not complex with raw canvas 2D-context API.

Come up with a new approach to compute the loudness data from microphone stream in realtime.

If we've converted both audio file and microphone stream to the same audio data structure (e.g. PCM data as mentioned above), it should be possible to use the same method to get loudness data from them.