This repository has been archived on 2026-03-06. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
openclaw-extensions/wecom/node_modules/music-metadata/lib/common/Util.js
T

153 lines
4.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { StringType } from 'token-types';
import { FieldDecodingError } from '../ParseError.js';
import { getUintBE } from 'uint8array-extras';
export function getBit(buf, off, bit) {
return (buf[off] & (1 << bit)) !== 0;
}
/**
* Find delimiting zero in uint8Array
* @param uint8Array Uint8Array to find the zero delimiter in
* @param encoding The string encoding used
* @return position in uint8Array where zero found, or uint8Array.length if not found
*/
export function findZero(uint8Array, encoding) {
const len = uint8Array.length;
if (encoding === 'utf-16le') {
// Look for 0x00 0x00 on 2-byte boundary
for (let i = 0; i + 1 < len; i += 2) {
if (uint8Array[i] === 0 && uint8Array[i + 1] === 0)
return i;
}
return len;
}
// latin1 / utf8 / utf16be (caller typically handles utf16be separately or via decode)
for (let i = 0; i < len; i++) {
if (uint8Array[i] === 0)
return i;
}
return len;
}
export function trimRightNull(x) {
const pos0 = x.indexOf('\0');
return pos0 === -1 ? x : x.substring(0, pos0);
}
function swapBytes(uint8Array) {
const l = uint8Array.length;
if ((l & 1) !== 0)
throw new FieldDecodingError('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;
}
/**
* Decode string
*/
export function decodeString(uint8Array, encoding) {
// annoying workaround for a double BOM issue
// https://github.com/leetreveil/musicmetadata/issues/84
if (uint8Array[0] === 0xFF && uint8Array[1] === 0xFE) { // little endian
return decodeString(uint8Array.subarray(2), encoding);
}
if (encoding === 'utf-16le' && uint8Array[0] === 0xFE && uint8Array[1] === 0xFF) {
// BOM, indicating big endian decoding
if ((uint8Array.length & 1) !== 0)
throw new FieldDecodingError('Expected even number of octets for 16-bit unicode string');
return decodeString(swapBytes(uint8Array), encoding);
}
return new StringType(uint8Array.length, encoding).get(uint8Array, 0);
}
export function stripNulls(str) {
str = str.replace(/^\x00+/g, '');
str = str.replace(/\x00+$/g, '');
return str;
}
/**
* Read bit-aligned number start from buffer
* Total offset in bits = byteOffset * 8 + bitOffset
* @param source Byte buffer
* @param byteOffset Starting offset in bytes
* @param bitOffset Starting offset in bits: 0 = lsb
* @param len Length of number in bits
* @return Decoded bit aligned number
*/
export function getBitAllignedNumber(source, byteOffset, bitOffset, len) {
const byteOff = byteOffset + ~~(bitOffset / 8);
const bitOff = bitOffset % 8;
let value = source[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(source, byteOffset, bitOffset + bitsRead, bitsLeft);
}
return value;
}
/**
* Read bit-aligned number start from buffer
* Total offset in bits = byteOffset * 8 + bitOffset
* @param source Byte Uint8Array
* @param byteOffset Starting offset in bytes
* @param bitOffset Starting offset in bits: 0 = most significant bit, 7 is the least significant bit
* @return True if bit is set
*/
export function isBitSet(source, byteOffset, bitOffset) {
return getBitAllignedNumber(source, byteOffset, bitOffset, 1) === 1;
}
export 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(' ');
}
/**
* Convert power ratio to DB
* ratio: [0..1]
*/
export function ratioToDb(ratio) {
return 10 * Math.log10(ratio);
}
/**
* Convert dB to ratio
* db Decibels
*/
export function dbToRatio(dB) {
return 10 ** (dB / 10);
}
/**
* Convert replay gain to ratio and Decibel
* @param value string holding a ratio like '0.034' or '-7.54 dB'
*/
export function toRatio(value) {
const ps = value.split(' ').map(p => p.trim().toLowerCase());
if (ps.length >= 1) {
const v = Number.parseFloat(ps[0]);
return ps.length === 2 && ps[1] === 'db' ? {
dB: v,
ratio: dbToRatio(v)
} : {
dB: ratioToDb(v),
ratio: v
};
}
}
/**
* Decode a big-endian unsigned integer from a Uint8Array.
* Supports dynamic length (1–8 bytes).
*/
export function decodeUintBE(uint8Array) {
if (uint8Array.length === 0) {
throw new Error("decodeUintBE: empty Uint8Array");
}
const view = new DataView(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength);
return getUintBE(view);
}