waveform test

by falldeaf

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.12.1/system.min.js"></script>
<!-- <canvas id="c1"></canvas> -->
<button onclick="getimg()">download</button>
<button onclick="playsong()">play</button>
<canvas id="c2"></canvas>
<canvas id="c3"></canvas>
<canvas id="c4"></canvas>
<div id="playhead"></div>

CSS

body {
    background: rgb(0,0,0);
}

canvas {
    margin: 20px;
}

#playhead {
  position:absolute;
  height:256px;
  width:1px;
  border-left:1px solid white;
  top:0;
  left:0;
}

JavaScript

//System.import('https://cdn.jsdelivr.net/npm/[email protected]/dist/index.min.js');
//import { CurveInterpolator } from 'https://cdn.jsdelivr.net/npm/[email protected]/dist/index.min.js';

window.AudioContext = window.AudioContext || window.webkitAudioContext;
const audioContext = new AudioContext();

var threshold = 30;
var gliding = [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6];

const drawAudio = url => {
  window.url = url;
  fetch(url)
    .then(response => response.arrayBuffer())
    .then(arrayBuffer => audioContext.decodeAudioData(arrayBuffer))
    //.then(audioBuffer => draw(normalizeData(filterData(audioBuffer))))
    //.then(audioBuffer => printData(normalizeData(filterData(audioBuffer))))
    .then(audioBuffer => createImg(normalizeData(filterData(audioBuffer))));
  //.then(audioBuffer => createImg(filterData(audioBuffer)));
};

const filterData = audioBuffer => {
  const rawData = audioBuffer.getChannelData(0); // We only need to work with one channel of data


  const samples = parseInt(audioBuffer.duration / 0.001);
  window.samples = samples;

  console.log("dur: " + audioBuffer.duration);
  console.log("frames: " + samples);

  const blockSize = Math.floor(rawData.length / samples); // the number of samples in each subdivision
  const filteredData = [];
  for (let i = 0; i < samples; i++) {
    let blockStart = blockSize * i; // the location of the first sample in the block
    let sum = 0;
    for (let j = 0; j < blockSize; j++) {
      sum = sum + Math.abs(rawData[blockStart + j]); // find the sum of all the samples in the block
    }
    filteredData.push(sum / blockSize); // divide the sum by the block size to get the average
  }
  return filteredData;
};

const normalizeData = filteredData => {
  const multiplier = Math.pow(Math.max(...filteredData), -1);
  return filteredData.map(n => n * multiplier);
}

const printData = normalizedData => {
  for (let i = 0; i < normalizedData.length; i++) {
   ...