JSFiddle - React, Tailwind, and code Playground
HTML
wav, mp3などの音声ファイル<br>
<input type="file" onchange="onChange(event);"><br><br>
<input type="button" value="play" onclick="play();"><br><br>
<a id="anchor" download="xacalite.dat">xacalite.dat</a><br>
<canvas id="canvas"></canvas>
<pre id="output"></pre>
CSS
canvas {
border: 1px solid green;
}
JavaScript
"use strict";
const MAG = 1000;
const FREQ = 4181.7;
//const FREQ = 8363.4;
let ac; // AudioContext
let abuf; // AudioBuffer
let abuf2; // AudioBuffer
let pcm;
let dpcm;
onload = function() {
ac = new AudioContext();
};
function onChange(e) {
let file = e.target.files[0];
let fr = new FileReader();
fr.onload = function(e) {
// wav, mp3などの音声ファイルをデコードする
ac.decodeAudioData(e.target.result)
.then(decodedData => {
// リサンプリングする
let sr = FREQ;
let oac = new OfflineAudioContext(1, sr * 9, sr);
let src = oac.createBufferSource();
src.buffer = decodedData;
src.connect(oac.destination);
src.start();
oac.startRendering()
.then(renderedBuffer => {
abuf = renderedBuffer;
check();
encode();
draw();
decode();
download();
});
});
};
fr.readAsArrayBuffer(file);
}
function play() {
// AudioBufferSourceNode
let src = ac.createBufferSource();
src.connect(ac.destination);
src.buffer = abuf2;
src.start();
}
function check() {
let log = "";
log += `${abuf.sampleRate.toFixed(1)} Hz\n`;
log += `${abuf.length}\n`;
log += `${abuf.duration.toFixed(2)} s\n`;
log += `${abuf.numberOfChannels} ch\n`;
let data = abuf.getChannelData(0);
let min = data[0];
let max = data[0];
let sum = data[0];
for (let i = 1; i < data.length; i++) {
if (min > data[i]) min = data[i];
if (max < data[i]) max = data[i];
sum += data[i];
}
let avg = sum / data.length;
log += `len: ${data.length}\n`;
log += `min: ${min}\n`;
log += `max: ${max}\n`;
log += `avg: ${avg}\n`;
output.textContent = log;
}
function encode() {
let data = abuf.getChannelData(0);
let len = 32768;
pcm = new Uint8Array(len);
dpcm = new Uint8Array(len);
for (let i = 0; i < len; i++) {
pcm[i] = Math.min(Math.max(Math.floor(64+data[1000+i]*MAG), 0), 127);
}
let v = 64;
for (let i = 0; i < len; i++) {
if (v < pcm[i]) {
v++;
dpcm[i] = 1;
} else {
v--;
dpcm[i] = 0;
}
}
}
function decode() {
abuf2 =...