JS Process Binary File.

JavaScript process binary file by DataView object.

by Tinytsunami

HTML

<div id="demo">
  <canvas width="300px" height="120px"></canvas>
  <div></div>
  <div>
    <progress value="0" max="100"></progress>
  </div>
  <label>
    <input type="file" accept=".wav"/>
    <div>select file</div>
  </label>
  <button>upload</button>
</div>

CSS

body {
  color: #ffffff;
  background: #20262e;
  font-family: monospace, sans-serif;
}

#demo {
  padding: 5px;
}

#demo canvas {
  border: solid 1px #ffffff;
}

#demo label input {
  color: #ffffff;
  background: #20262e;
  outline: none;
  display: none;
}

#demo label div {
  float: left;
  font-size: 13.3333px;
  text-align: center;
  padding: 1px 6px;
  margin-right: 10px;
  color: #ffffff;
  background: #20262e;
  border: 1px solid #ffffff;
  outline: none;
}

#demo label div:hover {
  color: #20262e;
  background: #ffffff;
  border: 1px solid #ffffff;
}

#demo button {
  float: left;
  color: #ffffff;
  background: #20262e;
  border: 1px solid #ffffff;
  outline: none;
  margin-right: 10px;
}

#demo button:hover {
  color: #20262e;
  background: #ffffff;
  border: 1px solid #ffffff;
}

#demo progress {
  -webkit-appearance: none;
  appearance: none;
  width: 300px;
  margin: 5px 0px;
  border: solid 1px #ffffff;
}

#demo progress::-webkit-progress-bar {
  background: #20262e;
}

#demo progress::-webkit-progress-value {
  background: #3f4b5a;
}

JavaScript

(function() {
  /* get elements */
  let root = document.getElementById("demo");
  let canvasNode = root.getElementsByTagName("canvas")[0];
  let contentsNode = root.getElementsByTagName("div")[0];
  let progressNode = root.getElementsByTagName("progress")[0];
  let inputNode = root.getElementsByTagName("input")[0];
  let buttonNode = root.getElementsByTagName("Button")[0];
  let fileNode = root.getElementsByTagName("div")[2];
  let context = canvasNode.getContext("2d");

  /* get binary file's string */
  DataView.prototype.getString = function(offset, len) {
    let result = "";
    for (let i = 0; i < len; i++) {
      let value = this.getUint8(offset + i);
      result += String.fromCharCode(value);
    }
    return result;
  };

  inputNode.onchange = function() {
    let file = inputNode.files[0];
    if (file)
      fileNode.innerHTML = `${file.name}`;
  };

  buttonNode.onclick = function() {
    let file = inputNode.files[0];
    let fileReader = new FileReader();

    fileReader.onprogress = function() {
      let rate = event.loaded / event.total;
      progressNode.value = Math.floor(rate * 100);
    };

    fileReader.onload = function() {
      let contents = new DataView(event.target.result);
      let wav = {
        CHUNK_ID: contents.getString(0, 4),
        CHUNK_SIZE: contents.getUint32(4, true),
        FORMAT: contents.getString(8, 4),
        SUBCHUNK_1_ID: contents.getString(12, 4),
        SUBCHUNK_1_SIZE: contents.getUint32(16, true),
        AUDIO_FORMAT: contents.getUint16(20, true),
        NUM_CHANNELS: contents.getUint16(22, true),
        SAMPLE_RATE: contents.getUint32(24, true),
        BYTE_RATE: contents.getUint32(28, true),
        BLOCK_ALIGN: contents.getUint16(32, true),
        BITS_PER_SAMPLE: contents.getUint16(34, true),
        SUBCHUNK_2_ID: contents.getString(36, 4),
        SUBCHUNK_2_SIZE: contents.getUint32(40, true),
        data: []
      };

      let simple_size = wav.BITS_PER_SAMPLE * wav.NUM_CHANNELS;
     ...