@echogarden/wave-codec
Version:
A fully-featured WAVE format encoder and decoder. Written in pure TypeScript.
160 lines • 6.17 kB
JavaScript
///////////////////////////////////////////////////////////////////////////////////////////////
// Int8
///////////////////////////////////////////////////////////////////////////////////////////////
export function readInt8(buffer, offset) {
const unsignedValue = buffer[offset];
if (unsignedValue < 128) {
return unsignedValue;
}
else {
return unsignedValue - 256;
}
}
export function writeInt8(buffer, value, offset) {
if (value < -128 || value > 127) {
throw new Error(`Value ${value} is outside the range of an 8-bit signed integer`);
}
let unsignedValue;
if (value >= 0) {
unsignedValue = value;
}
else {
unsignedValue = value + 256;
}
buffer[offset] = unsignedValue;
}
///////////////////////////////////////////////////////////////////////////////////////////////
// Uint8
///////////////////////////////////////////////////////////////////////////////////////////////
export function readUint8(buffer, offset) {
return buffer[offset];
}
export function writeUint8(buffer, value, offset) {
if (value < 0 || value > 255) {
throw new Error(`Value ${value} is outside the range of an 8-bit unsigned integer`);
}
buffer[offset] = value;
}
///////////////////////////////////////////////////////////////////////////////////////////////
// Int16LE
///////////////////////////////////////////////////////////////////////////////////////////////
export function readInt16LE(buffer, offset) {
const unsignedValue = readUint16LE(buffer, offset);
if (unsignedValue < 32768) {
return unsignedValue;
}
else {
return unsignedValue - 65536;
}
}
export function writeInt16LE(buffer, value, offset) {
if (value < -32768 || value > 32767) {
throw new Error(`Value ${value} is outside the range of a 16-bit signed integer`);
}
let unsignedValue;
if (value >= 0) {
unsignedValue = value;
}
else {
unsignedValue = value + 65536;
}
writeUint16LE(buffer, unsignedValue, offset);
}
///////////////////////////////////////////////////////////////////////////////////////////////
// Uint16LE
///////////////////////////////////////////////////////////////////////////////////////////////
export function readUint16LE(buffer, offset) {
return (buffer[offset]) | (buffer[offset + 1] << 8);
}
export function writeUint16LE(buffer, value, offset) {
if (value < 0 || value > 65535) {
throw new Error(`Value ${value} is outside the range of a 16-bit unsigned integer`);
}
buffer[offset] = value & 0xff;
buffer[offset + 1] = (value >>> 8) & 0xff;
}
///////////////////////////////////////////////////////////////////////////////////////////////
// Int16LE
///////////////////////////////////////////////////////////////////////////////////////////////
export function readInt32LE(buffer, offset) {
const value = (buffer[offset]) |
(buffer[offset + 1] << 8) |
(buffer[offset + 2] << 16) |
(buffer[offset + 3] << 24);
return value;
}
export function writeInt32LE(buffer, value, offset) {
if (value < -2147483648 || value > 2147483647) {
throw new Error(`Value ${value} is outside the range of a 32-bit signed integer`);
}
buffer[offset] = value & 0xff;
buffer[offset + 1] = (value >> 8) & 0xff;
buffer[offset + 2] = (value >> 16) & 0xff;
buffer[offset + 3] = (value >> 24) & 0xff;
}
///////////////////////////////////////////////////////////////////////////////////////////////
// Uint32LE
///////////////////////////////////////////////////////////////////////////////////////////////
export function readUint32LE(buffer, offset) {
return readInt32LE(buffer, offset) >>> 0;
}
export function writeUint32LE(buffer, value, offset) {
if (value < 0 || value > 4294967295) {
throw new Error(`Value ${value} is outside the range of a 32-bit unsigned integer`);
}
buffer[offset] = value & 0xff;
buffer[offset + 1] = (value >>> 8) & 0xff;
buffer[offset + 2] = (value >>> 16) & 0xff;
buffer[offset + 3] = (value >>> 24) & 0xff;
}
///////////////////////////////////////////////////////////////////////////////////////////////
// Ascii
///////////////////////////////////////////////////////////////////////////////////////////////
export function writeAscii(buffer, asciiString, writeStartOffset) {
const writeEndOffset = Math.min(writeStartOffset + asciiString.length, buffer.length);
let readOffset = 0;
let writeOffset = writeStartOffset;
while (writeOffset < writeEndOffset) {
const charCode = asciiString.charCodeAt(readOffset++);
if (charCode >= 128) {
throw new Error(`Character '${asciiString[readOffset]}' (code: ${charCode}) at offset ${readOffset} can't be encoded as ASCII`);
}
buffer[writeOffset++] = charCode;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
// Endianess
///////////////////////////////////////////////////////////////////////////////////////////////
export function reverseByteGroupsIfBigEndian(bytes, groupSize) {
if (isBigEndianArch()) {
return reverseByteGroups(bytes, groupSize);
}
else {
return bytes;
}
}
export function reverseByteGroups(bytes, groupSize) {
if (bytes.length % groupSize !== 0) {
throw new Error(`Byte count must be an integer multiple of the group size.`);
}
const groupEnd = groupSize - 1;
const result = new Uint8Array(bytes.length);
let offset = 0;
while (offset < bytes.length) {
for (let i = 0; i < groupSize; i++) {
result[offset + i] = bytes[offset + (groupEnd - i)];
}
offset += groupSize;
}
return result;
}
let isBigEndianArch_cached;
export function isBigEndianArch() {
if (isBigEndianArch_cached === undefined) {
const uint16Array = new Uint16Array([0x11_22]);
const byteView = new Uint8Array(uint16Array.buffer);
isBigEndianArch_cached = byteView[0] === 0x11;
}
return isBigEndianArch_cached;
}
//# sourceMappingURL=BinaryUtilities.js.map