Initial working version
This commit is contained in:
+169
@@ -0,0 +1,169 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.toRatio = exports.dbToRatio = exports.ratioToDb = exports.a2hex = exports.isBitSet = exports.getBitAllignedNumber = exports.stripNulls = exports.decodeString = exports.trimRightNull = exports.findZero = exports.getBit = void 0;
|
||||
function getBit(buf, off, bit) {
|
||||
return (buf[off] & (1 << bit)) !== 0;
|
||||
}
|
||||
exports.getBit = getBit;
|
||||
/**
|
||||
* Found delimiting zero in uint8Array
|
||||
* @param uint8Array Uint8Array to find the zero delimiter in
|
||||
* @param start Offset in uint8Array
|
||||
* @param end Last position to parse in uint8Array
|
||||
* @param encoding The string encoding used
|
||||
* @return Absolute position on uint8Array where zero found
|
||||
*/
|
||||
function findZero(uint8Array, start, end, encoding) {
|
||||
let i = start;
|
||||
if (encoding === 'utf16le') {
|
||||
while (uint8Array[i] !== 0 || uint8Array[i + 1] !== 0) {
|
||||
if (i >= end)
|
||||
return end;
|
||||
i += 2;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
else {
|
||||
while (uint8Array[i] !== 0) {
|
||||
if (i >= end)
|
||||
return end;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
exports.findZero = findZero;
|
||||
function trimRightNull(x) {
|
||||
const pos0 = x.indexOf('\0');
|
||||
return pos0 === -1 ? x : x.substr(0, pos0);
|
||||
}
|
||||
exports.trimRightNull = trimRightNull;
|
||||
function swapBytes(uint8Array) {
|
||||
const l = uint8Array.length;
|
||||
if ((l & 1) !== 0)
|
||||
throw new Error('Buffer length must be even');
|
||||
for (let i = 0; i < l; i += 2) {
|
||||
const a = uint8Array[i];
|
||||
uint8Array[i] = uint8Array[i + 1];
|
||||
uint8Array[i + 1] = a;
|
||||
}
|
||||
return uint8Array;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param buffer Decoder input data
|
||||
* @param encoding 'utf16le' | 'utf16' | 'utf8' | 'iso-8859-1'
|
||||
* @return {string}
|
||||
*/
|
||||
function decodeString(buffer, encoding) {
|
||||
// annoying workaround for a double BOM issue
|
||||
// https://github.com/leetreveil/musicmetadata/issues/84
|
||||
let offset = 0;
|
||||
if (buffer[0] === 0xFF && buffer[1] === 0xFE) { // little endian
|
||||
if (encoding === 'utf16le') {
|
||||
offset = 2;
|
||||
}
|
||||
else if (buffer[2] === 0xFE && buffer[3] === 0xFF) {
|
||||
offset = 2; // Clear double BOM
|
||||
}
|
||||
}
|
||||
else if (encoding === 'utf16le' && buffer[0] === 0xFE && buffer[1] === 0xFF) {
|
||||
// BOM, indicating big endian decoding
|
||||
return decodeString(swapBytes(buffer), encoding);
|
||||
}
|
||||
return buffer.toString(encoding, offset);
|
||||
}
|
||||
exports.decodeString = decodeString;
|
||||
function stripNulls(str) {
|
||||
str = str.replace(/^\x00+/g, '');
|
||||
str = str.replace(/\x00+$/g, '');
|
||||
return str;
|
||||
}
|
||||
exports.stripNulls = stripNulls;
|
||||
/**
|
||||
* Read bit-aligned number start from buffer
|
||||
* Total offset in bits = byteOffset * 8 + bitOffset
|
||||
* @param buf Byte buffer
|
||||
* @param byteOffset Starting offset in bytes
|
||||
* @param bitOffset Starting offset in bits: 0 = lsb
|
||||
* @param len Length of number in bits
|
||||
* @return {number} decoded bit aligned number
|
||||
*/
|
||||
function getBitAllignedNumber(buf, byteOffset, bitOffset, len) {
|
||||
const byteOff = byteOffset + ~~(bitOffset / 8);
|
||||
const bitOff = bitOffset % 8;
|
||||
let value = buf[byteOff];
|
||||
value &= 0xff >> bitOff;
|
||||
const bitsRead = 8 - bitOff;
|
||||
const bitsLeft = len - bitsRead;
|
||||
if (bitsLeft < 0) {
|
||||
value >>= (8 - bitOff - len);
|
||||
}
|
||||
else if (bitsLeft > 0) {
|
||||
value <<= bitsLeft;
|
||||
value |= getBitAllignedNumber(buf, byteOffset, bitOffset + bitsRead, bitsLeft);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
exports.getBitAllignedNumber = getBitAllignedNumber;
|
||||
/**
|
||||
* Read bit-aligned number start from buffer
|
||||
* Total offset in bits = byteOffset * 8 + bitOffset
|
||||
* @param buf Byte buffer
|
||||
* @param byteOffset Starting offset in bytes
|
||||
* @param bitOffset Starting offset in bits: 0 = most significant bit, 7 is least significant bit
|
||||
* @return {number} decoded bit aligned number
|
||||
*/
|
||||
function isBitSet(buf, byteOffset, bitOffset) {
|
||||
return getBitAllignedNumber(buf, byteOffset, bitOffset, 1) === 1;
|
||||
}
|
||||
exports.isBitSet = isBitSet;
|
||||
function a2hex(str) {
|
||||
const arr = [];
|
||||
for (let i = 0, l = str.length; i < l; i++) {
|
||||
const hex = Number(str.charCodeAt(i)).toString(16);
|
||||
arr.push(hex.length === 1 ? '0' + hex : hex);
|
||||
}
|
||||
return arr.join(' ');
|
||||
}
|
||||
exports.a2hex = a2hex;
|
||||
/**
|
||||
* Convert power ratio to DB
|
||||
* ratio: [0..1]
|
||||
*/
|
||||
function ratioToDb(ratio) {
|
||||
return 10 * Math.log10(ratio);
|
||||
}
|
||||
exports.ratioToDb = ratioToDb;
|
||||
/**
|
||||
* Convert dB to ratio
|
||||
* db Decibels
|
||||
*/
|
||||
function dbToRatio(dB) {
|
||||
return Math.pow(10, dB / 10);
|
||||
}
|
||||
exports.dbToRatio = dbToRatio;
|
||||
/**
|
||||
* Convert replay gain to ratio and Decibel
|
||||
* @param value string holding a ratio like '0.034' or '-7.54 dB'
|
||||
*/
|
||||
function toRatio(value) {
|
||||
const ps = value.split(' ').map(p => p.trim().toLowerCase());
|
||||
// @ts-ignore
|
||||
if (ps.length >= 1) {
|
||||
const v = parseFloat(ps[0]);
|
||||
if (ps.length === 2 && ps[1] === 'db') {
|
||||
return {
|
||||
dB: v,
|
||||
ratio: dbToRatio(v)
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
dB: ratioToDb(v),
|
||||
ratio: v
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.toRatio = toRatio;
|
||||
Reference in New Issue
Block a user