Skip to content

Commit

Permalink
feat: add parser and sampler
Browse files Browse the repository at this point in the history
  • Loading branch information
raphaklaus committed Jan 10, 2018
1 parent b033a20 commit 6b3bcb2
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
70 changes: 70 additions & 0 deletions src/parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { play } from './sampler.js';

const load = () => {
let reader = new FileReader();

reader.onload = (loadedFile) => {
let binary = new Uint8Array(loadedFile.srcElement.result, 0, loadedFile.srcElement.result.byteLength);
parse(binary);
};

document.querySelector('[type="file"]').files[0] |> reader.readAsArrayBuffer;
};

const parse = (binary) => {
var sound = {
channelNumber: toLittleEndian(binary.slice(22, 23)),
sampleRate: toLittleEndian(binary.slice(24, 27)),
bitsPerSample: toLittleEndian(binary.slice(34, 35)),
dataLength: toLittleEndian(binary.slice(40, 43))
};

sound.data = Array.from(binary.slice(44, binary.length));

sound.data = sound.data.map((byte, index) => {
if (index % 2 === 0) {
var short = composeBytes(byte, sound.data[index + 1]);
var range = 1 << sound.bitsPerSample - 1;

if (short >= range) {
short |= ~(range -1);
}
return (short / range);

}
}).filter((item) => {
return item !== undefined;
});

sound.data.leftChannel = sound.data.map((short, index) => {
if (index % 2 === 0)
return short;
}).filter( (item) => {
return item !== undefined;
});

sound.data.rightChannel = sound.data.map((short, index) => {
if (index % 2 !== 0)
return short;
}).filter( (item) => {
return item !== undefined;
});

document.querySelector('.play-button').addEventListener('click', play.bind(null, sound));
};

const composeBytes = (low, high) => {
return parseInt(`0x${('00' + high.toString(16)).substr(-2)}${('00' + low.toString(16)).substr(-2)}`);
};

const toLittleEndian = (array) => {
return parseInt(array.slice().reverse().reduce((prev, current) => {
// review if
if (current)
return prev.toString(16) + current.toString(16);

return '';
}, ''), 16);
};

document.querySelector('.load-button').addEventListener('click', load);
22 changes: 22 additions & 0 deletions src/sampler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export const play = (sound) => {
var audio = new (window.AudioContext || window.webkitAudioContext)();

let data = audio.createBuffer(2, sound.dataLength / 2 * 8 / sound.bitsPerSample, sound.sampleRate);

for (var channel = 0; channel < sound.channelNumber; channel++) {
var nowBuffering = data.getChannelData(channel);
for (var i = 0; i < data.length; i++) {
if (channel === 0)
nowBuffering[i] = sound.data.leftChannel[i];
else
nowBuffering[i] = sound.data.rightChannel[i];
}
}

var source = audio.createBufferSource();
source.buffer = data;

source.connect(audio.destination);

source.start();
};

0 comments on commit 6b3bcb2

Please sign in to comment.