diff --git a/apps/chat/package.json b/apps/chat/package.json index 4d74c6841..7e4afc42f 100644 --- a/apps/chat/package.json +++ b/apps/chat/package.json @@ -53,7 +53,7 @@ "@tsndr/cloudflare-worker-jwt": "^2.5.3", "@types/eventsource": "^1.1.15", "@types/three": "^0.167.1", - "@upstreet/multiplayer": "file:../../packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer", + "agent-multiplayer": "^0.0.8", "@vercel/analytics": "1.1.2", "@vercel/kv": "1.0.1", "@vercel/og": "0.6.2", @@ -61,7 +61,7 @@ "class-variance-authority": "0.7.0", "classnames": "2.5.1", "clsx": "2.1.0", - "codecs": "file:../../packages/usdk/packages/upstreet-agent/packages/codecs", + "agent-codecs": "^0.0.3", "cookie": "^0.6.0", "d3-scale": "4.0.2", "date-fns": "3.3.1", @@ -79,7 +79,7 @@ "next-auth": "5.0.0-beta.4", "next-themes": "0.3.0", "openai": "^4.55.4", - "queue-manager": "file:../../packages/usdk/packages/upstreet-agent/packages/queue-manager", + "queue-manager-async": "^0.0.1", "react": "^18.2.0", "react-agents": "file:../../packages/usdk/packages/upstreet-agent/packages/react-agents", "react-agents-browser": "file:../../packages/usdk/packages/upstreet-agent/packages/react-agents-browser", @@ -104,7 +104,7 @@ "ucom": "file:../../packages/ucom/src", "usehooks-ts": "2.16.0", "web-worker": "1.2.0", - "zjs": "file:../../packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs", + "u8-encoder": "^0.0.5", "zod": "^3.23.8" }, "devDependencies": { diff --git a/packages/usdk/cli.js b/packages/usdk/cli.js index 35d879884..f6dc9fe6b 100644 --- a/packages/usdk/cli.js +++ b/packages/usdk/cli.js @@ -13,7 +13,7 @@ import { rimraf } from 'rimraf'; import Table from 'cli-table3'; -import { QueueManager } from './packages/upstreet-agent/packages/queue-manager/queue-manager.mjs'; +import { QueueManager } from 'queue-manager-async'; import { parseAgentSpecs } from './lib/agent-spec-utils.mjs'; import { getAgentPublicUrl, @@ -87,11 +87,11 @@ import { // import { // env, // } from './lib/env.mjs'; -import { timeAgo } from './packages/upstreet-agent/packages/react-agents/util/time-ago.mjs'; +// import { timeAgo } from './packages/upstreet-agent/packages/react-agents/util/time-ago.mjs'; import { featureSpecs } from './packages/upstreet-agent/packages/react-agents/util/agent-features-spec.mjs'; -import { AudioDecodeStream } from './packages/upstreet-agent/packages/codecs/audio-decode.mjs'; -import { WebPEncoder } from './packages/upstreet-agent/packages/codecs/webp-codec.mjs'; -import * as codecs from './packages/upstreet-agent/packages/codecs/ws-codec-runtime-fs.mjs'; +import { AudioDecodeStream } from 'agent-codecs/audio-decode.mjs'; +import { WebPEncoder } from 'agent-codecs/webp-codec.mjs'; +import * as codecs from 'agent-codecs/ws-codec-runtime-fs.mjs'; // import { runJest } from './lib/jest-util.mjs'; import { logUpstreetBanner } from './util/logger/log-utils.mjs'; import { makeCorsHeaders, getServerOpts } from './util/server-utils.mjs'; @@ -99,7 +99,7 @@ import { makeCorsHeaders, getServerOpts } from './util/server-utils.mjs'; // generateMnemonic, // } from './util/ethereum-utils.mjs'; import LoggerFactory from './util/logger/logger-factory.mjs'; -import { getLatestVersion } from './lib/version.mjs'; +// import { getLatestVersion } from './lib/version.mjs'; // import { // getDirectoryHash, // } from './util/hash-util.mjs'; diff --git a/packages/usdk/lib/interactor.js b/packages/usdk/lib/interactor.js index aa8635644..ea9758a43 100644 --- a/packages/usdk/lib/interactor.js +++ b/packages/usdk/lib/interactor.js @@ -2,7 +2,7 @@ import { z } from 'zod'; import dedent from 'dedent'; import { defaultModels } from '../packages/upstreet-agent/packages/react-agents/constants.mjs'; import { fetchJsonCompletion } from '../packages/upstreet-agent/packages/react-agents/util/fetch.mjs'; -import { QueueManager } from 'queue-manager'; +import { QueueManager } from 'queue-manager-async'; // diff --git a/packages/usdk/lib/login.mjs b/packages/usdk/lib/login.mjs index c2f16aa75..baa144bd9 100644 --- a/packages/usdk/lib/login.mjs +++ b/packages/usdk/lib/login.mjs @@ -5,15 +5,15 @@ import readline from 'readline'; import open from 'open'; // import { mkdirp } from 'mkdirp'; -import { rimraf } from 'rimraf'; -import { QueueManager } from '../packages/upstreet-agent/packages/queue-manager/queue-manager.mjs'; +// import { rimraf } from 'rimraf'; +import { QueueManager } from 'queue-manager-async'; import { localPort, callbackPort, } from '../util/ports.mjs'; import { getLoginJwt } from '../util/login-util.mjs'; import { makeCorsHeaders, getServerOpts } from '../util/server-utils.mjs'; -import { loginLocation } from './locations.mjs'; +// import { loginLocation } from './locations.mjs'; // diff --git a/packages/usdk/lib/zip-util.mjs b/packages/usdk/lib/zip-util.mjs index 9461fbe41..62cb95150 100644 --- a/packages/usdk/lib/zip-util.mjs +++ b/packages/usdk/lib/zip-util.mjs @@ -5,7 +5,7 @@ import { mkdirp } from 'mkdirp'; import { rimraf } from 'rimraf'; import JSZip from 'jszip'; import archiver from 'archiver'; -import { QueueManager } from 'queue-manager'; +import { QueueManager } from 'queue-manager-async'; // Helper function to filter files with regular expressions const filterFiles = (files, excludePatterns) => { diff --git a/packages/usdk/package.json b/packages/usdk/package.json index f6671260c..409ee0001 100644 --- a/packages/usdk/package.json +++ b/packages/usdk/package.json @@ -60,7 +60,6 @@ "@supabase/supabase-js": "^2.47.1", "@tsndr/cloudflare-worker-jwt": "2.5.3", "@types/estree": "^1.0.5", - "@wasm-audio-decoders/common": "file:./packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common", "alea": "^1.0.1", "ansi-escape-sequences": "^6.2.2", "ansi-escapes": "^7.0.0", @@ -68,11 +67,11 @@ "chalk": "^5.3.0", "character-card-utils": "file:./packages/upstreet-agent/packages/character-card-utils", "cli-table3": "^0.6.4", - "codecs": "file:./packages/upstreet-agent/packages/codecs", + "agent-codecs": "^0.0.3", "commander": "^12.0.0", "cookie": "^0.6.0", "cross-spawn": "^7.0.3", - "debouncer": "file:./packages/upstreet-agent/packages/debouncer", + "debouncer-async": "^0.0.1", "dedent": "^1.5.3", "dotenv": "^16.4.5", "electron": "^31.3.0", @@ -89,12 +88,9 @@ "jimp": "^1.6.0", "json5": "^2.2.3", "jszip": "^3.10.1", - "lamejs": "file:./packages/upstreet-agent/packages/codecs/packages/lamejs", - "libopusjs": "file:./packages/upstreet-agent/packages/codecs/packages/libopusjs", "memoize-one": "^6.0.0", "mime": "^4.0.1", "mkdirp": "^3.0.1", - "mpg123-decoder": "file:./packages/upstreet-agent/packages/codecs/packages/mpg123-decoder", "open": "^10.1.0", "openai": "^4.56.0", "ora": "^8.1.1", @@ -104,7 +100,7 @@ "pnpm": "^9.12.3", "pretty-bytes": "^6.1.1", "react-agents": "file:./packages/upstreet-agent/packages/react-agents", - "queue-manager": "file:./packages/upstreet-agent/packages/queue-manager", + "queue-manager-async": "^0.0.1", "react-agents-electron": "file:./packages/upstreet-agent/packages/react-agents-electron", "react-agents-node": "file:./packages/upstreet-agent/packages/react-agents-node", "react-agents-wrangler": "file:./packages/upstreet-agent/packages/react-agents-wrangler", @@ -133,7 +129,7 @@ "wrangler": "^3.95.0", "ws": "^8.17.0", "yjs": "^13.6.18", - "zjs": "file:./packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs", + "u8-encoder": "^0.0.5", "zod": "^3.23.8", "zod-to-ts": "^1.2.0", "zod-to-json-schema": "^3.23.5" diff --git a/packages/usdk/packages/upstreet-agent/package.json b/packages/usdk/packages/upstreet-agent/package.json index 34ea84b3f..c71f27eb1 100644 --- a/packages/usdk/packages/upstreet-agent/package.json +++ b/packages/usdk/packages/upstreet-agent/package.json @@ -10,8 +10,8 @@ "@tsndr/cloudflare-worker-jwt": "2.5.3", "@types/jest": "^29.5.13", "browser-util-inspect": "^0.2.0", - "codecs": "file:./packages/codecs", - "debouncer": "file:./packages/debouncer", + "agent-codecs": "^0.0.3", + "debouncer-async": "^0.0.1", "dedent": "^1.5.3", "dotenv": "^16.4.5", "ethers": "^6.12.0", @@ -23,7 +23,7 @@ "minimatch": "^9.0.4", "openai": "^4.56.0", "playwright-core-lite": "file:./packages/playwright-core-lite", - "queue-manager": "file:./packages/queue-manager", + "queue-manager-async": "^0.0.1", "react": "file:./packages/react", "react-agents": "file:./packages/react-agents", "react-agents-client": "file:./packages/react-agents-client", @@ -36,7 +36,7 @@ "typescript": "^5.6.2", "uuid-by-string": "^4.0.0", "yjs": "^13.6.18", - "zjs": "file:./packages/react-agents-client/packages/multiplayer/packages/zjs", + "u8-encoder": "^0.0.5", "zod": "^3.23.8", "zod-to-json-schema": "^3.23.5", "zod-to-ts": "^1.2.0" diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/audio-classes.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/audio-classes.mjs deleted file mode 100644 index 5414c8bb8..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/audio-classes.mjs +++ /dev/null @@ -1,31 +0,0 @@ -export class AudioOutput extends EventTarget { - constructor() { - super(); - - this.live = true; - } - write(data) { - this.dispatchEvent(new MessageEvent('data', { - data, - })); - } - end() { - this.live = false; - this.dispatchEvent(new MessageEvent('end')); - } - readAll() { - return new Promise((accept, reject) => { - const bs = []; - if (this.live) { - this.addEventListener('data', e => { - bs.push(e.data); - }); - this.addEventListener('end', () => { - accept(bs); - }); - } else { - accept(bs); - } - }); - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/audio-client.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/audio-client.mjs deleted file mode 100644 index 75b2e3b6a..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/audio-client.mjs +++ /dev/null @@ -1,630 +0,0 @@ -import {OpusAudioEncoder, OpusAudioDecoder, Mp3AudioEncoder, Mp3AudioDecoder} from './ws-codec.mjs'; -import {WsMediaStreamAudioReader, FakeAudioData} from './ws-codec-util.mjs'; -import {AudioOutput} from './audio-classes.mjs'; -import {getEncodedAudioChunkBuffer, getAudioDataBuffer} from './audio-util.mjs'; - -// opus stream -> decoded output audio node -export function createOpusAudioOutputStream({ - audioContext, - codecs, -}) { - if (!audioContext) { - throw new Error('missing audio context'); - } - if (!codecs) { - throw new Error('missing codecs'); - } - - const audioWorkletNode = new AudioWorkletNode( - audioContext, - 'ws-output-worklet', - ); - audioWorkletNode.addEventListener('processorerror', e => { - console.log('audioWorkletNode processorerror', e); - }); - audioWorkletNode.port.onmessage = e => { - // console.log('audio worklet node message', e.data); - const { - method, - } = e.data; - switch (method) { - case 'finish': { - // console.log('finish', performance.now()); - audioWorkletNode.dispatchEvent(new MessageEvent('finish')); - break; - } - default: { - console.warn('opus audio stream got unknown method', method); - break; - } - } - }; - - const audioDecoder = new OpusAudioDecoder({ - sampleRate: audioContext.sampleRate, - output: data => { - if (data) { - // console.log('decoded data', structuredClone(data?.data), performance.now()); - data = getAudioDataBuffer(data); - audioWorkletNode.port.postMessage(data, [data.buffer]); - } else { - audioWorkletNode.port.postMessage(null); - } - }, - }); - - return { - outputNode: audioWorkletNode, - audioDecoder, - write(data) { - // console.log('decode data', structuredClone(data)); - audioDecoder.decode(data); - }, - end() { - // console.log('decode end'); - audioDecoder.decode(null); - } - // close() { - // audioWorkletNode.disconnect(); - // audioDecoder.close(); - // }, - }; -} - -// media stream -> encoded opus audio output -export function createOpusMicrophoneSource({ - mediaStream, - audioContext, - codecs, -}) { - if (!audioContext) { - throw new Error('missing audio context'); - } - if (!mediaStream) { - throw new Error('missing media stream'); - } - if (!codecs) { - throw new Error('missing codecs'); - } - - const output = new AudioOutput(); - - const muxAndSend = encodedChunk => { - if (encodedChunk.data) { - const data = getEncodedAudioChunkBuffer(encodedChunk); - output.write(data); - } else { - output.end(); - } - }; - function onEncoderError(err) { - console.warn('encoder error', err); - } - const audioEncoder = new OpusAudioEncoder({ - sampleRate: audioContext.sampleRate, - codecs, - output: muxAndSend, - error: onEncoderError, - }); - - const audioReader = new WsMediaStreamAudioReader(mediaStream, { - audioContext, - }); - async function readAndEncode() { - const result = await audioReader.read(); - if (!result.done) { - audioEncoder.encode(result.value); - readAndEncode(); - } else { - audioEncoder.encode(new FakeAudioData()); - } - } - readAndEncode(); - - const id = crypto.randomUUID(); - - return { - id, - output, - mediaStream, - audioReader, - audioEncoder, - close() { - audioReader.cancel(); - // note: the encoder will close itself on an end packet - // audioEncoder.close(); - }, - }; -}; - -// media stream -> pcm (Float32) 48000 audio output -export function createPcmF32MicrophoneSource({ - mediaStream, - audioContext, -}) { - if (!audioContext) { - throw new Error('missing audio context'); - } - if (!mediaStream) { - throw new Error('missing media stream'); - } - - const output = new AudioOutput(); - - const audioReader = new WsMediaStreamAudioReader(mediaStream, { - audioContext, - sampleRate: 48000, - }); - const _readLoop = async () => { - for (;;) { - const result = await audioReader.read(); - if (!result.done) { - output.write(result.value.data); - } else { - output.end(); - break; - } - } - }; - _readLoop(); - - const id = crypto.randomUUID(); - - return { - id, - output, - mediaStream, - audioReader, - // audioEncoder, - close() { - audioReader.cancel(); - // note: the encoder will close itself on an end packet - // audioEncoder.close(); - }, - }; -}; - -// samples readable stream -> encoded opus audio output -export function createOpusReadableStreamSource({ - readableStream, - // audioContext, - codecs, -}) { - if (!readableStream) { - throw new Error('missing readable stream'); - } - if (!codecs) { - throw new Error('missing codecs'); - } - - const {sampleRate} = readableStream; - if (!sampleRate) { - throw new Error('createOpusReadableStreamSource: missing sample rate on readable stream'); - } - - // create output - const output = new AudioOutput(); - - // create encoder - const muxAndSend = encodedChunk => { - if (encodedChunk.data) { - const data = getEncodedAudioChunkBuffer(encodedChunk); - output.write(data); - } else { - output.end(); - } - }; - function onEncoderError(err) { - console.warn('encoder error', err); - } - const audioEncoder = new OpusAudioEncoder({ - sampleRate, - codecs, - output: muxAndSend, - error: onEncoderError, - }); - - // read the stream - (async () => { - const fakeAudioData = new FakeAudioData(); - const reader = readableStream.getReader(); - for (;;) { - const {done, value} = await reader.read(); - if (!done) { - fakeAudioData.set(value); - audioEncoder.encode(fakeAudioData); - } else { - fakeAudioData.set(null); - audioEncoder.encode(fakeAudioData); - break; - } - } - })(); - - // return result - const id = crypto.randomUUID(); - - return { - id, - output, - audioEncoder, - close() { - audioReader.cancel(); - // note: the encoder will close itself on an end packet - // audioEncoder.close(); - }, - }; -} - -// samples readable stream -> encoded mp3 audio output -export function createMp3ReadableStreamSource({ - readableStream, - // audioContext, - codecs, -}) { - if (!readableStream) { - throw new Error('missing readable stream'); - } - if (!codecs) { - throw new Error('missing codecs'); - } - - const {sampleRate} = readableStream; - if (!sampleRate) { - throw new Error('createMp3ReadableStreamSource: missing sample rate on stream'); - } - - // create output - const output = new AudioOutput(); - - // create encoder - const muxAndSend = encodedChunk => { - if (encodedChunk.data) { - const data = getEncodedAudioChunkBuffer(encodedChunk); - output.write(data); - } else { - output.end(); - } - }; - function onEncoderError(err) { - console.warn('encoder error', err); - } - const audioEncoder = new Mp3AudioEncoder({ - sampleRate, - codecs, - output: muxAndSend, - error: onEncoderError, - }); - - // read the stream - (async () => { - const fakeAudioData = new FakeAudioData(); - const reader = readableStream.getReader(); - for (;;) { - const {done, value} = await reader.read(); - if (!done) { - fakeAudioData.set(value); - audioEncoder.encode(fakeAudioData); - } else { - fakeAudioData.set(null); - audioEncoder.encode(fakeAudioData); - break; - } - } - })(); - - // return result - const id = crypto.randomUUID(); - - return { - id, - output, - audioEncoder, - close() { - audioReader.cancel(); - // note: the encoder will close itself on an end packet - // audioEncoder.close(); - }, - }; -} - -// media stream -> encoded mp3 audio output -export function createMp3MicrophoneSource({ - mediaStream, - audioContext, - codecs, -}) { - const output = new AudioOutput(); - - const muxAndSend = encodedChunk => { - if (encodedChunk.data) { - const data = getEncodedAudioChunkBuffer(encodedChunk); - output.write(data); - } else { - output.end(); - } - }; - function onEncoderError(err) { - console.warn('mp3 encoder error', err); - } - const audioEncoder = new Mp3AudioEncoder({ - sampleRate: audioContext.sampleRate, - output: muxAndSend, - error: onEncoderError, - }); - - const audioReader = new WsMediaStreamAudioReader(mediaStream, { - audioContext, - codecs, - }); - async function readAndEncode() { - const result = await audioReader.read(); - if (!result.done) { - audioEncoder.encode(result.value); - readAndEncode(); - } else { - audioEncoder.encode(new FakeAudioData()); - } - } - readAndEncode(); - - const id = crypto.randomUUID(); - - return { - id, - output, - mediaStream, - audioReader, - audioEncoder, - close() { - audioReader.cancel(); - // note: the encoder will close itself on an end packet - // audioEncoder.close(); - }, - }; -} - -// -// DECODER STREAMS -// - -export function createMp3DecodeTransformStream({ - sampleRate, - format = 'f32', - transferBuffers, - codecs, -}) { - if (!sampleRate) { - throw new Error('missing sample rate'); - } - if (!format) { - throw new Error('missing format'); - } - if (!codecs) { - throw new Error('missing codecs'); - } - - let controller; - const { - promise: donePromise, - resolve: doneResolve, - reject: doneReject, - } = Promise.withResolvers(); - const transformStream = new TransformStream({ - start: (c) => { - controller = c; - }, - transform: (chunk) => { - // console.log('decoding data', chunk); - audioDecoder.decode(chunk); - }, - flush: async () => { - audioDecoder.decode(null); - await donePromise; - }, - }); - - const muxAndSend = encodedChunk => { - // console.log('decoded data', encodedChunk); - if (encodedChunk) { - controller.enqueue(encodedChunk.data); - } else { - doneResolve(); - } - }; - function onDecoderError(err) { - console.warn('mp3 decoder error', err); - } - const audioDecoder = new Mp3AudioDecoder({ - sampleRate, - format, - codecs, - transferBuffers, - output: muxAndSend, - error: onDecoderError, - }); - - transformStream.readable.sampleRate = sampleRate; - transformStream.readable.format = format; - transformStream.abort = (reason) => { - transformStream.readable.cancel(reason); - transformStream.writable.abort(reason); - audioDecoder.close(); - }; - - return transformStream; -} - -export function createOpusDecodeTransformStream({ - sampleRate, - format = 'f32', - codecs, -}) { - if (!sampleRate) { - throw new Error('missing sample rate'); - } - if (!format) { - throw new Error('missing format'); - } - if (!codecs) { - throw new Error('missing codecs'); - } - - let controller; - const { - promise: donePromise, - resolve: doneResolve, - reject: doneReject, - } = Promise.withResolvers(); - const transformStream = new TransformStream({ - start: (c) => { - controller = c; - }, - transform: (chunk) => { - // console.log('decode data 1', chunk); - audioDecoder.decode(chunk); - }, - flush: async () => { - audioDecoder.decode(null); - await donePromise; - }, - }); - - const muxAndSend = encodedChunk => { - if (encodedChunk) { - // console.log('decode data', encodedChunk.data); - controller.enqueue(encodedChunk.data); - } else { - doneResolve(); - } - }; - function onDecoderError(err) { - console.warn('opus decoder error', err); - } - const audioDecoder = new OpusAudioDecoder({ - sampleRate, - format, - codecs, - output: muxAndSend, - error: onDecoderError, - }); - - transformStream.readable.sampleRate = sampleRate; - transformStream.readable.format = format; - transformStream.abort = (reason) => { - transformStream.readable.cancel(reason); - transformStream.writable.abort(reason); - audioDecoder.close(); - }; - - return transformStream; -} - -export function createPcmF32TransformStream({ - sampleRate, - format = 'f32', -}) { - if (!sampleRate) { - throw new Error('missing sample rate'); - } - if (!format) { - throw new Error('missing format'); - } - - throw new Error('not implemented'); - - // let controller; - const transformStream = new TransformStream({ - start: c => { - controller = c; - }, - transform: (chunk, controller) => { - console.log('decode pcm', chunk); - // const formatted = formatSamples(output, format, 'i16'); - }, - flush: async controller => { - console.log('flush pcm'); - // await donePromise; - }, - }); - - transformStream.readable.sampleRate = sampleRate; - transformStream.readable.format = format; - transformStream.abort = (reason) => { - transformStream.readable.cancel(reason); - transformStream.writable.abort(reason); - }; - - return transformStream; -} - -// -// ENCODER STREAMS -// - -export function createMp3EncodeTransformStream({ - sampleRate, - transferBuffers, - codecs, -}) { - if (!sampleRate) { - throw new Error('missing sample rate'); - } - if (!codecs) { - throw new Error('missing codecs'); - } - - let controller; - const { - promise: donePromise, - resolve: doneResolve, - reject: doneReject, - } = Promise.withResolvers(); - const transformStream = new TransformStream({ - start: (c) => { - controller = c; - }, - transform: (chunk) => { - const audioData = new FakeAudioData(); - audioData.data = new Float32Array(chunk.buffer, chunk.byteOffset, chunk.byteLength / Float32Array.BYTES_PER_ELEMENT); - audioEncoder.encode(audioData); - }, - flush: async () => { - // console.log('flush'); - audioEncoder.encode(new FakeAudioData()); - await donePromise; - }, - }); - - // create encoder - const muxAndSend = encodedChunk => { - // console.log('mux and send', encodedChunk); - if (encodedChunk.data) { - const data = getEncodedAudioChunkBuffer(encodedChunk); - // output.write(data); - controller.enqueue(data); - } else { - // output.end(); - doneResolve(); - } - }; - function onEncoderError(err) { - console.warn('mp3 encoder error', err); - } - const audioEncoder = new Mp3AudioEncoder({ - sampleRate, - transferBuffers, - codecs, - output: muxAndSend, - error: onEncoderError, - }); - - transformStream.readable.sampleRate = sampleRate; - transformStream.abort = (reason) => { - transformStream.readable.cancel(reason); - transformStream.writable.abort(reason); - audioEncoder.close(); - }; - - return transformStream; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/audio-decode.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/audio-decode.mjs deleted file mode 100644 index db231366c..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/audio-decode.mjs +++ /dev/null @@ -1,43 +0,0 @@ -import { - createMp3DecodeTransformStream, - createOpusDecodeTransformStream, - createPcmF32TransformStream, -} from './audio-client.mjs'; - -export class AudioDecodeStream { - constructor({ - type, - sampleRate, - format, - codecs, - }) { - if (!codecs) { - throw new Error('no codecs'); - } - - switch (type) { - case 'audio/mpeg': { - return createMp3DecodeTransformStream({ - sampleRate, - format, - codecs, - }); - } - case 'audio/opus': { - return createOpusDecodeTransformStream({ - sampleRate, - format, - }); - } - case 'audio/pcm-f32': { - return createPcmF32TransformStream({ - sampleRate, - format, - }); - } - default: { - throw new Error(`unhandled audio mime type: ${type}`); - } - } - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/audio-encode.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/audio-encode.mjs deleted file mode 100644 index c8152c0ba..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/audio-encode.mjs +++ /dev/null @@ -1,33 +0,0 @@ -import { createMp3EncodeTransformStream } from './audio-client.mjs'; - -export class AudioEncodeStream { - constructor({ - type, - sampleRate, - codecs, - transferBuffers, - }) { - if (!type) { - throw new Error('no type'); - } - if (!sampleRate) { - throw new Error('no sample rate'); - } - if (!codecs) { - throw new Error('no codecs'); - } - - switch (type) { - case 'audio/mpeg': { - return createMp3EncodeTransformStream({ - sampleRate, - codecs, - transferBuffers, - }); - } - default: { - throw new Error(`unhandled audio mime type: ${type}`); - } - } - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/audio-util.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/audio-util.mjs deleted file mode 100644 index 857b6e36c..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/audio-util.mjs +++ /dev/null @@ -1,22 +0,0 @@ -export const getAudioDataBuffer = audioData => { - let channelData; - if (audioData.copyTo) { // new api - channelData = new Float32Array(audioData.numberOfFrames); - audioData.copyTo(channelData, { - planeIndex: 0, - frameCount: audioData.numberOfFrames, - }); - } else { // old api - channelData = audioData.buffer.getChannelData(0); - } - return channelData; -}; -export const getEncodedAudioChunkBuffer = encodedAudioChunk => { - if (encodedAudioChunk.copyTo) { // new api - const data = new Uint8Array(encodedAudioChunk.byteLength); - encodedAudioChunk.copyTo(data); - return data; - } else { // old api - return new Uint8Array(encodedAudioChunk.data); - } -}; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/convert.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/convert.mjs deleted file mode 100644 index 2f31f11a9..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/convert.mjs +++ /dev/null @@ -1,17 +0,0 @@ -export function floatTo16Bit(inputArray){ - const output = new Int16Array(inputArray.length); - for (let i = 0; i < inputArray.length; i++){ - const s = Math.max(-1, Math.min(1, inputArray[i])); - output[i] = s < 0 ? s * 0x8000 : s * 0x7FFF; - } - return output; -} -export function int16ToFloat32(inputArray) { - const output = new Float32Array(inputArray.length); - for (let i = 0; i < inputArray.length; i++) { - const int = inputArray[i]; - const float = (int >= 0x8000) ? -(0x10000 - int) / 0x8000 : int / 0x7FFF; - output[i] = float; - } - return output; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/format.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/format.mjs deleted file mode 100644 index cd5d560da..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/format.mjs +++ /dev/null @@ -1,47 +0,0 @@ -import { int16ToFloat32, floatTo16Bit } from './convert.mjs'; - -const validFormats = ['f32', 'i16']; - -export const formatSamples = (samples, dstFormat, srcFormat) => { - if (!samples || !dstFormat || !srcFormat) { - throw new Error('missing arguments: ' + JSON.stringify({ - samples: !!samples, - dstFormat: !!dstFormat, - srcFormat: !!srcFormat, - })); - } - if (!validFormats.includes(srcFormat)) { - throw new Error('invalid srcFormat: ' + srcFormat); - } - if (!validFormats.includes(dstFormat)) { - throw new Error('invalid dstFormat: ' + dstFormat); - } - - if (dstFormat === srcFormat) { - return samples; - } else { - switch (dstFormat) { - case 'f32': { - if (srcFormat === 'i16') { - const i16 = samples; - const f32 = int16ToFloat32(i16); - return f32; - } else { - return samples; - } - } - case 'i16': { - if (srcFormat === 'f32') { - const f32 = samples; - const i16 = floatTo16Bit(f32); - return i16; - } else { - return samples; - } - } - default: { - throw new Error('invalid format: ' + format); - } - } - } -}; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/package.json b/packages/usdk/packages/upstreet-agent/packages/codecs/package.json deleted file mode 100644 index e37b2492d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "codecs", - "type": "module", - "dependencies": { - "lamejs": "file:./packages/lamejs", - "libopusjs": "file:./packages/libopusjs", - "mpg123-decoder": "file:./packages/mpg123-decoder", - "queue-manager": "file:../queue-manager", - "zjs": "file:../react-agents-client/packages/multiplayer/packages/zjs" - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/.gitignore b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/.gitignore deleted file mode 100644 index 737f08e0d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -.idea/* -.settings/* -target/* -*.iml -*.jar -.project -.classpath -node_modules diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/LICENSE b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/LICENSE deleted file mode 100644 index e456b65d3..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ -Can I use LAME in my commercial program? - -Yes, you can, under the restrictions of the LGPL. The easiest -way to do this is to: - -1. Link to LAME as separate jar (lame.min.js or lame.all.js) - -2. Fully acknowledge that you are using LAME, and give a link - to our web site, lame.sourceforge.net - -3. If you make modifications to LAME, you *must* release these - these modifications back to the LAME project, under the LGPL. diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/README.md b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/README.md deleted file mode 100644 index 8301ade5c..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/README.md +++ /dev/null @@ -1,121 +0,0 @@ -# lamejs -Fast mp3 encoder written in JavaScript. -On my machine it works 20x faster than realtime (it will encode 132 second long sample in 6.5 seconds) both on node and chrome. -lamejs is a rewrite of jump3r-code which is a rewrite of libmp3lame. - -## Installation - -To install via Bower or npm, simply do the following: - -```bash -$ bower install lamejs --save -``` - -```bash -$ npm install lamejs -``` - -# Quick Start - -```javascript - - -``` - -To use lamejs in Node.js build, you can install it from `npm`: - -``` -npm install lamejs -``` - -Then use it: - -``` -var lamejs = require("lamejs"); -``` - -# Real Example - -Either see [example.html](https://github.com/zhuker/lamejs/blob/master/example.html) for full example of wav file encoding in browser or use this: - -```javascript - - -``` - -# Stereo - -If you want to encode stereo mp3 use separate sample buffers for left and right channel - -```javascript - - -``` diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/bower.json b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/bower.json deleted file mode 100644 index 7f7bb1727..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/bower.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "lamejs", - "homepage": "https://github.com/zhuker/lamejs", - "description": "Fast mp3 encoder written in JavaScript. On my machine it works 20x faster than realtime (it will encode 132 second long sample in 6.5 seconds) both on node and chrome. lamejs is a rewrite of jump3r-code which is a rewrite of libmp3lame", - "source": "https://github.com/zhuker/lamejs.git", - "main": "lame.min.js" -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/doc/1000px-Mp3filestructure.svg.png b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/doc/1000px-Mp3filestructure.svg.png deleted file mode 100644 index 1715335fa..000000000 Binary files a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/doc/1000px-Mp3filestructure.svg.png and /dev/null differ diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/example.html b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/example.html deleted file mode 100644 index 8f4baa775..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/example.html +++ /dev/null @@ -1,52 +0,0 @@ - -Encoding mp3 from testdata/Left44100.wav - - - - diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/lame.all.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/lame.all.js deleted file mode 100644 index f73a1d1a9..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/lame.all.js +++ /dev/null @@ -1,15520 +0,0 @@ -function lamejs() { -function new_byte(count) { - return new Int8Array(count); -} - -function new_short(count) { - return new Int16Array(count); -} - -function new_int(count) { - return new Int32Array(count); -} - -function new_float(count) { - return new Float32Array(count); -} - -function new_double(count) { - return new Float64Array(count); -} - -function new_float_n(args) { - if (args.length == 1) { - return new_float(args[0]); - } - var sz = args[0]; - args = args.slice(1); - var A = []; - for (var i = 0; i < sz; i++) { - A.push(new_float_n(args)); - } - return A; -} -function new_int_n(args) { - if (args.length == 1) { - return new_int(args[0]); - } - var sz = args[0]; - args = args.slice(1); - var A = []; - for (var i = 0; i < sz; i++) { - A.push(new_int_n(args)); - } - return A; -} - -function new_short_n(args) { - if (args.length == 1) { - return new_short(args[0]); - } - var sz = args[0]; - args = args.slice(1); - var A = []; - for (var i = 0; i < sz; i++) { - A.push(new_short_n(args)); - } - return A; -} - -function new_array_n(args) { - if (args.length == 1) { - return new Array(args[0]); - } - var sz = args[0]; - args = args.slice(1); - var A = []; - for (var i = 0; i < sz; i++) { - A.push(new_array_n(args)); - } - return A; -} - - -var Arrays = {}; - -Arrays.fill = function (a, fromIndex, toIndex, val) { - if (arguments.length == 2) { - for (var i = 0; i < a.length; i++) { - a[i] = arguments[1]; - } - } else { - for (var i = fromIndex; i < toIndex; i++) { - a[i] = val; - } - } -}; - -var System = {}; - -System.arraycopy = function (src, srcPos, dest, destPos, length) { - var srcEnd = srcPos + length; - while (srcPos < srcEnd) - dest[destPos++] = src[srcPos++]; -}; - - -var Util = {}; -Util.SQRT2 = 1.41421356237309504880; -Util.FAST_LOG10 = function (x) { - return Math.log10(x); -}; - -Util.FAST_LOG10_X = function (x, y) { - return Math.log10(x) * y; -}; - -function ShortBlock(ordinal) { - this.ordinal = ordinal; -} -/** - * LAME may use them, even different block types for L/R. - */ -ShortBlock.short_block_allowed = new ShortBlock(0); -/** - * LAME may use them, but always same block types in L/R. - */ -ShortBlock.short_block_coupled = new ShortBlock(1); -/** - * LAME will not use short blocks, long blocks only. - */ -ShortBlock.short_block_dispensed = new ShortBlock(2); -/** - * LAME will not use long blocks, short blocks only. - */ -ShortBlock.short_block_forced = new ShortBlock(3); - -var Float = {}; -Float.MAX_VALUE = 3.4028235e+38; - -function VbrMode(ordinal) { - this.ordinal = ordinal; -} -VbrMode.vbr_off = new VbrMode(0); -VbrMode.vbr_mt = new VbrMode(1); -VbrMode.vbr_rh = new VbrMode(2); -VbrMode.vbr_abr = new VbrMode(3); -VbrMode.vbr_mtrh = new VbrMode(4); -VbrMode.vbr_default = VbrMode.vbr_mtrh; - -var assert = function (x) { - //console.assert(x); -}; - -var module_exports = { - "System": System, - "VbrMode": VbrMode, - "Float": Float, - "ShortBlock": ShortBlock, - "Util": Util, - "Arrays": Arrays, - "new_array_n": new_array_n, - "new_byte": new_byte, - "new_double": new_double, - "new_float": new_float, - "new_float_n": new_float_n, - "new_int": new_int, - "new_int_n": new_int_n, - "new_short": new_short, - "new_short_n": new_short_n, - "assert": assert -}; -//package mp3; - -/* MPEG modes */ -function MPEGMode(ordinal) { - var _ordinal = ordinal; - this.ordinal = function () { - return _ordinal; - } -} - -MPEGMode.STEREO = new MPEGMode(0); -MPEGMode.JOINT_STEREO = new MPEGMode(1); -MPEGMode.DUAL_CHANNEL = new MPEGMode(2); -MPEGMode.MONO = new MPEGMode(3); -MPEGMode.NOT_SET = new MPEGMode(4); - -function Version() { - - /** - * URL for the LAME website. - */ - var LAME_URL = "http://www.mp3dev.org/"; - - /** - * Major version number. - */ - var LAME_MAJOR_VERSION = 3; - /** - * Minor version number. - */ - var LAME_MINOR_VERSION = 98; - /** - * Patch level. - */ - var LAME_PATCH_VERSION = 4; - - /** - * Major version number. - */ - var PSY_MAJOR_VERSION = 0; - /** - * Minor version number. - */ - var PSY_MINOR_VERSION = 93; - - /** - * A string which describes the version of LAME. - * - * @return string which describes the version of LAME - */ - this.getLameVersion = function () { - // primary to write screen reports - return (LAME_MAJOR_VERSION + "." + LAME_MINOR_VERSION + "." + LAME_PATCH_VERSION); - } - - /** - * The short version of the LAME version string. - * - * @return short version of the LAME version string - */ - this.getLameShortVersion = function () { - // Adding date and time to version string makes it harder for output - // validation - return (LAME_MAJOR_VERSION + "." + LAME_MINOR_VERSION + "." + LAME_PATCH_VERSION); - } - - /** - * The shortest version of the LAME version string. - * - * @return shortest version of the LAME version string - */ - this.getLameVeryShortVersion = function () { - // Adding date and time to version string makes it harder for output - return ("LAME" + LAME_MAJOR_VERSION + "." + LAME_MINOR_VERSION + "r"); - } - - /** - * String which describes the version of GPSYCHO - * - * @return string which describes the version of GPSYCHO - */ - this.getPsyVersion = function () { - return (PSY_MAJOR_VERSION + "." + PSY_MINOR_VERSION); - } - - /** - * String which is a URL for the LAME website. - * - * @return string which is a URL for the LAME website - */ - this.getLameUrl = function () { - return LAME_URL; - } - - /** - * Quite useless for a java version, however we are compatible ;-) - * - * @return "32bits" - */ - this.getLameOsBitness = function () { - return "32bits"; - } - -} - -/* - * ReplayGainAnalysis - analyzes input samples and give the recommended dB change - * Copyright (C) 2001 David Robinson and Glen Sawyer - * Improvements and optimizations added by Frank Klemm, and by Marcel Muller - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * concept and filter values by David Robinson (David@Robinson.org) - * -- blame him if you think the idea is flawed - * original coding by Glen Sawyer (mp3gain@hotmail.com) - * -- blame him if you think this runs too slowly, or the coding is otherwise flawed - * - * lots of code improvements by Frank Klemm ( http://www.uni-jena.de/~pfk/mpp/ ) - * -- credit him for all the _good_ programming ;) - * - * - * For an explanation of the concepts and the basic algorithms involved, go to: - * http://www.replaygain.org/ - */ - -/* - * Here's the deal. Call - * - * InitGainAnalysis ( long samplefreq ); - * - * to initialize everything. Call - * - * AnalyzeSamples ( var Float_t* left_samples, - * var Float_t* right_samples, - * size_t num_samples, - * int num_channels ); - * - * as many times as you want, with as many or as few samples as you want. - * If mono, pass the sample buffer in through left_samples, leave - * right_samples NULL, and make sure num_channels = 1. - * - * GetTitleGain() - * - * will return the recommended dB level change for all samples analyzed - * SINCE THE LAST TIME you called GetTitleGain() OR InitGainAnalysis(). - * - * GetAlbumGain() - * - * will return the recommended dB level change for all samples analyzed - * since InitGainAnalysis() was called and finalized with GetTitleGain(). - * - * Pseudo-code to process an album: - * - * Float_t l_samples [4096]; - * Float_t r_samples [4096]; - * size_t num_samples; - * unsigned int num_songs; - * unsigned int i; - * - * InitGainAnalysis ( 44100 ); - * for ( i = 1; i <= num_songs; i++ ) { - * while ( ( num_samples = getSongSamples ( song[i], left_samples, right_samples ) ) > 0 ) - * AnalyzeSamples ( left_samples, right_samples, num_samples, 2 ); - * fprintf ("Recommended dB change for song %2d: %+6.2 dB\n", i, GetTitleGain() ); - * } - * fprintf ("Recommended dB change for whole album: %+6.2 dB\n", GetAlbumGain() ); - */ - -/* - * So here's the main source of potential code confusion: - * - * The filters applied to the incoming samples are IIR filters, - * meaning they rely on up to number of previous samples - * AND up to number of previous filtered samples. - * - * I set up the AnalyzeSamples routine to minimize memory usage and interface - * complexity. The speed isn't compromised too much (I don't think), but the - * internal complexity is higher than it should be for such a relatively - * simple routine. - * - * Optimization/clarity suggestions are welcome. - */ - -/** - * Table entries per dB - */ -GainAnalysis.STEPS_per_dB = 100.; -/** - * Table entries for 0...MAX_dB (normal max. values are 70...80 dB) - */ -GainAnalysis.MAX_dB = 120.; -GainAnalysis.GAIN_NOT_ENOUGH_SAMPLES = -24601; -GainAnalysis.GAIN_ANALYSIS_ERROR = 0; -GainAnalysis.GAIN_ANALYSIS_OK = 1; -GainAnalysis.INIT_GAIN_ANALYSIS_ERROR = 0; -GainAnalysis.INIT_GAIN_ANALYSIS_OK = 1; - -GainAnalysis.YULE_ORDER = 10; -GainAnalysis.MAX_ORDER = GainAnalysis.YULE_ORDER; - -GainAnalysis.MAX_SAMP_FREQ = 48000; -GainAnalysis.RMS_WINDOW_TIME_NUMERATOR = 1; -GainAnalysis.RMS_WINDOW_TIME_DENOMINATOR = 20; -GainAnalysis.MAX_SAMPLES_PER_WINDOW = ((GainAnalysis.MAX_SAMP_FREQ * GainAnalysis.RMS_WINDOW_TIME_NUMERATOR) / GainAnalysis.RMS_WINDOW_TIME_DENOMINATOR + 1); - -function GainAnalysis() { - /** - * calibration value for 89dB - */ - var PINK_REF = 64.82; - - var YULE_ORDER = GainAnalysis.YULE_ORDER; - /** - * percentile which is louder than the proposed level - */ - var RMS_PERCENTILE = 0.95; - /** - * maximum allowed sample frequency [Hz] - */ - var MAX_SAMP_FREQ = GainAnalysis.MAX_SAMP_FREQ; - var RMS_WINDOW_TIME_NUMERATOR = GainAnalysis.RMS_WINDOW_TIME_NUMERATOR; - /** - * numerator / denominator = time slice size [s] - */ - var RMS_WINDOW_TIME_DENOMINATOR = GainAnalysis.RMS_WINDOW_TIME_DENOMINATOR; - /** - * max. Samples per Time slice - */ - var MAX_SAMPLES_PER_WINDOW = GainAnalysis.MAX_SAMPLES_PER_WINDOW; - - - var ABYule = [ - [0.03857599435200, -3.84664617118067, -0.02160367184185, - 7.81501653005538, -0.00123395316851, -11.34170355132042, - -0.00009291677959, 13.05504219327545, -0.01655260341619, - -12.28759895145294, 0.02161526843274, 9.48293806319790, - -0.02074045215285, -5.87257861775999, 0.00594298065125, - 2.75465861874613, 0.00306428023191, -0.86984376593551, - 0.00012025322027, 0.13919314567432, 0.00288463683916], - [0.05418656406430, -3.47845948550071, -0.02911007808948, - 6.36317777566148, -0.00848709379851, -8.54751527471874, - -0.00851165645469, 9.47693607801280, -0.00834990904936, - -8.81498681370155, 0.02245293253339, 6.85401540936998, - -0.02596338512915, -4.39470996079559, 0.01624864962975, - 2.19611684890774, -0.00240879051584, -0.75104302451432, - 0.00674613682247, 0.13149317958808, -0.00187763777362], - [0.15457299681924, -2.37898834973084, -0.09331049056315, - 2.84868151156327, -0.06247880153653, -2.64577170229825, - 0.02163541888798, 2.23697657451713, -0.05588393329856, - -1.67148153367602, 0.04781476674921, 1.00595954808547, - 0.00222312597743, -0.45953458054983, 0.03174092540049, - 0.16378164858596, -0.01390589421898, -0.05032077717131, - 0.00651420667831, 0.02347897407020, -0.00881362733839], - [0.30296907319327, -1.61273165137247, -0.22613988682123, - 1.07977492259970, -0.08587323730772, -0.25656257754070, - 0.03282930172664, -0.16276719120440, -0.00915702933434, - -0.22638893773906, -0.02364141202522, 0.39120800788284, - -0.00584456039913, -0.22138138954925, 0.06276101321749, - 0.04500235387352, -0.00000828086748, 0.02005851806501, - 0.00205861885564, 0.00302439095741, -0.02950134983287], - [0.33642304856132, -1.49858979367799, -0.25572241425570, - 0.87350271418188, -0.11828570177555, 0.12205022308084, - 0.11921148675203, -0.80774944671438, -0.07834489609479, - 0.47854794562326, -0.00469977914380, -0.12453458140019, - -0.00589500224440, -0.04067510197014, 0.05724228140351, - 0.08333755284107, 0.00832043980773, -0.04237348025746, - -0.01635381384540, 0.02977207319925, -0.01760176568150], - [0.44915256608450, -0.62820619233671, -0.14351757464547, - 0.29661783706366, -0.22784394429749, -0.37256372942400, - -0.01419140100551, 0.00213767857124, 0.04078262797139, - -0.42029820170918, -0.12398163381748, 0.22199650564824, - 0.04097565135648, 0.00613424350682, 0.10478503600251, - 0.06747620744683, -0.01863887810927, 0.05784820375801, - -0.03193428438915, 0.03222754072173, 0.00541907748707], - [0.56619470757641, -1.04800335126349, -0.75464456939302, - 0.29156311971249, 0.16242137742230, -0.26806001042947, - 0.16744243493672, 0.00819999645858, -0.18901604199609, - 0.45054734505008, 0.30931782841830, -0.33032403314006, - -0.27562961986224, 0.06739368333110, 0.00647310677246, - -0.04784254229033, 0.08647503780351, 0.01639907836189, - -0.03788984554840, 0.01807364323573, -0.00588215443421], - [0.58100494960553, -0.51035327095184, -0.53174909058578, - -0.31863563325245, -0.14289799034253, -0.20256413484477, - 0.17520704835522, 0.14728154134330, 0.02377945217615, - 0.38952639978999, 0.15558449135573, -0.23313271880868, - -0.25344790059353, -0.05246019024463, 0.01628462406333, - -0.02505961724053, 0.06920467763959, 0.02442357316099, - -0.03721611395801, 0.01818801111503, -0.00749618797172], - [0.53648789255105, -0.25049871956020, -0.42163034350696, - -0.43193942311114, -0.00275953611929, -0.03424681017675, - 0.04267842219415, -0.04678328784242, -0.10214864179676, - 0.26408300200955, 0.14590772289388, 0.15113130533216, - -0.02459864859345, -0.17556493366449, -0.11202315195388, - -0.18823009262115, -0.04060034127000, 0.05477720428674, - 0.04788665548180, 0.04704409688120, -0.02217936801134]]; - - var ABButter = [ - [0.98621192462708, -1.97223372919527, -1.97242384925416, - 0.97261396931306, 0.98621192462708], - [0.98500175787242, -1.96977855582618, -1.97000351574484, - 0.97022847566350, 0.98500175787242], - [0.97938932735214, -1.95835380975398, -1.95877865470428, - 0.95920349965459, 0.97938932735214], - [0.97531843204928, -1.95002759149878, -1.95063686409857, - 0.95124613669835, 0.97531843204928], - [0.97316523498161, -1.94561023566527, -1.94633046996323, - 0.94705070426118, 0.97316523498161], - [0.96454515552826, -1.92783286977036, -1.92909031105652, - 0.93034775234268, 0.96454515552826], - [0.96009142950541, -1.91858953033784, -1.92018285901082, - 0.92177618768381, 0.96009142950541], - [0.95856916599601, -1.91542108074780, -1.91713833199203, - 0.91885558323625, 0.95856916599601], - [0.94597685600279, -1.88903307939452, -1.89195371200558, - 0.89487434461664, 0.94597685600279]]; - - - /** - * When calling this procedure, make sure that ip[-order] and op[-order] - * point to real data - */ - //private void filterYule(final float[] input, int inputPos, float[] output, - //int outputPos, int nSamples, final float[] kernel) { - function filterYule(input, inputPos, output, outputPos, nSamples, kernel) { - - while ((nSamples--) != 0) { - /* 1e-10 is a hack to avoid slowdown because of denormals */ - output[outputPos] = 1e-10 + input[inputPos + 0] * kernel[0] - - output[outputPos - 1] * kernel[1] + input[inputPos - 1] - * kernel[2] - output[outputPos - 2] * kernel[3] - + input[inputPos - 2] * kernel[4] - output[outputPos - 3] - * kernel[5] + input[inputPos - 3] * kernel[6] - - output[outputPos - 4] * kernel[7] + input[inputPos - 4] - * kernel[8] - output[outputPos - 5] * kernel[9] - + input[inputPos - 5] * kernel[10] - output[outputPos - 6] - * kernel[11] + input[inputPos - 6] * kernel[12] - - output[outputPos - 7] * kernel[13] + input[inputPos - 7] - * kernel[14] - output[outputPos - 8] * kernel[15] - + input[inputPos - 8] * kernel[16] - output[outputPos - 9] - * kernel[17] + input[inputPos - 9] * kernel[18] - - output[outputPos - 10] * kernel[19] - + input[inputPos - 10] * kernel[20]; - ++outputPos; - ++inputPos; - } - } - -//private void filterButter(final float[] input, int inputPos, -// float[] output, int outputPos, int nSamples, final float[] kernel) { - function filterButter(input, inputPos, output, outputPos, nSamples, kernel) { - - while ((nSamples--) != 0) { - output[outputPos] = input[inputPos + 0] * kernel[0] - - output[outputPos - 1] * kernel[1] + input[inputPos - 1] - * kernel[2] - output[outputPos - 2] * kernel[3] - + input[inputPos - 2] * kernel[4]; - ++outputPos; - ++inputPos; - } - } - - /** - * @return INIT_GAIN_ANALYSIS_OK if successful, INIT_GAIN_ANALYSIS_ERROR if - * not - */ - function ResetSampleFrequency(rgData, samplefreq) { - /* zero out initial values */ - for (var i = 0; i < MAX_ORDER; i++) - rgData.linprebuf[i] = rgData.lstepbuf[i] = rgData.loutbuf[i] = rgData.rinprebuf[i] = rgData.rstepbuf[i] = rgData.routbuf[i] = 0.; - - switch (0 | (samplefreq)) { - case 48000: - rgData.reqindex = 0; - break; - case 44100: - rgData.reqindex = 1; - break; - case 32000: - rgData.reqindex = 2; - break; - case 24000: - rgData.reqindex = 3; - break; - case 22050: - rgData.reqindex = 4; - break; - case 16000: - rgData.reqindex = 5; - break; - case 12000: - rgData.reqindex = 6; - break; - case 11025: - rgData.reqindex = 7; - break; - case 8000: - rgData.reqindex = 8; - break; - default: - return INIT_GAIN_ANALYSIS_ERROR; - } - - rgData.sampleWindow = 0 | ((samplefreq * RMS_WINDOW_TIME_NUMERATOR - + RMS_WINDOW_TIME_DENOMINATOR - 1) / RMS_WINDOW_TIME_DENOMINATOR); - - rgData.lsum = 0.; - rgData.rsum = 0.; - rgData.totsamp = 0; - - Arrays.ill(rgData.A, 0); - - return INIT_GAIN_ANALYSIS_OK; - } - - this.InitGainAnalysis = function (rgData, samplefreq) { - if (ResetSampleFrequency(rgData, samplefreq) != INIT_GAIN_ANALYSIS_OK) { - return INIT_GAIN_ANALYSIS_ERROR; - } - - rgData.linpre = MAX_ORDER; - rgData.rinpre = MAX_ORDER; - rgData.lstep = MAX_ORDER; - rgData.rstep = MAX_ORDER; - rgData.lout = MAX_ORDER; - rgData.rout = MAX_ORDER; - - Arrays.fill(rgData.B, 0); - - return INIT_GAIN_ANALYSIS_OK; - }; - - /** - * square - */ - function fsqr(d) { - return d * d; - } - - this.AnalyzeSamples = function (rgData, left_samples, left_samplesPos, right_samples, right_samplesPos, num_samples, - num_channels) { - var curleft; - var curleftBase; - var curright; - var currightBase; - var batchsamples; - var cursamples; - var cursamplepos; - - if (num_samples == 0) - return GAIN_ANALYSIS_OK; - - cursamplepos = 0; - batchsamples = num_samples; - - switch (num_channels) { - case 1: - right_samples = left_samples; - right_samplesPos = left_samplesPos; - break; - case 2: - break; - default: - return GAIN_ANALYSIS_ERROR; - } - - if (num_samples < MAX_ORDER) { - System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf, - MAX_ORDER, num_samples); - System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf, - MAX_ORDER, num_samples); - } else { - System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf, - MAX_ORDER, MAX_ORDER); - System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf, - MAX_ORDER, MAX_ORDER); - } - - while (batchsamples > 0) { - cursamples = batchsamples > rgData.sampleWindow - rgData.totsamp ? rgData.sampleWindow - - rgData.totsamp - : batchsamples; - if (cursamplepos < MAX_ORDER) { - curleft = rgData.linpre + cursamplepos; - curleftBase = rgData.linprebuf; - curright = rgData.rinpre + cursamplepos; - currightBase = rgData.rinprebuf; - if (cursamples > MAX_ORDER - cursamplepos) - cursamples = MAX_ORDER - cursamplepos; - } else { - curleft = left_samplesPos + cursamplepos; - curleftBase = left_samples; - curright = right_samplesPos + cursamplepos; - currightBase = right_samples; - } - - filterYule(curleftBase, curleft, rgData.lstepbuf, rgData.lstep - + rgData.totsamp, cursamples, ABYule[rgData.reqindex]); - filterYule(currightBase, curright, rgData.rstepbuf, rgData.rstep - + rgData.totsamp, cursamples, ABYule[rgData.reqindex]); - - filterButter(rgData.lstepbuf, rgData.lstep + rgData.totsamp, - rgData.loutbuf, rgData.lout + rgData.totsamp, cursamples, - ABButter[rgData.reqindex]); - filterButter(rgData.rstepbuf, rgData.rstep + rgData.totsamp, - rgData.routbuf, rgData.rout + rgData.totsamp, cursamples, - ABButter[rgData.reqindex]); - - curleft = rgData.lout + rgData.totsamp; - /* Get the squared values */ - curleftBase = rgData.loutbuf; - curright = rgData.rout + rgData.totsamp; - currightBase = rgData.routbuf; - - var i = cursamples % 8; - while ((i--) != 0) { - rgData.lsum += fsqr(curleftBase[curleft++]); - rgData.rsum += fsqr(currightBase[curright++]); - } - i = cursamples / 8; - while ((i--) != 0) { - rgData.lsum += fsqr(curleftBase[curleft + 0]) - + fsqr(curleftBase[curleft + 1]) - + fsqr(curleftBase[curleft + 2]) - + fsqr(curleftBase[curleft + 3]) - + fsqr(curleftBase[curleft + 4]) - + fsqr(curleftBase[curleft + 5]) - + fsqr(curleftBase[curleft + 6]) - + fsqr(curleftBase[curleft + 7]); - curleft += 8; - rgData.rsum += fsqr(currightBase[curright + 0]) - + fsqr(currightBase[curright + 1]) - + fsqr(currightBase[curright + 2]) - + fsqr(currightBase[curright + 3]) - + fsqr(currightBase[curright + 4]) - + fsqr(currightBase[curright + 5]) - + fsqr(currightBase[curright + 6]) - + fsqr(currightBase[curright + 7]); - curright += 8; - } - - batchsamples -= cursamples; - cursamplepos += cursamples; - rgData.totsamp += cursamples; - if (rgData.totsamp == rgData.sampleWindow) { - /* Get the Root Mean Square (RMS) for this set of samples */ - var val = GainAnalysis.STEPS_per_dB - * 10. - * Math.log10((rgData.lsum + rgData.rsum) - / rgData.totsamp * 0.5 + 1.e-37); - var ival = (val <= 0) ? 0 : 0 | val; - if (ival >= rgData.A.length) - ival = rgData.A.length - 1; - rgData.A[ival]++; - rgData.lsum = rgData.rsum = 0.; - - System.arraycopy(rgData.loutbuf, rgData.totsamp, - rgData.loutbuf, 0, MAX_ORDER); - System.arraycopy(rgData.routbuf, rgData.totsamp, - rgData.routbuf, 0, MAX_ORDER); - System.arraycopy(rgData.lstepbuf, rgData.totsamp, - rgData.lstepbuf, 0, MAX_ORDER); - System.arraycopy(rgData.rstepbuf, rgData.totsamp, - rgData.rstepbuf, 0, MAX_ORDER); - rgData.totsamp = 0; - } - if (rgData.totsamp > rgData.sampleWindow) { - /* - * somehow I really screwed up: Error in programming! Contact - * author about totsamp > sampleWindow - */ - return GAIN_ANALYSIS_ERROR; - } - } - if (num_samples < MAX_ORDER) { - System.arraycopy(rgData.linprebuf, num_samples, rgData.linprebuf, - 0, MAX_ORDER - num_samples); - System.arraycopy(rgData.rinprebuf, num_samples, rgData.rinprebuf, - 0, MAX_ORDER - num_samples); - System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf, - MAX_ORDER - num_samples, num_samples); - System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf, - MAX_ORDER - num_samples, num_samples); - } else { - System.arraycopy(left_samples, left_samplesPos + num_samples - - MAX_ORDER, rgData.linprebuf, 0, MAX_ORDER); - System.arraycopy(right_samples, right_samplesPos + num_samples - - MAX_ORDER, rgData.rinprebuf, 0, MAX_ORDER); - } - - return GAIN_ANALYSIS_OK; - }; - - function analyzeResult(Array, len) { - var i; - - var elems = 0; - for (i = 0; i < len; i++) - elems += Array[i]; - if (elems == 0) - return GAIN_NOT_ENOUGH_SAMPLES; - - var upper = 0 | Math.ceil(elems * (1. - RMS_PERCENTILE)); - for (i = len; i-- > 0;) { - if ((upper -= Array[i]) <= 0) - break; - } - - //return (float) ((float) PINK_REF - (float) i / (float) STEPS_per_dB); - return (PINK_REF - i / GainAnalysis.STEPS_per_dB); - } - - this.GetTitleGain = function (rgData) { - var retval = analyzeResult(rgData.A, rgData.A.length); - - for (var i = 0; i < rgData.A.length; i++) { - rgData.B[i] += rgData.A[i]; - rgData.A[i] = 0; - } - - for (var i = 0; i < MAX_ORDER; i++) - rgData.linprebuf[i] = rgData.lstepbuf[i] = rgData.loutbuf[i] = rgData.rinprebuf[i] = rgData.rstepbuf[i] = rgData.routbuf[i] = 0.; - - rgData.totsamp = 0; - rgData.lsum = rgData.rsum = 0.; - return retval; - } - -} - - -function Presets() { - function VBRPresets(qual, comp, compS, - y, shThreshold, shThresholdS, - adj, adjShort, lower, - curve, sens, inter, - joint, mod, fix) { - this.vbr_q = qual; - this.quant_comp = comp; - this.quant_comp_s = compS; - this.expY = y; - this.st_lrm = shThreshold; - this.st_s = shThresholdS; - this.masking_adj = adj; - this.masking_adj_short = adjShort; - this.ath_lower = lower; - this.ath_curve = curve; - this.ath_sensitivity = sens; - this.interch = inter; - this.safejoint = joint; - this.sfb21mod = mod; - this.msfix = fix; - } - - function ABRPresets(kbps, comp, compS, - joint, fix, shThreshold, - shThresholdS, bass, sc, - mask, lower, curve, - interCh, sfScale) { - this.quant_comp = comp; - this.quant_comp_s = compS; - this.safejoint = joint; - this.nsmsfix = fix; - this.st_lrm = shThreshold; - this.st_s = shThresholdS; - this.nsbass = bass; - this.scale = sc; - this.masking_adj = mask; - this.ath_lower = lower; - this.ath_curve = curve; - this.interch = interCh; - this.sfscale = sfScale; - } - - var lame; - - this.setModules = function (_lame) { - lame = _lame; - }; - - /** - *
-     * Switch mappings for VBR mode VBR_RH
-     *             vbr_q  qcomp_l  qcomp_s  expY  st_lrm   st_s  mask adj_l  adj_s  ath_lower  ath_curve  ath_sens  interChR  safejoint sfb21mod  msfix
-     * 
- */ - var vbr_old_switch_map = [ - new VBRPresets(0, 9, 9, 0, 5.20, 125.0, -4.2, -6.3, 4.8, 1, 0, 0, 2, 21, 0.97), - new VBRPresets(1, 9, 9, 0, 5.30, 125.0, -3.6, -5.6, 4.5, 1.5, 0, 0, 2, 21, 1.35), - new VBRPresets(2, 9, 9, 0, 5.60, 125.0, -2.2, -3.5, 2.8, 2, 0, 0, 2, 21, 1.49), - new VBRPresets(3, 9, 9, 1, 5.80, 130.0, -1.8, -2.8, 2.6, 3, -4, 0, 2, 20, 1.64), - new VBRPresets(4, 9, 9, 1, 6.00, 135.0, -0.7, -1.1, 1.1, 3.5, -8, 0, 2, 0, 1.79), - new VBRPresets(5, 9, 9, 1, 6.40, 140.0, 0.5, 0.4, -7.5, 4, -12, 0.0002, 0, 0, 1.95), - new VBRPresets(6, 9, 9, 1, 6.60, 145.0, 0.67, 0.65, -14.7, 6.5, -19, 0.0004, 0, 0, 2.30), - new VBRPresets(7, 9, 9, 1, 6.60, 145.0, 0.8, 0.75, -19.7, 8, -22, 0.0006, 0, 0, 2.70), - new VBRPresets(8, 9, 9, 1, 6.60, 145.0, 1.2, 1.15, -27.5, 10, -23, 0.0007, 0, 0, 0), - new VBRPresets(9, 9, 9, 1, 6.60, 145.0, 1.6, 1.6, -36, 11, -25, 0.0008, 0, 0, 0), - new VBRPresets(10, 9, 9, 1, 6.60, 145.0, 2.0, 2.0, -36, 12, -25, 0.0008, 0, 0, 0) - ]; - - /** - *
-     *                 vbr_q  qcomp_l  qcomp_s  expY  st_lrm   st_s  mask adj_l  adj_s  ath_lower  ath_curve  ath_sens  interChR  safejoint sfb21mod  msfix
-     * 
- */ - var vbr_psy_switch_map = [ - new VBRPresets(0, 9, 9, 0, 4.20, 25.0, -7.0, -4.0, 7.5, 1, 0, 0, 2, 26, 0.97), - new VBRPresets(1, 9, 9, 0, 4.20, 25.0, -5.6, -3.6, 4.5, 1.5, 0, 0, 2, 21, 1.35), - new VBRPresets(2, 9, 9, 0, 4.20, 25.0, -4.4, -1.8, 2, 2, 0, 0, 2, 18, 1.49), - new VBRPresets(3, 9, 9, 1, 4.20, 25.0, -3.4, -1.25, 1.1, 3, -4, 0, 2, 15, 1.64), - new VBRPresets(4, 9, 9, 1, 4.20, 25.0, -2.2, 0.1, 0, 3.5, -8, 0, 2, 0, 1.79), - new VBRPresets(5, 9, 9, 1, 4.20, 25.0, -1.0, 1.65, -7.7, 4, -12, 0.0002, 0, 0, 1.95), - new VBRPresets(6, 9, 9, 1, 4.20, 25.0, -0.0, 2.47, -7.7, 6.5, -19, 0.0004, 0, 0, 2), - new VBRPresets(7, 9, 9, 1, 4.20, 25.0, 0.5, 2.0, -14.5, 8, -22, 0.0006, 0, 0, 2), - new VBRPresets(8, 9, 9, 1, 4.20, 25.0, 1.0, 2.4, -22.0, 10, -23, 0.0007, 0, 0, 2), - new VBRPresets(9, 9, 9, 1, 4.20, 25.0, 1.5, 2.95, -30.0, 11, -25, 0.0008, 0, 0, 2), - new VBRPresets(10, 9, 9, 1, 4.20, 25.0, 2.0, 2.95, -36.0, 12, -30, 0.0008, 0, 0, 2) - ]; - - function apply_vbr_preset(gfp, a, enforce) { - var vbr_preset = gfp.VBR == VbrMode.vbr_rh ? vbr_old_switch_map - : vbr_psy_switch_map; - - var x = gfp.VBR_q_frac; - var p = vbr_preset[a]; - var q = vbr_preset[a + 1]; - var set = p; - - // NOOP(vbr_q); - // NOOP(quant_comp); - // NOOP(quant_comp_s); - // NOOP(expY); - p.st_lrm = p.st_lrm + x * (q.st_lrm - p.st_lrm); - // LERP(st_lrm); - p.st_s = p.st_s + x * (q.st_s - p.st_s); - // LERP(st_s); - p.masking_adj = p.masking_adj + x * (q.masking_adj - p.masking_adj); - // LERP(masking_adj); - p.masking_adj_short = p.masking_adj_short + x - * (q.masking_adj_short - p.masking_adj_short); - // LERP(masking_adj_short); - p.ath_lower = p.ath_lower + x * (q.ath_lower - p.ath_lower); - // LERP(ath_lower); - p.ath_curve = p.ath_curve + x * (q.ath_curve - p.ath_curve); - // LERP(ath_curve); - p.ath_sensitivity = p.ath_sensitivity + x - * (q.ath_sensitivity - p.ath_sensitivity); - // LERP(ath_sensitivity); - p.interch = p.interch + x * (q.interch - p.interch); - // LERP(interch); - // NOOP(safejoint); - // NOOP(sfb21mod); - p.msfix = p.msfix + x * (q.msfix - p.msfix); - // LERP(msfix); - - lame_set_VBR_q(gfp, set.vbr_q); - - if (enforce != 0) - gfp.quant_comp = set.quant_comp; - else if (!(Math.abs(gfp.quant_comp - -1) > 0)) - gfp.quant_comp = set.quant_comp; - // SET_OPTION(quant_comp, set.quant_comp, -1); - if (enforce != 0) - gfp.quant_comp_short = set.quant_comp_s; - else if (!(Math.abs(gfp.quant_comp_short - -1) > 0)) - gfp.quant_comp_short = set.quant_comp_s; - // SET_OPTION(quant_comp_short, set.quant_comp_s, -1); - if (set.expY != 0) { - gfp.experimentalY = set.expY != 0; - } - if (enforce != 0) - gfp.internal_flags.nsPsy.attackthre = set.st_lrm; - else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre - -1) > 0)) - gfp.internal_flags.nsPsy.attackthre = set.st_lrm; - // SET_OPTION(short_threshold_lrm, set.st_lrm, -1); - if (enforce != 0) - gfp.internal_flags.nsPsy.attackthre_s = set.st_s; - else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre_s - -1) > 0)) - gfp.internal_flags.nsPsy.attackthre_s = set.st_s; - // SET_OPTION(short_threshold_s, set.st_s, -1); - if (enforce != 0) - gfp.maskingadjust = set.masking_adj; - else if (!(Math.abs(gfp.maskingadjust - 0) > 0)) - gfp.maskingadjust = set.masking_adj; - // SET_OPTION(maskingadjust, set.masking_adj, 0); - if (enforce != 0) - gfp.maskingadjust_short = set.masking_adj_short; - else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0)) - gfp.maskingadjust_short = set.masking_adj_short; - // SET_OPTION(maskingadjust_short, set.masking_adj_short, 0); - if (enforce != 0) - gfp.ATHlower = -set.ath_lower / 10.0; - else if (!(Math.abs((-gfp.ATHlower * 10.0) - 0) > 0)) - gfp.ATHlower = -set.ath_lower / 10.0; - // SET_OPTION(ATHlower, set.ath_lower, 0); - if (enforce != 0) - gfp.ATHcurve = set.ath_curve; - else if (!(Math.abs(gfp.ATHcurve - -1) > 0)) - gfp.ATHcurve = set.ath_curve; - // SET_OPTION(ATHcurve, set.ath_curve, -1); - if (enforce != 0) - gfp.athaa_sensitivity = set.ath_sensitivity; - else if (!(Math.abs(gfp.athaa_sensitivity - -1) > 0)) - gfp.athaa_sensitivity = set.ath_sensitivity; - // SET_OPTION(athaa_sensitivity, set.ath_sensitivity, 0); - if (set.interch > 0) { - if (enforce != 0) - gfp.interChRatio = set.interch; - else if (!(Math.abs(gfp.interChRatio - -1) > 0)) - gfp.interChRatio = set.interch; - // SET_OPTION(interChRatio, set.interch, -1); - } - - /* parameters for which there is no proper set/get interface */ - if (set.safejoint > 0) { - gfp.exp_nspsytune = gfp.exp_nspsytune | set.safejoint; - } - if (set.sfb21mod > 0) { - gfp.exp_nspsytune = gfp.exp_nspsytune | (set.sfb21mod << 20); - } - if (enforce != 0) - gfp.msfix = set.msfix; - else if (!(Math.abs(gfp.msfix - -1) > 0)) - gfp.msfix = set.msfix; - // SET_OPTION(msfix, set.msfix, -1); - - if (enforce == 0) { - gfp.VBR_q = a; - gfp.VBR_q_frac = x; - } - } - - /** - *
-     *  Switch mappings for ABR mode
-     *
-     *              kbps  quant q_s safejoint nsmsfix st_lrm  st_s  ns-bass scale   msk ath_lwr ath_curve  interch , sfscale
-     * 
- */ - var abr_switch_map = [ - new ABRPresets(8, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -30.0, 11, 0.0012, 1), /* 8, impossible to use in stereo */ - new ABRPresets(16, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -25.0, 11, 0.0010, 1), /* 16 */ - new ABRPresets(24, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -20.0, 11, 0.0010, 1), /* 24 */ - new ABRPresets(32, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -15.0, 11, 0.0010, 1), /* 32 */ - new ABRPresets(40, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -10.0, 11, 0.0009, 1), /* 40 */ - new ABRPresets(48, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -10.0, 11, 0.0009, 1), /* 48 */ - new ABRPresets(56, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -6.0, 11, 0.0008, 1), /* 56 */ - new ABRPresets(64, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -2.0, 11, 0.0008, 1), /* 64 */ - new ABRPresets(80, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, .0, 8, 0.0007, 1), /* 80 */ - new ABRPresets(96, 9, 9, 0, 2.50, 6.60, 145, 0, 0.95, 0, 1.0, 5.5, 0.0006, 1), /* 96 */ - new ABRPresets(112, 9, 9, 0, 2.25, 6.60, 145, 0, 0.95, 0, 2.0, 4.5, 0.0005, 1), /* 112 */ - new ABRPresets(128, 9, 9, 0, 1.95, 6.40, 140, 0, 0.95, 0, 3.0, 4, 0.0002, 1), /* 128 */ - new ABRPresets(160, 9, 9, 1, 1.79, 6.00, 135, 0, 0.95, -2, 5.0, 3.5, 0, 1), /* 160 */ - new ABRPresets(192, 9, 9, 1, 1.49, 5.60, 125, 0, 0.97, -4, 7.0, 3, 0, 0), /* 192 */ - new ABRPresets(224, 9, 9, 1, 1.25, 5.20, 125, 0, 0.98, -6, 9.0, 2, 0, 0), /* 224 */ - new ABRPresets(256, 9, 9, 1, 0.97, 5.20, 125, 0, 1.00, -8, 10.0, 1, 0, 0), /* 256 */ - new ABRPresets(320, 9, 9, 1, 0.90, 5.20, 125, 0, 1.00, -10, 12.0, 0, 0, 0) /* 320 */ - ]; - - function apply_abr_preset(gfp, preset, enforce) { - /* Variables for the ABR stuff */ - var actual_bitrate = preset; - - var r = lame.nearestBitrateFullIndex(preset); - - gfp.VBR = VbrMode.vbr_abr; - gfp.VBR_mean_bitrate_kbps = actual_bitrate; - gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps, 320); - gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps, 8); - gfp.brate = gfp.VBR_mean_bitrate_kbps; - if (gfp.VBR_mean_bitrate_kbps > 320) { - gfp.disable_reservoir = true; - } - - /* parameters for which there is no proper set/get interface */ - if (abr_switch_map[r].safejoint > 0) - gfp.exp_nspsytune = gfp.exp_nspsytune | 2; - /* safejoint */ - - if (abr_switch_map[r].sfscale > 0) { - gfp.internal_flags.noise_shaping = 2; - } - /* ns-bass tweaks */ - if (Math.abs(abr_switch_map[r].nsbass) > 0) { - var k = (int)(abr_switch_map[r].nsbass * 4); - if (k < 0) - k += 64; - gfp.exp_nspsytune = gfp.exp_nspsytune | (k << 2); - } - - if (enforce != 0) - gfp.quant_comp = abr_switch_map[r].quant_comp; - else if (!(Math.abs(gfp.quant_comp - -1) > 0)) - gfp.quant_comp = abr_switch_map[r].quant_comp; - // SET_OPTION(quant_comp, abr_switch_map[r].quant_comp, -1); - if (enforce != 0) - gfp.quant_comp_short = abr_switch_map[r].quant_comp_s; - else if (!(Math.abs(gfp.quant_comp_short - -1) > 0)) - gfp.quant_comp_short = abr_switch_map[r].quant_comp_s; - // SET_OPTION(quant_comp_short, abr_switch_map[r].quant_comp_s, -1); - - if (enforce != 0) - gfp.msfix = abr_switch_map[r].nsmsfix; - else if (!(Math.abs(gfp.msfix - -1) > 0)) - gfp.msfix = abr_switch_map[r].nsmsfix; - // SET_OPTION(msfix, abr_switch_map[r].nsmsfix, -1); - - if (enforce != 0) - gfp.internal_flags.nsPsy.attackthre = abr_switch_map[r].st_lrm; - else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre - -1) > 0)) - gfp.internal_flags.nsPsy.attackthre = abr_switch_map[r].st_lrm; - // SET_OPTION(short_threshold_lrm, abr_switch_map[r].st_lrm, -1); - if (enforce != 0) - gfp.internal_flags.nsPsy.attackthre_s = abr_switch_map[r].st_s; - else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre_s - -1) > 0)) - gfp.internal_flags.nsPsy.attackthre_s = abr_switch_map[r].st_s; - // SET_OPTION(short_threshold_s, abr_switch_map[r].st_s, -1); - - /* - * ABR seems to have big problems with clipping, especially at low - * bitrates - */ - /* - * so we compensate for that here by using a scale value depending on - * bitrate - */ - if (enforce != 0) - gfp.scale = abr_switch_map[r].scale; - else if (!(Math.abs(gfp.scale - -1) > 0)) - gfp.scale = abr_switch_map[r].scale; - // SET_OPTION(scale, abr_switch_map[r].scale, -1); - - if (enforce != 0) - gfp.maskingadjust = abr_switch_map[r].masking_adj; - else if (!(Math.abs(gfp.maskingadjust - 0) > 0)) - gfp.maskingadjust = abr_switch_map[r].masking_adj; - // SET_OPTION(maskingadjust, abr_switch_map[r].masking_adj, 0); - if (abr_switch_map[r].masking_adj > 0) { - if (enforce != 0) - gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * .9); - else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0)) - gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * .9); - // SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * - // .9, 0); - } else { - if (enforce != 0) - gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * 1.1); - else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0)) - gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * 1.1); - // SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * - // 1.1, 0); - } - - if (enforce != 0) - gfp.ATHlower = -abr_switch_map[r].ath_lower / 10.; - else if (!(Math.abs((-gfp.ATHlower * 10.) - 0) > 0)) - gfp.ATHlower = -abr_switch_map[r].ath_lower / 10.; - // SET_OPTION(ATHlower, abr_switch_map[r].ath_lower, 0); - if (enforce != 0) - gfp.ATHcurve = abr_switch_map[r].ath_curve; - else if (!(Math.abs(gfp.ATHcurve - -1) > 0)) - gfp.ATHcurve = abr_switch_map[r].ath_curve; - // SET_OPTION(ATHcurve, abr_switch_map[r].ath_curve, -1); - - if (enforce != 0) - gfp.interChRatio = abr_switch_map[r].interch; - else if (!(Math.abs(gfp.interChRatio - -1) > 0)) - gfp.interChRatio = abr_switch_map[r].interch; - // SET_OPTION(interChRatio, abr_switch_map[r].interch, -1); - - return preset; - } - - this.apply_preset = function(gfp, preset, enforce) { - /* translate legacy presets */ - switch (preset) { - case Lame.R3MIX: - { - preset = Lame.V3; - gfp.VBR = VbrMode.vbr_mtrh; - break; - } - case Lame.MEDIUM: - { - preset = Lame.V4; - gfp.VBR = VbrMode.vbr_rh; - break; - } - case Lame.MEDIUM_FAST: - { - preset = Lame.V4; - gfp.VBR = VbrMode.vbr_mtrh; - break; - } - case Lame.STANDARD: - { - preset = Lame.V2; - gfp.VBR = VbrMode.vbr_rh; - break; - } - case Lame.STANDARD_FAST: - { - preset = Lame.V2; - gfp.VBR = VbrMode.vbr_mtrh; - break; - } - case Lame.EXTREME: - { - preset = Lame.V0; - gfp.VBR = VbrMode.vbr_rh; - break; - } - case Lame.EXTREME_FAST: - { - preset = Lame.V0; - gfp.VBR = VbrMode.vbr_mtrh; - break; - } - case Lame.INSANE: - { - preset = 320; - gfp.preset = preset; - apply_abr_preset(gfp, preset, enforce); - gfp.VBR = VbrMode.vbr_off; - return preset; - } - } - - gfp.preset = preset; - { - switch (preset) { - case Lame.V9: - apply_vbr_preset(gfp, 9, enforce); - return preset; - case Lame.V8: - apply_vbr_preset(gfp, 8, enforce); - return preset; - case Lame.V7: - apply_vbr_preset(gfp, 7, enforce); - return preset; - case Lame.V6: - apply_vbr_preset(gfp, 6, enforce); - return preset; - case Lame.V5: - apply_vbr_preset(gfp, 5, enforce); - return preset; - case Lame.V4: - apply_vbr_preset(gfp, 4, enforce); - return preset; - case Lame.V3: - apply_vbr_preset(gfp, 3, enforce); - return preset; - case Lame.V2: - apply_vbr_preset(gfp, 2, enforce); - return preset; - case Lame.V1: - apply_vbr_preset(gfp, 1, enforce); - return preset; - case Lame.V0: - apply_vbr_preset(gfp, 0, enforce); - return preset; - default: - break; - } - } - if (8 <= preset && preset <= 320) { - return apply_abr_preset(gfp, preset, enforce); - } - - /* no corresponding preset found */ - gfp.preset = 0; - return preset; - } - - // Rest from getset.c: - - /** - * VBR quality level.
- * 0 = highest
- * 9 = lowest - */ - function lame_set_VBR_q(gfp, VBR_q) { - var ret = 0; - - if (0 > VBR_q) { - /* Unknown VBR quality level! */ - ret = -1; - VBR_q = 0; - } - if (9 < VBR_q) { - ret = -1; - VBR_q = 9; - } - - gfp.VBR_q = VBR_q; - gfp.VBR_q_frac = 0; - return ret; - } - -} - -/* - * MP3 huffman table selecting and bit counting - * - * Copyright (c) 1999-2005 Takehiro TOMINAGA - * Copyright (c) 2002-2005 Gabriel Bouvigne - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: Takehiro.java,v 1.26 2011/05/24 20:48:06 kenchis Exp $ */ - -//package mp3; - -//import java.util.Arrays; - - - -function Takehiro() { - - var qupvt = null; - this.qupvt = null; - - this.setModules = function (_qupvt) { - this.qupvt = _qupvt; - qupvt = _qupvt; - } - - function Bits(b) { - this.bits = 0 | b; - } - - var subdv_table = [[0, 0], /* 0 bands */ - [0, 0], /* 1 bands */ - [0, 0], /* 2 bands */ - [0, 0], /* 3 bands */ - [0, 0], /* 4 bands */ - [0, 1], /* 5 bands */ - [1, 1], /* 6 bands */ - [1, 1], /* 7 bands */ - [1, 2], /* 8 bands */ - [2, 2], /* 9 bands */ - [2, 3], /* 10 bands */ - [2, 3], /* 11 bands */ - [3, 4], /* 12 bands */ - [3, 4], /* 13 bands */ - [3, 4], /* 14 bands */ - [4, 5], /* 15 bands */ - [4, 5], /* 16 bands */ - [4, 6], /* 17 bands */ - [5, 6], /* 18 bands */ - [5, 6], /* 19 bands */ - [5, 7], /* 20 bands */ - [6, 7], /* 21 bands */ - [6, 7], /* 22 bands */ - ]; - - /** - * nonlinear quantization of xr More accurate formula than the ISO formula. - * Takes into account the fact that we are quantizing xr . ix, but we want - * ix^4/3 to be as close as possible to x^4/3. (taking the nearest int would - * mean ix is as close as possible to xr, which is different.) - * - * From Segher Boessenkool 11/1999 - * - * 09/2000: ASM code removed in favor of IEEE754 hack by Takehiro Tominaga. - * If you need the ASM code, check CVS circa Aug 2000. - * - * 01/2004: Optimizations by Gabriel Bouvigne - */ - function quantize_lines_xrpow_01(l, istep, xr, xrPos, ix, ixPos) { - var compareval0 = (1.0 - 0.4054) / istep; - - l = l >> 1; - while ((l--) != 0) { - ix[ixPos++] = (compareval0 > xr[xrPos++]) ? 0 : 1; - ix[ixPos++] = (compareval0 > xr[xrPos++]) ? 0 : 1; - } - } - - /** - * XRPOW_FTOI is a macro to convert floats to ints.
- * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x]
- * ROUNDFAC= -0.0946
- * - * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x]
- * ROUNDFAC=0.4054
- * - * Note: using floor() or 0| is extremely slow. On machines where the - * TAKEHIRO_IEEE754_HACK code above does not work, it is worthwile to write - * some ASM for XRPOW_FTOI(). - */ - function quantize_lines_xrpow(l, istep, xr, xrPos, ix, ixPos) { - - l = l >> 1; - var remaining = l % 2; - l = l >> 1; - while (l-- != 0) { - var x0, x1, x2, x3; - var rx0, rx1, rx2, rx3; - - x0 = xr[xrPos++] * istep; - x1 = xr[xrPos++] * istep; - rx0 = 0 | x0; - x2 = xr[xrPos++] * istep; - rx1 = 0 | x1; - x3 = xr[xrPos++] * istep; - rx2 = 0 | x2; - x0 += qupvt.adj43[rx0]; - rx3 = 0 | x3; - x1 += qupvt.adj43[rx1]; - ix[ixPos++] = 0 | x0; - x2 += qupvt.adj43[rx2]; - ix[ixPos++] = 0 | x1; - x3 += qupvt.adj43[rx3]; - ix[ixPos++] = 0 | x2; - ix[ixPos++] = 0 | x3; - } - if (remaining != 0) { - var x0, x1; - var rx0, rx1; - - x0 = xr[xrPos++] * istep; - x1 = xr[xrPos++] * istep; - rx0 = 0 | x0; - rx1 = 0 | x1; - x0 += qupvt.adj43[rx0]; - x1 += qupvt.adj43[rx1]; - ix[ixPos++] = 0 | x0; - ix[ixPos++] = 0 | x1; - } - } - - /** - * Quantization function This function will select which lines to quantize - * and call the proper quantization function - */ - function quantize_xrpow(xp, pi, istep, codInfo, prevNoise) { - /* quantize on xr^(3/4) instead of xr */ - var sfb; - var sfbmax; - var j = 0; - var prev_data_use; - var accumulate = 0; - var accumulate01 = 0; - var xpPos = 0; - var iData = pi; - var iDataPos = 0; - var acc_iData = iData; - var acc_iDataPos = 0; - var acc_xp = xp; - var acc_xpPos = 0; - - /* - * Reusing previously computed data does not seems to work if global - * gain is changed. Finding why it behaves this way would allow to use a - * cache of previously computed values (let's 10 cached values per sfb) - * that would probably provide a noticeable speedup - */ - prev_data_use = (prevNoise != null && (codInfo.global_gain == prevNoise.global_gain)); - - if (codInfo.block_type == Encoder.SHORT_TYPE) - sfbmax = 38; - else - sfbmax = 21; - - for (sfb = 0; sfb <= sfbmax; sfb++) { - var step = -1; - - if (prev_data_use || codInfo.block_type == Encoder.NORM_TYPE) { - step = codInfo.global_gain - - ((codInfo.scalefac[sfb] + (codInfo.preflag != 0 ? qupvt.pretab[sfb] - : 0)) << (codInfo.scalefac_scale + 1)) - - codInfo.subblock_gain[codInfo.window[sfb]] * 8; - } - if (prev_data_use && (prevNoise.step[sfb] == step)) { - /* - * do not recompute this part, but compute accumulated lines - */ - if (accumulate != 0) { - quantize_lines_xrpow(accumulate, istep, acc_xp, acc_xpPos, - acc_iData, acc_iDataPos); - accumulate = 0; - } - if (accumulate01 != 0) { - quantize_lines_xrpow_01(accumulate01, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate01 = 0; - } - } else { /* should compute this part */ - var l = codInfo.width[sfb]; - - if ((j + codInfo.width[sfb]) > codInfo.max_nonzero_coeff) { - /* do not compute upper zero part */ - var usefullsize; - usefullsize = codInfo.max_nonzero_coeff - j + 1; - Arrays.fill(pi, codInfo.max_nonzero_coeff, 576, 0); - l = usefullsize; - - if (l < 0) { - l = 0; - } - - /* no need to compute higher sfb values */ - sfb = sfbmax + 1; - } - - /* accumulate lines to quantize */ - if (0 == accumulate && 0 == accumulate01) { - acc_iData = iData; - acc_iDataPos = iDataPos; - acc_xp = xp; - acc_xpPos = xpPos; - } - if (prevNoise != null && prevNoise.sfb_count1 > 0 - && sfb >= prevNoise.sfb_count1 - && prevNoise.step[sfb] > 0 - && step >= prevNoise.step[sfb]) { - - if (accumulate != 0) { - quantize_lines_xrpow(accumulate, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate = 0; - acc_iData = iData; - acc_iDataPos = iDataPos; - acc_xp = xp; - acc_xpPos = xpPos; - } - accumulate01 += l; - } else { - if (accumulate01 != 0) { - quantize_lines_xrpow_01(accumulate01, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate01 = 0; - acc_iData = iData; - acc_iDataPos = iDataPos; - acc_xp = xp; - acc_xpPos = xpPos; - } - accumulate += l; - } - - if (l <= 0) { - /* - * rh: 20040215 may happen due to "prev_data_use" - * optimization - */ - if (accumulate01 != 0) { - quantize_lines_xrpow_01(accumulate01, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate01 = 0; - } - if (accumulate != 0) { - quantize_lines_xrpow(accumulate, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate = 0; - } - - break; - /* ends for-loop */ - } - } - if (sfb <= sfbmax) { - iDataPos += codInfo.width[sfb]; - xpPos += codInfo.width[sfb]; - j += codInfo.width[sfb]; - } - } - if (accumulate != 0) { /* last data part */ - quantize_lines_xrpow(accumulate, istep, acc_xp, acc_xpPos, - acc_iData, acc_iDataPos); - accumulate = 0; - } - if (accumulate01 != 0) { /* last data part */ - quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_xpPos, - acc_iData, acc_iDataPos); - accumulate01 = 0; - } - - } - - /** - * ix_max - */ - function ix_max(ix, ixPos, endPos) { - var max1 = 0, max2 = 0; - - do { - var x1 = ix[ixPos++]; - var x2 = ix[ixPos++]; - if (max1 < x1) - max1 = x1; - - if (max2 < x2) - max2 = x2; - } while (ixPos < endPos); - if (max1 < max2) - max1 = max2; - return max1; - } - - function count_bit_ESC(ix, ixPos, end, t1, t2, s) { - /* ESC-table is used */ - var linbits = Tables.ht[t1].xlen * 65536 + Tables.ht[t2].xlen; - var sum = 0, sum2; - - do { - var x = ix[ixPos++]; - var y = ix[ixPos++]; - - if (x != 0) { - if (x > 14) { - x = 15; - sum += linbits; - } - x *= 16; - } - - if (y != 0) { - if (y > 14) { - y = 15; - sum += linbits; - } - x += y; - } - - sum += Tables.largetbl[x]; - } while (ixPos < end); - - sum2 = sum & 0xffff; - sum >>= 16; - - if (sum > sum2) { - sum = sum2; - t1 = t2; - } - - s.bits += sum; - return t1; - } - - function count_bit_noESC(ix, ixPos, end, s) { - /* No ESC-words */ - var sum1 = 0; - var hlen1 = Tables.ht[1].hlen; - - do { - var x = ix[ixPos + 0] * 2 + ix[ixPos + 1]; - ixPos += 2; - sum1 += hlen1[x]; - } while (ixPos < end); - - s.bits += sum1; - return 1; - } - - function count_bit_noESC_from2(ix, ixPos, end, t1, s) { - /* No ESC-words */ - var sum = 0, sum2; - var xlen = Tables.ht[t1].xlen; - var hlen; - if (t1 == 2) - hlen = Tables.table23; - else - hlen = Tables.table56; - - do { - var x = ix[ixPos + 0] * xlen + ix[ixPos + 1]; - ixPos += 2; - sum += hlen[x]; - } while (ixPos < end); - - sum2 = sum & 0xffff; - sum >>= 16; - - if (sum > sum2) { - sum = sum2; - t1++; - } - - s.bits += sum; - return t1; - } - - function count_bit_noESC_from3(ix, ixPos, end, t1, s) { - /* No ESC-words */ - var sum1 = 0; - var sum2 = 0; - var sum3 = 0; - var xlen = Tables.ht[t1].xlen; - var hlen1 = Tables.ht[t1].hlen; - var hlen2 = Tables.ht[t1 + 1].hlen; - var hlen3 = Tables.ht[t1 + 2].hlen; - - do { - var x = ix[ixPos + 0] * xlen + ix[ixPos + 1]; - ixPos += 2; - sum1 += hlen1[x]; - sum2 += hlen2[x]; - sum3 += hlen3[x]; - } while (ixPos < end); - var t = t1; - if (sum1 > sum2) { - sum1 = sum2; - t++; - } - if (sum1 > sum3) { - sum1 = sum3; - t = t1 + 2; - } - s.bits += sum1; - - return t; - } - - /*************************************************************************/ - /* choose table */ - /*************************************************************************/ - - var huf_tbl_noESC = [1, 2, 5, 7, 7, 10, 10, 13, 13, - 13, 13, 13, 13, 13, 13]; - - /** - * Choose the Huffman table that will encode ix[begin..end] with the fewest - * bits. - * - * Note: This code contains knowledge about the sizes and characteristics of - * the Huffman tables as defined in the IS (Table B.7), and will not work - * with any arbitrary tables. - */ - function choose_table(ix, ixPos, endPos, s) { - var max = ix_max(ix, ixPos, endPos); - - switch (max) { - case 0: - return max; - - case 1: - return count_bit_noESC(ix, ixPos, endPos, s); - - case 2: - case 3: - return count_bit_noESC_from2(ix, ixPos, endPos, - huf_tbl_noESC[max - 1], s); - - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - return count_bit_noESC_from3(ix, ixPos, endPos, - huf_tbl_noESC[max - 1], s); - - default: - /* try tables with linbits */ - if (max > QuantizePVT.IXMAX_VAL) { - s.bits = QuantizePVT.LARGE_BITS; - return -1; - } - max -= 15; - var choice2; - for (choice2 = 24; choice2 < 32; choice2++) { - if (Tables.ht[choice2].linmax >= max) { - break; - } - } - var choice; - for (choice = choice2 - 8; choice < 24; choice++) { - if (Tables.ht[choice].linmax >= max) { - break; - } - } - return count_bit_ESC(ix, ixPos, endPos, choice, choice2, s); - } - } - - /** - * count_bit - */ - this.noquant_count_bits = function (gfc, gi, prev_noise) { - var ix = gi.l3_enc; - var i = Math.min(576, ((gi.max_nonzero_coeff + 2) >> 1) << 1); - - if (prev_noise != null) - prev_noise.sfb_count1 = 0; - - /* Determine count1 region */ - for (; i > 1; i -= 2) - if ((ix[i - 1] | ix[i - 2]) != 0) - break; - gi.count1 = i; - - /* Determines the number of bits to encode the quadruples. */ - var a1 = 0; - var a2 = 0; - for (; i > 3; i -= 4) { - var p; - /* hack to check if all values <= 1 */ - //throw "TODO: HACK if ((((long) ix[i - 1] | (long) ix[i - 2] | (long) ix[i - 3] | (long) ix[i - 4]) & 0xffffffffL) > 1L " - //if (true) { - if (((ix[i - 1] | ix[i - 2] | ix[i - 3] | ix[i - 4]) & 0x7fffffff) > 1) { - break; - } - p = ((ix[i - 4] * 2 + ix[i - 3]) * 2 + ix[i - 2]) * 2 + ix[i - 1]; - a1 += Tables.t32l[p]; - a2 += Tables.t33l[p]; - } - var bits = a1; - gi.count1table_select = 0; - if (a1 > a2) { - bits = a2; - gi.count1table_select = 1; - } - - gi.count1bits = bits; - gi.big_values = i; - if (i == 0) - return bits; - - if (gi.block_type == Encoder.SHORT_TYPE) { - a1 = 3 * gfc.scalefac_band.s[3]; - if (a1 > gi.big_values) - a1 = gi.big_values; - a2 = gi.big_values; - - } else if (gi.block_type == Encoder.NORM_TYPE) { - /* bv_scf has 576 entries (0..575) */ - a1 = gi.region0_count = gfc.bv_scf[i - 2]; - a2 = gi.region1_count = gfc.bv_scf[i - 1]; - - a2 = gfc.scalefac_band.l[a1 + a2 + 2]; - a1 = gfc.scalefac_band.l[a1 + 1]; - if (a2 < i) { - var bi = new Bits(bits); - gi.table_select[2] = choose_table(ix, a2, i, bi); - bits = bi.bits; - } - } else { - gi.region0_count = 7; - /* gi.region1_count = SBPSY_l - 7 - 1; */ - gi.region1_count = Encoder.SBMAX_l - 1 - 7 - 1; - a1 = gfc.scalefac_band.l[7 + 1]; - a2 = i; - if (a1 > a2) { - a1 = a2; - } - } - - /* have to allow for the case when bigvalues < region0 < region1 */ - /* (and region0, region1 are ignored) */ - a1 = Math.min(a1, i); - a2 = Math.min(a2, i); - - - /* Count the number of bits necessary to code the bigvalues region. */ - if (0 < a1) { - var bi = new Bits(bits); - gi.table_select[0] = choose_table(ix, 0, a1, bi); - bits = bi.bits; - } - if (a1 < a2) { - var bi = new Bits(bits); - gi.table_select[1] = choose_table(ix, a1, a2, bi); - bits = bi.bits; - } - if (gfc.use_best_huffman == 2) { - gi.part2_3_length = bits; - best_huffman_divide(gfc, gi); - bits = gi.part2_3_length; - } - - if (prev_noise != null) { - if (gi.block_type == Encoder.NORM_TYPE) { - var sfb = 0; - while (gfc.scalefac_band.l[sfb] < gi.big_values) { - sfb++; - } - prev_noise.sfb_count1 = sfb; - } - } - - return bits; - } - - this.count_bits = function (gfc, xr, gi, prev_noise) { - var ix = gi.l3_enc; - - /* since quantize_xrpow uses table lookup, we need to check this first: */ - var w = (QuantizePVT.IXMAX_VAL) / qupvt.IPOW20(gi.global_gain); - - if (gi.xrpow_max > w) - return QuantizePVT.LARGE_BITS; - - quantize_xrpow(xr, ix, qupvt.IPOW20(gi.global_gain), gi, prev_noise); - - if ((gfc.substep_shaping & 2) != 0) { - var j = 0; - /* 0.634521682242439 = 0.5946*2**(.5*0.1875) */ - var gain = gi.global_gain + gi.scalefac_scale; - var roundfac = 0.634521682242439 / qupvt.IPOW20(gain); - for (var sfb = 0; sfb < gi.sfbmax; sfb++) { - var width = gi.width[sfb]; - if (0 == gfc.pseudohalf[sfb]) { - j += width; - } else { - var k; - for (k = j, j += width; k < j; ++k) { - ix[k] = (xr[k] >= roundfac) ? ix[k] : 0; - } - } - } - } - return this.noquant_count_bits(gfc, gi, prev_noise); - } - - /** - * re-calculate the best scalefac_compress using scfsi the saved bits are - * kept in the bit reservoir. - */ - function recalc_divide_init(gfc, cod_info, ix, r01_bits, r01_div, r0_tbl, r1_tbl) { - var bigv = cod_info.big_values; - - for (var r0 = 0; r0 <= 7 + 15; r0++) { - r01_bits[r0] = QuantizePVT.LARGE_BITS; - } - - for (var r0 = 0; r0 < 16; r0++) { - var a1 = gfc.scalefac_band.l[r0 + 1]; - if (a1 >= bigv) - break; - var r0bits = 0; - var bi = new Bits(r0bits); - var r0t = choose_table(ix, 0, a1, bi); - r0bits = bi.bits; - - for (var r1 = 0; r1 < 8; r1++) { - var a2 = gfc.scalefac_band.l[r0 + r1 + 2]; - if (a2 >= bigv) - break; - var bits = r0bits; - bi = new Bits(bits); - var r1t = choose_table(ix, a1, a2, bi); - bits = bi.bits; - if (r01_bits[r0 + r1] > bits) { - r01_bits[r0 + r1] = bits; - r01_div[r0 + r1] = r0; - r0_tbl[r0 + r1] = r0t; - r1_tbl[r0 + r1] = r1t; - } - } - } - } - - function recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl) { - var bigv = cod_info2.big_values; - - for (var r2 = 2; r2 < Encoder.SBMAX_l + 1; r2++) { - var a2 = gfc.scalefac_band.l[r2]; - if (a2 >= bigv) - break; - var bits = r01_bits[r2 - 2] + cod_info2.count1bits; - if (gi.part2_3_length <= bits) - break; - - var bi = new Bits(bits); - var r2t = choose_table(ix, a2, bigv, bi); - bits = bi.bits; - if (gi.part2_3_length <= bits) - continue; - - gi.assign(cod_info2); - gi.part2_3_length = bits; - gi.region0_count = r01_div[r2 - 2]; - gi.region1_count = r2 - 2 - r01_div[r2 - 2]; - gi.table_select[0] = r0_tbl[r2 - 2]; - gi.table_select[1] = r1_tbl[r2 - 2]; - gi.table_select[2] = r2t; - } - } - - this.best_huffman_divide = function (gfc, gi) { - var cod_info2 = new GrInfo(); - var ix = gi.l3_enc; - var r01_bits = new_int(7 + 15 + 1); - var r01_div = new_int(7 + 15 + 1); - var r0_tbl = new_int(7 + 15 + 1); - var r1_tbl = new_int(7 + 15 + 1); - - /* SHORT BLOCK stuff fails for MPEG2 */ - if (gi.block_type == Encoder.SHORT_TYPE && gfc.mode_gr == 1) - return; - - cod_info2.assign(gi); - if (gi.block_type == Encoder.NORM_TYPE) { - recalc_divide_init(gfc, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl); - recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div, - r0_tbl, r1_tbl); - } - var i = cod_info2.big_values; - if (i == 0 || (ix[i - 2] | ix[i - 1]) > 1) - return; - - i = gi.count1 + 2; - if (i > 576) - return; - - /* Determines the number of bits to encode the quadruples. */ - cod_info2.assign(gi); - cod_info2.count1 = i; - var a1 = 0; - var a2 = 0; - - - for (; i > cod_info2.big_values; i -= 4) { - var p = ((ix[i - 4] * 2 + ix[i - 3]) * 2 + ix[i - 2]) * 2 - + ix[i - 1]; - a1 += Tables.t32l[p]; - a2 += Tables.t33l[p]; - } - cod_info2.big_values = i; - - cod_info2.count1table_select = 0; - if (a1 > a2) { - a1 = a2; - cod_info2.count1table_select = 1; - } - - cod_info2.count1bits = a1; - - if (cod_info2.block_type == Encoder.NORM_TYPE) - recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div, - r0_tbl, r1_tbl); - else { - /* Count the number of bits necessary to code the bigvalues region. */ - cod_info2.part2_3_length = a1; - a1 = gfc.scalefac_band.l[7 + 1]; - if (a1 > i) { - a1 = i; - } - if (a1 > 0) { - var bi = new Bits(cod_info2.part2_3_length); - cod_info2.table_select[0] = choose_table(ix, 0, a1, bi); - cod_info2.part2_3_length = bi.bits; - } - if (i > a1) { - var bi = new Bits(cod_info2.part2_3_length); - cod_info2.table_select[1] = choose_table(ix, a1, i, bi); - cod_info2.part2_3_length = bi.bits; - } - if (gi.part2_3_length > cod_info2.part2_3_length) - gi.assign(cod_info2); - } - } - - var slen1_n = [1, 1, 1, 1, 8, 2, 2, 2, 4, 4, 4, 8, 8, 8, 16, 16]; - var slen2_n = [1, 2, 4, 8, 1, 2, 4, 8, 2, 4, 8, 2, 4, 8, 4, 8]; - var slen1_tab = [0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4]; - var slen2_tab = [0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3]; - Takehiro.slen1_tab = slen1_tab; - Takehiro.slen2_tab = slen2_tab; - - function scfsi_calc(ch, l3_side) { - var sfb; - var gi = l3_side.tt[1][ch]; - var g0 = l3_side.tt[0][ch]; - - for (var i = 0; i < Tables.scfsi_band.length - 1; i++) { - for (sfb = Tables.scfsi_band[i]; sfb < Tables.scfsi_band[i + 1]; sfb++) { - if (g0.scalefac[sfb] != gi.scalefac[sfb] - && gi.scalefac[sfb] >= 0) - break; - } - if (sfb == Tables.scfsi_band[i + 1]) { - for (sfb = Tables.scfsi_band[i]; sfb < Tables.scfsi_band[i + 1]; sfb++) { - gi.scalefac[sfb] = -1; - } - l3_side.scfsi[ch][i] = 1; - } - } - var s1 = 0; - var c1 = 0; - for (sfb = 0; sfb < 11; sfb++) { - if (gi.scalefac[sfb] == -1) - continue; - c1++; - if (s1 < gi.scalefac[sfb]) - s1 = gi.scalefac[sfb]; - } - var s2 = 0; - var c2 = 0; - for (; sfb < Encoder.SBPSY_l; sfb++) { - if (gi.scalefac[sfb] == -1) - continue; - c2++; - if (s2 < gi.scalefac[sfb]) - s2 = gi.scalefac[sfb]; - } - - for (var i = 0; i < 16; i++) { - if (s1 < slen1_n[i] && s2 < slen2_n[i]) { - var c = slen1_tab[i] * c1 + slen2_tab[i] * c2; - if (gi.part2_length > c) { - gi.part2_length = c; - gi.scalefac_compress = i; - } - } - } - } - - /** - * Find the optimal way to store the scalefactors. Only call this routine - * after final scalefactors have been chosen and the channel/granule will - * not be re-encoded. - */ - this.best_scalefac_store = function (gfc, gr, ch, l3_side) { - /* use scalefac_scale if we can */ - var gi = l3_side.tt[gr][ch]; - var sfb, i, j, l; - var recalc = 0; - - /* - * remove scalefacs from bands with ix=0. This idea comes from the AAC - * ISO docs. added mt 3/00 - */ - /* check if l3_enc=0 */ - j = 0; - for (sfb = 0; sfb < gi.sfbmax; sfb++) { - var width = gi.width[sfb]; - j += width; - for (l = -width; l < 0; l++) { - if (gi.l3_enc[l + j] != 0) - break; - } - if (l == 0) - gi.scalefac[sfb] = recalc = -2; - /* anything goes. */ - /* - * only best_scalefac_store and calc_scfsi know--and only they - * should know--about the magic number -2. - */ - } - - if (0 == gi.scalefac_scale && 0 == gi.preflag) { - var s = 0; - for (sfb = 0; sfb < gi.sfbmax; sfb++) - if (gi.scalefac[sfb] > 0) - s |= gi.scalefac[sfb]; - - if (0 == (s & 1) && s != 0) { - for (sfb = 0; sfb < gi.sfbmax; sfb++) - if (gi.scalefac[sfb] > 0) - gi.scalefac[sfb] >>= 1; - - gi.scalefac_scale = recalc = 1; - } - } - - if (0 == gi.preflag && gi.block_type != Encoder.SHORT_TYPE - && gfc.mode_gr == 2) { - for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) - if (gi.scalefac[sfb] < qupvt.pretab[sfb] - && gi.scalefac[sfb] != -2) - break; - if (sfb == Encoder.SBPSY_l) { - for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) - if (gi.scalefac[sfb] > 0) - gi.scalefac[sfb] -= qupvt.pretab[sfb]; - - gi.preflag = recalc = 1; - } - } - - for (i = 0; i < 4; i++) - l3_side.scfsi[ch][i] = 0; - - if (gfc.mode_gr == 2 && gr == 1 - && l3_side.tt[0][ch].block_type != Encoder.SHORT_TYPE - && l3_side.tt[1][ch].block_type != Encoder.SHORT_TYPE) { - scfsi_calc(ch, l3_side); - recalc = 0; - } - for (sfb = 0; sfb < gi.sfbmax; sfb++) { - if (gi.scalefac[sfb] == -2) { - gi.scalefac[sfb] = 0; - /* if anything goes, then 0 is a good choice */ - } - } - if (recalc != 0) { - if (gfc.mode_gr == 2) { - this.scale_bitcount(gi); - } else { - this.scale_bitcount_lsf(gfc, gi); - } - } - } - - function all_scalefactors_not_negative(scalefac, n) { - for (var i = 0; i < n; ++i) { - if (scalefac[i] < 0) - return false; - } - return true; - } - - /** - * number of bits used to encode scalefacs. - * - * 18*slen1_tab[i] + 18*slen2_tab[i] - */ - var scale_short = [0, 18, 36, 54, 54, 36, 54, 72, - 54, 72, 90, 72, 90, 108, 108, 126]; - - /** - * number of bits used to encode scalefacs. - * - * 17*slen1_tab[i] + 18*slen2_tab[i] - */ - var scale_mixed = [0, 18, 36, 54, 51, 35, 53, 71, - 52, 70, 88, 69, 87, 105, 104, 122]; - - /** - * number of bits used to encode scalefacs. - * - * 11*slen1_tab[i] + 10*slen2_tab[i] - */ - var scale_long = [0, 10, 20, 30, 33, 21, 31, 41, 32, 42, - 52, 43, 53, 63, 64, 74]; - - /** - * Also calculates the number of bits necessary to code the scalefactors. - */ - this.scale_bitcount = function (cod_info) { - var k, sfb, max_slen1 = 0, max_slen2 = 0; - - /* maximum values */ - var tab; - var scalefac = cod_info.scalefac; - - - if (cod_info.block_type == Encoder.SHORT_TYPE) { - tab = scale_short; - if (cod_info.mixed_block_flag != 0) - tab = scale_mixed; - } else { /* block_type == 1,2,or 3 */ - tab = scale_long; - if (0 == cod_info.preflag) { - for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) - if (scalefac[sfb] < qupvt.pretab[sfb]) - break; - - if (sfb == Encoder.SBPSY_l) { - cod_info.preflag = 1; - for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) - scalefac[sfb] -= qupvt.pretab[sfb]; - } - } - } - - for (sfb = 0; sfb < cod_info.sfbdivide; sfb++) - if (max_slen1 < scalefac[sfb]) - max_slen1 = scalefac[sfb]; - - for (; sfb < cod_info.sfbmax; sfb++) - if (max_slen2 < scalefac[sfb]) - max_slen2 = scalefac[sfb]; - - /* - * from Takehiro TOMINAGA 10/99 loop over *all* - * posible values of scalefac_compress to find the one which uses the - * smallest number of bits. ISO would stop at first valid index - */ - cod_info.part2_length = QuantizePVT.LARGE_BITS; - for (k = 0; k < 16; k++) { - if (max_slen1 < slen1_n[k] && max_slen2 < slen2_n[k] - && cod_info.part2_length > tab[k]) { - cod_info.part2_length = tab[k]; - cod_info.scalefac_compress = k; - } - } - return cod_info.part2_length == QuantizePVT.LARGE_BITS; - } - - /** - * table of largest scalefactor values for MPEG2 - */ - var max_range_sfac_tab = [[15, 15, 7, 7], - [15, 15, 7, 0], [7, 3, 0, 0], [15, 31, 31, 0], - [7, 7, 7, 0], [3, 3, 0, 0]]; - - /** - * Also counts the number of bits to encode the scalefacs but for MPEG 2 - * Lower sampling frequencies (24, 22.05 and 16 kHz.) - * - * This is reverse-engineered from section 2.4.3.2 of the MPEG2 IS, - * "Audio Decoding Layer III" - */ - this.scale_bitcount_lsf = function (gfc, cod_info) { - var table_number, row_in_table, partition, nr_sfb, window; - var over; - var i, sfb; - var max_sfac = new_int(4); -//var partition_table; - var scalefac = cod_info.scalefac; - - /* - * Set partition table. Note that should try to use table one, but do - * not yet... - */ - if (cod_info.preflag != 0) - table_number = 2; - else - table_number = 0; - - for (i = 0; i < 4; i++) - max_sfac[i] = 0; - - if (cod_info.block_type == Encoder.SHORT_TYPE) { - row_in_table = 1; - var partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table]; - for (sfb = 0, partition = 0; partition < 4; partition++) { - nr_sfb = partition_table[partition] / 3; - for (i = 0; i < nr_sfb; i++, sfb++) - for (window = 0; window < 3; window++) - if (scalefac[sfb * 3 + window] > max_sfac[partition]) - max_sfac[partition] = scalefac[sfb * 3 + window]; - } - } else { - row_in_table = 0; - var partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table]; - for (sfb = 0, partition = 0; partition < 4; partition++) { - nr_sfb = partition_table[partition]; - for (i = 0; i < nr_sfb; i++, sfb++) - if (scalefac[sfb] > max_sfac[partition]) - max_sfac[partition] = scalefac[sfb]; - } - } - - for (over = false, partition = 0; partition < 4; partition++) { - if (max_sfac[partition] > max_range_sfac_tab[table_number][partition]) - over = true; - } - if (!over) { - var slen1, slen2, slen3, slen4; - - cod_info.sfb_partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table]; - for (partition = 0; partition < 4; partition++) - cod_info.slen[partition] = log2tab[max_sfac[partition]]; - - /* set scalefac_compress */ - slen1 = cod_info.slen[0]; - slen2 = cod_info.slen[1]; - slen3 = cod_info.slen[2]; - slen4 = cod_info.slen[3]; - - switch (table_number) { - case 0: - cod_info.scalefac_compress = (((slen1 * 5) + slen2) << 4) - + (slen3 << 2) + slen4; - break; - - case 1: - cod_info.scalefac_compress = 400 + (((slen1 * 5) + slen2) << 2) - + slen3; - break; - - case 2: - cod_info.scalefac_compress = 500 + (slen1 * 3) + slen2; - break; - - default: - System.err.printf("intensity stereo not implemented yet\n"); - break; - } - } - if (!over) { - cod_info.part2_length = 0; - for (partition = 0; partition < 4; partition++) - cod_info.part2_length += cod_info.slen[partition] - * cod_info.sfb_partition_table[partition]; - } - return over; - } - - /* - * Since no bands have been over-amplified, we can set scalefac_compress and - * slen[] for the formatter - */ - var log2tab = [0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, - 4, 4, 4, 4]; - - this.huffman_init = function (gfc) { - for (var i = 2; i <= 576; i += 2) { - var scfb_anz = 0, bv_index; - while (gfc.scalefac_band.l[++scfb_anz] < i) - ; - - bv_index = subdv_table[scfb_anz][0]; // .region0_count - while (gfc.scalefac_band.l[bv_index + 1] > i) - bv_index--; - - if (bv_index < 0) { - /* - * this is an indication that everything is going to be encoded - * as region0: bigvalues < region0 < region1 so lets set - * region0, region1 to some value larger than bigvalues - */ - bv_index = subdv_table[scfb_anz][0]; // .region0_count - } - - gfc.bv_scf[i - 2] = bv_index; - - bv_index = subdv_table[scfb_anz][1]; // .region1_count - while (gfc.scalefac_band.l[bv_index + gfc.bv_scf[i - 2] + 2] > i) - bv_index--; - - if (bv_index < 0) { - bv_index = subdv_table[scfb_anz][1]; // .region1_count - } - - gfc.bv_scf[i - 1] = bv_index; - } - } -} - -/* - * bit reservoir source file - * - * Copyright (c) 1999-2000 Mark Taylor - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: Reservoir.java,v 1.9 2011/05/24 20:48:06 kenchis Exp $ */ - -//package mp3; - -/** - * ResvFrameBegin:
- * Called (repeatedly) at the beginning of a frame. Updates the maximum size of - * the reservoir, and checks to make sure main_data_begin was set properly by - * the formatter
- * Background information: - * - * This is the original text from the ISO standard. Because of sooo many bugs - * and irritations correcting comments are added in brackets []. A '^W' means - * you should remove the last word. - * - *
- *  1. The following rule can be used to calculate the maximum
- *     number of bits used for one granule [^W frame]:
- * At the highest possible bitrate of Layer III (320 kbps - * per stereo signal [^W^W^W], 48 kHz) the frames must be of - * [^W^W^W are designed to have] constant length, i.e. - * one buffer [^W^W the frame] length is:
- * - * 320 kbps * 1152/48 kHz = 7680 bit = 960 byte - * - * This value is used as the maximum buffer per channel [^W^W] at - * lower bitrates [than 320 kbps]. At 64 kbps mono or 128 kbps - * stereo the main granule length is 64 kbps * 576/48 kHz = 768 bit - * [per granule and channel] at 48 kHz sampling frequency. - * This means that there is a maximum deviation (short time buffer - * [= reservoir]) of 7680 - 2*2*768 = 4608 bits is allowed at 64 kbps. - * The actual deviation is equal to the number of bytes [with the - * meaning of octets] denoted by the main_data_end offset pointer. - * The actual maximum deviation is (2^9-1)*8 bit = 4088 bits - * [for MPEG-1 and (2^8-1)*8 bit for MPEG-2, both are hard limits]. - * ... The xchange of buffer bits between the left and right channel - * is allowed without restrictions [exception: dual channel]. - * Because of the [constructed] constraint on the buffer size - * main_data_end is always set to 0 in the case of bit_rate_index==14, - * i.e. data rate 320 kbps per stereo signal [^W^W^W]. In this case - * all data are allocated between adjacent header [^W sync] words - * [, i.e. there is no buffering at all]. - *
- */ - - -function Reservoir() { - var bs; - - this.setModules = function(_bs) { - bs = _bs; - } - - this.ResvFrameBegin = function(gfp, mean_bits) { - var gfc = gfp.internal_flags; - var maxmp3buf; - var l3_side = gfc.l3_side; - - var frameLength = bs.getframebits(gfp); - mean_bits.bits = (frameLength - gfc.sideinfo_len * 8) / gfc.mode_gr; - - /** - *
-		 *  Meaning of the variables:
-		 *      resvLimit: (0, 8, ..., 8*255 (MPEG-2), 8*511 (MPEG-1))
-		 *          Number of bits can be stored in previous frame(s) due to
-		 *          counter size constaints
-		 *      maxmp3buf: ( ??? ... 8*1951 (MPEG-1 and 2), 8*2047 (MPEG-2.5))
-		 *          Number of bits allowed to encode one frame (you can take 8*511 bit
-		 *          from the bit reservoir and at most 8*1440 bit from the current
-		 *          frame (320 kbps, 32 kHz), so 8*1951 bit is the largest possible
-		 *          value for MPEG-1 and -2)
-		 * 
-		 *          maximum allowed granule/channel size times 4 = 8*2047 bits.,
-		 *          so this is the absolute maximum supported by the format.
-		 * 
-		 * 
-		 *      fullFrameBits:  maximum number of bits available for encoding
-		 *                      the current frame.
-		 * 
-		 *      mean_bits:      target number of bits per granule.
-		 * 
-		 *      frameLength:
-		 * 
-		 *      gfc.ResvMax:   maximum allowed reservoir
-		 * 
-		 *      gfc.ResvSize:  current reservoir size
-		 * 
-		 *      l3_side.resvDrain_pre:
-		 *         ancillary data to be added to previous frame:
-		 *         (only usefull in VBR modes if it is possible to have
-		 *         maxmp3buf < fullFrameBits)).  Currently disabled,
-		 *         see #define NEW_DRAIN
-		 *         2010-02-13: RH now enabled, it seems to be needed for CBR too,
-		 *                     as there exists one example, where the FhG decoder
-		 *                     can't decode a -b320 CBR file anymore.
-		 * 
-		 *      l3_side.resvDrain_post:
-		 *         ancillary data to be added to this frame:
-		 * 
-		 * 
- */ - - /* main_data_begin has 9 bits in MPEG-1, 8 bits MPEG-2 */ - var resvLimit = (8 * 256) * gfc.mode_gr - 8; - - /* - * maximum allowed frame size. dont use more than this number of bits, - * even if the frame has the space for them: - */ - if (gfp.brate > 320) { - /* in freeformat the buffer is constant */ - maxmp3buf = 8 * ((int) ((gfp.brate * 1000) - / (gfp.out_samplerate / 1152) / 8 + .5)); - } else { - /* - * all mp3 decoders should have enough buffer to handle this value: - * size of a 320kbps 32kHz frame - */ - maxmp3buf = 8 * 1440; - - /* - * Bouvigne suggests this more lax interpretation of the ISO doc - * instead of using 8*960. - */ - - if (gfp.strict_ISO) { - maxmp3buf = 8 * ((int) (320000 / (gfp.out_samplerate / 1152) / 8 + .5)); - } - } - - gfc.ResvMax = maxmp3buf - frameLength; - if (gfc.ResvMax > resvLimit) - gfc.ResvMax = resvLimit; - if (gfc.ResvMax < 0 || gfp.disable_reservoir) - gfc.ResvMax = 0; - - var fullFrameBits = mean_bits.bits * gfc.mode_gr - + Math.min(gfc.ResvSize, gfc.ResvMax); - - if (fullFrameBits > maxmp3buf) - fullFrameBits = maxmp3buf; - - - l3_side.resvDrain_pre = 0; - - // frame analyzer code - if (gfc.pinfo != null) { - /* - * expected bits per channel per granule [is this also right for - * mono/stereo, MPEG-1/2 ?] - */ - gfc.pinfo.mean_bits = mean_bits.bits / 2; - gfc.pinfo.resvsize = gfc.ResvSize; - } - - return fullFrameBits; - } - - /** - * returns targ_bits: target number of bits to use for 1 granule
- * extra_bits: amount extra available from reservoir
- * Mark Taylor 4/99 - */ - this.ResvMaxBits = function(gfp, mean_bits, targ_bits, cbr) { - var gfc = gfp.internal_flags; - var add_bits; - var ResvSize = gfc.ResvSize, ResvMax = gfc.ResvMax; - - /* compensate the saved bits used in the 1st granule */ - if (cbr != 0) - ResvSize += mean_bits; - - if ((gfc.substep_shaping & 1) != 0) - ResvMax *= 0.9; - - targ_bits.bits = mean_bits; - - /* extra bits if the reservoir is almost full */ - if (ResvSize * 10 > ResvMax * 9) { - add_bits = ResvSize - (ResvMax * 9) / 10; - targ_bits.bits += add_bits; - gfc.substep_shaping |= 0x80; - } else { - add_bits = 0; - gfc.substep_shaping &= 0x7f; - /* - * build up reservoir. this builds the reservoir a little slower - * than FhG. It could simple be mean_bits/15, but this was rigged to - * always produce 100 (the old value) at 128kbs - */ - if (!gfp.disable_reservoir && 0 == (gfc.substep_shaping & 1)) - targ_bits.bits -= .1 * mean_bits; - } - - /* amount from the reservoir we are allowed to use. ISO says 6/10 */ - var extra_bits = (ResvSize < (gfc.ResvMax * 6) / 10 ? ResvSize - : (gfc.ResvMax * 6) / 10); - extra_bits -= add_bits; - - if (extra_bits < 0) - extra_bits = 0; - return extra_bits; - } - - /** - * Called after a granule's bit allocation. Readjusts the size of the - * reservoir to reflect the granule's usage. - */ - this.ResvAdjust = function(gfc, gi) { - gfc.ResvSize -= gi.part2_3_length + gi.part2_length; - } - - /** - * Called after all granules in a frame have been allocated. Makes sure that - * the reservoir size is within limits, possibly by adding stuffing bits. - */ - this.ResvFrameEnd = function(gfc, mean_bits) { - var over_bits; - var l3_side = gfc.l3_side; - - gfc.ResvSize += mean_bits * gfc.mode_gr; - var stuffingBits = 0; - l3_side.resvDrain_post = 0; - l3_side.resvDrain_pre = 0; - - /* we must be byte aligned */ - if ((over_bits = gfc.ResvSize % 8) != 0) - stuffingBits += over_bits; - - over_bits = (gfc.ResvSize - stuffingBits) - gfc.ResvMax; - if (over_bits > 0) { - stuffingBits += over_bits; - } - - /* - * NOTE: enabling the NEW_DRAIN code fixes some problems with FhG - * decoder shipped with MS Windows operating systems. Using this, it is - * even possible to use Gabriel's lax buffer consideration again, which - * assumes, any decoder should have a buffer large enough for a 320 kbps - * frame at 32 kHz sample rate. - * - * old drain code: lame -b320 BlackBird.wav --. does not play with - * GraphEdit.exe using FhG decoder V1.5 Build 50 - * - * new drain code: lame -b320 BlackBird.wav --. plays fine with - * GraphEdit.exe using FhG decoder V1.5 Build 50 - * - * Robert Hegemann, 2010-02-13. - */ - /* - * drain as many bits as possible into previous frame ancillary data In - * particular, in VBR mode ResvMax may have changed, and we have to make - * sure main_data_begin does not create a reservoir bigger than ResvMax - * mt 4/00 - */ - { - var mdb_bytes = Math.min(l3_side.main_data_begin * 8, stuffingBits) / 8; - l3_side.resvDrain_pre += 8 * mdb_bytes; - stuffingBits -= 8 * mdb_bytes; - gfc.ResvSize -= 8 * mdb_bytes; - l3_side.main_data_begin -= mdb_bytes; - } - /* drain the rest into this frames ancillary data */ - l3_side.resvDrain_post += stuffingBits; - gfc.ResvSize -= stuffingBits; - } -} - - - -BitStream.EQ = function (a, b) { - return (Math.abs(a) > Math.abs(b)) ? (Math.abs((a) - (b)) <= (Math - .abs(a) * 1e-6)) - : (Math.abs((a) - (b)) <= (Math.abs(b) * 1e-6)); -}; - -BitStream.NEQ = function (a, b) { - return !BitStream.EQ(a, b); -}; - -function BitStream() { - var self = this; - var CRC16_POLYNOMIAL = 0x8005; - - /* - * we work with ints, so when doing bit manipulation, we limit ourselves to - * MAX_LENGTH-2 just to be on the safe side - */ - var MAX_LENGTH = 32; - - //GainAnalysis ga; - //MPGLib mpg; - //Version ver; - //VBRTag vbr; - var ga = null; - var mpg = null; - var ver = null; - var vbr = null; - - //public final void setModules(GainAnalysis ga, MPGLib mpg, Version ver, - // VBRTag vbr) { - - this.setModules = function (_ga, _mpg, _ver, _vbr) { - ga = _ga; - mpg = _mpg; - ver = _ver; - vbr = _vbr; - }; - - /** - * Bit stream buffer. - */ - //private byte[] buf; - var buf = null; - /** - * Bit counter of bit stream. - */ - var totbit = 0; - /** - * Pointer to top byte in buffer. - */ - var bufByteIdx = 0; - /** - * Pointer to top bit of top byte in buffer. - */ - var bufBitIdx = 0; - - /** - * compute bitsperframe and mean_bits for a layer III frame - */ - this.getframebits = function (gfp) { - var gfc = gfp.internal_flags; - var bit_rate; - - /* get bitrate in kbps [?] */ - if (gfc.bitrate_index != 0) - bit_rate = Tables.bitrate_table[gfp.version][gfc.bitrate_index]; - else - bit_rate = gfp.brate; - - /* main encoding routine toggles padding on and off */ - /* one Layer3 Slot consists of 8 bits */ - var bytes = 0 | (gfp.version + 1) * 72000 * bit_rate / gfp.out_samplerate + gfc.padding; - return 8 * bytes; - }; - - function putheader_bits(gfc) { - System.arraycopy(gfc.header[gfc.w_ptr].buf, 0, buf, bufByteIdx, gfc.sideinfo_len); - bufByteIdx += gfc.sideinfo_len; - totbit += gfc.sideinfo_len * 8; - gfc.w_ptr = (gfc.w_ptr + 1) & (LameInternalFlags.MAX_HEADER_BUF - 1); - } - - /** - * write j bits into the bit stream - */ - function putbits2(gfc, val, j) { - - while (j > 0) { - var k; - if (bufBitIdx == 0) { - bufBitIdx = 8; - bufByteIdx++; - if (gfc.header[gfc.w_ptr].write_timing == totbit) { - putheader_bits(gfc); - } - buf[bufByteIdx] = 0; - } - - k = Math.min(j, bufBitIdx); - j -= k; - - bufBitIdx -= k; - - /* 32 too large on 32 bit machines */ - - buf[bufByteIdx] |= ((val >> j) << bufBitIdx); - totbit += k; - } - } - - /** - * write j bits into the bit stream, ignoring frame headers - */ - function putbits_noheaders(gfc, val, j) { - - while (j > 0) { - var k; - if (bufBitIdx == 0) { - bufBitIdx = 8; - bufByteIdx++; - buf[bufByteIdx] = 0; - } - - k = Math.min(j, bufBitIdx); - j -= k; - - bufBitIdx -= k; - - /* 32 too large on 32 bit machines */ - - buf[bufByteIdx] |= ((val >> j) << bufBitIdx); - totbit += k; - } - } - - /** - * Some combinations of bitrate, Fs, and stereo make it impossible to stuff - * out a frame using just main_data, due to the limited number of bits to - * indicate main_data_length. In these situations, we put stuffing bits into - * the ancillary data... - */ - function drain_into_ancillary(gfp, remainingBits) { - var gfc = gfp.internal_flags; - var i; - - if (remainingBits >= 8) { - putbits2(gfc, 0x4c, 8); - remainingBits -= 8; - } - if (remainingBits >= 8) { - putbits2(gfc, 0x41, 8); - remainingBits -= 8; - } - if (remainingBits >= 8) { - putbits2(gfc, 0x4d, 8); - remainingBits -= 8; - } - if (remainingBits >= 8) { - putbits2(gfc, 0x45, 8); - remainingBits -= 8; - } - - if (remainingBits >= 32) { - var version = ver.getLameShortVersion(); - if (remainingBits >= 32) - for (i = 0; i < version.length && remainingBits >= 8; ++i) { - remainingBits -= 8; - putbits2(gfc, version.charAt(i), 8); - } - } - - for (; remainingBits >= 1; remainingBits -= 1) { - putbits2(gfc, gfc.ancillary_flag, 1); - gfc.ancillary_flag ^= (!gfp.disable_reservoir ? 1 : 0); - } - - - } - - /** - * write N bits into the header - */ - function writeheader(gfc, val, j) { - var ptr = gfc.header[gfc.h_ptr].ptr; - - while (j > 0) { - var k = Math.min(j, 8 - (ptr & 7)); - j -= k; - /* >> 32 too large for 32 bit machines */ - - gfc.header[gfc.h_ptr].buf[ptr >> 3] |= ((val >> j)) << (8 - (ptr & 7) - k); - ptr += k; - } - gfc.header[gfc.h_ptr].ptr = ptr; - } - - function CRC_update(value, crc) { - value <<= 8; - for (var i = 0; i < 8; i++) { - value <<= 1; - crc <<= 1; - - if ((((crc ^ value) & 0x10000) != 0)) - crc ^= CRC16_POLYNOMIAL; - } - return crc; - } - - this.CRC_writeheader = function (gfc, header) { - var crc = 0xffff; - /* (jo) init crc16 for error_protection */ - - crc = CRC_update(header[2] & 0xff, crc); - crc = CRC_update(header[3] & 0xff, crc); - for (var i = 6; i < gfc.sideinfo_len; i++) { - crc = CRC_update(header[i] & 0xff, crc); - } - - header[4] = (byte)(crc >> 8); - header[5] = (byte)(crc & 255); - }; - - function encodeSideInfo2(gfp, bitsPerFrame) { - var gfc = gfp.internal_flags; - var l3_side; - var gr, ch; - - l3_side = gfc.l3_side; - gfc.header[gfc.h_ptr].ptr = 0; - Arrays.fill(gfc.header[gfc.h_ptr].buf, 0, gfc.sideinfo_len, 0); - if (gfp.out_samplerate < 16000) - writeheader(gfc, 0xffe, 12); - else - writeheader(gfc, 0xfff, 12); - writeheader(gfc, (gfp.version), 1); - writeheader(gfc, 4 - 3, 2); - writeheader(gfc, (!gfp.error_protection ? 1 : 0), 1); - writeheader(gfc, (gfc.bitrate_index), 4); - writeheader(gfc, (gfc.samplerate_index), 2); - writeheader(gfc, (gfc.padding), 1); - writeheader(gfc, (gfp.extension), 1); - writeheader(gfc, (gfp.mode.ordinal()), 2); - writeheader(gfc, (gfc.mode_ext), 2); - writeheader(gfc, (gfp.copyright), 1); - writeheader(gfc, (gfp.original), 1); - writeheader(gfc, (gfp.emphasis), 2); - if (gfp.error_protection) { - writeheader(gfc, 0, 16); - /* dummy */ - } - - if (gfp.version == 1) { - /* MPEG1 */ - writeheader(gfc, (l3_side.main_data_begin), 9); - - if (gfc.channels_out == 2) - writeheader(gfc, l3_side.private_bits, 3); - else - writeheader(gfc, l3_side.private_bits, 5); - - for (ch = 0; ch < gfc.channels_out; ch++) { - var band; - for (band = 0; band < 4; band++) { - writeheader(gfc, l3_side.scfsi[ch][band], 1); - } - } - - for (gr = 0; gr < 2; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - var gi = l3_side.tt[gr][ch]; - writeheader(gfc, gi.part2_3_length + gi.part2_length, 12); - writeheader(gfc, gi.big_values / 2, 9); - writeheader(gfc, gi.global_gain, 8); - writeheader(gfc, gi.scalefac_compress, 4); - - if (gi.block_type != Encoder.NORM_TYPE) { - writeheader(gfc, 1, 1); - /* window_switching_flag */ - writeheader(gfc, gi.block_type, 2); - writeheader(gfc, gi.mixed_block_flag, 1); - - if (gi.table_select[0] == 14) - gi.table_select[0] = 16; - writeheader(gfc, gi.table_select[0], 5); - if (gi.table_select[1] == 14) - gi.table_select[1] = 16; - writeheader(gfc, gi.table_select[1], 5); - - writeheader(gfc, gi.subblock_gain[0], 3); - writeheader(gfc, gi.subblock_gain[1], 3); - writeheader(gfc, gi.subblock_gain[2], 3); - } else { - writeheader(gfc, 0, 1); - /* window_switching_flag */ - if (gi.table_select[0] == 14) - gi.table_select[0] = 16; - writeheader(gfc, gi.table_select[0], 5); - if (gi.table_select[1] == 14) - gi.table_select[1] = 16; - writeheader(gfc, gi.table_select[1], 5); - if (gi.table_select[2] == 14) - gi.table_select[2] = 16; - writeheader(gfc, gi.table_select[2], 5); - - writeheader(gfc, gi.region0_count, 4); - writeheader(gfc, gi.region1_count, 3); - } - writeheader(gfc, gi.preflag, 1); - writeheader(gfc, gi.scalefac_scale, 1); - writeheader(gfc, gi.count1table_select, 1); - } - } - } else { - /* MPEG2 */ - writeheader(gfc, (l3_side.main_data_begin), 8); - writeheader(gfc, l3_side.private_bits, gfc.channels_out); - - gr = 0; - for (ch = 0; ch < gfc.channels_out; ch++) { - var gi = l3_side.tt[gr][ch]; - writeheader(gfc, gi.part2_3_length + gi.part2_length, 12); - writeheader(gfc, gi.big_values / 2, 9); - writeheader(gfc, gi.global_gain, 8); - writeheader(gfc, gi.scalefac_compress, 9); - - if (gi.block_type != Encoder.NORM_TYPE) { - writeheader(gfc, 1, 1); - /* window_switching_flag */ - writeheader(gfc, gi.block_type, 2); - writeheader(gfc, gi.mixed_block_flag, 1); - - if (gi.table_select[0] == 14) - gi.table_select[0] = 16; - writeheader(gfc, gi.table_select[0], 5); - if (gi.table_select[1] == 14) - gi.table_select[1] = 16; - writeheader(gfc, gi.table_select[1], 5); - - writeheader(gfc, gi.subblock_gain[0], 3); - writeheader(gfc, gi.subblock_gain[1], 3); - writeheader(gfc, gi.subblock_gain[2], 3); - } else { - writeheader(gfc, 0, 1); - /* window_switching_flag */ - if (gi.table_select[0] == 14) - gi.table_select[0] = 16; - writeheader(gfc, gi.table_select[0], 5); - if (gi.table_select[1] == 14) - gi.table_select[1] = 16; - writeheader(gfc, gi.table_select[1], 5); - if (gi.table_select[2] == 14) - gi.table_select[2] = 16; - writeheader(gfc, gi.table_select[2], 5); - - writeheader(gfc, gi.region0_count, 4); - writeheader(gfc, gi.region1_count, 3); - } - - writeheader(gfc, gi.scalefac_scale, 1); - writeheader(gfc, gi.count1table_select, 1); - } - } - - if (gfp.error_protection) { - /* (jo) error_protection: add crc16 information to header */ - CRC_writeheader(gfc, gfc.header[gfc.h_ptr].buf); - } - - { - var old = gfc.h_ptr; - - gfc.h_ptr = (old + 1) & (LameInternalFlags.MAX_HEADER_BUF - 1); - gfc.header[gfc.h_ptr].write_timing = gfc.header[old].write_timing - + bitsPerFrame; - - if (gfc.h_ptr == gfc.w_ptr) { - /* yikes! we are out of header buffer space */ - System.err - .println("Error: MAX_HEADER_BUF too small in bitstream.c \n"); - } - - } - } - - function huffman_coder_count1(gfc, gi) { - /* Write count1 area */ - var h = Tables.ht[gi.count1table_select + 32]; - var i, bits = 0; - - var ix = gi.big_values; - var xr = gi.big_values; - - for (i = (gi.count1 - gi.big_values) / 4; i > 0; --i) { - var huffbits = 0; - var p = 0, v; - - v = gi.l3_enc[ix + 0]; - if (v != 0) { - p += 8; - if (gi.xr[xr + 0] < 0) - huffbits++; - } - - v = gi.l3_enc[ix + 1]; - if (v != 0) { - p += 4; - huffbits *= 2; - if (gi.xr[xr + 1] < 0) - huffbits++; - } - - v = gi.l3_enc[ix + 2]; - if (v != 0) { - p += 2; - huffbits *= 2; - if (gi.xr[xr + 2] < 0) - huffbits++; - } - - v = gi.l3_enc[ix + 3]; - if (v != 0) { - p++; - huffbits *= 2; - if (gi.xr[xr + 3] < 0) - huffbits++; - } - - ix += 4; - xr += 4; - putbits2(gfc, huffbits + h.table[p], h.hlen[p]); - bits += h.hlen[p]; - } - return bits; - } - - /** - * Implements the pseudocode of page 98 of the IS - */ - function Huffmancode(gfc, tableindex, start, end, gi) { - var h = Tables.ht[tableindex]; - var bits = 0; - - if (0 == tableindex) - return bits; - - for (var i = start; i < end; i += 2) { - var cbits = 0; - var xbits = 0; - var linbits = h.xlen; - var xlen = h.xlen; - var ext = 0; - var x1 = gi.l3_enc[i]; - var x2 = gi.l3_enc[i + 1]; - - if (x1 != 0) { - if (gi.xr[i] < 0) - ext++; - cbits--; - } - - if (tableindex > 15) { - /* use ESC-words */ - if (x1 > 14) { - var linbits_x1 = x1 - 15; - ext |= linbits_x1 << 1; - xbits = linbits; - x1 = 15; - } - - if (x2 > 14) { - var linbits_x2 = x2 - 15; - ext <<= linbits; - ext |= linbits_x2; - xbits += linbits; - x2 = 15; - } - xlen = 16; - } - - if (x2 != 0) { - ext <<= 1; - if (gi.xr[i + 1] < 0) - ext++; - cbits--; - } - - - x1 = x1 * xlen + x2; - xbits -= cbits; - cbits += h.hlen[x1]; - - - putbits2(gfc, h.table[x1], cbits); - putbits2(gfc, ext, xbits); - bits += cbits + xbits; - } - return bits; - } - - /** - * Note the discussion of huffmancodebits() on pages 28 and 29 of the IS, as - * well as the definitions of the side information on pages 26 and 27. - */ - function ShortHuffmancodebits(gfc, gi) { - var region1Start = 3 * gfc.scalefac_band.s[3]; - if (region1Start > gi.big_values) - region1Start = gi.big_values; - - /* short blocks do not have a region2 */ - var bits = Huffmancode(gfc, gi.table_select[0], 0, region1Start, gi); - bits += Huffmancode(gfc, gi.table_select[1], region1Start, - gi.big_values, gi); - return bits; - } - - function LongHuffmancodebits(gfc, gi) { - var bigvalues, bits; - var region1Start, region2Start; - - bigvalues = gi.big_values; - - var i = gi.region0_count + 1; - region1Start = gfc.scalefac_band.l[i]; - i += gi.region1_count + 1; - region2Start = gfc.scalefac_band.l[i]; - - if (region1Start > bigvalues) - region1Start = bigvalues; - - if (region2Start > bigvalues) - region2Start = bigvalues; - - bits = Huffmancode(gfc, gi.table_select[0], 0, region1Start, gi); - bits += Huffmancode(gfc, gi.table_select[1], region1Start, - region2Start, gi); - bits += Huffmancode(gfc, gi.table_select[2], region2Start, bigvalues, - gi); - return bits; - } - - function writeMainData(gfp) { - var gr, ch, sfb, data_bits, tot_bits = 0; - var gfc = gfp.internal_flags; - var l3_side = gfc.l3_side; - - if (gfp.version == 1) { - /* MPEG 1 */ - for (gr = 0; gr < 2; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - var gi = l3_side.tt[gr][ch]; - var slen1 = Takehiro.slen1_tab[gi.scalefac_compress]; - var slen2 = Takehiro.slen2_tab[gi.scalefac_compress]; - data_bits = 0; - for (sfb = 0; sfb < gi.sfbdivide; sfb++) { - if (gi.scalefac[sfb] == -1) - continue; - /* scfsi is used */ - putbits2(gfc, gi.scalefac[sfb], slen1); - data_bits += slen1; - } - for (; sfb < gi.sfbmax; sfb++) { - if (gi.scalefac[sfb] == -1) - continue; - /* scfsi is used */ - putbits2(gfc, gi.scalefac[sfb], slen2); - data_bits += slen2; - } - - if (gi.block_type == Encoder.SHORT_TYPE) { - data_bits += ShortHuffmancodebits(gfc, gi); - } else { - data_bits += LongHuffmancodebits(gfc, gi); - } - data_bits += huffman_coder_count1(gfc, gi); - /* does bitcount in quantize.c agree with actual bit count? */ - tot_bits += data_bits; - } - /* for ch */ - } - /* for gr */ - } else { - /* MPEG 2 */ - gr = 0; - for (ch = 0; ch < gfc.channels_out; ch++) { - var gi = l3_side.tt[gr][ch]; - var i, sfb_partition, scale_bits = 0; - data_bits = 0; - sfb = 0; - sfb_partition = 0; - - if (gi.block_type == Encoder.SHORT_TYPE) { - for (; sfb_partition < 4; sfb_partition++) { - var sfbs = gi.sfb_partition_table[sfb_partition] / 3; - var slen = gi.slen[sfb_partition]; - for (i = 0; i < sfbs; i++, sfb++) { - putbits2(gfc, - Math.max(gi.scalefac[sfb * 3 + 0], 0), slen); - putbits2(gfc, - Math.max(gi.scalefac[sfb * 3 + 1], 0), slen); - putbits2(gfc, - Math.max(gi.scalefac[sfb * 3 + 2], 0), slen); - scale_bits += 3 * slen; - } - } - data_bits += ShortHuffmancodebits(gfc, gi); - } else { - for (; sfb_partition < 4; sfb_partition++) { - var sfbs = gi.sfb_partition_table[sfb_partition]; - var slen = gi.slen[sfb_partition]; - for (i = 0; i < sfbs; i++, sfb++) { - putbits2(gfc, Math.max(gi.scalefac[sfb], 0), slen); - scale_bits += slen; - } - } - data_bits += LongHuffmancodebits(gfc, gi); - } - data_bits += huffman_coder_count1(gfc, gi); - /* does bitcount in quantize.c agree with actual bit count? */ - tot_bits += scale_bits + data_bits; - } - /* for ch */ - } - /* for gf */ - return tot_bits; - } - - /* main_data */ - - function TotalBytes() { - this.total = 0; - } - - /* - * compute the number of bits required to flush all mp3 frames currently in - * the buffer. This should be the same as the reservoir size. Only call this - * routine between frames - i.e. only after all headers and data have been - * added to the buffer by format_bitstream(). - * - * Also compute total_bits_output = size of mp3 buffer (including frame - * headers which may not have yet been send to the mp3 buffer) + number of - * bits needed to flush all mp3 frames. - * - * total_bytes_output is the size of the mp3 output buffer if - * lame_encode_flush_nogap() was called right now. - */ - function compute_flushbits(gfp, total_bytes_output) { - var gfc = gfp.internal_flags; - var flushbits, remaining_headers; - var bitsPerFrame; - var last_ptr, first_ptr; - first_ptr = gfc.w_ptr; - /* first header to add to bitstream */ - last_ptr = gfc.h_ptr - 1; - /* last header to add to bitstream */ - if (last_ptr == -1) - last_ptr = LameInternalFlags.MAX_HEADER_BUF - 1; - - /* add this many bits to bitstream so we can flush all headers */ - flushbits = gfc.header[last_ptr].write_timing - totbit; - total_bytes_output.total = flushbits; - - if (flushbits >= 0) { - /* if flushbits >= 0, some headers have not yet been written */ - /* reduce flushbits by the size of the headers */ - remaining_headers = 1 + last_ptr - first_ptr; - if (last_ptr < first_ptr) - remaining_headers = 1 + last_ptr - first_ptr - + LameInternalFlags.MAX_HEADER_BUF; - flushbits -= remaining_headers * 8 * gfc.sideinfo_len; - } - - /* - * finally, add some bits so that the last frame is complete these bits - * are not necessary to decode the last frame, but some decoders will - * ignore last frame if these bits are missing - */ - bitsPerFrame = self.getframebits(gfp); - flushbits += bitsPerFrame; - total_bytes_output.total += bitsPerFrame; - /* round up: */ - if ((total_bytes_output.total % 8) != 0) - total_bytes_output.total = 1 + (total_bytes_output.total / 8); - else - total_bytes_output.total = (total_bytes_output.total / 8); - total_bytes_output.total += bufByteIdx + 1; - - if (flushbits < 0) { - System.err.println("strange error flushing buffer ... \n"); - } - return flushbits; - } - - this.flush_bitstream = function (gfp) { - var gfc = gfp.internal_flags; - var l3_side; - var flushbits; - var last_ptr = gfc.h_ptr - 1; - /* last header to add to bitstream */ - if (last_ptr == -1) - last_ptr = LameInternalFlags.MAX_HEADER_BUF - 1; - l3_side = gfc.l3_side; - - if ((flushbits = compute_flushbits(gfp, new TotalBytes())) < 0) - return; - drain_into_ancillary(gfp, flushbits); - - /* check that the 100% of the last frame has been written to bitstream */ - - /* - * we have padded out all frames with ancillary data, which is the same - * as filling the bitreservoir with ancillary data, so : - */ - gfc.ResvSize = 0; - l3_side.main_data_begin = 0; - - /* save the ReplayGain value */ - if (gfc.findReplayGain) { - var RadioGain = ga.GetTitleGain(gfc.rgdata); - gfc.RadioGain = Math.floor(RadioGain * 10.0 + 0.5) | 0; - /* round to nearest */ - } - - /* find the gain and scale change required for no clipping */ - if (gfc.findPeakSample) { - gfc.noclipGainChange = Math.ceil(Math - .log10(gfc.PeakSample / 32767.0) * 20.0 * 10.0) | 0; - /* round up */ - - if (gfc.noclipGainChange > 0) { - /* clipping occurs */ - if (EQ(gfp.scale, 1.0) || EQ(gfp.scale, 0.0)) - gfc.noclipScale = (Math - .floor((32767.0 / gfc.PeakSample) * 100.0) / 100.0); - /* round down */ - else { - /* - * the user specified his own scaling factor. We could - * suggest the scaling factor of - * (32767.0/gfp.PeakSample)*(gfp.scale) but it's usually - * very inaccurate. So we'd rather not advice him on the - * scaling factor. - */ - gfc.noclipScale = -1; - } - } else - /* no clipping */ - gfc.noclipScale = -1; - } - }; - - this.add_dummy_byte = function (gfp, val, n) { - var gfc = gfp.internal_flags; - var i; - - while (n-- > 0) { - putbits_noheaders(gfc, val, 8); - - for (i = 0; i < LameInternalFlags.MAX_HEADER_BUF; ++i) - gfc.header[i].write_timing += 8; - } - }; - - /** - * This is called after a frame of audio has been quantized and coded. It - * will write the encoded audio to the bitstream. Note that from a layer3 - * encoder's perspective the bit stream is primarily a series of main_data() - * blocks, with header and side information inserted at the proper locations - * to maintain framing. (See Figure A.7 in the IS). - */ - this.format_bitstream = function (gfp) { - var gfc = gfp.internal_flags; - var l3_side; - l3_side = gfc.l3_side; - - var bitsPerFrame = this.getframebits(gfp); - drain_into_ancillary(gfp, l3_side.resvDrain_pre); - - encodeSideInfo2(gfp, bitsPerFrame); - var bits = 8 * gfc.sideinfo_len; - bits += writeMainData(gfp); - drain_into_ancillary(gfp, l3_side.resvDrain_post); - bits += l3_side.resvDrain_post; - - l3_side.main_data_begin += (bitsPerFrame - bits) / 8; - - /* - * compare number of bits needed to clear all buffered mp3 frames with - * what we think the resvsize is: - */ - if (compute_flushbits(gfp, new TotalBytes()) != gfc.ResvSize) { - System.err.println("Internal buffer inconsistency. flushbits <> ResvSize"); - } - - /* - * compare main_data_begin for the next frame with what we think the - * resvsize is: - */ - if ((l3_side.main_data_begin * 8) != gfc.ResvSize) { - System.err.printf("bit reservoir error: \n" - + "l3_side.main_data_begin: %d \n" - + "Resvoir size: %d \n" - + "resv drain (post) %d \n" - + "resv drain (pre) %d \n" - + "header and sideinfo: %d \n" - + "data bits: %d \n" - + "total bits: %d (remainder: %d) \n" - + "bitsperframe: %d \n", - 8 * l3_side.main_data_begin, gfc.ResvSize, - l3_side.resvDrain_post, l3_side.resvDrain_pre, - 8 * gfc.sideinfo_len, bits - l3_side.resvDrain_post - 8 - * gfc.sideinfo_len, bits, bits % 8, bitsPerFrame); - - System.err.println("This is a fatal error. It has several possible causes:"); - System.err.println("90%% LAME compiled with buggy version of gcc using advanced optimizations"); - System.err.println(" 9%% Your system is overclocked"); - System.err.println(" 1%% bug in LAME encoding library"); - - gfc.ResvSize = l3_side.main_data_begin * 8; - } - //; - - if (totbit > 1000000000) { - /* - * to avoid totbit overflow, (at 8h encoding at 128kbs) lets reset - * bit counter - */ - var i; - for (i = 0; i < LameInternalFlags.MAX_HEADER_BUF; ++i) - gfc.header[i].write_timing -= totbit; - totbit = 0; - } - - return 0; - }; - - /** - *
-     * copy data out of the internal MP3 bit buffer into a user supplied
-     *       unsigned char buffer.
-     *
-     *       mp3data=0      indicates data in buffer is an id3tags and VBR tags
-     *       mp3data=1      data is real mp3 frame data.
-     * 
- */ - this.copy_buffer = function (gfc, buffer, bufferPos, size, mp3data) { - var minimum = bufByteIdx + 1; - if (minimum <= 0) - return 0; - if (size != 0 && minimum > size) { - /* buffer is too small */ - return -1; - } - System.arraycopy(buf, 0, buffer, bufferPos, minimum); - bufByteIdx = -1; - bufBitIdx = 0; - - if (mp3data != 0) { - var crc = new_int(1); - crc[0] = gfc.nMusicCRC; - vbr.updateMusicCRC(crc, buffer, bufferPos, minimum); - gfc.nMusicCRC = crc[0]; - - /** - * sum number of bytes belonging to the mp3 stream this info will be - * written into the Xing/LAME header for seeking - */ - if (minimum > 0) { - gfc.VBR_seek_table.nBytesWritten += minimum; - } - - if (gfc.decode_on_the_fly) { /* decode the frame */ - var pcm_buf = new_float_n([2, 1152]); - var mp3_in = minimum; - var samples_out = -1; - var i; - - /* re-synthesis to pcm. Repeat until we get a samples_out=0 */ - while (samples_out != 0) { - - samples_out = mpg.hip_decode1_unclipped(gfc.hip, buffer, - bufferPos, mp3_in, pcm_buf[0], pcm_buf[1]); - /* - * samples_out = 0: need more data to decode samples_out = - * -1: error. Lets assume 0 pcm output samples_out = number - * of samples output - */ - - /* - * set the lenght of the mp3 input buffer to zero, so that - * in the next iteration of the loop we will be querying - * mpglib about buffered data - */ - mp3_in = 0; - - if (samples_out == -1) { - /* - * error decoding. Not fatal, but might screw up the - * ReplayGain tag. What should we do? Ignore for now - */ - samples_out = 0; - } - if (samples_out > 0) { - /* process the PCM data */ - - /* - * this should not be possible, and indicates we have - * overflown the pcm_buf buffer - */ - - if (gfc.findPeakSample) { - for (i = 0; i < samples_out; i++) { - if (pcm_buf[0][i] > gfc.PeakSample) - gfc.PeakSample = pcm_buf[0][i]; - else if (-pcm_buf[0][i] > gfc.PeakSample) - gfc.PeakSample = -pcm_buf[0][i]; - } - if (gfc.channels_out > 1) - for (i = 0; i < samples_out; i++) { - if (pcm_buf[1][i] > gfc.PeakSample) - gfc.PeakSample = pcm_buf[1][i]; - else if (-pcm_buf[1][i] > gfc.PeakSample) - gfc.PeakSample = -pcm_buf[1][i]; - } - } - - if (gfc.findReplayGain) - if (ga.AnalyzeSamples(gfc.rgdata, pcm_buf[0], 0, - pcm_buf[1], 0, samples_out, - gfc.channels_out) == GainAnalysis.GAIN_ANALYSIS_ERROR) - return -6; - - } - /* if (samples_out>0) */ - } - /* while (samples_out!=0) */ - } - /* if (gfc.decode_on_the_fly) */ - - } - /* if (mp3data) */ - return minimum; - }; - - this.init_bit_stream_w = function (gfc) { - buf = new_byte(Lame.LAME_MAXMP3BUFFER); - - gfc.h_ptr = gfc.w_ptr = 0; - gfc.header[gfc.h_ptr].write_timing = 0; - bufByteIdx = -1; - bufBitIdx = 0; - totbit = 0; - }; - - // From machine.h - - -} - - -/** - * A Vbr header may be present in the ancillary data field of the first frame of - * an mp3 bitstream
- * The Vbr header (optionally) contains - *
    - *
  • frames total number of audio frames in the bitstream - *
  • bytes total number of bytes in the bitstream - *
  • toc table of contents - *
- * - * toc (table of contents) gives seek points for random access.
- * The ith entry determines the seek point for i-percent duration.
- * seek point in bytes = (toc[i]/256.0) * total_bitstream_bytes
- * e.g. half duration seek point = (toc[50]/256.0) * total_bitstream_bytes - */ -VBRTag.NUMTOCENTRIES = 100; -VBRTag.MAXFRAMESIZE = 2880; - -function VBRTag() { - - var lame; - var bs; - var v; - - this.setModules = function (_lame, _bs, _v) { - lame = _lame; - bs = _bs; - v = _v; - }; - - var FRAMES_FLAG = 0x0001; - var BYTES_FLAG = 0x0002; - var TOC_FLAG = 0x0004; - var VBR_SCALE_FLAG = 0x0008; - - var NUMTOCENTRIES = VBRTag.NUMTOCENTRIES; - - /** - * (0xB40) the max freeformat 640 32kHz framesize. - */ - var MAXFRAMESIZE = VBRTag.MAXFRAMESIZE; - - /** - *
-     *    4 bytes for Header Tag
-     *    4 bytes for Header Flags
-     *  100 bytes for entry (toc)
-     *    4 bytes for frame size
-     *    4 bytes for stream size
-     *    4 bytes for VBR scale. a VBR quality indicator: 0=best 100=worst
-     *   20 bytes for LAME tag.  for example, "LAME3.12 (beta 6)"
-     * ___________
-     *  140 bytes
-     * 
- */ - var VBRHEADERSIZE = (NUMTOCENTRIES + 4 + 4 + 4 + 4 + 4); - - var LAMEHEADERSIZE = (VBRHEADERSIZE + 9 + 1 + 1 + 8 - + 1 + 1 + 3 + 1 + 1 + 2 + 4 + 2 + 2); - - /** - * The size of the Xing header MPEG-1, bit rate in kbps. - */ - var XING_BITRATE1 = 128; - /** - * The size of the Xing header MPEG-2, bit rate in kbps. - */ - var XING_BITRATE2 = 64; - /** - * The size of the Xing header MPEG-2.5, bit rate in kbps. - */ - var XING_BITRATE25 = 32; - - /** - * ISO-8859-1 charset for byte to string operations. - */ - var ISO_8859_1 = null; //Charset.forName("ISO-8859-1"); - - /** - * VBR header magic string. - */ - var VBRTag0 = "Xing"; - /** - * VBR header magic string (VBR == VBRMode.vbr_off). - */ - var VBRTag1 = "Info"; - - /** - * Lookup table for fast CRC-16 computation. Uses the polynomial - * x^16+x^15+x^2+1 - */ - var crc16Lookup = [0x0000, 0xC0C1, 0xC181, 0x0140, - 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, - 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, - 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, - 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, - 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, - 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, - 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, - 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, - 0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, - 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, - 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, - 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, - 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, - 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, - 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, - 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, - 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, - 0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, - 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, - 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, - 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, - 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, - 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, - 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, - 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, - 0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, - 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, - 0x9901, 0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, - 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, - 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, - 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, - 0x4100, 0x81C1, 0x8081, 0x4040]; - - /*********************************************************************** - * Robert Hegemann 2001-01-17 - ***********************************************************************/ - - function addVbr(v, bitrate) { - v.nVbrNumFrames++; - v.sum += bitrate; - v.seen++; - - if (v.seen < v.want) { - return; - } - - if (v.pos < v.size) { - v.bag[v.pos] = v.sum; - v.pos++; - v.seen = 0; - } - if (v.pos == v.size) { - for (var i = 1; i < v.size; i += 2) { - v.bag[i / 2] = v.bag[i]; - } - v.want *= 2; - v.pos /= 2; - } - } - - function xingSeekTable(v, t) { - if (v.pos <= 0) - return; - - for (var i = 1; i < NUMTOCENTRIES; ++i) { - var j = i / NUMTOCENTRIES, act, sum; - var indx = 0 | (Math.floor(j * v.pos)); - if (indx > v.pos - 1) - indx = v.pos - 1; - act = v.bag[indx]; - sum = v.sum; - var seek_point = 0 | (256. * act / sum); - if (seek_point > 255) - seek_point = 255; - t[i] = 0xff & seek_point; - } - } - - /** - * Add VBR entry, used to fill the VBR TOC entries. - * - * @param gfp - * global flags - */ - this.addVbrFrame = function (gfp) { - var gfc = gfp.internal_flags; - var kbps = Tables.bitrate_table[gfp.version][gfc.bitrate_index]; - addVbr(gfc.VBR_seek_table, kbps); - } - - /** - * Read big endian integer (4-bytes) from header. - * - * @param buf - * header containing the integer - * @param bufPos - * offset into the header - * @return extracted integer - */ - function extractInteger(buf, bufPos) { - var x = buf[bufPos + 0] & 0xff; - x <<= 8; - x |= buf[bufPos + 1] & 0xff; - x <<= 8; - x |= buf[bufPos + 2] & 0xff; - x <<= 8; - x |= buf[bufPos + 3] & 0xff; - return x; - } - - /** - * Write big endian integer (4-bytes) in the header. - * - * @param buf - * header to write the integer into - * @param bufPos - * offset into the header - * @param value - * integer value to write - */ - function createInteger(buf, bufPos, value) { - buf[bufPos + 0] = 0xff & ((value >> 24) & 0xff); - buf[bufPos + 1] = 0xff & ((value >> 16) & 0xff); - buf[bufPos + 2] = 0xff & ((value >> 8) & 0xff); - buf[bufPos + 3] = 0xff & (value & 0xff); - } - - /** - * Write big endian short (2-bytes) in the header. - * - * @param buf - * header to write the integer into - * @param bufPos - * offset into the header - * @param value - * integer value to write - */ - function createShort(buf, bufPos, value) { - buf[bufPos + 0] = 0xff & ((value >> 8) & 0xff); - buf[bufPos + 1] = 0xff & (value & 0xff); - } - - /** - * Check for magic strings (Xing/Info). - * - * @param buf - * header to check - * @param bufPos - * header offset to check - * @return magic string found - */ - function isVbrTag(buf, bufPos) { - return new String(buf, bufPos, VBRTag0.length(), ISO_8859_1) - .equals(VBRTag0) - || new String(buf, bufPos, VBRTag1.length(), ISO_8859_1) - .equals(VBRTag1); - } - - function shiftInBitsValue(x, n, v) { - return 0xff & ((x << n) | (v & ~(-1 << n))); - } - - /** - * Construct the MP3 header using the settings of the global flags. - * - * - * - * @param gfp - * global flags - * @param buffer - * header - */ - function setLameTagFrameHeader(gfp, buffer) { - var gfc = gfp.internal_flags; - - // MP3 Sync Word - buffer[0] = shiftInBitsValue(buffer[0], 8, 0xff); - - buffer[1] = shiftInBitsValue(buffer[1], 3, 7); - buffer[1] = shiftInBitsValue(buffer[1], 1, - (gfp.out_samplerate < 16000) ? 0 : 1); - // Version - buffer[1] = shiftInBitsValue(buffer[1], 1, gfp.version); - // 01 == Layer 3 - buffer[1] = shiftInBitsValue(buffer[1], 2, 4 - 3); - // Error protection - buffer[1] = shiftInBitsValue(buffer[1], 1, (!gfp.error_protection) ? 1 - : 0); - - // Bit rate - buffer[2] = shiftInBitsValue(buffer[2], 4, gfc.bitrate_index); - // Frequency - buffer[2] = shiftInBitsValue(buffer[2], 2, gfc.samplerate_index); - // Pad. Bit - buffer[2] = shiftInBitsValue(buffer[2], 1, 0); - // Priv. Bit - buffer[2] = shiftInBitsValue(buffer[2], 1, gfp.extension); - - // Mode - buffer[3] = shiftInBitsValue(buffer[3], 2, gfp.mode.ordinal()); - // Mode extension (Used with Joint Stereo) - buffer[3] = shiftInBitsValue(buffer[3], 2, gfc.mode_ext); - // Copy - buffer[3] = shiftInBitsValue(buffer[3], 1, gfp.copyright); - // Original - buffer[3] = shiftInBitsValue(buffer[3], 1, gfp.original); - // Emphasis - buffer[3] = shiftInBitsValue(buffer[3], 2, gfp.emphasis); - - /* the default VBR header. 48 kbps layer III, no padding, no crc */ - /* but sampling freq, mode and copyright/copy protection taken */ - /* from first valid frame */ - buffer[0] = 0xff; - var abyte = 0xff & (buffer[1] & 0xf1); - var bitrate; - if (1 == gfp.version) { - bitrate = XING_BITRATE1; - } else { - if (gfp.out_samplerate < 16000) - bitrate = XING_BITRATE25; - else - bitrate = XING_BITRATE2; - } - - if (gfp.VBR == VbrMode.vbr_off) - bitrate = gfp.brate; - - var bbyte; - if (gfp.free_format) - bbyte = 0x00; - else - bbyte = 0xff & (16 * lame.BitrateIndex(bitrate, gfp.version, - gfp.out_samplerate)); - - /* - * Use as much of the info from the real frames in the Xing header: - * samplerate, channels, crc, etc... - */ - if (gfp.version == 1) { - /* MPEG1 */ - buffer[1] = 0xff & (abyte | 0x0a); - /* was 0x0b; */ - abyte = 0xff & (buffer[2] & 0x0d); - /* AF keep also private bit */ - buffer[2] = 0xff & (bbyte | abyte); - /* 64kbs MPEG1 frame */ - } else { - /* MPEG2 */ - buffer[1] = 0xff & (abyte | 0x02); - /* was 0x03; */ - abyte = 0xff & (buffer[2] & 0x0d); - /* AF keep also private bit */ - buffer[2] = 0xff & (bbyte | abyte); - /* 64kbs MPEG2 frame */ - } - } - - /** - * Get VBR tag information - * - * @param buf - * header to analyze - * @param bufPos - * offset into the header - * @return VBR tag data - */ - this.getVbrTag = function (buf) { - var pTagData = new VBRTagData(); - var bufPos = 0; - - /* get Vbr header data */ - pTagData.flags = 0; - - /* get selected MPEG header data */ - var hId = (buf[bufPos + 1] >> 3) & 1; - var hSrIndex = (buf[bufPos + 2] >> 2) & 3; - var hMode = (buf[bufPos + 3] >> 6) & 3; - var hBitrate = ((buf[bufPos + 2] >> 4) & 0xf); - hBitrate = Tables.bitrate_table[hId][hBitrate]; - - /* check for FFE syncword */ - if ((buf[bufPos + 1] >> 4) == 0xE) - pTagData.samprate = Tables.samplerate_table[2][hSrIndex]; - else - pTagData.samprate = Tables.samplerate_table[hId][hSrIndex]; - - /* determine offset of header */ - if (hId != 0) { - /* mpeg1 */ - if (hMode != 3) - bufPos += (32 + 4); - else - bufPos += (17 + 4); - } else { - /* mpeg2 */ - if (hMode != 3) - bufPos += (17 + 4); - else - bufPos += (9 + 4); - } - - if (!isVbrTag(buf, bufPos)) - return null; - - bufPos += 4; - - pTagData.hId = hId; - - /* get flags */ - var head_flags = pTagData.flags = extractInteger(buf, bufPos); - bufPos += 4; - - if ((head_flags & FRAMES_FLAG) != 0) { - pTagData.frames = extractInteger(buf, bufPos); - bufPos += 4; - } - - if ((head_flags & BYTES_FLAG) != 0) { - pTagData.bytes = extractInteger(buf, bufPos); - bufPos += 4; - } - - if ((head_flags & TOC_FLAG) != 0) { - if (pTagData.toc != null) { - for (var i = 0; i < NUMTOCENTRIES; i++) - pTagData.toc[i] = buf[bufPos + i]; - } - bufPos += NUMTOCENTRIES; - } - - pTagData.vbrScale = -1; - - if ((head_flags & VBR_SCALE_FLAG) != 0) { - pTagData.vbrScale = extractInteger(buf, bufPos); - bufPos += 4; - } - - pTagData.headersize = ((hId + 1) * 72000 * hBitrate) - / pTagData.samprate; - - bufPos += 21; - var encDelay = buf[bufPos + 0] << 4; - encDelay += buf[bufPos + 1] >> 4; - var encPadding = (buf[bufPos + 1] & 0x0F) << 8; - encPadding += buf[bufPos + 2] & 0xff; - /* check for reasonable values (this may be an old Xing header, */ - /* not a INFO tag) */ - if (encDelay < 0 || encDelay > 3000) - encDelay = -1; - if (encPadding < 0 || encPadding > 3000) - encPadding = -1; - - pTagData.encDelay = encDelay; - pTagData.encPadding = encPadding; - - /* success */ - return pTagData; - } - - /** - * Initializes the header - * - * @param gfp - * global flags - */ - this.InitVbrTag = function (gfp) { - var gfc = gfp.internal_flags; - - /** - *
-         * Xing VBR pretends to be a 48kbs layer III frame.  (at 44.1kHz).
-         * (at 48kHz they use 56kbs since 48kbs frame not big enough for
-         * table of contents)
-         * let's always embed Xing header inside a 64kbs layer III frame.
-         * this gives us enough room for a LAME version string too.
-         * size determined by sampling frequency (MPEG1)
-         * 32kHz:    216 bytes@48kbs    288bytes@ 64kbs
-         * 44.1kHz:  156 bytes          208bytes@64kbs     (+1 if padding = 1)
-         * 48kHz:    144 bytes          192
-         *
-         * MPEG 2 values are the same since the framesize and samplerate
-         * are each reduced by a factor of 2.
-         * 
- */ - var kbps_header; - if (1 == gfp.version) { - kbps_header = XING_BITRATE1; - } else { - if (gfp.out_samplerate < 16000) - kbps_header = XING_BITRATE25; - else - kbps_header = XING_BITRATE2; - } - - if (gfp.VBR == VbrMode.vbr_off) - kbps_header = gfp.brate; - - // make sure LAME Header fits into Frame - var totalFrameSize = ((gfp.version + 1) * 72000 * kbps_header) - / gfp.out_samplerate; - var headerSize = (gfc.sideinfo_len + LAMEHEADERSIZE); - gfc.VBR_seek_table.TotalFrameSize = totalFrameSize; - if (totalFrameSize < headerSize || totalFrameSize > MAXFRAMESIZE) { - /* disable tag, it wont fit */ - gfp.bWriteVbrTag = false; - return; - } - - gfc.VBR_seek_table.nVbrNumFrames = 0; - gfc.VBR_seek_table.nBytesWritten = 0; - gfc.VBR_seek_table.sum = 0; - - gfc.VBR_seek_table.seen = 0; - gfc.VBR_seek_table.want = 1; - gfc.VBR_seek_table.pos = 0; - - if (gfc.VBR_seek_table.bag == null) { - gfc.VBR_seek_table.bag = new int[400]; - gfc.VBR_seek_table.size = 400; - } - - // write dummy VBR tag of all 0's into bitstream - var buffer = new_byte(MAXFRAMESIZE); - - setLameTagFrameHeader(gfp, buffer); - var n = gfc.VBR_seek_table.TotalFrameSize; - for (var i = 0; i < n; ++i) { - bs.add_dummy_byte(gfp, buffer[i] & 0xff, 1); - } - } - - /** - * Fast CRC-16 computation (uses table crc16Lookup). - * - * @param value - * @param crc - * @return - */ - function crcUpdateLookup(value, crc) { - var tmp = crc ^ value; - crc = (crc >> 8) ^ crc16Lookup[tmp & 0xff]; - return crc; - } - - this.updateMusicCRC = function (crc, buffer, bufferPos, size) { - for (var i = 0; i < size; ++i) - crc[0] = crcUpdateLookup(buffer[bufferPos + i], crc[0]); - } - - /** - * Write LAME info: mini version + info on various switches used (Jonathan - * Dee 2001/08/31). - * - * @param gfp - * global flags - * @param musicLength - * music length - * @param streamBuffer - * pointer to output buffer - * @param streamBufferPos - * offset into the output buffer - * @param crc - * computation of CRC-16 of Lame Tag so far (starting at frame - * sync) - * @return number of bytes written to the stream - */ - function putLameVBR(gfp, musicLength, streamBuffer, streamBufferPos, crc) { - var gfc = gfp.internal_flags; - var bytesWritten = 0; - - /* encoder delay */ - var encDelay = gfp.encoder_delay; - /* encoder padding */ - var encPadding = gfp.encoder_padding; - - /* recall: gfp.VBR_q is for example set by the switch -V */ - /* gfp.quality by -q, -h, -f, etc */ - var quality = (100 - 10 * gfp.VBR_q - gfp.quality); - - var version = v.getLameVeryShortVersion(); - var vbr; - var revision = 0x00; - var revMethod; - // numbering different in vbr_mode vs. Lame tag - var vbrTypeTranslator = [1, 5, 3, 2, 4, 0, 3]; - var lowpass = 0 | (((gfp.lowpassfreq / 100.0) + .5) > 255 ? 255 - : (gfp.lowpassfreq / 100.0) + .5); - var peakSignalAmplitude = 0; - var radioReplayGain = 0; - var audiophileReplayGain = 0; - var noiseShaping = gfp.internal_flags.noise_shaping; - var stereoMode = 0; - var nonOptimal = 0; - var sourceFreq = 0; - var misc = 0; - var musicCRC = 0; - - // psy model type: Gpsycho or NsPsytune - var expNPsyTune = (gfp.exp_nspsytune & 1) != 0; - var safeJoint = (gfp.exp_nspsytune & 2) != 0; - var noGapMore = false; - var noGapPrevious = false; - var noGapCount = gfp.internal_flags.nogap_total; - var noGapCurr = gfp.internal_flags.nogap_current; - - // 4 bits - var athType = gfp.ATHtype; - var flags = 0; - - // vbr modes - var abrBitrate; - switch (gfp.VBR) { - case vbr_abr: - abrBitrate = gfp.VBR_mean_bitrate_kbps; - break; - case vbr_off: - abrBitrate = gfp.brate; - break; - default: - abrBitrate = gfp.VBR_min_bitrate_kbps; - } - - // revision and vbr method - if (gfp.VBR.ordinal() < vbrTypeTranslator.length) - vbr = vbrTypeTranslator[gfp.VBR.ordinal()]; - else - vbr = 0x00; // unknown - - revMethod = 0x10 * revision + vbr; - - // ReplayGain - if (gfc.findReplayGain) { - if (gfc.RadioGain > 0x1FE) - gfc.RadioGain = 0x1FE; - if (gfc.RadioGain < -0x1FE) - gfc.RadioGain = -0x1FE; - - // set name code - radioReplayGain = 0x2000; - // set originator code to `determined automatically' - radioReplayGain |= 0xC00; - - if (gfc.RadioGain >= 0) { - // set gain adjustment - radioReplayGain |= gfc.RadioGain; - } else { - // set the sign bit - radioReplayGain |= 0x200; - // set gain adjustment - radioReplayGain |= -gfc.RadioGain; - } - } - - // peak sample - if (gfc.findPeakSample) - peakSignalAmplitude = Math - .abs(0 | ((( gfc.PeakSample) / 32767.0) * Math.pow(2, 23) + .5)); - - // nogap - if (noGapCount != -1) { - if (noGapCurr > 0) - noGapPrevious = true; - - if (noGapCurr < noGapCount - 1) - noGapMore = true; - } - - // flags - flags = athType + ((expNPsyTune ? 1 : 0) << 4) - + ((safeJoint ? 1 : 0) << 5) + ((noGapMore ? 1 : 0) << 6) - + ((noGapPrevious ? 1 : 0) << 7); - - if (quality < 0) - quality = 0; - - // stereo mode field (Intensity stereo is not implemented) - switch (gfp.mode) { - case MONO: - stereoMode = 0; - break; - case STEREO: - stereoMode = 1; - break; - case DUAL_CHANNEL: - stereoMode = 2; - break; - case JOINT_STEREO: - if (gfp.force_ms) - stereoMode = 4; - else - stereoMode = 3; - break; - case NOT_SET: - //$FALL-THROUGH$ - default: - stereoMode = 7; - break; - } - - if (gfp.in_samplerate <= 32000) - sourceFreq = 0x00; - else if (gfp.in_samplerate == 48000) - sourceFreq = 0x02; - else if (gfp.in_samplerate > 48000) - sourceFreq = 0x03; - else { - // default is 44100Hz - sourceFreq = 0x01; - } - - // Check if the user overrided the default LAME behavior with some - // nasty options - if (gfp.short_blocks == ShortBlock.short_block_forced - || gfp.short_blocks == ShortBlock.short_block_dispensed - || ((gfp.lowpassfreq == -1) && (gfp.highpassfreq == -1)) || /* "-k" */ - (gfp.scale_left < gfp.scale_right) - || (gfp.scale_left > gfp.scale_right) - || (gfp.disable_reservoir && gfp.brate < 320) || gfp.noATH - || gfp.ATHonly || (athType == 0) || gfp.in_samplerate <= 32000) - nonOptimal = 1; - - misc = noiseShaping + (stereoMode << 2) + (nonOptimal << 5) - + (sourceFreq << 6); - - musicCRC = gfc.nMusicCRC; - - // Write all this information into the stream - - createInteger(streamBuffer, streamBufferPos + bytesWritten, quality); - bytesWritten += 4; - - for (var j = 0; j < 9; j++) { - streamBuffer[streamBufferPos + bytesWritten + j] = 0xff & version .charAt(j); - } - bytesWritten += 9; - - streamBuffer[streamBufferPos + bytesWritten] = 0xff & revMethod; - bytesWritten++; - - streamBuffer[streamBufferPos + bytesWritten] = 0xff & lowpass; - bytesWritten++; - - createInteger(streamBuffer, streamBufferPos + bytesWritten, - peakSignalAmplitude); - bytesWritten += 4; - - createShort(streamBuffer, streamBufferPos + bytesWritten, - radioReplayGain); - bytesWritten += 2; - - createShort(streamBuffer, streamBufferPos + bytesWritten, - audiophileReplayGain); - bytesWritten += 2; - - streamBuffer[streamBufferPos + bytesWritten] = 0xff & flags; - bytesWritten++; - - if (abrBitrate >= 255) - streamBuffer[streamBufferPos + bytesWritten] = 0xFF; - else - streamBuffer[streamBufferPos + bytesWritten] = 0xff & abrBitrate; - bytesWritten++; - - streamBuffer[streamBufferPos + bytesWritten] = 0xff & (encDelay >> 4); - streamBuffer[streamBufferPos + bytesWritten + 1] = 0xff & ((encDelay << 4) + (encPadding >> 8)); - streamBuffer[streamBufferPos + bytesWritten + 2] = 0xff & encPadding; - - bytesWritten += 3; - - streamBuffer[streamBufferPos + bytesWritten] = 0xff & misc; - bytesWritten++; - - // unused in rev0 - streamBuffer[streamBufferPos + bytesWritten++] = 0; - - createShort(streamBuffer, streamBufferPos + bytesWritten, gfp.preset); - bytesWritten += 2; - - createInteger(streamBuffer, streamBufferPos + bytesWritten, musicLength); - bytesWritten += 4; - - createShort(streamBuffer, streamBufferPos + bytesWritten, musicCRC); - bytesWritten += 2; - - // Calculate tag CRC.... must be done here, since it includes previous - // information - - for (var i = 0; i < bytesWritten; i++) - crc = crcUpdateLookup(streamBuffer[streamBufferPos + i], crc); - - createShort(streamBuffer, streamBufferPos + bytesWritten, crc); - bytesWritten += 2; - - return bytesWritten; - } - - function skipId3v2(fpStream) { - // seek to the beginning of the stream - fpStream.seek(0); - // read 10 bytes in case there's an ID3 version 2 header here - var id3v2Header = new_byte(10); - fpStream.readFully(id3v2Header); - /* does the stream begin with the ID3 version 2 file identifier? */ - var id3v2TagSize; - if (!new String(id3v2Header, "ISO-8859-1").startsWith("ID3")) { - /* - * the tag size (minus the 10-byte header) is encoded into four - * bytes where the most significant bit is clear in each byte - */ - id3v2TagSize = (((id3v2Header[6] & 0x7f) << 21) - | ((id3v2Header[7] & 0x7f) << 14) - | ((id3v2Header[8] & 0x7f) << 7) | (id3v2Header[9] & 0x7f)) - + id3v2Header.length; - } else { - /* no ID3 version 2 tag in this stream */ - id3v2TagSize = 0; - } - return id3v2TagSize; - } - - this.getLameTagFrame = function (gfp, buffer) { - var gfc = gfp.internal_flags; - - if (!gfp.bWriteVbrTag) { - return 0; - } - if (gfc.Class_ID != Lame.LAME_ID) { - return 0; - } - if (gfc.VBR_seek_table.pos <= 0) { - return 0; - } - if (buffer.length < gfc.VBR_seek_table.TotalFrameSize) { - return gfc.VBR_seek_table.TotalFrameSize; - } - - Arrays.fill(buffer, 0, gfc.VBR_seek_table.TotalFrameSize, 0); - - // 4 bytes frame header - setLameTagFrameHeader(gfp, buffer); - - // Create TOC entries - var toc = new_byte(NUMTOCENTRIES); - - if (gfp.free_format) { - for (var i = 1; i < NUMTOCENTRIES; ++i) - toc[i] = 0xff & (255 * i / 100); - } else { - xingSeekTable(gfc.VBR_seek_table, toc); - } - - // Start writing the tag after the zero frame - var streamIndex = gfc.sideinfo_len; - /** - * Note: Xing header specifies that Xing data goes in the ancillary data - * with NO ERROR PROTECTION. If error protecton in enabled, the Xing - * data still starts at the same offset, and now it is in sideinfo data - * block, and thus will not decode correctly by non-Xing tag aware - * players - */ - if (gfp.error_protection) - streamIndex -= 2; - - // Put Vbr tag - if (gfp.VBR == VbrMode.vbr_off) { - buffer[streamIndex++] = 0xff & VBRTag1.charAt(0); - buffer[streamIndex++] = 0xff & VBRTag1.charAt(1); - buffer[streamIndex++] = 0xff & VBRTag1.charAt(2); - buffer[streamIndex++] = 0xff & VBRTag1.charAt(3); - - } else { - buffer[streamIndex++] = 0xff & VBRTag0.charAt(0); - buffer[streamIndex++] = 0xff & VBRTag0.charAt(1); - buffer[streamIndex++] = 0xff & VBRTag0.charAt(2); - buffer[streamIndex++] = 0xff & VBRTag0.charAt(3); - } - - // Put header flags - createInteger(buffer, streamIndex, FRAMES_FLAG + BYTES_FLAG + TOC_FLAG - + VBR_SCALE_FLAG); - streamIndex += 4; - - // Put Total Number of frames - createInteger(buffer, streamIndex, gfc.VBR_seek_table.nVbrNumFrames); - streamIndex += 4; - - // Put total audio stream size, including Xing/LAME Header - var streamSize = (gfc.VBR_seek_table.nBytesWritten + gfc.VBR_seek_table.TotalFrameSize); - createInteger(buffer, streamIndex, 0 | streamSize); - streamIndex += 4; - - /* Put TOC */ - System.arraycopy(toc, 0, buffer, streamIndex, toc.length); - streamIndex += toc.length; - - if (gfp.error_protection) { - // (jo) error_protection: add crc16 information to header - bs.CRC_writeheader(gfc, buffer); - } - - // work out CRC so far: initially crc = 0 - var crc = 0x00; - for (var i = 0; i < streamIndex; i++) - crc = crcUpdateLookup(buffer[i], crc); - // Put LAME VBR info - streamIndex += putLameVBR(gfp, streamSize, buffer, streamIndex, crc); - - return gfc.VBR_seek_table.TotalFrameSize; - } - - /** - * Write final VBR tag to the file. - * - * @param gfp - * global flags - * @param stream - * stream to add the VBR tag to - * @return 0 (OK), -1 else - * @throws IOException - * I/O error - */ - this.putVbrTag = function (gfp, stream) { - var gfc = gfp.internal_flags; - - if (gfc.VBR_seek_table.pos <= 0) - return -1; - - // Seek to end of file - stream.seek(stream.length()); - - // Get file size, abort if file has zero length. - if (stream.length() == 0) - return -1; - - // The VBR tag may NOT be located at the beginning of the stream. If an - // ID3 version 2 tag was added, then it must be skipped to write the VBR - // tag data. - var id3v2TagSize = skipId3v2(stream); - - // Seek to the beginning of the stream - stream.seek(id3v2TagSize); - - var buffer = new_byte(MAXFRAMESIZE); - var bytes = getLameTagFrame(gfp, buffer); - if (bytes > buffer.length) { - return -1; - } - - if (bytes < 1) { - return 0; - } - - // Put it all to disk again - stream.write(buffer, 0, bytes); - // success - return 0; - } - -} - -function HuffCodeTab(len, max, tab, hl) { - this.xlen = len; - this.linmax = max; - this.table = tab; - this.hlen = hl; -} - -var Tables = {}; - - -Tables.t1HB = [ - 1, 1, - 1, 0 -]; - -Tables.t2HB = [ - 1, 2, 1, - 3, 1, 1, - 3, 2, 0 -]; - -Tables.t3HB = [ - 3, 2, 1, - 1, 1, 1, - 3, 2, 0 -]; - -Tables.t5HB = [ - 1, 2, 6, 5, - 3, 1, 4, 4, - 7, 5, 7, 1, - 6, 1, 1, 0 -]; - -Tables.t6HB = [ - 7, 3, 5, 1, - 6, 2, 3, 2, - 5, 4, 4, 1, - 3, 3, 2, 0 -]; - -Tables.t7HB = [ - 1, 2, 10, 19, 16, 10, - 3, 3, 7, 10, 5, 3, - 11, 4, 13, 17, 8, 4, - 12, 11, 18, 15, 11, 2, - 7, 6, 9, 14, 3, 1, - 6, 4, 5, 3, 2, 0 -]; - -Tables.t8HB = [ - 3, 4, 6, 18, 12, 5, - 5, 1, 2, 16, 9, 3, - 7, 3, 5, 14, 7, 3, - 19, 17, 15, 13, 10, 4, - 13, 5, 8, 11, 5, 1, - 12, 4, 4, 1, 1, 0 -]; - -Tables.t9HB = [ - 7, 5, 9, 14, 15, 7, - 6, 4, 5, 5, 6, 7, - 7, 6, 8, 8, 8, 5, - 15, 6, 9, 10, 5, 1, - 11, 7, 9, 6, 4, 1, - 14, 4, 6, 2, 6, 0 -]; - -Tables.t10HB = [ - 1, 2, 10, 23, 35, 30, 12, 17, - 3, 3, 8, 12, 18, 21, 12, 7, - 11, 9, 15, 21, 32, 40, 19, 6, - 14, 13, 22, 34, 46, 23, 18, 7, - 20, 19, 33, 47, 27, 22, 9, 3, - 31, 22, 41, 26, 21, 20, 5, 3, - 14, 13, 10, 11, 16, 6, 5, 1, - 9, 8, 7, 8, 4, 4, 2, 0 -]; - -Tables.t11HB = [ - 3, 4, 10, 24, 34, 33, 21, 15, - 5, 3, 4, 10, 32, 17, 11, 10, - 11, 7, 13, 18, 30, 31, 20, 5, - 25, 11, 19, 59, 27, 18, 12, 5, - 35, 33, 31, 58, 30, 16, 7, 5, - 28, 26, 32, 19, 17, 15, 8, 14, - 14, 12, 9, 13, 14, 9, 4, 1, - 11, 4, 6, 6, 6, 3, 2, 0 -]; - -Tables.t12HB = [ - 9, 6, 16, 33, 41, 39, 38, 26, - 7, 5, 6, 9, 23, 16, 26, 11, - 17, 7, 11, 14, 21, 30, 10, 7, - 17, 10, 15, 12, 18, 28, 14, 5, - 32, 13, 22, 19, 18, 16, 9, 5, - 40, 17, 31, 29, 17, 13, 4, 2, - 27, 12, 11, 15, 10, 7, 4, 1, - 27, 12, 8, 12, 6, 3, 1, 0 -]; - -Tables.t13HB = [ - 1, 5, 14, 21, 34, 51, 46, 71, 42, 52, 68, 52, 67, 44, 43, 19, - 3, 4, 12, 19, 31, 26, 44, 33, 31, 24, 32, 24, 31, 35, 22, 14, - 15, 13, 23, 36, 59, 49, 77, 65, 29, 40, 30, 40, 27, 33, 42, 16, - 22, 20, 37, 61, 56, 79, 73, 64, 43, 76, 56, 37, 26, 31, 25, 14, - 35, 16, 60, 57, 97, 75, 114, 91, 54, 73, 55, 41, 48, 53, 23, 24, - 58, 27, 50, 96, 76, 70, 93, 84, 77, 58, 79, 29, 74, 49, 41, 17, - 47, 45, 78, 74, 115, 94, 90, 79, 69, 83, 71, 50, 59, 38, 36, 15, - 72, 34, 56, 95, 92, 85, 91, 90, 86, 73, 77, 65, 51, 44, 43, 42, - 43, 20, 30, 44, 55, 78, 72, 87, 78, 61, 46, 54, 37, 30, 20, 16, - 53, 25, 41, 37, 44, 59, 54, 81, 66, 76, 57, 54, 37, 18, 39, 11, - 35, 33, 31, 57, 42, 82, 72, 80, 47, 58, 55, 21, 22, 26, 38, 22, - 53, 25, 23, 38, 70, 60, 51, 36, 55, 26, 34, 23, 27, 14, 9, 7, - 34, 32, 28, 39, 49, 75, 30, 52, 48, 40, 52, 28, 18, 17, 9, 5, - 45, 21, 34, 64, 56, 50, 49, 45, 31, 19, 12, 15, 10, 7, 6, 3, - 48, 23, 20, 39, 36, 35, 53, 21, 16, 23, 13, 10, 6, 1, 4, 2, - 16, 15, 17, 27, 25, 20, 29, 11, 17, 12, 16, 8, 1, 1, 0, 1 -]; - -Tables.t15HB = [ - 7, 12, 18, 53, 47, 76, 124, 108, 89, 123, 108, 119, 107, 81, 122, 63, - 13, 5, 16, 27, 46, 36, 61, 51, 42, 70, 52, 83, 65, 41, 59, 36, - 19, 17, 15, 24, 41, 34, 59, 48, 40, 64, 50, 78, 62, 80, 56, 33, - 29, 28, 25, 43, 39, 63, 55, 93, 76, 59, 93, 72, 54, 75, 50, 29, - 52, 22, 42, 40, 67, 57, 95, 79, 72, 57, 89, 69, 49, 66, 46, 27, - 77, 37, 35, 66, 58, 52, 91, 74, 62, 48, 79, 63, 90, 62, 40, 38, - 125, 32, 60, 56, 50, 92, 78, 65, 55, 87, 71, 51, 73, 51, 70, 30, - 109, 53, 49, 94, 88, 75, 66, 122, 91, 73, 56, 42, 64, 44, 21, 25, - 90, 43, 41, 77, 73, 63, 56, 92, 77, 66, 47, 67, 48, 53, 36, 20, - 71, 34, 67, 60, 58, 49, 88, 76, 67, 106, 71, 54, 38, 39, 23, 15, - 109, 53, 51, 47, 90, 82, 58, 57, 48, 72, 57, 41, 23, 27, 62, 9, - 86, 42, 40, 37, 70, 64, 52, 43, 70, 55, 42, 25, 29, 18, 11, 11, - 118, 68, 30, 55, 50, 46, 74, 65, 49, 39, 24, 16, 22, 13, 14, 7, - 91, 44, 39, 38, 34, 63, 52, 45, 31, 52, 28, 19, 14, 8, 9, 3, - 123, 60, 58, 53, 47, 43, 32, 22, 37, 24, 17, 12, 15, 10, 2, 1, - 71, 37, 34, 30, 28, 20, 17, 26, 21, 16, 10, 6, 8, 6, 2, 0 -]; - -Tables.t16HB = [ - 1, 5, 14, 44, 74, 63, 110, 93, 172, 149, 138, 242, 225, 195, 376, 17, - 3, 4, 12, 20, 35, 62, 53, 47, 83, 75, 68, 119, 201, 107, 207, 9, - 15, 13, 23, 38, 67, 58, 103, 90, 161, 72, 127, 117, 110, 209, 206, 16, - 45, 21, 39, 69, 64, 114, 99, 87, 158, 140, 252, 212, 199, 387, 365, 26, - 75, 36, 68, 65, 115, 101, 179, 164, 155, 264, 246, 226, 395, 382, 362, 9, - 66, 30, 59, 56, 102, 185, 173, 265, 142, 253, 232, 400, 388, 378, 445, 16, - 111, 54, 52, 100, 184, 178, 160, 133, 257, 244, 228, 217, 385, 366, 715, 10, - 98, 48, 91, 88, 165, 157, 148, 261, 248, 407, 397, 372, 380, 889, 884, 8, - 85, 84, 81, 159, 156, 143, 260, 249, 427, 401, 392, 383, 727, 713, 708, 7, - 154, 76, 73, 141, 131, 256, 245, 426, 406, 394, 384, 735, 359, 710, 352, 11, - 139, 129, 67, 125, 247, 233, 229, 219, 393, 743, 737, 720, 885, 882, 439, 4, - 243, 120, 118, 115, 227, 223, 396, 746, 742, 736, 721, 712, 706, 223, 436, 6, - 202, 224, 222, 218, 216, 389, 386, 381, 364, 888, 443, 707, 440, 437, 1728, 4, - 747, 211, 210, 208, 370, 379, 734, 723, 714, 1735, 883, 877, 876, 3459, 865, 2, - 377, 369, 102, 187, 726, 722, 358, 711, 709, 866, 1734, 871, 3458, 870, 434, 0, - 12, 10, 7, 11, 10, 17, 11, 9, 13, 12, 10, 7, 5, 3, 1, 3 -]; - -Tables.t24HB = [ - 15, 13, 46, 80, 146, 262, 248, 434, 426, 669, 653, 649, 621, 517, 1032, 88, - 14, 12, 21, 38, 71, 130, 122, 216, 209, 198, 327, 345, 319, 297, 279, 42, - 47, 22, 41, 74, 68, 128, 120, 221, 207, 194, 182, 340, 315, 295, 541, 18, - 81, 39, 75, 70, 134, 125, 116, 220, 204, 190, 178, 325, 311, 293, 271, 16, - 147, 72, 69, 135, 127, 118, 112, 210, 200, 188, 352, 323, 306, 285, 540, 14, - 263, 66, 129, 126, 119, 114, 214, 202, 192, 180, 341, 317, 301, 281, 262, 12, - 249, 123, 121, 117, 113, 215, 206, 195, 185, 347, 330, 308, 291, 272, 520, 10, - 435, 115, 111, 109, 211, 203, 196, 187, 353, 332, 313, 298, 283, 531, 381, 17, - 427, 212, 208, 205, 201, 193, 186, 177, 169, 320, 303, 286, 268, 514, 377, 16, - 335, 199, 197, 191, 189, 181, 174, 333, 321, 305, 289, 275, 521, 379, 371, 11, - 668, 184, 183, 179, 175, 344, 331, 314, 304, 290, 277, 530, 383, 373, 366, 10, - 652, 346, 171, 168, 164, 318, 309, 299, 287, 276, 263, 513, 375, 368, 362, 6, - 648, 322, 316, 312, 307, 302, 292, 284, 269, 261, 512, 376, 370, 364, 359, 4, - 620, 300, 296, 294, 288, 282, 273, 266, 515, 380, 374, 369, 365, 361, 357, 2, - 1033, 280, 278, 274, 267, 264, 259, 382, 378, 372, 367, 363, 360, 358, 356, 0, - 43, 20, 19, 17, 15, 13, 11, 9, 7, 6, 4, 7, 5, 3, 1, 3 -]; - -Tables.t32HB = [ - 1 << 0, 5 << 1, 4 << 1, 5 << 2, 6 << 1, 5 << 2, 4 << 2, 4 << 3, - 7 << 1, 3 << 2, 6 << 2, 0 << 3, 7 << 2, 2 << 3, 3 << 3, 1 << 4 -]; - -Tables.t33HB = [ - 15 << 0, 14 << 1, 13 << 1, 12 << 2, 11 << 1, 10 << 2, 9 << 2, 8 << 3, - 7 << 1, 6 << 2, 5 << 2, 4 << 3, 3 << 2, 2 << 3, 1 << 3, 0 << 4 -]; - -Tables.t1l = [ - 1, 4, - 3, 5 -]; - -Tables.t2l = [ - 1, 4, 7, - 4, 5, 7, - 6, 7, 8 -]; - -Tables.t3l = [ - 2, 3, 7, - 4, 4, 7, - 6, 7, 8 -]; - -Tables.t5l = [ - 1, 4, 7, 8, - 4, 5, 8, 9, - 7, 8, 9, 10, - 8, 8, 9, 10 -]; - -Tables.t6l = [ - 3, 4, 6, 8, - 4, 4, 6, 7, - 5, 6, 7, 8, - 7, 7, 8, 9 -]; - -Tables.t7l = [ - 1, 4, 7, 9, 9, 10, - 4, 6, 8, 9, 9, 10, - 7, 7, 9, 10, 10, 11, - 8, 9, 10, 11, 11, 11, - 8, 9, 10, 11, 11, 12, - 9, 10, 11, 12, 12, 12 -]; - -Tables.t8l = [ - 2, 4, 7, 9, 9, 10, - 4, 4, 6, 10, 10, 10, - 7, 6, 8, 10, 10, 11, - 9, 10, 10, 11, 11, 12, - 9, 9, 10, 11, 12, 12, - 10, 10, 11, 11, 13, 13 -]; - -Tables.t9l = [ - 3, 4, 6, 7, 9, 10, - 4, 5, 6, 7, 8, 10, - 5, 6, 7, 8, 9, 10, - 7, 7, 8, 9, 9, 10, - 8, 8, 9, 9, 10, 11, - 9, 9, 10, 10, 11, 11 -]; - -Tables.t10l = [ - 1, 4, 7, 9, 10, 10, 10, 11, - 4, 6, 8, 9, 10, 11, 10, 10, - 7, 8, 9, 10, 11, 12, 11, 11, - 8, 9, 10, 11, 12, 12, 11, 12, - 9, 10, 11, 12, 12, 12, 12, 12, - 10, 11, 12, 12, 13, 13, 12, 13, - 9, 10, 11, 12, 12, 12, 13, 13, - 10, 10, 11, 12, 12, 13, 13, 13 -]; - -Tables.t11l = [ - 2, 4, 6, 8, 9, 10, 9, 10, - 4, 5, 6, 8, 10, 10, 9, 10, - 6, 7, 8, 9, 10, 11, 10, 10, - 8, 8, 9, 11, 10, 12, 10, 11, - 9, 10, 10, 11, 11, 12, 11, 12, - 9, 10, 11, 12, 12, 13, 12, 13, - 9, 9, 9, 10, 11, 12, 12, 12, - 9, 9, 10, 11, 12, 12, 12, 12 -]; - -Tables.t12l = [ - 4, 4, 6, 8, 9, 10, 10, 10, - 4, 5, 6, 7, 9, 9, 10, 10, - 6, 6, 7, 8, 9, 10, 9, 10, - 7, 7, 8, 8, 9, 10, 10, 10, - 8, 8, 9, 9, 10, 10, 10, 11, - 9, 9, 10, 10, 10, 11, 10, 11, - 9, 9, 9, 10, 10, 11, 11, 12, - 10, 10, 10, 11, 11, 11, 11, 12 -]; - -Tables.t13l = [ - 1, 5, 7, 8, 9, 10, 10, 11, 10, 11, 12, 12, 13, 13, 14, 14, - 4, 6, 8, 9, 10, 10, 11, 11, 11, 11, 12, 12, 13, 14, 14, 14, - 7, 8, 9, 10, 11, 11, 12, 12, 11, 12, 12, 13, 13, 14, 15, 15, - 8, 9, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 15, 15, - 9, 9, 11, 11, 12, 12, 13, 13, 12, 13, 13, 14, 14, 15, 15, 16, - 10, 10, 11, 12, 12, 12, 13, 13, 13, 13, 14, 13, 15, 15, 16, 16, - 10, 11, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, - 11, 11, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 16, 18, 18, - 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 15, 15, 16, 17, 17, - 11, 11, 12, 12, 13, 13, 13, 15, 14, 15, 15, 16, 16, 16, 18, 17, - 11, 12, 12, 13, 13, 14, 14, 15, 14, 15, 16, 15, 16, 17, 18, 19, - 12, 12, 12, 13, 14, 14, 14, 14, 15, 15, 15, 16, 17, 17, 17, 18, - 12, 13, 13, 14, 14, 15, 14, 15, 16, 16, 17, 17, 17, 18, 18, 18, - 13, 13, 14, 15, 15, 15, 16, 16, 16, 16, 16, 17, 18, 17, 18, 18, - 14, 14, 14, 15, 15, 15, 17, 16, 16, 19, 17, 17, 17, 19, 18, 18, - 13, 14, 15, 16, 16, 16, 17, 16, 17, 17, 18, 18, 21, 20, 21, 18 -]; - -Tables.t15l = [ - 3, 5, 6, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 14, - 5, 5, 7, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, - 6, 7, 7, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 13, - 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, - 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, - 9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 13, 13, 13, 14, - 10, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14, - 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 14, - 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 14, 14, - 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, - 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 15, 14, - 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, - 12, 12, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 14, 14, 15, 15, - 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, - 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 14, 15, - 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15 -]; - -Tables.t16_5l = [ - 1, 5, 7, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 11, - 4, 6, 8, 9, 10, 11, 11, 11, 12, 12, 12, 13, 14, 13, 14, 11, - 7, 8, 9, 10, 11, 11, 12, 12, 13, 12, 13, 13, 13, 14, 14, 12, - 9, 9, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 13, - 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 12, - 10, 10, 11, 11, 12, 13, 13, 14, 13, 14, 14, 15, 15, 15, 16, 13, - 11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 13, - 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 17, 17, 13, - 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 13, - 12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 16, 15, 14, - 12, 13, 12, 13, 14, 14, 14, 14, 15, 16, 16, 16, 17, 17, 16, 13, - 13, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 14, - 13, 14, 14, 14, 14, 15, 15, 15, 15, 17, 16, 16, 16, 16, 18, 14, - 15, 14, 14, 14, 15, 15, 16, 16, 16, 18, 17, 17, 17, 19, 17, 14, - 14, 15, 13, 14, 16, 16, 15, 16, 16, 17, 18, 17, 19, 17, 16, 14, - 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 12 -]; - -Tables.t16l = [ - 1, 5, 7, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 10, - 4, 6, 8, 9, 10, 11, 11, 11, 12, 12, 12, 13, 14, 13, 14, 10, - 7, 8, 9, 10, 11, 11, 12, 12, 13, 12, 13, 13, 13, 14, 14, 11, - 9, 9, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 12, - 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 11, - 10, 10, 11, 11, 12, 13, 13, 14, 13, 14, 14, 15, 15, 15, 16, 12, - 11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 12, - 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 17, 17, 12, - 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 12, - 12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 16, 15, 13, - 12, 13, 12, 13, 14, 14, 14, 14, 15, 16, 16, 16, 17, 17, 16, 12, - 13, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 13, - 13, 14, 14, 14, 14, 15, 15, 15, 15, 17, 16, 16, 16, 16, 18, 13, - 15, 14, 14, 14, 15, 15, 16, 16, 16, 18, 17, 17, 17, 19, 17, 13, - 14, 15, 13, 14, 16, 16, 15, 16, 16, 17, 18, 17, 19, 17, 16, 13, - 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 10 -]; - -Tables.t24l = [ - 4, 5, 7, 8, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 13, 10, - 5, 6, 7, 8, 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 10, - 7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 9, - 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 9, - 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, 9, - 10, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 9, - 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 9, - 11, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 10, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 10, - 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 10, - 12, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 10, - 12, 12, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 10, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 10, - 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 10, - 13, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 10, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 6 -]; - -Tables.t32l = [ - 1 + 0, 4 + 1, 4 + 1, 5 + 2, 4 + 1, 6 + 2, 5 + 2, 6 + 3, - 4 + 1, 5 + 2, 5 + 2, 6 + 3, 5 + 2, 6 + 3, 6 + 3, 6 + 4 -]; - -Tables.t33l = [ - 4 + 0, 4 + 1, 4 + 1, 4 + 2, 4 + 1, 4 + 2, 4 + 2, 4 + 3, - 4 + 1, 4 + 2, 4 + 2, 4 + 3, 4 + 2, 4 + 3, 4 + 3, 4 + 4 -]; - -Tables.ht = [ - /* xlen, linmax, table, hlen */ - new HuffCodeTab(0, 0, null, null), - new HuffCodeTab(2, 0, Tables.t1HB, Tables.t1l), - new HuffCodeTab(3, 0, Tables.t2HB, Tables.t2l), - new HuffCodeTab(3, 0, Tables.t3HB, Tables.t3l), - new HuffCodeTab(0, 0, null, null), /* Apparently not used */ - new HuffCodeTab(4, 0, Tables.t5HB, Tables.t5l), - new HuffCodeTab(4, 0, Tables.t6HB, Tables.t6l), - new HuffCodeTab(6, 0, Tables.t7HB, Tables.t7l), - new HuffCodeTab(6, 0, Tables.t8HB, Tables.t8l), - new HuffCodeTab(6, 0, Tables.t9HB, Tables.t9l), - new HuffCodeTab(8, 0, Tables.t10HB, Tables.t10l), - new HuffCodeTab(8, 0, Tables.t11HB, Tables.t11l), - new HuffCodeTab(8, 0, Tables.t12HB, Tables.t12l), - new HuffCodeTab(16, 0, Tables.t13HB, Tables.t13l), - new HuffCodeTab(0, 0, null, Tables.t16_5l), /* Apparently not used */ - new HuffCodeTab(16, 0, Tables.t15HB, Tables.t15l), - - new HuffCodeTab(1, 1, Tables.t16HB, Tables.t16l), - new HuffCodeTab(2, 3, Tables.t16HB, Tables.t16l), - new HuffCodeTab(3, 7, Tables.t16HB, Tables.t16l), - new HuffCodeTab(4, 15, Tables.t16HB, Tables.t16l), - new HuffCodeTab(6, 63, Tables.t16HB, Tables.t16l), - new HuffCodeTab(8, 255, Tables.t16HB, Tables.t16l), - new HuffCodeTab(10, 1023, Tables.t16HB, Tables.t16l), - new HuffCodeTab(13, 8191, Tables.t16HB, Tables.t16l), - - new HuffCodeTab(4, 15, Tables.t24HB, Tables.t24l), - new HuffCodeTab(5, 31, Tables.t24HB, Tables.t24l), - new HuffCodeTab(6, 63, Tables.t24HB, Tables.t24l), - new HuffCodeTab(7, 127, Tables.t24HB, Tables.t24l), - new HuffCodeTab(8, 255, Tables.t24HB, Tables.t24l), - new HuffCodeTab(9, 511, Tables.t24HB, Tables.t24l), - new HuffCodeTab(11, 2047, Tables.t24HB, Tables.t24l), - new HuffCodeTab(13, 8191, Tables.t24HB, Tables.t24l), - - new HuffCodeTab(0, 0, Tables.t32HB, Tables.t32l), - new HuffCodeTab(0, 0, Tables.t33HB, Tables.t33l), -]; - -/** - * - * for (i = 0; i < 16*16; i++) [ - * largetbl[i] = ((ht[16].hlen[i]) << 16) + ht[24].hlen[i]; - * ] - * - * - */ -Tables.largetbl = [ - 0x010004, 0x050005, 0x070007, 0x090008, 0x0a0009, 0x0a000a, 0x0b000a, 0x0b000b, - 0x0c000b, 0x0c000c, 0x0c000c, 0x0d000c, 0x0d000c, 0x0d000c, 0x0e000d, 0x0a000a, - 0x040005, 0x060006, 0x080007, 0x090008, 0x0a0009, 0x0b000a, 0x0b000a, 0x0b000b, - 0x0c000b, 0x0c000b, 0x0c000c, 0x0d000c, 0x0e000c, 0x0d000c, 0x0e000c, 0x0a000a, - 0x070007, 0x080007, 0x090008, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000b, - 0x0d000b, 0x0c000b, 0x0d000b, 0x0d000c, 0x0d000c, 0x0e000c, 0x0e000d, 0x0b0009, - 0x090008, 0x090008, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000a, 0x0c000b, - 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0c0009, - 0x0a0009, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000a, 0x0d000a, 0x0d000b, - 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000d, 0x0b0009, - 0x0a000a, 0x0a0009, 0x0b000a, 0x0b000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0e000b, - 0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x0c0009, - 0x0b000a, 0x0b000a, 0x0b000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0d000b, 0x0d000b, - 0x0e000b, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x10000d, 0x0c0009, - 0x0b000b, 0x0b000a, 0x0c000a, 0x0c000a, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b, - 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x11000d, 0x11000d, 0x0c000a, - 0x0b000b, 0x0c000b, 0x0c000b, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000b, - 0x0f000b, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x10000d, 0x10000d, 0x0c000a, - 0x0c000b, 0x0c000b, 0x0c000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000b, 0x0f000c, - 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x0f000d, 0x10000d, 0x0f000d, 0x0d000a, - 0x0c000c, 0x0d000b, 0x0c000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0e000c, - 0x0f000c, 0x10000c, 0x10000c, 0x10000d, 0x11000d, 0x11000d, 0x10000d, 0x0c000a, - 0x0d000c, 0x0d000c, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x10000c, - 0x10000c, 0x10000c, 0x10000c, 0x10000d, 0x10000d, 0x0f000d, 0x10000d, 0x0d000a, - 0x0d000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, - 0x0f000c, 0x11000c, 0x10000d, 0x10000d, 0x10000d, 0x10000d, 0x12000d, 0x0d000a, - 0x0f000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x10000c, 0x10000c, - 0x10000d, 0x12000d, 0x11000d, 0x11000d, 0x11000d, 0x13000d, 0x11000d, 0x0d000a, - 0x0e000d, 0x0f000c, 0x0d000c, 0x0e000c, 0x10000c, 0x10000c, 0x0f000c, 0x10000d, - 0x10000d, 0x11000d, 0x12000d, 0x11000d, 0x13000d, 0x11000d, 0x10000d, 0x0d000a, - 0x0a0009, 0x0a0009, 0x0a0009, 0x0b0009, 0x0b0009, 0x0c0009, 0x0c0009, 0x0c0009, - 0x0d0009, 0x0d0009, 0x0d0009, 0x0d000a, 0x0d000a, 0x0d000a, 0x0d000a, 0x0a0006 -]; -/** - * - * for (i = 0; i < 3*3; i++) [ - * table23[i] = ((ht[2].hlen[i]) << 16) + ht[3].hlen[i]; - * ] - * - * - */ -Tables.table23 = [ - 0x010002, 0x040003, 0x070007, - 0x040004, 0x050004, 0x070007, - 0x060006, 0x070007, 0x080008 -]; - -/** - * - * for (i = 0; i < 4*4; i++) [ - * table56[i] = ((ht[5].hlen[i]) << 16) + ht[6].hlen[i]; - * ] - * - * - */ -Tables.table56 = [ - 0x010003, 0x040004, 0x070006, 0x080008, 0x040004, 0x050004, 0x080006, 0x090007, - 0x070005, 0x080006, 0x090007, 0x0a0008, 0x080007, 0x080007, 0x090008, 0x0a0009 -]; - -Tables.bitrate_table = [ - [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1], /* MPEG 2 */ - [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1], /* MPEG 1 */ - [0, 8, 16, 24, 32, 40, 48, 56, 64, -1, -1, -1, -1, -1, -1, -1], /* MPEG 2.5 */ -]; - -/** - * MPEG 2, MPEG 1, MPEG 2.5. - */ -Tables.samplerate_table = [ - [22050, 24000, 16000, -1], - [44100, 48000, 32000, -1], - [11025, 12000, 8000, -1], -]; - -/** - * This is the scfsi_band table from 2.4.2.7 of the IS. - */ -Tables.scfsi_band = [0, 6, 11, 16, 21]; - -function MeanBits(meanBits) { - this.bits = meanBits; -} - -function VBRQuantize() { - var qupvt; - var tak; - - this.setModules = function (_qupvt, _tk) { - qupvt = _qupvt; - tak = _tk; - } - //TODO - -} - -//package mp3; - -function CalcNoiseResult() { - /** - * sum of quantization noise > masking - */ - this.over_noise = 0.; - /** - * sum of all quantization noise - */ - this.tot_noise = 0.; - /** - * max quantization noise - */ - this.max_noise = 0.; - /** - * number of quantization noise > masking - */ - this.over_count = 0; - /** - * SSD-like cost of distorted bands - */ - this.over_SSD = 0; - this.bits = 0; -} - - -function LameGlobalFlags() { - - this.class_id = 0; - - /* input description */ - - /** - * number of samples. default=-1 - */ - this.num_samples = 0; - /** - * input number of channels. default=2 - */ - this.num_channels = 0; - /** - * input_samp_rate in Hz. default=44.1 kHz - */ - this.in_samplerate = 0; - /** - * output_samp_rate. default: LAME picks best value at least not used for - * MP3 decoding: Remember 44.1 kHz MP3s and AC97 - */ - this.out_samplerate = 0; - /** - * scale input by this amount before encoding at least not used for MP3 - * decoding - */ - this.scale = 0.; - /** - * scale input of channel 0 (left) by this amount before encoding - */ - this.scale_left = 0.; - /** - * scale input of channel 1 (right) by this amount before encoding - */ - this.scale_right = 0.; - - /* general control params */ - /** - * collect data for a MP3 frame analyzer? - */ - this.analysis = false; - /** - * add Xing VBR tag? - */ - this.bWriteVbrTag = false; - - /** - * use lame/mpglib to convert mp3 to wav - */ - this.decode_only = false; - /** - * quality setting 0=best, 9=worst default=5 - */ - this.quality = 0; - /** - * see enum default = LAME picks best value - */ - this.mode = MPEGMode.STEREO; - /** - * force M/S mode. requires mode=1 - */ - this.force_ms = false; - /** - * use free format? default=0 - */ - this.free_format = false; - /** - * find the RG value? default=0 - */ - this.findReplayGain = false; - /** - * decode on the fly? default=0 - */ - this.decode_on_the_fly = false; - /** - * 1 (default) writes ID3 tags, 0 not - */ - this.write_id3tag_automatic = false; - - /* - * set either brate>0 or compression_ratio>0, LAME will compute the value of - * the variable not set. Default is compression_ratio = 11.025 - */ - /** - * bitrate - */ - this.brate = 0; - /** - * sizeof(wav file)/sizeof(mp3 file) - */ - this.compression_ratio = 0.; - - /* frame params */ - /** - * mark as copyright. default=0 - */ - this.copyright = 0; - /** - * mark as original. default=1 - */ - this.original = 0; - /** - * the MP3 'private extension' bit. Meaningless - */ - this.extension = 0; - /** - * Input PCM is emphased PCM (for instance from one of the rarely emphased - * CDs), it is STRONGLY not recommended to use this, because psycho does not - * take it into account, and last but not least many decoders don't care - * about these bits - */ - this.emphasis = 0; - /** - * use 2 bytes per frame for a CRC checksum. default=0 - */ - this.error_protection = 0; - /** - * enforce ISO spec as much as possible - */ - this.strict_ISO = false; - - /** - * use bit reservoir? - */ - this.disable_reservoir = false; - - /* quantization/noise shaping */ - this.quant_comp = 0; - this.quant_comp_short = 0; - this.experimentalY = false; - this.experimentalZ = 0; - this.exp_nspsytune = 0; - - this.preset = 0; - - /* VBR control */ - this.VBR = null; - /** - * Range [0,...,1[ - */ - this.VBR_q_frac = 0.; - /** - * Range [0,...,9] - */ - this.VBR_q = 0; - this.VBR_mean_bitrate_kbps = 0; - this.VBR_min_bitrate_kbps = 0; - this.VBR_max_bitrate_kbps = 0; - /** - * strictly enforce VBR_min_bitrate normaly, it will be violated for analog - * silence - */ - this.VBR_hard_min = 0; - - /* resampling and filtering */ - - /** - * freq in Hz. 0=lame choses. -1=no filter - */ - this.lowpassfreq = 0; - /** - * freq in Hz. 0=lame choses. -1=no filter - */ - this.highpassfreq = 0; - /** - * freq width of filter, in Hz (default=15%) - */ - this.lowpasswidth = 0; - /** - * freq width of filter, in Hz (default=15%) - */ - this.highpasswidth = 0; - - /* - * psycho acoustics and other arguments which you should not change unless - * you know what you are doing - */ - - this.maskingadjust = 0.; - this.maskingadjust_short = 0.; - /** - * only use ATH - */ - this.ATHonly = false; - /** - * only use ATH for short blocks - */ - this.ATHshort = false; - /** - * disable ATH - */ - this.noATH = false; - /** - * select ATH formula - */ - this.ATHtype = 0; - /** - * change ATH formula 4 shape - */ - this.ATHcurve = 0.; - /** - * lower ATH by this many db - */ - this.ATHlower = 0.; - /** - * select ATH auto-adjust scheme - */ - this.athaa_type = 0; - /** - * select ATH auto-adjust loudness calc - */ - this.athaa_loudapprox = 0; - /** - * dB, tune active region of auto-level - */ - this.athaa_sensitivity = 0.; - this.short_blocks = null; - /** - * use temporal masking effect - */ - this.useTemporal = false; - this.interChRatio = 0.; - /** - * Naoki's adjustment of Mid/Side maskings - */ - this.msfix = 0.; - - /** - * 0 off, 1 on - */ - this.tune = false; - /** - * used to pass values for debugging and stuff - */ - this.tune_value_a = 0.; - - /************************************************************************/ - /* internal variables, do not set... */ - /* provided because they may be of use to calling application */ - /************************************************************************/ - - /** - * 0=MPEG-2/2.5 1=MPEG-1 - */ - this.version = 0; - this.encoder_delay = 0; - /** - * number of samples of padding appended to input - */ - this.encoder_padding = 0; - this.framesize = 0; - /** - * number of frames encoded - */ - this.frameNum = 0; - /** - * is this struct owned by calling program or lame? - */ - this.lame_allocated_gfp = 0; - /**************************************************************************/ - /* more internal variables are stored in this structure: */ - /**************************************************************************/ - this.internal_flags = null; -} - - - -function ReplayGain() { - this.linprebuf = new_float(GainAnalysis.MAX_ORDER * 2); - /** - * left input samples, with pre-buffer - */ - this.linpre = 0; - this.lstepbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER); - /** - * left "first step" (i.e. post first filter) samples - */ - this.lstep = 0; - this.loutbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER); - /** - * left "out" (i.e. post second filter) samples - */ - this.lout = 0; - this.rinprebuf = new_float(GainAnalysis.MAX_ORDER * 2); - /** - * right input samples ... - */ - this.rinpre = 0; - this.rstepbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER); - this.rstep = 0; - this.routbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER); - this.rout = 0; - /** - * number of samples required to reach number of milliseconds required - * for RMS window - */ - this.sampleWindow = 0; - this.totsamp = 0; - this.lsum = 0.; - this.rsum = 0.; - this.freqindex = 0; - this.first = 0; - this.A = new_int(0 | (GainAnalysis.STEPS_per_dB * GainAnalysis.MAX_dB)); - this.B = new_int(0 | (GainAnalysis.STEPS_per_dB * GainAnalysis.MAX_dB)); - -} - - - -function CBRNewIterationLoop(_quantize) { - var quantize = _quantize; - this.quantize = quantize; - this.iteration_loop = function(gfp, pe, ms_ener_ratio, ratio) { - var gfc = gfp.internal_flags; - var l3_xmin = new_float(L3Side.SFBMAX); - var xrpow = new_float(576); - var targ_bits = new_int(2); - var mean_bits = 0, max_bits; - var l3_side = gfc.l3_side; - - var mb = new MeanBits(mean_bits); - this.quantize.rv.ResvFrameBegin(gfp, mb); - mean_bits = mb.bits; - - /* quantize! */ - for (var gr = 0; gr < gfc.mode_gr; gr++) { - - /* - * calculate needed bits - */ - max_bits = this.quantize.qupvt.on_pe(gfp, pe, targ_bits, mean_bits, - gr, gr); - - if (gfc.mode_ext == Encoder.MPG_MD_MS_LR) { - this.quantize.ms_convert(gfc.l3_side, gr); - this.quantize.qupvt.reduce_side(targ_bits, ms_ener_ratio[gr], - mean_bits, max_bits); - } - - for (var ch = 0; ch < gfc.channels_out; ch++) { - var adjust, masking_lower_db; - var cod_info = l3_side.tt[gr][ch]; - - if (cod_info.block_type != Encoder.SHORT_TYPE) { - // NORM, START or STOP type - adjust = 0; - masking_lower_db = gfc.PSY.mask_adjust - adjust; - } else { - adjust = 0; - masking_lower_db = gfc.PSY.mask_adjust_short - adjust; - } - gfc.masking_lower = Math.pow(10.0, - masking_lower_db * 0.1); - - /* - * init_outer_loop sets up cod_info, scalefac and xrpow - */ - this.quantize.init_outer_loop(gfc, cod_info); - if (this.quantize.init_xrpow(gfc, cod_info, xrpow)) { - /* - * xr contains energy we will have to encode calculate the - * masking abilities find some good quantization in - * outer_loop - */ - this.quantize.qupvt.calc_xmin(gfp, ratio[gr][ch], cod_info, - l3_xmin); - this.quantize.outer_loop(gfp, cod_info, l3_xmin, xrpow, ch, - targ_bits[ch]); - } - - this.quantize.iteration_finish_one(gfc, gr, ch); - } /* for ch */ - } /* for gr */ - - this.quantize.rv.ResvFrameEnd(gfc, mean_bits); - } -} - - -/** - * ATH related stuff, if something new ATH related has to be added, please plug - * it here into the ATH. - */ -function ATH() { - /** - * Method for the auto adjustment. - */ - this.useAdjust = 0; - /** - * factor for tuning the (sample power) point below which adaptive threshold - * of hearing adjustment occurs - */ - this.aaSensitivityP = 0.; - /** - * Lowering based on peak volume, 1 = no lowering. - */ - this.adjust = 0.; - /** - * Limit for dynamic ATH adjust. - */ - this.adjustLimit = 0.; - /** - * Determined to lower x dB each second. - */ - this.decay = 0.; - /** - * Lowest ATH value. - */ - this.floor = 0.; - /** - * ATH for sfbs in long blocks. - */ - this.l = new_float(Encoder.SBMAX_l); - /** - * ATH for sfbs in short blocks. - */ - this.s = new_float(Encoder.SBMAX_s); - /** - * ATH for partitioned sfb21 in long blocks. - */ - this.psfb21 = new_float(Encoder.PSFB21); - /** - * ATH for partitioned sfb12 in short blocks. - */ - this.psfb12 = new_float(Encoder.PSFB12); - /** - * ATH for long block convolution bands. - */ - this.cb_l = new_float(Encoder.CBANDS); - /** - * ATH for short block convolution bands. - */ - this.cb_s = new_float(Encoder.CBANDS); - /** - * Equal loudness weights (based on ATH). - */ - this.eql_w = new_float(Encoder.BLKSIZE / 2); -} - -//package mp3; - -/** - * Layer III side information. - * - * @author Ken - * - */ - - - -function ScaleFac(arrL, arrS, arr21, arr12) { - - this.l = new_int(1 + Encoder.SBMAX_l); - this.s = new_int(1 + Encoder.SBMAX_s); - this.psfb21 = new_int(1 + Encoder.PSFB21); - this.psfb12 = new_int(1 + Encoder.PSFB12); - var l = this.l; - var s = this.s; - - if (arguments.length == 4) { - //public ScaleFac(final int[] arrL, final int[] arrS, final int[] arr21, - // final int[] arr12) { - this.arrL = arguments[0]; - this.arrS = arguments[1]; - this.arr21 = arguments[2]; - this.arr12 = arguments[3]; - - System.arraycopy(this.arrL, 0, l, 0, Math.min(this.arrL.length, this.l.length)); - System.arraycopy(this.arrS, 0, s, 0, Math.min(this.arrS.length, this.s.length)); - System.arraycopy(this.arr21, 0, this.psfb21, 0, Math.min(this.arr21.length, this.psfb21.length)); - System.arraycopy(this.arr12, 0, this.psfb12, 0, Math.min(this.arr12.length, this.psfb12.length)); - } -} - -/* - * quantize_pvt source file - * - * Copyright (c) 1999-2002 Takehiro Tominaga - * Copyright (c) 2000-2002 Robert Hegemann - * Copyright (c) 2001 Naoki Shibata - * Copyright (c) 2002-2005 Gabriel Bouvigne - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: QuantizePVT.java,v 1.24 2011/05/24 20:48:06 kenchis Exp $ */ - - -QuantizePVT.Q_MAX = (256 + 1); -QuantizePVT.Q_MAX2 = 116; -QuantizePVT.LARGE_BITS = 100000; -QuantizePVT.IXMAX_VAL = 8206; - -function QuantizePVT() { - - var tak = null; - var rv = null; - var psy = null; - - this.setModules = function (_tk, _rv, _psy) { - tak = _tk; - rv = _rv; - psy = _psy; - }; - - function POW20(x) { - return pow20[x + QuantizePVT.Q_MAX2]; - } - - this.IPOW20 = function (x) { - return ipow20[x]; - } - - /** - * smallest such that 1.0+DBL_EPSILON != 1.0 - */ - var DBL_EPSILON = 2.2204460492503131e-016; - - /** - * ix always <= 8191+15. see count_bits() - */ - var IXMAX_VAL = QuantizePVT.IXMAX_VAL; - - var PRECALC_SIZE = (IXMAX_VAL + 2); - - var Q_MAX = QuantizePVT.Q_MAX; - - - /** - * - * minimum possible number of - * -cod_info.global_gain + ((scalefac[] + (cod_info.preflag ? pretab[sfb] : 0)) - * << (cod_info.scalefac_scale + 1)) + cod_info.subblock_gain[cod_info.window[sfb]] * 8; - * - * for long block, 0+((15+3)<<2) = 18*4 = 72 - * for short block, 0+(15<<2)+7*8 = 15*4+56 = 116 - * - */ - var Q_MAX2 = QuantizePVT.Q_MAX2; - - var LARGE_BITS = QuantizePVT.LARGE_BITS; - - - /** - * Assuming dynamic range=96dB, this value should be 92 - */ - var NSATHSCALE = 100; - - /** - * The following table is used to implement the scalefactor partitioning for - * MPEG2 as described in section 2.4.3.2 of the IS. The indexing corresponds - * to the way the tables are presented in the IS: - * - * [table_number][row_in_table][column of nr_of_sfb] - */ - this.nr_of_sfb_block = [ - [[6, 5, 5, 5], [9, 9, 9, 9], [6, 9, 9, 9]], - [[6, 5, 7, 3], [9, 9, 12, 6], [6, 9, 12, 6]], - [[11, 10, 0, 0], [18, 18, 0, 0], [15, 18, 0, 0]], - [[7, 7, 7, 0], [12, 12, 12, 0], [6, 15, 12, 0]], - [[6, 6, 6, 3], [12, 9, 9, 6], [6, 12, 9, 6]], - [[8, 8, 5, 0], [15, 12, 9, 0], [6, 18, 9, 0]]]; - - /** - * Table B.6: layer3 preemphasis - */ - var pretab = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, - 2, 2, 3, 3, 3, 2, 0]; - this.pretab = pretab; - - /** - * Here are MPEG1 Table B.8 and MPEG2 Table B.1 -- Layer III scalefactor - * bands.
- * Index into this using a method such as:
- * idx = fr_ps.header.sampling_frequency + (fr_ps.header.version * 3) - */ - this.sfBandIndex = [ - // Table B.2.b: 22.05 kHz - new ScaleFac([0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, - 522, 576], - [0, 4, 8, 12, 18, 24, 32, 42, 56, 74, 100, 132, 174, 192] - , [0, 0, 0, 0, 0, 0, 0] // sfb21 pseudo sub bands - , [0, 0, 0, 0, 0, 0, 0] // sfb12 pseudo sub bands - ), - /* Table B.2.c: 24 kHz */ /* docs: 332. mpg123(broken): 330 */ - new ScaleFac([0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 114, 136, 162, 194, 232, 278, 332, 394, 464, - 540, 576], - [0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 136, 180, 192] - , [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */ - , [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */ - ), - /* Table B.2.a: 16 kHz */ - new ScaleFac([0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, - 522, 576], - [0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192] - , [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */ - , [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */ - ), - /* Table B.8.b: 44.1 kHz */ - new ScaleFac([0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418, - 576], - [0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84, 106, 136, 192] - , [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */ - , [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */ - ), - /* Table B.8.c: 48 kHz */ - new ScaleFac([0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330, 384, - 576], - [0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80, 100, 126, 192] - , [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */ - , [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */ - ), - /* Table B.8.a: 32 kHz */ - new ScaleFac([0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448, 550, - 576], - [0, 4, 8, 12, 16, 22, 30, 42, 58, 78, 104, 138, 180, 192] - , [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */ - , [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */ - ), - /* MPEG-2.5 11.025 kHz */ - new ScaleFac([0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, - 522, 576], - [0 / 3, 12 / 3, 24 / 3, 36 / 3, 54 / 3, 78 / 3, 108 / 3, 144 / 3, 186 / 3, 240 / 3, 312 / 3, - 402 / 3, 522 / 3, 576 / 3] - , [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */ - , [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */ - ), - /* MPEG-2.5 12 kHz */ - new ScaleFac([0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, - 522, 576], - [0 / 3, 12 / 3, 24 / 3, 36 / 3, 54 / 3, 78 / 3, 108 / 3, 144 / 3, 186 / 3, 240 / 3, 312 / 3, - 402 / 3, 522 / 3, 576 / 3] - , [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */ - , [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */ - ), - /* MPEG-2.5 8 kHz */ - new ScaleFac([0, 12, 24, 36, 48, 60, 72, 88, 108, 132, 160, 192, 232, 280, 336, 400, 476, 566, 568, 570, - 572, 574, 576], - [0 / 3, 24 / 3, 48 / 3, 72 / 3, 108 / 3, 156 / 3, 216 / 3, 288 / 3, 372 / 3, 480 / 3, 486 / 3, - 492 / 3, 498 / 3, 576 / 3] - , [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */ - , [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */ - ) - ]; - - var pow20 = new_float(Q_MAX + Q_MAX2 + 1); - var ipow20 = new_float(Q_MAX); - var pow43 = new_float(PRECALC_SIZE); - - var adj43 = new_float(PRECALC_SIZE); - this.adj43 = adj43; - - /** - *
-     * compute the ATH for each scalefactor band cd range: 0..96db
-     *
-     * Input: 3.3kHz signal 32767 amplitude (3.3kHz is where ATH is smallest =
-     * -5db) longblocks: sfb=12 en0/bw=-11db max_en0 = 1.3db shortblocks: sfb=5
-     * -9db 0db
-     *
-     * Input: 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated) longblocks: amp=1
-     * sfb=12 en0/bw=-103 db max_en0 = -92db amp=32767 sfb=12 -12 db -1.4db
-     *
-     * Input: 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated) shortblocks: amp=1
-     * sfb=5 en0/bw= -99 -86 amp=32767 sfb=5 -9 db 4db
-     *
-     *
-     * MAX energy of largest wave at 3.3kHz = 1db AVE energy of largest wave at
-     * 3.3kHz = -11db Let's take AVE: -11db = maximum signal in sfb=12. Dynamic
-     * range of CD: 96db. Therefor energy of smallest audible wave in sfb=12 =
-     * -11 - 96 = -107db = ATH at 3.3kHz.
-     *
-     * ATH formula for this wave: -5db. To adjust to LAME scaling, we need ATH =
-     * ATH_formula - 103 (db) ATH = ATH * 2.5e-10 (ener)
-     * 
- */ - function ATHmdct(gfp, f) { - var ath = psy.ATHformula(f, gfp); - - ath -= NSATHSCALE; - - /* modify the MDCT scaling for the ATH and convert to energy */ - ath = Math.pow(10.0, ath / 10.0 + gfp.ATHlower); - return ath; - } - - function compute_ath(gfp) { - var ATH_l = gfp.internal_flags.ATH.l; - var ATH_psfb21 = gfp.internal_flags.ATH.psfb21; - var ATH_s = gfp.internal_flags.ATH.s; - var ATH_psfb12 = gfp.internal_flags.ATH.psfb12; - var gfc = gfp.internal_flags; - var samp_freq = gfp.out_samplerate; - - for (var sfb = 0; sfb < Encoder.SBMAX_l; sfb++) { - var start = gfc.scalefac_band.l[sfb]; - var end = gfc.scalefac_band.l[sfb + 1]; - ATH_l[sfb] = Float.MAX_VALUE; - for (var i = start; i < end; i++) { - var freq = i * samp_freq / (2 * 576); - var ATH_f = ATHmdct(gfp, freq); - /* freq in kHz */ - ATH_l[sfb] = Math.min(ATH_l[sfb], ATH_f); - } - } - - for (var sfb = 0; sfb < Encoder.PSFB21; sfb++) { - var start = gfc.scalefac_band.psfb21[sfb]; - var end = gfc.scalefac_band.psfb21[sfb + 1]; - ATH_psfb21[sfb] = Float.MAX_VALUE; - for (var i = start; i < end; i++) { - var freq = i * samp_freq / (2 * 576); - var ATH_f = ATHmdct(gfp, freq); - /* freq in kHz */ - ATH_psfb21[sfb] = Math.min(ATH_psfb21[sfb], ATH_f); - } - } - - for (var sfb = 0; sfb < Encoder.SBMAX_s; sfb++) { - var start = gfc.scalefac_band.s[sfb]; - var end = gfc.scalefac_band.s[sfb + 1]; - ATH_s[sfb] = Float.MAX_VALUE; - for (var i = start; i < end; i++) { - var freq = i * samp_freq / (2 * 192); - var ATH_f = ATHmdct(gfp, freq); - /* freq in kHz */ - ATH_s[sfb] = Math.min(ATH_s[sfb], ATH_f); - } - ATH_s[sfb] *= (gfc.scalefac_band.s[sfb + 1] - gfc.scalefac_band.s[sfb]); - } - - for (var sfb = 0; sfb < Encoder.PSFB12; sfb++) { - var start = gfc.scalefac_band.psfb12[sfb]; - var end = gfc.scalefac_band.psfb12[sfb + 1]; - ATH_psfb12[sfb] = Float.MAX_VALUE; - for (var i = start; i < end; i++) { - var freq = i * samp_freq / (2 * 192); - var ATH_f = ATHmdct(gfp, freq); - /* freq in kHz */ - ATH_psfb12[sfb] = Math.min(ATH_psfb12[sfb], ATH_f); - } - /* not sure about the following */ - ATH_psfb12[sfb] *= (gfc.scalefac_band.s[13] - gfc.scalefac_band.s[12]); - } - - /* - * no-ATH mode: reduce ATH to -200 dB - */ - if (gfp.noATH) { - for (var sfb = 0; sfb < Encoder.SBMAX_l; sfb++) { - ATH_l[sfb] = 1E-20; - } - for (var sfb = 0; sfb < Encoder.PSFB21; sfb++) { - ATH_psfb21[sfb] = 1E-20; - } - for (var sfb = 0; sfb < Encoder.SBMAX_s; sfb++) { - ATH_s[sfb] = 1E-20; - } - for (var sfb = 0; sfb < Encoder.PSFB12; sfb++) { - ATH_psfb12[sfb] = 1E-20; - } - } - - /* - * work in progress, don't rely on it too much - */ - gfc.ATH.floor = 10. * Math.log10(ATHmdct(gfp, -1.)); - } - - /** - * initialization for iteration_loop - */ - this.iteration_init = function (gfp) { - var gfc = gfp.internal_flags; - var l3_side = gfc.l3_side; - var i; - - if (gfc.iteration_init_init == 0) { - gfc.iteration_init_init = 1; - - l3_side.main_data_begin = 0; - compute_ath(gfp); - - pow43[0] = 0.0; - for (i = 1; i < PRECALC_SIZE; i++) - pow43[i] = Math.pow(i, 4.0 / 3.0); - - for (i = 0; i < PRECALC_SIZE - 1; i++) - adj43[i] = ((i + 1) - Math.pow( - 0.5 * (pow43[i] + pow43[i + 1]), 0.75)); - adj43[i] = 0.5; - - for (i = 0; i < Q_MAX; i++) - ipow20[i] = Math.pow(2.0, (i - 210) * -0.1875); - for (i = 0; i <= Q_MAX + Q_MAX2; i++) - pow20[i] = Math.pow(2.0, (i - 210 - Q_MAX2) * 0.25); - - tak.huffman_init(gfc); - - { - var bass, alto, treble, sfb21; - - i = (gfp.exp_nspsytune >> 2) & 63; - if (i >= 32) - i -= 64; - bass = Math.pow(10, i / 4.0 / 10.0); - - i = (gfp.exp_nspsytune >> 8) & 63; - if (i >= 32) - i -= 64; - alto = Math.pow(10, i / 4.0 / 10.0); - - i = (gfp.exp_nspsytune >> 14) & 63; - if (i >= 32) - i -= 64; - treble = Math.pow(10, i / 4.0 / 10.0); - - /* - * to be compatible with Naoki's original code, the next 6 bits - * define only the amount of changing treble for sfb21 - */ - i = (gfp.exp_nspsytune >> 20) & 63; - if (i >= 32) - i -= 64; - sfb21 = treble * Math.pow(10, i / 4.0 / 10.0); - for (i = 0; i < Encoder.SBMAX_l; i++) { - var f; - if (i <= 6) - f = bass; - else if (i <= 13) - f = alto; - else if (i <= 20) - f = treble; - else - f = sfb21; - - gfc.nsPsy.longfact[i] = f; - } - for (i = 0; i < Encoder.SBMAX_s; i++) { - var f; - if (i <= 5) - f = bass; - else if (i <= 10) - f = alto; - else if (i <= 11) - f = treble; - else - f = sfb21; - - gfc.nsPsy.shortfact[i] = f; - } - } - } - } - - /** - * allocate bits among 2 channels based on PE
- * mt 6/99
- * bugfixes rh 8/01: often allocated more than the allowed 4095 bits - */ - this.on_pe = function (gfp, pe, - targ_bits, mean_bits, gr, cbr) { - var gfc = gfp.internal_flags; - var tbits = 0, bits; - var add_bits = new_int(2); - var ch; - - /* allocate targ_bits for granule */ - var mb = new MeanBits(tbits); - var extra_bits = rv.ResvMaxBits(gfp, mean_bits, mb, cbr); - tbits = mb.bits; - /* maximum allowed bits for this granule */ - var max_bits = tbits + extra_bits; - if (max_bits > LameInternalFlags.MAX_BITS_PER_GRANULE) { - // hard limit per granule - max_bits = LameInternalFlags.MAX_BITS_PER_GRANULE; - } - for (bits = 0, ch = 0; ch < gfc.channels_out; ++ch) { - /****************************************************************** - * allocate bits for each channel - ******************************************************************/ - targ_bits[ch] = Math.min(LameInternalFlags.MAX_BITS_PER_CHANNEL, - tbits / gfc.channels_out); - - add_bits[ch] = 0 | (targ_bits[ch] * pe[gr][ch] / 700.0 - targ_bits[ch]); - - /* at most increase bits by 1.5*average */ - if (add_bits[ch] > mean_bits * 3 / 4) - add_bits[ch] = mean_bits * 3 / 4; - if (add_bits[ch] < 0) - add_bits[ch] = 0; - - if (add_bits[ch] + targ_bits[ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL) - add_bits[ch] = Math.max(0, - LameInternalFlags.MAX_BITS_PER_CHANNEL - targ_bits[ch]); - - bits += add_bits[ch]; - } - if (bits > extra_bits) { - for (ch = 0; ch < gfc.channels_out; ++ch) { - add_bits[ch] = extra_bits * add_bits[ch] / bits; - } - } - - for (ch = 0; ch < gfc.channels_out; ++ch) { - targ_bits[ch] += add_bits[ch]; - extra_bits -= add_bits[ch]; - } - - for (bits = 0, ch = 0; ch < gfc.channels_out; ++ch) { - bits += targ_bits[ch]; - } - if (bits > LameInternalFlags.MAX_BITS_PER_GRANULE) { - var sum = 0; - for (ch = 0; ch < gfc.channels_out; ++ch) { - targ_bits[ch] *= LameInternalFlags.MAX_BITS_PER_GRANULE; - targ_bits[ch] /= bits; - sum += targ_bits[ch]; - } - } - - return max_bits; - } - - this.reduce_side = function (targ_bits, ms_ener_ratio, mean_bits, max_bits) { - - /* - * ms_ener_ratio = 0: allocate 66/33 mid/side fac=.33 ms_ener_ratio =.5: - * allocate 50/50 mid/side fac= 0 - */ - /* 75/25 split is fac=.5 */ - var fac = .33 * (.5 - ms_ener_ratio) / .5; - if (fac < 0) - fac = 0; - if (fac > .5) - fac = .5; - - /* number of bits to move from side channel to mid channel */ - /* move_bits = fac*targ_bits[1]; */ - var move_bits = 0 | (fac * .5 * (targ_bits[0] + targ_bits[1])); - - if (move_bits > LameInternalFlags.MAX_BITS_PER_CHANNEL - targ_bits[0]) { - move_bits = LameInternalFlags.MAX_BITS_PER_CHANNEL - targ_bits[0]; - } - if (move_bits < 0) - move_bits = 0; - - if (targ_bits[1] >= 125) { - /* dont reduce side channel below 125 bits */ - if (targ_bits[1] - move_bits > 125) { - - /* if mid channel already has 2x more than average, dont bother */ - /* mean_bits = bits per granule (for both channels) */ - if (targ_bits[0] < mean_bits) - targ_bits[0] += move_bits; - targ_bits[1] -= move_bits; - } else { - targ_bits[0] += targ_bits[1] - 125; - targ_bits[1] = 125; - } - } - - move_bits = targ_bits[0] + targ_bits[1]; - if (move_bits > max_bits) { - targ_bits[0] = (max_bits * targ_bits[0]) / move_bits; - targ_bits[1] = (max_bits * targ_bits[1]) / move_bits; - } - }; - - /** - * Robert Hegemann 2001-04-27: - * this adjusts the ATH, keeping the original noise floor - * affects the higher frequencies more than the lower ones - */ - this.athAdjust = function (a, x, athFloor) { - /* - * work in progress - */ - var o = 90.30873362; - var p = 94.82444863; - var u = Util.FAST_LOG10_X(x, 10.0); - var v = a * a; - var w = 0.0; - u -= athFloor; - /* undo scaling */ - if (v > 1E-20) - w = 1. + Util.FAST_LOG10_X(v, 10.0 / o); - if (w < 0) - w = 0.; - u *= w; - u += athFloor + o - p; - /* redo scaling */ - - return Math.pow(10., 0.1 * u); - }; - - /** - * Calculate the allowed distortion for each scalefactor band, as determined - * by the psychoacoustic model. xmin(sb) = ratio(sb) * en(sb) / bw(sb) - * - * returns number of sfb's with energy > ATH - */ - this.calc_xmin = function (gfp, ratio, cod_info, pxmin) { - var pxminPos = 0; - var gfc = gfp.internal_flags; - var gsfb, j = 0, ath_over = 0; - var ATH = gfc.ATH; - var xr = cod_info.xr; - var enable_athaa_fix = (gfp.VBR == VbrMode.vbr_mtrh) ? 1 : 0; - var masking_lower = gfc.masking_lower; - - if (gfp.VBR == VbrMode.vbr_mtrh || gfp.VBR == VbrMode.vbr_mt) { - /* was already done in PSY-Model */ - masking_lower = 1.0; - } - - for (gsfb = 0; gsfb < cod_info.psy_lmax; gsfb++) { - var en0, xmin; - var rh1, rh2; - var width, l; - - if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh) - xmin = athAdjust(ATH.adjust, ATH.l[gsfb], ATH.floor); - else - xmin = ATH.adjust * ATH.l[gsfb]; - - width = cod_info.width[gsfb]; - rh1 = xmin / width; - rh2 = DBL_EPSILON; - l = width >> 1; - en0 = 0.0; - do { - var xa, xb; - xa = xr[j] * xr[j]; - en0 += xa; - rh2 += (xa < rh1) ? xa : rh1; - j++; - xb = xr[j] * xr[j]; - en0 += xb; - rh2 += (xb < rh1) ? xb : rh1; - j++; - } while (--l > 0); - if (en0 > xmin) - ath_over++; - - if (gsfb == Encoder.SBPSY_l) { - var x = xmin * gfc.nsPsy.longfact[gsfb]; - if (rh2 < x) { - rh2 = x; - } - } - if (enable_athaa_fix != 0) { - xmin = rh2; - } - if (!gfp.ATHonly) { - var e = ratio.en.l[gsfb]; - if (e > 0.0) { - var x; - x = en0 * ratio.thm.l[gsfb] * masking_lower / e; - if (enable_athaa_fix != 0) - x *= gfc.nsPsy.longfact[gsfb]; - if (xmin < x) - xmin = x; - } - } - if (enable_athaa_fix != 0) - pxmin[pxminPos++] = xmin; - else - pxmin[pxminPos++] = xmin * gfc.nsPsy.longfact[gsfb]; - } - /* end of long block loop */ - - /* use this function to determine the highest non-zero coeff */ - var max_nonzero = 575; - if (cod_info.block_type != Encoder.SHORT_TYPE) { - // NORM, START or STOP type, but not SHORT - var k = 576; - while (k-- != 0 && BitStream.EQ(xr[k], 0)) { - max_nonzero = k; - } - } - cod_info.max_nonzero_coeff = max_nonzero; - - for (var sfb = cod_info.sfb_smin; gsfb < cod_info.psymax; sfb++, gsfb += 3) { - var width, b; - var tmpATH; - if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh) - tmpATH = athAdjust(ATH.adjust, ATH.s[sfb], ATH.floor); - else - tmpATH = ATH.adjust * ATH.s[sfb]; - - width = cod_info.width[gsfb]; - for (b = 0; b < 3; b++) { - var en0 = 0.0, xmin; - var rh1, rh2; - var l = width >> 1; - - rh1 = tmpATH / width; - rh2 = DBL_EPSILON; - do { - var xa, xb; - xa = xr[j] * xr[j]; - en0 += xa; - rh2 += (xa < rh1) ? xa : rh1; - j++; - xb = xr[j] * xr[j]; - en0 += xb; - rh2 += (xb < rh1) ? xb : rh1; - j++; - } while (--l > 0); - if (en0 > tmpATH) - ath_over++; - if (sfb == Encoder.SBPSY_s) { - var x = tmpATH * gfc.nsPsy.shortfact[sfb]; - if (rh2 < x) { - rh2 = x; - } - } - if (enable_athaa_fix != 0) - xmin = rh2; - else - xmin = tmpATH; - - if (!gfp.ATHonly && !gfp.ATHshort) { - var e = ratio.en.s[sfb][b]; - if (e > 0.0) { - var x; - x = en0 * ratio.thm.s[sfb][b] * masking_lower / e; - if (enable_athaa_fix != 0) - x *= gfc.nsPsy.shortfact[sfb]; - if (xmin < x) - xmin = x; - } - } - if (enable_athaa_fix != 0) - pxmin[pxminPos++] = xmin; - else - pxmin[pxminPos++] = xmin * gfc.nsPsy.shortfact[sfb]; - } - /* b */ - if (gfp.useTemporal) { - if (pxmin[pxminPos - 3] > pxmin[pxminPos - 3 + 1]) - pxmin[pxminPos - 3 + 1] += (pxmin[pxminPos - 3] - pxmin[pxminPos - 3 + 1]) - * gfc.decay; - if (pxmin[pxminPos - 3 + 1] > pxmin[pxminPos - 3 + 2]) - pxmin[pxminPos - 3 + 2] += (pxmin[pxminPos - 3 + 1] - pxmin[pxminPos - 3 + 2]) - * gfc.decay; - } - } - /* end of short block sfb loop */ - - return ath_over; - }; - - function StartLine(j) { - this.s = j; - } - - this.calc_noise_core = function (cod_info, startline, l, step) { - var noise = 0; - var j = startline.s; - var ix = cod_info.l3_enc; - - if (j > cod_info.count1) { - while ((l--) != 0) { - var temp; - temp = cod_info.xr[j]; - j++; - noise += temp * temp; - temp = cod_info.xr[j]; - j++; - noise += temp * temp; - } - } else if (j > cod_info.big_values) { - var ix01 = new_float(2); - ix01[0] = 0; - ix01[1] = step; - while ((l--) != 0) { - var temp; - temp = Math.abs(cod_info.xr[j]) - ix01[ix[j]]; - j++; - noise += temp * temp; - temp = Math.abs(cod_info.xr[j]) - ix01[ix[j]]; - j++; - noise += temp * temp; - } - } else { - while ((l--) != 0) { - var temp; - temp = Math.abs(cod_info.xr[j]) - pow43[ix[j]] * step; - j++; - noise += temp * temp; - temp = Math.abs(cod_info.xr[j]) - pow43[ix[j]] * step; - j++; - noise += temp * temp; - } - } - - startline.s = j; - return noise; - } - - /** - *
-     * -oo dB  =>  -1.00
-     * - 6 dB  =>  -0.97
-     * - 3 dB  =>  -0.80
-     * - 2 dB  =>  -0.64
-     * - 1 dB  =>  -0.38
-     *   0 dB  =>   0.00
-     * + 1 dB  =>  +0.49
-     * + 2 dB  =>  +1.06
-     * + 3 dB  =>  +1.68
-     * + 6 dB  =>  +3.69
-     * +10 dB  =>  +6.45
-     * 
- */ - this.calc_noise = function (cod_info, l3_xmin, distort, res, prev_noise) { - var distortPos = 0; - var l3_xminPos = 0; - var sfb, l, over = 0; - var over_noise_db = 0; - /* 0 dB relative to masking */ - var tot_noise_db = 0; - /* -200 dB relative to masking */ - var max_noise = -20.0; - var j = 0; - var scalefac = cod_info.scalefac; - var scalefacPos = 0; - - res.over_SSD = 0; - - for (sfb = 0; sfb < cod_info.psymax; sfb++) { - var s = cod_info.global_gain - - (((scalefac[scalefacPos++]) + (cod_info.preflag != 0 ? pretab[sfb] - : 0)) << (cod_info.scalefac_scale + 1)) - - cod_info.subblock_gain[cod_info.window[sfb]] * 8; - var noise = 0.0; - - if (prev_noise != null && (prev_noise.step[sfb] == s)) { - - /* use previously computed values */ - noise = prev_noise.noise[sfb]; - j += cod_info.width[sfb]; - distort[distortPos++] = noise / l3_xmin[l3_xminPos++]; - - noise = prev_noise.noise_log[sfb]; - - } else { - var step = POW20(s); - l = cod_info.width[sfb] >> 1; - - if ((j + cod_info.width[sfb]) > cod_info.max_nonzero_coeff) { - var usefullsize; - usefullsize = cod_info.max_nonzero_coeff - j + 1; - - if (usefullsize > 0) - l = usefullsize >> 1; - else - l = 0; - } - - var sl = new StartLine(j); - noise = this.calc_noise_core(cod_info, sl, l, step); - j = sl.s; - - if (prev_noise != null) { - /* save noise values */ - prev_noise.step[sfb] = s; - prev_noise.noise[sfb] = noise; - } - - noise = distort[distortPos++] = noise / l3_xmin[l3_xminPos++]; - - /* multiplying here is adding in dB, but can overflow */ - noise = Util.FAST_LOG10(Math.max(noise, 1E-20)); - - if (prev_noise != null) { - /* save noise values */ - prev_noise.noise_log[sfb] = noise; - } - } - - if (prev_noise != null) { - /* save noise values */ - prev_noise.global_gain = cod_info.global_gain; - } - - tot_noise_db += noise; - - if (noise > 0.0) { - var tmp; - - tmp = Math.max(0 | (noise * 10 + .5), 1); - res.over_SSD += tmp * tmp; - - over++; - /* multiplying here is adding in dB -but can overflow */ - /* over_noise *= noise; */ - over_noise_db += noise; - } - max_noise = Math.max(max_noise, noise); - - } - - res.over_count = over; - res.tot_noise = tot_noise_db; - res.over_noise = over_noise_db; - res.max_noise = max_noise; - - return over; - } - - /** - * updates plotting data - * - * Mark Taylor 2000-??-?? - * - * Robert Hegemann: moved noise/distortion calc into it - */ - this.set_pinfo = function (gfp, cod_info, ratio, gr, ch) { - var gfc = gfp.internal_flags; - var sfb, sfb2; - var l; - var en0, en1; - var ifqstep = (cod_info.scalefac_scale == 0) ? .5 : 1.0; - var scalefac = cod_info.scalefac; - - var l3_xmin = new_float(L3Side.SFBMAX); - var xfsf = new_float(L3Side.SFBMAX); - var noise = new CalcNoiseResult(); - - calc_xmin(gfp, ratio, cod_info, l3_xmin); - calc_noise(cod_info, l3_xmin, xfsf, noise, null); - - var j = 0; - sfb2 = cod_info.sfb_lmax; - if (cod_info.block_type != Encoder.SHORT_TYPE - && 0 == cod_info.mixed_block_flag) - sfb2 = 22; - for (sfb = 0; sfb < sfb2; sfb++) { - var start = gfc.scalefac_band.l[sfb]; - var end = gfc.scalefac_band.l[sfb + 1]; - var bw = end - start; - for (en0 = 0.0; j < end; j++) - en0 += cod_info.xr[j] * cod_info.xr[j]; - en0 /= bw; - /* convert to MDCT units */ - /* scaling so it shows up on FFT plot */ - en1 = 1e15; - gfc.pinfo.en[gr][ch][sfb] = en1 * en0; - gfc.pinfo.xfsf[gr][ch][sfb] = en1 * l3_xmin[sfb] * xfsf[sfb] / bw; - - if (ratio.en.l[sfb] > 0 && !gfp.ATHonly) - en0 = en0 / ratio.en.l[sfb]; - else - en0 = 0.0; - - gfc.pinfo.thr[gr][ch][sfb] = en1 - * Math.max(en0 * ratio.thm.l[sfb], gfc.ATH.l[sfb]); - - /* there is no scalefactor bands >= SBPSY_l */ - gfc.pinfo.LAMEsfb[gr][ch][sfb] = 0; - if (cod_info.preflag != 0 && sfb >= 11) - gfc.pinfo.LAMEsfb[gr][ch][sfb] = -ifqstep * pretab[sfb]; - - if (sfb < Encoder.SBPSY_l) { - /* scfsi should be decoded by caller side */ - gfc.pinfo.LAMEsfb[gr][ch][sfb] -= ifqstep * scalefac[sfb]; - } - } - /* for sfb */ - - if (cod_info.block_type == Encoder.SHORT_TYPE) { - sfb2 = sfb; - for (sfb = cod_info.sfb_smin; sfb < Encoder.SBMAX_s; sfb++) { - var start = gfc.scalefac_band.s[sfb]; - var end = gfc.scalefac_band.s[sfb + 1]; - var bw = end - start; - for (var i = 0; i < 3; i++) { - for (en0 = 0.0, l = start; l < end; l++) { - en0 += cod_info.xr[j] * cod_info.xr[j]; - j++; - } - en0 = Math.max(en0 / bw, 1e-20); - /* convert to MDCT units */ - /* scaling so it shows up on FFT plot */ - en1 = 1e15; - - gfc.pinfo.en_s[gr][ch][3 * sfb + i] = en1 * en0; - gfc.pinfo.xfsf_s[gr][ch][3 * sfb + i] = en1 * l3_xmin[sfb2] - * xfsf[sfb2] / bw; - if (ratio.en.s[sfb][i] > 0) - en0 = en0 / ratio.en.s[sfb][i]; - else - en0 = 0.0; - if (gfp.ATHonly || gfp.ATHshort) - en0 = 0; - - gfc.pinfo.thr_s[gr][ch][3 * sfb + i] = en1 - * Math.max(en0 * ratio.thm.s[sfb][i], - gfc.ATH.s[sfb]); - - /* there is no scalefactor bands >= SBPSY_s */ - gfc.pinfo.LAMEsfb_s[gr][ch][3 * sfb + i] = -2.0 - * cod_info.subblock_gain[i]; - if (sfb < Encoder.SBPSY_s) { - gfc.pinfo.LAMEsfb_s[gr][ch][3 * sfb + i] -= ifqstep - * scalefac[sfb2]; - } - sfb2++; - } - } - } - /* block type short */ - gfc.pinfo.LAMEqss[gr][ch] = cod_info.global_gain; - gfc.pinfo.LAMEmainbits[gr][ch] = cod_info.part2_3_length - + cod_info.part2_length; - gfc.pinfo.LAMEsfbits[gr][ch] = cod_info.part2_length; - - gfc.pinfo.over[gr][ch] = noise.over_count; - gfc.pinfo.max_noise[gr][ch] = noise.max_noise * 10.0; - gfc.pinfo.over_noise[gr][ch] = noise.over_noise * 10.0; - gfc.pinfo.tot_noise[gr][ch] = noise.tot_noise * 10.0; - gfc.pinfo.over_SSD[gr][ch] = noise.over_SSD; - } - - /** - * updates plotting data for a whole frame - * - * Robert Hegemann 2000-10-21 - */ - function set_frame_pinfo(gfp, ratio) { - var gfc = gfp.internal_flags; - - gfc.masking_lower = 1.0; - - /* - * for every granule and channel patch l3_enc and set info - */ - for (var gr = 0; gr < gfc.mode_gr; gr++) { - for (var ch = 0; ch < gfc.channels_out; ch++) { - var cod_info = gfc.l3_side.tt[gr][ch]; - var scalefac_sav = new_int(L3Side.SFBMAX); - System.arraycopy(cod_info.scalefac, 0, scalefac_sav, 0, - scalefac_sav.length); - - /* - * reconstruct the scalefactors in case SCFSI was used - */ - if (gr == 1) { - var sfb; - for (sfb = 0; sfb < cod_info.sfb_lmax; sfb++) { - if (cod_info.scalefac[sfb] < 0) /* scfsi */ - cod_info.scalefac[sfb] = gfc.l3_side.tt[0][ch].scalefac[sfb]; - } - } - - set_pinfo(gfp, cod_info, ratio[gr][ch], gr, ch); - System.arraycopy(scalefac_sav, 0, cod_info.scalefac, 0, - scalefac_sav.length); - } - /* for ch */ - } - /* for gr */ - } - -} - - -function CalcNoiseData() { - this.global_gain = 0; - this.sfb_count1 = 0; - this.step = new_int(39); - this.noise = new_float(39); - this.noise_log = new_float(39); -} - -//package mp3; - - -function GrInfo() { - //float xr[] = new float[576]; - this.xr = new_float(576); - //int l3_enc[] = new int[576]; - this.l3_enc = new_int(576); - //int scalefac[] = new int[L3Side.SFBMAX]; - this.scalefac = new_int(L3Side.SFBMAX); - this.xrpow_max = 0.; - - this.part2_3_length = 0; - this.big_values = 0; - this.count1 = 0; - this.global_gain = 0; - this.scalefac_compress = 0; - this.block_type = 0; - this.mixed_block_flag = 0; - this.table_select = new_int(3); - this.subblock_gain = new_int(3 + 1); - this.region0_count = 0; - this.region1_count = 0; - this.preflag = 0; - this.scalefac_scale = 0; - this.count1table_select = 0; - - this.part2_length = 0; - this.sfb_lmax = 0; - this.sfb_smin = 0; - this.psy_lmax = 0; - this.sfbmax = 0; - this.psymax = 0; - this.sfbdivide = 0; - this.width = new_int(L3Side.SFBMAX); - this.window = new_int(L3Side.SFBMAX); - this.count1bits = 0; - /** - * added for LSF - */ - this.sfb_partition_table = null; - this.slen = new_int(4); - - this.max_nonzero_coeff = 0; - - var self = this; - function clone_int(array) { - return new Int32Array(array); - } - function clone_float(array) { - return new Float32Array(array); - } - this.assign = function (other) { - self.xr = clone_float(other.xr); //.slice(0); //clone(); - self.l3_enc = clone_int(other.l3_enc); //.slice(0); //clone(); - self.scalefac = clone_int(other.scalefac);//.slice(0); //clone(); - self.xrpow_max = other.xrpow_max; - - self.part2_3_length = other.part2_3_length; - self.big_values = other.big_values; - self.count1 = other.count1; - self.global_gain = other.global_gain; - self.scalefac_compress = other.scalefac_compress; - self.block_type = other.block_type; - self.mixed_block_flag = other.mixed_block_flag; - self.table_select = clone_int(other.table_select);//.slice(0); //clone(); - self.subblock_gain = clone_int(other.subblock_gain); //.slice(0); //.clone(); - self.region0_count = other.region0_count; - self.region1_count = other.region1_count; - self.preflag = other.preflag; - self.scalefac_scale = other.scalefac_scale; - self.count1table_select = other.count1table_select; - - self.part2_length = other.part2_length; - self.sfb_lmax = other.sfb_lmax; - self.sfb_smin = other.sfb_smin; - self.psy_lmax = other.psy_lmax; - self.sfbmax = other.sfbmax; - self.psymax = other.psymax; - self.sfbdivide = other.sfbdivide; - self.width = clone_int(other.width); //.slice(0); //.clone(); - self.window = clone_int(other.window); //.slice(0); //.clone(); - self.count1bits = other.count1bits; - - self.sfb_partition_table = other.sfb_partition_table.slice(0); //.clone(); - self.slen = clone_int(other.slen); //.slice(0); //.clone(); - self.max_nonzero_coeff = other.max_nonzero_coeff; - } -} - - -var L3Side = {}; - - - /** - * max scalefactor band, max(SBMAX_l, SBMAX_s*3, (SBMAX_s-3)*3+8) - */ -L3Side.SFBMAX = (Encoder.SBMAX_s * 3); - -/* - * MP3 quantization - * - * Copyright (c) 1999-2000 Mark Taylor - * Copyright (c) 1999-2003 Takehiro Tominaga - * Copyright (c) 2000-2007 Robert Hegemann - * Copyright (c) 2001-2005 Gabriel Bouvigne - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: Quantize.java,v 1.24 2011/05/24 20:48:06 kenchis Exp $ */ - -//package mp3; - -//import java.util.Arrays; - - -function Quantize() { - var bs; - this.rv = null; - var rv; - this.qupvt = null; - var qupvt; - - var vbr = new VBRQuantize(); - var tk; - - this.setModules = function (_bs, _rv, _qupvt, _tk) { - bs = _bs; - rv = _rv; - this.rv = _rv; - qupvt = _qupvt; - this.qupvt = _qupvt; - tk = _tk; - vbr.setModules(qupvt, tk); - } - - /** - * convert from L/R <. Mid/Side - */ - this.ms_convert = function (l3_side, gr) { - for (var i = 0; i < 576; ++i) { - var l = l3_side.tt[gr][0].xr[i]; - var r = l3_side.tt[gr][1].xr[i]; - l3_side.tt[gr][0].xr[i] = (l + r) * (Util.SQRT2 * 0.5); - l3_side.tt[gr][1].xr[i] = (l - r) * (Util.SQRT2 * 0.5); - } - }; - - /** - * mt 6/99 - * - * initializes cod_info, scalefac and xrpow - * - * returns 0 if all energies in xr are zero, else 1 - */ - function init_xrpow_core(cod_info, xrpow, upper, sum) { - sum = 0; - for (var i = 0; i <= upper; ++i) { - var tmp = Math.abs(cod_info.xr[i]); - sum += tmp; - xrpow[i] = Math.sqrt(tmp * Math.sqrt(tmp)); - - if (xrpow[i] > cod_info.xrpow_max) - cod_info.xrpow_max = xrpow[i]; - } - return sum; - } - - this.init_xrpow = function (gfc, cod_info, xrpow) { - var sum = 0; - var upper = 0 | cod_info.max_nonzero_coeff; - - cod_info.xrpow_max = 0; - - /* - * check if there is some energy we have to quantize and calculate xrpow - * matching our fresh scalefactors - */ - - Arrays.fill(xrpow, upper, 576, 0); - - sum = init_xrpow_core(cod_info, xrpow, upper, sum); - - /* - * return 1 if we have something to quantize, else 0 - */ - if (sum > 1E-20) { - var j = 0; - if ((gfc.substep_shaping & 2) != 0) - j = 1; - - for (var i = 0; i < cod_info.psymax; i++) - gfc.pseudohalf[i] = j; - - return true; - } - - Arrays.fill(cod_info.l3_enc, 0, 576, 0); - return false; - } - - /** - * Gabriel Bouvigne feb/apr 2003
- * Analog silence detection in partitionned sfb21 or sfb12 for short blocks - * - * From top to bottom of sfb, changes to 0 coeffs which are below ath. It - * stops on the first coeff higher than ath. - */ - function psfb21_analogsilence(gfc, cod_info) { - var ath = gfc.ATH; - var xr = cod_info.xr; - - if (cod_info.block_type != Encoder.SHORT_TYPE) { - /* NORM, START or STOP type, but not SHORT blocks */ - var stop = false; - for (var gsfb = Encoder.PSFB21 - 1; gsfb >= 0 && !stop; gsfb--) { - var start = gfc.scalefac_band.psfb21[gsfb]; - var end = gfc.scalefac_band.psfb21[gsfb + 1]; - var ath21 = qupvt.athAdjust(ath.adjust, ath.psfb21[gsfb], - ath.floor); - - if (gfc.nsPsy.longfact[21] > 1e-12) - ath21 *= gfc.nsPsy.longfact[21]; - - for (var j = end - 1; j >= start; j--) { - if (Math.abs(xr[j]) < ath21) - xr[j] = 0; - else { - stop = true; - break; - } - } - } - } else { - /* note: short blocks coeffs are reordered */ - for (var block = 0; block < 3; block++) { - var stop = false; - for (var gsfb = Encoder.PSFB12 - 1; gsfb >= 0 && !stop; gsfb--) { - var start = gfc.scalefac_band.s[12] - * 3 - + (gfc.scalefac_band.s[13] - gfc.scalefac_band.s[12]) - * block - + (gfc.scalefac_band.psfb12[gsfb] - gfc.scalefac_band.psfb12[0]); - var end = start - + (gfc.scalefac_band.psfb12[gsfb + 1] - gfc.scalefac_band.psfb12[gsfb]); - var ath12 = qupvt.athAdjust(ath.adjust, ath.psfb12[gsfb], - ath.floor); - - if (gfc.nsPsy.shortfact[12] > 1e-12) - ath12 *= gfc.nsPsy.shortfact[12]; - - for (var j = end - 1; j >= start; j--) { - if (Math.abs(xr[j]) < ath12) - xr[j] = 0; - else { - stop = true; - break; - } - } - } - } - } - - } - - this.init_outer_loop = function (gfc, cod_info) { - /* - * initialize fresh cod_info - */ - cod_info.part2_3_length = 0; - cod_info.big_values = 0; - cod_info.count1 = 0; - cod_info.global_gain = 210; - cod_info.scalefac_compress = 0; - /* mixed_block_flag, block_type was set in psymodel.c */ - cod_info.table_select[0] = 0; - cod_info.table_select[1] = 0; - cod_info.table_select[2] = 0; - cod_info.subblock_gain[0] = 0; - cod_info.subblock_gain[1] = 0; - cod_info.subblock_gain[2] = 0; - cod_info.subblock_gain[3] = 0; - /* this one is always 0 */ - cod_info.region0_count = 0; - cod_info.region1_count = 0; - cod_info.preflag = 0; - cod_info.scalefac_scale = 0; - cod_info.count1table_select = 0; - cod_info.part2_length = 0; - cod_info.sfb_lmax = Encoder.SBPSY_l; - cod_info.sfb_smin = Encoder.SBPSY_s; - cod_info.psy_lmax = gfc.sfb21_extra ? Encoder.SBMAX_l : Encoder.SBPSY_l; - cod_info.psymax = cod_info.psy_lmax; - cod_info.sfbmax = cod_info.sfb_lmax; - cod_info.sfbdivide = 11; - for (var sfb = 0; sfb < Encoder.SBMAX_l; sfb++) { - cod_info.width[sfb] = gfc.scalefac_band.l[sfb + 1] - - gfc.scalefac_band.l[sfb]; - /* which is always 0. */ - cod_info.window[sfb] = 3; - } - if (cod_info.block_type == Encoder.SHORT_TYPE) { - var ixwork = new_float(576); - - cod_info.sfb_smin = 0; - cod_info.sfb_lmax = 0; - if (cod_info.mixed_block_flag != 0) { - /* - * MPEG-1: sfbs 0-7 long block, 3-12 short blocks MPEG-2(.5): - * sfbs 0-5 long block, 3-12 short blocks - */ - cod_info.sfb_smin = 3; - cod_info.sfb_lmax = gfc.mode_gr * 2 + 4; - } - cod_info.psymax = cod_info.sfb_lmax - + 3 - * ((gfc.sfb21_extra ? Encoder.SBMAX_s : Encoder.SBPSY_s) - cod_info.sfb_smin); - cod_info.sfbmax = cod_info.sfb_lmax + 3 - * (Encoder.SBPSY_s - cod_info.sfb_smin); - cod_info.sfbdivide = cod_info.sfbmax - 18; - cod_info.psy_lmax = cod_info.sfb_lmax; - /* re-order the short blocks, for more efficient encoding below */ - /* By Takehiro TOMINAGA */ - /* - * Within each scalefactor band, data is given for successive time - * windows, beginning with window 0 and ending with window 2. Within - * each window, the quantized values are then arranged in order of - * increasing frequency... - */ - var ix = gfc.scalefac_band.l[cod_info.sfb_lmax]; - System.arraycopy(cod_info.xr, 0, ixwork, 0, 576); - for (var sfb = cod_info.sfb_smin; sfb < Encoder.SBMAX_s; sfb++) { - var start = gfc.scalefac_band.s[sfb]; - var end = gfc.scalefac_band.s[sfb + 1]; - for (var window = 0; window < 3; window++) { - for (var l = start; l < end; l++) { - cod_info.xr[ix++] = ixwork[3 * l + window]; - } - } - } - - var j = cod_info.sfb_lmax; - for (var sfb = cod_info.sfb_smin; sfb < Encoder.SBMAX_s; sfb++) { - cod_info.width[j] = cod_info.width[j + 1] = cod_info.width[j + 2] = gfc.scalefac_band.s[sfb + 1] - - gfc.scalefac_band.s[sfb]; - cod_info.window[j] = 0; - cod_info.window[j + 1] = 1; - cod_info.window[j + 2] = 2; - j += 3; - } - } - - cod_info.count1bits = 0; - cod_info.sfb_partition_table = qupvt.nr_of_sfb_block[0][0]; - cod_info.slen[0] = 0; - cod_info.slen[1] = 0; - cod_info.slen[2] = 0; - cod_info.slen[3] = 0; - - cod_info.max_nonzero_coeff = 575; - - /* - * fresh scalefactors are all zero - */ - Arrays.fill(cod_info.scalefac, 0); - - psfb21_analogsilence(gfc, cod_info); - }; - - function BinSearchDirection(ordinal) { - this.ordinal = ordinal; - } - - BinSearchDirection.BINSEARCH_NONE = new BinSearchDirection(0); - BinSearchDirection.BINSEARCH_UP = new BinSearchDirection(1); - BinSearchDirection.BINSEARCH_DOWN = new BinSearchDirection(2); - - /** - * author/date?? - * - * binary step size search used by outer_loop to get a quantizer step size - * to start with - */ - function bin_search_StepSize(gfc, cod_info, desired_rate, ch, xrpow) { - var nBits; - var CurrentStep = gfc.CurrentStep[ch]; - var flagGoneOver = false; - var start = gfc.OldValue[ch]; - var Direction = BinSearchDirection.BINSEARCH_NONE; - cod_info.global_gain = start; - desired_rate -= cod_info.part2_length; - - for (; ;) { - var step; - nBits = tk.count_bits(gfc, xrpow, cod_info, null); - - if (CurrentStep == 1 || nBits == desired_rate) - break; - /* nothing to adjust anymore */ - - if (nBits > desired_rate) { - /* increase Quantize_StepSize */ - if (Direction == BinSearchDirection.BINSEARCH_DOWN) - flagGoneOver = true; - - if (flagGoneOver) - CurrentStep /= 2; - Direction = BinSearchDirection.BINSEARCH_UP; - step = CurrentStep; - } else { - /* decrease Quantize_StepSize */ - if (Direction == BinSearchDirection.BINSEARCH_UP) - flagGoneOver = true; - - if (flagGoneOver) - CurrentStep /= 2; - Direction = BinSearchDirection.BINSEARCH_DOWN; - step = -CurrentStep; - } - cod_info.global_gain += step; - if (cod_info.global_gain < 0) { - cod_info.global_gain = 0; - flagGoneOver = true; - } - if (cod_info.global_gain > 255) { - cod_info.global_gain = 255; - flagGoneOver = true; - } - } - - - while (nBits > desired_rate && cod_info.global_gain < 255) { - cod_info.global_gain++; - nBits = tk.count_bits(gfc, xrpow, cod_info, null); - } - gfc.CurrentStep[ch] = (start - cod_info.global_gain >= 4) ? 4 : 2; - gfc.OldValue[ch] = cod_info.global_gain; - cod_info.part2_3_length = nBits; - return nBits; - } - - this.trancate_smallspectrums = function (gfc, gi, l3_xmin, work) { - var distort = new_float(L3Side.SFBMAX); - - if ((0 == (gfc.substep_shaping & 4) && gi.block_type == Encoder.SHORT_TYPE) - || (gfc.substep_shaping & 0x80) != 0) - return; - qupvt.calc_noise(gi, l3_xmin, distort, new CalcNoiseResult(), null); - for (var j = 0; j < 576; j++) { - var xr = 0.0; - if (gi.l3_enc[j] != 0) - xr = Math.abs(gi.xr[j]); - work[j] = xr; - } - - var j = 0; - var sfb = 8; - if (gi.block_type == Encoder.SHORT_TYPE) - sfb = 6; - do { - var allowedNoise, trancateThreshold; - var nsame, start; - - var width = gi.width[sfb]; - j += width; - if (distort[sfb] >= 1.0) - continue; - - Arrays.sort(work, j - width, width); - if (BitStream.EQ(work[j - 1], 0.0)) - continue; - /* all zero sfb */ - - allowedNoise = (1.0 - distort[sfb]) * l3_xmin[sfb]; - trancateThreshold = 0.0; - start = 0; - do { - var noise; - for (nsame = 1; start + nsame < width; nsame++) - if (BitStream.NEQ(work[start + j - width], work[start + j - + nsame - width])) - break; - - noise = work[start + j - width] * work[start + j - width] - * nsame; - if (allowedNoise < noise) { - if (start != 0) - trancateThreshold = work[start + j - width - 1]; - break; - } - allowedNoise -= noise; - start += nsame; - } while (start < width); - if (BitStream.EQ(trancateThreshold, 0.0)) - continue; - - do { - if (Math.abs(gi.xr[j - width]) <= trancateThreshold) - gi.l3_enc[j - width] = 0; - } while (--width > 0); - } while (++sfb < gi.psymax); - - gi.part2_3_length = tk.noquant_count_bits(gfc, gi, null); - }; - - /** - * author/date?? - * - * Function: Returns zero if there is a scalefac which has not been - * amplified. Otherwise it returns one. - */ - function loop_break(cod_info) { - for (var sfb = 0; sfb < cod_info.sfbmax; sfb++) - if (cod_info.scalefac[sfb] - + cod_info.subblock_gain[cod_info.window[sfb]] == 0) - return false; - - return true; - } - - /* mt 5/99: Function: Improved calc_noise for a single channel */ - - function penalties(noise) { - return Util.FAST_LOG10((0.368 + 0.632 * noise * noise * noise)); - } - - /** - * author/date?? - * - * several different codes to decide which quantization is better - */ - function get_klemm_noise(distort, gi) { - var klemm_noise = 1E-37; - for (var sfb = 0; sfb < gi.psymax; sfb++) - klemm_noise += penalties(distort[sfb]); - - return Math.max(1e-20, klemm_noise); - } - - function quant_compare(quant_comp, best, calc, gi, distort) { - /** - * noise is given in decibels (dB) relative to masking thesholds.
- * - * over_noise: ??? (the previous comment is fully wrong)
- * tot_noise: ??? (the previous comment is fully wrong)
- * max_noise: max quantization noise - */ - var better; - - switch (quant_comp) { - default: - case 9: - { - if (best.over_count > 0) { - /* there are distorted sfb */ - better = calc.over_SSD <= best.over_SSD; - if (calc.over_SSD == best.over_SSD) - better = calc.bits < best.bits; - } else { - /* no distorted sfb */ - better = ((calc.max_noise < 0) && ((calc.max_noise * 10 + calc.bits) <= (best.max_noise * 10 + best.bits))); - } - break; - } - - case 0: - better = calc.over_count < best.over_count - || (calc.over_count == best.over_count && calc.over_noise < best.over_noise) - || (calc.over_count == best.over_count - && BitStream.EQ(calc.over_noise, best.over_noise) && calc.tot_noise < best.tot_noise); - break; - - case 8: - calc.max_noise = get_klemm_noise(distort, gi); - //$FALL-THROUGH$ - case 1: - better = calc.max_noise < best.max_noise; - break; - case 2: - better = calc.tot_noise < best.tot_noise; - break; - case 3: - better = (calc.tot_noise < best.tot_noise) - && (calc.max_noise < best.max_noise); - break; - case 4: - better = (calc.max_noise <= 0.0 && best.max_noise > 0.2) - || (calc.max_noise <= 0.0 && best.max_noise < 0.0 - && best.max_noise > calc.max_noise - 0.2 && calc.tot_noise < best.tot_noise) - || (calc.max_noise <= 0.0 && best.max_noise > 0.0 - && best.max_noise > calc.max_noise - 0.2 && calc.tot_noise < best.tot_noise - + best.over_noise) - || (calc.max_noise > 0.0 && best.max_noise > -0.05 - && best.max_noise > calc.max_noise - 0.1 && calc.tot_noise - + calc.over_noise < best.tot_noise - + best.over_noise) - || (calc.max_noise > 0.0 && best.max_noise > -0.1 - && best.max_noise > calc.max_noise - 0.15 && calc.tot_noise - + calc.over_noise + calc.over_noise < best.tot_noise - + best.over_noise + best.over_noise); - break; - case 5: - better = calc.over_noise < best.over_noise - || (BitStream.EQ(calc.over_noise, best.over_noise) && calc.tot_noise < best.tot_noise); - break; - case 6: - better = calc.over_noise < best.over_noise - || (BitStream.EQ(calc.over_noise, best.over_noise) && (calc.max_noise < best.max_noise || (BitStream - .EQ(calc.max_noise, best.max_noise) && calc.tot_noise <= best.tot_noise))); - break; - case 7: - better = calc.over_count < best.over_count - || calc.over_noise < best.over_noise; - break; - } - - if (best.over_count == 0) { - /* - * If no distorted bands, only use this quantization if it is - * better, and if it uses less bits. Unfortunately, part2_3_length - * is sometimes a poor estimator of the final size at low bitrates. - */ - better = better && calc.bits < best.bits; - } - - return better; - } - - /** - * author/date?? - * - *
-     *  Amplify the scalefactor bands that violate the masking threshold.
-     *  See ISO 11172-3 Section C.1.5.4.3.5
-     *
-     *  distort[] = noise/masking
-     *  distort[] > 1   ==> noise is not masked
-     *  distort[] < 1   ==> noise is masked
-     *  max_dist = maximum value of distort[]
-     *
-     *  Three algorithms:
-     *  noise_shaping_amp
-     *        0             Amplify all bands with distort[]>1.
-     *
-     *        1             Amplify all bands with distort[] >= max_dist^(.5);
-     *                     ( 50% in the db scale)
-     *
-     *        2             Amplify first band with distort[] >= max_dist;
-     *
-     *
-     *  For algorithms 0 and 1, if max_dist < 1, then amplify all bands
-     *  with distort[] >= .95*max_dist.  This is to make sure we always
-     *  amplify at least one band.
-     * 
- */ - function amp_scalefac_bands(gfp, cod_info, distort, xrpow, bRefine) { - var gfc = gfp.internal_flags; - var ifqstep34; - - if (cod_info.scalefac_scale == 0) { - ifqstep34 = 1.29683955465100964055; - /* 2**(.75*.5) */ - } else { - ifqstep34 = 1.68179283050742922612; - /* 2**(.75*1) */ - } - - /* compute maximum value of distort[] */ - var trigger = 0; - for (var sfb = 0; sfb < cod_info.sfbmax; sfb++) { - if (trigger < distort[sfb]) - trigger = distort[sfb]; - } - - var noise_shaping_amp = gfc.noise_shaping_amp; - if (noise_shaping_amp == 3) { - if (bRefine) - noise_shaping_amp = 2; - else - noise_shaping_amp = 1; - } - switch (noise_shaping_amp) { - case 2: - /* amplify exactly 1 band */ - break; - - case 1: - /* amplify bands within 50% of max (on db scale) */ - if (trigger > 1.0) - trigger = Math.pow(trigger, .5); - else - trigger *= .95; - break; - - case 0: - default: - /* ISO algorithm. amplify all bands with distort>1 */ - if (trigger > 1.0) - trigger = 1.0; - else - trigger *= .95; - break; - } - - var j = 0; - for (var sfb = 0; sfb < cod_info.sfbmax; sfb++) { - var width = cod_info.width[sfb]; - var l; - j += width; - if (distort[sfb] < trigger) - continue; - - if ((gfc.substep_shaping & 2) != 0) { - gfc.pseudohalf[sfb] = (0 == gfc.pseudohalf[sfb]) ? 1 : 0; - if (0 == gfc.pseudohalf[sfb] && gfc.noise_shaping_amp == 2) - return; - } - cod_info.scalefac[sfb]++; - for (l = -width; l < 0; l++) { - xrpow[j + l] *= ifqstep34; - if (xrpow[j + l] > cod_info.xrpow_max) - cod_info.xrpow_max = xrpow[j + l]; - } - - if (gfc.noise_shaping_amp == 2) - return; - } - } - - /** - * Takehiro Tominaga 2000-xx-xx - * - * turns on scalefac scale and adjusts scalefactors - */ - function inc_scalefac_scale(cod_info, xrpow) { - var ifqstep34 = 1.29683955465100964055; - - var j = 0; - for (var sfb = 0; sfb < cod_info.sfbmax; sfb++) { - var width = cod_info.width[sfb]; - var s = cod_info.scalefac[sfb]; - if (cod_info.preflag != 0) - s += qupvt.pretab[sfb]; - j += width; - if ((s & 1) != 0) { - s++; - for (var l = -width; l < 0; l++) { - xrpow[j + l] *= ifqstep34; - if (xrpow[j + l] > cod_info.xrpow_max) - cod_info.xrpow_max = xrpow[j + l]; - } - } - cod_info.scalefac[sfb] = s >> 1; - } - cod_info.preflag = 0; - cod_info.scalefac_scale = 1; - } - - /** - * Takehiro Tominaga 2000-xx-xx - * - * increases the subblock gain and adjusts scalefactors - */ - function inc_subblock_gain(gfc, cod_info, xrpow) { - var sfb; - var scalefac = cod_info.scalefac; - - /* subbloc_gain can't do anything in the long block region */ - for (sfb = 0; sfb < cod_info.sfb_lmax; sfb++) { - if (scalefac[sfb] >= 16) - return true; - } - - for (var window = 0; window < 3; window++) { - var s1 = 0; - var s2 = 0; - - for (sfb = cod_info.sfb_lmax + window; sfb < cod_info.sfbdivide; sfb += 3) { - if (s1 < scalefac[sfb]) - s1 = scalefac[sfb]; - } - for (; sfb < cod_info.sfbmax; sfb += 3) { - if (s2 < scalefac[sfb]) - s2 = scalefac[sfb]; - } - - if (s1 < 16 && s2 < 8) - continue; - - if (cod_info.subblock_gain[window] >= 7) - return true; - - /* - * even though there is no scalefactor for sfb12 subblock gain - * affects upper frequencies too, that's why we have to go up to - * SBMAX_s - */ - cod_info.subblock_gain[window]++; - var j = gfc.scalefac_band.l[cod_info.sfb_lmax]; - for (sfb = cod_info.sfb_lmax + window; sfb < cod_info.sfbmax; sfb += 3) { - var amp; - var width = cod_info.width[sfb]; - var s = scalefac[sfb]; - s = s - (4 >> cod_info.scalefac_scale); - if (s >= 0) { - scalefac[sfb] = s; - j += width * 3; - continue; - } - - scalefac[sfb] = 0; - { - var gain = 210 + (s << (cod_info.scalefac_scale + 1)); - amp = qupvt.IPOW20(gain); - } - j += width * (window + 1); - for (var l = -width; l < 0; l++) { - xrpow[j + l] *= amp; - if (xrpow[j + l] > cod_info.xrpow_max) - cod_info.xrpow_max = xrpow[j + l]; - } - j += width * (3 - window - 1); - } - - { - var amp = qupvt.IPOW20(202); - j += cod_info.width[sfb] * (window + 1); - for (var l = -cod_info.width[sfb]; l < 0; l++) { - xrpow[j + l] *= amp; - if (xrpow[j + l] > cod_info.xrpow_max) - cod_info.xrpow_max = xrpow[j + l]; - } - } - } - return false; - } - - /** - *
-     *  Takehiro Tominaga /date??
-     *  Robert Hegemann 2000-09-06: made a function of it
-     *
-     *  amplifies scalefactor bands,
-     *   - if all are already amplified returns 0
-     *   - if some bands are amplified too much:
-     *      * try to increase scalefac_scale
-     *      * if already scalefac_scale was set
-     *          try on short blocks to increase subblock gain
-     * 
- */ - function balance_noise(gfp, cod_info, distort, xrpow, bRefine) { - var gfc = gfp.internal_flags; - - amp_scalefac_bands(gfp, cod_info, distort, xrpow, bRefine); - - /* - * check to make sure we have not amplified too much loop_break returns - * 0 if there is an unamplified scalefac scale_bitcount returns 0 if no - * scalefactors are too large - */ - - var status = loop_break(cod_info); - - if (status) - return false; - /* all bands amplified */ - - /* - * not all scalefactors have been amplified. so these scalefacs are - * possibly valid. encode them: - */ - if (gfc.mode_gr == 2) - status = tk.scale_bitcount(cod_info); - else - status = tk.scale_bitcount_lsf(gfc, cod_info); - - if (!status) - return true; - /* amplified some bands not exceeding limits */ - - /* - * some scalefactors are too large. lets try setting scalefac_scale=1 - */ - if (gfc.noise_shaping > 1) { - Arrays.fill(gfc.pseudohalf, 0); - if (0 == cod_info.scalefac_scale) { - inc_scalefac_scale(cod_info, xrpow); - status = false; - } else { - if (cod_info.block_type == Encoder.SHORT_TYPE - && gfc.subblock_gain > 0) { - status = (inc_subblock_gain(gfc, cod_info, xrpow) || loop_break(cod_info)); - } - } - } - - if (!status) { - if (gfc.mode_gr == 2) - status = tk.scale_bitcount(cod_info); - else - status = tk.scale_bitcount_lsf(gfc, cod_info); - } - return !status; - } - - /** - *
-     *  Function: The outer iteration loop controls the masking conditions
-     *  of all scalefactorbands. It computes the best scalefac and
-     *  global gain. This module calls the inner iteration loop
-     *
-     *  mt 5/99 completely rewritten to allow for bit reservoir control,
-     *  mid/side channels with L/R or mid/side masking thresholds,
-     *  and chooses best quantization instead of last quantization when
-     *  no distortion free quantization can be found.
-     *
-     *  added VBR support mt 5/99
-     *
-     *  some code shuffle rh 9/00
-     * 
- * - * @param l3_xmin - * allowed distortion - * @param xrpow - * coloured magnitudes of spectral - * @param targ_bits - * maximum allowed bits - */ - this.outer_loop = function (gfp, cod_info, l3_xmin, xrpow, ch, targ_bits) { - var gfc = gfp.internal_flags; - var cod_info_w = new GrInfo(); - var save_xrpow = new_float(576); - var distort = new_float(L3Side.SFBMAX); - var best_noise_info = new CalcNoiseResult(); - var better; - var prev_noise = new CalcNoiseData(); - var best_part2_3_length = 9999999; - var bEndOfSearch = false; - var bRefine = false; - var best_ggain_pass1 = 0; - - bin_search_StepSize(gfc, cod_info, targ_bits, ch, xrpow); - - if (0 == gfc.noise_shaping) - /* fast mode, no noise shaping, we are ready */ - return 100; - /* default noise_info.over_count */ - - /* compute the distortion in this quantization */ - /* coefficients and thresholds both l/r (or both mid/side) */ - qupvt.calc_noise(cod_info, l3_xmin, distort, best_noise_info, - prev_noise); - best_noise_info.bits = cod_info.part2_3_length; - - cod_info_w.assign(cod_info); - var age = 0; - System.arraycopy(xrpow, 0, save_xrpow, 0, 576); - - while (!bEndOfSearch) { - /* BEGIN MAIN LOOP */ - do { - var noise_info = new CalcNoiseResult(); - var search_limit; - var maxggain = 255; - - /* - * When quantization with no distorted bands is found, allow up - * to X new unsuccesful tries in serial. This gives us more - * possibilities for different quant_compare modes. Much more - * than 3 makes not a big difference, it is only slower. - */ - - if ((gfc.substep_shaping & 2) != 0) { - search_limit = 20; - } else { - search_limit = 3; - } - - /* - * Check if the last scalefactor band is distorted. in VBR mode - * we can't get rid of the distortion, so quit now and VBR mode - * will try again with more bits. (makes a 10% speed increase, - * the files I tested were binary identical, 2000/05/20 Robert - * Hegemann) distort[] > 1 means noise > allowed noise - */ - if (gfc.sfb21_extra) { - if (distort[cod_info_w.sfbmax] > 1.0) - break; - if (cod_info_w.block_type == Encoder.SHORT_TYPE - && (distort[cod_info_w.sfbmax + 1] > 1.0 || distort[cod_info_w.sfbmax + 2] > 1.0)) - break; - } - - /* try a new scalefactor conbination on cod_info_w */ - if (!balance_noise(gfp, cod_info_w, distort, xrpow, bRefine)) - break; - if (cod_info_w.scalefac_scale != 0) - maxggain = 254; - - /* - * inner_loop starts with the initial quantization step computed - * above and slowly increases until the bits < huff_bits. Thus - * it is important not to start with too large of an inital - * quantization step. Too small is ok, but inner_loop will take - * longer - */ - var huff_bits = targ_bits - cod_info_w.part2_length; - if (huff_bits <= 0) - break; - - /* - * increase quantizer stepsize until needed bits are below - * maximum - */ - while ((cod_info_w.part2_3_length = tk.count_bits(gfc, xrpow, - cod_info_w, prev_noise)) > huff_bits - && cod_info_w.global_gain <= maxggain) - cod_info_w.global_gain++; - - if (cod_info_w.global_gain > maxggain) - break; - - if (best_noise_info.over_count == 0) { - - while ((cod_info_w.part2_3_length = tk.count_bits(gfc, - xrpow, cod_info_w, prev_noise)) > best_part2_3_length - && cod_info_w.global_gain <= maxggain) - cod_info_w.global_gain++; - - if (cod_info_w.global_gain > maxggain) - break; - } - - /* compute the distortion in this quantization */ - qupvt.calc_noise(cod_info_w, l3_xmin, distort, noise_info, - prev_noise); - noise_info.bits = cod_info_w.part2_3_length; - - /* - * check if this quantization is better than our saved - * quantization - */ - if (cod_info.block_type != Encoder.SHORT_TYPE) { - // NORM, START or STOP type - better = gfp.quant_comp; - } else - better = gfp.quant_comp_short; - - better = quant_compare(better, best_noise_info, noise_info, - cod_info_w, distort) ? 1 : 0; - - /* save data so we can restore this quantization later */ - if (better != 0) { - best_part2_3_length = cod_info.part2_3_length; - best_noise_info = noise_info; - cod_info.assign(cod_info_w); - age = 0; - /* save data so we can restore this quantization later */ - /* store for later reuse */ - System.arraycopy(xrpow, 0, save_xrpow, 0, 576); - } else { - /* early stop? */ - if (gfc.full_outer_loop == 0) { - if (++age > search_limit - && best_noise_info.over_count == 0) - break; - if ((gfc.noise_shaping_amp == 3) && bRefine && age > 30) - break; - if ((gfc.noise_shaping_amp == 3) - && bRefine - && (cod_info_w.global_gain - best_ggain_pass1) > 15) - break; - } - } - } while ((cod_info_w.global_gain + cod_info_w.scalefac_scale) < 255); - - if (gfc.noise_shaping_amp == 3) { - if (!bRefine) { - /* refine search */ - cod_info_w.assign(cod_info); - System.arraycopy(save_xrpow, 0, xrpow, 0, 576); - age = 0; - best_ggain_pass1 = cod_info_w.global_gain; - - bRefine = true; - } else { - /* search already refined, stop */ - bEndOfSearch = true; - } - - } else { - bEndOfSearch = true; - } - } - - /* - * finish up - */ - if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh) - /* restore for reuse on next try */ - System.arraycopy(save_xrpow, 0, xrpow, 0, 576); - /* - * do the 'substep shaping' - */ - else if ((gfc.substep_shaping & 1) != 0) - trancate_smallspectrums(gfc, cod_info, l3_xmin, xrpow); - - return best_noise_info.over_count; - } - - /** - * Robert Hegemann 2000-09-06 - * - * update reservoir status after FINAL quantization/bitrate - */ - this.iteration_finish_one = function (gfc, gr, ch) { - var l3_side = gfc.l3_side; - var cod_info = l3_side.tt[gr][ch]; - - /* - * try some better scalefac storage - */ - tk.best_scalefac_store(gfc, gr, ch, l3_side); - - /* - * best huffman_divide may save some bits too - */ - if (gfc.use_best_huffman == 1) - tk.best_huffman_divide(gfc, cod_info); - - /* - * update reservoir status after FINAL quantization/bitrate - */ - rv.ResvAdjust(gfc, cod_info); - }; - - /** - * - * 2000-09-04 Robert Hegemann - * - * @param l3_xmin - * allowed distortion of the scalefactor - * @param xrpow - * coloured magnitudes of spectral values - */ - this.VBR_encode_granule = function (gfp, cod_info, l3_xmin, xrpow, ch, min_bits, max_bits) { - var gfc = gfp.internal_flags; - var bst_cod_info = new GrInfo(); - var bst_xrpow = new_float(576); - var Max_bits = max_bits; - var real_bits = max_bits + 1; - var this_bits = (max_bits + min_bits) / 2; - var dbits, over, found = 0; - var sfb21_extra = gfc.sfb21_extra; - - Arrays.fill(bst_cod_info.l3_enc, 0); - - /* - * search within round about 40 bits of optimal - */ - do { - - if (this_bits > Max_bits - 42) - gfc.sfb21_extra = false; - else - gfc.sfb21_extra = sfb21_extra; - - over = outer_loop(gfp, cod_info, l3_xmin, xrpow, ch, this_bits); - - /* - * is quantization as good as we are looking for ? in this case: is - * no scalefactor band distorted? - */ - if (over <= 0) { - found = 1; - /* - * now we know it can be done with "real_bits" and maybe we can - * skip some iterations - */ - real_bits = cod_info.part2_3_length; - - /* - * store best quantization so far - */ - bst_cod_info.assign(cod_info); - System.arraycopy(xrpow, 0, bst_xrpow, 0, 576); - - /* - * try with fewer bits - */ - max_bits = real_bits - 32; - dbits = max_bits - min_bits; - this_bits = (max_bits + min_bits) / 2; - } else { - /* - * try with more bits - */ - min_bits = this_bits + 32; - dbits = max_bits - min_bits; - this_bits = (max_bits + min_bits) / 2; - - if (found != 0) { - found = 2; - /* - * start again with best quantization so far - */ - cod_info.assign(bst_cod_info); - System.arraycopy(bst_xrpow, 0, xrpow, 0, 576); - } - } - } while (dbits > 12); - - gfc.sfb21_extra = sfb21_extra; - - /* - * found=0 => nothing found, use last one found=1 => we just found the - * best and left the loop found=2 => we restored a good one and have now - * l3_enc to restore too - */ - if (found == 2) { - System.arraycopy(bst_cod_info.l3_enc, 0, cod_info.l3_enc, 0, 576); - } - } - - /** - * Robert Hegemann 2000-09-05 - * - * calculates * how many bits are available for analog silent granules * how - * many bits to use for the lowest allowed bitrate * how many bits each - * bitrate would provide - */ - this.get_framebits = function (gfp, frameBits) { - var gfc = gfp.internal_flags; - - /* - * always use at least this many bits per granule per channel unless we - * detect analog silence, see below - */ - gfc.bitrate_index = gfc.VBR_min_bitrate; - var bitsPerFrame = bs.getframebits(gfp); - - /* - * bits for analog silence - */ - gfc.bitrate_index = 1; - bitsPerFrame = bs.getframebits(gfp); - - for (var i = 1; i <= gfc.VBR_max_bitrate; i++) { - gfc.bitrate_index = i; - var mb = new MeanBits(bitsPerFrame); - frameBits[i] = rv.ResvFrameBegin(gfp, mb); - bitsPerFrame = mb.bits; - } - }; - - /* RH: this one needs to be overhauled sometime */ - - /** - *
-     *  2000-09-04 Robert Hegemann
-     *
-     *  * converts LR to MS coding when necessary
-     *  * calculates allowed/adjusted quantization noise amounts
-     *  * detects analog silent frames
-     *
-     *  some remarks:
-     *  - lower masking depending on Quality setting
-     *  - quality control together with adjusted ATH MDCT scaling
-     *    on lower quality setting allocate more noise from
-     *    ATH masking, and on higher quality setting allocate
-     *    less noise from ATH masking.
-     *  - experiments show that going more than 2dB over GPSYCHO's
-     *    limits ends up in very annoying artefacts
-     * 
- */ - this.VBR_old_prepare = function (gfp, pe, ms_ener_ratio, ratio, l3_xmin, frameBits, min_bits, - max_bits, bands) { - var gfc = gfp.internal_flags; - - var masking_lower_db, adjust = 0.0; - var analog_silence = 1; - var bits = 0; - - gfc.bitrate_index = gfc.VBR_max_bitrate; - var avg = rv.ResvFrameBegin(gfp, new MeanBits(0)) / gfc.mode_gr; - - get_framebits(gfp, frameBits); - - for (var gr = 0; gr < gfc.mode_gr; gr++) { - var mxb = qupvt.on_pe(gfp, pe, max_bits[gr], avg, gr, 0); - if (gfc.mode_ext == Encoder.MPG_MD_MS_LR) { - ms_convert(gfc.l3_side, gr); - qupvt.reduce_side(max_bits[gr], ms_ener_ratio[gr], avg, mxb); - } - for (var ch = 0; ch < gfc.channels_out; ++ch) { - var cod_info = gfc.l3_side.tt[gr][ch]; - - if (cod_info.block_type != Encoder.SHORT_TYPE) { - // NORM, START or STOP type - adjust = 1.28 / (1 + Math - .exp(3.5 - pe[gr][ch] / 300.)) - 0.05; - masking_lower_db = gfc.PSY.mask_adjust - adjust; - } else { - adjust = 2.56 / (1 + Math - .exp(3.5 - pe[gr][ch] / 300.)) - 0.14; - masking_lower_db = gfc.PSY.mask_adjust_short - adjust; - } - gfc.masking_lower = Math.pow(10.0, - masking_lower_db * 0.1); - - init_outer_loop(gfc, cod_info); - bands[gr][ch] = qupvt.calc_xmin(gfp, ratio[gr][ch], cod_info, - l3_xmin[gr][ch]); - if (bands[gr][ch] != 0) - analog_silence = 0; - - min_bits[gr][ch] = 126; - - bits += max_bits[gr][ch]; - } - } - for (var gr = 0; gr < gfc.mode_gr; gr++) { - for (var ch = 0; ch < gfc.channels_out; ch++) { - if (bits > frameBits[gfc.VBR_max_bitrate]) { - max_bits[gr][ch] *= frameBits[gfc.VBR_max_bitrate]; - max_bits[gr][ch] /= bits; - } - if (min_bits[gr][ch] > max_bits[gr][ch]) - min_bits[gr][ch] = max_bits[gr][ch]; - - } - /* for ch */ - } - /* for gr */ - - return analog_silence; - }; - - this.bitpressure_strategy = function (gfc, l3_xmin, min_bits, max_bits) { - for (var gr = 0; gr < gfc.mode_gr; gr++) { - for (var ch = 0; ch < gfc.channels_out; ch++) { - var gi = gfc.l3_side.tt[gr][ch]; - var pxmin = l3_xmin[gr][ch]; - var pxminPos = 0; - for (var sfb = 0; sfb < gi.psy_lmax; sfb++) - pxmin[pxminPos++] *= 1. + .029 * sfb * sfb - / Encoder.SBMAX_l / Encoder.SBMAX_l; - - if (gi.block_type == Encoder.SHORT_TYPE) { - for (var sfb = gi.sfb_smin; sfb < Encoder.SBMAX_s; sfb++) { - pxmin[pxminPos++] *= 1. + .029 * sfb * sfb - / Encoder.SBMAX_s / Encoder.SBMAX_s; - pxmin[pxminPos++] *= 1. + .029 * sfb * sfb - / Encoder.SBMAX_s / Encoder.SBMAX_s; - pxmin[pxminPos++] *= 1. + .029 * sfb * sfb - / Encoder.SBMAX_s / Encoder.SBMAX_s; - } - } - max_bits[gr][ch] = 0 | Math.max(min_bits[gr][ch], - 0.9 * max_bits[gr][ch]); - } - } - }; - - this.VBR_new_prepare = function (gfp, pe, ratio, l3_xmin, frameBits, max_bits) { - var gfc = gfp.internal_flags; - - var analog_silence = 1; - var avg = 0, bits = 0; - var maximum_framebits; - - if (!gfp.free_format) { - gfc.bitrate_index = gfc.VBR_max_bitrate; - - var mb = new MeanBits(avg); - rv.ResvFrameBegin(gfp, mb); - avg = mb.bits; - - get_framebits(gfp, frameBits); - maximum_framebits = frameBits[gfc.VBR_max_bitrate]; - } else { - gfc.bitrate_index = 0; - var mb = new MeanBits(avg); - maximum_framebits = rv.ResvFrameBegin(gfp, mb); - avg = mb.bits; - frameBits[0] = maximum_framebits; - } - - for (var gr = 0; gr < gfc.mode_gr; gr++) { - qupvt.on_pe(gfp, pe, max_bits[gr], avg, gr, 0); - if (gfc.mode_ext == Encoder.MPG_MD_MS_LR) { - ms_convert(gfc.l3_side, gr); - } - for (var ch = 0; ch < gfc.channels_out; ++ch) { - var cod_info = gfc.l3_side.tt[gr][ch]; - - gfc.masking_lower = Math.pow(10.0, - gfc.PSY.mask_adjust * 0.1); - - init_outer_loop(gfc, cod_info); - if (0 != qupvt.calc_xmin(gfp, ratio[gr][ch], cod_info, - l3_xmin[gr][ch])) - analog_silence = 0; - - bits += max_bits[gr][ch]; - } - } - for (var gr = 0; gr < gfc.mode_gr; gr++) { - for (var ch = 0; ch < gfc.channels_out; ch++) { - if (bits > maximum_framebits) { - max_bits[gr][ch] *= maximum_framebits; - max_bits[gr][ch] /= bits; - } - - } - /* for ch */ - } - /* for gr */ - - return analog_silence; - }; - - /** - * calculates target bits for ABR encoding - * - * mt 2000/05/31 - */ - this.calc_target_bits = function (gfp, pe, ms_ener_ratio, targ_bits, analog_silence_bits, max_frame_bits) { - var gfc = gfp.internal_flags; - var l3_side = gfc.l3_side; - var res_factor; - var gr, ch, totbits, mean_bits = 0; - - gfc.bitrate_index = gfc.VBR_max_bitrate; - var mb = new MeanBits(mean_bits); - max_frame_bits[0] = rv.ResvFrameBegin(gfp, mb); - mean_bits = mb.bits; - - gfc.bitrate_index = 1; - mean_bits = bs.getframebits(gfp) - gfc.sideinfo_len * 8; - analog_silence_bits[0] = mean_bits / (gfc.mode_gr * gfc.channels_out); - - mean_bits = gfp.VBR_mean_bitrate_kbps * gfp.framesize * 1000; - if ((gfc.substep_shaping & 1) != 0) - mean_bits *= 1.09; - mean_bits /= gfp.out_samplerate; - mean_bits -= gfc.sideinfo_len * 8; - mean_bits /= (gfc.mode_gr * gfc.channels_out); - - /** - *
-         *           res_factor is the percentage of the target bitrate that should
-         *           be used on average.  the remaining bits are added to the
-         *           bitreservoir and used for difficult to encode frames.
-         *
-         *           Since we are tracking the average bitrate, we should adjust
-         *           res_factor "on the fly", increasing it if the average bitrate
-         *           is greater than the requested bitrate, and decreasing it
-         *           otherwise.  Reasonable ranges are from .9 to 1.0
-         *
-         *           Until we get the above suggestion working, we use the following
-         *           tuning:
-         *           compression ratio    res_factor
-         *           5.5  (256kbps)         1.0      no need for bitreservoir
-         *           11   (128kbps)         .93      7% held for reservoir
-         *
-         *           with linear interpolation for other values.
-         * 
- */ - res_factor = .93 + .07 * (11.0 - gfp.compression_ratio) - / (11.0 - 5.5); - if (res_factor < .90) - res_factor = .90; - if (res_factor > 1.00) - res_factor = 1.00; - - for (gr = 0; gr < gfc.mode_gr; gr++) { - var sum = 0; - for (ch = 0; ch < gfc.channels_out; ch++) { - targ_bits[gr][ch] = (int)(res_factor * mean_bits); - - if (pe[gr][ch] > 700) { - var add_bits = (int)((pe[gr][ch] - 700) / 1.4); - - var cod_info = l3_side.tt[gr][ch]; - targ_bits[gr][ch] = (int)(res_factor * mean_bits); - - /* short blocks use a little extra, no matter what the pe */ - if (cod_info.block_type == Encoder.SHORT_TYPE) { - if (add_bits < mean_bits / 2) - add_bits = mean_bits / 2; - } - /* at most increase bits by 1.5*average */ - if (add_bits > mean_bits * 3 / 2) - add_bits = mean_bits * 3 / 2; - else if (add_bits < 0) - add_bits = 0; - - targ_bits[gr][ch] += add_bits; - } - if (targ_bits[gr][ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL) { - targ_bits[gr][ch] = LameInternalFlags.MAX_BITS_PER_CHANNEL; - } - sum += targ_bits[gr][ch]; - } - /* for ch */ - if (sum > LameInternalFlags.MAX_BITS_PER_GRANULE) { - for (ch = 0; ch < gfc.channels_out; ++ch) { - targ_bits[gr][ch] *= LameInternalFlags.MAX_BITS_PER_GRANULE; - targ_bits[gr][ch] /= sum; - } - } - } - /* for gr */ - - if (gfc.mode_ext == Encoder.MPG_MD_MS_LR) - for (gr = 0; gr < gfc.mode_gr; gr++) { - qupvt.reduce_side(targ_bits[gr], ms_ener_ratio[gr], mean_bits - * gfc.channels_out, - LameInternalFlags.MAX_BITS_PER_GRANULE); - } - - /* - * sum target bits - */ - totbits = 0; - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - if (targ_bits[gr][ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL) - targ_bits[gr][ch] = LameInternalFlags.MAX_BITS_PER_CHANNEL; - totbits += targ_bits[gr][ch]; - } - } - - /* - * repartion target bits if needed - */ - if (totbits > max_frame_bits[0]) { - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - targ_bits[gr][ch] *= max_frame_bits[0]; - targ_bits[gr][ch] /= totbits; - } - } - } - } - -} - -/* - * MP3 window subband -> subband filtering -> mdct routine - * - * Copyright (c) 1999-2000 Takehiro Tominaga - * - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -/* - * Special Thanks to Patrick De Smet for your advices. - */ - -/* $Id: NewMDCT.java,v 1.11 2011/05/24 20:48:06 kenchis Exp $ */ - -//package mp3; - -//import java.util.Arrays; - - - -function NewMDCT() { - - var enwindow = [ - -4.77e-07 * 0.740951125354959 / 2.384e-06, - 1.03951e-04 * 0.740951125354959 / 2.384e-06, - 9.53674e-04 * 0.740951125354959 / 2.384e-06, - 2.841473e-03 * 0.740951125354959 / 2.384e-06, - 3.5758972e-02 * 0.740951125354959 / 2.384e-06, - 3.401756e-03 * 0.740951125354959 / 2.384e-06, - 9.83715e-04 * 0.740951125354959 / 2.384e-06, - 9.9182e-05 * 0.740951125354959 / 2.384e-06, /* 15 */ - 1.2398e-05 * 0.740951125354959 / 2.384e-06, - 1.91212e-04 * 0.740951125354959 / 2.384e-06, - 2.283096e-03 * 0.740951125354959 / 2.384e-06, - 1.6994476e-02 * 0.740951125354959 / 2.384e-06, - -1.8756866e-02 * 0.740951125354959 / 2.384e-06, - -2.630711e-03 * 0.740951125354959 / 2.384e-06, - -2.47478e-04 * 0.740951125354959 / 2.384e-06, - -1.4782e-05 * 0.740951125354959 / 2.384e-06, - 9.063471690191471e-01, 1.960342806591213e-01, - - -4.77e-07 * 0.773010453362737 / 2.384e-06, - 1.05858e-04 * 0.773010453362737 / 2.384e-06, - 9.30786e-04 * 0.773010453362737 / 2.384e-06, - 2.521515e-03 * 0.773010453362737 / 2.384e-06, - 3.5694122e-02 * 0.773010453362737 / 2.384e-06, - 3.643036e-03 * 0.773010453362737 / 2.384e-06, - 9.91821e-04 * 0.773010453362737 / 2.384e-06, - 9.6321e-05 * 0.773010453362737 / 2.384e-06, /* 14 */ - 1.1444e-05 * 0.773010453362737 / 2.384e-06, - 1.65462e-04 * 0.773010453362737 / 2.384e-06, - 2.110004e-03 * 0.773010453362737 / 2.384e-06, - 1.6112804e-02 * 0.773010453362737 / 2.384e-06, - -1.9634247e-02 * 0.773010453362737 / 2.384e-06, - -2.803326e-03 * 0.773010453362737 / 2.384e-06, - -2.77042e-04 * 0.773010453362737 / 2.384e-06, - -1.6689e-05 * 0.773010453362737 / 2.384e-06, - 8.206787908286602e-01, 3.901806440322567e-01, - - -4.77e-07 * 0.803207531480645 / 2.384e-06, - 1.07288e-04 * 0.803207531480645 / 2.384e-06, - 9.02653e-04 * 0.803207531480645 / 2.384e-06, - 2.174854e-03 * 0.803207531480645 / 2.384e-06, - 3.5586357e-02 * 0.803207531480645 / 2.384e-06, - 3.858566e-03 * 0.803207531480645 / 2.384e-06, - 9.95159e-04 * 0.803207531480645 / 2.384e-06, - 9.3460e-05 * 0.803207531480645 / 2.384e-06, /* 13 */ - 1.0014e-05 * 0.803207531480645 / 2.384e-06, - 1.40190e-04 * 0.803207531480645 / 2.384e-06, - 1.937389e-03 * 0.803207531480645 / 2.384e-06, - 1.5233517e-02 * 0.803207531480645 / 2.384e-06, - -2.0506859e-02 * 0.803207531480645 / 2.384e-06, - -2.974033e-03 * 0.803207531480645 / 2.384e-06, - -3.07560e-04 * 0.803207531480645 / 2.384e-06, - -1.8120e-05 * 0.803207531480645 / 2.384e-06, - 7.416505462720353e-01, 5.805693545089249e-01, - - -4.77e-07 * 0.831469612302545 / 2.384e-06, - 1.08242e-04 * 0.831469612302545 / 2.384e-06, - 8.68797e-04 * 0.831469612302545 / 2.384e-06, - 1.800537e-03 * 0.831469612302545 / 2.384e-06, - 3.5435200e-02 * 0.831469612302545 / 2.384e-06, - 4.049301e-03 * 0.831469612302545 / 2.384e-06, - 9.94205e-04 * 0.831469612302545 / 2.384e-06, - 9.0599e-05 * 0.831469612302545 / 2.384e-06, /* 12 */ - 9.060e-06 * 0.831469612302545 / 2.384e-06, - 1.16348e-04 * 0.831469612302545 / 2.384e-06, - 1.766682e-03 * 0.831469612302545 / 2.384e-06, - 1.4358521e-02 * 0.831469612302545 / 2.384e-06, - -2.1372318e-02 * 0.831469612302545 / 2.384e-06, - -3.14188e-03 * 0.831469612302545 / 2.384e-06, - -3.39031e-04 * 0.831469612302545 / 2.384e-06, - -1.9550e-05 * 0.831469612302545 / 2.384e-06, - 6.681786379192989e-01, 7.653668647301797e-01, - - -4.77e-07 * 0.857728610000272 / 2.384e-06, - 1.08719e-04 * 0.857728610000272 / 2.384e-06, - 8.29220e-04 * 0.857728610000272 / 2.384e-06, - 1.399517e-03 * 0.857728610000272 / 2.384e-06, - 3.5242081e-02 * 0.857728610000272 / 2.384e-06, - 4.215240e-03 * 0.857728610000272 / 2.384e-06, - 9.89437e-04 * 0.857728610000272 / 2.384e-06, - 8.7261e-05 * 0.857728610000272 / 2.384e-06, /* 11 */ - 8.106e-06 * 0.857728610000272 / 2.384e-06, - 9.3937e-05 * 0.857728610000272 / 2.384e-06, - 1.597881e-03 * 0.857728610000272 / 2.384e-06, - 1.3489246e-02 * 0.857728610000272 / 2.384e-06, - -2.2228718e-02 * 0.857728610000272 / 2.384e-06, - -3.306866e-03 * 0.857728610000272 / 2.384e-06, - -3.71456e-04 * 0.857728610000272 / 2.384e-06, - -2.1458e-05 * 0.857728610000272 / 2.384e-06, - 5.993769336819237e-01, 9.427934736519954e-01, - - -4.77e-07 * 0.881921264348355 / 2.384e-06, - 1.08719e-04 * 0.881921264348355 / 2.384e-06, - 7.8392e-04 * 0.881921264348355 / 2.384e-06, - 9.71317e-04 * 0.881921264348355 / 2.384e-06, - 3.5007000e-02 * 0.881921264348355 / 2.384e-06, - 4.357815e-03 * 0.881921264348355 / 2.384e-06, - 9.80854e-04 * 0.881921264348355 / 2.384e-06, - 8.3923e-05 * 0.881921264348355 / 2.384e-06, /* 10 */ - 7.629e-06 * 0.881921264348355 / 2.384e-06, - 7.2956e-05 * 0.881921264348355 / 2.384e-06, - 1.432419e-03 * 0.881921264348355 / 2.384e-06, - 1.2627602e-02 * 0.881921264348355 / 2.384e-06, - -2.3074150e-02 * 0.881921264348355 / 2.384e-06, - -3.467083e-03 * 0.881921264348355 / 2.384e-06, - -4.04358e-04 * 0.881921264348355 / 2.384e-06, - -2.3365e-05 * 0.881921264348355 / 2.384e-06, - 5.345111359507916e-01, 1.111140466039205e+00, - - -9.54e-07 * 0.903989293123443 / 2.384e-06, - 1.08242e-04 * 0.903989293123443 / 2.384e-06, - 7.31945e-04 * 0.903989293123443 / 2.384e-06, - 5.15938e-04 * 0.903989293123443 / 2.384e-06, - 3.4730434e-02 * 0.903989293123443 / 2.384e-06, - 4.477024e-03 * 0.903989293123443 / 2.384e-06, - 9.68933e-04 * 0.903989293123443 / 2.384e-06, - 8.0585e-05 * 0.903989293123443 / 2.384e-06, /* 9 */ - 6.676e-06 * 0.903989293123443 / 2.384e-06, - 5.2929e-05 * 0.903989293123443 / 2.384e-06, - 1.269817e-03 * 0.903989293123443 / 2.384e-06, - 1.1775017e-02 * 0.903989293123443 / 2.384e-06, - -2.3907185e-02 * 0.903989293123443 / 2.384e-06, - -3.622532e-03 * 0.903989293123443 / 2.384e-06, - -4.38213e-04 * 0.903989293123443 / 2.384e-06, - -2.5272e-05 * 0.903989293123443 / 2.384e-06, - 4.729647758913199e-01, 1.268786568327291e+00, - - -9.54e-07 * 0.92387953251128675613 / 2.384e-06, - 1.06812e-04 * 0.92387953251128675613 / 2.384e-06, - 6.74248e-04 * 0.92387953251128675613 / 2.384e-06, - 3.3379e-05 * 0.92387953251128675613 / 2.384e-06, - 3.4412861e-02 * 0.92387953251128675613 / 2.384e-06, - 4.573822e-03 * 0.92387953251128675613 / 2.384e-06, - 9.54151e-04 * 0.92387953251128675613 / 2.384e-06, - 7.6771e-05 * 0.92387953251128675613 / 2.384e-06, - 6.199e-06 * 0.92387953251128675613 / 2.384e-06, - 3.4332e-05 * 0.92387953251128675613 / 2.384e-06, - 1.111031e-03 * 0.92387953251128675613 / 2.384e-06, - 1.0933399e-02 * 0.92387953251128675613 / 2.384e-06, - -2.4725437e-02 * 0.92387953251128675613 / 2.384e-06, - -3.771782e-03 * 0.92387953251128675613 / 2.384e-06, - -4.72546e-04 * 0.92387953251128675613 / 2.384e-06, - -2.7657e-05 * 0.92387953251128675613 / 2.384e-06, - 4.1421356237309504879e-01, /* tan(PI/8) */ - 1.414213562373095e+00, - - -9.54e-07 * 0.941544065183021 / 2.384e-06, - 1.05381e-04 * 0.941544065183021 / 2.384e-06, - 6.10352e-04 * 0.941544065183021 / 2.384e-06, - -4.75883e-04 * 0.941544065183021 / 2.384e-06, - 3.4055710e-02 * 0.941544065183021 / 2.384e-06, - 4.649162e-03 * 0.941544065183021 / 2.384e-06, - 9.35555e-04 * 0.941544065183021 / 2.384e-06, - 7.3433e-05 * 0.941544065183021 / 2.384e-06, /* 7 */ - 5.245e-06 * 0.941544065183021 / 2.384e-06, - 1.7166e-05 * 0.941544065183021 / 2.384e-06, - 9.56535e-04 * 0.941544065183021 / 2.384e-06, - 1.0103703e-02 * 0.941544065183021 / 2.384e-06, - -2.5527000e-02 * 0.941544065183021 / 2.384e-06, - -3.914356e-03 * 0.941544065183021 / 2.384e-06, - -5.07355e-04 * 0.941544065183021 / 2.384e-06, - -3.0041e-05 * 0.941544065183021 / 2.384e-06, - 3.578057213145241e-01, 1.546020906725474e+00, - - -9.54e-07 * 0.956940335732209 / 2.384e-06, - 1.02520e-04 * 0.956940335732209 / 2.384e-06, - 5.39303e-04 * 0.956940335732209 / 2.384e-06, - -1.011848e-03 * 0.956940335732209 / 2.384e-06, - 3.3659935e-02 * 0.956940335732209 / 2.384e-06, - 4.703045e-03 * 0.956940335732209 / 2.384e-06, - 9.15051e-04 * 0.956940335732209 / 2.384e-06, - 7.0095e-05 * 0.956940335732209 / 2.384e-06, /* 6 */ - 4.768e-06 * 0.956940335732209 / 2.384e-06, - 9.54e-07 * 0.956940335732209 / 2.384e-06, - 8.06808e-04 * 0.956940335732209 / 2.384e-06, - 9.287834e-03 * 0.956940335732209 / 2.384e-06, - -2.6310921e-02 * 0.956940335732209 / 2.384e-06, - -4.048824e-03 * 0.956940335732209 / 2.384e-06, - -5.42164e-04 * 0.956940335732209 / 2.384e-06, - -3.2425e-05 * 0.956940335732209 / 2.384e-06, - 3.033466836073424e-01, 1.662939224605090e+00, - - -1.431e-06 * 0.970031253194544 / 2.384e-06, - 9.9182e-05 * 0.970031253194544 / 2.384e-06, - 4.62532e-04 * 0.970031253194544 / 2.384e-06, - -1.573563e-03 * 0.970031253194544 / 2.384e-06, - 3.3225536e-02 * 0.970031253194544 / 2.384e-06, - 4.737377e-03 * 0.970031253194544 / 2.384e-06, - 8.91685e-04 * 0.970031253194544 / 2.384e-06, - 6.6280e-05 * 0.970031253194544 / 2.384e-06, /* 5 */ - 4.292e-06 * 0.970031253194544 / 2.384e-06, - -1.3828e-05 * 0.970031253194544 / 2.384e-06, - 6.61850e-04 * 0.970031253194544 / 2.384e-06, - 8.487225e-03 * 0.970031253194544 / 2.384e-06, - -2.7073860e-02 * 0.970031253194544 / 2.384e-06, - -4.174709e-03 * 0.970031253194544 / 2.384e-06, - -5.76973e-04 * 0.970031253194544 / 2.384e-06, - -3.4809e-05 * 0.970031253194544 / 2.384e-06, - 2.504869601913055e-01, 1.763842528696710e+00, - - -1.431e-06 * 0.98078528040323 / 2.384e-06, - 9.5367e-05 * 0.98078528040323 / 2.384e-06, - 3.78609e-04 * 0.98078528040323 / 2.384e-06, - -2.161503e-03 * 0.98078528040323 / 2.384e-06, - 3.2754898e-02 * 0.98078528040323 / 2.384e-06, - 4.752159e-03 * 0.98078528040323 / 2.384e-06, - 8.66413e-04 * 0.98078528040323 / 2.384e-06, - 6.2943e-05 * 0.98078528040323 / 2.384e-06, /* 4 */ - 3.815e-06 * 0.98078528040323 / 2.384e-06, - -2.718e-05 * 0.98078528040323 / 2.384e-06, - 5.22137e-04 * 0.98078528040323 / 2.384e-06, - 7.703304e-03 * 0.98078528040323 / 2.384e-06, - -2.7815342e-02 * 0.98078528040323 / 2.384e-06, - -4.290581e-03 * 0.98078528040323 / 2.384e-06, - -6.11782e-04 * 0.98078528040323 / 2.384e-06, - -3.7670e-05 * 0.98078528040323 / 2.384e-06, - 1.989123673796580e-01, 1.847759065022573e+00, - - -1.907e-06 * 0.989176509964781 / 2.384e-06, - 9.0122e-05 * 0.989176509964781 / 2.384e-06, - 2.88486e-04 * 0.989176509964781 / 2.384e-06, - -2.774239e-03 * 0.989176509964781 / 2.384e-06, - 3.2248020e-02 * 0.989176509964781 / 2.384e-06, - 4.748821e-03 * 0.989176509964781 / 2.384e-06, - 8.38757e-04 * 0.989176509964781 / 2.384e-06, - 5.9605e-05 * 0.989176509964781 / 2.384e-06, /* 3 */ - 3.338e-06 * 0.989176509964781 / 2.384e-06, - -3.9577e-05 * 0.989176509964781 / 2.384e-06, - 3.88145e-04 * 0.989176509964781 / 2.384e-06, - 6.937027e-03 * 0.989176509964781 / 2.384e-06, - -2.8532982e-02 * 0.989176509964781 / 2.384e-06, - -4.395962e-03 * 0.989176509964781 / 2.384e-06, - -6.46591e-04 * 0.989176509964781 / 2.384e-06, - -4.0531e-05 * 0.989176509964781 / 2.384e-06, - 1.483359875383474e-01, 1.913880671464418e+00, - - -1.907e-06 * 0.995184726672197 / 2.384e-06, - 8.4400e-05 * 0.995184726672197 / 2.384e-06, - 1.91689e-04 * 0.995184726672197 / 2.384e-06, - -3.411293e-03 * 0.995184726672197 / 2.384e-06, - 3.1706810e-02 * 0.995184726672197 / 2.384e-06, - 4.728317e-03 * 0.995184726672197 / 2.384e-06, - 8.09669e-04 * 0.995184726672197 / 2.384e-06, - 5.579e-05 * 0.995184726672197 / 2.384e-06, - 3.338e-06 * 0.995184726672197 / 2.384e-06, - -5.0545e-05 * 0.995184726672197 / 2.384e-06, - 2.59876e-04 * 0.995184726672197 / 2.384e-06, - 6.189346e-03 * 0.995184726672197 / 2.384e-06, - -2.9224873e-02 * 0.995184726672197 / 2.384e-06, - -4.489899e-03 * 0.995184726672197 / 2.384e-06, - -6.80923e-04 * 0.995184726672197 / 2.384e-06, - -4.3392e-05 * 0.995184726672197 / 2.384e-06, - 9.849140335716425e-02, 1.961570560806461e+00, - - -2.384e-06 * 0.998795456205172 / 2.384e-06, - 7.7724e-05 * 0.998795456205172 / 2.384e-06, - 8.8215e-05 * 0.998795456205172 / 2.384e-06, - -4.072189e-03 * 0.998795456205172 / 2.384e-06, - 3.1132698e-02 * 0.998795456205172 / 2.384e-06, - 4.691124e-03 * 0.998795456205172 / 2.384e-06, - 7.79152e-04 * 0.998795456205172 / 2.384e-06, - 5.2929e-05 * 0.998795456205172 / 2.384e-06, - 2.861e-06 * 0.998795456205172 / 2.384e-06, - -6.0558e-05 * 0.998795456205172 / 2.384e-06, - 1.37329e-04 * 0.998795456205172 / 2.384e-06, - 5.462170e-03 * 0.998795456205172 / 2.384e-06, - -2.9890060e-02 * 0.998795456205172 / 2.384e-06, - -4.570484e-03 * 0.998795456205172 / 2.384e-06, - -7.14302e-04 * 0.998795456205172 / 2.384e-06, - -4.6253e-05 * 0.998795456205172 / 2.384e-06, - 4.912684976946725e-02, 1.990369453344394e+00, - - 3.5780907e-02 * Util.SQRT2 * 0.5 / 2.384e-06, - 1.7876148e-02 * Util.SQRT2 * 0.5 / 2.384e-06, - 3.134727e-03 * Util.SQRT2 * 0.5 / 2.384e-06, - 2.457142e-03 * Util.SQRT2 * 0.5 / 2.384e-06, - 9.71317e-04 * Util.SQRT2 * 0.5 / 2.384e-06, - 2.18868e-04 * Util.SQRT2 * 0.5 / 2.384e-06, - 1.01566e-04 * Util.SQRT2 * 0.5 / 2.384e-06, - 1.3828e-05 * Util.SQRT2 * 0.5 / 2.384e-06, - - 3.0526638e-02 / 2.384e-06, 4.638195e-03 / 2.384e-06, - 7.47204e-04 / 2.384e-06, 4.9591e-05 / 2.384e-06, - 4.756451e-03 / 2.384e-06, 2.1458e-05 / 2.384e-06, - -6.9618e-05 / 2.384e-06, /* 2.384e-06/2.384e-06 */ - ]; - - var NS = 12; - var NL = 36; - - var win = [ - [ - 2.382191739347913e-13, - 6.423305872147834e-13, - 9.400849094049688e-13, - 1.122435026096556e-12, - 1.183840321267481e-12, - 1.122435026096556e-12, - 9.400849094049690e-13, - 6.423305872147839e-13, - 2.382191739347918e-13, - - 5.456116108943412e-12, - 4.878985199565852e-12, - 4.240448995017367e-12, - 3.559909094758252e-12, - 2.858043359288075e-12, - 2.156177623817898e-12, - 1.475637723558783e-12, - 8.371015190102974e-13, - 2.599706096327376e-13, - - -5.456116108943412e-12, - -4.878985199565852e-12, - -4.240448995017367e-12, - -3.559909094758252e-12, - -2.858043359288076e-12, - -2.156177623817898e-12, - -1.475637723558783e-12, - -8.371015190102975e-13, - -2.599706096327376e-13, - - -2.382191739347923e-13, - -6.423305872147843e-13, - -9.400849094049696e-13, - -1.122435026096556e-12, - -1.183840321267481e-12, - -1.122435026096556e-12, - -9.400849094049694e-13, - -6.423305872147840e-13, - -2.382191739347918e-13, - ], - [ - 2.382191739347913e-13, - 6.423305872147834e-13, - 9.400849094049688e-13, - 1.122435026096556e-12, - 1.183840321267481e-12, - 1.122435026096556e-12, - 9.400849094049688e-13, - 6.423305872147841e-13, - 2.382191739347918e-13, - - 5.456116108943413e-12, - 4.878985199565852e-12, - 4.240448995017367e-12, - 3.559909094758253e-12, - 2.858043359288075e-12, - 2.156177623817898e-12, - 1.475637723558782e-12, - 8.371015190102975e-13, - 2.599706096327376e-13, - - -5.461314069809755e-12, - -4.921085770524055e-12, - -4.343405037091838e-12, - -3.732668368707687e-12, - -3.093523840190885e-12, - -2.430835727329465e-12, - -1.734679010007751e-12, - -9.748253656609281e-13, - -2.797435120168326e-13, - - 0.000000000000000e+00, - 0.000000000000000e+00, - 0.000000000000000e+00, - 0.000000000000000e+00, - 0.000000000000000e+00, - 0.000000000000000e+00, - -2.283748241799531e-13, - -4.037858874020686e-13, - -2.146547464825323e-13, - ], - [ - 1.316524975873958e-01, /* win[SHORT_TYPE] */ - 4.142135623730950e-01, - 7.673269879789602e-01, - - 1.091308501069271e+00, /* tantab_l */ - 1.303225372841206e+00, - 1.569685577117490e+00, - 1.920982126971166e+00, - 2.414213562373094e+00, - 3.171594802363212e+00, - 4.510708503662055e+00, - 7.595754112725146e+00, - 2.290376554843115e+01, - - 0.98480775301220802032, /* cx */ - 0.64278760968653936292, - 0.34202014332566882393, - 0.93969262078590842791, - -0.17364817766693030343, - -0.76604444311897790243, - 0.86602540378443870761, - 0.500000000000000e+00, - - -5.144957554275265e-01, /* ca */ - -4.717319685649723e-01, - -3.133774542039019e-01, - -1.819131996109812e-01, - -9.457419252642064e-02, - -4.096558288530405e-02, - -1.419856857247115e-02, - -3.699974673760037e-03, - - 8.574929257125442e-01, /* cs */ - 8.817419973177052e-01, - 9.496286491027329e-01, - 9.833145924917901e-01, - 9.955178160675857e-01, - 9.991605581781475e-01, - 9.998991952444470e-01, - 9.999931550702802e-01, - ], - [ - 0.000000000000000e+00, - 0.000000000000000e+00, - 0.000000000000000e+00, - 0.000000000000000e+00, - 0.000000000000000e+00, - 0.000000000000000e+00, - 2.283748241799531e-13, - 4.037858874020686e-13, - 2.146547464825323e-13, - - 5.461314069809755e-12, - 4.921085770524055e-12, - 4.343405037091838e-12, - 3.732668368707687e-12, - 3.093523840190885e-12, - 2.430835727329466e-12, - 1.734679010007751e-12, - 9.748253656609281e-13, - 2.797435120168326e-13, - - -5.456116108943413e-12, - -4.878985199565852e-12, - -4.240448995017367e-12, - -3.559909094758253e-12, - -2.858043359288075e-12, - -2.156177623817898e-12, - -1.475637723558782e-12, - -8.371015190102975e-13, - -2.599706096327376e-13, - - -2.382191739347913e-13, - -6.423305872147834e-13, - -9.400849094049688e-13, - -1.122435026096556e-12, - -1.183840321267481e-12, - -1.122435026096556e-12, - -9.400849094049688e-13, - -6.423305872147841e-13, - -2.382191739347918e-13, - ] - ]; - - var tantab_l = win[Encoder.SHORT_TYPE]; - var cx = win[Encoder.SHORT_TYPE]; - var ca = win[Encoder.SHORT_TYPE]; - var cs = win[Encoder.SHORT_TYPE]; - - /** - * new IDCT routine written by Takehiro TOMINAGA - * - * PURPOSE: Overlapping window on PCM samples
- * - * SEMANTICS:
- * 32 16-bit pcm samples are scaled to fractional 2's complement and - * concatenated to the end of the window buffer #x#. The updated window - * buffer #x# is then windowed by the analysis window #c# to produce the - * windowed sample #z# - */ - var order = [ - 0, 1, 16, 17, 8, 9, 24, 25, 4, 5, 20, 21, 12, 13, 28, 29, - 2, 3, 18, 19, 10, 11, 26, 27, 6, 7, 22, 23, 14, 15, 30, 31 - ]; - - /** - * returns sum_j=0^31 a[j]*cos(PI*j*(k+1/2)/32), 0<=k<32 - */ - function window_subband(x1, x1Pos, a) { - var wp = 10; - - var x2 = x1Pos + 238 - 14 - 286; - - for (var i = -15; i < 0; i++) { - var w, s, t; - - w = enwindow[wp + -10]; - s = x1[x2 + -224] * w; - t = x1[x1Pos + 224] * w; - w = enwindow[wp + -9]; - s += x1[x2 + -160] * w; - t += x1[x1Pos + 160] * w; - w = enwindow[wp + -8]; - s += x1[x2 + -96] * w; - t += x1[x1Pos + 96] * w; - w = enwindow[wp + -7]; - s += x1[x2 + -32] * w; - t += x1[x1Pos + 32] * w; - w = enwindow[wp + -6]; - s += x1[x2 + 32] * w; - t += x1[x1Pos + -32] * w; - w = enwindow[wp + -5]; - s += x1[x2 + 96] * w; - t += x1[x1Pos + -96] * w; - w = enwindow[wp + -4]; - s += x1[x2 + 160] * w; - t += x1[x1Pos + -160] * w; - w = enwindow[wp + -3]; - s += x1[x2 + 224] * w; - t += x1[x1Pos + -224] * w; - - w = enwindow[wp + -2]; - s += x1[x1Pos + -256] * w; - t -= x1[x2 + 256] * w; - w = enwindow[wp + -1]; - s += x1[x1Pos + -192] * w; - t -= x1[x2 + 192] * w; - w = enwindow[wp + 0]; - s += x1[x1Pos + -128] * w; - t -= x1[x2 + 128] * w; - w = enwindow[wp + 1]; - s += x1[x1Pos + -64] * w; - t -= x1[x2 + 64] * w; - w = enwindow[wp + 2]; - s += x1[x1Pos + 0] * w; - t -= x1[x2 + 0] * w; - w = enwindow[wp + 3]; - s += x1[x1Pos + 64] * w; - t -= x1[x2 + -64] * w; - w = enwindow[wp + 4]; - s += x1[x1Pos + 128] * w; - t -= x1[x2 + -128] * w; - w = enwindow[wp + 5]; - s += x1[x1Pos + 192] * w; - t -= x1[x2 + -192] * w; - - /* - * this multiplyer could be removed, but it needs more 256 FLOAT - * data. thinking about the data cache performance, I think we - * should not use such a huge table. tt 2000/Oct/25 - */ - s *= enwindow[wp + 6]; - w = t - s; - a[30 + i * 2] = t + s; - a[31 + i * 2] = enwindow[wp + 7] * w; - wp += 18; - x1Pos--; - x2++; - } - { - var s, t, u, v; - t = x1[x1Pos + -16] * enwindow[wp + -10]; - s = x1[x1Pos + -32] * enwindow[wp + -2]; - t += (x1[x1Pos + -48] - x1[x1Pos + 16]) * enwindow[wp + -9]; - s += x1[x1Pos + -96] * enwindow[wp + -1]; - t += (x1[x1Pos + -80] + x1[x1Pos + 48]) * enwindow[wp + -8]; - s += x1[x1Pos + -160] * enwindow[wp + 0]; - t += (x1[x1Pos + -112] - x1[x1Pos + 80]) * enwindow[wp + -7]; - s += x1[x1Pos + -224] * enwindow[wp + 1]; - t += (x1[x1Pos + -144] + x1[x1Pos + 112]) * enwindow[wp + -6]; - s -= x1[x1Pos + 32] * enwindow[wp + 2]; - t += (x1[x1Pos + -176] - x1[x1Pos + 144]) * enwindow[wp + -5]; - s -= x1[x1Pos + 96] * enwindow[wp + 3]; - t += (x1[x1Pos + -208] + x1[x1Pos + 176]) * enwindow[wp + -4]; - s -= x1[x1Pos + 160] * enwindow[wp + 4]; - t += (x1[x1Pos + -240] - x1[x1Pos + 208]) * enwindow[wp + -3]; - s -= x1[x1Pos + 224]; - - u = s - t; - v = s + t; - - t = a[14]; - s = a[15] - t; - - a[31] = v + t; /* A0 */ - a[30] = u + s; /* A1 */ - a[15] = u - s; /* A2 */ - a[14] = v - t; /* A3 */ - } - { - var xr; - xr = a[28] - a[0]; - a[0] += a[28]; - a[28] = xr * enwindow[wp + -2 * 18 + 7]; - xr = a[29] - a[1]; - a[1] += a[29]; - a[29] = xr * enwindow[wp + -2 * 18 + 7]; - - xr = a[26] - a[2]; - a[2] += a[26]; - a[26] = xr * enwindow[wp + -4 * 18 + 7]; - xr = a[27] - a[3]; - a[3] += a[27]; - a[27] = xr * enwindow[wp + -4 * 18 + 7]; - - xr = a[24] - a[4]; - a[4] += a[24]; - a[24] = xr * enwindow[wp + -6 * 18 + 7]; - xr = a[25] - a[5]; - a[5] += a[25]; - a[25] = xr * enwindow[wp + -6 * 18 + 7]; - - xr = a[22] - a[6]; - a[6] += a[22]; - a[22] = xr * Util.SQRT2; - xr = a[23] - a[7]; - a[7] += a[23]; - a[23] = xr * Util.SQRT2 - a[7]; - a[7] -= a[6]; - a[22] -= a[7]; - a[23] -= a[22]; - - xr = a[6]; - a[6] = a[31] - xr; - a[31] = a[31] + xr; - xr = a[7]; - a[7] = a[30] - xr; - a[30] = a[30] + xr; - xr = a[22]; - a[22] = a[15] - xr; - a[15] = a[15] + xr; - xr = a[23]; - a[23] = a[14] - xr; - a[14] = a[14] + xr; - - xr = a[20] - a[8]; - a[8] += a[20]; - a[20] = xr * enwindow[wp + -10 * 18 + 7]; - xr = a[21] - a[9]; - a[9] += a[21]; - a[21] = xr * enwindow[wp + -10 * 18 + 7]; - - xr = a[18] - a[10]; - a[10] += a[18]; - a[18] = xr * enwindow[wp + -12 * 18 + 7]; - xr = a[19] - a[11]; - a[11] += a[19]; - a[19] = xr * enwindow[wp + -12 * 18 + 7]; - - xr = a[16] - a[12]; - a[12] += a[16]; - a[16] = xr * enwindow[wp + -14 * 18 + 7]; - xr = a[17] - a[13]; - a[13] += a[17]; - a[17] = xr * enwindow[wp + -14 * 18 + 7]; - - xr = -a[20] + a[24]; - a[20] += a[24]; - a[24] = xr * enwindow[wp + -12 * 18 + 7]; - xr = -a[21] + a[25]; - a[21] += a[25]; - a[25] = xr * enwindow[wp + -12 * 18 + 7]; - - xr = a[4] - a[8]; - a[4] += a[8]; - a[8] = xr * enwindow[wp + -12 * 18 + 7]; - xr = a[5] - a[9]; - a[5] += a[9]; - a[9] = xr * enwindow[wp + -12 * 18 + 7]; - - xr = a[0] - a[12]; - a[0] += a[12]; - a[12] = xr * enwindow[wp + -4 * 18 + 7]; - xr = a[1] - a[13]; - a[1] += a[13]; - a[13] = xr * enwindow[wp + -4 * 18 + 7]; - xr = a[16] - a[28]; - a[16] += a[28]; - a[28] = xr * enwindow[wp + -4 * 18 + 7]; - xr = -a[17] + a[29]; - a[17] += a[29]; - a[29] = xr * enwindow[wp + -4 * 18 + 7]; - - xr = Util.SQRT2 * (a[2] - a[10]); - a[2] += a[10]; - a[10] = xr; - xr = Util.SQRT2 * (a[3] - a[11]); - a[3] += a[11]; - a[11] = xr; - xr = Util.SQRT2 * (-a[18] + a[26]); - a[18] += a[26]; - a[26] = xr - a[18]; - xr = Util.SQRT2 * (-a[19] + a[27]); - a[19] += a[27]; - a[27] = xr - a[19]; - - xr = a[2]; - a[19] -= a[3]; - a[3] -= xr; - a[2] = a[31] - xr; - a[31] += xr; - xr = a[3]; - a[11] -= a[19]; - a[18] -= xr; - a[3] = a[30] - xr; - a[30] += xr; - xr = a[18]; - a[27] -= a[11]; - a[19] -= xr; - a[18] = a[15] - xr; - a[15] += xr; - - xr = a[19]; - a[10] -= xr; - a[19] = a[14] - xr; - a[14] += xr; - xr = a[10]; - a[11] -= xr; - a[10] = a[23] - xr; - a[23] += xr; - xr = a[11]; - a[26] -= xr; - a[11] = a[22] - xr; - a[22] += xr; - xr = a[26]; - a[27] -= xr; - a[26] = a[7] - xr; - a[7] += xr; - - xr = a[27]; - a[27] = a[6] - xr; - a[6] += xr; - - xr = Util.SQRT2 * (a[0] - a[4]); - a[0] += a[4]; - a[4] = xr; - xr = Util.SQRT2 * (a[1] - a[5]); - a[1] += a[5]; - a[5] = xr; - xr = Util.SQRT2 * (a[16] - a[20]); - a[16] += a[20]; - a[20] = xr; - xr = Util.SQRT2 * (a[17] - a[21]); - a[17] += a[21]; - a[21] = xr; - - xr = -Util.SQRT2 * (a[8] - a[12]); - a[8] += a[12]; - a[12] = xr - a[8]; - xr = -Util.SQRT2 * (a[9] - a[13]); - a[9] += a[13]; - a[13] = xr - a[9]; - xr = -Util.SQRT2 * (a[25] - a[29]); - a[25] += a[29]; - a[29] = xr - a[25]; - xr = -Util.SQRT2 * (a[24] + a[28]); - a[24] -= a[28]; - a[28] = xr - a[24]; - - xr = a[24] - a[16]; - a[24] = xr; - xr = a[20] - xr; - a[20] = xr; - xr = a[28] - xr; - a[28] = xr; - - xr = a[25] - a[17]; - a[25] = xr; - xr = a[21] - xr; - a[21] = xr; - xr = a[29] - xr; - a[29] = xr; - - xr = a[17] - a[1]; - a[17] = xr; - xr = a[9] - xr; - a[9] = xr; - xr = a[25] - xr; - a[25] = xr; - xr = a[5] - xr; - a[5] = xr; - xr = a[21] - xr; - a[21] = xr; - xr = a[13] - xr; - a[13] = xr; - xr = a[29] - xr; - a[29] = xr; - - xr = a[1] - a[0]; - a[1] = xr; - xr = a[16] - xr; - a[16] = xr; - xr = a[17] - xr; - a[17] = xr; - xr = a[8] - xr; - a[8] = xr; - xr = a[9] - xr; - a[9] = xr; - xr = a[24] - xr; - a[24] = xr; - xr = a[25] - xr; - a[25] = xr; - xr = a[4] - xr; - a[4] = xr; - xr = a[5] - xr; - a[5] = xr; - xr = a[20] - xr; - a[20] = xr; - xr = a[21] - xr; - a[21] = xr; - xr = a[12] - xr; - a[12] = xr; - xr = a[13] - xr; - a[13] = xr; - xr = a[28] - xr; - a[28] = xr; - xr = a[29] - xr; - a[29] = xr; - - xr = a[0]; - a[0] += a[31]; - a[31] -= xr; - xr = a[1]; - a[1] += a[30]; - a[30] -= xr; - xr = a[16]; - a[16] += a[15]; - a[15] -= xr; - xr = a[17]; - a[17] += a[14]; - a[14] -= xr; - xr = a[8]; - a[8] += a[23]; - a[23] -= xr; - xr = a[9]; - a[9] += a[22]; - a[22] -= xr; - xr = a[24]; - a[24] += a[7]; - a[7] -= xr; - xr = a[25]; - a[25] += a[6]; - a[6] -= xr; - xr = a[4]; - a[4] += a[27]; - a[27] -= xr; - xr = a[5]; - a[5] += a[26]; - a[26] -= xr; - xr = a[20]; - a[20] += a[11]; - a[11] -= xr; - xr = a[21]; - a[21] += a[10]; - a[10] -= xr; - xr = a[12]; - a[12] += a[19]; - a[19] -= xr; - xr = a[13]; - a[13] += a[18]; - a[18] -= xr; - xr = a[28]; - a[28] += a[3]; - a[3] -= xr; - xr = a[29]; - a[29] += a[2]; - a[2] -= xr; - } - } - - /** - * Function: Calculation of the MDCT In the case of long blocks (type 0,1,3) - * there are 36 coefficents in the time domain and 18 in the frequency - * domain.
- * In the case of short blocks (type 2) there are 3 transformations with - * short length. This leads to 12 coefficents in the time and 6 in the - * frequency domain. In this case the results are stored side by side in the - * vector out[]. - * - * New layer3 - */ - function mdct_short(inout, inoutPos) { - for (var l = 0; l < 3; l++) { - var tc0, tc1, tc2, ts0, ts1, ts2; - - ts0 = inout[inoutPos + 2 * 3] * win[Encoder.SHORT_TYPE][0] - - inout[inoutPos + 5 * 3]; - tc0 = inout[inoutPos + 0 * 3] * win[Encoder.SHORT_TYPE][2] - - inout[inoutPos + 3 * 3]; - tc1 = ts0 + tc0; - tc2 = ts0 - tc0; - - ts0 = inout[inoutPos + 5 * 3] * win[Encoder.SHORT_TYPE][0] - + inout[inoutPos + 2 * 3]; - tc0 = inout[inoutPos + 3 * 3] * win[Encoder.SHORT_TYPE][2] - + inout[inoutPos + 0 * 3]; - ts1 = ts0 + tc0; - ts2 = -ts0 + tc0; - - tc0 = (inout[inoutPos + 1 * 3] * win[Encoder.SHORT_TYPE][1] - inout[inoutPos + 4 * 3]) * 2.069978111953089e-11; - /* - * tritab_s [ 1 ] - */ - ts0 = (inout[inoutPos + 4 * 3] * win[Encoder.SHORT_TYPE][1] + inout[inoutPos + 1 * 3]) * 2.069978111953089e-11; - /* - * tritab_s [ 1 ] - */ - inout[inoutPos + 3 * 0] = tc1 * 1.907525191737280e-11 + tc0; - /* - * tritab_s[ 2 ] - */ - inout[inoutPos + 3 * 5] = -ts1 * 1.907525191737280e-11 + ts0; - /* - * tritab_s[0 ] - */ - tc2 = tc2 * 0.86602540378443870761 * 1.907525191737281e-11; - /* - * tritab_s[ 2] - */ - ts1 = ts1 * 0.5 * 1.907525191737281e-11 + ts0; - inout[inoutPos + 3 * 1] = tc2 - ts1; - inout[inoutPos + 3 * 2] = tc2 + ts1; - - tc1 = tc1 * 0.5 * 1.907525191737281e-11 - tc0; - ts2 = ts2 * 0.86602540378443870761 * 1.907525191737281e-11; - /* - * tritab_s[ 0] - */ - inout[inoutPos + 3 * 3] = tc1 + ts2; - inout[inoutPos + 3 * 4] = tc1 - ts2; - - inoutPos++; - } - } - - function mdct_long(out, outPos, _in) { - var ct, st; - { - var tc1, tc2, tc3, tc4, ts5, ts6, ts7, ts8; - /* 1,2, 5,6, 9,10, 13,14, 17 */ - tc1 = _in[17] - _in[9]; - tc3 = _in[15] - _in[11]; - tc4 = _in[14] - _in[12]; - ts5 = _in[0] + _in[8]; - ts6 = _in[1] + _in[7]; - ts7 = _in[2] + _in[6]; - ts8 = _in[3] + _in[5]; - - out[outPos + 17] = (ts5 + ts7 - ts8) - (ts6 - _in[4]); - st = (ts5 + ts7 - ts8) * cx[12 + 7] + (ts6 - _in[4]); - ct = (tc1 - tc3 - tc4) * cx[12 + 6]; - out[outPos + 5] = ct + st; - out[outPos + 6] = ct - st; - - tc2 = (_in[16] - _in[10]) * cx[12 + 6]; - ts6 = ts6 * cx[12 + 7] + _in[4]; - ct = tc1 * cx[12 + 0] + tc2 + tc3 * cx[12 + 1] + tc4 * cx[12 + 2]; - st = -ts5 * cx[12 + 4] + ts6 - ts7 * cx[12 + 5] + ts8 * cx[12 + 3]; - out[outPos + 1] = ct + st; - out[outPos + 2] = ct - st; - - ct = tc1 * cx[12 + 1] - tc2 - tc3 * cx[12 + 2] + tc4 * cx[12 + 0]; - st = -ts5 * cx[12 + 5] + ts6 - ts7 * cx[12 + 3] + ts8 * cx[12 + 4]; - out[outPos + 9] = ct + st; - out[outPos + 10] = ct - st; - - ct = tc1 * cx[12 + 2] - tc2 + tc3 * cx[12 + 0] - tc4 * cx[12 + 1]; - st = ts5 * cx[12 + 3] - ts6 + ts7 * cx[12 + 4] - ts8 * cx[12 + 5]; - out[outPos + 13] = ct + st; - out[outPos + 14] = ct - st; - } - { - var ts1, ts2, ts3, ts4, tc5, tc6, tc7, tc8; - - ts1 = _in[8] - _in[0]; - ts3 = _in[6] - _in[2]; - ts4 = _in[5] - _in[3]; - tc5 = _in[17] + _in[9]; - tc6 = _in[16] + _in[10]; - tc7 = _in[15] + _in[11]; - tc8 = _in[14] + _in[12]; - - out[outPos + 0] = (tc5 + tc7 + tc8) + (tc6 + _in[13]); - ct = (tc5 + tc7 + tc8) * cx[12 + 7] - (tc6 + _in[13]); - st = (ts1 - ts3 + ts4) * cx[12 + 6]; - out[outPos + 11] = ct + st; - out[outPos + 12] = ct - st; - - ts2 = (_in[7] - _in[1]) * cx[12 + 6]; - tc6 = _in[13] - tc6 * cx[12 + 7]; - ct = tc5 * cx[12 + 3] - tc6 + tc7 * cx[12 + 4] + tc8 * cx[12 + 5]; - st = ts1 * cx[12 + 2] + ts2 + ts3 * cx[12 + 0] + ts4 * cx[12 + 1]; - out[outPos + 3] = ct + st; - out[outPos + 4] = ct - st; - - ct = -tc5 * cx[12 + 5] + tc6 - tc7 * cx[12 + 3] - tc8 * cx[12 + 4]; - st = ts1 * cx[12 + 1] + ts2 - ts3 * cx[12 + 2] - ts4 * cx[12 + 0]; - out[outPos + 7] = ct + st; - out[outPos + 8] = ct - st; - - ct = -tc5 * cx[12 + 4] + tc6 - tc7 * cx[12 + 5] - tc8 * cx[12 + 3]; - st = ts1 * cx[12 + 0] - ts2 + ts3 * cx[12 + 1] - ts4 * cx[12 + 2]; - out[outPos + 15] = ct + st; - out[outPos + 16] = ct - st; - } - } - - this.mdct_sub48 = function(gfc, w0, w1) { - var wk = w0; - var wkPos = 286; - /* thinking cache performance, ch->gr loop is better than gr->ch loop */ - for (var ch = 0; ch < gfc.channels_out; ch++) { - for (var gr = 0; gr < gfc.mode_gr; gr++) { - var band; - var gi = (gfc.l3_side.tt[gr][ch]); - var mdct_enc = gi.xr; - var mdct_encPos = 0; - var samp = gfc.sb_sample[ch][1 - gr]; - var sampPos = 0; - - for (var k = 0; k < 18 / 2; k++) { - window_subband(wk, wkPos, samp[sampPos]); - window_subband(wk, wkPos + 32, samp[sampPos + 1]); - sampPos += 2; - wkPos += 64; - /* - * Compensate for inversion in the analysis filter - */ - for (band = 1; band < 32; band += 2) { - samp[sampPos - 1][band] *= -1; - } - } - - /* - * Perform imdct of 18 previous subband samples + 18 current - * subband samples - */ - for (band = 0; band < 32; band++, mdct_encPos += 18) { - var type = gi.block_type; - var band0 = gfc.sb_sample[ch][gr]; - var band1 = gfc.sb_sample[ch][1 - gr]; - if (gi.mixed_block_flag != 0 && band < 2) - type = 0; - if (gfc.amp_filter[band] < 1e-12) { - Arrays.fill(mdct_enc, mdct_encPos + 0, - mdct_encPos + 18, 0); - } else { - if (gfc.amp_filter[band] < 1.0) { - for (var k = 0; k < 18; k++) - band1[k][order[band]] *= gfc.amp_filter[band]; - } - if (type == Encoder.SHORT_TYPE) { - for (var k = -NS / 4; k < 0; k++) { - var w = win[Encoder.SHORT_TYPE][k + 3]; - mdct_enc[mdct_encPos + k * 3 + 9] = band0[9 + k][order[band]] - * w - band0[8 - k][order[band]]; - mdct_enc[mdct_encPos + k * 3 + 18] = band0[14 - k][order[band]] - * w + band0[15 + k][order[band]]; - mdct_enc[mdct_encPos + k * 3 + 10] = band0[15 + k][order[band]] - * w - band0[14 - k][order[band]]; - mdct_enc[mdct_encPos + k * 3 + 19] = band1[2 - k][order[band]] - * w + band1[3 + k][order[band]]; - mdct_enc[mdct_encPos + k * 3 + 11] = band1[3 + k][order[band]] - * w - band1[2 - k][order[band]]; - mdct_enc[mdct_encPos + k * 3 + 20] = band1[8 - k][order[band]] - * w + band1[9 + k][order[band]]; - } - mdct_short(mdct_enc, mdct_encPos); - } else { - var work = new_float(18); - for (var k = -NL / 4; k < 0; k++) { - var a, b; - a = win[type][k + 27] - * band1[k + 9][order[band]] - + win[type][k + 36] - * band1[8 - k][order[band]]; - b = win[type][k + 9] - * band0[k + 9][order[band]] - - win[type][k + 18] - * band0[8 - k][order[band]]; - work[k + 9] = a - b * tantab_l[3 + k + 9]; - work[k + 18] = a * tantab_l[3 + k + 9] + b; - } - - mdct_long(mdct_enc, mdct_encPos, work); - } - } - /* - * Perform aliasing reduction butterfly - */ - if (type != Encoder.SHORT_TYPE && band != 0) { - for (var k = 7; k >= 0; --k) { - var bu, bd; - bu = mdct_enc[mdct_encPos + k] * ca[20 + k] - + mdct_enc[mdct_encPos + -1 - k] - * cs[28 + k]; - bd = mdct_enc[mdct_encPos + k] * cs[28 + k] - - mdct_enc[mdct_encPos + -1 - k] - * ca[20 + k]; - - mdct_enc[mdct_encPos + -1 - k] = bu; - mdct_enc[mdct_encPos + k] = bd; - } - } - } - } - wk = w1; - wkPos = 286; - if (gfc.mode_gr == 1) { - for (var i = 0; i < 18; i++) { - System.arraycopy(gfc.sb_sample[ch][1][i], 0, - gfc.sb_sample[ch][0][i], 0, 32); - } - } - } - } -} - -//package mp3; - - -function III_psy_ratio() { - this.thm = new III_psy_xmin(); - this.en = new III_psy_xmin(); -} - - -/** - * ENCDELAY The encoder delay. - * - * Minimum allowed is MDCTDELAY (see below) - * - * The first 96 samples will be attenuated, so using a value less than 96 - * will result in corrupt data for the first 96-ENCDELAY samples. - * - * suggested: 576 set to 1160 to sync with FhG. - */ -Encoder.ENCDELAY = 576; -/** - * make sure there is at least one complete frame after the last frame - * containing real data - * - * Using a value of 288 would be sufficient for a a very sophisticated - * decoder that can decode granule-by-granule instead of frame by frame. But - * lets not assume this, and assume the decoder will not decode frame N - * unless it also has data for frame N+1 - */ -Encoder.POSTDELAY = 1152; - -/** - * delay of the MDCT used in mdct.c original ISO routines had a delay of - * 528! Takehiro's routines: - */ -Encoder.MDCTDELAY = 48; -Encoder.FFTOFFSET = (224 + Encoder.MDCTDELAY); - -/** - * Most decoders, including the one we use, have a delay of 528 samples. - */ -Encoder.DECDELAY = 528; - -/** - * number of subbands - */ -Encoder.SBLIMIT = 32; - -/** - * parition bands bands - */ -Encoder.CBANDS = 64; - -/** - * number of critical bands/scale factor bands where masking is computed - */ -Encoder.SBPSY_l = 21; -Encoder.SBPSY_s = 12; - -/** - * total number of scalefactor bands encoded - */ -Encoder.SBMAX_l = 22; -Encoder.SBMAX_s = 13; -Encoder.PSFB21 = 6; -Encoder.PSFB12 = 6; - -/** - * FFT sizes - */ -Encoder.BLKSIZE = 1024; -Encoder.HBLKSIZE = (Encoder.BLKSIZE / 2 + 1); -Encoder.BLKSIZE_s = 256; -Encoder.HBLKSIZE_s = (Encoder.BLKSIZE_s / 2 + 1); - -Encoder.NORM_TYPE = 0; -Encoder.START_TYPE = 1; -Encoder.SHORT_TYPE = 2; -Encoder.STOP_TYPE = 3; - -/** - *
- * Mode Extention:
- * When we are in stereo mode, there are 4 possible methods to store these
- * two channels. The stereo modes -m? are using a subset of them.
- *
- *  -ms: MPG_MD_LR_LR
- *  -mj: MPG_MD_LR_LR and MPG_MD_MS_LR
- *  -mf: MPG_MD_MS_LR
- *  -mi: all
- * 
- */ -Encoder.MPG_MD_LR_LR = 0; -Encoder.MPG_MD_LR_I = 1; -Encoder.MPG_MD_MS_LR = 2; -Encoder.MPG_MD_MS_I = 3; - -Encoder.fircoef = [-0.0207887 * 5, -0.0378413 * 5, - -0.0432472 * 5, -0.031183 * 5, 7.79609e-18 * 5, 0.0467745 * 5, - 0.10091 * 5, 0.151365 * 5, 0.187098 * 5]; - -function Encoder() { - - var FFTOFFSET = Encoder.FFTOFFSET; - var MPG_MD_MS_LR = Encoder.MPG_MD_MS_LR; - //BitStream bs; - //PsyModel psy; - //VBRTag vbr; - //QuantizePVT qupvt; - var bs = null; - this.psy = null; - var psy = null; - var vbr = null; - var qupvt = null; - - //public final void setModules(BitStream bs, PsyModel psy, QuantizePVT qupvt, - // VBRTag vbr) { - this.setModules = function (_bs, _psy, _qupvt, _vbr) { - bs = _bs; - this.psy = _psy; - psy = _psy; - vbr = _vbr; - qupvt = _qupvt; - }; - - var newMDCT = new NewMDCT(); - - /*********************************************************************** - * - * encoder and decoder delays - * - ***********************************************************************/ - - /** - *
-     * layer III enc->dec delay:  1056 (1057?)   (observed)
-     * layer  II enc->dec delay:   480  (481?)   (observed)
-     *
-     * polyphase 256-16             (dec or enc)        = 240
-     * mdct      256+32  (9*32)     (dec or enc)        = 288
-     * total:    512+16
-     *
-     * My guess is that delay of polyphase filterbank is actualy 240.5
-     * (there are technical reasons for this, see postings in mp3encoder).
-     * So total Encode+Decode delay = ENCDELAY + 528 + 1
-     * 
- */ - - - /** - * auto-adjust of ATH, useful for low volume Gabriel Bouvigne 3 feb 2001 - * - * modifies some values in gfp.internal_flags.ATH (gfc.ATH) - */ -//private void adjust_ATH(final LameInternalFlags gfc) { - function adjust_ATH(gfc) { - var gr2_max, max_pow; - - if (gfc.ATH.useAdjust == 0) { - gfc.ATH.adjust = 1.0; - /* no adjustment */ - return; - } - - /* jd - 2001 mar 12, 27, jun 30 */ - /* loudness based on equal loudness curve; */ - /* use granule with maximum combined loudness */ - max_pow = gfc.loudness_sq[0][0]; - gr2_max = gfc.loudness_sq[1][0]; - if (gfc.channels_out == 2) { - max_pow += gfc.loudness_sq[0][1]; - gr2_max += gfc.loudness_sq[1][1]; - } else { - max_pow += max_pow; - gr2_max += gr2_max; - } - if (gfc.mode_gr == 2) { - max_pow = Math.max(max_pow, gr2_max); - } - max_pow *= 0.5; - /* max_pow approaches 1.0 for full band noise */ - - /* jd - 2001 mar 31, jun 30 */ - /* user tuning of ATH adjustment region */ - max_pow *= gfc.ATH.aaSensitivityP; - - /* - * adjust ATH depending on range of maximum value - */ - - /* jd - 2001 feb27, mar12,20, jun30, jul22 */ - /* continuous curves based on approximation */ - /* to GB's original values. */ - /* For an increase in approximate loudness, */ - /* set ATH adjust to adjust_limit immediately */ - /* after a delay of one frame. */ - /* For a loudness decrease, reduce ATH adjust */ - /* towards adjust_limit gradually. */ - /* max_pow is a loudness squared or a power. */ - if (max_pow > 0.03125) { /* ((1 - 0.000625)/ 31.98) from curve below */ - if (gfc.ATH.adjust >= 1.0) { - gfc.ATH.adjust = 1.0; - } else { - /* preceding frame has lower ATH adjust; */ - /* ascend only to the preceding adjust_limit */ - /* in case there is leading low volume */ - if (gfc.ATH.adjust < gfc.ATH.adjustLimit) { - gfc.ATH.adjust = gfc.ATH.adjustLimit; - } - } - gfc.ATH.adjustLimit = 1.0; - } else { /* adjustment curve */ - /* about 32 dB maximum adjust (0.000625) */ - var adj_lim_new = 31.98 * max_pow + 0.000625; - if (gfc.ATH.adjust >= adj_lim_new) { /* descend gradually */ - gfc.ATH.adjust *= adj_lim_new * 0.075 + 0.925; - if (gfc.ATH.adjust < adj_lim_new) { /* stop descent */ - gfc.ATH.adjust = adj_lim_new; - } - } else { /* ascend */ - if (gfc.ATH.adjustLimit >= adj_lim_new) { - gfc.ATH.adjust = adj_lim_new; - } else { - /* preceding frame has lower ATH adjust; */ - /* ascend only to the preceding adjust_limit */ - if (gfc.ATH.adjust < gfc.ATH.adjustLimit) { - gfc.ATH.adjust = gfc.ATH.adjustLimit; - } - } - } - gfc.ATH.adjustLimit = adj_lim_new; - } - } - - /** - *
-     *  some simple statistics
-     *
-     *  bitrate index 0: free bitrate . not allowed in VBR mode
-     *  : bitrates, kbps depending on MPEG version
-     *  bitrate index 15: forbidden
-     *
-     *  mode_ext:
-     *  0:  LR
-     *  1:  LR-i
-     *  2:  MS
-     *  3:  MS-i
-     * 
- */ - function updateStats(gfc) { - var gr, ch; - - /* count bitrate indices */ - gfc.bitrate_stereoMode_Hist[gfc.bitrate_index][4]++; - gfc.bitrate_stereoMode_Hist[15][4]++; - - /* count 'em for every mode extension in case of 2 channel encoding */ - if (gfc.channels_out == 2) { - gfc.bitrate_stereoMode_Hist[gfc.bitrate_index][gfc.mode_ext]++; - gfc.bitrate_stereoMode_Hist[15][gfc.mode_ext]++; - } - for (gr = 0; gr < gfc.mode_gr; ++gr) { - for (ch = 0; ch < gfc.channels_out; ++ch) { - var bt = gfc.l3_side.tt[gr][ch].block_type | 0; - if (gfc.l3_side.tt[gr][ch].mixed_block_flag != 0) - bt = 4; - gfc.bitrate_blockType_Hist[gfc.bitrate_index][bt]++; - gfc.bitrate_blockType_Hist[gfc.bitrate_index][5]++; - gfc.bitrate_blockType_Hist[15][bt]++; - gfc.bitrate_blockType_Hist[15][5]++; - } - } - } - - function lame_encode_frame_init(gfp, inbuf) { - var gfc = gfp.internal_flags; - - var ch, gr; - - if (gfc.lame_encode_frame_init == 0) { - /* prime the MDCT/polyphase filterbank with a short block */ - var i, j; - var primebuff0 = new_float(286 + 1152 + 576); - var primebuff1 = new_float(286 + 1152 + 576); - gfc.lame_encode_frame_init = 1; - for (i = 0, j = 0; i < 286 + 576 * (1 + gfc.mode_gr); ++i) { - if (i < 576 * gfc.mode_gr) { - primebuff0[i] = 0; - if (gfc.channels_out == 2) - primebuff1[i] = 0; - } else { - primebuff0[i] = inbuf[0][j]; - if (gfc.channels_out == 2) - primebuff1[i] = inbuf[1][j]; - ++j; - } - } - /* polyphase filtering / mdct */ - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - gfc.l3_side.tt[gr][ch].block_type = Encoder.SHORT_TYPE; - } - } - newMDCT.mdct_sub48(gfc, primebuff0, primebuff1); - - /* check FFT will not use a negative starting offset */ - /* check if we have enough data for FFT */ - /* check if we have enough data for polyphase filterbank */ - } - - } - - /** - *
-     * encodeframe()           Layer 3
-     *
-     * encode a single frame
-     *
-     *
-     *    lame_encode_frame()
-     *
-     *
-     *                           gr 0            gr 1
-     *    inbuf:           |--------------|--------------|--------------|
-     *
-     *
-     *    Polyphase (18 windows, each shifted 32)
-     *    gr 0:
-     *    window1          <----512---.
-     *    window18                 <----512---.
-     *
-     *    gr 1:
-     *    window1                         <----512---.
-     *    window18                                <----512---.
-     *
-     *
-     *
-     *    MDCT output:  |--------------|--------------|--------------|
-     *
-     *    FFT's                    <---------1024---------.
-     *                                             <---------1024-------.
-     *
-     *
-     *
-     *        inbuf = buffer of PCM data size=MP3 framesize
-     *        encoder acts on inbuf[ch][0], but output is delayed by MDCTDELAY
-     *        so the MDCT coefficints are from inbuf[ch][-MDCTDELAY]
-     *
-     *        psy-model FFT has a 1 granule delay, so we feed it data for the
-     *        next granule.
-     *        FFT is centered over granule:  224+576+224
-     *        So FFT starts at:   576-224-MDCTDELAY
-     *
-     *        MPEG2:  FFT ends at:  BLKSIZE+576-224-MDCTDELAY      (1328)
-     *        MPEG1:  FFT ends at:  BLKSIZE+2*576-224-MDCTDELAY    (1904)
-     *
-     *        MPEG2:  polyphase first window:  [0..511]
-     *                          18th window:   [544..1055]          (1056)
-     *        MPEG1:            36th window:   [1120..1631]         (1632)
-     *                data needed:  512+framesize-32
-     *
-     *        A close look newmdct.c shows that the polyphase filterbank
-     *        only uses data from [0..510] for each window.  Perhaps because the window
-     *        used by the filterbank is zero for the last point, so Takehiro's
-     *        code doesn't bother to compute with it.
-     *
-     *        FFT starts at 576-224-MDCTDELAY (304)  = 576-FFTOFFSET
-     *
-     * 
- */ - - - this.lame_encode_mp3_frame = function (gfp, inbuf_l, inbuf_r, mp3buf, mp3bufPos, mp3buf_size) { - var mp3count; - var masking_LR = new_array_n([2, 2]); - /* - * LR masking & - * energy - */ - masking_LR[0][0] = new III_psy_ratio(); - masking_LR[0][1] = new III_psy_ratio(); - masking_LR[1][0] = new III_psy_ratio(); - masking_LR[1][1] = new III_psy_ratio(); - var masking_MS = new_array_n([2, 2]); - /* MS masking & energy */ - masking_MS[0][0] = new III_psy_ratio(); - masking_MS[0][1] = new III_psy_ratio(); - masking_MS[1][0] = new III_psy_ratio(); - masking_MS[1][1] = new III_psy_ratio(); - //III_psy_ratio masking[][]; - var masking; - /* pointer to selected maskings */ - var inbuf = [null, null]; - var gfc = gfp.internal_flags; - - var tot_ener = new_float_n([2, 4]); - var ms_ener_ratio = [.5, .5]; - var pe = [[0., 0.], [0., 0.]]; - var pe_MS = [[0., 0.], [0., 0.]]; - -//float[][] pe_use; - var pe_use; - - var ch, gr; - - inbuf[0] = inbuf_l; - inbuf[1] = inbuf_r; - - if (gfc.lame_encode_frame_init == 0) { - /* first run? */ - lame_encode_frame_init(gfp, inbuf); - - } - - /********************** padding *****************************/ - /** - *
-         * padding method as described in
-         * "MPEG-Layer3 / Bitstream Syntax and Decoding"
-         * by Martin Sieler, Ralph Sperschneider
-         *
-         * note: there is no padding for the very first frame
-         *
-         * Robert Hegemann 2000-06-22
-         * 
- */ - gfc.padding = 0; - if ((gfc.slot_lag -= gfc.frac_SpF) < 0) { - gfc.slot_lag += gfp.out_samplerate; - gfc.padding = 1; - } - - /**************************************** - * Stage 1: psychoacoustic model * - ****************************************/ - - if (gfc.psymodel != 0) { - /* - * psychoacoustic model psy model has a 1 granule (576) delay that - * we must compensate for (mt 6/99). - */ - var ret; - var bufp = [null, null]; - /* address of beginning of left & right granule */ - var bufpPos = 0; - /* address of beginning of left & right granule */ - var blocktype = new_int(2); - - for (gr = 0; gr < gfc.mode_gr; gr++) { - - for (ch = 0; ch < gfc.channels_out; ch++) { - bufp[ch] = inbuf[ch]; - bufpPos = 576 + gr * 576 - Encoder.FFTOFFSET; - } - if (gfp.VBR == VbrMode.vbr_mtrh || gfp.VBR == VbrMode.vbr_mt) { - ret = psy.L3psycho_anal_vbr(gfp, bufp, bufpPos, gr, - masking_LR, masking_MS, pe[gr], pe_MS[gr], - tot_ener[gr], blocktype); - } else { - ret = psy.L3psycho_anal_ns(gfp, bufp, bufpPos, gr, - masking_LR, masking_MS, pe[gr], pe_MS[gr], - tot_ener[gr], blocktype); - } - if (ret != 0) - return -4; - - if (gfp.mode == MPEGMode.JOINT_STEREO) { - ms_ener_ratio[gr] = tot_ener[gr][2] + tot_ener[gr][3]; - if (ms_ener_ratio[gr] > 0) - ms_ener_ratio[gr] = tot_ener[gr][3] / ms_ener_ratio[gr]; - } - - /* block type flags */ - for (ch = 0; ch < gfc.channels_out; ch++) { - var cod_info = gfc.l3_side.tt[gr][ch]; - cod_info.block_type = blocktype[ch]; - cod_info.mixed_block_flag = 0; - } - } - } else { - /* no psy model */ - for (gr = 0; gr < gfc.mode_gr; gr++) - for (ch = 0; ch < gfc.channels_out; ch++) { - gfc.l3_side.tt[gr][ch].block_type = Encoder.NORM_TYPE; - gfc.l3_side.tt[gr][ch].mixed_block_flag = 0; - pe_MS[gr][ch] = pe[gr][ch] = 700; - } - } - - /* auto-adjust of ATH, useful for low volume */ - adjust_ATH(gfc); - - /**************************************** - * Stage 2: MDCT * - ****************************************/ - - /* polyphase filtering / mdct */ - newMDCT.mdct_sub48(gfc, inbuf[0], inbuf[1]); - - /**************************************** - * Stage 3: MS/LR decision * - ****************************************/ - - /* Here will be selected MS or LR coding of the 2 stereo channels */ - gfc.mode_ext = Encoder.MPG_MD_LR_LR; - - if (gfp.force_ms) { - gfc.mode_ext = Encoder.MPG_MD_MS_LR; - } else if (gfp.mode == MPEGMode.JOINT_STEREO) { - /* - * ms_ratio = is scaled, for historical reasons, to look like a - * ratio of side_channel / total. 0 = signal is 100% mono .5 = L & R - * uncorrelated - */ - - /** - *
-             * [0] and [1] are the results for the two granules in MPEG-1,
-             * in MPEG-2 it's only a faked averaging of the same value
-             * _prev is the value of the last granule of the previous frame
-             * _next is the value of the first granule of the next frame
-             * 
- */ - - var sum_pe_MS = 0.; - var sum_pe_LR = 0.; - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - sum_pe_MS += pe_MS[gr][ch]; - sum_pe_LR += pe[gr][ch]; - } - } - - /* based on PE: M/S coding would not use much more bits than L/R */ - if (sum_pe_MS <= 1.00 * sum_pe_LR) { - - var gi0 = gfc.l3_side.tt[0]; - var gi1 = gfc.l3_side.tt[gfc.mode_gr - 1]; - - if (gi0[0].block_type == gi0[1].block_type - && gi1[0].block_type == gi1[1].block_type) { - - gfc.mode_ext = Encoder.MPG_MD_MS_LR; - } - } - } - - /* bit and noise allocation */ - if (gfc.mode_ext == MPG_MD_MS_LR) { - masking = masking_MS; - /* use MS masking */ - pe_use = pe_MS; - } else { - masking = masking_LR; - /* use LR masking */ - pe_use = pe; - } - - /* copy data for MP3 frame analyzer */ - if (gfp.analysis && gfc.pinfo != null) { - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - gfc.pinfo.ms_ratio[gr] = gfc.ms_ratio[gr]; - gfc.pinfo.ms_ener_ratio[gr] = ms_ener_ratio[gr]; - gfc.pinfo.blocktype[gr][ch] = gfc.l3_side.tt[gr][ch].block_type; - gfc.pinfo.pe[gr][ch] = pe_use[gr][ch]; - System.arraycopy(gfc.l3_side.tt[gr][ch].xr, 0, - gfc.pinfo.xr[gr][ch], 0, 576); - /* - * in psymodel, LR and MS data was stored in pinfo. switch - * to MS data: - */ - if (gfc.mode_ext == MPG_MD_MS_LR) { - gfc.pinfo.ers[gr][ch] = gfc.pinfo.ers[gr][ch + 2]; - System.arraycopy(gfc.pinfo.energy[gr][ch + 2], 0, - gfc.pinfo.energy[gr][ch], 0, - gfc.pinfo.energy[gr][ch].length); - } - } - } - } - - /**************************************** - * Stage 4: quantization loop * - ****************************************/ - - if (gfp.VBR == VbrMode.vbr_off || gfp.VBR == VbrMode.vbr_abr) { - - var i; - var f; - - for (i = 0; i < 18; i++) - gfc.nsPsy.pefirbuf[i] = gfc.nsPsy.pefirbuf[i + 1]; - - f = 0.0; - for (gr = 0; gr < gfc.mode_gr; gr++) - for (ch = 0; ch < gfc.channels_out; ch++) - f += pe_use[gr][ch]; - gfc.nsPsy.pefirbuf[18] = f; - - f = gfc.nsPsy.pefirbuf[9]; - for (i = 0; i < 9; i++) - f += (gfc.nsPsy.pefirbuf[i] + gfc.nsPsy.pefirbuf[18 - i]) - * Encoder.fircoef[i]; - - f = (670 * 5 * gfc.mode_gr * gfc.channels_out) / f; - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - pe_use[gr][ch] *= f; - } - } - } - gfc.iteration_loop.iteration_loop(gfp, pe_use, ms_ener_ratio, masking); - - /**************************************** - * Stage 5: bitstream formatting * - ****************************************/ - - /* write the frame to the bitstream */ - bs.format_bitstream(gfp); - - /* copy mp3 bit buffer into array */ - mp3count = bs.copy_buffer(gfc, mp3buf, mp3bufPos, mp3buf_size, 1); - - if (gfp.bWriteVbrTag) - vbr.addVbrFrame(gfp); - - if (gfp.analysis && gfc.pinfo != null) { - for (ch = 0; ch < gfc.channels_out; ch++) { - var j; - for (j = 0; j < FFTOFFSET; j++) - gfc.pinfo.pcmdata[ch][j] = gfc.pinfo.pcmdata[ch][j - + gfp.framesize]; - for (j = FFTOFFSET; j < 1600; j++) { - gfc.pinfo.pcmdata[ch][j] = inbuf[ch][j - FFTOFFSET]; - } - } - qupvt.set_frame_pinfo(gfp, masking); - } - - updateStats(gfc); - - return mp3count; - } -} - - -//package mp3; - -function VBRSeekInfo() { - /** - * What we have seen so far. - */ - this.sum = 0; - /** - * How many frames we have seen in this chunk. - */ - this.seen = 0; - /** - * How many frames we want to collect into one chunk. - */ - this.want = 0; - /** - * Actual position in our bag. - */ - this.pos = 0; - /** - * Size of our bag. - */ - this.size = 0; - /** - * Pointer to our bag. - */ - this.bag = null; - this.nVbrNumFrames = 0; - this.nBytesWritten = 0; - /* VBR tag data */ - this.TotalFrameSize = 0; -} - - - -function IIISideInfo() { - this.tt = [[null, null], [null, null]]; - this.main_data_begin = 0; - this.private_bits = 0; - this.resvDrain_pre = 0; - this.resvDrain_post = 0; - this.scfsi = [new_int(4), new_int(4)]; - - for (var gr = 0; gr < 2; gr++) { - for (var ch = 0; ch < 2; ch++) { - this.tt[gr][ch] = new GrInfo(); - } - } -} - - - -//package mp3; - -/** - * Variables used for --nspsytune - * - * @author Ken - * - */ -function NsPsy() { - this.last_en_subshort = new_float_n([4, 9]); - this.lastAttacks = new_int(4); - this.pefirbuf = new_float(19); - this.longfact = new_float(Encoder.SBMAX_l); - this.shortfact = new_float(Encoder.SBMAX_s); - - /** - * short block tuning - */ - this.attackthre = 0.; - this.attackthre_s = 0.; -} - - -function III_psy_xmin() { - this.l = new_float(Encoder.SBMAX_l); - this.s = new_float_n([Encoder.SBMAX_s, 3]); - - var self = this; - this.assign = function (iii_psy_xmin) { - System.arraycopy(iii_psy_xmin.l, 0, self.l, 0, Encoder.SBMAX_l); - for (var i = 0; i < Encoder.SBMAX_s; i++) { - for (var j = 0; j < 3; j++) { - self.s[i][j] = iii_psy_xmin.s[i][j]; - } - } - } -} - - - - -LameInternalFlags.MFSIZE = (3 * 1152 + Encoder.ENCDELAY - Encoder.MDCTDELAY); -LameInternalFlags.MAX_HEADER_BUF = 256; -LameInternalFlags.MAX_BITS_PER_CHANNEL = 4095; -LameInternalFlags.MAX_BITS_PER_GRANULE = 7680; -LameInternalFlags.BPC = 320; - -function LameInternalFlags() { - var MAX_HEADER_LEN = 40; - - - /******************************************************************** - * internal variables NOT set by calling program, and should not be * - * modified by the calling program * - ********************************************************************/ - - /** - * Some remarks to the Class_ID field: The Class ID is an Identifier for a - * pointer to this struct. It is very unlikely that a pointer to - * lame_global_flags has the same 32 bits in it's structure (large and other - * special properties, for instance prime). - * - * To test that the structure is right and initialized, use: if ( gfc . - * Class_ID == LAME_ID ) ... Other remark: If you set a flag to 0 for uninit - * data and 1 for init data, the right test should be "if (flag == 1)" and - * NOT "if (flag)". Unintended modification of this element will be - * otherwise misinterpreted as an init. - */ - this.Class_ID = 0; - - this.lame_encode_frame_init = 0; - this.iteration_init_init = 0; - this.fill_buffer_resample_init = 0; - - //public float mfbuf[][] = new float[2][MFSIZE]; - this.mfbuf = new_float_n([2, LameInternalFlags.MFSIZE]); - - /** - * granules per frame - */ - this.mode_gr = 0; - /** - * number of channels in the input data stream (PCM or decoded PCM) - */ - this.channels_in = 0; - /** - * number of channels in the output data stream (not used for decoding) - */ - this.channels_out = 0; - /** - * input_samp_rate/output_samp_rate - */ - //public double resample_ratio; - this.resample_ratio = 0.; - - this.mf_samples_to_encode = 0; - this.mf_size = 0; - /** - * min bitrate index - */ - this.VBR_min_bitrate = 0; - /** - * max bitrate index - */ - this.VBR_max_bitrate = 0; - this.bitrate_index = 0; - this.samplerate_index = 0; - this.mode_ext = 0; - - /* lowpass and highpass filter control */ - /** - * normalized frequency bounds of passband - */ - this.lowpass1 = 0.; - this.lowpass2 = 0.; - /** - * normalized frequency bounds of passband - */ - this.highpass1 = 0.; - this.highpass2 = 0.; - - /** - * 0 = none 1 = ISO AAC model 2 = allow scalefac_select=1 - */ - this.noise_shaping = 0; - - /** - * 0 = ISO model: amplify all distorted bands
- * 1 = amplify within 50% of max (on db scale)
- * 2 = amplify only most distorted band
- * 3 = method 1 and refine with method 2
- */ - this.noise_shaping_amp = 0; - /** - * 0 = no substep
- * 1 = use substep shaping at last step(VBR only)
- * (not implemented yet)
- * 2 = use substep inside loop
- * 3 = use substep inside loop and last step
- */ - this.substep_shaping = 0; - - /** - * 1 = gpsycho. 0 = none - */ - this.psymodel = 0; - /** - * 0 = stop at over=0, all scalefacs amplified or
- * a scalefac has reached max value
- * 1 = stop when all scalefacs amplified or a scalefac has reached max value
- * 2 = stop when all scalefacs amplified - */ - this.noise_shaping_stop = 0; - - /** - * 0 = no, 1 = yes - */ - this.subblock_gain = 0; - /** - * 0 = no. 1=outside loop 2=inside loop(slow) - */ - this.use_best_huffman = 0; - - /** - * 0 = stop early after 0 distortion found. 1 = full search - */ - this.full_outer_loop = 0; - - //public IIISideInfo l3_side = new IIISideInfo(); - this.l3_side = new IIISideInfo(); - this.ms_ratio = new_float(2); - - /* used for padding */ - /** - * padding for the current frame? - */ - this.padding = 0; - this.frac_SpF = 0; - this.slot_lag = 0; - - /** - * optional ID3 tags - */ - //public ID3TagSpec tag_spec; - this.tag_spec = null; - this.nMusicCRC = 0; - - /* variables used by Quantize */ - //public int OldValue[] = new int[2]; - this.OldValue = new_int(2); - //public int CurrentStep[] = new int[2]; - this.CurrentStep = new_int(2); - - this.masking_lower = 0.; - //public int bv_scf[] = new int[576]; - this.bv_scf = new_int(576); - //public int pseudohalf[] = new int[L3Side.SFBMAX]; - this.pseudohalf = new_int(L3Side.SFBMAX); - - /** - * will be set in lame_init_params - */ - this.sfb21_extra = false; - - /* BPC = maximum number of filter convolution windows to precompute */ - //public float[][] inbuf_old = new float[2][]; - this.inbuf_old = new Array(2); - //public float[][] blackfilt = new float[2 * BPC + 1][]; - this.blackfilt = new Array(2 * LameInternalFlags.BPC + 1); - //public double itime[] = new double[2]; - this.itime = new_double(2); - this.sideinfo_len = 0; - - /* variables for newmdct.c */ - //public float sb_sample[][][][] = new float[2][2][18][Encoder.SBLIMIT]; - this.sb_sample = new_float_n([2, 2, 18, Encoder.SBLIMIT]); - this.amp_filter = new_float(32); - - /* variables for BitStream */ - - /** - *
-     * mpeg1: buffer=511 bytes  smallest frame: 96-38(sideinfo)=58
-     * max number of frames in reservoir:  8
-     * mpeg2: buffer=255 bytes.  smallest frame: 24-23bytes=1
-     * with VBR, if you are encoding all silence, it is possible to
-     * have 8kbs/24khz frames with 1byte of data each, which means we need
-     * to buffer up to 255 headers!
-     * 
- */ - /** - * also, max_header_buf has to be a power of two - */ - /** - * max size of header is 38 - */ - - function Header() { - this.write_timing = 0; - this.ptr = 0; - //public byte buf[] = new byte[MAX_HEADER_LEN]; - this.buf = new_byte(MAX_HEADER_LEN); - } - - this.header = new Array(LameInternalFlags.MAX_HEADER_BUF); - - this.h_ptr = 0; - this.w_ptr = 0; - this.ancillary_flag = 0; - - /* variables for Reservoir */ - /** - * in bits - */ - this.ResvSize = 0; - /** - * in bits - */ - this.ResvMax = 0; - - //public ScaleFac scalefac_band = new ScaleFac(); - this.scalefac_band = new ScaleFac(); - - /* daa from PsyModel */ - /* The static variables "r", "phi_sav", "new", "old" and "oldest" have */ - /* to be remembered for the unpredictability measure. For "r" and */ - /* "phi_sav", the first index from the left is the channel select and */ - /* the second index is the "age" of the data. */ - this.minval_l = new_float(Encoder.CBANDS); - this.minval_s = new_float(Encoder.CBANDS); - this.nb_1 = new_float_n([4, Encoder.CBANDS]); - this.nb_2 = new_float_n([4, Encoder.CBANDS]); - this.nb_s1 = new_float_n([4, Encoder.CBANDS]); - this.nb_s2 = new_float_n([4, Encoder.CBANDS]); - this.s3_ss = null; - this.s3_ll = null; - this.decay = 0.; - - //public III_psy_xmin[] thm = new III_psy_xmin[4]; - //public III_psy_xmin[] en = new III_psy_xmin[4]; - this.thm = new Array(4); - this.en = new Array(4); - - /** - * fft and energy calculation - */ - this.tot_ener = new_float(4); - - /* loudness calculation (for adaptive threshold of hearing) */ - /** - * loudness^2 approx. per granule and channel - */ - this.loudness_sq = new_float_n([2, 2]); - /** - * account for granule delay of L3psycho_anal - */ - this.loudness_sq_save = new_float(2); - - /** - * Scale Factor Bands - */ - this.mld_l = new_float(Encoder.SBMAX_l); - this.mld_s = new_float(Encoder.SBMAX_s); - this.bm_l = new_int(Encoder.SBMAX_l); - this.bo_l = new_int(Encoder.SBMAX_l); - this.bm_s = new_int(Encoder.SBMAX_s); - this.bo_s = new_int(Encoder.SBMAX_s); - this.npart_l = 0; - this.npart_s = 0; - - this.s3ind = new_int_n([Encoder.CBANDS, 2]); - this.s3ind_s = new_int_n([Encoder.CBANDS, 2]); - - this.numlines_s = new_int(Encoder.CBANDS); - this.numlines_l = new_int(Encoder.CBANDS); - this.rnumlines_l = new_float(Encoder.CBANDS); - this.mld_cb_l = new_float(Encoder.CBANDS); - this.mld_cb_s = new_float(Encoder.CBANDS); - this.numlines_s_num1 = 0; - this.numlines_l_num1 = 0; - - /* ratios */ - this.pe = new_float(4); - this.ms_ratio_s_old = 0.; - this.ms_ratio_l_old = 0.; - this.ms_ener_ratio_old = 0.; - - /** - * block type - */ - this.blocktype_old = new_int(2); - - /** - * variables used for --nspsytune - */ - this.nsPsy = new NsPsy(); - - /** - * used for Xing VBR header - */ - this.VBR_seek_table = new VBRSeekInfo(); - - /** - * all ATH related stuff - */ - //public ATH ATH; - this.ATH = null; - - this.PSY = null; - - this.nogap_total = 0; - this.nogap_current = 0; - - /* ReplayGain */ - this.decode_on_the_fly = true; - this.findReplayGain = true; - this.findPeakSample = true; - this.PeakSample = 0.; - this.RadioGain = 0; - this.AudiophileGain = 0; - //public ReplayGain rgdata; - this.rgdata = null; - - /** - * gain change required for preventing clipping - */ - this.noclipGainChange = 0; - /** - * user-specified scale factor required for preventing clipping - */ - this.noclipScale = 0.; - - /* simple statistics */ - this.bitrate_stereoMode_Hist = new_int_n([16, 4 + 1]); - /** - * norm/start/short/stop/mixed(short)/sum - */ - this.bitrate_blockType_Hist = new_int_n([16, 4 + 1 + 1]); - - //public PlottingData pinfo; - //public MPGLib.mpstr_tag hip; - this.pinfo = null; - this.hip = null; - - this.in_buffer_nsamples = 0; - //public float[] in_buffer_0; - //public float[] in_buffer_1; - this.in_buffer_0 = null; - this.in_buffer_1 = null; - - //public IIterationLoop iteration_loop; - this.iteration_loop = null; - - for (var i = 0; i < this.en.length; i++) { - this.en[i] = new III_psy_xmin(); - } - for (var i = 0; i < this.thm.length; i++) { - this.thm[i] = new III_psy_xmin(); - } - for (var i = 0; i < this.header.length; i++) { - this.header[i] = new Header(); - } - -} - - - -function FFT() { - - var window = new_float(Encoder.BLKSIZE); - var window_s = new_float(Encoder.BLKSIZE_s / 2); - - var costab = [ - 9.238795325112867e-01, 3.826834323650898e-01, - 9.951847266721969e-01, 9.801714032956060e-02, - 9.996988186962042e-01, 2.454122852291229e-02, - 9.999811752826011e-01, 6.135884649154475e-03 - ]; - - function fht(fz, fzPos, n) { - var tri = 0; - var k4; - var fi; - var gi; - - n <<= 1; - /* to get BLKSIZE, because of 3DNow! ASM routine */ - var fn = fzPos + n; - k4 = 4; - do { - var s1, c1; - var i, k1, k2, k3, kx; - kx = k4 >> 1; - k1 = k4; - k2 = k4 << 1; - k3 = k2 + k1; - k4 = k2 << 1; - fi = fzPos; - gi = fi + kx; - do { - var f0, f1, f2, f3; - f1 = fz[fi + 0] - fz[fi + k1]; - f0 = fz[fi + 0] + fz[fi + k1]; - f3 = fz[fi + k2] - fz[fi + k3]; - f2 = fz[fi + k2] + fz[fi + k3]; - fz[fi + k2] = f0 - f2; - fz[fi + 0] = f0 + f2; - fz[fi + k3] = f1 - f3; - fz[fi + k1] = f1 + f3; - f1 = fz[gi + 0] - fz[gi + k1]; - f0 = fz[gi + 0] + fz[gi + k1]; - f3 = (Util.SQRT2 * fz[gi + k3]); - f2 = (Util.SQRT2 * fz[gi + k2]); - fz[gi + k2] = f0 - f2; - fz[gi + 0] = f0 + f2; - fz[gi + k3] = f1 - f3; - fz[gi + k1] = f1 + f3; - gi += k4; - fi += k4; - } while (fi < fn); - c1 = costab[tri + 0]; - s1 = costab[tri + 1]; - for (i = 1; i < kx; i++) { - var c2, s2; - c2 = 1 - (2 * s1) * s1; - s2 = (2 * s1) * c1; - fi = fzPos + i; - gi = fzPos + k1 - i; - do { - var a, b, g0, f0, f1, g1, f2, g2, f3, g3; - b = s2 * fz[fi + k1] - c2 * fz[gi + k1]; - a = c2 * fz[fi + k1] + s2 * fz[gi + k1]; - f1 = fz[fi + 0] - a; - f0 = fz[fi + 0] + a; - g1 = fz[gi + 0] - b; - g0 = fz[gi + 0] + b; - b = s2 * fz[fi + k3] - c2 * fz[gi + k3]; - a = c2 * fz[fi + k3] + s2 * fz[gi + k3]; - f3 = fz[fi + k2] - a; - f2 = fz[fi + k2] + a; - g3 = fz[gi + k2] - b; - g2 = fz[gi + k2] + b; - b = s1 * f2 - c1 * g3; - a = c1 * f2 + s1 * g3; - fz[fi + k2] = f0 - a; - fz[fi + 0] = f0 + a; - fz[gi + k3] = g1 - b; - fz[gi + k1] = g1 + b; - b = c1 * g2 - s1 * f3; - a = s1 * g2 + c1 * f3; - fz[gi + k2] = g0 - a; - fz[gi + 0] = g0 + a; - fz[fi + k3] = f1 - b; - fz[fi + k1] = f1 + b; - gi += k4; - fi += k4; - } while (fi < fn); - c2 = c1; - c1 = c2 * costab[tri + 0] - s1 * costab[tri + 1]; - s1 = c2 * costab[tri + 1] + s1 * costab[tri + 0]; - } - tri += 2; - } while (k4 < n); - } - - var rv_tbl = [0x00, 0x80, 0x40, - 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, - 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, - 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, - 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, - 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, - 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, - 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, - 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, - 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, - 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, - 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, - 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, - 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, - 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, - 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, - 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, - 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, - 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, - 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, - 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, - 0xde, 0x3e, 0xbe, 0x7e, 0xfe]; - - this.fft_short = function (gfc, x_real, chn, buffer, bufPos) { - for (var b = 0; b < 3; b++) { - var x = Encoder.BLKSIZE_s / 2; - var k = 0xffff & ((576 / 3) * (b + 1)); - var j = Encoder.BLKSIZE_s / 8 - 1; - do { - var f0, f1, f2, f3, w; - var i = rv_tbl[j << 2] & 0xff; - - f0 = window_s[i] * buffer[chn][bufPos + i + k]; - w = window_s[0x7f - i] * buffer[chn][bufPos + i + k + 0x80]; - f1 = f0 - w; - f0 = f0 + w; - f2 = window_s[i + 0x40] * buffer[chn][bufPos + i + k + 0x40]; - w = window_s[0x3f - i] * buffer[chn][bufPos + i + k + 0xc0]; - f3 = f2 - w; - f2 = f2 + w; - - x -= 4; - x_real[b][x + 0] = f0 + f2; - x_real[b][x + 2] = f0 - f2; - x_real[b][x + 1] = f1 + f3; - x_real[b][x + 3] = f1 - f3; - - f0 = window_s[i + 0x01] * buffer[chn][bufPos + i + k + 0x01]; - w = window_s[0x7e - i] * buffer[chn][bufPos + i + k + 0x81]; - f1 = f0 - w; - f0 = f0 + w; - f2 = window_s[i + 0x41] * buffer[chn][bufPos + i + k + 0x41]; - w = window_s[0x3e - i] * buffer[chn][bufPos + i + k + 0xc1]; - f3 = f2 - w; - f2 = f2 + w; - - x_real[b][x + Encoder.BLKSIZE_s / 2 + 0] = f0 + f2; - x_real[b][x + Encoder.BLKSIZE_s / 2 + 2] = f0 - f2; - x_real[b][x + Encoder.BLKSIZE_s / 2 + 1] = f1 + f3; - x_real[b][x + Encoder.BLKSIZE_s / 2 + 3] = f1 - f3; - } while (--j >= 0); - - fht(x_real[b], x, Encoder.BLKSIZE_s / 2); - /* BLKSIZE_s/2 because of 3DNow! ASM routine */ - /* BLKSIZE/2 because of 3DNow! ASM routine */ - } - } - - this.fft_long = function (gfc, y, chn, buffer, bufPos) { - var jj = Encoder.BLKSIZE / 8 - 1; - var x = Encoder.BLKSIZE / 2; - - do { - var f0, f1, f2, f3, w; - var i = rv_tbl[jj] & 0xff; - f0 = window[i] * buffer[chn][bufPos + i]; - w = window[i + 0x200] * buffer[chn][bufPos + i + 0x200]; - f1 = f0 - w; - f0 = f0 + w; - f2 = window[i + 0x100] * buffer[chn][bufPos + i + 0x100]; - w = window[i + 0x300] * buffer[chn][bufPos + i + 0x300]; - f3 = f2 - w; - f2 = f2 + w; - - x -= 4; - y[x + 0] = f0 + f2; - y[x + 2] = f0 - f2; - y[x + 1] = f1 + f3; - y[x + 3] = f1 - f3; - - f0 = window[i + 0x001] * buffer[chn][bufPos + i + 0x001]; - w = window[i + 0x201] * buffer[chn][bufPos + i + 0x201]; - f1 = f0 - w; - f0 = f0 + w; - f2 = window[i + 0x101] * buffer[chn][bufPos + i + 0x101]; - w = window[i + 0x301] * buffer[chn][bufPos + i + 0x301]; - f3 = f2 - w; - f2 = f2 + w; - - y[x + Encoder.BLKSIZE / 2 + 0] = f0 + f2; - y[x + Encoder.BLKSIZE / 2 + 2] = f0 - f2; - y[x + Encoder.BLKSIZE / 2 + 1] = f1 + f3; - y[x + Encoder.BLKSIZE / 2 + 3] = f1 - f3; - } while (--jj >= 0); - - fht(y, x, Encoder.BLKSIZE / 2); - /* BLKSIZE/2 because of 3DNow! ASM routine */ - } - - this.init_fft = function (gfc) { - /* The type of window used here will make no real difference, but */ - /* - * in the interest of merging nspsytune stuff - switch to blackman - * window - */ - for (var i = 0; i < Encoder.BLKSIZE; i++) - /* blackman window */ - window[i] = (0.42 - 0.5 * Math.cos(2 * Math.PI * (i + .5) - / Encoder.BLKSIZE) + 0.08 * Math.cos(4 * Math.PI * (i + .5) - / Encoder.BLKSIZE)); - - for (var i = 0; i < Encoder.BLKSIZE_s / 2; i++) - window_s[i] = (0.5 * (1.0 - Math.cos(2.0 * Math.PI - * (i + 0.5) / Encoder.BLKSIZE_s))); - - } - -} - -/* - * psymodel.c - * - * Copyright (c) 1999-2000 Mark Taylor - * Copyright (c) 2001-2002 Naoki Shibata - * Copyright (c) 2000-2003 Takehiro Tominaga - * Copyright (c) 2000-2008 Robert Hegemann - * Copyright (c) 2000-2005 Gabriel Bouvigne - * Copyright (c) 2000-2005 Alexander Leidinger - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: PsyModel.java,v 1.27 2011/05/24 20:48:06 kenchis Exp $ */ - - -/* - PSYCHO ACOUSTICS - - - This routine computes the psycho acoustics, delayed by one granule. - - Input: buffer of PCM data (1024 samples). - - This window should be centered over the 576 sample granule window. - The routine will compute the psycho acoustics for - this granule, but return the psycho acoustics computed - for the *previous* granule. This is because the block - type of the previous granule can only be determined - after we have computed the psycho acoustics for the following - granule. - - Output: maskings and energies for each scalefactor band. - block type, PE, and some correlation measures. - The PE is used by CBR modes to determine if extra bits - from the bit reservoir should be used. The correlation - measures are used to determine mid/side or regular stereo. - */ -/* - Notation: - - barks: a non-linear frequency scale. Mapping from frequency to - barks is given by freq2bark() - - scalefactor bands: The spectrum (frequencies) are broken into - SBMAX "scalefactor bands". Thes bands - are determined by the MPEG ISO spec. In - the noise shaping/quantization code, we allocate - bits among the partition bands to achieve the - best possible quality - - partition bands: The spectrum is also broken into about - 64 "partition bands". Each partition - band is about .34 barks wide. There are about 2-5 - partition bands for each scalefactor band. - - LAME computes all psycho acoustic information for each partition - band. Then at the end of the computations, this information - is mapped to scalefactor bands. The energy in each scalefactor - band is taken as the sum of the energy in all partition bands - which overlap the scalefactor band. The maskings can be computed - in the same way (and thus represent the average masking in that band) - or by taking the minmum value multiplied by the number of - partition bands used (which represents a minimum masking in that band). - */ -/* - The general outline is as follows: - - 1. compute the energy in each partition band - 2. compute the tonality in each partition band - 3. compute the strength of each partion band "masker" - 4. compute the masking (via the spreading function applied to each masker) - 5. Modifications for mid/side masking. - - Each partition band is considiered a "masker". The strength - of the i'th masker in band j is given by: - - s3(bark(i)-bark(j))*strength(i) - - The strength of the masker is a function of the energy and tonality. - The more tonal, the less masking. LAME uses a simple linear formula - (controlled by NMT and TMN) which says the strength is given by the - energy divided by a linear function of the tonality. - */ -/* - s3() is the "spreading function". It is given by a formula - determined via listening tests. - - The total masking in the j'th partition band is the sum over - all maskings i. It is thus given by the convolution of - the strength with s3(), the "spreading function." - - masking(j) = sum_over_i s3(i-j)*strength(i) = s3 o strength - - where "o" = convolution operator. s3 is given by a formula determined - via listening tests. It is normalized so that s3 o 1 = 1. - - Note: instead of a simple convolution, LAME also has the - option of using "additive masking" - - The most critical part is step 2, computing the tonality of each - partition band. LAME has two tonality estimators. The first - is based on the ISO spec, and measures how predictiable the - signal is over time. The more predictable, the more tonal. - The second measure is based on looking at the spectrum of - a single granule. The more peaky the spectrum, the more - tonal. By most indications, the latter approach is better. - - Finally, in step 5, the maskings for the mid and side - channel are possibly increased. Under certain circumstances, - noise in the mid & side channels is assumed to also - be masked by strong maskers in the L or R channels. - - - Other data computed by the psy-model: - - ms_ratio side-channel / mid-channel masking ratio (for previous granule) - ms_ratio_next side-channel / mid-channel masking ratio for this granule - - percep_entropy[2] L and R values (prev granule) of PE - A measure of how - much pre-echo is in the previous granule - percep_entropy_MS[2] mid and side channel values (prev granule) of percep_entropy - energy[4] L,R,M,S energy in each channel, prev granule - blocktype_d[2] block type to use for previous granule - */ -//package mp3; - -//import java.util.Arrays; - - -function PsyModel() { - - var fft = new FFT(); - - var LOG10 = 2.30258509299404568402; - - var rpelev = 2; - var rpelev2 = 16; - var rpelev_s = 2; - var rpelev2_s = 16; - - /* size of each partition band, in barks: */ - var DELBARK = .34; - - /* tuned for output level (sensitive to energy scale) */ - var VO_SCALE = (1. / (14752 * 14752) / (Encoder.BLKSIZE / 2)); - - var temporalmask_sustain_sec = 0.01; - - var NS_PREECHO_ATT0 = 0.8; - var NS_PREECHO_ATT1 = 0.6; - var NS_PREECHO_ATT2 = 0.3; - - var NS_MSFIX = 3.5; - - var NSATTACKTHRE = 4.4; - var NSATTACKTHRE_S = 25; - - var NSFIRLEN = 21; - - /* size of each partition band, in barks: */ - var LN_TO_LOG10 = 0.2302585093; - - function NON_LINEAR_SCALE_ENERGY(x) { - return x; - } - - /** - *
-     *       L3psycho_anal.  Compute psycho acoustics.
-     *
-     *       Data returned to the calling program must be delayed by one
-     *       granule.
-     *
-     *       This is done in two places.
-     *       If we do not need to know the blocktype, the copying
-     *       can be done here at the top of the program: we copy the data for
-     *       the last granule (computed during the last call) before it is
-     *       overwritten with the new data.  It looks like this:
-     *
-     *       0. static psymodel_data
-     *       1. calling_program_data = psymodel_data
-     *       2. compute psymodel_data
-     *
-     *       For data which needs to know the blocktype, the copying must be
-     *       done at the end of this loop, and the old values must be saved:
-     *
-     *       0. static psymodel_data_old
-     *       1. compute psymodel_data
-     *       2. compute possible block type of this granule
-     *       3. compute final block type of previous granule based on #2.
-     *       4. calling_program_data = psymodel_data_old
-     *       5. psymodel_data_old = psymodel_data
-     *     psycho_loudness_approx
-     *       jd - 2001 mar 12
-     *    in:  energy   - BLKSIZE/2 elements of frequency magnitudes ^ 2
-     *         gfp      - uses out_samplerate, ATHtype (also needed for ATHformula)
-     *    returns: loudness^2 approximation, a positive value roughly tuned for a value
-     *             of 1.0 for signals near clipping.
-     *    notes:   When calibrated, feeding this function binary white noise at sample
-     *             values +32767 or -32768 should return values that approach 3.
-     *             ATHformula is used to approximate an equal loudness curve.
-     *    future:  Data indicates that the shape of the equal loudness curve varies
-     *             with intensity.  This function might be improved by using an equal
-     *             loudness curve shaped for typical playback levels (instead of the
-     *             ATH, that is shaped for the threshold).  A flexible realization might
-     *             simply bend the existing ATH curve to achieve the desired shape.
-     *             However, the potential gain may not be enough to justify an effort.
-     * 
- */ - function psycho_loudness_approx(energy, gfc) { - var loudness_power = 0.0; - /* apply weights to power in freq. bands */ - for (var i = 0; i < Encoder.BLKSIZE / 2; ++i) - loudness_power += energy[i] * gfc.ATH.eql_w[i]; - loudness_power *= VO_SCALE; - - return loudness_power; - } - - function compute_ffts(gfp, fftenergy, fftenergy_s, wsamp_l, wsamp_lPos, wsamp_s, wsamp_sPos, gr_out, chn, buffer, bufPos) { - var gfc = gfp.internal_flags; - if (chn < 2) { - fft.fft_long(gfc, wsamp_l[wsamp_lPos], chn, buffer, bufPos); - fft.fft_short(gfc, wsamp_s[wsamp_sPos], chn, buffer, bufPos); - } - /* FFT data for mid and side channel is derived from L & R */ - else if (chn == 2) { - for (var j = Encoder.BLKSIZE - 1; j >= 0; --j) { - var l = wsamp_l[wsamp_lPos + 0][j]; - var r = wsamp_l[wsamp_lPos + 1][j]; - wsamp_l[wsamp_lPos + 0][j] = (l + r) * Util.SQRT2 * 0.5; - wsamp_l[wsamp_lPos + 1][j] = (l - r) * Util.SQRT2 * 0.5; - } - for (var b = 2; b >= 0; --b) { - for (var j = Encoder.BLKSIZE_s - 1; j >= 0; --j) { - var l = wsamp_s[wsamp_sPos + 0][b][j]; - var r = wsamp_s[wsamp_sPos + 1][b][j]; - wsamp_s[wsamp_sPos + 0][b][j] = (l + r) * Util.SQRT2 * 0.5; - wsamp_s[wsamp_sPos + 1][b][j] = (l - r) * Util.SQRT2 * 0.5; - } - } - } - - /********************************************************************* - * compute energies - *********************************************************************/ - fftenergy[0] = NON_LINEAR_SCALE_ENERGY(wsamp_l[wsamp_lPos + 0][0]); - fftenergy[0] *= fftenergy[0]; - - for (var j = Encoder.BLKSIZE / 2 - 1; j >= 0; --j) { - var re = (wsamp_l[wsamp_lPos + 0])[Encoder.BLKSIZE / 2 - j]; - var im = (wsamp_l[wsamp_lPos + 0])[Encoder.BLKSIZE / 2 + j]; - fftenergy[Encoder.BLKSIZE / 2 - j] = NON_LINEAR_SCALE_ENERGY((re - * re + im * im) * 0.5); - } - for (var b = 2; b >= 0; --b) { - fftenergy_s[b][0] = (wsamp_s[wsamp_sPos + 0])[b][0]; - fftenergy_s[b][0] *= fftenergy_s[b][0]; - for (var j = Encoder.BLKSIZE_s / 2 - 1; j >= 0; --j) { - var re = (wsamp_s[wsamp_sPos + 0])[b][Encoder.BLKSIZE_s - / 2 - j]; - var im = (wsamp_s[wsamp_sPos + 0])[b][Encoder.BLKSIZE_s - / 2 + j]; - fftenergy_s[b][Encoder.BLKSIZE_s / 2 - j] = NON_LINEAR_SCALE_ENERGY((re - * re + im * im) * 0.5); - } - } - /* total energy */ - { - var totalenergy = 0.0; - for (var j = 11; j < Encoder.HBLKSIZE; j++) - totalenergy += fftenergy[j]; - - gfc.tot_ener[chn] = totalenergy; - } - - if (gfp.analysis) { - for (var j = 0; j < Encoder.HBLKSIZE; j++) { - gfc.pinfo.energy[gr_out][chn][j] = gfc.pinfo.energy_save[chn][j]; - gfc.pinfo.energy_save[chn][j] = fftenergy[j]; - } - gfc.pinfo.pe[gr_out][chn] = gfc.pe[chn]; - } - - /********************************************************************* - * compute loudness approximation (used for ATH auto-level adjustment) - *********************************************************************/ - if (gfp.athaa_loudapprox == 2 && chn < 2) { - // no loudness for mid/side ch - gfc.loudness_sq[gr_out][chn] = gfc.loudness_sq_save[chn]; - gfc.loudness_sq_save[chn] = psycho_loudness_approx(fftenergy, gfc); - } - } - - /* mask_add optimization */ - /* init the limit values used to avoid computing log in mask_add when it is not necessary */ - - /** - *
-     *  For example, with i = 10*log10(m2/m1)/10*16         (= log10(m2/m1)*16)
-     *
-     * abs(i)>8 is equivalent (as i is an integer) to
-     * abs(i)>=9
-     * i>=9 || i<=-9
-     * equivalent to (as i is the biggest integer smaller than log10(m2/m1)*16
-     * or the smallest integer bigger than log10(m2/m1)*16 depending on the sign of log10(m2/m1)*16)
-     * log10(m2/m1)>=9/16 || log10(m2/m1)<=-9/16
-     * exp10 is strictly increasing thus this is equivalent to
-     * m2/m1 >= 10^(9/16) || m2/m1<=10^(-9/16) which are comparisons to constants
-     * 
- */ - - /** - * as in if(i>8) - */ - var I1LIMIT = 8; - /** - * as in if(i>24) . changed 23 - */ - var I2LIMIT = 23; - /** - * as in if(m<15) - */ - var MLIMIT = 15; - - var ma_max_i1; - var ma_max_i2; - var ma_max_m; - - /** - * This is the masking table:
- * According to tonality, values are going from 0dB (TMN) to 9.3dB (NMT).
- * After additive masking computation, 8dB are added, so final values are - * going from 8dB to 17.3dB - * - * pow(10, -0.0..-0.6) - */ - var tab = [1.0, 0.79433, 0.63096, 0.63096, - 0.63096, 0.63096, 0.63096, 0.25119, 0.11749]; - - function init_mask_add_max_values() { - ma_max_i1 = Math.pow(10, (I1LIMIT + 1) / 16.0); - ma_max_i2 = Math.pow(10, (I2LIMIT + 1) / 16.0); - ma_max_m = Math.pow(10, (MLIMIT) / 10.0); - } - - var table1 = [3.3246 * 3.3246, - 3.23837 * 3.23837, 3.15437 * 3.15437, 3.00412 * 3.00412, - 2.86103 * 2.86103, 2.65407 * 2.65407, 2.46209 * 2.46209, - 2.284 * 2.284, 2.11879 * 2.11879, 1.96552 * 1.96552, - 1.82335 * 1.82335, 1.69146 * 1.69146, 1.56911 * 1.56911, - 1.46658 * 1.46658, 1.37074 * 1.37074, 1.31036 * 1.31036, - 1.25264 * 1.25264, 1.20648 * 1.20648, 1.16203 * 1.16203, - 1.12765 * 1.12765, 1.09428 * 1.09428, 1.0659 * 1.0659, - 1.03826 * 1.03826, 1.01895 * 1.01895, 1]; - - var table2 = [1.33352 * 1.33352, - 1.35879 * 1.35879, 1.38454 * 1.38454, 1.39497 * 1.39497, - 1.40548 * 1.40548, 1.3537 * 1.3537, 1.30382 * 1.30382, - 1.22321 * 1.22321, 1.14758 * 1.14758, 1]; - - var table3 = [2.35364 * 2.35364, - 2.29259 * 2.29259, 2.23313 * 2.23313, 2.12675 * 2.12675, - 2.02545 * 2.02545, 1.87894 * 1.87894, 1.74303 * 1.74303, - 1.61695 * 1.61695, 1.49999 * 1.49999, 1.39148 * 1.39148, - 1.29083 * 1.29083, 1.19746 * 1.19746, 1.11084 * 1.11084, - 1.03826 * 1.03826]; - - /** - * addition of simultaneous masking Naoki Shibata 2000/7 - */ - function mask_add(m1, m2, kk, b, gfc, shortblock) { - var ratio; - - if (m2 > m1) { - if (m2 < (m1 * ma_max_i2)) - ratio = m2 / m1; - else - return (m1 + m2); - } else { - if (m1 >= (m2 * ma_max_i2)) - return (m1 + m2); - ratio = m1 / m2; - } - - /* Should always be true, just checking */ - - m1 += m2; - //if (((long)(b + 3) & 0xffffffff) <= 3 + 3) { - if ((b + 3) <= 3 + 3) { - /* approximately, 1 bark = 3 partitions */ - /* 65% of the cases */ - /* originally 'if(i > 8)' */ - if (ratio >= ma_max_i1) { - /* 43% of the total */ - return m1; - } - - /* 22% of the total */ - var i = 0 | (Util.FAST_LOG10_X(ratio, 16.0)); - return m1 * table2[i]; - } - - /** - *
-         * m<15 equ log10((m1+m2)/gfc.ATH.cb[k])<1.5
-         * equ (m1+m2)/gfc.ATH.cb[k]<10^1.5
-         * equ (m1+m2)<10^1.5 * gfc.ATH.cb[k]
-         * 
- */ - var i = 0 | Util.FAST_LOG10_X(ratio, 16.0); - if (shortblock != 0) { - m2 = gfc.ATH.cb_s[kk] * gfc.ATH.adjust; - } else { - m2 = gfc.ATH.cb_l[kk] * gfc.ATH.adjust; - } - if (m1 < ma_max_m * m2) { - /* 3% of the total */ - /* Originally if (m > 0) { */ - if (m1 > m2) { - var f, r; - - f = 1.0; - if (i <= 13) - f = table3[i]; - - r = Util.FAST_LOG10_X(m1 / m2, 10.0 / 15.0); - return m1 * ((table1[i] - f) * r + f); - } - - if (i > 13) - return m1; - - return m1 * table3[i]; - } - - /* 10% of total */ - return m1 * table1[i]; - } - - var table2_ = [1.33352 * 1.33352, - 1.35879 * 1.35879, 1.38454 * 1.38454, 1.39497 * 1.39497, - 1.40548 * 1.40548, 1.3537 * 1.3537, 1.30382 * 1.30382, - 1.22321 * 1.22321, 1.14758 * 1.14758, 1]; - - /** - * addition of simultaneous masking Naoki Shibata 2000/7 - */ - function vbrpsy_mask_add(m1, m2, b) { - var ratio; - - if (m1 < 0) { - m1 = 0; - } - if (m2 < 0) { - m2 = 0; - } - if (m1 <= 0) { - return m2; - } - if (m2 <= 0) { - return m1; - } - if (m2 > m1) { - ratio = m2 / m1; - } else { - ratio = m1 / m2; - } - if (-2 <= b && b <= 2) { - /* approximately, 1 bark = 3 partitions */ - /* originally 'if(i > 8)' */ - if (ratio >= ma_max_i1) { - return m1 + m2; - } else { - var i = 0 | (Util.FAST_LOG10_X(ratio, 16.0)); - return (m1 + m2) * table2_[i]; - } - } - if (ratio < ma_max_i2) { - return m1 + m2; - } - if (m1 < m2) { - m1 = m2; - } - return m1; - } - - /** - * compute interchannel masking effects - */ - function calc_interchannel_masking(gfp, ratio) { - var gfc = gfp.internal_flags; - if (gfc.channels_out > 1) { - for (var sb = 0; sb < Encoder.SBMAX_l; sb++) { - var l = gfc.thm[0].l[sb]; - var r = gfc.thm[1].l[sb]; - gfc.thm[0].l[sb] += r * ratio; - gfc.thm[1].l[sb] += l * ratio; - } - for (var sb = 0; sb < Encoder.SBMAX_s; sb++) { - for (var sblock = 0; sblock < 3; sblock++) { - var l = gfc.thm[0].s[sb][sblock]; - var r = gfc.thm[1].s[sb][sblock]; - gfc.thm[0].s[sb][sblock] += r * ratio; - gfc.thm[1].s[sb][sblock] += l * ratio; - } - } - } - } - - /** - * compute M/S thresholds from Johnston & Ferreira 1992 ICASSP paper - */ - function msfix1(gfc) { - for (var sb = 0; sb < Encoder.SBMAX_l; sb++) { - /* use this fix if L & R masking differs by 2db or less */ - /* if db = 10*log10(x2/x1) < 2 */ - /* if (x2 < 1.58*x1) { */ - if (gfc.thm[0].l[sb] > 1.58 * gfc.thm[1].l[sb] - || gfc.thm[1].l[sb] > 1.58 * gfc.thm[0].l[sb]) - continue; - var mld = gfc.mld_l[sb] * gfc.en[3].l[sb]; - var rmid = Math.max(gfc.thm[2].l[sb], - Math.min(gfc.thm[3].l[sb], mld)); - - mld = gfc.mld_l[sb] * gfc.en[2].l[sb]; - var rside = Math.max(gfc.thm[3].l[sb], - Math.min(gfc.thm[2].l[sb], mld)); - gfc.thm[2].l[sb] = rmid; - gfc.thm[3].l[sb] = rside; - } - - for (var sb = 0; sb < Encoder.SBMAX_s; sb++) { - for (var sblock = 0; sblock < 3; sblock++) { - if (gfc.thm[0].s[sb][sblock] > 1.58 * gfc.thm[1].s[sb][sblock] - || gfc.thm[1].s[sb][sblock] > 1.58 * gfc.thm[0].s[sb][sblock]) - continue; - var mld = gfc.mld_s[sb] * gfc.en[3].s[sb][sblock]; - var rmid = Math.max(gfc.thm[2].s[sb][sblock], - Math.min(gfc.thm[3].s[sb][sblock], mld)); - - mld = gfc.mld_s[sb] * gfc.en[2].s[sb][sblock]; - var rside = Math.max(gfc.thm[3].s[sb][sblock], - Math.min(gfc.thm[2].s[sb][sblock], mld)); - - gfc.thm[2].s[sb][sblock] = rmid; - gfc.thm[3].s[sb][sblock] = rside; - } - } - } - - /** - * Adjust M/S maskings if user set "msfix" - * - * Naoki Shibata 2000 - */ - function ns_msfix(gfc, msfix, athadjust) { - var msfix2 = msfix; - var athlower = Math.pow(10, athadjust); - - msfix *= 2.0; - msfix2 *= 2.0; - for (var sb = 0; sb < Encoder.SBMAX_l; sb++) { - var thmLR, thmM, thmS, ath; - ath = (gfc.ATH.cb_l[gfc.bm_l[sb]]) * athlower; - thmLR = Math.min(Math.max(gfc.thm[0].l[sb], ath), - Math.max(gfc.thm[1].l[sb], ath)); - thmM = Math.max(gfc.thm[2].l[sb], ath); - thmS = Math.max(gfc.thm[3].l[sb], ath); - if (thmLR * msfix < thmM + thmS) { - var f = thmLR * msfix2 / (thmM + thmS); - thmM *= f; - thmS *= f; - } - gfc.thm[2].l[sb] = Math.min(thmM, gfc.thm[2].l[sb]); - gfc.thm[3].l[sb] = Math.min(thmS, gfc.thm[3].l[sb]); - } - - athlower *= ( Encoder.BLKSIZE_s / Encoder.BLKSIZE); - for (var sb = 0; sb < Encoder.SBMAX_s; sb++) { - for (var sblock = 0; sblock < 3; sblock++) { - var thmLR, thmM, thmS, ath; - ath = (gfc.ATH.cb_s[gfc.bm_s[sb]]) * athlower; - thmLR = Math.min(Math.max(gfc.thm[0].s[sb][sblock], ath), - Math.max(gfc.thm[1].s[sb][sblock], ath)); - thmM = Math.max(gfc.thm[2].s[sb][sblock], ath); - thmS = Math.max(gfc.thm[3].s[sb][sblock], ath); - - if (thmLR * msfix < thmM + thmS) { - var f = thmLR * msfix / (thmM + thmS); - thmM *= f; - thmS *= f; - } - gfc.thm[2].s[sb][sblock] = Math.min(gfc.thm[2].s[sb][sblock], - thmM); - gfc.thm[3].s[sb][sblock] = Math.min(gfc.thm[3].s[sb][sblock], - thmS); - } - } - } - - /** - * short block threshold calculation (part 2) - * - * partition band bo_s[sfb] is at the transition from scalefactor band sfb - * to the next one sfb+1; enn and thmm have to be split between them - */ - function convert_partition2scalefac_s(gfc, eb, thr, chn, sblock) { - var sb, b; - var enn = 0.0; - var thmm = 0.0; - for (sb = b = 0; sb < Encoder.SBMAX_s; ++b, ++sb) { - var bo_s_sb = gfc.bo_s[sb]; - var npart_s = gfc.npart_s; - var b_lim = bo_s_sb < npart_s ? bo_s_sb : npart_s; - while (b < b_lim) { - // iff failed, it may indicate some index error elsewhere - enn += eb[b]; - thmm += thr[b]; - b++; - } - gfc.en[chn].s[sb][sblock] = enn; - gfc.thm[chn].s[sb][sblock] = thmm; - - if (b >= npart_s) { - ++sb; - break; - } - // iff failed, it may indicate some index error elsewhere - { - /* at transition sfb . sfb+1 */ - var w_curr = gfc.PSY.bo_s_weight[sb]; - var w_next = 1.0 - w_curr; - enn = w_curr * eb[b]; - thmm = w_curr * thr[b]; - gfc.en[chn].s[sb][sblock] += enn; - gfc.thm[chn].s[sb][sblock] += thmm; - enn = w_next * eb[b]; - thmm = w_next * thr[b]; - } - } - /* zero initialize the rest */ - for (; sb < Encoder.SBMAX_s; ++sb) { - gfc.en[chn].s[sb][sblock] = 0; - gfc.thm[chn].s[sb][sblock] = 0; - } - } - - /** - * longblock threshold calculation (part 2) - */ - function convert_partition2scalefac_l(gfc, eb, thr, chn) { - var sb, b; - var enn = 0.0; - var thmm = 0.0; - for (sb = b = 0; sb < Encoder.SBMAX_l; ++b, ++sb) { - var bo_l_sb = gfc.bo_l[sb]; - var npart_l = gfc.npart_l; - var b_lim = bo_l_sb < npart_l ? bo_l_sb : npart_l; - while (b < b_lim) { - // iff failed, it may indicate some index error elsewhere - enn += eb[b]; - thmm += thr[b]; - b++; - } - gfc.en[chn].l[sb] = enn; - gfc.thm[chn].l[sb] = thmm; - - if (b >= npart_l) { - ++sb; - break; - } - { - /* at transition sfb . sfb+1 */ - var w_curr = gfc.PSY.bo_l_weight[sb]; - var w_next = 1.0 - w_curr; - enn = w_curr * eb[b]; - thmm = w_curr * thr[b]; - gfc.en[chn].l[sb] += enn; - gfc.thm[chn].l[sb] += thmm; - enn = w_next * eb[b]; - thmm = w_next * thr[b]; - } - } - /* zero initialize the rest */ - for (; sb < Encoder.SBMAX_l; ++sb) { - gfc.en[chn].l[sb] = 0; - gfc.thm[chn].l[sb] = 0; - } - } - - function compute_masking_s(gfp, fftenergy_s, eb, thr, chn, sblock) { - var gfc = gfp.internal_flags; - var j, b; - - for (b = j = 0; b < gfc.npart_s; ++b) { - var ebb = 0, m = 0; - var n = gfc.numlines_s[b]; - for (var i = 0; i < n; ++i, ++j) { - var el = fftenergy_s[sblock][j]; - ebb += el; - if (m < el) - m = el; - } - eb[b] = ebb; - } - for (j = b = 0; b < gfc.npart_s; b++) { - var kk = gfc.s3ind_s[b][0]; - var ecb = gfc.s3_ss[j++] * eb[kk]; - ++kk; - while (kk <= gfc.s3ind_s[b][1]) { - ecb += gfc.s3_ss[j] * eb[kk]; - ++j; - ++kk; - } - - { /* limit calculated threshold by previous granule */ - var x = rpelev_s * gfc.nb_s1[chn][b]; - thr[b] = Math.min(ecb, x); - } - if (gfc.blocktype_old[chn & 1] == Encoder.SHORT_TYPE) { - /* limit calculated threshold by even older granule */ - var x = rpelev2_s * gfc.nb_s2[chn][b]; - var y = thr[b]; - thr[b] = Math.min(x, y); - } - - gfc.nb_s2[chn][b] = gfc.nb_s1[chn][b]; - gfc.nb_s1[chn][b] = ecb; - } - for (; b <= Encoder.CBANDS; ++b) { - eb[b] = 0; - thr[b] = 0; - } - } - - function block_type_set(gfp, uselongblock, blocktype_d, blocktype) { - var gfc = gfp.internal_flags; - - if (gfp.short_blocks == ShortBlock.short_block_coupled - /* force both channels to use the same block type */ - /* this is necessary if the frame is to be encoded in ms_stereo. */ - /* But even without ms_stereo, FhG does this */ - && !(uselongblock[0] != 0 && uselongblock[1] != 0)) - uselongblock[0] = uselongblock[1] = 0; - - /* - * update the blocktype of the previous granule, since it depends on - * what happend in this granule - */ - for (var chn = 0; chn < gfc.channels_out; chn++) { - blocktype[chn] = Encoder.NORM_TYPE; - /* disable short blocks */ - if (gfp.short_blocks == ShortBlock.short_block_dispensed) - uselongblock[chn] = 1; - if (gfp.short_blocks == ShortBlock.short_block_forced) - uselongblock[chn] = 0; - - if (uselongblock[chn] != 0) { - /* no attack : use long blocks */ - if (gfc.blocktype_old[chn] == Encoder.SHORT_TYPE) - blocktype[chn] = Encoder.STOP_TYPE; - } else { - /* attack : use short blocks */ - blocktype[chn] = Encoder.SHORT_TYPE; - if (gfc.blocktype_old[chn] == Encoder.NORM_TYPE) { - gfc.blocktype_old[chn] = Encoder.START_TYPE; - } - if (gfc.blocktype_old[chn] == Encoder.STOP_TYPE) - gfc.blocktype_old[chn] = Encoder.SHORT_TYPE; - } - - blocktype_d[chn] = gfc.blocktype_old[chn]; - // value returned to calling program - gfc.blocktype_old[chn] = blocktype[chn]; - // save for next call to l3psy_anal - } - } - - function NS_INTERP(x, y, r) { - /* was pow((x),(r))*pow((y),1-(r)) */ - if (r >= 1.0) { - /* 99.7% of the time */ - return x; - } - if (r <= 0.0) - return y; - if (y > 0.0) { - /* rest of the time */ - return (Math.pow(x / y, r) * y); - } - /* never happens */ - return 0.0; - } - - /** - * these values are tuned only for 44.1kHz... - */ - var regcoef_s = [11.8, 13.6, 17.2, 32, 46.5, - 51.3, 57.5, 67.1, 71.5, 84.6, 97.6, 130, - /* 255.8 */ - ]; - - function pecalc_s(mr, masking_lower) { - var pe_s = 1236.28 / 4; - for (var sb = 0; sb < Encoder.SBMAX_s - 1; sb++) { - for (var sblock = 0; sblock < 3; sblock++) { - var thm = mr.thm.s[sb][sblock]; - if (thm > 0.0) { - var x = thm * masking_lower; - var en = mr.en.s[sb][sblock]; - if (en > x) { - if (en > x * 1e10) { - pe_s += regcoef_s[sb] * (10.0 * LOG10); - } else { - pe_s += regcoef_s[sb] * Util.FAST_LOG10(en / x); - } - } - } - } - } - - return pe_s; - } - - /** - * these values are tuned only for 44.1kHz... - */ - var regcoef_l = [6.8, 5.8, 5.8, 6.4, 6.5, 9.9, - 12.1, 14.4, 15, 18.9, 21.6, 26.9, 34.2, 40.2, 46.8, 56.5, - 60.7, 73.9, 85.7, 93.4, 126.1, - /* 241.3 */ - ]; - - function pecalc_l(mr, masking_lower) { - var pe_l = 1124.23 / 4; - for (var sb = 0; sb < Encoder.SBMAX_l - 1; sb++) { - var thm = mr.thm.l[sb]; - if (thm > 0.0) { - var x = thm * masking_lower; - var en = mr.en.l[sb]; - if (en > x) { - if (en > x * 1e10) { - pe_l += regcoef_l[sb] * (10.0 * LOG10); - } else { - pe_l += regcoef_l[sb] * Util.FAST_LOG10(en / x); - } - } - } - } - return pe_l; - } - - function calc_energy(gfc, fftenergy, eb, max, avg) { - var b, j; - - for (b = j = 0; b < gfc.npart_l; ++b) { - var ebb = 0, m = 0; - var i; - for (i = 0; i < gfc.numlines_l[b]; ++i, ++j) { - var el = fftenergy[j]; - ebb += el; - if (m < el) - m = el; - } - eb[b] = ebb; - max[b] = m; - avg[b] = ebb * gfc.rnumlines_l[b]; - } - } - - function calc_mask_index_l(gfc, max, avg, mask_idx) { - var last_tab_entry = tab.length - 1; - var b = 0; - var a = avg[b] + avg[b + 1]; - if (a > 0.0) { - var m = max[b]; - if (m < max[b + 1]) - m = max[b + 1]; - a = 20.0 * (m * 2.0 - a) - / (a * (gfc.numlines_l[b] + gfc.numlines_l[b + 1] - 1)); - var k = 0 | a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - - for (b = 1; b < gfc.npart_l - 1; b++) { - a = avg[b - 1] + avg[b] + avg[b + 1]; - if (a > 0.0) { - var m = max[b - 1]; - if (m < max[b]) - m = max[b]; - if (m < max[b + 1]) - m = max[b + 1]; - a = 20.0 - * (m * 3.0 - a) - / (a * (gfc.numlines_l[b - 1] + gfc.numlines_l[b] - + gfc.numlines_l[b + 1] - 1)); - var k = 0 | a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - } - - a = avg[b - 1] + avg[b]; - if (a > 0.0) { - var m = max[b - 1]; - if (m < max[b]) - m = max[b]; - a = 20.0 * (m * 2.0 - a) - / (a * (gfc.numlines_l[b - 1] + gfc.numlines_l[b] - 1)); - var k = 0 | a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - } - - var fircoef = [ - -8.65163e-18 * 2, -0.00851586 * 2, -6.74764e-18 * 2, 0.0209036 * 2, - -3.36639e-17 * 2, -0.0438162 * 2, -1.54175e-17 * 2, 0.0931738 * 2, - -5.52212e-17 * 2, -0.313819 * 2 - ]; - - this.L3psycho_anal_ns = function (gfp, buffer, bufPos, gr_out, masking_ratio, masking_MS_ratio, percep_entropy, percep_MS_entropy, energy, blocktype_d) { - /* - * to get a good cache performance, one has to think about the sequence, - * in which the variables are used. - */ - var gfc = gfp.internal_flags; - - /* fft and energy calculation */ - var wsamp_L = new_float_n([2, Encoder.BLKSIZE]); - var wsamp_S = new_float_n([2, 3, Encoder.BLKSIZE_s]); - - /* convolution */ - var eb_l = new_float(Encoder.CBANDS + 1); - var eb_s = new_float(Encoder.CBANDS + 1); - var thr = new_float(Encoder.CBANDS + 2); - - /* block type */ - var blocktype = new_int(2), uselongblock = new_int(2); - - /* usual variables like loop indices, etc.. */ - var numchn, chn; - var b, i, j, k; - var sb, sblock; - - /* variables used for --nspsytune */ - var ns_hpfsmpl = new_float_n([2, 576]); - var pcfact; - var mask_idx_l = new_int(Encoder.CBANDS + 2), mask_idx_s = new_int(Encoder.CBANDS + 2); - - Arrays.fill(mask_idx_s, 0); - - numchn = gfc.channels_out; - /* chn=2 and 3 = Mid and Side channels */ - if (gfp.mode == MPEGMode.JOINT_STEREO) - numchn = 4; - - if (gfp.VBR == VbrMode.vbr_off) - pcfact = gfc.ResvMax == 0 ? 0 : ( gfc.ResvSize) - / gfc.ResvMax * 0.5; - else if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh - || gfp.VBR == VbrMode.vbr_mt) { - pcfact = 0.6; - } else - pcfact = 1.0; - - /********************************************************************** - * Apply HPF of fs/4 to the input signal. This is used for attack - * detection / handling. - **********************************************************************/ - /* Don't copy the input buffer into a temporary buffer */ - /* unroll the loop 2 times */ - for (chn = 0; chn < gfc.channels_out; chn++) { - /* apply high pass filter of fs/4 */ - var firbuf = buffer[chn]; - var firbufPos = bufPos + 576 - 350 - NSFIRLEN + 192; - for (i = 0; i < 576; i++) { - var sum1, sum2; - sum1 = firbuf[firbufPos + i + 10]; - sum2 = 0.0; - for (j = 0; j < ((NSFIRLEN - 1) / 2) - 1; j += 2) { - sum1 += fircoef[j] - * (firbuf[firbufPos + i + j] + firbuf[firbufPos + i - + NSFIRLEN - j]); - sum2 += fircoef[j + 1] - * (firbuf[firbufPos + i + j + 1] + firbuf[firbufPos - + i + NSFIRLEN - j - 1]); - } - ns_hpfsmpl[chn][i] = sum1 + sum2; - } - masking_ratio[gr_out][chn].en.assign(gfc.en[chn]); - masking_ratio[gr_out][chn].thm.assign(gfc.thm[chn]); - if (numchn > 2) { - /* MS maskings */ - /* percep_MS_entropy [chn-2] = gfc . pe [chn]; */ - masking_MS_ratio[gr_out][chn].en.assign(gfc.en[chn + 2]); - masking_MS_ratio[gr_out][chn].thm.assign(gfc.thm[chn + 2]); - } - } - - for (chn = 0; chn < numchn; chn++) { - var wsamp_l; - var wsamp_s; - var en_subshort = new_float(12); - var en_short = [0, 0, 0, 0]; - var attack_intensity = new_float(12); - var ns_uselongblock = 1; - var attackThreshold; - var max = new_float(Encoder.CBANDS), avg = new_float(Encoder.CBANDS); - var ns_attacks = [0, 0, 0, 0]; - var fftenergy = new_float(Encoder.HBLKSIZE); - var fftenergy_s = new_float_n([3, Encoder.HBLKSIZE_s]); - - /* - * rh 20040301: the following loops do access one off the limits so - * I increase the array dimensions by one and initialize the - * accessed values to zero - */ - - /*************************************************************** - * determine the block type (window type) - ***************************************************************/ - /* calculate energies of each sub-shortblocks */ - for (i = 0; i < 3; i++) { - en_subshort[i] = gfc.nsPsy.last_en_subshort[chn][i + 6]; - attack_intensity[i] = en_subshort[i] - / gfc.nsPsy.last_en_subshort[chn][i + 4]; - en_short[0] += en_subshort[i]; - } - - if (chn == 2) { - for (i = 0; i < 576; i++) { - var l, r; - l = ns_hpfsmpl[0][i]; - r = ns_hpfsmpl[1][i]; - ns_hpfsmpl[0][i] = l + r; - ns_hpfsmpl[1][i] = l - r; - } - } - { - var pf = ns_hpfsmpl[chn & 1]; - var pfPos = 0; - for (i = 0; i < 9; i++) { - var pfe = pfPos + 576 / 9; - var p = 1.; - for (; pfPos < pfe; pfPos++) - if (p < Math.abs(pf[pfPos])) - p = Math.abs(pf[pfPos]); - - gfc.nsPsy.last_en_subshort[chn][i] = en_subshort[i + 3] = p; - en_short[1 + i / 3] += p; - if (p > en_subshort[i + 3 - 2]) { - p = p / en_subshort[i + 3 - 2]; - } else if (en_subshort[i + 3 - 2] > p * 10.0) { - p = en_subshort[i + 3 - 2] / (p * 10.0); - } else - p = 0.0; - attack_intensity[i + 3] = p; - } - } - - if (gfp.analysis) { - var x = attack_intensity[0]; - for (i = 1; i < 12; i++) - if (x < attack_intensity[i]) - x = attack_intensity[i]; - gfc.pinfo.ers[gr_out][chn] = gfc.pinfo.ers_save[chn]; - gfc.pinfo.ers_save[chn] = x; - } - - /* compare energies between sub-shortblocks */ - attackThreshold = (chn == 3) ? gfc.nsPsy.attackthre_s - : gfc.nsPsy.attackthre; - for (i = 0; i < 12; i++) - if (0 == ns_attacks[i / 3] - && attack_intensity[i] > attackThreshold) - ns_attacks[i / 3] = (i % 3) + 1; - - /* - * should have energy change between short blocks, in order to avoid - * periodic signals - */ - for (i = 1; i < 4; i++) { - var ratio; - if (en_short[i - 1] > en_short[i]) { - ratio = en_short[i - 1] / en_short[i]; - } else { - ratio = en_short[i] / en_short[i - 1]; - } - if (ratio < 1.7) { - ns_attacks[i] = 0; - if (i == 1) - ns_attacks[0] = 0; - } - } - - if (ns_attacks[0] != 0 && gfc.nsPsy.lastAttacks[chn] != 0) - ns_attacks[0] = 0; - - if (gfc.nsPsy.lastAttacks[chn] == 3 - || (ns_attacks[0] + ns_attacks[1] + ns_attacks[2] + ns_attacks[3]) != 0) { - ns_uselongblock = 0; - - if (ns_attacks[1] != 0 && ns_attacks[0] != 0) - ns_attacks[1] = 0; - if (ns_attacks[2] != 0 && ns_attacks[1] != 0) - ns_attacks[2] = 0; - if (ns_attacks[3] != 0 && ns_attacks[2] != 0) - ns_attacks[3] = 0; - } - - if (chn < 2) { - uselongblock[chn] = ns_uselongblock; - } else { - if (ns_uselongblock == 0) { - uselongblock[0] = uselongblock[1] = 0; - } - } - - /* - * there is a one granule delay. Copy maskings computed last call - * into masking_ratio to return to calling program. - */ - energy[chn] = gfc.tot_ener[chn]; - - /********************************************************************* - * compute FFTs - *********************************************************************/ - wsamp_s = wsamp_S; - wsamp_l = wsamp_L; - compute_ffts(gfp, fftenergy, fftenergy_s, wsamp_l, (chn & 1), - wsamp_s, (chn & 1), gr_out, chn, buffer, bufPos); - - /********************************************************************* - * Calculate the energy and the tonality of each partition. - *********************************************************************/ - calc_energy(gfc, fftenergy, eb_l, max, avg); - calc_mask_index_l(gfc, max, avg, mask_idx_l); - /* compute masking thresholds for short blocks */ - for (sblock = 0; sblock < 3; sblock++) { - var enn, thmm; - compute_masking_s(gfp, fftenergy_s, eb_s, thr, chn, sblock); - convert_partition2scalefac_s(gfc, eb_s, thr, chn, sblock); - /**** short block pre-echo control ****/ - for (sb = 0; sb < Encoder.SBMAX_s; sb++) { - thmm = gfc.thm[chn].s[sb][sblock]; - - thmm *= NS_PREECHO_ATT0; - if (ns_attacks[sblock] >= 2 || ns_attacks[sblock + 1] == 1) { - var idx = (sblock != 0) ? sblock - 1 : 2; - var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT1 * pcfact); - thmm = Math.min(thmm, p); - } - - if (ns_attacks[sblock] == 1) { - var idx = (sblock != 0) ? sblock - 1 : 2; - var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT2 * pcfact); - thmm = Math.min(thmm, p); - } else if ((sblock != 0 && ns_attacks[sblock - 1] == 3) - || (sblock == 0 && gfc.nsPsy.lastAttacks[chn] == 3)) { - var idx = (sblock != 2) ? sblock + 1 : 0; - var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT2 * pcfact); - thmm = Math.min(thmm, p); - } - - /* pulse like signal detection for fatboy.wav and so on */ - enn = en_subshort[sblock * 3 + 3] - + en_subshort[sblock * 3 + 4] - + en_subshort[sblock * 3 + 5]; - if (en_subshort[sblock * 3 + 5] * 6 < enn) { - thmm *= 0.5; - if (en_subshort[sblock * 3 + 4] * 6 < enn) - thmm *= 0.5; - } - - gfc.thm[chn].s[sb][sblock] = thmm; - } - } - gfc.nsPsy.lastAttacks[chn] = ns_attacks[2]; - - /********************************************************************* - * convolve the partitioned energy and unpredictability with the - * spreading function, s3_l[b][k] - ********************************************************************/ - k = 0; - { - for (b = 0; b < gfc.npart_l; b++) { - /* - * convolve the partitioned energy with the spreading - * function - */ - var kk = gfc.s3ind[b][0]; - var eb2 = eb_l[kk] * tab[mask_idx_l[kk]]; - var ecb = gfc.s3_ll[k++] * eb2; - while (++kk <= gfc.s3ind[b][1]) { - eb2 = eb_l[kk] * tab[mask_idx_l[kk]]; - ecb = mask_add(ecb, gfc.s3_ll[k++] * eb2, kk, kk - b, - gfc, 0); - } - ecb *= 0.158489319246111; - /* pow(10,-0.8) */ - - /**** long block pre-echo control ****/ - /** - *
-                     * dont use long block pre-echo control if previous granule was
-                     * a short block.  This is to avoid the situation:
-                     * frame0:  quiet (very low masking)
-                     * frame1:  surge  (triggers short blocks)
-                     * frame2:  regular frame.  looks like pre-echo when compared to
-                     *          frame0, but all pre-echo was in frame1.
-                     * 
- */ - /* - * chn=0,1 L and R channels - * - * chn=2,3 S and M channels. - */ - - if (gfc.blocktype_old[chn & 1] == Encoder.SHORT_TYPE) - thr[b] = ecb; - else - thr[b] = NS_INTERP( - Math.min(ecb, Math.min(rpelev - * gfc.nb_1[chn][b], rpelev2 - * gfc.nb_2[chn][b])), ecb, pcfact); - - gfc.nb_2[chn][b] = gfc.nb_1[chn][b]; - gfc.nb_1[chn][b] = ecb; - } - } - for (; b <= Encoder.CBANDS; ++b) { - eb_l[b] = 0; - thr[b] = 0; - } - /* compute masking thresholds for long blocks */ - convert_partition2scalefac_l(gfc, eb_l, thr, chn); - } - /* end loop over chn */ - - if (gfp.mode == MPEGMode.STEREO || gfp.mode == MPEGMode.JOINT_STEREO) { - if (gfp.interChRatio > 0.0) { - calc_interchannel_masking(gfp, gfp.interChRatio); - } - } - - if (gfp.mode == MPEGMode.JOINT_STEREO) { - var msfix; - msfix1(gfc); - msfix = gfp.msfix; - if (Math.abs(msfix) > 0.0) - ns_msfix(gfc, msfix, gfp.ATHlower * gfc.ATH.adjust); - } - - /*************************************************************** - * determine final block type - ***************************************************************/ - block_type_set(gfp, uselongblock, blocktype_d, blocktype); - - /********************************************************************* - * compute the value of PE to return ... no delay and advance - *********************************************************************/ - for (chn = 0; chn < numchn; chn++) { - var ppe; - var ppePos = 0; - var type; - var mr; - - if (chn > 1) { - ppe = percep_MS_entropy; - ppePos = -2; - type = Encoder.NORM_TYPE; - if (blocktype_d[0] == Encoder.SHORT_TYPE - || blocktype_d[1] == Encoder.SHORT_TYPE) - type = Encoder.SHORT_TYPE; - mr = masking_MS_ratio[gr_out][chn - 2]; - } else { - ppe = percep_entropy; - ppePos = 0; - type = blocktype_d[chn]; - mr = masking_ratio[gr_out][chn]; - } - - if (type == Encoder.SHORT_TYPE) - ppe[ppePos + chn] = pecalc_s(mr, gfc.masking_lower); - else - ppe[ppePos + chn] = pecalc_l(mr, gfc.masking_lower); - - if (gfp.analysis) - gfc.pinfo.pe[gr_out][chn] = ppe[ppePos + chn]; - - } - return 0; - } - - function vbrpsy_compute_fft_l(gfp, buffer, bufPos, chn, gr_out, fftenergy, wsamp_l, wsamp_lPos) { - var gfc = gfp.internal_flags; - if (chn < 2) { - fft.fft_long(gfc, wsamp_l[wsamp_lPos], chn, buffer, bufPos); - } else if (chn == 2) { - /* FFT data for mid and side channel is derived from L & R */ - for (var j = Encoder.BLKSIZE - 1; j >= 0; --j) { - var l = wsamp_l[wsamp_lPos + 0][j]; - var r = wsamp_l[wsamp_lPos + 1][j]; - wsamp_l[wsamp_lPos + 0][j] = (l + r) * Util.SQRT2 * 0.5; - wsamp_l[wsamp_lPos + 1][j] = (l - r) * Util.SQRT2 * 0.5; - } - } - - /********************************************************************* - * compute energies - *********************************************************************/ - fftenergy[0] = NON_LINEAR_SCALE_ENERGY(wsamp_l[wsamp_lPos + 0][0]); - fftenergy[0] *= fftenergy[0]; - - for (var j = Encoder.BLKSIZE / 2 - 1; j >= 0; --j) { - var re = wsamp_l[wsamp_lPos + 0][Encoder.BLKSIZE / 2 - j]; - var im = wsamp_l[wsamp_lPos + 0][Encoder.BLKSIZE / 2 + j]; - fftenergy[Encoder.BLKSIZE / 2 - j] = NON_LINEAR_SCALE_ENERGY((re - * re + im * im) * 0.5); - } - /* total energy */ - { - var totalenergy = 0.0; - for (var j = 11; j < Encoder.HBLKSIZE; j++) - totalenergy += fftenergy[j]; - - gfc.tot_ener[chn] = totalenergy; - } - - if (gfp.analysis) { - for (var j = 0; j < Encoder.HBLKSIZE; j++) { - gfc.pinfo.energy[gr_out][chn][j] = gfc.pinfo.energy_save[chn][j]; - gfc.pinfo.energy_save[chn][j] = fftenergy[j]; - } - gfc.pinfo.pe[gr_out][chn] = gfc.pe[chn]; - } - } - - function vbrpsy_compute_fft_s(gfp, buffer, bufPos, chn, sblock, fftenergy_s, wsamp_s, wsamp_sPos) { - var gfc = gfp.internal_flags; - - if (sblock == 0 && chn < 2) { - fft.fft_short(gfc, wsamp_s[wsamp_sPos], chn, buffer, bufPos); - } - if (chn == 2) { - /* FFT data for mid and side channel is derived from L & R */ - for (var j = Encoder.BLKSIZE_s - 1; j >= 0; --j) { - var l = wsamp_s[wsamp_sPos + 0][sblock][j]; - var r = wsamp_s[wsamp_sPos + 1][sblock][j]; - wsamp_s[wsamp_sPos + 0][sblock][j] = (l + r) * Util.SQRT2 * 0.5; - wsamp_s[wsamp_sPos + 1][sblock][j] = (l - r) * Util.SQRT2 * 0.5; - } - } - - /********************************************************************* - * compute energies - *********************************************************************/ - fftenergy_s[sblock][0] = wsamp_s[wsamp_sPos + 0][sblock][0]; - fftenergy_s[sblock][0] *= fftenergy_s[sblock][0]; - for (var j = Encoder.BLKSIZE_s / 2 - 1; j >= 0; --j) { - var re = wsamp_s[wsamp_sPos + 0][sblock][Encoder.BLKSIZE_s / 2 - j]; - var im = wsamp_s[wsamp_sPos + 0][sblock][Encoder.BLKSIZE_s / 2 + j]; - fftenergy_s[sblock][Encoder.BLKSIZE_s / 2 - j] = NON_LINEAR_SCALE_ENERGY((re - * re + im * im) * 0.5); - } - } - - /** - * compute loudness approximation (used for ATH auto-level adjustment) - */ - function vbrpsy_compute_loudness_approximation_l(gfp, gr_out, chn, fftenergy) { - var gfc = gfp.internal_flags; - if (gfp.athaa_loudapprox == 2 && chn < 2) { - // no loudness for mid/side ch - gfc.loudness_sq[gr_out][chn] = gfc.loudness_sq_save[chn]; - gfc.loudness_sq_save[chn] = psycho_loudness_approx(fftenergy, gfc); - } - } - - var fircoef_ = [-8.65163e-18 * 2, - -0.00851586 * 2, -6.74764e-18 * 2, 0.0209036 * 2, - -3.36639e-17 * 2, -0.0438162 * 2, -1.54175e-17 * 2, - 0.0931738 * 2, -5.52212e-17 * 2, -0.313819 * 2]; - - /** - * Apply HPF of fs/4 to the input signal. This is used for attack detection - * / handling. - */ - function vbrpsy_attack_detection(gfp, buffer, bufPos, gr_out, masking_ratio, masking_MS_ratio, energy, sub_short_factor, ns_attacks, uselongblock) { - var ns_hpfsmpl = new_float_n([2, 576]); - var gfc = gfp.internal_flags; - var n_chn_out = gfc.channels_out; - /* chn=2 and 3 = Mid and Side channels */ - var n_chn_psy = (gfp.mode == MPEGMode.JOINT_STEREO) ? 4 : n_chn_out; - /* Don't copy the input buffer into a temporary buffer */ - /* unroll the loop 2 times */ - for (var chn = 0; chn < n_chn_out; chn++) { - /* apply high pass filter of fs/4 */ - firbuf = buffer[chn]; - var firbufPos = bufPos + 576 - 350 - NSFIRLEN + 192; - for (var i = 0; i < 576; i++) { - var sum1, sum2; - sum1 = firbuf[firbufPos + i + 10]; - sum2 = 0.0; - for (var j = 0; j < ((NSFIRLEN - 1) / 2) - 1; j += 2) { - sum1 += fircoef_[j] - * (firbuf[firbufPos + i + j] + firbuf[firbufPos + i - + NSFIRLEN - j]); - sum2 += fircoef_[j + 1] - * (firbuf[firbufPos + i + j + 1] + firbuf[firbufPos - + i + NSFIRLEN - j - 1]); - } - ns_hpfsmpl[chn][i] = sum1 + sum2; - } - masking_ratio[gr_out][chn].en.assign(gfc.en[chn]); - masking_ratio[gr_out][chn].thm.assign(gfc.thm[chn]); - if (n_chn_psy > 2) { - /* MS maskings */ - /* percep_MS_entropy [chn-2] = gfc . pe [chn]; */ - masking_MS_ratio[gr_out][chn].en.assign(gfc.en[chn + 2]); - masking_MS_ratio[gr_out][chn].thm.assign(gfc.thm[chn + 2]); - } - } - for (var chn = 0; chn < n_chn_psy; chn++) { - var attack_intensity = new_float(12); - var en_subshort = new_float(12); - var en_short = [0, 0, 0, 0]; - var pf = ns_hpfsmpl[chn & 1]; - var pfPos = 0; - var attackThreshold = (chn == 3) ? gfc.nsPsy.attackthre_s - : gfc.nsPsy.attackthre; - var ns_uselongblock = 1; - - if (chn == 2) { - for (var i = 0, j = 576; j > 0; ++i, --j) { - var l = ns_hpfsmpl[0][i]; - var r = ns_hpfsmpl[1][i]; - ns_hpfsmpl[0][i] = l + r; - ns_hpfsmpl[1][i] = l - r; - } - } - /*************************************************************** - * determine the block type (window type) - ***************************************************************/ - /* calculate energies of each sub-shortblocks */ - for (var i = 0; i < 3; i++) { - en_subshort[i] = gfc.nsPsy.last_en_subshort[chn][i + 6]; - attack_intensity[i] = en_subshort[i] - / gfc.nsPsy.last_en_subshort[chn][i + 4]; - en_short[0] += en_subshort[i]; - } - - for (var i = 0; i < 9; i++) { - var pfe = pfPos + 576 / 9; - var p = 1.; - for (; pfPos < pfe; pfPos++) - if (p < Math.abs(pf[pfPos])) - p = Math.abs(pf[pfPos]); - - gfc.nsPsy.last_en_subshort[chn][i] = en_subshort[i + 3] = p; - en_short[1 + i / 3] += p; - if (p > en_subshort[i + 3 - 2]) { - p = p / en_subshort[i + 3 - 2]; - } else if (en_subshort[i + 3 - 2] > p * 10.0) { - p = en_subshort[i + 3 - 2] / (p * 10.0); - } else { - p = 0.0; - } - attack_intensity[i + 3] = p; - } - /* pulse like signal detection for fatboy.wav and so on */ - for (var i = 0; i < 3; ++i) { - var enn = en_subshort[i * 3 + 3] - + en_subshort[i * 3 + 4] + en_subshort[i * 3 + 5]; - var factor = 1.; - if (en_subshort[i * 3 + 5] * 6 < enn) { - factor *= 0.5; - if (en_subshort[i * 3 + 4] * 6 < enn) { - factor *= 0.5; - } - } - sub_short_factor[chn][i] = factor; - } - - if (gfp.analysis) { - var x = attack_intensity[0]; - for (var i = 1; i < 12; i++) { - if (x < attack_intensity[i]) { - x = attack_intensity[i]; - } - } - gfc.pinfo.ers[gr_out][chn] = gfc.pinfo.ers_save[chn]; - gfc.pinfo.ers_save[chn] = x; - } - - /* compare energies between sub-shortblocks */ - for (var i = 0; i < 12; i++) { - if (0 == ns_attacks[chn][i / 3] - && attack_intensity[i] > attackThreshold) { - ns_attacks[chn][i / 3] = (i % 3) + 1; - } - } - - /* - * should have energy change between short blocks, in order to avoid - * periodic signals - */ - /* Good samples to show the effect are Trumpet test songs */ - /* - * GB: tuned (1) to avoid too many short blocks for test sample - * TRUMPET - */ - /* - * RH: tuned (2) to let enough short blocks through for test sample - * FSOL and SNAPS - */ - for (var i = 1; i < 4; i++) { - var u = en_short[i - 1]; - var v = en_short[i]; - var m = Math.max(u, v); - if (m < 40000) { /* (2) */ - if (u < 1.7 * v && v < 1.7 * u) { /* (1) */ - if (i == 1 && ns_attacks[chn][0] <= ns_attacks[chn][i]) { - ns_attacks[chn][0] = 0; - } - ns_attacks[chn][i] = 0; - } - } - } - - if (ns_attacks[chn][0] <= gfc.nsPsy.lastAttacks[chn]) { - ns_attacks[chn][0] = 0; - } - - if (gfc.nsPsy.lastAttacks[chn] == 3 - || (ns_attacks[chn][0] + ns_attacks[chn][1] - + ns_attacks[chn][2] + ns_attacks[chn][3]) != 0) { - ns_uselongblock = 0; - - if (ns_attacks[chn][1] != 0 && ns_attacks[chn][0] != 0) { - ns_attacks[chn][1] = 0; - } - if (ns_attacks[chn][2] != 0 && ns_attacks[chn][1] != 0) { - ns_attacks[chn][2] = 0; - } - if (ns_attacks[chn][3] != 0 && ns_attacks[chn][2] != 0) { - ns_attacks[chn][3] = 0; - } - } - if (chn < 2) { - uselongblock[chn] = ns_uselongblock; - } else { - if (ns_uselongblock == 0) { - uselongblock[0] = uselongblock[1] = 0; - } - } - - /* - * there is a one granule delay. Copy maskings computed last call - * into masking_ratio to return to calling program. - */ - energy[chn] = gfc.tot_ener[chn]; - } - } - - function vbrpsy_skip_masking_s(gfc, chn, sblock) { - if (sblock == 0) { - for (var b = 0; b < gfc.npart_s; b++) { - gfc.nb_s2[chn][b] = gfc.nb_s1[chn][b]; - gfc.nb_s1[chn][b] = 0; - } - } - } - - function vbrpsy_skip_masking_l(gfc, chn) { - for (var b = 0; b < gfc.npart_l; b++) { - gfc.nb_2[chn][b] = gfc.nb_1[chn][b]; - gfc.nb_1[chn][b] = 0; - } - } - - function psyvbr_calc_mask_index_s(gfc, max, avg, mask_idx) { - var last_tab_entry = tab.length - 1; - var b = 0; - var a = avg[b] + avg[b + 1]; - if (a > 0.0) { - var m = max[b]; - if (m < max[b + 1]) - m = max[b + 1]; - a = 20.0 * (m * 2.0 - a) - / (a * (gfc.numlines_s[b] + gfc.numlines_s[b + 1] - 1)); - var k = 0 | a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - - for (b = 1; b < gfc.npart_s - 1; b++) { - a = avg[b - 1] + avg[b] + avg[b + 1]; - if (a > 0.0) { - var m = max[b - 1]; - if (m < max[b]) - m = max[b]; - if (m < max[b + 1]) - m = max[b + 1]; - a = 20.0 - * (m * 3.0 - a) - / (a * (gfc.numlines_s[b - 1] + gfc.numlines_s[b] - + gfc.numlines_s[b + 1] - 1)); - var k = 0 | a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - } - - a = avg[b - 1] + avg[b]; - if (a > 0.0) { - var m = max[b - 1]; - if (m < max[b]) - m = max[b]; - a = 20.0 * (m * 2.0 - a) - / (a * (gfc.numlines_s[b - 1] + gfc.numlines_s[b] - 1)); - var k = 0 | a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - } - - function vbrpsy_compute_masking_s(gfp, fftenergy_s, eb, thr, chn, sblock) { - var gfc = gfp.internal_flags; - var max = new float[Encoder.CBANDS], avg = new_float(Encoder.CBANDS); - var i, j, b; - var mask_idx_s = new int[Encoder.CBANDS]; - - for (b = j = 0; b < gfc.npart_s; ++b) { - var ebb = 0, m = 0; - var n = gfc.numlines_s[b]; - for (i = 0; i < n; ++i, ++j) { - var el = fftenergy_s[sblock][j]; - ebb += el; - if (m < el) - m = el; - } - eb[b] = ebb; - max[b] = m; - avg[b] = ebb / n; - } - for (; b < Encoder.CBANDS; ++b) { - max[b] = 0; - avg[b] = 0; - } - psyvbr_calc_mask_index_s(gfc, max, avg, mask_idx_s); - for (j = b = 0; b < gfc.npart_s; b++) { - var kk = gfc.s3ind_s[b][0]; - var last = gfc.s3ind_s[b][1]; - var dd, dd_n; - var x, ecb, avg_mask; - dd = mask_idx_s[kk]; - dd_n = 1; - ecb = gfc.s3_ss[j] * eb[kk] * tab[mask_idx_s[kk]]; - ++j; - ++kk; - while (kk <= last) { - dd += mask_idx_s[kk]; - dd_n += 1; - x = gfc.s3_ss[j] * eb[kk] * tab[mask_idx_s[kk]]; - ecb = vbrpsy_mask_add(ecb, x, kk - b); - ++j; - ++kk; - } - dd = (1 + 2 * dd) / (2 * dd_n); - avg_mask = tab[dd] * 0.5; - ecb *= avg_mask; - thr[b] = ecb; - gfc.nb_s2[chn][b] = gfc.nb_s1[chn][b]; - gfc.nb_s1[chn][b] = ecb; - { - /* - * if THR exceeds EB, the quantization routines will take the - * difference from other bands. in case of strong tonal samples - * (tonaltest.wav) this leads to heavy distortions. that's why - * we limit THR here. - */ - x = max[b]; - x *= gfc.minval_s[b]; - x *= avg_mask; - if (thr[b] > x) { - thr[b] = x; - } - } - if (gfc.masking_lower > 1) { - thr[b] *= gfc.masking_lower; - } - if (thr[b] > eb[b]) { - thr[b] = eb[b]; - } - if (gfc.masking_lower < 1) { - thr[b] *= gfc.masking_lower; - } - - } - for (; b < Encoder.CBANDS; ++b) { - eb[b] = 0; - thr[b] = 0; - } - } - - function vbrpsy_compute_masking_l(gfc, fftenergy, eb_l, thr, chn) { - var max = new_float(Encoder.CBANDS), avg = new_float(Encoder.CBANDS); - var mask_idx_l = new_int(Encoder.CBANDS + 2); - var b; - - /********************************************************************* - * Calculate the energy and the tonality of each partition. - *********************************************************************/ - calc_energy(gfc, fftenergy, eb_l, max, avg); - calc_mask_index_l(gfc, max, avg, mask_idx_l); - - /********************************************************************* - * convolve the partitioned energy and unpredictability with the - * spreading function, s3_l[b][k] - ********************************************************************/ - var k = 0; - for (b = 0; b < gfc.npart_l; b++) { - var x, ecb, avg_mask, t; - /* convolve the partitioned energy with the spreading function */ - var kk = gfc.s3ind[b][0]; - var last = gfc.s3ind[b][1]; - var dd = 0, dd_n = 0; - dd = mask_idx_l[kk]; - dd_n += 1; - ecb = gfc.s3_ll[k] * eb_l[kk] * tab[mask_idx_l[kk]]; - ++k; - ++kk; - while (kk <= last) { - dd += mask_idx_l[kk]; - dd_n += 1; - x = gfc.s3_ll[k] * eb_l[kk] * tab[mask_idx_l[kk]]; - t = vbrpsy_mask_add(ecb, x, kk - b); - ecb = t; - ++k; - ++kk; - } - dd = (1 + 2 * dd) / (2 * dd_n); - avg_mask = tab[dd] * 0.5; - ecb *= avg_mask; - - /**** long block pre-echo control ****/ - /** - *
-             * dont use long block pre-echo control if previous granule was
-             * a short block.  This is to avoid the situation:
-             * frame0:  quiet (very low masking)
-             * frame1:  surge  (triggers short blocks)
-             * frame2:  regular frame.  looks like pre-echo when compared to
-             *          frame0, but all pre-echo was in frame1.
-             * 
- */ - /* - * chn=0,1 L and R channels chn=2,3 S and M channels. - */ - if (gfc.blocktype_old[chn & 0x01] == Encoder.SHORT_TYPE) { - var ecb_limit = rpelev * gfc.nb_1[chn][b]; - if (ecb_limit > 0) { - thr[b] = Math.min(ecb, ecb_limit); - } else { - /** - *
-                     * Robert 071209:
-                     * Because we don't calculate long block psy when we know a granule
-                     * should be of short blocks, we don't have any clue how the granule
-                     * before would have looked like as a long block. So we have to guess
-                     * a little bit for this END_TYPE block.
-                     * Most of the time we get away with this sloppyness. (fingers crossed :)
-                     * The speed increase is worth it.
-                     * 
- */ - thr[b] = Math.min(ecb, eb_l[b] * NS_PREECHO_ATT2); - } - } else { - var ecb_limit_2 = rpelev2 * gfc.nb_2[chn][b]; - var ecb_limit_1 = rpelev * gfc.nb_1[chn][b]; - var ecb_limit; - if (ecb_limit_2 <= 0) { - ecb_limit_2 = ecb; - } - if (ecb_limit_1 <= 0) { - ecb_limit_1 = ecb; - } - if (gfc.blocktype_old[chn & 0x01] == Encoder.NORM_TYPE) { - ecb_limit = Math.min(ecb_limit_1, ecb_limit_2); - } else { - ecb_limit = ecb_limit_1; - } - thr[b] = Math.min(ecb, ecb_limit); - } - gfc.nb_2[chn][b] = gfc.nb_1[chn][b]; - gfc.nb_1[chn][b] = ecb; - { - /* - * if THR exceeds EB, the quantization routines will take the - * difference from other bands. in case of strong tonal samples - * (tonaltest.wav) this leads to heavy distortions. that's why - * we limit THR here. - */ - x = max[b]; - x *= gfc.minval_l[b]; - x *= avg_mask; - if (thr[b] > x) { - thr[b] = x; - } - } - if (gfc.masking_lower > 1) { - thr[b] *= gfc.masking_lower; - } - if (thr[b] > eb_l[b]) { - thr[b] = eb_l[b]; - } - if (gfc.masking_lower < 1) { - thr[b] *= gfc.masking_lower; - } - } - for (; b < Encoder.CBANDS; ++b) { - eb_l[b] = 0; - thr[b] = 0; - } - } - - function vbrpsy_compute_block_type(gfp, uselongblock) { - var gfc = gfp.internal_flags; - - if (gfp.short_blocks == ShortBlock.short_block_coupled - /* force both channels to use the same block type */ - /* this is necessary if the frame is to be encoded in ms_stereo. */ - /* But even without ms_stereo, FhG does this */ - && !(uselongblock[0] != 0 && uselongblock[1] != 0)) - uselongblock[0] = uselongblock[1] = 0; - - for (var chn = 0; chn < gfc.channels_out; chn++) { - /* disable short blocks */ - if (gfp.short_blocks == ShortBlock.short_block_dispensed) { - uselongblock[chn] = 1; - } - if (gfp.short_blocks == ShortBlock.short_block_forced) { - uselongblock[chn] = 0; - } - } - } - - function vbrpsy_apply_block_type(gfp, uselongblock, blocktype_d) { - var gfc = gfp.internal_flags; - - /* - * update the blocktype of the previous granule, since it depends on - * what happend in this granule - */ - for (var chn = 0; chn < gfc.channels_out; chn++) { - var blocktype = Encoder.NORM_TYPE; - /* disable short blocks */ - - if (uselongblock[chn] != 0) { - /* no attack : use long blocks */ - if (gfc.blocktype_old[chn] == Encoder.SHORT_TYPE) - blocktype = Encoder.STOP_TYPE; - } else { - /* attack : use short blocks */ - blocktype = Encoder.SHORT_TYPE; - if (gfc.blocktype_old[chn] == Encoder.NORM_TYPE) { - gfc.blocktype_old[chn] = Encoder.START_TYPE; - } - if (gfc.blocktype_old[chn] == Encoder.STOP_TYPE) - gfc.blocktype_old[chn] = Encoder.SHORT_TYPE; - } - - blocktype_d[chn] = gfc.blocktype_old[chn]; - // value returned to calling program - gfc.blocktype_old[chn] = blocktype; - // save for next call to l3psy_anal - } - } - - /** - * compute M/S thresholds from Johnston & Ferreira 1992 ICASSP paper - */ - function vbrpsy_compute_MS_thresholds(eb, thr, cb_mld, ath_cb, athadjust, msfix, n) { - var msfix2 = msfix * 2; - var athlower = msfix > 0 ? Math.pow(10, athadjust) : 1; - var rside, rmid; - for (var b = 0; b < n; ++b) { - var ebM = eb[2][b]; - var ebS = eb[3][b]; - var thmL = thr[0][b]; - var thmR = thr[1][b]; - var thmM = thr[2][b]; - var thmS = thr[3][b]; - - /* use this fix if L & R masking differs by 2db or less */ - if (thmL <= 1.58 * thmR && thmR <= 1.58 * thmL) { - var mld_m = cb_mld[b] * ebS; - var mld_s = cb_mld[b] * ebM; - rmid = Math.max(thmM, Math.min(thmS, mld_m)); - rside = Math.max(thmS, Math.min(thmM, mld_s)); - } else { - rmid = thmM; - rside = thmS; - } - if (msfix > 0) { - /***************************************************************/ - /* Adjust M/S maskings if user set "msfix" */ - /***************************************************************/ - /* Naoki Shibata 2000 */ - var thmLR, thmMS; - var ath = ath_cb[b] * athlower; - thmLR = Math.min(Math.max(thmL, ath), Math.max(thmR, ath)); - thmM = Math.max(rmid, ath); - thmS = Math.max(rside, ath); - thmMS = thmM + thmS; - if (thmMS > 0 && (thmLR * msfix2) < thmMS) { - var f = thmLR * msfix2 / thmMS; - thmM *= f; - thmS *= f; - } - rmid = Math.min(thmM, rmid); - rside = Math.min(thmS, rside); - } - if (rmid > ebM) { - rmid = ebM; - } - if (rside > ebS) { - rside = ebS; - } - thr[2][b] = rmid; - thr[3][b] = rside; - } - } - - this.L3psycho_anal_vbr = function (gfp, buffer, bufPos, gr_out, masking_ratio, masking_MS_ratio, percep_entropy, percep_MS_entropy, energy, blocktype_d) { - var gfc = gfp.internal_flags; - - /* fft and energy calculation */ - var wsamp_l; - var wsamp_s; - var fftenergy = new_float(Encoder.HBLKSIZE); - var fftenergy_s = new_float_n([3, Encoder.HBLKSIZE_s]); - var wsamp_L = new_float_n([2, Encoder.BLKSIZE]); - var wsamp_S = new_float_n([2, 3, Encoder.BLKSIZE_s]); - var eb = new_float_n([4, Encoder.CBANDS]), thr = new_float_n([4, Encoder.CBANDS]); - var sub_short_factor = new_float_n([4, 3]); - var pcfact = 0.6; - - /* block type */ - var ns_attacks = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], - [0, 0, 0, 0]]; - var uselongblock = new_int(2); - - /* usual variables like loop indices, etc.. */ - - /* chn=2 and 3 = Mid and Side channels */ - var n_chn_psy = (gfp.mode == MPEGMode.JOINT_STEREO) ? 4 - : gfc.channels_out; - - vbrpsy_attack_detection(gfp, buffer, bufPos, gr_out, masking_ratio, - masking_MS_ratio, energy, sub_short_factor, ns_attacks, - uselongblock); - - vbrpsy_compute_block_type(gfp, uselongblock); - - /* LONG BLOCK CASE */ - { - for (var chn = 0; chn < n_chn_psy; chn++) { - var ch01 = chn & 0x01; - wsamp_l = wsamp_L; - vbrpsy_compute_fft_l(gfp, buffer, bufPos, chn, gr_out, - fftenergy, wsamp_l, ch01); - - vbrpsy_compute_loudness_approximation_l(gfp, gr_out, chn, - fftenergy); - - if (uselongblock[ch01] != 0) { - vbrpsy_compute_masking_l(gfc, fftenergy, eb[chn], thr[chn], - chn); - } else { - vbrpsy_skip_masking_l(gfc, chn); - } - } - if ((uselongblock[0] + uselongblock[1]) == 2) { - /* M/S channel */ - if (gfp.mode == MPEGMode.JOINT_STEREO) { - vbrpsy_compute_MS_thresholds(eb, thr, gfc.mld_cb_l, - gfc.ATH.cb_l, gfp.ATHlower * gfc.ATH.adjust, - gfp.msfix, gfc.npart_l); - } - } - /* TODO: apply adaptive ATH masking here ?? */ - for (var chn = 0; chn < n_chn_psy; chn++) { - var ch01 = chn & 0x01; - if (uselongblock[ch01] != 0) { - convert_partition2scalefac_l(gfc, eb[chn], thr[chn], chn); - } - } - } - - /* SHORT BLOCKS CASE */ - { - for (var sblock = 0; sblock < 3; sblock++) { - for (var chn = 0; chn < n_chn_psy; ++chn) { - var ch01 = chn & 0x01; - - if (uselongblock[ch01] != 0) { - vbrpsy_skip_masking_s(gfc, chn, sblock); - } else { - /* compute masking thresholds for short blocks */ - wsamp_s = wsamp_S; - vbrpsy_compute_fft_s(gfp, buffer, bufPos, chn, sblock, - fftenergy_s, wsamp_s, ch01); - vbrpsy_compute_masking_s(gfp, fftenergy_s, eb[chn], - thr[chn], chn, sblock); - } - } - if ((uselongblock[0] + uselongblock[1]) == 0) { - /* M/S channel */ - if (gfp.mode == MPEGMode.JOINT_STEREO) { - vbrpsy_compute_MS_thresholds(eb, thr, gfc.mld_cb_s, - gfc.ATH.cb_s, gfp.ATHlower * gfc.ATH.adjust, - gfp.msfix, gfc.npart_s); - } - /* L/R channel */ - } - /* TODO: apply adaptive ATH masking here ?? */ - for (var chn = 0; chn < n_chn_psy; ++chn) { - var ch01 = chn & 0x01; - if (0 == uselongblock[ch01]) { - convert_partition2scalefac_s(gfc, eb[chn], thr[chn], - chn, sblock); - } - } - } - - /**** short block pre-echo control ****/ - for (var chn = 0; chn < n_chn_psy; chn++) { - var ch01 = chn & 0x01; - - if (uselongblock[ch01] != 0) { - continue; - } - for (var sb = 0; sb < Encoder.SBMAX_s; sb++) { - var new_thmm = new_float(3); - for (var sblock = 0; sblock < 3; sblock++) { - var thmm = gfc.thm[chn].s[sb][sblock]; - thmm *= NS_PREECHO_ATT0; - - if (ns_attacks[chn][sblock] >= 2 - || ns_attacks[chn][sblock + 1] == 1) { - var idx = (sblock != 0) ? sblock - 1 : 2; - var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT1 * pcfact); - thmm = Math.min(thmm, p); - } else if (ns_attacks[chn][sblock] == 1) { - var idx = (sblock != 0) ? sblock - 1 : 2; - var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT2 * pcfact); - thmm = Math.min(thmm, p); - } else if ((sblock != 0 && ns_attacks[chn][sblock - 1] == 3) - || (sblock == 0 && gfc.nsPsy.lastAttacks[chn] == 3)) { - var idx = (sblock != 2) ? sblock + 1 : 0; - var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT2 * pcfact); - thmm = Math.min(thmm, p); - } - - /* pulse like signal detection for fatboy.wav and so on */ - thmm *= sub_short_factor[chn][sblock]; - - new_thmm[sblock] = thmm; - } - for (var sblock = 0; sblock < 3; sblock++) { - gfc.thm[chn].s[sb][sblock] = new_thmm[sblock]; - } - } - } - } - for (var chn = 0; chn < n_chn_psy; chn++) { - gfc.nsPsy.lastAttacks[chn] = ns_attacks[chn][2]; - } - - /*************************************************************** - * determine final block type - ***************************************************************/ - vbrpsy_apply_block_type(gfp, uselongblock, blocktype_d); - - /********************************************************************* - * compute the value of PE to return ... no delay and advance - *********************************************************************/ - for (var chn = 0; chn < n_chn_psy; chn++) { - var ppe; - var ppePos; - var type; - var mr; - - if (chn > 1) { - ppe = percep_MS_entropy; - ppePos = -2; - type = Encoder.NORM_TYPE; - if (blocktype_d[0] == Encoder.SHORT_TYPE - || blocktype_d[1] == Encoder.SHORT_TYPE) - type = Encoder.SHORT_TYPE; - mr = masking_MS_ratio[gr_out][chn - 2]; - } else { - ppe = percep_entropy; - ppePos = 0; - type = blocktype_d[chn]; - mr = masking_ratio[gr_out][chn]; - } - - if (type == Encoder.SHORT_TYPE) { - ppe[ppePos + chn] = pecalc_s(mr, gfc.masking_lower); - } else { - ppe[ppePos + chn] = pecalc_l(mr, gfc.masking_lower); - } - - if (gfp.analysis) { - gfc.pinfo.pe[gr_out][chn] = ppe[ppePos + chn]; - } - } - return 0; - } - - function s3_func_x(bark, hf_slope) { - var tempx = bark, tempy; - - if (tempx >= 0) { - tempy = -tempx * 27; - } else { - tempy = tempx * hf_slope; - } - if (tempy <= -72.0) { - return 0; - } - return Math.exp(tempy * LN_TO_LOG10); - } - - function norm_s3_func_x(hf_slope) { - var lim_a = 0, lim_b = 0; - { - var x = 0, l, h; - for (x = 0; s3_func_x(x, hf_slope) > 1e-20; x -= 1) - ; - l = x; - h = 0; - while (Math.abs(h - l) > 1e-12) { - x = (h + l) / 2; - if (s3_func_x(x, hf_slope) > 0) { - h = x; - } else { - l = x; - } - } - lim_a = l; - } - { - var x = 0, l, h; - for (x = 0; s3_func_x(x, hf_slope) > 1e-20; x += 1) - ; - l = 0; - h = x; - while (Math.abs(h - l) > 1e-12) { - x = (h + l) / 2; - if (s3_func_x(x, hf_slope) > 0) { - l = x; - } else { - h = x; - } - } - lim_b = h; - } - { - var sum = 0; - var m = 1000; - var i; - for (i = 0; i <= m; ++i) { - var x = lim_a + i * (lim_b - lim_a) / m; - var y = s3_func_x(x, hf_slope); - sum += y; - } - { - var norm = (m + 1) / (sum * (lim_b - lim_a)); - /* printf( "norm = %lf\n",norm); */ - return norm; - } - } - } - - /** - * The spreading function. Values returned in units of energy - */ - function s3_func(bark) { - var tempx, x, tempy, temp; - tempx = bark; - if (tempx >= 0) - tempx *= 3; - else - tempx *= 1.5; - - if (tempx >= 0.5 && tempx <= 2.5) { - temp = tempx - 0.5; - x = 8.0 * (temp * temp - 2.0 * temp); - } else - x = 0.0; - tempx += 0.474; - tempy = 15.811389 + 7.5 * tempx - 17.5 - * Math.sqrt(1.0 + tempx * tempx); - - if (tempy <= -60.0) - return 0.0; - - tempx = Math.exp((x + tempy) * LN_TO_LOG10); - - /** - *
-         * Normalization.  The spreading function should be normalized so that:
-         * +inf
-         * /
-         * |  s3 [ bark ]  d(bark)   =  1
-         * /
-         * -inf
-         * 
- */ - tempx /= .6609193; - return tempx; - } - - /** - * see for example "Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 - */ - function freq2bark(freq) { - /* input: freq in hz output: barks */ - if (freq < 0) - freq = 0; - freq = freq * 0.001; - return 13.0 * Math.atan(.76 * freq) + 3.5 - * Math.atan(freq * freq / (7.5 * 7.5)); - } - - function init_numline(numlines, bo, bm, bval, bval_width, mld, bo_w, sfreq, blksize, scalepos, deltafreq, sbmax) { - var b_frq = new_float(Encoder.CBANDS + 1); - var sample_freq_frac = sfreq / (sbmax > 15 ? 2 * 576 : 2 * 192); - var partition = new_int(Encoder.HBLKSIZE); - var i; - sfreq /= blksize; - var j = 0; - var ni = 0; - /* compute numlines, the number of spectral lines in each partition band */ - /* each partition band should be about DELBARK wide. */ - for (i = 0; i < Encoder.CBANDS; i++) { - var bark1; - var j2; - bark1 = freq2bark(sfreq * j); - - b_frq[i] = sfreq * j; - - for (j2 = j; freq2bark(sfreq * j2) - bark1 < DELBARK - && j2 <= blksize / 2; j2++) - ; - - numlines[i] = j2 - j; - ni = i + 1; - - while (j < j2) { - partition[j++] = i; - } - if (j > blksize / 2) { - j = blksize / 2; - ++i; - break; - } - } - b_frq[i] = sfreq * j; - - for (var sfb = 0; sfb < sbmax; sfb++) { - var i1, i2, start, end; - var arg; - start = scalepos[sfb]; - end = scalepos[sfb + 1]; - - i1 = 0 | Math.floor(.5 + deltafreq * (start - .5)); - if (i1 < 0) - i1 = 0; - i2 = 0 | Math.floor(.5 + deltafreq * (end - .5)); - - if (i2 > blksize / 2) - i2 = blksize / 2; - - bm[sfb] = (partition[i1] + partition[i2]) / 2; - bo[sfb] = partition[i2]; - var f_tmp = sample_freq_frac * end; - /* - * calculate how much of this band belongs to current scalefactor - * band - */ - bo_w[sfb] = (f_tmp - b_frq[bo[sfb]]) - / (b_frq[bo[sfb] + 1] - b_frq[bo[sfb]]); - if (bo_w[sfb] < 0) { - bo_w[sfb] = 0; - } else { - if (bo_w[sfb] > 1) { - bo_w[sfb] = 1; - } - } - /* setup stereo demasking thresholds */ - /* formula reverse enginerred from plot in paper */ - arg = freq2bark(sfreq * scalepos[sfb] * deltafreq); - arg = ( Math.min(arg, 15.5) / 15.5); - - mld[sfb] = Math.pow(10.0, - 1.25 * (1 - Math.cos(Math.PI * arg)) - 2.5); - } - - /* compute bark values of each critical band */ - j = 0; - for (var k = 0; k < ni; k++) { - var w = numlines[k]; - var bark1, bark2; - - bark1 = freq2bark(sfreq * (j)); - bark2 = freq2bark(sfreq * (j + w - 1)); - bval[k] = .5 * (bark1 + bark2); - - bark1 = freq2bark(sfreq * (j - .5)); - bark2 = freq2bark(sfreq * (j + w - .5)); - bval_width[k] = bark2 - bark1; - j += w; - } - - return ni; - } - - function init_s3_values(s3ind, npart, bval, bval_width, norm, use_old_s3) { - var s3 = new_float_n([Encoder.CBANDS, Encoder.CBANDS]); - /* - * The s3 array is not linear in the bark scale. - * - * bval[x] should be used to get the bark value. - */ - var j; - var numberOfNoneZero = 0; - - /** - *
-         * s[i][j], the value of the spreading function,
-         * centered at band j (masker), for band i (maskee)
-         *
-         * i.e.: sum over j to spread into signal barkval=i
-         * NOTE: i and j are used opposite as in the ISO docs
-         * 
- */ - if (use_old_s3) { - for (var i = 0; i < npart; i++) { - for (j = 0; j < npart; j++) { - var v = s3_func(bval[i] - bval[j]) * bval_width[j]; - s3[i][j] = v * norm[i]; - } - } - } else { - for (j = 0; j < npart; j++) { - var hf_slope = 15 + Math.min(21 / bval[j], 12); - var s3_x_norm = norm_s3_func_x(hf_slope); - for (var i = 0; i < npart; i++) { - var v = s3_x_norm - * s3_func_x(bval[i] - bval[j], hf_slope) - * bval_width[j]; - s3[i][j] = v * norm[i]; - } - } - } - for (var i = 0; i < npart; i++) { - for (j = 0; j < npart; j++) { - if (s3[i][j] > 0.0) - break; - } - s3ind[i][0] = j; - - for (j = npart - 1; j > 0; j--) { - if (s3[i][j] > 0.0) - break; - } - s3ind[i][1] = j; - numberOfNoneZero += (s3ind[i][1] - s3ind[i][0] + 1); - } - - var p = new_float(numberOfNoneZero); - var k = 0; - for (var i = 0; i < npart; i++) - for (j = s3ind[i][0]; j <= s3ind[i][1]; j++) - p[k++] = s3[i][j]; - - return p; - } - - function stereo_demask(f) { - /* setup stereo demasking thresholds */ - /* formula reverse enginerred from plot in paper */ - var arg = freq2bark(f); - arg = (Math.min(arg, 15.5) / 15.5); - - return Math.pow(10.0, - 1.25 * (1 - Math.cos(Math.PI * arg)) - 2.5); - } - - /** - * NOTE: the bitrate reduction from the inter-channel masking effect is low - * compared to the chance of getting annyoing artefacts. L3psycho_anal_vbr - * does not use this feature. (Robert 071216) - */ - this.psymodel_init = function (gfp) { - var gfc = gfp.internal_flags; - var i; - var useOldS3 = true; - var bvl_a = 13, bvl_b = 24; - var snr_l_a = 0, snr_l_b = 0; - var snr_s_a = -8.25, snr_s_b = -4.5; - var bval = new_float(Encoder.CBANDS); - var bval_width = new_float(Encoder.CBANDS); - var norm = new_float(Encoder.CBANDS); - var sfreq = gfp.out_samplerate; - - switch (gfp.experimentalZ) { - default: - case 0: - useOldS3 = true; - break; - case 1: - useOldS3 = (gfp.VBR == VbrMode.vbr_mtrh || gfp.VBR == VbrMode.vbr_mt) ? false - : true; - break; - case 2: - useOldS3 = false; - break; - case 3: - bvl_a = 8; - snr_l_a = -1.75; - snr_l_b = -0.0125; - snr_s_a = -8.25; - snr_s_b = -2.25; - break; - } - gfc.ms_ener_ratio_old = .25; - gfc.blocktype_old[0] = gfc.blocktype_old[1] = Encoder.NORM_TYPE; - // the vbr header is long blocks - - for (i = 0; i < 4; ++i) { - for (var j = 0; j < Encoder.CBANDS; ++j) { - gfc.nb_1[i][j] = 1e20; - gfc.nb_2[i][j] = 1e20; - gfc.nb_s1[i][j] = gfc.nb_s2[i][j] = 1.0; - } - for (var sb = 0; sb < Encoder.SBMAX_l; sb++) { - gfc.en[i].l[sb] = 1e20; - gfc.thm[i].l[sb] = 1e20; - } - for (var j = 0; j < 3; ++j) { - for (var sb = 0; sb < Encoder.SBMAX_s; sb++) { - gfc.en[i].s[sb][j] = 1e20; - gfc.thm[i].s[sb][j] = 1e20; - } - gfc.nsPsy.lastAttacks[i] = 0; - } - for (var j = 0; j < 9; j++) - gfc.nsPsy.last_en_subshort[i][j] = 10.; - } - - /* init. for loudness approx. -jd 2001 mar 27 */ - gfc.loudness_sq_save[0] = gfc.loudness_sq_save[1] = 0.0; - - /************************************************************************* - * now compute the psychoacoustic model specific constants - ************************************************************************/ - /* compute numlines, bo, bm, bval, bval_width, mld */ - - gfc.npart_l = init_numline(gfc.numlines_l, gfc.bo_l, gfc.bm_l, bval, - bval_width, gfc.mld_l, gfc.PSY.bo_l_weight, sfreq, - Encoder.BLKSIZE, gfc.scalefac_band.l, Encoder.BLKSIZE - / (2.0 * 576), Encoder.SBMAX_l); - /* compute the spreading function */ - for (i = 0; i < gfc.npart_l; i++) { - var snr = snr_l_a; - if (bval[i] >= bvl_a) { - snr = snr_l_b * (bval[i] - bvl_a) / (bvl_b - bvl_a) + snr_l_a - * (bvl_b - bval[i]) / (bvl_b - bvl_a); - } - norm[i] = Math.pow(10.0, snr / 10.0); - if (gfc.numlines_l[i] > 0) { - gfc.rnumlines_l[i] = 1.0 / gfc.numlines_l[i]; - } else { - gfc.rnumlines_l[i] = 0; - } - } - gfc.s3_ll = init_s3_values(gfc.s3ind, gfc.npart_l, bval, bval_width, - norm, useOldS3); - - /* compute long block specific values, ATH and MINVAL */ - var j = 0; - for (i = 0; i < gfc.npart_l; i++) { - var x; - - /* ATH */ - x = Float.MAX_VALUE; - for (var k = 0; k < gfc.numlines_l[i]; k++, j++) { - var freq = sfreq * j / (1000.0 * Encoder.BLKSIZE); - var level; - /* - * ATH below 100 Hz constant, not further climbing - */ - level = this.ATHformula(freq * 1000, gfp) - 20; - // scale to FFT units; returned value is in dB - level = Math.pow(10., 0.1 * level); - // convert from dB . energy - level *= gfc.numlines_l[i]; - if (x > level) - x = level; - } - gfc.ATH.cb_l[i] = x; - - /* - * MINVAL. For low freq, the strength of the masking is limited by - * minval this is an ISO MPEG1 thing, dont know if it is really - * needed - */ - /* - * FIXME: it does work to reduce low-freq problems in S53-Wind-Sax - * and lead-voice samples, but introduces some 3 kbps bit bloat too. - * TODO: Further refinement of the shape of this hack. - */ - x = -20 + bval[i] * 20 / 10; - if (x > 6) { - x = 100; - } - if (x < -15) { - x = -15; - } - x -= 8.; - gfc.minval_l[i] = (Math.pow(10.0, x / 10.) * gfc.numlines_l[i]); - } - - /************************************************************************ - * do the same things for short blocks - ************************************************************************/ - gfc.npart_s = init_numline(gfc.numlines_s, gfc.bo_s, gfc.bm_s, bval, - bval_width, gfc.mld_s, gfc.PSY.bo_s_weight, sfreq, - Encoder.BLKSIZE_s, gfc.scalefac_band.s, Encoder.BLKSIZE_s - / (2.0 * 192), Encoder.SBMAX_s); - - /* SNR formula. short block is normalized by SNR. is it still right ? */ - j = 0; - for (i = 0; i < gfc.npart_s; i++) { - var x; - var snr = snr_s_a; - if (bval[i] >= bvl_a) { - snr = snr_s_b * (bval[i] - bvl_a) / (bvl_b - bvl_a) + snr_s_a - * (bvl_b - bval[i]) / (bvl_b - bvl_a); - } - norm[i] = Math.pow(10.0, snr / 10.0); - - /* ATH */ - x = Float.MAX_VALUE; - for (var k = 0; k < gfc.numlines_s[i]; k++, j++) { - var freq = sfreq * j / (1000.0 * Encoder.BLKSIZE_s); - var level; - /* freq = Min(.1,freq); */ - /* - * ATH below 100 Hz constant, not - * further climbing - */ - level = this.ATHformula(freq * 1000, gfp) - 20; - // scale to FFT units; returned value is in dB - level = Math.pow(10., 0.1 * level); - // convert from dB . energy - level *= gfc.numlines_s[i]; - if (x > level) - x = level; - } - gfc.ATH.cb_s[i] = x; - - /* - * MINVAL. For low freq, the strength of the masking is limited by - * minval this is an ISO MPEG1 thing, dont know if it is really - * needed - */ - x = (-7.0 + bval[i] * 7.0 / 12.0); - if (bval[i] > 12) { - x *= 1 + Math.log(1 + x) * 3.1; - } - if (bval[i] < 12) { - x *= 1 + Math.log(1 - x) * 2.3; - } - if (x < -15) { - x = -15; - } - x -= 8; - gfc.minval_s[i] = Math.pow(10.0, x / 10) - * gfc.numlines_s[i]; - } - - gfc.s3_ss = init_s3_values(gfc.s3ind_s, gfc.npart_s, bval, bval_width, - norm, useOldS3); - - init_mask_add_max_values(); - fft.init_fft(gfc); - - /* setup temporal masking */ - gfc.decay = Math.exp(-1.0 * LOG10 - / (temporalmask_sustain_sec * sfreq / 192.0)); - - { - var msfix; - msfix = NS_MSFIX; - if ((gfp.exp_nspsytune & 2) != 0) - msfix = 1.0; - if (Math.abs(gfp.msfix) > 0.0) - msfix = gfp.msfix; - gfp.msfix = msfix; - - /* - * spread only from npart_l bands. Normally, we use the spreading - * function to convolve from npart_l down to npart_l bands - */ - for (var b = 0; b < gfc.npart_l; b++) - if (gfc.s3ind[b][1] > gfc.npart_l - 1) - gfc.s3ind[b][1] = gfc.npart_l - 1; - } - - /* - * prepare for ATH auto adjustment: we want to decrease the ATH by 12 dB - * per second - */ - var frame_duration = (576. * gfc.mode_gr / sfreq); - gfc.ATH.decay = Math.pow(10., -12. / 10. * frame_duration); - gfc.ATH.adjust = 0.01; - /* minimum, for leading low loudness */ - gfc.ATH.adjustLimit = 1.0; - /* on lead, allow adjust up to maximum */ - - - if (gfp.ATHtype != -1) { - /* compute equal loudness weights (eql_w) */ - var freq; - var freq_inc = gfp.out_samplerate - / (Encoder.BLKSIZE); - var eql_balance = 0.0; - freq = 0.0; - for (i = 0; i < Encoder.BLKSIZE / 2; ++i) { - /* convert ATH dB to relative power (not dB) */ - /* to determine eql_w */ - freq += freq_inc; - gfc.ATH.eql_w[i] = 1. / Math.pow(10, this.ATHformula(freq, gfp) / 10); - eql_balance += gfc.ATH.eql_w[i]; - } - eql_balance = 1.0 / eql_balance; - for (i = Encoder.BLKSIZE / 2; --i >= 0;) { /* scale weights */ - gfc.ATH.eql_w[i] *= eql_balance; - } - } - { - for (var b = j = 0; b < gfc.npart_s; ++b) { - for (i = 0; i < gfc.numlines_s[b]; ++i) { - ++j; - } - } - for (var b = j = 0; b < gfc.npart_l; ++b) { - for (i = 0; i < gfc.numlines_l[b]; ++i) { - ++j; - } - } - } - j = 0; - for (i = 0; i < gfc.npart_l; i++) { - var freq = sfreq * (j + gfc.numlines_l[i] / 2) / (1.0 * Encoder.BLKSIZE); - gfc.mld_cb_l[i] = stereo_demask(freq); - j += gfc.numlines_l[i]; - } - for (; i < Encoder.CBANDS; ++i) { - gfc.mld_cb_l[i] = 1; - } - j = 0; - for (i = 0; i < gfc.npart_s; i++) { - var freq = sfreq * (j + gfc.numlines_s[i] / 2) / (1.0 * Encoder.BLKSIZE_s); - gfc.mld_cb_s[i] = stereo_demask(freq); - j += gfc.numlines_s[i]; - } - for (; i < Encoder.CBANDS; ++i) { - gfc.mld_cb_s[i] = 1; - } - return 0; - } - - /** - * Those ATH formulas are returning their minimum value for input = -1 - */ - function ATHformula_GB(f, value) { - /** - *
-         *  from Painter & Spanias
-         *           modified by Gabriel Bouvigne to better fit the reality
-         *           ath =    3.640 * pow(f,-0.8)
-         *           - 6.800 * exp(-0.6*pow(f-3.4,2.0))
-         *           + 6.000 * exp(-0.15*pow(f-8.7,2.0))
-         *           + 0.6* 0.001 * pow(f,4.0);
-         *
-         *
-         *           In the past LAME was using the Painter &Spanias formula.
-         *           But we had some recurrent problems with HF content.
-         *           We measured real ATH values, and found the older formula
-         *           to be inaccurate in the higher part. So we made this new
-         *           formula and this solved most of HF problematic test cases.
-         *           The tradeoff is that in VBR mode it increases a lot the
-         *           bitrate.
-         * 
- */ - - /* - * This curve can be adjusted according to the VBR scale: it adjusts - * from something close to Painter & Spanias on V9 up to Bouvigne's - * formula for V0. This way the VBR bitrate is more balanced according - * to the -V value. - */ - - // the following Hack allows to ask for the lowest value - if (f < -.3) - f = 3410; - - // convert to khz - f /= 1000; - f = Math.max(0.1, f); - var ath = 3.640 * Math.pow(f, -0.8) - 6.800 - * Math.exp(-0.6 * Math.pow(f - 3.4, 2.0)) + 6.000 - * Math.exp(-0.15 * Math.pow(f - 8.7, 2.0)) - + (0.6 + 0.04 * value) * 0.001 * Math.pow(f, 4.0); - return ath; - } - - this.ATHformula = function (f, gfp) { - var ath; - switch (gfp.ATHtype) { - case 0: - ath = ATHformula_GB(f, 9); - break; - case 1: - // over sensitive, should probably be removed - ath = ATHformula_GB(f, -1); - break; - case 2: - ath = ATHformula_GB(f, 0); - break; - case 3: - // modification of GB formula by Roel - ath = ATHformula_GB(f, 1) + 6; - break; - case 4: - ath = ATHformula_GB(f, gfp.ATHcurve); - break; - default: - ath = ATHformula_GB(f, 0); - break; - } - return ath; - } - -} - - - -function Lame() { - var self = this; - var LAME_MAXALBUMART = (128 * 1024); - - Lame.V9 = 410; - Lame.V8 = 420; - Lame.V7 = 430; - Lame.V6 = 440; - Lame.V5 = 450; - Lame.V4 = 460; - Lame.V3 = 470; - Lame.V2 = 480; - Lame.V1 = 490; - Lame.V0 = 500; - - /* still there for compatibility */ - - Lame.R3MIX = 1000; - Lame.STANDARD = 1001; - Lame.EXTREME = 1002; - Lame.INSANE = 1003; - Lame.STANDARD_FAST = 1004; - Lame.EXTREME_FAST = 1005; - Lame.MEDIUM = 1006; - Lame.MEDIUM_FAST = 1007; - - /** - * maximum size of mp3buffer needed if you encode at most 1152 samples for - * each call to lame_encode_buffer. see lame_encode_buffer() below - * (LAME_MAXMP3BUFFER is now obsolete) - */ - var LAME_MAXMP3BUFFER = (16384 + LAME_MAXALBUMART); - Lame.LAME_MAXMP3BUFFER = LAME_MAXMP3BUFFER; - - var ga; - var bs; - var p; - var qupvt; - var qu; - var psy = new PsyModel(); - var vbr; - var ver; - var id3; - var mpglib; - this.enc = new Encoder(); - - this.setModules = function (_ga, _bs, _p, _qupvt, _qu, _vbr, _ver, _id3, _mpglib) { - ga = _ga; - bs = _bs; - p = _p; - qupvt = _qupvt; - qu = _qu; - vbr = _vbr; - ver = _ver; - id3 = _id3; - mpglib = _mpglib; - this.enc.setModules(bs, psy, qupvt, vbr); - } - - /** - * PSY Model related stuff - */ - function PSY() { - /** - * The dbQ stuff. - */ - this.mask_adjust = 0.; - /** - * The dbQ stuff. - */ - this.mask_adjust_short = 0.; - /* at transition from one scalefactor band to next */ - /** - * Band weight long scalefactor bands. - */ - this.bo_l_weight = new_float(Encoder.SBMAX_l); - /** - * Band weight short scalefactor bands. - */ - this.bo_s_weight = new_float(Encoder.SBMAX_s); - } - - function LowPassHighPass() { - this.lowerlimit = 0.; - } - - function BandPass(bitrate, lPass) { - this.lowpass = lPass; - } - - var LAME_ID = 0xFFF88E3B; - - function lame_init_old(gfp) { - var gfc; - - gfp.class_id = LAME_ID; - - gfc = gfp.internal_flags = new LameInternalFlags(); - - /* Global flags. set defaults here for non-zero values */ - /* see lame.h for description */ - /* - * set integer values to -1 to mean that LAME will compute the best - * value, UNLESS the calling program as set it (and the value is no - * longer -1) - */ - - gfp.mode = MPEGMode.NOT_SET; - gfp.original = 1; - gfp.in_samplerate = 44100; - gfp.num_channels = 2; - gfp.num_samples = -1; - - gfp.bWriteVbrTag = true; - gfp.quality = -1; - gfp.short_blocks = null; - gfc.subblock_gain = -1; - - gfp.lowpassfreq = 0; - gfp.highpassfreq = 0; - gfp.lowpasswidth = -1; - gfp.highpasswidth = -1; - - gfp.VBR = VbrMode.vbr_off; - gfp.VBR_q = 4; - gfp.ATHcurve = -1; - gfp.VBR_mean_bitrate_kbps = 128; - gfp.VBR_min_bitrate_kbps = 0; - gfp.VBR_max_bitrate_kbps = 0; - gfp.VBR_hard_min = 0; - gfc.VBR_min_bitrate = 1; - /* not 0 ????? */ - gfc.VBR_max_bitrate = 13; - /* not 14 ????? */ - - gfp.quant_comp = -1; - gfp.quant_comp_short = -1; - - gfp.msfix = -1; - - gfc.resample_ratio = 1; - - gfc.OldValue[0] = 180; - gfc.OldValue[1] = 180; - gfc.CurrentStep[0] = 4; - gfc.CurrentStep[1] = 4; - gfc.masking_lower = 1; - gfc.nsPsy.attackthre = -1; - gfc.nsPsy.attackthre_s = -1; - - gfp.scale = -1; - - gfp.athaa_type = -1; - gfp.ATHtype = -1; - /* default = -1 = set in lame_init_params */ - gfp.athaa_loudapprox = -1; - /* 1 = flat loudness approx. (total energy) */ - /* 2 = equal loudness curve */ - gfp.athaa_sensitivity = 0.0; - /* no offset */ - gfp.useTemporal = null; - gfp.interChRatio = -1; - - /* - * The reason for int mf_samples_to_encode = ENCDELAY + POSTDELAY; - * ENCDELAY = internal encoder delay. And then we have to add - * POSTDELAY=288 because of the 50% MDCT overlap. A 576 MDCT granule - * decodes to 1152 samples. To synthesize the 576 samples centered under - * this granule we need the previous granule for the first 288 samples - * (no problem), and the next granule for the next 288 samples (not - * possible if this is last granule). So we need to pad with 288 samples - * to make sure we can encode the 576 samples we are interested in. - */ - gfc.mf_samples_to_encode = Encoder.ENCDELAY + Encoder.POSTDELAY; - gfp.encoder_padding = 0; - gfc.mf_size = Encoder.ENCDELAY - Encoder.MDCTDELAY; - /* - * we pad input with this many 0's - */ - - gfp.findReplayGain = false; - gfp.decode_on_the_fly = false; - - gfc.decode_on_the_fly = false; - gfc.findReplayGain = false; - gfc.findPeakSample = false; - - gfc.RadioGain = 0; - gfc.AudiophileGain = 0; - gfc.noclipGainChange = 0; - gfc.noclipScale = -1.0; - - gfp.preset = 0; - - gfp.write_id3tag_automatic = true; - return 0; - } - - this.lame_init = function () { - var gfp = new LameGlobalFlags(); - - var ret = lame_init_old(gfp); - if (ret != 0) { - return null; - } - - gfp.lame_allocated_gfp = 1; - return gfp; - } - - function filter_coef(x) { - if (x > 1.0) - return 0.0; - if (x <= 0.0) - return 1.0; - - return Math.cos(Math.PI / 2 * x); - } - - this.nearestBitrateFullIndex = function (bitrate) { - /* borrowed from DM abr presets */ - - var full_bitrate_table = [8, 16, 24, 32, 40, 48, 56, 64, 80, - 96, 112, 128, 160, 192, 224, 256, 320]; - - var lower_range = 0, lower_range_kbps = 0, upper_range = 0, upper_range_kbps = 0; - - /* We assume specified bitrate will be 320kbps */ - upper_range_kbps = full_bitrate_table[16]; - upper_range = 16; - lower_range_kbps = full_bitrate_table[16]; - lower_range = 16; - - /* - * Determine which significant bitrates the value specified falls - * between, if loop ends without breaking then we were correct above - * that the value was 320 - */ - for (var b = 0; b < 16; b++) { - if ((Math.max(bitrate, full_bitrate_table[b + 1])) != bitrate) { - upper_range_kbps = full_bitrate_table[b + 1]; - upper_range = b + 1; - lower_range_kbps = full_bitrate_table[b]; - lower_range = (b); - break; - /* We found upper range */ - } - } - - /* Determine which range the value specified is closer to */ - if ((upper_range_kbps - bitrate) > (bitrate - lower_range_kbps)) { - return lower_range; - } - return upper_range; - } - - function optimum_samplefreq(lowpassfreq, input_samplefreq) { - /* - * Rules: - * - * - if possible, sfb21 should NOT be used - */ - var suggested_samplefreq = 44100; - - if (input_samplefreq >= 48000) - suggested_samplefreq = 48000; - else if (input_samplefreq >= 44100) - suggested_samplefreq = 44100; - else if (input_samplefreq >= 32000) - suggested_samplefreq = 32000; - else if (input_samplefreq >= 24000) - suggested_samplefreq = 24000; - else if (input_samplefreq >= 22050) - suggested_samplefreq = 22050; - else if (input_samplefreq >= 16000) - suggested_samplefreq = 16000; - else if (input_samplefreq >= 12000) - suggested_samplefreq = 12000; - else if (input_samplefreq >= 11025) - suggested_samplefreq = 11025; - else if (input_samplefreq >= 8000) - suggested_samplefreq = 8000; - - if (lowpassfreq == -1) - return suggested_samplefreq; - - if (lowpassfreq <= 15960) - suggested_samplefreq = 44100; - if (lowpassfreq <= 15250) - suggested_samplefreq = 32000; - if (lowpassfreq <= 11220) - suggested_samplefreq = 24000; - if (lowpassfreq <= 9970) - suggested_samplefreq = 22050; - if (lowpassfreq <= 7230) - suggested_samplefreq = 16000; - if (lowpassfreq <= 5420) - suggested_samplefreq = 12000; - if (lowpassfreq <= 4510) - suggested_samplefreq = 11025; - if (lowpassfreq <= 3970) - suggested_samplefreq = 8000; - - if (input_samplefreq < suggested_samplefreq) { - /* - * choose a valid MPEG sample frequency above the input sample - * frequency to avoid SFB21/12 bitrate bloat rh 061115 - */ - if (input_samplefreq > 44100) { - return 48000; - } - if (input_samplefreq > 32000) { - return 44100; - } - if (input_samplefreq > 24000) { - return 32000; - } - if (input_samplefreq > 22050) { - return 24000; - } - if (input_samplefreq > 16000) { - return 22050; - } - if (input_samplefreq > 12000) { - return 16000; - } - if (input_samplefreq > 11025) { - return 12000; - } - if (input_samplefreq > 8000) { - return 11025; - } - return 8000; - } - return suggested_samplefreq; - } - - /** - * convert samp freq in Hz to index - */ - function SmpFrqIndex(sample_freq, gpf) { - switch (sample_freq) { - case 44100: - gpf.version = 1; - return 0; - case 48000: - gpf.version = 1; - return 1; - case 32000: - gpf.version = 1; - return 2; - case 22050: - gpf.version = 0; - return 0; - case 24000: - gpf.version = 0; - return 1; - case 16000: - gpf.version = 0; - return 2; - case 11025: - gpf.version = 0; - return 0; - case 12000: - gpf.version = 0; - return 1; - case 8000: - gpf.version = 0; - return 2; - default: - gpf.version = 0; - return -1; - } - } - - /** - * @param bRate - * legal rates from 8 to 320 - */ - function FindNearestBitrate(bRate, version, samplerate) { - /* MPEG-1 or MPEG-2 LSF */ - if (samplerate < 16000) - version = 2; - - var bitrate = Tables.bitrate_table[version][1]; - - for (var i = 2; i <= 14; i++) { - if (Tables.bitrate_table[version][i] > 0) { - if (Math.abs(Tables.bitrate_table[version][i] - bRate) < Math - .abs(bitrate - bRate)) - bitrate = Tables.bitrate_table[version][i]; - } - } - return bitrate; - } - - /** - * @param bRate - * legal rates from 32 to 448 kbps - * @param version - * MPEG-1 or MPEG-2/2.5 LSF - */ - function BitrateIndex(bRate, version, samplerate) { - /* convert bitrate in kbps to index */ - if (samplerate < 16000) - version = 2; - for (var i = 0; i <= 14; i++) { - if (Tables.bitrate_table[version][i] > 0) { - if (Tables.bitrate_table[version][i] == bRate) { - return i; - } - } - } - return -1; - } - - function optimum_bandwidth(lh, bitrate) { - /** - *
-         *  Input:
-         *      bitrate     total bitrate in kbps
-         *
-         *   Output:
-         *      lowerlimit: best lowpass frequency limit for input filter in Hz
-         *      upperlimit: best highpass frequency limit for input filter in Hz
-         * 
- */ - var freq_map = [new BandPass(8, 2000), - new BandPass(16, 3700), new BandPass(24, 3900), - new BandPass(32, 5500), new BandPass(40, 7000), - new BandPass(48, 7500), new BandPass(56, 10000), - new BandPass(64, 11000), new BandPass(80, 13500), - new BandPass(96, 15100), new BandPass(112, 15600), - new BandPass(128, 17000), new BandPass(160, 17500), - new BandPass(192, 18600), new BandPass(224, 19400), - new BandPass(256, 19700), new BandPass(320, 20500)]; - - var table_index = self.nearestBitrateFullIndex(bitrate); - lh.lowerlimit = freq_map[table_index].lowpass; - } - - function lame_init_params_ppflt(gfp) { - var gfc = gfp.internal_flags; - /***************************************************************/ - /* compute info needed for polyphase filter (filter type==0, default) */ - /***************************************************************/ - - var lowpass_band = 32; - var highpass_band = -1; - - if (gfc.lowpass1 > 0) { - var minband = 999; - for (var band = 0; band <= 31; band++) { - var freq = (band / 31.0); - /* this band and above will be zeroed: */ - if (freq >= gfc.lowpass2) { - lowpass_band = Math.min(lowpass_band, band); - } - if (gfc.lowpass1 < freq && freq < gfc.lowpass2) { - minband = Math.min(minband, band); - } - } - - /* - * compute the *actual* transition band implemented by the polyphase - * filter - */ - if (minband == 999) { - gfc.lowpass1 = (lowpass_band - .75) / 31.0; - } else { - gfc.lowpass1 = (minband - .75) / 31.0; - } - gfc.lowpass2 = lowpass_band / 31.0; - } - - /* - * make sure highpass filter is within 90% of what the effective - * highpass frequency will be - */ - if (gfc.highpass2 > 0) { - if (gfc.highpass2 < .9 * (.75 / 31.0)) { - gfc.highpass1 = 0; - gfc.highpass2 = 0; - System.err.println("Warning: highpass filter disabled. " - + "highpass frequency too small\n"); - } - } - - if (gfc.highpass2 > 0) { - var maxband = -1; - for (var band = 0; band <= 31; band++) { - var freq = band / 31.0; - /* this band and below will be zereod */ - if (freq <= gfc.highpass1) { - highpass_band = Math.max(highpass_band, band); - } - if (gfc.highpass1 < freq && freq < gfc.highpass2) { - maxband = Math.max(maxband, band); - } - } - /* - * compute the *actual* transition band implemented by the polyphase - * filter - */ - gfc.highpass1 = highpass_band / 31.0; - if (maxband == -1) { - gfc.highpass2 = (highpass_band + .75) / 31.0; - } else { - gfc.highpass2 = (maxband + .75) / 31.0; - } - } - - for (var band = 0; band < 32; band++) { - var fc1, fc2; - var freq = band / 31.0; - if (gfc.highpass2 > gfc.highpass1) { - fc1 = filter_coef((gfc.highpass2 - freq) - / (gfc.highpass2 - gfc.highpass1 + 1e-20)); - } else { - fc1 = 1.0; - } - if (gfc.lowpass2 > gfc.lowpass1) { - fc2 = filter_coef((freq - gfc.lowpass1) - / (gfc.lowpass2 - gfc.lowpass1 + 1e-20)); - } else { - fc2 = 1.0; - } - gfc.amp_filter[band] = (fc1 * fc2); - } - } - - function lame_init_qval(gfp) { - var gfc = gfp.internal_flags; - - switch (gfp.quality) { - default: - case 9: /* no psymodel, no noise shaping */ - gfc.psymodel = 0; - gfc.noise_shaping = 0; - gfc.noise_shaping_amp = 0; - gfc.noise_shaping_stop = 0; - gfc.use_best_huffman = 0; - gfc.full_outer_loop = 0; - break; - - case 8: - gfp.quality = 7; - //$FALL-THROUGH$ - case 7: - /* - * use psymodel (for short block and m/s switching), but no noise - * shapping - */ - gfc.psymodel = 1; - gfc.noise_shaping = 0; - gfc.noise_shaping_amp = 0; - gfc.noise_shaping_stop = 0; - gfc.use_best_huffman = 0; - gfc.full_outer_loop = 0; - break; - - case 6: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - gfc.noise_shaping_amp = 0; - gfc.noise_shaping_stop = 0; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 0; - gfc.full_outer_loop = 0; - break; - - case 5: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - gfc.noise_shaping_amp = 0; - gfc.noise_shaping_stop = 0; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 0; - gfc.full_outer_loop = 0; - break; - - case 4: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - gfc.noise_shaping_amp = 0; - gfc.noise_shaping_stop = 0; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 1; - gfc.full_outer_loop = 0; - break; - - case 3: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - gfc.noise_shaping_amp = 1; - gfc.noise_shaping_stop = 1; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 1; - gfc.full_outer_loop = 0; - break; - - case 2: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - if (gfc.substep_shaping == 0) - gfc.substep_shaping = 2; - gfc.noise_shaping_amp = 1; - gfc.noise_shaping_stop = 1; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 1; - /* inner loop */ - gfc.full_outer_loop = 0; - break; - - case 1: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - if (gfc.substep_shaping == 0) - gfc.substep_shaping = 2; - gfc.noise_shaping_amp = 2; - gfc.noise_shaping_stop = 1; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 1; - gfc.full_outer_loop = 0; - break; - - case 0: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - if (gfc.substep_shaping == 0) - gfc.substep_shaping = 2; - gfc.noise_shaping_amp = 2; - gfc.noise_shaping_stop = 1; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 1; - /* - * type 2 disabled because of it slowness, in favor of full outer - * loop search - */ - gfc.full_outer_loop = 0; - /* - * full outer loop search disabled because of audible distortions it - * may generate rh 060629 - */ - break; - } - - } - - function lame_init_bitstream(gfp) { - var gfc = gfp.internal_flags; - gfp.frameNum = 0; - - if (gfp.write_id3tag_automatic) { - id3.id3tag_write_v2(gfp); - } - /* initialize histogram data optionally used by frontend */ - - gfc.bitrate_stereoMode_Hist = new_int_n([16, 4 + 1]); - gfc.bitrate_blockType_Hist = new_int_n([16, 4 + 1 + 1]); - - gfc.PeakSample = 0.0; - - /* Write initial VBR Header to bitstream and init VBR data */ - if (gfp.bWriteVbrTag) - vbr.InitVbrTag(gfp); - } - - /******************************************************************** - * initialize internal params based on data in gf (globalflags struct filled - * in by calling program) - * - * OUTLINE: - * - * We first have some complex code to determine bitrate, output samplerate - * and mode. It is complicated by the fact that we allow the user to set - * some or all of these parameters, and need to determine best possible - * values for the rest of them: - * - * 1. set some CPU related flags 2. check if we are mono.mono, stereo.mono - * or stereo.stereo 3. compute bitrate and output samplerate: user may have - * set compression ratio user may have set a bitrate user may have set a - * output samplerate 4. set some options which depend on output samplerate - * 5. compute the actual compression ratio 6. set mode based on compression - * ratio - * - * The remaining code is much simpler - it just sets options based on the - * mode & compression ratio: - * - * set allow_diff_short based on mode select lowpass filter based on - * compression ratio & mode set the bitrate index, and min/max bitrates for - * VBR modes disable VBR tag if it is not appropriate initialize the - * bitstream initialize scalefac_band data set sideinfo_len (based on - * channels, CRC, out_samplerate) write an id3v2 tag into the bitstream - * write VBR tag into the bitstream set mpeg1/2 flag estimate the number of - * frames (based on a lot of data) - * - * now we set more flags: nspsytune: see code VBR modes see code CBR/ABR see - * code - * - * Finally, we set the algorithm flags based on the gfp.quality value - * lame_init_qval(gfp); - * - ********************************************************************/ - this.lame_init_params = function (gfp) { - var gfc = gfp.internal_flags; - - gfc.Class_ID = 0; - if (gfc.ATH == null) - gfc.ATH = new ATH(); - if (gfc.PSY == null) - gfc.PSY = new PSY(); - if (gfc.rgdata == null) - gfc.rgdata = new ReplayGain(); - - gfc.channels_in = gfp.num_channels; - if (gfc.channels_in == 1) - gfp.mode = MPEGMode.MONO; - gfc.channels_out = (gfp.mode == MPEGMode.MONO) ? 1 : 2; - gfc.mode_ext = Encoder.MPG_MD_MS_LR; - if (gfp.mode == MPEGMode.MONO) - gfp.force_ms = false; - /* - * don't allow forced mid/side stereo for mono output - */ - - if (gfp.VBR == VbrMode.vbr_off && gfp.VBR_mean_bitrate_kbps != 128 - && gfp.brate == 0) - gfp.brate = gfp.VBR_mean_bitrate_kbps; - - if (gfp.VBR == VbrMode.vbr_off || gfp.VBR == VbrMode.vbr_mtrh - || gfp.VBR == VbrMode.vbr_mt) { - /* these modes can handle free format condition */ - } else { - gfp.free_format = false; - /* mode can't be mixed with free format */ - } - - if (gfp.VBR == VbrMode.vbr_off && gfp.brate == 0) { - /* no bitrate or compression ratio specified, use 11.025 */ - if (BitStream.EQ(gfp.compression_ratio, 0)) - gfp.compression_ratio = 11.025; - /* - * rate to compress a CD down to exactly 128000 bps - */ - } - - /* find bitrate if user specify a compression ratio */ - if (gfp.VBR == VbrMode.vbr_off && gfp.compression_ratio > 0) { - - if (gfp.out_samplerate == 0) - gfp.out_samplerate = map2MP3Frequency((int)(0.97 * gfp.in_samplerate)); - /* - * round up with a margin of 3 % - */ - - /* - * choose a bitrate for the output samplerate which achieves - * specified compression ratio - */ - gfp.brate = 0 | (gfp.out_samplerate * 16 * gfc.channels_out / (1.e3 * gfp.compression_ratio)); - - /* we need the version for the bitrate table look up */ - gfc.samplerate_index = SmpFrqIndex(gfp.out_samplerate, gfp); - - if (!gfp.free_format) /* - * for non Free Format find the nearest allowed - * bitrate - */ - gfp.brate = FindNearestBitrate(gfp.brate, gfp.version, - gfp.out_samplerate); - } - - if (gfp.out_samplerate != 0) { - if (gfp.out_samplerate < 16000) { - gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps, - 8); - gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps, - 64); - } else if (gfp.out_samplerate < 32000) { - gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps, - 8); - gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps, - 160); - } else { - gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps, - 32); - gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps, - 320); - } - } - - /****************************************************************/ - /* if a filter has not been enabled, see if we should add one: */ - /****************************************************************/ - if (gfp.lowpassfreq == 0) { - var lowpass = 16000.; - - switch (gfp.VBR) { - case VbrMode.vbr_off: - { - var lh = new LowPassHighPass(); - optimum_bandwidth(lh, gfp.brate); - lowpass = lh.lowerlimit; - break; - } - case VbrMode.vbr_abr: - { - var lh = new LowPassHighPass(); - optimum_bandwidth(lh, gfp.VBR_mean_bitrate_kbps); - lowpass = lh.lowerlimit; - break; - } - case VbrMode.vbr_rh: - { - var x = [19500, 19000, 18600, 18000, 17500, 16000, - 15600, 14900, 12500, 10000, 3950]; - if (0 <= gfp.VBR_q && gfp.VBR_q <= 9) { - var a = x[gfp.VBR_q], b = x[gfp.VBR_q + 1], m = gfp.VBR_q_frac; - lowpass = linear_int(a, b, m); - } else { - lowpass = 19500; - } - break; - } - default: - { - var x = [19500, 19000, 18500, 18000, 17500, 16500, - 15500, 14500, 12500, 9500, 3950]; - if (0 <= gfp.VBR_q && gfp.VBR_q <= 9) { - var a = x[gfp.VBR_q], b = x[gfp.VBR_q + 1], m = gfp.VBR_q_frac; - lowpass = linear_int(a, b, m); - } else { - lowpass = 19500; - } - } - } - if (gfp.mode == MPEGMode.MONO - && (gfp.VBR == VbrMode.vbr_off || gfp.VBR == VbrMode.vbr_abr)) - lowpass *= 1.5; - - gfp.lowpassfreq = lowpass | 0; - } - - if (gfp.out_samplerate == 0) { - if (2 * gfp.lowpassfreq > gfp.in_samplerate) { - gfp.lowpassfreq = gfp.in_samplerate / 2; - } - gfp.out_samplerate = optimum_samplefreq(gfp.lowpassfreq | 0, - gfp.in_samplerate); - } - - gfp.lowpassfreq = Math.min(20500, gfp.lowpassfreq); - gfp.lowpassfreq = Math.min(gfp.out_samplerate / 2, gfp.lowpassfreq); - - if (gfp.VBR == VbrMode.vbr_off) { - gfp.compression_ratio = gfp.out_samplerate * 16 * gfc.channels_out - / (1.e3 * gfp.brate); - } - if (gfp.VBR == VbrMode.vbr_abr) { - gfp.compression_ratio = gfp.out_samplerate * 16 * gfc.channels_out - / (1.e3 * gfp.VBR_mean_bitrate_kbps); - } - - /* - * do not compute ReplayGain values and do not find the peak sample if - * we can't store them - */ - if (!gfp.bWriteVbrTag) { - gfp.findReplayGain = false; - gfp.decode_on_the_fly = false; - gfc.findPeakSample = false; - } - gfc.findReplayGain = gfp.findReplayGain; - gfc.decode_on_the_fly = gfp.decode_on_the_fly; - - if (gfc.decode_on_the_fly) - gfc.findPeakSample = true; - - if (gfc.findReplayGain) { - if (ga.InitGainAnalysis(gfc.rgdata, gfp.out_samplerate) == GainAnalysis.INIT_GAIN_ANALYSIS_ERROR) { - gfp.internal_flags = null; - return -6; - } - } - - if (gfc.decode_on_the_fly && !gfp.decode_only) { - if (gfc.hip != null) { - mpglib.hip_decode_exit(gfc.hip); - } - gfc.hip = mpglib.hip_decode_init(); - } - - gfc.mode_gr = gfp.out_samplerate <= 24000 ? 1 : 2; - /* - * Number of granules per frame - */ - gfp.framesize = 576 * gfc.mode_gr; - gfp.encoder_delay = Encoder.ENCDELAY; - - gfc.resample_ratio = gfp.in_samplerate / gfp.out_samplerate; - - /** - *
-         *  sample freq       bitrate     compression ratio
-         *     [kHz]      [kbps/channel]   for 16 bit input
-         *     44.1            56               12.6
-         *     44.1            64               11.025
-         *     44.1            80                8.82
-         *     22.05           24               14.7
-         *     22.05           32               11.025
-         *     22.05           40                8.82
-         *     16              16               16.0
-         *     16              24               10.667
-         * 
- */ - /** - *
-         *  For VBR, take a guess at the compression_ratio.
-         *  For example:
-         *
-         *    VBR_q    compression     like
-         *     -        4.4         320 kbps/44 kHz
-         *   0...1      5.5         256 kbps/44 kHz
-         *     2        7.3         192 kbps/44 kHz
-         *     4        8.8         160 kbps/44 kHz
-         *     6       11           128 kbps/44 kHz
-         *     9       14.7          96 kbps
-         *
-         *  for lower bitrates, downsample with --resample
-         * 
- */ - switch (gfp.VBR) { - case VbrMode.vbr_mt: - case VbrMode.vbr_rh: - case VbrMode.vbr_mtrh: - { - /* numbers are a bit strange, but they determine the lowpass value */ - var cmp = [5.7, 6.5, 7.3, 8.2, 10, 11.9, 13, 14, - 15, 16.5]; - gfp.compression_ratio = cmp[gfp.VBR_q]; - } - break; - case VbrMode.vbr_abr: - gfp.compression_ratio = gfp.out_samplerate * 16 * gfc.channels_out - / (1.e3 * gfp.VBR_mean_bitrate_kbps); - break; - default: - gfp.compression_ratio = gfp.out_samplerate * 16 * gfc.channels_out - / (1.e3 * gfp.brate); - break; - } - - /* - * mode = -1 (not set by user) or mode = MONO (because of only 1 input - * channel). If mode has not been set, then select J-STEREO - */ - if (gfp.mode == MPEGMode.NOT_SET) { - gfp.mode = MPEGMode.JOINT_STEREO; - } - - /* apply user driven high pass filter */ - if (gfp.highpassfreq > 0) { - gfc.highpass1 = 2. * gfp.highpassfreq; - - if (gfp.highpasswidth >= 0) - gfc.highpass2 = 2. * (gfp.highpassfreq + gfp.highpasswidth); - else - /* 0% above on default */ - gfc.highpass2 = (1 + 0.00) * 2. * gfp.highpassfreq; - - gfc.highpass1 /= gfp.out_samplerate; - gfc.highpass2 /= gfp.out_samplerate; - } else { - gfc.highpass1 = 0; - gfc.highpass2 = 0; - } - /* apply user driven low pass filter */ - if (gfp.lowpassfreq > 0) { - gfc.lowpass2 = 2. * gfp.lowpassfreq; - if (gfp.lowpasswidth >= 0) { - gfc.lowpass1 = 2. * (gfp.lowpassfreq - gfp.lowpasswidth); - if (gfc.lowpass1 < 0) /* has to be >= 0 */ - gfc.lowpass1 = 0; - } else { /* 0% below on default */ - gfc.lowpass1 = (1 - 0.00) * 2. * gfp.lowpassfreq; - } - gfc.lowpass1 /= gfp.out_samplerate; - gfc.lowpass2 /= gfp.out_samplerate; - } else { - gfc.lowpass1 = 0; - gfc.lowpass2 = 0; - } - - /**********************************************************************/ - /* compute info needed for polyphase filter (filter type==0, default) */ - /**********************************************************************/ - lame_init_params_ppflt(gfp); - /******************************************************* - * samplerate and bitrate index - *******************************************************/ - gfc.samplerate_index = SmpFrqIndex(gfp.out_samplerate, gfp); - if (gfc.samplerate_index < 0) { - gfp.internal_flags = null; - return -1; - } - - if (gfp.VBR == VbrMode.vbr_off) { - if (gfp.free_format) { - gfc.bitrate_index = 0; - } else { - gfp.brate = FindNearestBitrate(gfp.brate, gfp.version, - gfp.out_samplerate); - gfc.bitrate_index = BitrateIndex(gfp.brate, gfp.version, - gfp.out_samplerate); - if (gfc.bitrate_index <= 0) { - gfp.internal_flags = null; - return -1; - } - } - } else { - gfc.bitrate_index = 1; - } - - /* for CBR, we will write an "info" tag. */ - - if (gfp.analysis) - gfp.bWriteVbrTag = false; - - /* some file options not allowed if output is: not specified or stdout */ - if (gfc.pinfo != null) - gfp.bWriteVbrTag = false; - /* disable Xing VBR tag */ - - bs.init_bit_stream_w(gfc); - - var j = gfc.samplerate_index + (3 * gfp.version) + 6 - * (gfp.out_samplerate < 16000 ? 1 : 0); - for (var i = 0; i < Encoder.SBMAX_l + 1; i++) - gfc.scalefac_band.l[i] = qupvt.sfBandIndex[j].l[i]; - - for (var i = 0; i < Encoder.PSFB21 + 1; i++) { - var size = (gfc.scalefac_band.l[22] - gfc.scalefac_band.l[21]) - / Encoder.PSFB21; - var start = gfc.scalefac_band.l[21] + i * size; - gfc.scalefac_band.psfb21[i] = start; - } - gfc.scalefac_band.psfb21[Encoder.PSFB21] = 576; - - for (var i = 0; i < Encoder.SBMAX_s + 1; i++) - gfc.scalefac_band.s[i] = qupvt.sfBandIndex[j].s[i]; - - for (var i = 0; i < Encoder.PSFB12 + 1; i++) { - var size = (gfc.scalefac_band.s[13] - gfc.scalefac_band.s[12]) - / Encoder.PSFB12; - var start = gfc.scalefac_band.s[12] + i * size; - gfc.scalefac_band.psfb12[i] = start; - } - gfc.scalefac_band.psfb12[Encoder.PSFB12] = 192; - /* determine the mean bitrate for main data */ - if (gfp.version == 1) /* MPEG 1 */ - gfc.sideinfo_len = (gfc.channels_out == 1) ? 4 + 17 : 4 + 32; - else - /* MPEG 2 */ - gfc.sideinfo_len = (gfc.channels_out == 1) ? 4 + 9 : 4 + 17; - - if (gfp.error_protection) - gfc.sideinfo_len += 2; - - lame_init_bitstream(gfp); - - gfc.Class_ID = LAME_ID; - - { - var k; - - for (k = 0; k < 19; k++) - gfc.nsPsy.pefirbuf[k] = 700 * gfc.mode_gr * gfc.channels_out; - - if (gfp.ATHtype == -1) - gfp.ATHtype = 4; - } - - switch (gfp.VBR) { - - case VbrMode.vbr_mt: - gfp.VBR = VbrMode.vbr_mtrh; - //$FALL-THROUGH$ - case VbrMode.vbr_mtrh: - { - if (gfp.useTemporal == null) { - gfp.useTemporal = false; - /* off by default for this VBR mode */ - } - - p.apply_preset(gfp, 500 - (gfp.VBR_q * 10), 0); - /** - *
-                 *   The newer VBR code supports only a limited
-                 *     subset of quality levels:
-                 *     9-5=5 are the same, uses x^3/4 quantization
-                 *   4-0=0 are the same  5 plus best huffman divide code
-                 * 
- */ - if (gfp.quality < 0) - gfp.quality = LAME_DEFAULT_QUALITY; - if (gfp.quality < 5) - gfp.quality = 0; - if (gfp.quality > 5) - gfp.quality = 5; - - gfc.PSY.mask_adjust = gfp.maskingadjust; - gfc.PSY.mask_adjust_short = gfp.maskingadjust_short; - - /* - * sfb21 extra only with MPEG-1 at higher sampling rates - */ - if (gfp.experimentalY) - gfc.sfb21_extra = false; - else - gfc.sfb21_extra = (gfp.out_samplerate > 44000); - - gfc.iteration_loop = new VBRNewIterationLoop(qu); - break; - - } - case VbrMode.vbr_rh: - { - - p.apply_preset(gfp, 500 - (gfp.VBR_q * 10), 0); - - gfc.PSY.mask_adjust = gfp.maskingadjust; - gfc.PSY.mask_adjust_short = gfp.maskingadjust_short; - - /* - * sfb21 extra only with MPEG-1 at higher sampling rates - */ - if (gfp.experimentalY) - gfc.sfb21_extra = false; - else - gfc.sfb21_extra = (gfp.out_samplerate > 44000); - - /* - * VBR needs at least the output of GPSYCHO, so we have to garantee - * that by setting a minimum quality level, actually level 6 does - * it. down to level 6 - */ - if (gfp.quality > 6) - gfp.quality = 6; - - if (gfp.quality < 0) - gfp.quality = LAME_DEFAULT_QUALITY; - - gfc.iteration_loop = new VBROldIterationLoop(qu); - break; - } - - default: /* cbr/abr */ - { - var vbrmode; - - /* - * no sfb21 extra with CBR code - */ - gfc.sfb21_extra = false; - - if (gfp.quality < 0) - gfp.quality = LAME_DEFAULT_QUALITY; - - vbrmode = gfp.VBR; - if (vbrmode == VbrMode.vbr_off) - gfp.VBR_mean_bitrate_kbps = gfp.brate; - /* second, set parameters depending on bitrate */ - p.apply_preset(gfp, gfp.VBR_mean_bitrate_kbps, 0); - gfp.VBR = vbrmode; - - gfc.PSY.mask_adjust = gfp.maskingadjust; - gfc.PSY.mask_adjust_short = gfp.maskingadjust_short; - - if (vbrmode == VbrMode.vbr_off) { - gfc.iteration_loop = new CBRNewIterationLoop(qu); - } else { - gfc.iteration_loop = new ABRIterationLoop(qu); - } - break; - } - } - /* initialize default values common for all modes */ - - if (gfp.VBR != VbrMode.vbr_off) { /* choose a min/max bitrate for VBR */ - /* if the user didn't specify VBR_max_bitrate: */ - gfc.VBR_min_bitrate = 1; - /* - * default: allow 8 kbps (MPEG-2) or 32 kbps (MPEG-1) - */ - gfc.VBR_max_bitrate = 14; - /* - * default: allow 160 kbps (MPEG-2) or 320 kbps (MPEG-1) - */ - if (gfp.out_samplerate < 16000) - gfc.VBR_max_bitrate = 8; - /* default: allow 64 kbps (MPEG-2.5) */ - if (gfp.VBR_min_bitrate_kbps != 0) { - gfp.VBR_min_bitrate_kbps = FindNearestBitrate( - gfp.VBR_min_bitrate_kbps, gfp.version, - gfp.out_samplerate); - gfc.VBR_min_bitrate = BitrateIndex(gfp.VBR_min_bitrate_kbps, - gfp.version, gfp.out_samplerate); - if (gfc.VBR_min_bitrate < 0) - return -1; - } - if (gfp.VBR_max_bitrate_kbps != 0) { - gfp.VBR_max_bitrate_kbps = FindNearestBitrate( - gfp.VBR_max_bitrate_kbps, gfp.version, - gfp.out_samplerate); - gfc.VBR_max_bitrate = BitrateIndex(gfp.VBR_max_bitrate_kbps, - gfp.version, gfp.out_samplerate); - if (gfc.VBR_max_bitrate < 0) - return -1; - } - gfp.VBR_min_bitrate_kbps = Tables.bitrate_table[gfp.version][gfc.VBR_min_bitrate]; - gfp.VBR_max_bitrate_kbps = Tables.bitrate_table[gfp.version][gfc.VBR_max_bitrate]; - gfp.VBR_mean_bitrate_kbps = Math.min( - Tables.bitrate_table[gfp.version][gfc.VBR_max_bitrate], - gfp.VBR_mean_bitrate_kbps); - gfp.VBR_mean_bitrate_kbps = Math.max( - Tables.bitrate_table[gfp.version][gfc.VBR_min_bitrate], - gfp.VBR_mean_bitrate_kbps); - } - - /* just another daily changing developer switch */ - if (gfp.tune) { - gfc.PSY.mask_adjust += gfp.tune_value_a; - gfc.PSY.mask_adjust_short += gfp.tune_value_a; - } - - /* initialize internal qval settings */ - lame_init_qval(gfp); - /* - * automatic ATH adjustment on - */ - if (gfp.athaa_type < 0) - gfc.ATH.useAdjust = 3; - else - gfc.ATH.useAdjust = gfp.athaa_type; - - /* initialize internal adaptive ATH settings -jd */ - gfc.ATH.aaSensitivityP = Math.pow(10.0, gfp.athaa_sensitivity - / -10.0); - - if (gfp.short_blocks == null) { - gfp.short_blocks = ShortBlock.short_block_allowed; - } - - /* - * Note Jan/2003: Many hardware decoders cannot handle short blocks in - * regular stereo mode unless they are coupled (same type in both - * channels) it is a rare event (1 frame per min. or so) that LAME would - * use uncoupled short blocks, so lets turn them off until we decide how - * to handle this. No other encoders allow uncoupled short blocks, even - * though it is in the standard. - */ - /* - * rh 20040217: coupling makes no sense for mono and dual-mono streams - */ - if (gfp.short_blocks == ShortBlock.short_block_allowed - && (gfp.mode == MPEGMode.JOINT_STEREO || gfp.mode == MPEGMode.STEREO)) { - gfp.short_blocks = ShortBlock.short_block_coupled; - } - - if (gfp.quant_comp < 0) - gfp.quant_comp = 1; - if (gfp.quant_comp_short < 0) - gfp.quant_comp_short = 0; - - if (gfp.msfix < 0) - gfp.msfix = 0; - - /* select psychoacoustic model */ - gfp.exp_nspsytune = gfp.exp_nspsytune | 1; - - if (gfp.internal_flags.nsPsy.attackthre < 0) - gfp.internal_flags.nsPsy.attackthre = PsyModel.NSATTACKTHRE; - if (gfp.internal_flags.nsPsy.attackthre_s < 0) - gfp.internal_flags.nsPsy.attackthre_s = PsyModel.NSATTACKTHRE_S; - - - if (gfp.scale < 0) - gfp.scale = 1; - - if (gfp.ATHtype < 0) - gfp.ATHtype = 4; - - if (gfp.ATHcurve < 0) - gfp.ATHcurve = 4; - - if (gfp.athaa_loudapprox < 0) - gfp.athaa_loudapprox = 2; - - if (gfp.interChRatio < 0) - gfp.interChRatio = 0; - - if (gfp.useTemporal == null) - gfp.useTemporal = true; - /* on by default */ - - /* - * padding method as described in - * "MPEG-Layer3 / Bitstream Syntax and Decoding" by Martin Sieler, Ralph - * Sperschneider - * - * note: there is no padding for the very first frame - * - * Robert Hegemann 2000-06-22 - */ - gfc.slot_lag = gfc.frac_SpF = 0; - if (gfp.VBR == VbrMode.vbr_off) - gfc.slot_lag = gfc.frac_SpF = (((gfp.version + 1) * 72000 * gfp.brate) % gfp.out_samplerate) | 0; - - qupvt.iteration_init(gfp); - psy.psymodel_init(gfp); - return 0; - } - - function update_inbuffer_size(gfc, nsamples) { - if (gfc.in_buffer_0 == null || gfc.in_buffer_nsamples < nsamples) { - gfc.in_buffer_0 = new_float(nsamples); - gfc.in_buffer_1 = new_float(nsamples); - gfc.in_buffer_nsamples = nsamples; - } - } - - this.lame_encode_flush = function (gfp, mp3buffer, mp3bufferPos, mp3buffer_size) { - var gfc = gfp.internal_flags; - var buffer = new_short_n([2, 1152]); - var imp3 = 0, mp3count, mp3buffer_size_remaining; - - /* - * we always add POSTDELAY=288 padding to make sure granule with real - * data can be complety decoded (because of 50% overlap with next - * granule - */ - var end_padding; - var frames_left; - var samples_to_encode = gfc.mf_samples_to_encode - Encoder.POSTDELAY; - var mf_needed = calcNeeded(gfp); - - /* Was flush already called? */ - if (gfc.mf_samples_to_encode < 1) { - return 0; - } - mp3count = 0; - - if (gfp.in_samplerate != gfp.out_samplerate) { - /* - * delay due to resampling; needs to be fixed, if resampling code - * gets changed - */ - samples_to_encode += 16. * gfp.out_samplerate / gfp.in_samplerate; - } - end_padding = gfp.framesize - (samples_to_encode % gfp.framesize); - if (end_padding < 576) - end_padding += gfp.framesize; - gfp.encoder_padding = end_padding; - - frames_left = (samples_to_encode + end_padding) / gfp.framesize; - - /* - * send in a frame of 0 padding until all internal sample buffers are - * flushed - */ - while (frames_left > 0 && imp3 >= 0) { - var bunch = mf_needed - gfc.mf_size; - var frame_num = gfp.frameNum; - - bunch *= gfp.in_samplerate; - bunch /= gfp.out_samplerate; - if (bunch > 1152) - bunch = 1152; - if (bunch < 1) - bunch = 1; - - mp3buffer_size_remaining = mp3buffer_size - mp3count; - - /* if user specifed buffer size = 0, dont check size */ - if (mp3buffer_size == 0) - mp3buffer_size_remaining = 0; - - imp3 = this.lame_encode_buffer(gfp, buffer[0], buffer[1], bunch, - mp3buffer, mp3bufferPos, mp3buffer_size_remaining); - - mp3bufferPos += imp3; - mp3count += imp3; - frames_left -= (frame_num != gfp.frameNum) ? 1 : 0; - } - /* - * Set gfc.mf_samples_to_encode to 0, so we may detect and break loops - * calling it more than once in a row. - */ - gfc.mf_samples_to_encode = 0; - - if (imp3 < 0) { - /* some type of fatal error */ - return imp3; - } - - mp3buffer_size_remaining = mp3buffer_size - mp3count; - /* if user specifed buffer size = 0, dont check size */ - if (mp3buffer_size == 0) - mp3buffer_size_remaining = 0; - - /* mp3 related stuff. bit buffer might still contain some mp3 data */ - bs.flush_bitstream(gfp); - imp3 = bs.copy_buffer(gfc, mp3buffer, mp3bufferPos, - mp3buffer_size_remaining, 1); - if (imp3 < 0) { - /* some type of fatal error */ - return imp3; - } - mp3bufferPos += imp3; - mp3count += imp3; - mp3buffer_size_remaining = mp3buffer_size - mp3count; - /* if user specifed buffer size = 0, dont check size */ - if (mp3buffer_size == 0) - mp3buffer_size_remaining = 0; - - if (gfp.write_id3tag_automatic) { - /* write a id3 tag to the bitstream */ - id3.id3tag_write_v1(gfp); - - imp3 = bs.copy_buffer(gfc, mp3buffer, mp3bufferPos, - mp3buffer_size_remaining, 0); - - if (imp3 < 0) { - return imp3; - } - mp3count += imp3; - } - return mp3count; - }; - - this.lame_encode_buffer = function (gfp, buffer_l, buffer_r, nsamples, mp3buf, mp3bufPos, mp3buf_size) { - var gfc = gfp.internal_flags; - var in_buffer = [null, null]; - - if (gfc.Class_ID != LAME_ID) - return -3; - - if (nsamples == 0) - return 0; - - update_inbuffer_size(gfc, nsamples); - - in_buffer[0] = gfc.in_buffer_0; - in_buffer[1] = gfc.in_buffer_1; - - /* make a copy of input buffer, changing type to sample_t */ - for (var i = 0; i < nsamples; i++) { - in_buffer[0][i] = buffer_l[i]; - if (gfc.channels_in > 1) - in_buffer[1][i] = buffer_r[i]; - } - - return lame_encode_buffer_sample(gfp, in_buffer[0], in_buffer[1], - nsamples, mp3buf, mp3bufPos, mp3buf_size); - } - - function calcNeeded(gfp) { - var mf_needed = Encoder.BLKSIZE + gfp.framesize - Encoder.FFTOFFSET; - /* - * amount needed for FFT - */ - mf_needed = Math.max(mf_needed, 512 + gfp.framesize - 32); - - return mf_needed; - } - - function lame_encode_buffer_sample(gfp, buffer_l, buffer_r, nsamples, mp3buf, mp3bufPos, mp3buf_size) { - var gfc = gfp.internal_flags; - var mp3size = 0, ret, i, ch, mf_needed; - var mp3out; - var mfbuf = [null, null]; - var in_buffer = [null, null]; - - if (gfc.Class_ID != LAME_ID) - return -3; - - if (nsamples == 0) - return 0; - - /* copy out any tags that may have been written into bitstream */ - mp3out = bs.copy_buffer(gfc, mp3buf, mp3bufPos, mp3buf_size, 0); - if (mp3out < 0) - return mp3out; - /* not enough buffer space */ - mp3bufPos += mp3out; - mp3size += mp3out; - - in_buffer[0] = buffer_l; - in_buffer[1] = buffer_r; - - /* Apply user defined re-scaling */ - - /* user selected scaling of the samples */ - if (BitStream.NEQ(gfp.scale, 0) && BitStream.NEQ(gfp.scale, 1.0)) { - for (i = 0; i < nsamples; ++i) { - in_buffer[0][i] *= gfp.scale; - if (gfc.channels_out == 2) - in_buffer[1][i] *= gfp.scale; - } - } - - /* user selected scaling of the channel 0 (left) samples */ - if (BitStream.NEQ(gfp.scale_left, 0) - && BitStream.NEQ(gfp.scale_left, 1.0)) { - for (i = 0; i < nsamples; ++i) { - in_buffer[0][i] *= gfp.scale_left; - } - } - - /* user selected scaling of the channel 1 (right) samples */ - if (BitStream.NEQ(gfp.scale_right, 0) - && BitStream.NEQ(gfp.scale_right, 1.0)) { - for (i = 0; i < nsamples; ++i) { - in_buffer[1][i] *= gfp.scale_right; - } - } - - /* Downsample to Mono if 2 channels in and 1 channel out */ - if (gfp.num_channels == 2 && gfc.channels_out == 1) { - for (i = 0; i < nsamples; ++i) { - in_buffer[0][i] = 0.5 * ( in_buffer[0][i] + in_buffer[1][i]); - in_buffer[1][i] = 0.0; - } - } - - mf_needed = calcNeeded(gfp); - - mfbuf[0] = gfc.mfbuf[0]; - mfbuf[1] = gfc.mfbuf[1]; - - var in_bufferPos = 0; - while (nsamples > 0) { - var in_buffer_ptr = [null, null]; - var n_in = 0; - /* number of input samples processed with fill_buffer */ - var n_out = 0; - /* number of samples output with fill_buffer */ - /* n_in <> n_out if we are resampling */ - - in_buffer_ptr[0] = in_buffer[0]; - in_buffer_ptr[1] = in_buffer[1]; - /* copy in new samples into mfbuf, with resampling */ - var inOut = new InOut(); - fill_buffer(gfp, mfbuf, in_buffer_ptr, in_bufferPos, nsamples, - inOut); - n_in = inOut.n_in; - n_out = inOut.n_out; - - /* compute ReplayGain of resampled input if requested */ - if (gfc.findReplayGain && !gfc.decode_on_the_fly) - if (ga.AnalyzeSamples(gfc.rgdata, mfbuf[0], gfc.mf_size, - mfbuf[1], gfc.mf_size, n_out, gfc.channels_out) == GainAnalysis.GAIN_ANALYSIS_ERROR) - return -6; - - /* update in_buffer counters */ - nsamples -= n_in; - in_bufferPos += n_in; - if (gfc.channels_out == 2) - ;// in_bufferPos += n_in; - - /* update mfbuf[] counters */ - gfc.mf_size += n_out; - - /* - * lame_encode_flush may have set gfc.mf_sample_to_encode to 0 so we - * have to reinitialize it here when that happened. - */ - if (gfc.mf_samples_to_encode < 1) { - gfc.mf_samples_to_encode = Encoder.ENCDELAY + Encoder.POSTDELAY; - } - gfc.mf_samples_to_encode += n_out; - - if (gfc.mf_size >= mf_needed) { - /* encode the frame. */ - /* mp3buf = pointer to current location in buffer */ - /* mp3buf_size = size of original mp3 output buffer */ - /* = 0 if we should not worry about the */ - /* buffer size because calling program is */ - /* to lazy to compute it */ - /* mp3size = size of data written to buffer so far */ - /* mp3buf_size-mp3size = amount of space avalable */ - - var buf_size = mp3buf_size - mp3size; - if (mp3buf_size == 0) - buf_size = 0; - - ret = lame_encode_frame(gfp, mfbuf[0], mfbuf[1], mp3buf, - mp3bufPos, buf_size); - - if (ret < 0) - return ret; - mp3bufPos += ret; - mp3size += ret; - - /* shift out old samples */ - gfc.mf_size -= gfp.framesize; - gfc.mf_samples_to_encode -= gfp.framesize; - for (ch = 0; ch < gfc.channels_out; ch++) - for (i = 0; i < gfc.mf_size; i++) - mfbuf[ch][i] = mfbuf[ch][i + gfp.framesize]; - } - } - - return mp3size; - } - - function lame_encode_frame(gfp, inbuf_l, inbuf_r, mp3buf, mp3bufPos, mp3buf_size) { - var ret = self.enc.lame_encode_mp3_frame(gfp, inbuf_l, inbuf_r, mp3buf, - mp3bufPos, mp3buf_size); - gfp.frameNum++; - return ret; - } - - function InOut() { - this.n_in = 0; - this.n_out = 0; - } - - - function NumUsed() { - this.num_used = 0; - } - - /** - * Greatest common divisor. - *

- * Joint work of Euclid and M. Hendry - */ - function gcd(i, j) { - return j != 0 ? gcd(j, i % j) : i; - } - - /** - * Resampling via FIR filter, blackman window. - */ - function blackman(x, fcn, l) { - /* - * This algorithm from: SIGNAL PROCESSING ALGORITHMS IN FORTRAN AND C - * S.D. Stearns and R.A. David, Prentice-Hall, 1992 - */ - var wcn = (Math.PI * fcn); - - x /= l; - if (x < 0) - x = 0; - if (x > 1) - x = 1; - var x2 = x - .5; - - var bkwn = 0.42 - 0.5 * Math.cos(2 * x * Math.PI) + 0.08 * Math.cos(4 * x * Math.PI); - if (Math.abs(x2) < 1e-9) - return (wcn / Math.PI); - else - return (bkwn * Math.sin(l * wcn * x2) / (Math.PI * l * x2)); - } - - function fill_buffer_resample(gfp, outbuf, outbufPos, desired_len, inbuf, in_bufferPos, len, num_used, ch) { - var gfc = gfp.internal_flags; - var i, j = 0, k; - /* number of convolution functions to pre-compute */ - var bpc = gfp.out_samplerate - / gcd(gfp.out_samplerate, gfp.in_samplerate); - if (bpc > LameInternalFlags.BPC) - bpc = LameInternalFlags.BPC; - - var intratio = (Math.abs(gfc.resample_ratio - - Math.floor(.5 + gfc.resample_ratio)) < .0001) ? 1 : 0; - var fcn = 1.00 / gfc.resample_ratio; - if (fcn > 1.00) - fcn = 1.00; - var filter_l = 31; - if (0 == filter_l % 2) - --filter_l; - /* must be odd */ - filter_l += intratio; - /* unless resample_ratio=int, it must be even */ - - var BLACKSIZE = filter_l + 1; - /* size of data needed for FIR */ - - if (gfc.fill_buffer_resample_init == 0) { - gfc.inbuf_old[0] = new_float(BLACKSIZE); - gfc.inbuf_old[1] = new_float(BLACKSIZE); - for (i = 0; i <= 2 * bpc; ++i) - gfc.blackfilt[i] = new_float(BLACKSIZE); - - gfc.itime[0] = 0; - gfc.itime[1] = 0; - - /* precompute blackman filter coefficients */ - for (j = 0; j <= 2 * bpc; j++) { - var sum = 0.; - var offset = (j - bpc) / (2. * bpc); - for (i = 0; i <= filter_l; i++) - sum += gfc.blackfilt[j][i] = blackman(i - offset, fcn, - filter_l); - for (i = 0; i <= filter_l; i++) - gfc.blackfilt[j][i] /= sum; - } - gfc.fill_buffer_resample_init = 1; - } - - var inbuf_old = gfc.inbuf_old[ch]; - - /* time of j'th element in inbuf = itime + j/ifreq; */ - /* time of k'th element in outbuf = j/ofreq */ - for (k = 0; k < desired_len; k++) { - var time0; - var joff; - - time0 = k * gfc.resample_ratio; - /* time of k'th output sample */ - j = 0 | Math.floor(time0 - gfc.itime[ch]); - - /* check if we need more input data */ - if ((filter_l + j - filter_l / 2) >= len) - break; - - /* blackman filter. by default, window centered at j+.5(filter_l%2) */ - /* but we want a window centered at time0. */ - var offset = (time0 - gfc.itime[ch] - (j + .5 * (filter_l % 2))); - - /* find the closest precomputed window for this offset: */ - joff = 0 | Math.floor((offset * 2 * bpc) + bpc + .5); - var xvalue = 0.; - for (i = 0; i <= filter_l; ++i) { - /* force integer index */ - var j2 = 0 | (i + j - filter_l / 2); - var y; - y = (j2 < 0) ? inbuf_old[BLACKSIZE + j2] : inbuf[in_bufferPos - + j2]; - xvalue += y * gfc.blackfilt[joff][i]; - } - outbuf[outbufPos + k] = xvalue; - } - - /* k = number of samples added to outbuf */ - /* last k sample used data from [j-filter_l/2,j+filter_l-filter_l/2] */ - - /* how many samples of input data were used: */ - num_used.num_used = Math.min(len, filter_l + j - filter_l / 2); - - /* - * adjust our input time counter. Incriment by the number of samples - * used, then normalize so that next output sample is at time 0, next - * input buffer is at time itime[ch] - */ - gfc.itime[ch] += num_used.num_used - k * gfc.resample_ratio; - - /* save the last BLACKSIZE samples into the inbuf_old buffer */ - if (num_used.num_used >= BLACKSIZE) { - for (i = 0; i < BLACKSIZE; i++) - inbuf_old[i] = inbuf[in_bufferPos + num_used.num_used + i - - BLACKSIZE]; - } else { - /* shift in num_used.num_used samples into inbuf_old */ - var n_shift = BLACKSIZE - num_used.num_used; - /* - * number of samples to - * shift - */ - - /* - * shift n_shift samples by num_used.num_used, to make room for the - * num_used new samples - */ - for (i = 0; i < n_shift; ++i) - inbuf_old[i] = inbuf_old[i + num_used.num_used]; - - /* shift in the num_used.num_used samples */ - for (j = 0; i < BLACKSIZE; ++i, ++j) - inbuf_old[i] = inbuf[in_bufferPos + j]; - - } - return k; - /* return the number samples created at the new samplerate */ - } - - function fill_buffer(gfp, mfbuf, in_buffer, in_bufferPos, nsamples, io) { - var gfc = gfp.internal_flags; - - /* copy in new samples into mfbuf, with resampling if necessary */ - if ((gfc.resample_ratio < .9999) || (gfc.resample_ratio > 1.0001)) { - for (var ch = 0; ch < gfc.channels_out; ch++) { - var numUsed = new NumUsed(); - io.n_out = fill_buffer_resample(gfp, mfbuf[ch], gfc.mf_size, - gfp.framesize, in_buffer[ch], in_bufferPos, nsamples, - numUsed, ch); - io.n_in = numUsed.num_used; - } - } else { - io.n_out = Math.min(gfp.framesize, nsamples); - io.n_in = io.n_out; - for (var i = 0; i < io.n_out; ++i) { - mfbuf[0][gfc.mf_size + i] = in_buffer[0][in_bufferPos + i]; - if (gfc.channels_out == 2) - mfbuf[1][gfc.mf_size + i] = in_buffer[1][in_bufferPos + i]; - } - } - } - -} - - - -function GetAudio() { - var parse; - var mpg; - - this.setModules = function (parse2, mpg2) { - parse = parse2; - mpg = mpg2; - } -} - - -function Parse() { - var ver; - var id3; - var pre; - - this.setModules = function (ver2, id32, pre2) { - ver = ver2; - id3 = id32; - pre = pre2; - } -} - -function MPGLib() { -} - -function ID3Tag() { - var bits; - var ver; - - this.setModules = function (_bits, _ver) { - bits = _bits; - ver = _ver; - } -} - -function Mp3Encoder(channels, samplerate, kbps) { - if (arguments.length != 3) { - console.error('WARN: Mp3Encoder(channels, samplerate, kbps) not specified'); - channels = 1; - samplerate = 44100; - kbps = 128; - } - var lame = new Lame(); - var gaud = new GetAudio(); - var ga = new GainAnalysis(); - var bs = new BitStream(); - var p = new Presets(); - var qupvt = new QuantizePVT(); - var qu = new Quantize(); - var vbr = new VBRTag(); - var ver = new Version(); - var id3 = new ID3Tag(); - var rv = new Reservoir(); - var tak = new Takehiro(); - var parse = new Parse(); - var mpg = new MPGLib(); - - lame.setModules(ga, bs, p, qupvt, qu, vbr, ver, id3, mpg); - bs.setModules(ga, mpg, ver, vbr); - id3.setModules(bs, ver); - p.setModules(lame); - qu.setModules(bs, rv, qupvt, tak); - qupvt.setModules(tak, rv, lame.enc.psy); - rv.setModules(bs); - tak.setModules(qupvt); - vbr.setModules(lame, bs, ver); - gaud.setModules(parse, mpg); - parse.setModules(ver, id3, p); - - var gfp = lame.lame_init(); - - gfp.num_channels = channels; - gfp.in_samplerate = samplerate; - gfp.brate = kbps; - gfp.mode = MPEGMode.STEREO; - gfp.quality = 3; - gfp.bWriteVbrTag = false; - gfp.disable_reservoir = true; - gfp.write_id3tag_automatic = false; - - var retcode = lame.lame_init_params(gfp); - var maxSamples = 1152; - var mp3buf_size = 0 | (1.25 * maxSamples + 7200); - var mp3buf = new_byte(mp3buf_size); - - this.encodeBuffer = function (left, right) { - if (channels == 1) { - right = left; - } - if (left.length > maxSamples) { - maxSamples = left.length; - mp3buf_size = 0 | (1.25 * maxSamples + 7200); - mp3buf = new_byte(mp3buf_size); - } - - var _sz = lame.lame_encode_buffer(gfp, left, right, left.length, mp3buf, 0, mp3buf_size); - return new Int8Array(mp3buf.subarray(0, _sz)); - }; - - this.flush = function () { - var _sz = lame.lame_encode_flush(gfp, mp3buf, 0, mp3buf_size); - return new Int8Array(mp3buf.subarray(0, _sz)); - }; -} - -function WavHeader() { - this.dataOffset = 0; - this.dataLen = 0; - this.channels = 0; - this.sampleRate = 0; -} - -function fourccToInt(fourcc) { - return fourcc.charCodeAt(0) << 24 | fourcc.charCodeAt(1) << 16 | fourcc.charCodeAt(2) << 8 | fourcc.charCodeAt(3); -} - -WavHeader.RIFF = fourccToInt("RIFF"); -WavHeader.WAVE = fourccToInt("WAVE"); -WavHeader.fmt_ = fourccToInt("fmt "); -WavHeader.data = fourccToInt("data"); - -WavHeader.readHeader = function (dataView) { - var w = new WavHeader(); - - var header = dataView.getUint32(0, false); - if (WavHeader.RIFF != header) { - return; - } - var fileLen = dataView.getUint32(4, true); - if (WavHeader.WAVE != dataView.getUint32(8, false)) { - return; - } - if (WavHeader.fmt_ != dataView.getUint32(12, false)) { - return; - } - var fmtLen = dataView.getUint32(16, true); - var pos = 16 + 4; - switch (fmtLen) { - case 16: - case 18: - w.channels = dataView.getUint16(pos + 2, true); - w.sampleRate = dataView.getUint32(pos + 4, true); - break; - default: - throw 'extended fmt chunk not implemented'; - } - pos += fmtLen; - var data = WavHeader.data; - var len = 0; - while (data != header) { - header = dataView.getUint32(pos, false); - len = dataView.getUint32(pos + 4, true); - if (data == header) { - break; - } - pos += (len + 8); - } - w.dataLen = len; - w.dataOffset = pos + 8; - return w; -}; - -L3Side.SFBMAX = (Encoder.SBMAX_s * 3); -//testFullLength(); -lamejs.Mp3Encoder = Mp3Encoder; -lamejs.WavHeader = WavHeader; -} -//fs=require('fs'); -lamejs(); - -export default lamejs; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/lame.min.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/lame.min.js deleted file mode 100644 index 76e0cf6c6..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/lame.min.js +++ /dev/null @@ -1,308 +0,0 @@ -function lamejs(){function X(c){return new Int32Array(c)}function K(c){return new Float32Array(c)}function ca(c){if(1==c.length)return K(c[0]);var k=c[0];c=c.slice(1);for(var n=[],u=0;uf.sampleWindow-f.totsamp?f.sampleWindow-f.totsamp:d;if(lMAX_ORDER-l&&(g=MAX_ORDER-l)}else e=v+l,q=b,D=m+l,p=a;c(q,e,f.lstepbuf,f.lstep+f.totsamp,g,B[f.reqindex]);c(p,D,f.rstepbuf,f.rstep+f.totsamp,g,B[f.reqindex]);k(f.lstepbuf,f.lstep+f.totsamp,f.loutbuf,f.lout+f.totsamp,g,w[f.reqindex]);k(f.rstepbuf,f.rstep+f.totsamp,f.routbuf,f.rout+f.totsamp,g,w[f.reqindex]);e=f.lout+f.totsamp;q=f.loutbuf; -D=f.rout+f.totsamp;p=f.routbuf;for(var r=g%8;0!=r--;)f.lsum+=n(q[e++]),f.rsum+=n(p[D++]);for(r=g/8;0!=r--;)f.lsum+=n(q[e+0])+n(q[e+1])+n(q[e+2])+n(q[e+3])+n(q[e+4])+n(q[e+5])+n(q[e+6])+n(q[e+7]),e+=8,f.rsum+=n(p[D+0])+n(p[D+1])+n(p[D+2])+n(p[D+3])+n(p[D+4])+n(p[D+5])+n(p[D+6])+n(p[D+7]),D+=8;d-=g;l+=g;f.totsamp+=g;f.totsamp==f.sampleWindow&&(e=10*Y.STEPS_per_dB*Math.log10((f.lsum+f.rsum)/f.totsamp*.5+1E-37),e=0>=e?0:0|e,e>=f.A.length&&(e=f.A.length-1),f.A[e]++,f.lsum=f.rsum=0,T.arraycopy(f.loutbuf, -f.totsamp,f.loutbuf,0,MAX_ORDER),T.arraycopy(f.routbuf,f.totsamp,f.routbuf,0,MAX_ORDER),T.arraycopy(f.lstepbuf,f.totsamp,f.lstepbuf,0,MAX_ORDER),T.arraycopy(f.rstepbuf,f.totsamp,f.rstepbuf,0,MAX_ORDER),f.totsamp=0);if(f.totsamp>f.sampleWindow)return GAIN_ANALYSIS_ERROR}u=(m-=b[a])););b=64.82-a/Y.STEPS_per_dB}for(c=0;cf&&(f=0);9k&&(k+=64);b.exp_nspsytune|=k<<2}0!=a?b.quant_comp=f[m].quant_comp:0=c)return V(b,c,a);b.preset=0;return c}}function qb(){function u(a){this.bits=0|a}function k(a,d,p,b,e,c){d=.5946/d;for(a>>=1;0!=a--;)e[c++]=d>p[b++]? -0:1,e[c++]=d>p[b++]?0:1}function n(a,d,b,e,c,l){a>>=1;var h=a%2;for(a>>=1;0!=a--;){var p=b[e++]*d;var r=b[e++]*d;var t=0|p;var f=b[e++]*d;var g=0|r;var J=b[e++]*d;var D=0|f;p+=B.adj43[t];t=0|J;r+=B.adj43[g];c[l++]=0|p;f+=B.adj43[D];c[l++]=0|r;J+=B.adj43[t];c[l++]=0|f;c[l++]=0|J}0!=h&&(p=b[e++]*d,r=b[e++]*d,p+=B.adj43[0|p],r+=B.adj43[0|r],c[l++]=0|p,c[l++]=0|r)}function V(a,d,b,e){var p,c=d,h=p=0;do{var r=a[c++],l=a[c++];p>=16;p>a&&(p=a,d++);e.bits+=p;return d;case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:c=d;d=f[p-1];r=h=p=0;l=w.ht[d].xlen;var g=w.ht[d].hlen,D=w.ht[d+1].hlen,q=w.ht[d+2].hlen;do{var m=a[c+0]*l+a[c+1];c+=2;p+=g[m];h+=D[m];r+=q[m]}while(ch&&(p=h,a++);p>r&&(p=r,a=d+2);e.bits+=p;return a;default:if(p>ia.IXMAX_VAL)return e.bits=ia.LARGE_BITS,-1;p-=15;for(c=24;32>c&&!(w.ht[c].linmax>=p);c++);for(h=c-8;24>h&&!(w.ht[h].linmax>=p);h++);p=h;r=65536*w.ht[p].xlen+w.ht[c].xlen;h=0;do l=a[d++],g=a[d++],0!=l&&(14>=16;h>a&&(h=a,p=c);e.bits+=h;return p}}function E(a,d,p,b,e,l,h,g){for(var r=d.big_values,f=2;f=r)break;var t=e[f-2]+d.count1bits;if(p.part2_3_length<=t)break;t=new u(t);x=V(b,x,r,t);t=t.bits;p.part2_3_length<=t||(p.assign(d),p.part2_3_length=t,p.region0_count=l[f-2],p.region1_count=f-2-l[f-2],p.table_select[0]=h[f-2],p.table_select[1]=g[f-2],p.table_select[2]=x)}}var B=null;this.qupvt=null;this.setModules=function(a){B=this.qupvt=a};var ha=[[0,0],[0,0],[0,0],[0,0],[0,0],[0,1],[1,1],[1,1],[1,2],[2,2],[2,3],[2,3],[3,4],[3,4],[3,4],[4,5],[4,5],[4,6],[5,6],[5,6],[5,7],[6,7],[6,7]],f=[1,2, -5,7,7,10,10,13,13,13,13,13,13,13,13];this.noquant_count_bits=function(a,d,p){var b=d.l3_enc,e=Math.min(576,d.max_nonzero_coeff+2>>1<<1);null!=p&&(p.sfb_count1=0);for(;1h&&(f=h,d.count1table_select=1);d.count1bits=f;d.big_values=e;if(0==e)return f;d.block_type==c.SHORT_TYPE?(l=3*a.scalefac_band.s[3], -l>d.big_values&&(l=d.big_values),h=d.big_values):d.block_type==c.NORM_TYPE?(l=d.region0_count=a.bv_scf[e-2],h=d.region1_count=a.bv_scf[e-1],h=a.scalefac_band.l[l+h+2],l=a.scalefac_band.l[l+1],hh&&(l=h));l=Math.min(l,e);h=Math.min(h,e);0l)return ia.LARGE_BITS;l=B.IPOW20(e.global_gain);var h,f=0,g=0,r=0,D=0,m=0,q=p,v=0,C=d,I=0;var Q=null!=b&&e.global_gain==b.global_gain;var S=e.block_type==c.SHORT_TYPE?38:21;for(h=0;h<=S;h++){var u=-1;if(Q||e.block_type==c.NORM_TYPE)u= -e.global_gain-(e.scalefac[h]+(0!=e.preflag?B.pretab[h]:0)<e.max_nonzero_coeff&&(h=e.max_nonzero_coeff-f+1,na.fill(p,e.max_nonzero_coeff,576,0),Z=h,0>Z&&(Z=0),h=S+1);0==g&&0==r&&(q=p,v=m,C=d,I=D);null!=b&&0=b.sfb_count1&&0=b.step[h]?(0!=g&&(n(g,l,C,I,q,v),g=0,q=p,v=m,C=d,I=D),r+=Z):(0!=r&&(k(r,l,C,I,q,v),r=0,q= -p,v=m,C=d,I=D),g+=Z);if(0>=Z){0!=r&&(k(r,l,C,I,q,v),r=0);0!=g&&(n(g,l,C,I,q,v),g=0);break}}h<=S&&(m+=e.width[h],D+=e.width[h],f+=e.width[h])}0!=g&&n(g,l,C,I,q,v);0!=r&&k(r,l,C,I,q,v);if(0!=(a.substep_shaping&2))for(l=0,S=.634521682242439/B.IPOW20(e.global_gain+e.scalefac_scale),f=0;f=S?p[g]:0;return this.noquant_count_bits(a,e,b)};this.best_huffman_divide=function(a,d){var e=new rb,b=d.l3_enc,l=X(23),f=X(23), -h=X(23),g=X(23);if(d.block_type!=c.SHORT_TYPE||1!=a.mode_gr){e.assign(d);if(d.block_type==c.NORM_TYPE){for(var y=d.big_values,m=0;22>=m;m++)l[m]=ia.LARGE_BITS;for(m=0;16>m;m++){var D=a.scalefac_band.l[m+1];if(D>=y)break;var q=0,k=new u(q),v=V(b,0,D,k);q=k.bits;for(var C=0;8>C;C++){var I=a.scalefac_band.l[m+C+2];if(I>=y)break;k=q;k=new u(k);I=V(b,D,I,k);k=k.bits;l[m+C]>k&&(l[m+C]=k,f[m+C]=m,h[m+C]=v,g[m+C]=I)}}E(a,e,d,b,l,f,h,g)}y=e.big_values;if(!(0==y||1<(b[y-2]|b[y-1])||(y=d.count1+2,576e.big_values;y-=4)q=2*(2*(2*b[y-4]+b[y-3])+b[y-2])+b[y-1],m+=w.t32l[q],D+=w.t33l[q];e.big_values=y;e.count1table_select=0;m>D&&(m=D,e.count1table_select=1);e.count1bits=m;e.block_type==c.NORM_TYPE?E(a,e,d,b,l,f,h,g):(e.part2_3_length=m,m=a.scalefac_band.l[8],m>y&&(m=y),0m&&(a=new u(e.part2_3_length),e.table_select[1]=V(b,m,y,a),e.part2_3_length=a.bits),d.part2_3_length>e.part2_3_length&&d.assign(e))}}}; -var b=[1,1,1,1,8,2,2,2,4,4,4,8,8,8,16,16],v=[1,2,4,8,1,2,4,8,2,4,8,2,4,8,4,8],a=[0,0,0,0,3,1,1,1,2,2,2,3,3,3,4,4],m=[0,1,2,3,0,1,2,3,1,2,3,1,2,3,2,3];qb.slen1_tab=a;qb.slen2_tab=m;this.best_scalefac_store=function(d,e,p,l){var f=l.tt[e][p],g,h,r=0;for(g=h=0;gy&&0==f.l3_enc[y+h];y++);0==y&&(f.scalefac[g]=r=-2)}if(0==f.scalefac_scale&&0==f.preflag){for(g=h=0;g>=1);f.scalefac_scale=r=1}}if(0==f.preflag&&f.block_type!=c.SHORT_TYPE&&2==d.mode_gr){for(g=11;gg;g++)l.scfsi[p][g]=0;if(2==d.mode_gr&&1==e&&l.tt[0][p].block_type!=c.SHORT_TYPE&&l.tt[1][p].block_type!=c.SHORT_TYPE){e=l.tt[1][p];h=l.tt[0][p];for(r=0;rg;g++)-1!=e.scalefac[g]&&(l++,pr;r++)pg&&(e.part2_length=g,e.scalefac_compress=r));r=0}for(g=0;gd;d++)gm[d]&&(a.part2_length=m[d],a.scalefac_compress=d);return a.part2_length==ia.LARGE_BITS};var d=[[15,15,7,7],[15,15,7,0],[7,3,0,0],[15,31,31,0],[7,7,7,0],[3,3,0,0]];this.scale_bitcount_lsf=function(a,e){var b,f,l,m,h=X(4),x=e.scalefac;a=0!=e.preflag?2:0;for(l=0;4>l;l++)h[l]=0;if(e.block_type==c.SHORT_TYPE){var y=1;var k=B.nr_of_sfb_block[a][y]; -for(b=m=0;4>b;b++){var q=k[b]/3;for(l=0;lf;f++)x[3*m+f]>h[b]&&(h[b]=x[3*m+f])}}else for(y=0,k=B.nr_of_sfb_block[a][y],b=m=0;4>b;b++)for(q=k[b],l=0;lh[b]&&(h[b]=x[m]);q=!1;for(b=0;4>b;b++)h[b]>d[a][b]&&(q=!0);if(!q){e.sfb_partition_table=B.nr_of_sfb_block[a][y];for(b=0;4>b;b++)e.slen[b]=g[h[b]];y=e.slen[0];b=e.slen[1];h=e.slen[2];f=e.slen[3];switch(a){case 0:e.scalefac_compress=(5*y+b<<4)+(h<<2)+f;break;case 1:e.scalefac_compress=400+(5*y+b<<2)+h;break;case 2:e.scalefac_compress= -500+3*y+b;break;default:T.err.printf("intensity stereo not implemented yet\n")}}if(!q)for(b=e.part2_length=0;4>b;b++)e.part2_length+=e.slen[b]*e.sfb_partition_table[b];return q};var g=[0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4];this.huffman_init=function(a){for(var d=2;576>=d;d+=2){for(var e=0,b;a.scalefac_band.l[++e]d;)b--;0>b&&(b=ha[e][0]);a.bv_scf[d-2]=b;for(b=ha[e][1];a.scalefac_band.l[b+a.bv_scf[d-2]+2]>d;)b--;0>b&&(b=ha[e][1]);a.bv_scf[d-1]=b}}}function xc(){var c; -this.setModules=function(k){c=k};this.ResvFrameBegin=function(k,n){var u=k.internal_flags,E=u.l3_side,B=c.getframebits(k);n.bits=(B-8*u.sideinfo_len)/u.mode_gr;var w=2048*u.mode_gr-8;if(320w&&(u.ResvMax=w);if(0>u.ResvMax||k.disable_reservoir)u.ResvMax=0;k=n.bits*u.mode_gr+Math.min(u.ResvSize,u.ResvMax);k>f&&(k=f);E.resvDrain_pre=0;null!=u.pinfo&& -(u.pinfo.mean_bits=n.bits/2,u.pinfo.resvsize=u.ResvSize);return k};this.ResvMaxBits=function(c,n,u,E){var k=c.internal_flags,w=k.ResvSize,f=k.ResvMax;0!=E&&(w+=n);0!=(k.substep_shaping&1)&&(f*=.9);u.bits=n;10*w>9*f?(E=w-9*f/10,u.bits+=E,k.substep_shaping|=128):(E=0,k.substep_shaping&=127,c.disable_reservoir||0!=(k.substep_shaping&1)||(u.bits-=.1*n));c=w<6*k.ResvMax/10?w:6*k.ResvMax/10;c-=E;0>c&&(c=0);return c};this.ResvAdjust=function(c,n){c.ResvSize-=n.part2_3_length+n.part2_length};this.ResvFrameEnd= -function(c,n){var k,u=c.l3_side;c.ResvSize+=n*c.mode_gr;n=0;u.resvDrain_post=0;u.resvDrain_pre=0;0!=(k=c.ResvSize%8)&&(n+=k);k=c.ResvSize-n-c.ResvMax;0>b<> -3]|=d>>e<<8-(b&7)-h;b+=h}a.header[a.h_ptr].ptr=b}function V(a,d){a<<=8;for(var e=0;8>e;e++)a<<=1,d<<=1,0!=((d^a)&65536)&&(d^=32773);return d}function E(a,d){var e=w.ht[d.count1table_select+32],b,h=0,c=d.big_values,g=d.big_values;for(b=(d.count1-d.big_values)/4;0d.xr[g+0]&&l++);p=d.l3_enc[c+1];0!=p&&(f+=4,l*=2,0>d.xr[g+1]&&l++);p=d.l3_enc[c+2];0!=p&&(f+=2,l*=2,0>d.xr[g+2]&&l++);p=d.l3_enc[c+3];0!=p&&(f++,l*=2,0>d.xr[g+3]&&l++);c+=4;g+=4;u(a,l+e.table[f], -e.hlen[f]);h+=e.hlen[f]}return h}function B(a,d,e,b,h){var c=w.ht[d],g=0;if(0==d)return g;for(;eh.xr[e]&&m++,l--);15h.xr[e+1]&&m++,l--);C=C*r+k;f-=l;l+=c.hlen[C];u(a,c.table[C],l);u(a,m,f);g+=l+f}return g}function K(a,d){var e=3*a.scalefac_band.s[3];e>d.big_values&&(e=d.big_values);var b=B(a,d.table_select[0],0,e,d);return b+=B(a, -d.table_select[1],e,d.big_values,d)}function f(a,d){var e=d.big_values;var b=d.region0_count+1;var h=a.scalefac_band.l[b];b+=d.region1_count+1;var c=a.scalefac_band.l[b];h>e&&(h=e);c>e&&(c=e);b=B(a,d.table_select[0],0,h,d);b+=B(a,d.table_select[1],h,c,d);return b+=B(a,d.table_select[2],c,e,d)}function b(){this.total=0}function v(d,e){var b=d.internal_flags;var c=b.w_ptr;var h=b.h_ptr-1;-1==h&&(h=da.MAX_HEADER_BUF-1);var l=b.header[h].write_timing-g;e.total=l;if(0<=l){var f=1+h-c;hl&&T.err.println("strange error flushing buffer ... \n");return l}var a=this,m=null,z=null,e=null,l=null;this.setModules=function(a,d,b,c){m=a;z=d;e=b;l=c};var d=null,g=0,q=0,D=0;this.getframebits=function(a){var d=a.internal_flags;return 8*(0|72E3*(a.version+1)*(0!=d.bitrate_index?w.bitrate_table[a.version][d.bitrate_index]:a.brate)/a.out_samplerate+d.padding)};this.CRC_writeheader= -function(a,d){var e=V(d[2]&255,65535);e=V(d[3]&255,e);for(var b=6;b>8);d[5]=byte(e&255)};this.flush_bitstream=function(a){var d=a.internal_flags,e;var c=d.l3_side;0>(e=v(a,new b))||(k(a,e),d.ResvSize=0,c.main_data_begin=0,d.findReplayGain&&(c=m.GetTitleGain(d.rgdata),d.RadioGain=Math.floor(10*c+.5)|0),d.findPeakSample&&(d.noclipGainChange=Math.ceil(200*Math.log10(d.PeakSample/32767))|0,0>h<a.out_samplerate?n(h,4094,12):n(h,4095,12);n(h,a.version,1);n(h,1,2);n(h,a.error_protection?0:1,1);n(h,h.bitrate_index,4);n(h,h.samplerate_index,2);n(h,h.padding,1);n(h,a.extension,1);n(h,a.mode.ordinal(),2);n(h,h.mode_ext,2);n(h,a.copyright,1);n(h,a.original,1);n(h,a.emphasis,2);a.error_protection&&n(h,0,16);if(1==a.version){n(h,m.main_data_begin,9);2==h.channels_out?n(h,m.private_bits,3):n(h,m.private_bits,5);for(y=0;yp;p++)n(h,m.scfsi[y][p], -1);for(p=0;2>p;p++)for(y=0;ym;m++)for(y=0;yQ;Q++){var w=C.sfb_partition_table[Q]/3,Z=C.slen[Q];for(I=0;IQ;Q++)for(w=C.sfb_partition_table[Q],Z=C.slen[Q],I=0;I ResvSize");8*e.main_data_begin!=d.ResvSize&&(T.err.printf("bit reservoir error: \nl3_side.main_data_begin: %d \nResvoir size: %d \nresv drain (post) %d \nresv drain (pre) %d \nheader and sideinfo: %d \ndata bits: %d \ntotal bits: %d (remainder: %d) \nbitsperframe: %d \n", -8*e.main_data_begin,d.ResvSize,e.resvDrain_post,e.resvDrain_pre,8*d.sideinfo_len,h-e.resvDrain_post-8*d.sideinfo_len,h,h%8,l),T.err.println("This is a fatal error. It has several possible causes:"),T.err.println("90%% LAME compiled with buggy version of gcc using advanced optimizations"),T.err.println(" 9%% Your system is overclocked"),T.err.println(" 1%% bug in LAME encoding library"),d.ResvSize=8*e.main_data_begin);if(1E9=g)return 0;if(0!=c&&g>c)return-1;T.arraycopy(d,0,e,b,g);q=-1;D=0;if(0!=h&&(c=X(1),c[0]=a.nMusicCRC,l.updateMusicCRC(c,e,b,g),a.nMusicCRC=c[0],0a.PeakSample?a.PeakSample=c[0][p]:-c[0][p]>a.PeakSample&&(a.PeakSample=-c[0][p]);if(1< -a.channels_out)for(p=0;pa.PeakSample?a.PeakSample=c[1][p]:-c[1][p]>a.PeakSample&&(a.PeakSample=-c[1][p])}if(a.findReplayGain&&m.AnalyzeSamples(a.rgdata,c[0],0,c[1],0,f,a.channels_out)==Y.GAIN_ANALYSIS_ERROR)return-6}}return g};this.init_bit_stream_w=function(a){d=new Int8Array(W.LAME_MAXMP3BUFFER);a.h_ptr=a.w_ptr=0;a.header[a.h_ptr].write_timing=0;q=-1;g=D=0}}function zb(){function c(a,b){var d=a[b+0]&255;d=d<<8|a[b+1]&255;d=d<<8|a[b+2]&255;return d=d<<8|a[b+3]&255}function k(a,b,d){a[b+ -0]=d>>24&255;a[b+1]=d>>16&255;a[b+2]=d>>8&255;a[b+3]=d&255}function n(a,b,d){a[b+0]=d>>8&255;a[b+1]=d&255}function V(a,b,d){return 255&(a<a.out_samplerate?0:1);b[1]=V(b[1],1,a.version);b[1]=V(b[1],2,1);b[1]=V(b[1],1,a.error_protection?0:1);b[2]=V(b[2],4,d.bitrate_index);b[2]=V(b[2],2,d.samplerate_index);b[2]=V(b[2],1,0);b[2]=V(b[2],1,a.extension);b[3]=V(b[3],2,a.mode.ordinal());b[3]=V(b[3], -2,d.mode_ext);b[3]=V(b[3],1,a.copyright);b[3]=V(b[3],1,a.original);b[3]=V(b[3],2,a.emphasis);b[0]=255;d=b[1]&241;var e=1==a.version?128:16E3>a.out_samplerate?32:64;a.VBR==G.vbr_off&&(e=a.brate);e=a.free_format?0:255&16*K.BitrateIndex(e,a.version,a.out_samplerate);b[1]=1==a.version?255&(d|10):255&(d|2);d=b[2]&13;b[2]=255&(e|d)}function B(a,b){return b=b>>8^z[(b^a)&255]}var K,f,b;this.setModules=function(a,c,d){K=a;f=c;b=d};var v=zb.NUMTOCENTRIES,a=zb.MAXFRAMESIZE,m=v+4+4+4+4+4+9+1+1+8+1+1+3+1+1+2+ -4+2+2,z=[0,49345,49537,320,49921,960,640,49729,50689,1728,1920,51009,1280,50625,50305,1088,52225,3264,3456,52545,3840,53185,52865,3648,2560,51905,52097,2880,51457,2496,2176,51265,55297,6336,6528,55617,6912,56257,55937,6720,7680,57025,57217,8E3,56577,7616,7296,56385,5120,54465,54657,5440,55041,6080,5760,54849,53761,4800,4992,54081,4352,53697,53377,4160,61441,12480,12672,61761,13056,62401,62081,12864,13824,63169,63361,14144,62721,13760,13440,62529,15360,64705,64897,15680,65281,16320,16E3,65089,64001, -15040,15232,64321,14592,63937,63617,14400,10240,59585,59777,10560,60161,11200,10880,59969,60929,11968,12160,61249,11520,60865,60545,11328,58369,9408,9600,58689,9984,59329,59009,9792,8704,58049,58241,9024,57601,8640,8320,57409,40961,24768,24960,41281,25344,41921,41601,25152,26112,42689,42881,26432,42241,26048,25728,42049,27648,44225,44417,27968,44801,28608,28288,44609,43521,27328,27520,43841,26880,43457,43137,26688,30720,47297,47489,31040,47873,31680,31360,47681,48641,32448,32640,48961,32E3,48577, -48257,31808,46081,29888,30080,46401,30464,47041,46721,30272,29184,45761,45953,29504,45313,29120,28800,45121,20480,37057,37249,20800,37633,21440,21120,37441,38401,22208,22400,38721,21760,38337,38017,21568,39937,23744,23936,40257,24320,40897,40577,24128,23040,39617,39809,23360,39169,22976,22656,38977,34817,18624,18816,35137,19200,35777,35457,19008,19968,36545,36737,20288,36097,19904,19584,35905,17408,33985,34177,17728,34561,18368,18048,34369,33281,17088,17280,33601,16640,33217,32897,16448];this.addVbrFrame= -function(a){var b=a.internal_flags;var d=b.VBR_seek_table;a=w.bitrate_table[a.version][b.bitrate_index];d.nVbrNumFrames++;d.sum+=a;d.seen++;if(!(d.seen>3&1,f=a[d+2]>>2&3,m=a[d+3]>>6&3,p=a[d+2]>>4&15;p=w.bitrate_table[e][p];b.samprate=14==a[d+1]>>4?w.samplerate_table[2][f]:w.samplerate_table[e][f]; -f=d=0!=e?3!=m?d+36:d+21:3!=m?d+21:d+13;if(!(new String(a,f,4(),null)).equals("Xing")&&!(new String(a,f,4(),null)).equals("Info"))return null;d+=4;b.hId=e;f=b.flags=c(a,d);d+=4;0!=(f&1)&&(b.frames=c(a,d),d+=4);0!=(f&2)&&(b.bytes=c(a,d),d+=4);if(0!=(f&4)){if(null!=b.toc)for(m=0;m>4;p=(a[d+1]&15)<<8;p+=a[d+2]&255;if(0>e||3E3p||3E3b.out_samplerate?32:64;b.VBR==G.vbr_off&&(d=b.brate);d=72E3*(b.version+1)*d/b.out_samplerate;var c=e.sideinfo_len+m;e.VBR_seek_table.TotalFrameSize=d;if(da)b.bWriteVbrTag=!1;else for(e.VBR_seek_table.nVbrNumFrames=0,e.VBR_seek_table.nBytesWritten=0,e.VBR_seek_table.sum=0,e.VBR_seek_table.seen=0,e.VBR_seek_table.want=1,e.VBR_seek_table.pos=0,null==e.VBR_seek_table.bag&&(e.VBR_seek_table.bag= -new int[400],e.VBR_seek_table.size=400),d=new Int8Array(a),E(b,d),e=e.VBR_seek_table.TotalFrameSize,c=0;c=d.VBR_seek_table.pos)return 0;if(c.length=m.pos))for(l=1;lm.pos-1&&(p=m.pos-1);p=0|256*m.bag[p]/m.sum;255t.RadioGain&&(t.RadioGain=-510),w=11264,w=0<=t.RadioGain?w|t.RadioGain:w|512|-t.RadioGain);t.findPeakSample&&(z=Math.abs(0|t.PeakSample/32767*Math.pow(2,23)+.5));-1!=ma&&(0h&&(h=0);switch(a.mode){case MONO:Q=0;break;case STEREO:Q=1;break; -case DUAL_CHANNEL:Q=2;break;case JOINT_STEREO:Q=a.force_ms?4:3;break;default:Q=7}C=32E3>=a.in_samplerate?0:48E3==a.in_samplerate?2:48E3a.scale_right||a.disable_reservoir&&320>a.brate||a.noATH||a.ATHonly||0==L||32E3>=a.in_samplerate)F=1;O=O+(Q<<2)+(F<<5)+(C<<6);t=t.nMusicCRC;k(c,e+p,h);p+=4;for(h=0;9>h;h++)c[e+p+h]= -255&x.charAt(h);p+=9;c[e+p]=255&y;p++;c[e+p]=255&A;p++;k(c,e+p,z);p+=4;n(c,e+p,w);p+=2;n(c,e+p,0);p+=2;c[e+p]=255&I;p++;c[e+p]=255<=V?255:255&V;p++;c[e+p]=255&r>>4;c[e+p+1]=255&(r<<4)+(u>>8);c[e+p+2]=255&u;p+=3;c[e+p]=255&O;p++;c[e+p++]=0;n(c,e+p,a.preset);p+=2;k(c,e+p,m);p+=4;n(c,e+p,t);p+=2;for(a=0;a=b.internal_flags.VBR_seek_table.pos)return-1;c.seek(c.length());if(0==c.length())return-1;c.seek(0); -var d=new Int8Array(10);c.readFully(d);d=(new String(d,"ISO-8859-1")).startsWith("ID3")?0:((d[6]&127)<<21|(d[7]&127)<<14|(d[8]&127)<<7|d[9]&127)+d.length;c.seek(d);d=new Int8Array(a);b=getLameTagFrame(b,d);if(b>d.length)return-1;if(1>b)return 0;c.write(d,0,b);return 0}}function U(c,k,n,w){this.xlen=c;this.linmax=k;this.table=n;this.hlen=w}function xa(c){this.bits=c}function yc(){this.setModules=function(c,k){}}function sb(){this.bits=this.over_SSD=this.over_count=this.max_noise=this.tot_noise=this.over_noise= -0}function zc(){this.scale_right=this.scale_left=this.scale=this.out_samplerate=this.in_samplerate=this.num_channels=this.num_samples=this.class_id=0;this.decode_only=this.bWriteVbrTag=this.analysis=!1;this.quality=0;this.mode=la.STEREO;this.write_id3tag_automatic=this.decode_on_the_fly=this.findReplayGain=this.free_format=this.force_ms=!1;this.error_protection=this.emphasis=this.extension=this.original=this.copyright=this.compression_ratio=this.brate=0;this.disable_reservoir=this.strict_ISO=!1;this.quant_comp_short= -this.quant_comp=0;this.experimentalY=!1;this.preset=this.exp_nspsytune=this.experimentalZ=0;this.VBR=null;this.maskingadjust_short=this.maskingadjust=this.highpasswidth=this.lowpasswidth=this.highpassfreq=this.lowpassfreq=this.VBR_hard_min=this.VBR_max_bitrate_kbps=this.VBR_min_bitrate_kbps=this.VBR_mean_bitrate_kbps=this.VBR_q=this.VBR_q_frac=0;this.noATH=this.ATHshort=this.ATHonly=!1;this.athaa_sensitivity=this.athaa_loudapprox=this.athaa_type=this.ATHlower=this.ATHcurve=this.ATHtype=0;this.short_blocks= -null;this.useTemporal=!1;this.msfix=this.interChRatio=0;this.tune=!1;this.lame_allocated_gfp=this.frameNum=this.framesize=this.encoder_padding=this.encoder_delay=this.version=this.tune_value_a=0;this.internal_flags=null}function Ac(){this.linprebuf=K(2*Y.MAX_ORDER);this.linpre=0;this.lstepbuf=K(Y.MAX_SAMPLES_PER_WINDOW+Y.MAX_ORDER);this.lstep=0;this.loutbuf=K(Y.MAX_SAMPLES_PER_WINDOW+Y.MAX_ORDER);this.lout=0;this.rinprebuf=K(2*Y.MAX_ORDER);this.rinpre=0;this.rstepbuf=K(Y.MAX_SAMPLES_PER_WINDOW+Y.MAX_ORDER); -this.rstep=0;this.routbuf=K(Y.MAX_SAMPLES_PER_WINDOW+Y.MAX_ORDER);this.first=this.freqindex=this.rsum=this.lsum=this.totsamp=this.sampleWindow=this.rout=0;this.A=X(0|Y.STEPS_per_dB*Y.MAX_dB);this.B=X(0|Y.STEPS_per_dB*Y.MAX_dB)}function Bc(u){this.quantize=u;this.iteration_loop=function(k,n,u,w){var B=k.internal_flags,E=K(sa.SFBMAX),f=K(576),b=X(2),v=B.l3_side;var a=new xa(0);this.quantize.rv.ResvFrameBegin(k,a);a=a.bits;for(var m=0;m>2&63;32<=d&&(d-=64);g=Math.pow(10,d/4/10);d=b.exp_nspsytune>>8&63;32<=d&&(d-=64);q=Math.pow(10,d/4/10);d=b.exp_nspsytune>>14&63;32<=d&&(d-=64);k= -Math.pow(10,d/4/10);d=b.exp_nspsytune>>20&63;32<=d&&(d-=64);b=k*Math.pow(10,d/4/10);for(d=0;d=d?g:13>=d?q:20>=d?k:b,e.nsPsy.longfact[d]=p;for(d=0;d=d?g:10>=d?q:11>=d?k:b,e.nsPsy.shortfact[d]=p}};this.on_pe=function(a,b,d,c,f,m){var e=a.internal_flags,g=0,l=X(2),q;g=new xa(g);a=w.ResvMaxBits(a,c,g,m);g=g.bits;var h=g+a;h>da.MAX_BITS_PER_GRANULE&&(h=da.MAX_BITS_PER_GRANULE);for(q=m=0;q3*c/4&&(l[q]=3*c/4),0>l[q]&&(l[q]=0),l[q]+d[q]>da.MAX_BITS_PER_CHANNEL&&(l[q]=Math.max(0,da.MAX_BITS_PER_CHANNEL-d[q])),m+=l[q];if(m>a)for(q=0;qda.MAX_BITS_PER_GRANULE)for(q=0;qb&&(b=0);.5da.MAX_BITS_PER_CHANNEL- -a[0]&&(b=da.MAX_BITS_PER_CHANNEL-a[0]);0>b&&(b=0);125<=a[1]&&(125c&&(a[0]=c*a[0]/b,a[1]=c*a[1]/b)};this.athAdjust=function(a,b,d){b=aa.FAST_LOG10_X(b,10);a*=a;var c=0;b-=d;1E-20c&&(c=0);return Math.pow(10,.1*(b*c+(d+90.30873362-94.82444863)))};this.calc_xmin=function(a,b,d,f){var e=0,g=a.internal_flags,m,l=0,k=0,v=g.ATH,h=d.xr,x=a.VBR==G.vbr_mtrh?1:0,y=g.masking_lower;if(a.VBR== -G.vbr_mtrh||a.VBR==G.vbr_mt)y=1;for(m=0;m>1;var C=0;do{var I=h[l]*h[l];C+=I;B+=IA&&k++;m==c.SBPSY_l&&(u=A*g.nsPsy.longfact[m],BS;S++){C=0;z=n>>1;u=w/n;B=2.220446049250313E-16;do I=h[l]*h[l],C+=I,B+=Iw&&k++;Q==c.SBPSY_s&&(u=w*g.nsPsy.shortfact[Q],Bf[e-3+1]&&(f[e-3+1]+=(f[e-3]-f[e-3+1])*g.decay),f[e-3+1]>f[e-3+2]&&(f[e-3+2]+=(f[e-3+1]-f[e-3+2])*g.decay))}return k};this.calc_noise_core=function(a,b,d,c){var e=0,f=b.s,g=a.l3_enc;if(f>a.count1)for(;0!=d--;){var l=a.xr[f];f++;e+=l*l;l=a.xr[f];f++;e+=l*l}else if(f>a.big_values){var k=K(2);k[0]=0;for(k[1]=c;0!=d--;)l=Math.abs(a.xr[f])-k[g[f]],f++,e+=l*l,l=Math.abs(a.xr[f])- -k[g[f]],f++,e+=l*l}else for(;0!=d--;)l=Math.abs(a.xr[f])-m[g[f]]*c,f++,e+=l*l,l=Math.abs(a.xr[f])-m[g[f]]*c,f++,e+=l*l;b.s=f;return e};this.calc_noise=function(a,c,d,f,m){var e=0,g=0,l,q=0,u=0,h=0,x=-20,y=0,A=a.scalefac,n=0;for(l=f.over_SSD=0;l>1;y+a.width[l]> -a.max_nonzero_coeff&&(w=a.max_nonzero_coeff-y+1,w=0>1:0);y=new k(y);z=this.calc_noise_core(a,y,w,z);y=y.s;null!=m&&(m.step[l]=B,m.noise[l]=z);z=d[e++]=z/c[g++];z=aa.FAST_LOG10(Math.max(z,1E-20));null!=m&&(m.noise_log[l]=z)}null!=m&&(m.global_gain=a.global_gain);h+=z;0I;I++){k=0;for(C=B;Cf;++f){var a=c.tt[b][0].xr[f],m=c.tt[b][1].xr[f];c.tt[b][0].xr[f]=.5*(a+m)*aa.SQRT2; -c.tt[b][1].xr[f]=.5*(a-m)*aa.SQRT2}};this.init_xrpow=function(c,b,k){var a=0|b.max_nonzero_coeff;b.xrpow_max=0;na.fill(k,a,576,0);for(var f,v=f=0;v<=a;++v){var e=Math.abs(b.xr[v]);f+=e;k[v]=Math.sqrt(e*Math.sqrt(e));k[v]>b.xrpow_max&&(b.xrpow_max=k[v])}if(1E-20l;l++)for(var d=n;d=n;e--)if(Math.abs(a[e])l;l++)for(b=!1,m=c.PSFB12-1;0<=m&&!b;m--)for(n=3*f.scalefac_band.s[12]+(f.scalefac_band.s[13]-f.scalefac_band.s[12])*l+(f.scalefac_band.psfb12[m]-f.scalefac_band.psfb12[0]),e=n+(f.scalefac_band.psfb12[m+1]-f.scalefac_band.psfb12[m]),d=E.athAdjust(k.adjust,k.psfb12[m],k.floor),1E-12=n;e--)if(Math.abs(a[e])n;n++){var e=0;0!=b.l3_enc[n]&&(e=Math.abs(b.xr[n]));a[n]=e}n=0;e=8;b.block_type==c.SHORT_TYPE&&(e=6);do{var l,d,g=b.width[e];n+=g;if(!(1<=m[e]||(na.sort(a,n-g,g),qa.EQ(a[n-1],0)))){var q=(1-m[e])*k[e];var v=l=0;do{for(d= -1;v+dh?(z==u.BINSEARCH_DOWN&&(y=!0),y&&(x/=2),z=u.BINSEARCH_UP,H=x):(z==u.BINSEARCH_UP&&(y=!0),y&&(x/=2),z=u.BINSEARCH_DOWN,H=-x);b.global_gain+=H;0>b.global_gain&&(b.global_gain=0,y=!0);255h&&255>b.global_gain;)b.global_gain++,H=ha.count_bits(e,a,b,null);e.CurrentStep[m]=4<=A-b.global_gain?4:2;e.OldValue[m]=b.global_gain;b.part2_3_length=H;if(0==e.noise_shaping)return 100;E.calc_noise(b,n,g,q,v);q.bits=b.part2_3_length; -l.assign(b);m=0;for(T.arraycopy(a,0,d,0,576);!r;){do{h=new sb;y=255;x=0!=(e.substep_shaping&2)?20:3;if(e.sfb21_extra){if(1L;L++)C[Z+L]*=Q,C[Z+L]>O.xrpow_max&&(O.xrpow_max=C[Z+L]);if(2==I.noise_shaping_amp)break}}if(Q=k(A))A=!1;else if(Q=2==z.mode_gr?ha.scale_bitcount(A):ha.scale_bitcount_lsf(z,A)){if(1I;I++)H[O+I]*=1.2968395546510096,H[O+I]>Q.xrpow_max&&(Q.xrpow_max=H[O+I]);Q.scalefac[F]=C>>1}Q.preflag=0;Q.scalefac_scale=1;Q=!1}else if(A.block_type==c.SHORT_TYPE&&0I;I++){ma=S=0;for(H=O.sfb_lmax+I;HS&&8>ma)){if(7<=O.subblock_gain[I]){H= -!0;break b}O.subblock_gain[I]++;S=Q.scalefac_band.l[O.sfb_lmax];for(H=O.sfb_lmax+I;H>O.scalefac_scale,0<=Z)C[H]=Z,S+=3*ma;else{C[H]=0;Z=E.IPOW20(210+(Z<L;L++)F[S+L]*=Z,F[S+L]>O.xrpow_max&&(O.xrpow_max=F[S+L]);S+=ma*(3-I-1)}Z=E.IPOW20(202);S+=O.width[H]*(I+1);for(L=-O.width[H];0>L;L++)F[S+L]*=Z,F[S+L]>O.xrpow_max&&(O.xrpow_max=F[S+L])}}H=!1}Q=H||k(A)}Q||(Q=2==z.mode_gr?ha.scale_bitcount(A):ha.scale_bitcount_lsf(z, -A));A=!Q}else A=!0;if(!A)break;0!=l.scalefac_scale&&(y=254);A=B-l.part2_length;if(0>=A)break;for(;(l.part2_3_length=ha.count_bits(e,a,l,v))>A&&l.global_gain<=y;)l.global_gain++;if(l.global_gain>y)break;if(0==q.over_count){for(;(l.part2_3_length=ha.count_bits(e,a,l,v))>p&&l.global_gain<=y;)l.global_gain++;if(l.global_gain>y)break}E.calc_noise(l,n,g,h,v);h.bits=l.part2_3_length;z=b.block_type!=c.SHORT_TYPE?f.quant_comp:f.quant_comp_short;y=q;A=h;Q=l;H=g;switch(z){default:case 9:0A.max_noise&&10*A.max_noise+A.bits<=10*y.max_noise+y.bits;break;case 0:z=A.over_count=A.max_noise&&.2=A.max_noise&&0>y.max_noise&&y.max_noise>A.max_noise-.2&&A.tot_noise=A.max_noise&&0A.max_noise-.2&&A.tot_noiseA.max_noise-.1&&A.tot_noise+A.over_noiseA.max_noise-.15&&A.tot_noise+A.over_noise+A.over_noisex&&0== -q.over_count)break;if(3==e.noise_shaping_amp&&t&&30l.global_gain+l.scalefac_scale);3==e.noise_shaping_amp?t?r=!0:(l.assign(b),T.arraycopy(d,0,a,0,576),m=0,w=l.global_gain,t=!0):r=!0}f.VBR==G.vbr_rh||f.VBR==G.vbr_mtrh?T.arraycopy(d,0,a,0,576):0!=(e.substep_shaping&1)&&trancate_smallspectrums(e,b,n,a);return q.over_count};this.iteration_finish_one=function(c,b,k){var a=c.l3_side,f=a.tt[b][k];ha.best_scalefac_store(c,b,k,a);1== -c.use_best_huffman&&ha.best_huffman_divide(c,f);w.ResvAdjust(c,f)};this.VBR_encode_granule=function(c,b,k,a,m,n,e){var f=c.internal_flags,d=new rb,g=K(576),q=e,v=(e+n)/2,p=0,r=f.sfb21_extra;na.fill(d.l3_enc,0);do{f.sfb21_extra=v>q-42?!1:r;var t=outer_loop(c,b,k,a,m,v);0>=t?(p=1,e=b.part2_3_length,d.assign(b),T.arraycopy(a,0,g,0,576),e-=32,t=e-n,v=(e+n)/2):(n=v+32,t=e-n,v=(e+n)/2,0!=p&&(p=2,b.assign(d),T.arraycopy(g,0,a,0,576)))}while(12n[g.VBR_max_bitrate]&& -(l[r][t]*=n[g.VBR_max_bitrate],l[r][t]/=v),e[r][t]>l[r][t]&&(e[r][t]=l[r][t]);return q};this.bitpressure_strategy=function(f,b,k,a){for(var m=0;mq&&(n[m][v]*=q,n[m][v]/=g);return l};this.calc_target_bits=function(f,b,k,a,m,u){var e=f.internal_flags,l=e.l3_side;e.bitrate_index=e.VBR_max_bitrate;var d=new xa(0);u[0]=w.ResvFrameBegin(f,d);e.bitrate_index=1;d=n.getframebits(f)-8*e.sideinfo_len;m[0]=d/(e.mode_gr*e.channels_out);d=f.VBR_mean_bitrate_kbps*f.framesize*1E3;0!=(e.substep_shaping&1)&&(d*=1.09);d/=f.out_samplerate; -d-=8*e.sideinfo_len;d/=e.mode_gr*e.channels_out;var g=.93+.07*(11-f.compression_ratio)/5.5;.9>g&&(g=.9);13*d/2?v=3*d/2:0>v&&(v=0);a[f][m]+=v}a[f][m]>da.MAX_BITS_PER_CHANNEL&&(a[f][m]=da.MAX_BITS_PER_CHANNEL);q+=a[f][m]}if(q>da.MAX_BITS_PER_GRANULE)for(m=0;mda.MAX_BITS_PER_CHANNEL&&(a[f][m]=da.MAX_BITS_PER_CHANNEL),b+=a[f][m];if(b>u[0])for(f=0;fe;e++){var l=k[f+-10];var d=b[n+-224]*l;var g=b[c+224]*l;l=k[f+-9];d+=b[n+-160]* -l;g+=b[c+160]*l;l=k[f+-8];d+=b[n+-96]*l;g+=b[c+96]*l;l=k[f+-7];d+=b[n+-32]*l;g+=b[c+32]*l;l=k[f+-6];d+=b[n+32]*l;g+=b[c+-32]*l;l=k[f+-5];d+=b[n+96]*l;g+=b[c+-96]*l;l=k[f+-4];d+=b[n+160]*l;g+=b[c+-160]*l;l=k[f+-3];d+=b[n+224]*l;g+=b[c+-224]*l;l=k[f+-2];d+=b[c+-256]*l;g-=b[n+256]*l;l=k[f+-1];d+=b[c+-192]*l;g-=b[n+192]*l;l=k[f+0];d+=b[c+-128]*l;g-=b[n+128]*l;l=k[f+1];d+=b[c+-64]*l;g-=b[n+64]*l;l=k[f+2];d+=b[c+0]*l;g-=b[n+0]*l;l=k[f+3];d+=b[c+64]*l;g-=b[n+-64]*l;l=k[f+4];d+=b[c+128]*l;g-=b[n+-128]*l; -l=k[f+5];d+=b[c+192]*l;g-=b[n+-192]*l;d*=k[f+6];l=g-d;a[30+2*e]=g+d;a[31+2*e]=k[f+7]*l;f+=18;c--;n++}g=b[c+-16]*k[f+-10];d=b[c+-32]*k[f+-2];g+=(b[c+-48]-b[c+16])*k[f+-9];d+=b[c+-96]*k[f+-1];g+=(b[c+-80]+b[c+48])*k[f+-8];d+=b[c+-160]*k[f+0];g+=(b[c+-112]-b[c+80])*k[f+-7];d+=b[c+-224]*k[f+1];g+=(b[c+-144]+b[c+112])*k[f+-6];d-=b[c+32]*k[f+2];g+=(b[c+-176]-b[c+144])*k[f+-5];d-=b[c+96]*k[f+3];g+=(b[c+-208]+b[c+176])*k[f+-4];d-=b[c+160]*k[f+4];g+=(b[c+-240]-b[c+208])*k[f+-3];d-=b[c+224];b=d-g;c=d+g;g=a[14]; -d=a[15]-g;a[31]=c+g;a[30]=b+d;a[15]=b-d;a[14]=c-g;d=a[28]-a[0];a[0]+=a[28];a[28]=d*k[f+-36+7];d=a[29]-a[1];a[1]+=a[29];a[29]=d*k[f+-36+7];d=a[26]-a[2];a[2]+=a[26];a[26]=d*k[f+-72+7];d=a[27]-a[3];a[3]+=a[27];a[27]=d*k[f+-72+7];d=a[24]-a[4];a[4]+=a[24];a[24]=d*k[f+-108+7];d=a[25]-a[5];a[5]+=a[25];a[25]=d*k[f+-108+7];d=a[22]-a[6];a[6]+=a[22];a[22]=d*aa.SQRT2;d=a[23]-a[7];a[7]+=a[23];a[23]=d*aa.SQRT2-a[7];a[7]-=a[6];a[22]-=a[7];a[23]-=a[22];d=a[6];a[6]=a[31]-d;a[31]+=d;d=a[7];a[7]=a[30]-d;a[30]+=d;d= -a[22];a[22]=a[15]-d;a[15]+=d;d=a[23];a[23]=a[14]-d;a[14]+=d;d=a[20]-a[8];a[8]+=a[20];a[20]=d*k[f+-180+7];d=a[21]-a[9];a[9]+=a[21];a[21]=d*k[f+-180+7];d=a[18]-a[10];a[10]+=a[18];a[18]=d*k[f+-216+7];d=a[19]-a[11];a[11]+=a[19];a[19]=d*k[f+-216+7];d=a[16]-a[12];a[12]+=a[16];a[16]=d*k[f+-252+7];d=a[17]-a[13];a[13]+=a[17];a[17]=d*k[f+-252+7];d=-a[20]+a[24];a[20]+=a[24];a[24]=d*k[f+-216+7];d=-a[21]+a[25];a[21]+=a[25];a[25]=d*k[f+-216+7];d=a[4]-a[8];a[4]+=a[8];a[8]=d*k[f+-216+7];d=a[5]-a[9];a[5]+=a[9];a[9]= -d*k[f+-216+7];d=a[0]-a[12];a[0]+=a[12];a[12]=d*k[f+-72+7];d=a[1]-a[13];a[1]+=a[13];a[13]=d*k[f+-72+7];d=a[16]-a[28];a[16]+=a[28];a[28]=d*k[f+-72+7];d=-a[17]+a[29];a[17]+=a[29];a[29]=d*k[f+-72+7];d=aa.SQRT2*(a[2]-a[10]);a[2]+=a[10];a[10]=d;d=aa.SQRT2*(a[3]-a[11]);a[3]+=a[11];a[11]=d;d=aa.SQRT2*(-a[18]+a[26]);a[18]+=a[26];a[26]=d-a[18];d=aa.SQRT2*(-a[19]+a[27]);a[19]+=a[27];a[27]=d-a[19];d=a[2];a[19]-=a[3];a[3]-=d;a[2]=a[31]-d;a[31]+=d;d=a[3];a[11]-=a[19];a[18]-=d;a[3]=a[30]-d;a[30]+=d;d=a[18];a[27]-= -a[11];a[19]-=d;a[18]=a[15]-d;a[15]+=d;d=a[19];a[10]-=d;a[19]=a[14]-d;a[14]+=d;d=a[10];a[11]-=d;a[10]=a[23]-d;a[23]+=d;d=a[11];a[26]-=d;a[11]=a[22]-d;a[22]+=d;d=a[26];a[27]-=d;a[26]=a[7]-d;a[7]+=d;d=a[27];a[27]=a[6]-d;a[6]+=d;d=aa.SQRT2*(a[0]-a[4]);a[0]+=a[4];a[4]=d;d=aa.SQRT2*(a[1]-a[5]);a[1]+=a[5];a[5]=d;d=aa.SQRT2*(a[16]-a[20]);a[16]+=a[20];a[20]=d;d=aa.SQRT2*(a[17]-a[21]);a[17]+=a[21];a[21]=d;d=-aa.SQRT2*(a[8]-a[12]);a[8]+=a[12];a[12]=d-a[8];d=-aa.SQRT2*(a[9]-a[13]);a[9]+=a[13];a[13]=d-a[9];d= --aa.SQRT2*(a[25]-a[29]);a[25]+=a[29];a[29]=d-a[25];d=-aa.SQRT2*(a[24]+a[28]);a[24]-=a[28];a[28]=d-a[24];d=a[24]-a[16];a[24]=d;d=a[20]-d;a[20]=d;d=a[28]-d;a[28]=d;d=a[25]-a[17];a[25]=d;d=a[21]-d;a[21]=d;d=a[29]-d;a[29]=d;d=a[17]-a[1];a[17]=d;d=a[9]-d;a[9]=d;d=a[25]-d;a[25]=d;d=a[5]-d;a[5]=d;d=a[21]-d;a[21]=d;d=a[13]-d;a[13]=d;d=a[29]-d;a[29]=d;d=a[1]-a[0];a[1]=d;d=a[16]-d;a[16]=d;d=a[17]-d;a[17]=d;d=a[8]-d;a[8]=d;d=a[9]-d;a[9]=d;d=a[24]-d;a[24]=d;d=a[25]-d;a[25]=d;d=a[4]-d;a[4]=d;d=a[5]-d;a[5]=d;d= -a[20]-d;a[20]=d;d=a[21]-d;a[21]=d;d=a[12]-d;a[12]=d;d=a[13]-d;a[13]=d;d=a[28]-d;a[28]=d;d=a[29]-d;a[29]=d;d=a[0];a[0]+=a[31];a[31]-=d;d=a[1];a[1]+=a[30];a[30]-=d;d=a[16];a[16]+=a[15];a[15]-=d;d=a[17];a[17]+=a[14];a[14]-=d;d=a[8];a[8]+=a[23];a[23]-=d;d=a[9];a[9]+=a[22];a[22]-=d;d=a[24];a[24]+=a[7];a[7]-=d;d=a[25];a[25]+=a[6];a[6]-=d;d=a[4];a[4]+=a[27];a[27]-=d;d=a[5];a[5]+=a[26];a[26]-=d;d=a[20];a[20]+=a[11];a[11]-=d;d=a[21];a[21]+=a[10];a[10]-=d;d=a[12];a[12]+=a[19];a[19]-=d;d=a[13];a[13]+=a[18]; -a[18]-=d;d=a[28];a[28]+=a[3];a[3]-=d;d=a[29];a[29]+=a[2];a[2]-=d}var k=[-.1482523854003001,32.308141959636465,296.40344946382766,883.1344870032432,11113.947376231741,1057.2713659324597,305.7402417275812,30.825928907280012,3.8533188138216365,59.42900443849514,709.5899960123345,5281.91112291017,-5829.66483675846,-817.6293103748613,-76.91656988279972,-4.594269939176596,.9063471690191471,.1960342806591213,-.15466694054279598,34.324387823855965,301.8067566458425,817.599602898885,11573.795901679885,1181.2520595540152, -321.59731579894424,31.232021761053772,3.7107095756221318,53.650946155329365,684.167428119626,5224.56624370173,-6366.391851890084,-908.9766368219582,-89.83068876699639,-5.411397422890401,.8206787908286602,.3901806440322567,-.16070888947830023,36.147034243915876,304.11815768187864,732.7429163887613,11989.60988270091,1300.012278487897,335.28490093152146,31.48816102859945,3.373875931311736,47.232241542899175,652.7371796173471,5132.414255594984,-6909.087078780055,-1001.9990371107289,-103.62185754286375, --6.104916304710272,.7416505462720353,.5805693545089249,-.16636367662261495,37.751650073343995,303.01103387567713,627.9747488785183,12358.763425278165,1412.2779918482834,346.7496836825721,31.598286663170416,3.1598635433980946,40.57878626349686,616.1671130880391,5007.833007176154,-7454.040671756168,-1095.7960341867115,-118.24411666465777,-6.818469345853504,.6681786379192989,.7653668647301797,-.1716176790982088,39.11551877123304,298.3413246578966,503.5259106886539,12679.589408408976,1516.5821921214542, -355.9850766329023,31.395241710249053,2.9164211881972335,33.79716964664243,574.8943997801362,4853.234992253242,-7997.57021486075,-1189.7624067269965,-133.6444792601766,-7.7202770609839915,.5993769336819237,.9427934736519954,-.17645823955292173,40.21879108166477,289.9982036694474,359.3226160751053,12950.259102786438,1612.1013903507662,362.85067106591504,31.045922092242872,2.822222032597987,26.988862316190684,529.8996541764288,4671.371946949588,-8535.899136645805,-1282.5898586244496,-149.58553632943463, --8.643494270763135,.5345111359507916,1.111140466039205,-.36174739330527045,41.04429910497807,277.5463268268618,195.6386023135583,13169.43812144731,1697.6433561479398,367.40983966190305,30.557037410382826,2.531473372857427,20.070154905927314,481.50208566532336,4464.970341588308,-9065.36882077239,-1373.62841526722,-166.1660487028118,-9.58289321133207,.4729647758913199,1.268786568327291,-.36970682634889585,41.393213350082036,261.2935935556502,12.935476055240873,13336.131683328815,1772.508612059496,369.76534388639965, -29.751323653701338,2.4023193045459172,13.304795348228817,430.5615775526625,4237.0568611071185,-9581.931701634761,-1461.6913552409758,-183.12733958476446,-10.718010163869403,.41421356237309503,1.414213562373095,-.37677560326535325,41.619486213528496,241.05423794991074,-187.94665032361226,13450.063605744153,1836.153896465782,369.4908799925761,29.001847876923147,2.0714759319987186,6.779591200894186,377.7767837205709,3990.386575512536,-10081.709459700915,-1545.947424837898,-200.3762958015653,-11.864482073055006, -.3578057213145241,1.546020906725474,-.3829366947518991,41.1516456456653,216.47684307105183,-406.1569483347166,13511.136535077321,1887.8076599260432,367.3025214564151,28.136213436723654,1.913880671464418,.3829366947518991,323.85365704338597,3728.1472257487526,-10561.233882199509,-1625.2025997821418,-217.62525175416,-13.015432208941645,.3033466836073424,1.66293922460509,-.5822628872992417,40.35639251440489,188.20071124269245,-640.2706748618148,13519.21490106562,1927.6022433578062,362.8197642637487, -26.968821921868447,1.7463817695935329,-5.62650678237171,269.3016715297017,3453.386536448852,-11016.145278780888,-1698.6569643425091,-234.7658734267683,-14.16351421663124,.2504869601913055,1.76384252869671,-.5887180101749253,39.23429103868072,155.76096234403798,-889.2492977967378,13475.470561874661,1955.0535223723712,356.4450994756727,25.894952980042156,1.5695032905781554,-11.181939564328772,214.80884394039484,3169.1640829158237,-11443.321309975563,-1765.1588461316153,-251.68908574481912,-15.49755935939164, -.198912367379658,1.847759065022573,-.7912582233652842,37.39369355329111,119.699486012458,-1151.0956593239027,13380.446257078214,1970.3952110853447,348.01959814116185,24.731487364283044,1.3850130831637748,-16.421408865300393,161.05030052864092,2878.3322807850063,-11838.991423510031,-1823.985884688674,-268.2854986386903,-16.81724543849939,.1483359875383474,1.913880671464418,-.7960642926861912,35.2322109610459,80.01928065061526,-1424.0212633405113,13235.794061869668,1973.804052543835,337.9908651258184, -23.289159354463873,1.3934255946442087,-21.099669467133474,108.48348407242611,2583.700758091299,-12199.726194855148,-1874.2780658979746,-284.2467154529415,-18.11369784385905,.09849140335716425,1.961570560806461,-.998795456205172,32.56307803611191,36.958364584370486,-1706.075448829146,13043.287458812016,1965.3831106103316,326.43182772364605,22.175018750622293,1.198638339011324,-25.371248002043963,57.53505923036915,2288.41886619975,-12522.674544337233,-1914.8400385312243,-299.26241273417224,-19.37805630698734, -.04912684976946725,1.990369453344394,.0178904535*aa.SQRT2/2.384E-6,.008938074*aa.SQRT2/2.384E-6,.0015673635*aa.SQRT2/2.384E-6,.001228571*aa.SQRT2/2.384E-6,4.856585E-4*aa.SQRT2/2.384E-6,1.09434E-4*aa.SQRT2/2.384E-6,5.0783E-5*aa.SQRT2/2.384E-6,6.914E-6*aa.SQRT2/2.384E-6,12804.797818791945,1945.5515939597317,313.4244966442953,20.801593959731544,1995.1556208053692,9.000838926174497,-29.20218120805369],n=[[2.382191739347913E-13,6.423305872147834E-13,9.400849094049688E-13,1.122435026096556E-12,1.183840321267481E-12, -1.122435026096556E-12,9.40084909404969E-13,6.423305872147839E-13,2.382191739347918E-13,5.456116108943412E-12,4.878985199565852E-12,4.240448995017367E-12,3.559909094758252E-12,2.858043359288075E-12,2.156177623817898E-12,1.475637723558783E-12,8.371015190102974E-13,2.599706096327376E-13,-5.456116108943412E-12,-4.878985199565852E-12,-4.240448995017367E-12,-3.559909094758252E-12,-2.858043359288076E-12,-2.156177623817898E-12,-1.475637723558783E-12,-8.371015190102975E-13,-2.599706096327376E-13,-2.382191739347923E-13, --6.423305872147843E-13,-9.400849094049696E-13,-1.122435026096556E-12,-1.183840321267481E-12,-1.122435026096556E-12,-9.400849094049694E-13,-6.42330587214784E-13,-2.382191739347918E-13],[2.382191739347913E-13,6.423305872147834E-13,9.400849094049688E-13,1.122435026096556E-12,1.183840321267481E-12,1.122435026096556E-12,9.400849094049688E-13,6.423305872147841E-13,2.382191739347918E-13,5.456116108943413E-12,4.878985199565852E-12,4.240448995017367E-12,3.559909094758253E-12,2.858043359288075E-12,2.156177623817898E-12, -1.475637723558782E-12,8.371015190102975E-13,2.599706096327376E-13,-5.461314069809755E-12,-4.921085770524055E-12,-4.343405037091838E-12,-3.732668368707687E-12,-3.093523840190885E-12,-2.430835727329465E-12,-1.734679010007751E-12,-9.74825365660928E-13,-2.797435120168326E-13,0,0,0,0,0,0,-2.283748241799531E-13,-4.037858874020686E-13,-2.146547464825323E-13],[.1316524975873958,.414213562373095,.7673269879789602,1.091308501069271,1.303225372841206,1.56968557711749,1.920982126971166,2.414213562373094,3.171594802363212, -4.510708503662055,7.595754112725146,22.90376554843115,.984807753012208,.6427876096865394,.3420201433256688,.9396926207859084,-.1736481776669303,-.7660444431189779,.8660254037844387,.5,-.5144957554275265,-.4717319685649723,-.3133774542039019,-.1819131996109812,-.09457419252642064,-.04096558288530405,-.01419856857247115,-.003699974673760037,.8574929257125442,.8817419973177052,.9496286491027329,.9833145924917901,.9955178160675857,.9991605581781475,.999899195244447,.9999931550702802],[0,0,0,0,0,0,2.283748241799531E-13, -4.037858874020686E-13,2.146547464825323E-13,5.461314069809755E-12,4.921085770524055E-12,4.343405037091838E-12,3.732668368707687E-12,3.093523840190885E-12,2.430835727329466E-12,1.734679010007751E-12,9.74825365660928E-13,2.797435120168326E-13,-5.456116108943413E-12,-4.878985199565852E-12,-4.240448995017367E-12,-3.559909094758253E-12,-2.858043359288075E-12,-2.156177623817898E-12,-1.475637723558782E-12,-8.371015190102975E-13,-2.599706096327376E-13,-2.382191739347913E-13,-6.423305872147834E-13,-9.400849094049688E-13, --1.122435026096556E-12,-1.183840321267481E-12,-1.122435026096556E-12,-9.400849094049688E-13,-6.423305872147841E-13,-2.382191739347918E-13]],w=n[c.SHORT_TYPE],E=n[c.SHORT_TYPE],B=n[c.SHORT_TYPE],G=n[c.SHORT_TYPE],f=[0,1,16,17,8,9,24,25,4,5,20,21,12,13,28,29,2,3,18,19,10,11,26,27,6,7,22,23,14,15,30,31];this.mdct_sub48=function(b,k,a){for(var m=286,v=0;vr;r++)for(u(k,m,D[p]),u(k, -m+32,D[p+1]),p+=2,m+=64,l=1;32>l;l+=2)D[p-1][l]*=-1;for(l=0;32>l;l++,q+=18){D=d.block_type;p=b.sb_sample[v][e];var t=b.sb_sample[v][1-e];0!=d.mixed_block_flag&&2>l&&(D=0);if(1E-12>b.amp_filter[l])na.fill(g,q+0,q+18,0);else{if(1>b.amp_filter[l])for(r=0;18>r;r++)t[r][f[l]]*=b.amp_filter[l];if(D==c.SHORT_TYPE){for(r=-3;0>r;r++){var J=n[c.SHORT_TYPE][r+3];g[q+3*r+9]=p[9+r][f[l]]*J-p[8-r][f[l]];g[q+3*r+18]=p[14-r][f[l]]*J+p[15+r][f[l]];g[q+3*r+10]=p[15+r][f[l]]*J-p[14-r][f[l]];g[q+3*r+19]=t[2-r][f[l]]* -J+t[3+r][f[l]];g[q+3*r+11]=t[3+r][f[l]]*J-t[2-r][f[l]];g[q+3*r+20]=t[8-r][f[l]]*J+t[9+r][f[l]]}r=g;p=q;for(J=0;3>J;J++){var h=r[p+6]*n[c.SHORT_TYPE][0]-r[p+15];t=r[p+0]*n[c.SHORT_TYPE][2]-r[p+9];var x=h+t;var y=h-t;h=r[p+15]*n[c.SHORT_TYPE][0]+r[p+6];t=r[p+9]*n[c.SHORT_TYPE][2]+r[p+0];var A=h+t;var N=-h+t;t=2.069978111953089E-11*(r[p+3]*n[c.SHORT_TYPE][1]-r[p+12]);h=2.069978111953089E-11*(r[p+12]*n[c.SHORT_TYPE][1]+r[p+3]);r[p+0]=1.90752519173728E-11*x+t;r[p+15]=1.90752519173728E-11*-A+h;y*=1.6519652744032674E-11; -A=9.537625958686404E-12*A+h;r[p+3]=y-A;r[p+6]=y+A;x=9.537625958686404E-12*x-t;N*=1.6519652744032674E-11;r[p+9]=x+N;r[p+12]=x-N;p++}}else{J=K(18);for(r=-9;0>r;r++)x=n[D][r+27]*t[r+9][f[l]]+n[D][r+36]*t[8-r][f[l]],y=n[D][r+9]*p[r+9][f[l]]-n[D][r+18]*p[8-r][f[l]],J[r+9]=x-y*w[3+r+9],J[r+18]=x*w[3+r+9]+y;r=g;p=q;x=J;var H=x[17]-x[9];var O=x[15]-x[11];var F=x[14]-x[12];N=x[0]+x[8];A=x[1]+x[7];h=x[2]+x[6];y=x[3]+x[5];r[p+17]=N+h-y-(A-x[4]);J=(N+h-y)*E[19]+(A-x[4]);t=(H-O-F)*E[18];r[p+5]=t+J;r[p+6]=t-J; -var C=(x[16]-x[10])*E[18];A=A*E[19]+x[4];t=H*E[12]+C+O*E[13]+F*E[14];J=-N*E[16]+A-h*E[17]+y*E[15];r[p+1]=t+J;r[p+2]=t-J;t=H*E[13]-C-O*E[14]+F*E[12];J=-N*E[17]+A-h*E[15]+y*E[16];r[p+9]=t+J;r[p+10]=t-J;t=H*E[14]-C+O*E[12]-F*E[13];J=N*E[15]-A+h*E[16]-y*E[17];r[p+13]=t+J;r[p+14]=t-J;H=x[8]-x[0];O=x[6]-x[2];F=x[5]-x[3];N=x[17]+x[9];A=x[16]+x[10];h=x[15]+x[11];y=x[14]+x[12];r[p+0]=N+h+y+(A+x[13]);t=(N+h+y)*E[19]-(A+x[13]);J=(H-O+F)*E[18];r[p+11]=t+J;r[p+12]=t-J;C=(x[7]-x[1])*E[18];A=x[13]-A*E[19];t=N*E[15]- -A+h*E[16]+y*E[17];J=H*E[14]+C+O*E[12]+F*E[13];r[p+3]=t+J;r[p+4]=t-J;t=-N*E[17]+A-h*E[15]-y*E[16];J=H*E[13]+C-O*E[14]-F*E[12];r[p+7]=t+J;r[p+8]=t-J;t=-N*E[16]+A-h*E[17]-y*E[15];J=H*E[12]-C+O*E[13]-F*E[14];r[p+15]=t+J;r[p+16]=t-J}}if(D!=c.SHORT_TYPE&&0!=l)for(r=7;0<=r;--r)D=g[q+r]*B[20+r]+g[q+-1-r]*G[28+r],p=g[q+r]*G[28+r]-g[q+-1-r]*B[20+r],g[q+-1-r]=D,g[q+r]=p}}k=a;m=286;if(1==b.mode_gr)for(e=0;18>e;e++)T.arraycopy(b.sb_sample[v][1][e],0,b.sb_sample[v][0][e],0,32)}}}function Xa(){this.thm=new Xb;this.en= -new Xb}function c(){var u=c.FFTOFFSET,k=c.MPG_MD_MS_LR,n=null,w=this.psy=null,E=null,B=null;this.setModules=function(c,b,k,a){n=c;w=this.psy=b;E=a;B=k};var ha=new Fc;this.lame_encode_mp3_frame=function(f,b,v,a,m,z){var e=Ob([2,2]);e[0][0]=new Xa;e[0][1]=new Xa;e[1][0]=new Xa;e[1][1]=new Xa;var l=Ob([2,2]);l[0][0]=new Xa;l[0][1]=new Xa;l[1][0]=new Xa;l[1][1]=new Xa;var d=[null,null],g=f.internal_flags,q=ca([2,4]),D=[.5,.5],p=[[0,0],[0,0]],r=[[0,0],[0,0]];d[0]=b;d[1]=v;if(0==g.lame_encode_frame_init){b= -f.internal_flags;var t,J;if(0==b.lame_encode_frame_init){v=K(2014);var h=K(2014);b.lame_encode_frame_init=1;for(J=t=0;t<286+576*(1+b.mode_gr);++t)t<576*b.mode_gr?(v[t]=0,2==b.channels_out&&(h[t]=0)):(v[t]=d[0][J],2==b.channels_out&&(h[t]=d[1][J]),++J);for(J=0;J(g.slot_lag-=g.frac_SpF)&&(g.slot_lag+=f.out_samplerate,g.padding=1);if(0!=g.psymodel)for(h=[null,null],t=0,J=X(2),v= -0;v=q?(g.ATH.adjust*=.075*q+.925,g.ATH.adjust= -q?g.ATH.adjust=q:g.ATH.adjustl;l++)g.nsPsy.pefirbuf[l]=g.nsPsy.pefirbuf[l+ -1];for(v=r=0;vl;l++)r+=(g.nsPsy.pefirbuf[l]+g.nsPsy.pefirbuf[18-l])*c.fircoef[l];r=3350*g.mode_gr*g.channels_out/r;for(v=0;vm;m++)g.pinfo.pcmdata[b][m]=d[b][m-u]}B.set_frame_pinfo(f,e)}g.bitrate_stereoMode_Hist[g.bitrate_index][4]++;g.bitrate_stereoMode_Hist[15][4]++;2==g.channels_out&&(g.bitrate_stereoMode_Hist[g.bitrate_index][g.mode_ext]++,g.bitrate_stereoMode_Hist[15][g.mode_ext]++);for(f=0;fc;c++)for(var k=0;2>k;k++)this.tt[c][k]=new rb}function Ic(){this.last_en_subshort=ca([4,9]);this.lastAttacks=X(4);this.pefirbuf= -K(19);this.longfact=K(c.SBMAX_l);this.shortfact=K(c.SBMAX_s);this.attackthre_s=this.attackthre=0}function Xb(){this.l=K(c.SBMAX_l);this.s=ca([c.SBMAX_s,3]);var u=this;this.assign=function(k){T.arraycopy(k.l,0,u.l,0,c.SBMAX_l);for(var n=0;nw;w++)u.s[n][w]=k.s[n][w]}}function da(){function u(){this.ptr=this.write_timing=0;this.buf=new Int8Array(40)}this.fill_buffer_resample_init=this.iteration_init_init=this.lame_encode_frame_init=this.Class_ID=0;this.mfbuf=ca([2,da.MFSIZE]); -this.full_outer_loop=this.use_best_huffman=this.subblock_gain=this.noise_shaping_stop=this.psymodel=this.substep_shaping=this.noise_shaping_amp=this.noise_shaping=this.highpass2=this.highpass1=this.lowpass2=this.lowpass1=this.mode_ext=this.samplerate_index=this.bitrate_index=this.VBR_max_bitrate=this.VBR_min_bitrate=this.mf_size=this.mf_samples_to_encode=this.resample_ratio=this.channels_out=this.channels_in=this.mode_gr=0;this.l3_side=new Hc;this.ms_ratio=K(2);this.slot_lag=this.frac_SpF=this.padding= -0;this.tag_spec=null;this.nMusicCRC=0;this.OldValue=X(2);this.CurrentStep=X(2);this.masking_lower=0;this.bv_scf=X(576);this.pseudohalf=X(sa.SFBMAX);this.sfb21_extra=!1;this.inbuf_old=Array(2);this.blackfilt=Array(2*da.BPC+1);this.itime=new Float64Array(2);this.sideinfo_len=0;this.sb_sample=ca([2,2,18,c.SBLIMIT]);this.amp_filter=K(32);this.header=Array(da.MAX_HEADER_BUF);this.ResvMax=this.ResvSize=this.ancillary_flag=this.w_ptr=this.h_ptr=0;this.scalefac_band=new za;this.minval_l=K(c.CBANDS);this.minval_s= -K(c.CBANDS);this.nb_1=ca([4,c.CBANDS]);this.nb_2=ca([4,c.CBANDS]);this.nb_s1=ca([4,c.CBANDS]);this.nb_s2=ca([4,c.CBANDS]);this.s3_ll=this.s3_ss=null;this.decay=0;this.thm=Array(4);this.en=Array(4);this.tot_ener=K(4);this.loudness_sq=ca([2,2]);this.loudness_sq_save=K(2);this.mld_l=K(c.SBMAX_l);this.mld_s=K(c.SBMAX_s);this.bm_l=X(c.SBMAX_l);this.bo_l=X(c.SBMAX_l);this.bm_s=X(c.SBMAX_s);this.bo_s=X(c.SBMAX_s);this.npart_s=this.npart_l=0;this.s3ind=Ia([c.CBANDS,2]);this.s3ind_s=Ia([c.CBANDS,2]);this.numlines_s= -X(c.CBANDS);this.numlines_l=X(c.CBANDS);this.rnumlines_l=K(c.CBANDS);this.mld_cb_l=K(c.CBANDS);this.mld_cb_s=K(c.CBANDS);this.numlines_l_num1=this.numlines_s_num1=0;this.pe=K(4);this.ms_ener_ratio_old=this.ms_ratio_l_old=this.ms_ratio_s_old=0;this.blocktype_old=X(2);this.nsPsy=new Ic;this.VBR_seek_table=new Gc;this.PSY=this.ATH=null;this.nogap_current=this.nogap_total=0;this.findPeakSample=this.findReplayGain=this.decode_on_the_fly=!0;this.AudiophileGain=this.RadioGain=this.PeakSample=0;this.rgdata= -null;this.noclipScale=this.noclipGainChange=0;this.bitrate_stereoMode_Hist=Ia([16,5]);this.bitrate_blockType_Hist=Ia([16,6]);this.hip=this.pinfo=null;this.in_buffer_nsamples=0;this.iteration_loop=this.in_buffer_1=this.in_buffer_0=null;for(var k=0;k>1;var e=a;var l=a<<1;var d=l+e; -a=l<<1;var g=k;var q=g+u;do{var B=c[g+0]-c[g+e];var p=c[g+0]+c[g+e];var r=c[g+l]-c[g+d];var t=c[g+l]+c[g+d];c[g+l]=p-t;c[g+0]=p+t;c[g+d]=B-r;c[g+e]=B+r;B=c[q+0]-c[q+e];p=c[q+0]+c[q+e];r=aa.SQRT2*c[q+d];t=aa.SQRT2*c[q+l];c[q+l]=p-t;c[q+0]=p+t;c[q+d]=B-r;c[q+e]=B+r;q+=a;g+=a}while(gk;k++){var a=c.BLKSIZE_s/2,m=65535&192*(k+1),B= -c.BLKSIZE_s/8-1;do{var e=E[B<<2]&255;var l=n[e]*b[f][v+e+m];var d=n[127-e]*b[f][v+e+m+128];var g=l-d;l+=d;var q=n[e+64]*b[f][v+e+m+64];d=n[63-e]*b[f][v+e+m+192];var D=q-d;q+=d;a-=4;w[k][a+0]=l+q;w[k][a+2]=l-q;w[k][a+1]=g+D;w[k][a+3]=g-D;l=n[e+1]*b[f][v+e+m+1];d=n[126-e]*b[f][v+e+m+129];g=l-d;l+=d;q=n[e+65]*b[f][v+e+m+65];d=n[62-e]*b[f][v+e+m+193];D=q-d;q+=d;w[k][a+c.BLKSIZE_s/2+0]=l+q;w[k][a+c.BLKSIZE_s/2+2]=l-q;w[k][a+c.BLKSIZE_s/2+1]=g+D;w[k][a+c.BLKSIZE_s/2+3]=g-D}while(0<=--B);u(w[k],a,c.BLKSIZE_s/ -2)}};this.fft_long=function(n,w,f,b,v){n=c.BLKSIZE/8-1;var a=c.BLKSIZE/2;do{var m=E[n]&255;var B=k[m]*b[f][v+m];var e=k[m+512]*b[f][v+m+512];var l=B-e;B+=e;var d=k[m+256]*b[f][v+m+256];e=k[m+768]*b[f][v+m+768];var g=d-e;d+=e;a-=4;w[a+0]=B+d;w[a+2]=B-d;w[a+1]=l+g;w[a+3]=l-g;B=k[m+1]*b[f][v+m+1];e=k[m+513]*b[f][v+m+513];l=B-e;B+=e;d=k[m+257]*b[f][v+m+257];e=k[m+769]*b[f][v+m+769];g=d-e;d+=e;w[a+c.BLKSIZE/2+0]=B+d;w[a+c.BLKSIZE/2+2]=B-d;w[a+c.BLKSIZE/2+1]=l+g;w[a+c.BLKSIZE/2+3]=l-g}while(0<=--n);u(w, -a,c.BLKSIZE/2)};this.init_fft=function(u){for(u=0;ua)if(c=c*r)return a+c;g=a/c}a+=c;if(6>=b+3){if(g>=p)return a;b=0|aa.FAST_LOG10_X(g,16);return a* -x[b]}b=0|aa.FAST_LOG10_X(g,16);c=0!=e?f.ATH.cb_s[d]*f.ATH.adjust:f.ATH.cb_l[d]*f.ATH.adjust;return ac?(d=1,13>=b&&(d=y[b]),c=aa.FAST_LOG10_X(a/c,10/15),a*((h[b]-d)*c+d)):13a&&(a=0);0>c&&(c=0);if(0>=a)return c;if(0>=c)return a;var b=c>a?c/a:a/c;if(-2<=d&&2>=d){if(b>=p)return a+c;d=0|aa.FAST_LOG10_X(b,16);return(a+c)*A[d]}if(b=y){++e;break}k=a.PSY.bo_s_weight[e];y=1-k;l=k*d[g];k*=b[g];a.en[h].s[e][f]+=l;a.thm[h].s[e][f]+=k;l=y*d[g];k=y*b[g]}for(;e=m){++f;break}l=a.PSY.bo_l_weight[f];m=1-l;g=l*d[e];l*=b[e];a.en[h].l[f]+=g; -a.thm[h].l[f]+=l;g=m*d[e];l=m*b[e]}for(;f=d?c:0f;f++){var e=a.thm.s[h][f];if(0e&&(b=g>1E10*e?b+23.02585092994046*N[h]:b+N[h]*aa.FAST_LOG10(g/e))}}return b}function f(a,d){for(var b=281.0575,h=0;hf&&(b=e>1E10*f?b+23.02585092994046*H[h]: -b+H[h]*aa.FAST_LOG10(e/f))}}return b}function b(a,c,b,d,h){var f,e;for(f=e=0;fh&&(e=h);d[f]=e}else d[f]=0;for(f=1;fh&&(e=h),d[f]=e):d[f]=0;e=b[f-1]+b[f];0h&&(e=h),d[f]=e):d[f]=0}function a(a,c,b,d,f,h,e){var g=2*h;f=0y&&(k=y);l>p&&(l=p);c[2][m]=k;c[3][m]=l}}function m(a,c){a=0<=a?27*-a:a*c;return-72>=a?0:Math.exp(.2302585093*a)}function z(a){0>a&&(a=0);a*=.001;return 13*Math.atan(.76*a)+3.5*Math.atan(a*a/56.25)}function e(a,b,d,f,h,e,g,l,k,m,y,p){var q=K(c.CBANDS+1),n=l/(15z(l*t)- -A&&t<=k/2;t++);a[r]=t-u;for(C=r+1;uk/2){u=k/2;++r;break}}q[r]=l*u;for(u=0;ur&&(r=0),t=0|Math.floor(.5+y*(A-.5)),t>k/2&&(t=k/2),d[u]=(x[r]+x[t])/2,b[u]=x[t],g[u]=(n*A-q[b[u]])/(q[b[u]+1]-q[b[u]]),0>g[u]?g[u]=0:1=y){var p=y-.5;p=8*(p*p-2*p)}else p=0;y+=.474;y=15.811389+7.5*y-17.5*Math.sqrt(1+y*y);-60>=y?p=0:(y=Math.exp(.2302585093*(p+y)),p=y/.6609193);y=p*f[e];g[k][e]=y*h[k]}else for(e=0;e=n;++n)q=y+n*(x-y)/1E3,q=m(q,k),r+=q;q=1001/(r*(x-y));for(k=0;k -a&&(a=3410);a=Math.max(.1,a/1E3);return 3.64*Math.pow(a,-.8)-6.8*Math.exp(-.6*Math.pow(a-3.4,2))+6*Math.exp(-.15*Math.pow(a-8.7,2))+.001*(.6+.04*c)*Math.pow(a,4)}var q=new Jc,D=1/217621504/(c.BLKSIZE/2),p,r,t,J=[1,.79433,.63096,.63096,.63096,.63096,.63096,.25119,.11749],h=[3.3246*3.3246,3.23837*3.23837,9.9500500969,9.0247369744,8.1854926609,7.0440875649,2.46209*2.46209,2.284*2.284,4.4892710641,1.96552*1.96552,1.82335*1.82335,1.69146*1.69146,2.4621061921,2.1508568964,1.37074*1.37074,1.31036*1.31036, -1.5691069696,1.4555939904,1.16203*1.16203,1.2715945225,1.09428*1.09428,1.0659*1.0659,1.0779838276,1.0382591025,1],x=[1.7782755904,1.35879*1.35879,1.38454*1.38454,1.39497*1.39497,1.40548*1.40548,1.3537*1.3537,1.6999465924,1.22321*1.22321,1.3169398564,1],y=[5.5396212496,2.29259*2.29259,4.9868695969,2.12675*2.12675,2.02545*2.02545,1.87894*1.87894,1.74303*1.74303,1.61695*1.61695,2.2499700001,1.39148*1.39148,1.29083*1.29083,1.19746*1.19746,1.2339655056,1.0779838276],A=[1.7782755904,1.35879*1.35879,1.38454* -1.38454,1.39497*1.39497,1.40548*1.40548,1.3537*1.3537,1.6999465924,1.22321*1.22321,1.3169398564,1],N=[11.8,13.6,17.2,32,46.5,51.3,57.5,67.1,71.5,84.6,97.6,130],H=[6.8,5.8,5.8,6.4,6.5,9.9,12.1,14.4,15,18.9,21.6,26.9,34.2,40.2,46.8,56.5,60.7,73.9,85.7,93.4,126.1],O=[-1.730326E-17,-.01703172,-1.349528E-17,.0418072,-6.73278E-17,-.0876324,-3.0835E-17,.1863476,-1.104424E-16,-.627638];this.L3psycho_anal_ns=function(a,d,h,e,g,l,m,y,p,n){var x=a.internal_flags,r=ca([2,c.BLKSIZE]),t=ca([2,3,c.BLKSIZE_s]),A= -K(c.CBANDS+1),I=K(c.CBANDS+1),C=K(c.CBANDS+2),Q=X(2),S=X(2),z,D,F,H,N,Z,L,V=ca([2,576]),ma=X(c.CBANDS+2),R=X(c.CBANDS+2);na.fill(R,0);var T=x.channels_out;a.mode==la.JOINT_STEREO&&(T=4);var M=a.VBR==G.vbr_off?0==x.ResvMax?0:x.ResvSize/x.ResvMax*.5:a.VBR==G.vbr_rh||a.VBR==G.vbr_mtrh||a.VBR==G.vbr_mt?.6:1;for(z=0;zF;F++){var U;var da=Y[ha+F+10];for(H=U=0;9>H;H+=2)da+=O[H]*(Y[ha+F+H]+Y[ha+F+21-H]),U+=O[H+1]*(Y[ha+F+H+1]+Y[ha+F+21-H-1]); -V[z][F]=da+U}g[e][z].en.assign(x.en[z]);g[e][z].thm.assign(x.thm[z]);2F;F++)Qa[F]=x.nsPsy.last_en_subshort[z][F+6],qa[F]=Qa[F]/x.nsPsy.last_en_subshort[z][F+4],ya[0]+=Qa[F];if(2==z)for(F=0;576>F;F++){var Ya=V[0][F];var Xa=V[1][F];V[0][F]=Ya+Xa;V[1][F]=Ya-Xa}var Ia=V[z&1],ec=0;for(F=0;9> -F;F++){for(var xa=ec+64,Ga=1;ecQa[F+3-2]?Ga/Qa[F+3-2]:Qa[F+3-2]>10*Ga?Qa[F+3-2]/(10*Ga):0;qa[F+3]=Ga}if(a.analysis){var Qb=qa[0];for(F=1;12>F;F++)QbF;F++)0==ta[F/3]&&qa[F]>Ma&&(ta[F/3]=F%3+1);for(F=1;4>F;F++)1.7>(ya[F-1]>ya[F]?ya[F-1]/ya[F]:ya[F]/ -ya[F-1])&&(ta[F]=0,1==F&&(ta[0]=0));0!=ta[0]&&0!=x.nsPsy.lastAttacks[z]&&(ta[0]=0);if(3==x.nsPsy.lastAttacks[z]||0!=ta[0]+ta[1]+ta[2]+ta[3])ia=0,0!=ta[1]&&0!=ta[0]&&(ta[1]=0),0!=ta[2]&&0!=ta[1]&&(ta[2]=0),0!=ta[3]&&0!=ta[2]&&(ta[3]=0);2>z?S[z]=ia:0==ia&&(S[0]=S[1]=0);p[z]=x.tot_ener[z];var P=a,Ha=za,Gb=Wb,La=r,kb=z&1,Ra=t,Na=z&1,cb=e,Aa=z,va=d,qb=h,Va=P.internal_flags;if(2>Aa)q.fft_long(Va,La[kb],Aa,va,qb),q.fft_short(Va,Ra[Na],Aa,va,qb);else if(2==Aa){for(var ja=c.BLKSIZE-1;0<=ja;--ja){var Hb=La[kb+ -0][ja],Ib=La[kb+1][ja];La[kb+0][ja]=(Hb+Ib)*aa.SQRT2*.5;La[kb+1][ja]=(Hb-Ib)*aa.SQRT2*.5}for(var Ba=2;0<=Ba;--Ba)for(ja=c.BLKSIZE_s-1;0<=ja;--ja)Hb=Ra[Na+0][Ba][ja],Ib=Ra[Na+1][Ba][ja],Ra[Na+0][Ba][ja]=(Hb+Ib)*aa.SQRT2*.5,Ra[Na+1][Ba][ja]=(Hb-Ib)*aa.SQRT2*.5}Ha[0]=La[kb+0][0];Ha[0]*=Ha[0];for(ja=c.BLKSIZE/2-1;0<=ja;--ja){var fc=La[kb+0][c.BLKSIZE/2-ja],tb=La[kb+0][c.BLKSIZE/2+ja];Ha[c.BLKSIZE/2-ja]=.5*(fc*fc+tb*tb)}for(Ba=2;0<=Ba;--Ba)for(Gb[Ba][0]=Ra[Na+0][Ba][0],Gb[Ba][0]*=Gb[Ba][0],ja=c.BLKSIZE_s/ -2-1;0<=ja;--ja)fc=Ra[Na+0][Ba][c.BLKSIZE_s/2-ja],tb=Ra[Na+0][Ba][c.BLKSIZE_s/2+ja],Gb[Ba][c.BLKSIZE_s/2-ja]=.5*(fc*fc+tb*tb);var oa=0;for(ja=11;jaAa&&(Va.loudness_sq[cb][Aa]=Va.loudness_sq_save[Aa],Va.loudness_sq_save[Aa]=u(Ha,Va));b(x,za,A,sa,Fa);v(x,sa,Fa,ma);for(L= -0;3>L;L++){var ea=void 0,Ab=void 0,Bb=Wb,Sa=I,Za=C,ub=z,zb=L,Ja=a.internal_flags;for(ea=Ab=0;eafb;fb++)Sb=fa.thm[0].s[Ca][fb],Eb=fa.thm[1].s[Ca][fb],fa.thm[0].s[Ca][fb]+=Eb*xb,fa.thm[1].s[Ca][fb]+=Sb*xb}}if(a.mode==la.JOINT_STEREO){for(var Oa,ka=0;ka1.58*x.thm[1].l[ka]||x.thm[1].l[ka]>1.58* -x.thm[0].l[ka])){var Ua=x.mld_l[ka]*x.en[3].l[ka],gb=Math.max(x.thm[2].l[ka],Math.min(x.thm[3].l[ka],Ua));Ua=x.mld_l[ka]*x.en[2].l[ka];var gc=Math.max(x.thm[3].l[ka],Math.min(x.thm[2].l[ka],Ua));x.thm[2].l[ka]=gb;x.thm[3].l[ka]=gc}for(ka=0;kaua;ua++)x.thm[0].s[ka][ua]>1.58*x.thm[1].s[ka][ua]||x.thm[1].s[ka][ua]>1.58*x.thm[0].s[ka][ua]||(Ua=x.mld_s[ka]*x.en[3].s[ka][ua],gb=Math.max(x.thm[2].s[ka][ua],Math.min(x.thm[3].s[ka][ua],Ua)),Ua=x.mld_s[ka]*x.en[2].s[ka][ua],gc= -Math.max(x.thm[3].s[ka][ua],Math.min(x.thm[2].s[ka][ua],Ua)),x.thm[2].s[ka][ua]=gb,x.thm[3].s[ka][ua]=gc);Oa=a.msfix;if(0Da;Da++)ba=x.ATH.cb_s[x.bm_s[wa]]*Zb,Wa=Math.min(Math.max(x.thm[0].s[wa][Da],ba),Math.max(x.thm[1].s[wa][Da],ba)),ab=Math.max(x.thm[2].s[wa][Da],ba),mb=Math.max(x.thm[3].s[wa][Da],ba),Wa*KbM;M++){var Y;var ha=firbuf[T+M+10];for(var U=Y=0;9>U;U+=2)ha+=F[U]*(firbuf[T+M+U]+firbuf[T+M+21-U]),Y+=F[U+1]*(firbuf[T+M+U+1]+firbuf[T+M+21-U-1]);Z[R][M]=ha+Y}l[g][R].en.assign(G.en[R]); -l[g][R].thm.assign(G.thm[R]);2M;M++)ya[M]=G.nsPsy.last_en_subshort[R][M+6],da[M]=ya[M]/G.nsPsy.last_en_subshort[R][M+4],qa[0]+=ya[M];for(M=0;9>M;M++){for(var Xa=sa+64,Ya=1;saya[M+3-2]?Ya/ya[M+3-2]:ya[M+3-2]>10*Ya?ya[M+3-2]/(10*Ya):0;da[M+3]=Ya}for(M=0;3>M;++M){var Ia=ya[3*M+3]+ya[3*M+4]+ya[3*M+5],Wb=1;6*ya[3*M+5]M;M++)xaM;M++)0==L[R][M/3]&&da[M]>Fa&&(L[R][M/3]=M%3+1);for(M=1;4>M;M++){var Qb=qa[M-1],Ga=qa[M];4E4>Math.max(Qb,Ga)&&Qb< -1.7*Ga&&Ga<1.7*Qb&&(1==M&&L[R][0]<=L[R][M]&&(L[R][0]=0),L[R][M]=0)}L[R][0]<=G.nsPsy.lastAttacks[R]&&(L[R][0]=0);if(3==G.nsPsy.lastAttacks[R]||0!=L[R][0]+L[R][1]+L[R][2]+L[R][3])na=0,0!=L[R][1]&&0!=L[R][0]&&(L[R][1]=0),0!=L[R][2]&&0!=L[R][1]&&(L[R][2]=0),0!=L[R][3]&&0!=L[R][2]&&(L[R][3]=0);2>R?H[R]=na:0==na&&(H[0]=H[1]=0);y[R]=G.tot_ener[R]}var qb=d.internal_flags;d.short_blocks!=ra.short_block_coupled||0!=H[0]&&0!=H[1]||(H[0]=H[1]=0);for(var Ma=0;MaLa)q.fft_long(Aa,Na[cb],La,h,e);else if(2==La)for(var va=c.BLKSIZE-1;0<=va;--va){var rb=Na[cb+0][va],Va=Na[cb+1][va];Na[cb+0][va]=(rb+Va)*aa.SQRT2*.5;Na[cb+1][va]=(rb-Va)*aa.SQRT2*.5}Ra[0]=Na[cb+0][0];Ra[0]*=Ra[0];for(va=c.BLKSIZE/2-1;0<=va;--va){var ja=Na[cb+0][c.BLKSIZE/2-va],Hb=Na[cb+0][c.BLKSIZE/2+va];Ra[c.BLKSIZE/2-va]=.5*(ja*ja+Hb*Hb)}var Ib= -0;for(va=11;vaBa&&(tb.loudness_sq[g][Ba]=tb.loudness_sq_save[Ba],tb.loudness_sq_save[Ba]=u(zb,tb));if(0!=H[Ha]){var oa=void 0,ea=r,Ab=I,Bb=S[P],Sa=D[P],Za=P,ub=K(c.CBANDS),sb=K(c.CBANDS),Ja=X(c.CBANDS+2);b(ea,Ab,Bb,ub,sb);v(ea,ub, -sb,Ja);var Rb=0;for(oa=0;oa=Yb&&(Yb=$a);0>=eb&&(eb=$a); -wb=ea.blocktype_old[Za&1]==c.NORM_TYPE?Math.min(eb,Yb):eb;Sa[oa]=Math.min($a,wb)}ea.nb_2[Za][oa]=ea.nb_1[Za][oa];ea.nb_1[Za][oa]=$a;vb=ub[oa];vb*=ea.minval_l[oa];vb*=Ta;Sa[oa]>vb&&(Sa[oa]=vb);1Bb[oa]&&(Sa[oa]=Bb[oa]);1>ea.masking_lower&&(Sa[oa]*=ea.masking_lower)}for(;oafa;fa++){for(P=0;Pfb&&q.fft_short(gc,Ua[gb],fb,h,e);if(2==fb)for(var ua=c.BLKSIZE_s-1;0<=ua;--ua){var Kb=Ua[gb+0][Oa][ua],hc=Ua[gb+1][Oa][ua];Ua[gb+0][Oa][ua]=(Kb+hc)*aa.SQRT2*.5; -Ua[gb+1][Oa][ua]=(Kb-hc)*aa.SQRT2*.5}ka[Oa][0]=Ua[gb+0][Oa][0];ka[Oa][0]*=ka[Oa][0];for(ua=c.BLKSIZE_s/2-1;0<=ua;--ua){var Zb=Ua[gb+0][Oa][c.BLKSIZE_s/2-ua],wa=Ua[gb+0][Oa][c.BLKSIZE_s/2+ua];ka[Oa][c.BLKSIZE_s/2-ua]=.5*(Zb*Zb+wa*wa)}var ba=void 0,Wa=void 0,ab=void 0,mb=C,hb=S[P],Da=D[P],ib=P,Ka=fa,Ea=d.internal_flags,Lb=new float[c.CBANDS],Tb=K(c.CBANDS),Fb=new int[c.CBANDS];for(ba=Wa=0;baac&&(ob=ac);$b[pa]=ob}else $b[pa]=0;for(pa=1;paac&&(ob=ac),$b[pa]=ob):$b[pa]=0;Pa=Ub[pa-1]+Ub[pa];0ac&&(ob=ac),$b[pa]=ob):$b[pa]=0;for(Wa=ba=0;babc&&(Da[ba]=bc);1hb[ba]&&(Da[ba]=hb[ba]);1>Ea.masking_lower&&(Da[ba]*=Ea.masking_lower)}for(;bafa;fa++){var jb=r.thm[P].s[Vb][fa];jb*=.8;if(2<=L[P][fa]||1==L[P][fa+1]){var jc=0!=fa?fa-1:2,kc=B(r.thm[P].s[Vb][jc],jb,.36);jb=Math.min(jb,kc)}else if(1==L[P][fa])jc=0!=fa?fa-1:2,kc=B(r.thm[P].s[Vb][jc],jb,.18),jb=Math.min(jb,kc);else if(0!=fa&&3==L[P][fa-1]||0==fa&&3==r.nsPsy.lastAttacks[P])jc=2!=fa?fa+1:0,kc=B(r.thm[P].s[Vb][jc],jb,.18),jb=Math.min(jb,kc);jb*=O[P][fa];vc[fa]=jb}for(fa=0;3>fa;fa++)r.thm[P].s[Vb][fa]=vc[fa]}for(P=0;Pf;++f){for(var v=0;vv;++v){for(z=0;zv;v++)b.nsPsy.last_en_subshort[f][v]=10}b.loudness_sq_save[0]=b.loudness_sq_save[1]=0;b.npart_l=e(b.numlines_l,b.bo_l,b.bm_l,n,u,b.mld_l,b.PSY.bo_l_weight,w,c.BLKSIZE,b.scalefac_band.l, -c.BLKSIZE/1152,c.SBMAX_l);for(f=0;f=g&&(z=m*(n[f]-g)/(24-g)+k*(24-n[f])/(24-g)),A[f]=Math.pow(10,z/10),b.rnumlines_l[f]=0k&&(m=k);b.ATH.cb_l[f]=m;m=-20+20*n[f]/10;6m&&(m=-15);m-=8;b.minval_l[f]=Math.pow(10,m/10)*b.numlines_l[f]}b.npart_s= -e(b.numlines_s,b.bo_s,b.bm_s,n,u,b.mld_s,b.PSY.bo_s_weight,w,c.BLKSIZE_s,b.scalefac_band.s,c.BLKSIZE_s/384,c.SBMAX_s);for(f=v=0;f=g&&(z=y*(n[f]-g)/(24-g)+x*(24-n[f])/(24-g));A[f]=Math.pow(10,z/10);m=Ma.MAX_VALUE;for(z=0;zk&&(m=k);b.ATH.cb_s[f]=m;m=-7+7*n[f]/12;12n[f]&&(m*=1+2.3*Math.log(1-m));-15>m&&(m=-15);m-=8;b.minval_s[f]= -Math.pow(10,m/10)*b.numlines_s[f]}b.s3_ss=l(b.s3ind_s,b.npart_s,n,u,A,h);p=Math.pow(10,.5625);r=Math.pow(10,1.5);t=Math.pow(10,1.5);q.init_fft(b);b.decay=Math.exp(-2.302585092994046/(.01*w/192));f=3.5;0!=(a.exp_nspsytune&2)&&(f=1);0b.npart_l-1&&(b.s3ind[h][1]=b.npart_l-1);b.ATH.decay=Math.pow(10,576*b.mode_gr/w*-1.2);b.ATH.adjust=.01;b.ATH.adjustLimit=1;if(-1!=a.ATHtype){v=a.out_samplerate/c.BLKSIZE;for(f=k=h=0;f=a?1:Math.cos(Math.PI/2*a)}function E(a,b){switch(a){case 44100:return b.version= -1,0;case 48E3:return b.version=1;case 32E3:return b.version=1,2;case 22050:return b.version=0;case 24E3:return b.version=0,1;case 16E3:return b.version=0,2;case 11025:return b.version=0;case 12E3:return b.version=0,1;case 8E3:return b.version=0,2;default:return b.version=0,-1}}function B(a,b,d){16E3>d&&(b=2);d=w.bitrate_table[b][1];for(var c=2;14>=c;c++)0d&&(b=2);for(d= -0;14>=d;d++)if(0t)return t;n+=t;x+=t;u[0]=g;u[1]=k;if(qa.NEQ(f.scale,0)&&qa.NEQ(f.scale,1))for(t=0;tH.resample_ratio||1.0001da.BPC&&(sa= -da.BPC);var ra=1E-4>Math.abs(ca.resample_ratio-Math.floor(.5+ca.resample_ratio))?1:0;var R=1/ca.resample_ratio;1xa&&(xa=0);1Math.abs(Ma)?Qa/Math.PI:xa*Math.sin(na*Qa*Ma)/(Math.PI*na*Ma)}for(N=0;N<=na;N++)ca.blackfilt[ia][N]/=M}ca.fill_buffer_resample_init=1}M=ca.inbuf_old[la];for(R=0;R=aa)break;za=N-ca.itime[la]-(ia+na%2*.5);za=0|Math.floor(2*za*sa+sa+.5);for(N=Fa=0;N<=na;++N)Ia=0|N+ia-na/2,Fa+=(0>Ia?M[ra+Ia]:W[X+Ia])*ca.blackfilt[za][N];V[T+R]=Fa}ha.num_used=Math.min(aa,na+ia-na/2);ca.itime[la]+=ha.num_used- -R*ca.resample_ratio;if(ha.num_used>=ra)for(N=0;Nh.mf_samples_to_encode&&(h.mf_samples_to_encode=c.ENCDELAY+c.POSTDELAY);h.mf_samples_to_encode+=t;if(h.mf_size>=g){w=r-x;0==r&&(w=0);t=f;w=e.enc.lame_encode_mp3_frame(t,y[0],y[1],q,n,w);t.frameNum++;t=w;if(0>t)return t;n+=t;x+=t;h.mf_size-=f.framesize;h.mf_samples_to_encode-=f.framesize;for(w=0;wh;h++)if(Math.max(a,b[h+1])!=a){d=b[h+1];c=h+1;f=b[h];e=h;break}return d-a>a-f?e:c};this.lame_init_params=function(a){var b=a.internal_flags;b.Class_ID=0;null==b.ATH&&(b.ATH=new Cc);null==b.PSY&&(b.PSY=new u);null==b.rgdata&&(b.rgdata=new Ac);b.channels_in=a.num_channels; -1==b.channels_in&&(a.mode=la.MONO);b.channels_out=a.mode==la.MONO?1:2;b.mode_ext=c.MPG_MD_MS_LR;a.mode==la.MONO&&(a.force_ms=!1);a.VBR==G.vbr_off&&128!=a.VBR_mean_bitrate_kbps&&0==a.brate&&(a.brate=a.VBR_mean_bitrate_kbps);a.VBR!=G.vbr_off&&a.VBR!=G.vbr_mtrh&&a.VBR!=G.vbr_mt&&(a.free_format=!1);a.VBR==G.vbr_off&&0==a.brate&&qa.EQ(a.compression_ratio,0)&&(a.compression_ratio=11.025);a.VBR==G.vbr_off&&0a.out_samplerate?(a.VBR_mean_bitrate_kbps=Math.max(a.VBR_mean_bitrate_kbps,8),a.VBR_mean_bitrate_kbps=Math.min(a.VBR_mean_bitrate_kbps,64)):32E3>a.out_samplerate?(a.VBR_mean_bitrate_kbps=Math.max(a.VBR_mean_bitrate_kbps,8),a.VBR_mean_bitrate_kbps=Math.min(a.VBR_mean_bitrate_kbps,160)):(a.VBR_mean_bitrate_kbps= -Math.max(a.VBR_mean_bitrate_kbps,32),a.VBR_mean_bitrate_kbps=Math.min(a.VBR_mean_bitrate_kbps,320)));if(0==a.lowpassfreq){switch(a.VBR){case G.vbr_off:var e=new k;f(e,a.brate);e=e.lowerlimit;break;case G.vbr_abr:e=new k;f(e,a.VBR_mean_bitrate_kbps);e=e.lowerlimit;break;case G.vbr_rh:var h=[19500,19E3,18600,18E3,17500,16E3,15600,14900,12500,1E4,3950];if(0<=a.VBR_q&&9>=a.VBR_q){e=h[a.VBR_q];h=h[a.VBR_q+1];var m=a.VBR_q_frac;e=linear_int(e,h,m)}else e=19500;break;default:h=[19500,19E3,18500,18E3,17500, -16500,15500,14500,12500,9500,3950],0<=a.VBR_q&&9>=a.VBR_q?(e=h[a.VBR_q],h=h[a.VBR_q+1],m=a.VBR_q_frac,e=linear_int(e,h,m)):e=19500}a.mode!=la.MONO||a.VBR!=G.vbr_off&&a.VBR!=G.vbr_abr||(e*=1.5);a.lowpassfreq=e|0}0==a.out_samplerate&&(2*a.lowpassfreq>a.in_samplerate&&(a.lowpassfreq=a.in_samplerate/2),e=a.lowpassfreq|0,h=a.in_samplerate,m=44100,48E3<=h?m=48E3:44100<=h?m=44100:32E3<=h?m=32E3:24E3<=h?m=24E3:22050<=h?m=22050:16E3<=h?m=16E3:12E3<=h?m=12E3:11025<=h?m=11025:8E3<=h&&(m=8E3),-1==e?e=m:(15960>= -e&&(m=44100),15250>=e&&(m=32E3),11220>=e&&(m=24E3),9970>=e&&(m=22050),7230>=e&&(m=16E3),5420>=e&&(m=12E3),4510>=e&&(m=11025),3970>=e&&(m=8E3),e=h=a.out_samplerate?1:2;a.framesize=576*b.mode_gr;a.encoder_delay=c.ENCDELAY;b.resample_ratio=a.in_samplerate/a.out_samplerate;switch(a.VBR){case G.vbr_mt:case G.vbr_rh:case G.vbr_mtrh:a.compression_ratio=[5.7,6.5,7.3,8.2,10,11.9,13,14,15,16.5][a.VBR_q];break;case G.vbr_abr:a.compression_ratio=16*a.out_samplerate*b.channels_out/(1E3*a.VBR_mean_bitrate_kbps);break;default:a.compression_ratio=16*a.out_samplerate*b.channels_out/(1E3*a.brate)}a.mode==la.NOT_SET&&(a.mode=la.JOINT_STEREO);0b.lowpass1&&(b.lowpass1=0)):b.lowpass1=2*a.lowpassfreq,b.lowpass1/=a.out_samplerate,b.lowpass2/=a.out_samplerate):(b.lowpass1=0,b.lowpass2=0);e=a.internal_flags;var n=32,v=-1;if(0=h;h++)m=h/31,m>=e.lowpass2&&(n=Math.min(n,h)),e.lowpass1=h;h++)m=h/31,m<=e.highpass1&&(v=Math.max(v,h)),e.highpass1h;h++)m=h/31,v=e.highpass2>e.highpass1?V((e.highpass2-m)/(e.highpass2-e.highpass1+1E-20)):1,m=e.lowpass2>e.lowpass1?V((m-e.lowpass1)/(e.lowpass2-e.lowpass1+1E-20)):1,e.amp_filter[h]=v*m;b.samplerate_index=E(a.out_samplerate,a);if(0>b.samplerate_index)return a.internal_flags=null,-1;if(a.VBR==G.vbr_off)if(a.free_format)b.bitrate_index=0;else{if(a.brate=B(a.brate,a.version,a.out_samplerate),b.bitrate_index=U(a.brate,a.version,a.out_samplerate),0>=b.bitrate_index)return a.internal_flags=null,-1}else b.bitrate_index= -1;a.analysis&&(a.bWriteVbrTag=!1);null!=b.pinfo&&(a.bWriteVbrTag=!1);d.init_bit_stream_w(b);e=b.samplerate_index+3*a.version+6*(16E3>a.out_samplerate?1:0);for(h=0;he;e++)b.nsPsy.pefirbuf[e]=700* -b.mode_gr*b.channels_out;-1==a.ATHtype&&(a.ATHtype=4);switch(a.VBR){case G.vbr_mt:a.VBR=G.vbr_mtrh;case G.vbr_mtrh:null==a.useTemporal&&(a.useTemporal=!1);g.apply_preset(a,500-10*a.VBR_q,0);0>a.quality&&(a.quality=LAME_DEFAULT_QUALITY);5>a.quality&&(a.quality=0);5a.quality&&(a.quality=LAME_DEFAULT_QUALITY);b.iteration_loop=new VBROldIterationLoop(D);break;default:b.sfb21_extra=!1,0>a.quality&&(a.quality=LAME_DEFAULT_QUALITY),e=a.VBR,e==G.vbr_off&&(a.VBR_mean_bitrate_kbps=a.brate),g.apply_preset(a,a.VBR_mean_bitrate_kbps,0),a.VBR=e,b.PSY.mask_adjust=a.maskingadjust,b.PSY.mask_adjust_short= -a.maskingadjust_short,b.iteration_loop=e==G.vbr_off?new Bc(D):new ABRIterationLoop(D)}if(a.VBR!=G.vbr_off){b.VBR_min_bitrate=1;b.VBR_max_bitrate=14;16E3>a.out_samplerate&&(b.VBR_max_bitrate=8);if(0!=a.VBR_min_bitrate_kbps&&(a.VBR_min_bitrate_kbps=B(a.VBR_min_bitrate_kbps,a.version,a.out_samplerate),b.VBR_min_bitrate=U(a.VBR_min_bitrate_kbps,a.version,a.out_samplerate),0>b.VBR_min_bitrate)||0!=a.VBR_max_bitrate_kbps&&(a.VBR_max_bitrate_kbps=B(a.VBR_max_bitrate_kbps,a.version,a.out_samplerate),b.VBR_max_bitrate= -U(a.VBR_max_bitrate_kbps,a.version,a.out_samplerate),0>b.VBR_max_bitrate))return-1;a.VBR_min_bitrate_kbps=w.bitrate_table[a.version][b.VBR_min_bitrate];a.VBR_max_bitrate_kbps=w.bitrate_table[a.version][b.VBR_max_bitrate];a.VBR_mean_bitrate_kbps=Math.min(w.bitrate_table[a.version][b.VBR_max_bitrate],a.VBR_mean_bitrate_kbps);a.VBR_mean_bitrate_kbps=Math.max(w.bitrate_table[a.version][b.VBR_min_bitrate],a.VBR_mean_bitrate_kbps)}a.tune&&(b.PSY.mask_adjust+=a.tune_value_a,b.PSY.mask_adjust_short+=a.tune_value_a); -e=a.internal_flags;switch(a.quality){default:case 9:e.psymodel=0;e.noise_shaping=0;e.noise_shaping_amp=0;e.noise_shaping_stop=0;e.use_best_huffman=0;e.full_outer_loop=0;break;case 8:a.quality=7;case 7:e.psymodel=1;e.noise_shaping=0;e.noise_shaping_amp=0;e.noise_shaping_stop=0;e.use_best_huffman=0;e.full_outer_loop=0;break;case 6:e.psymodel=1;0==e.noise_shaping&&(e.noise_shaping=1);e.noise_shaping_amp=0;e.noise_shaping_stop=0;-1==e.subblock_gain&&(e.subblock_gain=1);e.use_best_huffman=0;e.full_outer_loop= -0;break;case 5:e.psymodel=1;0==e.noise_shaping&&(e.noise_shaping=1);e.noise_shaping_amp=0;e.noise_shaping_stop=0;-1==e.subblock_gain&&(e.subblock_gain=1);e.use_best_huffman=0;e.full_outer_loop=0;break;case 4:e.psymodel=1;0==e.noise_shaping&&(e.noise_shaping=1);e.noise_shaping_amp=0;e.noise_shaping_stop=0;-1==e.subblock_gain&&(e.subblock_gain=1);e.use_best_huffman=1;e.full_outer_loop=0;break;case 3:e.psymodel=1;0==e.noise_shaping&&(e.noise_shaping=1);e.noise_shaping_amp=1;e.noise_shaping_stop=1;-1== -e.subblock_gain&&(e.subblock_gain=1);e.use_best_huffman=1;e.full_outer_loop=0;break;case 2:e.psymodel=1;0==e.noise_shaping&&(e.noise_shaping=1);0==e.substep_shaping&&(e.substep_shaping=2);e.noise_shaping_amp=1;e.noise_shaping_stop=1;-1==e.subblock_gain&&(e.subblock_gain=1);e.use_best_huffman=1;e.full_outer_loop=0;break;case 1:e.psymodel=1;0==e.noise_shaping&&(e.noise_shaping=1);0==e.substep_shaping&&(e.substep_shaping=2);e.noise_shaping_amp=2;e.noise_shaping_stop=1;-1==e.subblock_gain&&(e.subblock_gain= -1);e.use_best_huffman=1;e.full_outer_loop=0;break;case 0:e.psymodel=1,0==e.noise_shaping&&(e.noise_shaping=1),0==e.substep_shaping&&(e.substep_shaping=2),e.noise_shaping_amp=2,e.noise_shaping_stop=1,-1==e.subblock_gain&&(e.subblock_gain=1),e.use_best_huffman=1,e.full_outer_loop=0}b.ATH.useAdjust=0>a.athaa_type?3:a.athaa_type;b.ATH.aaSensitivityP=Math.pow(10,a.athaa_sensitivity/-10);null==a.short_blocks&&(a.short_blocks=ra.short_block_allowed);a.short_blocks!=ra.short_block_allowed||a.mode!=la.JOINT_STEREO&& -a.mode!=la.STEREO||(a.short_blocks=ra.short_block_coupled);0>a.quant_comp&&(a.quant_comp=1);0>a.quant_comp_short&&(a.quant_comp_short=0);0>a.msfix&&(a.msfix=0);a.exp_nspsytune|=1;0>a.internal_flags.nsPsy.attackthre&&(a.internal_flags.nsPsy.attackthre=Pb.NSATTACKTHRE);0>a.internal_flags.nsPsy.attackthre_s&&(a.internal_flags.nsPsy.attackthre_s=Pb.NSATTACKTHRE_S);0>a.scale&&(a.scale=1);0>a.ATHtype&&(a.ATHtype=4);0>a.ATHcurve&&(a.ATHcurve=4);0>a.athaa_loudapprox&&(a.athaa_loudapprox=2);0>a.interChRatio&& -(a.interChRatio=0);null==a.useTemporal&&(a.useTemporal=!0);b.slot_lag=b.frac_SpF=0;a.VBR==G.vbr_off&&(b.slot_lag=b.frac_SpF=72E3*(a.version+1)*a.brate%a.out_samplerate|0);q.iteration_init(a);p.psymodel_init(a);return 0};this.lame_encode_flush=function(a,e,f,g){var k=a.internal_flags,l=dc([2,1152]),h=0,m=k.mf_samples_to_encode-c.POSTDELAY,p=b(a);if(1>k.mf_samples_to_encode)return 0;var n=0;a.in_samplerate!=a.out_samplerate&&(m+=16*a.out_samplerate/a.in_samplerate);var q=a.framesize-m%a.framesize;576> -q&&(q+=a.framesize);a.encoder_padding=q;for(q=(m+q)/a.framesize;0r&&(r=1);h=g-n;0==g&&(h=0);h=this.lame_encode_buffer(a,l[0],l[1],r,e,f,h);f+=h;n+=h;q-=m!=a.frameNum?1:0}k.mf_samples_to_encode=0;if(0>h)return h;h=g-n;0==g&&(h=0);d.flush_bitstream(a);h=d.copy_buffer(k,e,f,h,1);if(0>h)return h;f+=h;n+=h;h=g-n;0==g&&(h=0);if(a.write_id3tag_automatic){t.id3tag_write_v1(a);h=d.copy_buffer(k,e,f,h,0);if(0> -h)return h;n+=h}return n};this.lame_encode_buffer=function(a,b,d,c,e,f,g){var h=a.internal_flags,k=[null,null];if(4294479419!=h.Class_ID)return-3;if(0==c)return 0;if(null==h.in_buffer_0||h.in_buffer_nsamplesMath.abs(k)?Math.abs(c-k)<=1E-6*Math.abs(c):Math.abs(c-k)<=1E-6*Math.abs(k)};qa.NEQ=function(c,k){return!qa.EQ(c,k)};zb.NUMTOCENTRIES=100;zb.MAXFRAMESIZE=2880; -var w={t1HB:[1,1,1,0],t2HB:[1,2,1,3,1,1,3,2,0],t3HB:[3,2,1,1,1,1,3,2,0],t5HB:[1,2,6,5,3,1,4,4,7,5,7,1,6,1,1,0],t6HB:[7,3,5,1,6,2,3,2,5,4,4,1,3,3,2,0],t7HB:[1,2,10,19,16,10,3,3,7,10,5,3,11,4,13,17,8,4,12,11,18,15,11,2,7,6,9,14,3,1,6,4,5,3,2,0],t8HB:[3,4,6,18,12,5,5,1,2,16,9,3,7,3,5,14,7,3,19,17,15,13,10,4,13,5,8,11,5,1,12,4,4,1,1,0],t9HB:[7,5,9,14,15,7,6,4,5,5,6,7,7,6,8,8,8,5,15,6,9,10,5,1,11,7,9,6,4,1,14,4,6,2,6,0],t10HB:[1,2,10,23,35,30,12,17,3,3,8,12,18,21,12,7,11,9,15,21,32,40,19,6,14,13,22,34, -46,23,18,7,20,19,33,47,27,22,9,3,31,22,41,26,21,20,5,3,14,13,10,11,16,6,5,1,9,8,7,8,4,4,2,0],t11HB:[3,4,10,24,34,33,21,15,5,3,4,10,32,17,11,10,11,7,13,18,30,31,20,5,25,11,19,59,27,18,12,5,35,33,31,58,30,16,7,5,28,26,32,19,17,15,8,14,14,12,9,13,14,9,4,1,11,4,6,6,6,3,2,0],t12HB:[9,6,16,33,41,39,38,26,7,5,6,9,23,16,26,11,17,7,11,14,21,30,10,7,17,10,15,12,18,28,14,5,32,13,22,19,18,16,9,5,40,17,31,29,17,13,4,2,27,12,11,15,10,7,4,1,27,12,8,12,6,3,1,0],t13HB:[1,5,14,21,34,51,46,71,42,52,68,52,67,44,43,19, -3,4,12,19,31,26,44,33,31,24,32,24,31,35,22,14,15,13,23,36,59,49,77,65,29,40,30,40,27,33,42,16,22,20,37,61,56,79,73,64,43,76,56,37,26,31,25,14,35,16,60,57,97,75,114,91,54,73,55,41,48,53,23,24,58,27,50,96,76,70,93,84,77,58,79,29,74,49,41,17,47,45,78,74,115,94,90,79,69,83,71,50,59,38,36,15,72,34,56,95,92,85,91,90,86,73,77,65,51,44,43,42,43,20,30,44,55,78,72,87,78,61,46,54,37,30,20,16,53,25,41,37,44,59,54,81,66,76,57,54,37,18,39,11,35,33,31,57,42,82,72,80,47,58,55,21,22,26,38,22,53,25,23,38,70,60,51, -36,55,26,34,23,27,14,9,7,34,32,28,39,49,75,30,52,48,40,52,28,18,17,9,5,45,21,34,64,56,50,49,45,31,19,12,15,10,7,6,3,48,23,20,39,36,35,53,21,16,23,13,10,6,1,4,2,16,15,17,27,25,20,29,11,17,12,16,8,1,1,0,1],t15HB:[7,12,18,53,47,76,124,108,89,123,108,119,107,81,122,63,13,5,16,27,46,36,61,51,42,70,52,83,65,41,59,36,19,17,15,24,41,34,59,48,40,64,50,78,62,80,56,33,29,28,25,43,39,63,55,93,76,59,93,72,54,75,50,29,52,22,42,40,67,57,95,79,72,57,89,69,49,66,46,27,77,37,35,66,58,52,91,74,62,48,79,63,90,62,40, -38,125,32,60,56,50,92,78,65,55,87,71,51,73,51,70,30,109,53,49,94,88,75,66,122,91,73,56,42,64,44,21,25,90,43,41,77,73,63,56,92,77,66,47,67,48,53,36,20,71,34,67,60,58,49,88,76,67,106,71,54,38,39,23,15,109,53,51,47,90,82,58,57,48,72,57,41,23,27,62,9,86,42,40,37,70,64,52,43,70,55,42,25,29,18,11,11,118,68,30,55,50,46,74,65,49,39,24,16,22,13,14,7,91,44,39,38,34,63,52,45,31,52,28,19,14,8,9,3,123,60,58,53,47,43,32,22,37,24,17,12,15,10,2,1,71,37,34,30,28,20,17,26,21,16,10,6,8,6,2,0],t16HB:[1,5,14,44,74,63, -110,93,172,149,138,242,225,195,376,17,3,4,12,20,35,62,53,47,83,75,68,119,201,107,207,9,15,13,23,38,67,58,103,90,161,72,127,117,110,209,206,16,45,21,39,69,64,114,99,87,158,140,252,212,199,387,365,26,75,36,68,65,115,101,179,164,155,264,246,226,395,382,362,9,66,30,59,56,102,185,173,265,142,253,232,400,388,378,445,16,111,54,52,100,184,178,160,133,257,244,228,217,385,366,715,10,98,48,91,88,165,157,148,261,248,407,397,372,380,889,884,8,85,84,81,159,156,143,260,249,427,401,392,383,727,713,708,7,154,76,73, -141,131,256,245,426,406,394,384,735,359,710,352,11,139,129,67,125,247,233,229,219,393,743,737,720,885,882,439,4,243,120,118,115,227,223,396,746,742,736,721,712,706,223,436,6,202,224,222,218,216,389,386,381,364,888,443,707,440,437,1728,4,747,211,210,208,370,379,734,723,714,1735,883,877,876,3459,865,2,377,369,102,187,726,722,358,711,709,866,1734,871,3458,870,434,0,12,10,7,11,10,17,11,9,13,12,10,7,5,3,1,3],t24HB:[15,13,46,80,146,262,248,434,426,669,653,649,621,517,1032,88,14,12,21,38,71,130,122,216, -209,198,327,345,319,297,279,42,47,22,41,74,68,128,120,221,207,194,182,340,315,295,541,18,81,39,75,70,134,125,116,220,204,190,178,325,311,293,271,16,147,72,69,135,127,118,112,210,200,188,352,323,306,285,540,14,263,66,129,126,119,114,214,202,192,180,341,317,301,281,262,12,249,123,121,117,113,215,206,195,185,347,330,308,291,272,520,10,435,115,111,109,211,203,196,187,353,332,313,298,283,531,381,17,427,212,208,205,201,193,186,177,169,320,303,286,268,514,377,16,335,199,197,191,189,181,174,333,321,305,289, -275,521,379,371,11,668,184,183,179,175,344,331,314,304,290,277,530,383,373,366,10,652,346,171,168,164,318,309,299,287,276,263,513,375,368,362,6,648,322,316,312,307,302,292,284,269,261,512,376,370,364,359,4,620,300,296,294,288,282,273,266,515,380,374,369,365,361,357,2,1033,280,278,274,267,264,259,382,378,372,367,363,360,358,356,0,43,20,19,17,15,13,11,9,7,6,4,7,5,3,1,3],t32HB:[1,10,8,20,12,20,16,32,14,12,24,0,28,16,24,16],t33HB:[15,28,26,48,22,40,36,64,14,24,20,32,12,16,8,0],t1l:[1,4,3,5],t2l:[1,4, -7,4,5,7,6,7,8],t3l:[2,3,7,4,4,7,6,7,8],t5l:[1,4,7,8,4,5,8,9,7,8,9,10,8,8,9,10],t6l:[3,4,6,8,4,4,6,7,5,6,7,8,7,7,8,9],t7l:[1,4,7,9,9,10,4,6,8,9,9,10,7,7,9,10,10,11,8,9,10,11,11,11,8,9,10,11,11,12,9,10,11,12,12,12],t8l:[2,4,7,9,9,10,4,4,6,10,10,10,7,6,8,10,10,11,9,10,10,11,11,12,9,9,10,11,12,12,10,10,11,11,13,13],t9l:[3,4,6,7,9,10,4,5,6,7,8,10,5,6,7,8,9,10,7,7,8,9,9,10,8,8,9,9,10,11,9,9,10,10,11,11],t10l:[1,4,7,9,10,10,10,11,4,6,8,9,10,11,10,10,7,8,9,10,11,12,11,11,8,9,10,11,12,12,11,12,9,10,11,12, -12,12,12,12,10,11,12,12,13,13,12,13,9,10,11,12,12,12,13,13,10,10,11,12,12,13,13,13],t11l:[2,4,6,8,9,10,9,10,4,5,6,8,10,10,9,10,6,7,8,9,10,11,10,10,8,8,9,11,10,12,10,11,9,10,10,11,11,12,11,12,9,10,11,12,12,13,12,13,9,9,9,10,11,12,12,12,9,9,10,11,12,12,12,12],t12l:[4,4,6,8,9,10,10,10,4,5,6,7,9,9,10,10,6,6,7,8,9,10,9,10,7,7,8,8,9,10,10,10,8,8,9,9,10,10,10,11,9,9,10,10,10,11,10,11,9,9,9,10,10,11,11,12,10,10,10,11,11,11,11,12],t13l:[1,5,7,8,9,10,10,11,10,11,12,12,13,13,14,14,4,6,8,9,10,10,11,11,11,11, -12,12,13,14,14,14,7,8,9,10,11,11,12,12,11,12,12,13,13,14,15,15,8,9,10,11,11,12,12,12,12,13,13,13,13,14,15,15,9,9,11,11,12,12,13,13,12,13,13,14,14,15,15,16,10,10,11,12,12,12,13,13,13,13,14,13,15,15,16,16,10,11,12,12,13,13,13,13,13,14,14,14,15,15,16,16,11,11,12,13,13,13,14,14,14,14,15,15,15,16,18,18,10,10,11,12,12,13,13,14,14,14,14,15,15,16,17,17,11,11,12,12,13,13,13,15,14,15,15,16,16,16,18,17,11,12,12,13,13,14,14,15,14,15,16,15,16,17,18,19,12,12,12,13,14,14,14,14,15,15,15,16,17,17,17,18,12,13,13,14, -14,15,14,15,16,16,17,17,17,18,18,18,13,13,14,15,15,15,16,16,16,16,16,17,18,17,18,18,14,14,14,15,15,15,17,16,16,19,17,17,17,19,18,18,13,14,15,16,16,16,17,16,17,17,18,18,21,20,21,18],t15l:[3,5,6,8,8,9,10,10,10,11,11,12,12,12,13,14,5,5,7,8,9,9,10,10,10,11,11,12,12,12,13,13,6,7,7,8,9,9,10,10,10,11,11,12,12,13,13,13,7,8,8,9,9,10,10,11,11,11,12,12,12,13,13,13,8,8,9,9,10,10,11,11,11,11,12,12,12,13,13,13,9,9,9,10,10,10,11,11,11,11,12,12,13,13,13,14,10,9,10,10,10,11,11,11,11,12,12,12,13,13,14,14,10,10,10, -11,11,11,11,12,12,12,12,12,13,13,13,14,10,10,10,11,11,11,11,12,12,12,12,13,13,14,14,14,10,10,11,11,11,11,12,12,12,13,13,13,13,14,14,14,11,11,11,11,12,12,12,12,12,13,13,13,13,14,15,14,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,15,12,12,11,12,12,12,13,13,13,13,13,13,14,14,15,15,12,12,12,12,12,13,13,13,13,14,14,14,14,14,15,15,13,13,13,13,13,13,13,13,14,14,14,14,15,15,14,15,13,13,13,13,13,13,13,14,14,14,14,14,15,15,15,15],t16_5l:[1,5,7,9,10,10,11,11,12,12,12,13,13,13,14,11,4,6,8,9,10,11,11,11,12,12, -12,13,14,13,14,11,7,8,9,10,11,11,12,12,13,12,13,13,13,14,14,12,9,9,10,11,11,12,12,12,13,13,14,14,14,15,15,13,10,10,11,11,12,12,13,13,13,14,14,14,15,15,15,12,10,10,11,11,12,13,13,14,13,14,14,15,15,15,16,13,11,11,11,12,13,13,13,13,14,14,14,14,15,15,16,13,11,11,12,12,13,13,13,14,14,15,15,15,15,17,17,13,11,12,12,13,13,13,14,14,15,15,15,15,16,16,16,13,12,12,12,13,13,14,14,15,15,15,15,16,15,16,15,14,12,13,12,13,14,14,14,14,15,16,16,16,17,17,16,13,13,13,13,13,14,14,15,16,16,16,16,16,16,15,16,14,13,14,14, -14,14,15,15,15,15,17,16,16,16,16,18,14,15,14,14,14,15,15,16,16,16,18,17,17,17,19,17,14,14,15,13,14,16,16,15,16,16,17,18,17,19,17,16,14,11,11,11,12,12,13,13,13,14,14,14,14,14,14,14,12],t16l:[1,5,7,9,10,10,11,11,12,12,12,13,13,13,14,10,4,6,8,9,10,11,11,11,12,12,12,13,14,13,14,10,7,8,9,10,11,11,12,12,13,12,13,13,13,14,14,11,9,9,10,11,11,12,12,12,13,13,14,14,14,15,15,12,10,10,11,11,12,12,13,13,13,14,14,14,15,15,15,11,10,10,11,11,12,13,13,14,13,14,14,15,15,15,16,12,11,11,11,12,13,13,13,13,14,14,14,14, -15,15,16,12,11,11,12,12,13,13,13,14,14,15,15,15,15,17,17,12,11,12,12,13,13,13,14,14,15,15,15,15,16,16,16,12,12,12,12,13,13,14,14,15,15,15,15,16,15,16,15,13,12,13,12,13,14,14,14,14,15,16,16,16,17,17,16,12,13,13,13,13,14,14,15,16,16,16,16,16,16,15,16,13,13,14,14,14,14,15,15,15,15,17,16,16,16,16,18,13,15,14,14,14,15,15,16,16,16,18,17,17,17,19,17,13,14,15,13,14,16,16,15,16,16,17,18,17,19,17,16,13,10,10,10,11,11,12,12,12,13,13,13,13,13,13,13,10],t24l:[4,5,7,8,9,10,10,11,11,12,12,12,12,12,13,10,5,6,7,8, -9,10,10,11,11,11,12,12,12,12,12,10,7,7,8,9,9,10,10,11,11,11,11,12,12,12,13,9,8,8,9,9,10,10,10,11,11,11,11,12,12,12,12,9,9,9,9,10,10,10,10,11,11,11,12,12,12,12,13,9,10,9,10,10,10,10,11,11,11,11,12,12,12,12,12,9,10,10,10,10,10,11,11,11,11,12,12,12,12,12,13,9,11,10,10,10,11,11,11,11,12,12,12,12,12,13,13,10,11,11,11,11,11,11,11,11,11,12,12,12,12,13,13,10,11,11,11,11,11,11,11,12,12,12,12,12,13,13,13,10,12,11,11,11,11,12,12,12,12,12,12,13,13,13,13,10,12,12,11,11,11,12,12,12,12,12,12,13,13,13,13,10,12,12, -12,12,12,12,12,12,12,12,13,13,13,13,13,10,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,10,13,12,12,12,12,12,12,13,13,13,13,13,13,13,13,10,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,6],t32l:[1,5,5,7,5,8,7,9,5,7,7,9,7,9,9,10],t33l:[4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8]};w.ht=[new U(0,0,null,null),new U(2,0,w.t1HB,w.t1l),new U(3,0,w.t2HB,w.t2l),new U(3,0,w.t3HB,w.t3l),new U(0,0,null,null),new U(4,0,w.t5HB,w.t5l),new U(4,0,w.t6HB,w.t6l),new U(6,0,w.t7HB,w.t7l),new U(6,0,w.t8HB,w.t8l),new U(6,0,w.t9HB,w.t9l),new U(8, -0,w.t10HB,w.t10l),new U(8,0,w.t11HB,w.t11l),new U(8,0,w.t12HB,w.t12l),new U(16,0,w.t13HB,w.t13l),new U(0,0,null,w.t16_5l),new U(16,0,w.t15HB,w.t15l),new U(1,1,w.t16HB,w.t16l),new U(2,3,w.t16HB,w.t16l),new U(3,7,w.t16HB,w.t16l),new U(4,15,w.t16HB,w.t16l),new U(6,63,w.t16HB,w.t16l),new U(8,255,w.t16HB,w.t16l),new U(10,1023,w.t16HB,w.t16l),new U(13,8191,w.t16HB,w.t16l),new U(4,15,w.t24HB,w.t24l),new U(5,31,w.t24HB,w.t24l),new U(6,63,w.t24HB,w.t24l),new U(7,127,w.t24HB,w.t24l),new U(8,255,w.t24HB,w.t24l), -new U(9,511,w.t24HB,w.t24l),new U(11,2047,w.t24HB,w.t24l),new U(13,8191,w.t24HB,w.t24l),new U(0,0,w.t32HB,w.t32l),new U(0,0,w.t33HB,w.t33l)];w.largetbl=[65540,327685,458759,589832,655369,655370,720906,720907,786443,786444,786444,851980,851980,851980,917517,655370,262149,393222,524295,589832,655369,720906,720906,720907,786443,786443,786444,851980,917516,851980,917516,655370,458759,524295,589832,655369,720905,720906,786442,786443,851979,786443,851979,851980,851980,917516,917517,720905,589832,589832, -655369,720905,720906,786442,786442,786443,851979,851979,917515,917516,917516,983052,983052,786441,655369,655369,720905,720906,786442,786442,851978,851979,851979,917515,917516,917516,983052,983052,983053,720905,655370,655369,720906,720906,786442,851978,851979,917515,851979,917515,917516,983052,983052,983052,1048588,786441,720906,720906,720906,786442,851978,851979,851979,851979,917515,917516,917516,917516,983052,983052,1048589,786441,720907,720906,786442,786442,851979,851979,851979,917515,917516,983052, -983052,983052,983052,1114125,1114125,786442,720907,786443,786443,851979,851979,851979,917515,917515,983051,983052,983052,983052,1048588,1048589,1048589,786442,786443,786443,786443,851979,851979,917515,917515,983052,983052,983052,983052,1048588,983053,1048589,983053,851978,786444,851979,786443,851979,917515,917516,917516,917516,983052,1048588,1048588,1048589,1114125,1114125,1048589,786442,851980,851980,851979,851979,917515,917516,983052,1048588,1048588,1048588,1048588,1048589,1048589,983053,1048589, -851978,851980,917516,917516,917516,917516,983052,983052,983052,983052,1114124,1048589,1048589,1048589,1048589,1179661,851978,983052,917516,917516,917516,983052,983052,1048588,1048588,1048589,1179661,1114125,1114125,1114125,1245197,1114125,851978,917517,983052,851980,917516,1048588,1048588,983052,1048589,1048589,1114125,1179661,1114125,1245197,1114125,1048589,851978,655369,655369,655369,720905,720905,786441,786441,786441,851977,851977,851977,851978,851978,851978,851978,655366];w.table23=[65538,262147, -458759,262148,327684,458759,393222,458759,524296];w.table56=[65539,262148,458758,524296,262148,327684,524294,589831,458757,524294,589831,655368,524295,524295,589832,655369];w.bitrate_table=[[0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,-1],[0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,-1],[0,8,16,24,32,40,48,56,64,-1,-1,-1,-1,-1,-1,-1]];w.samplerate_table=[[22050,24E3,16E3,-1],[44100,48E3,32E3,-1],[11025,12E3,8E3,-1]];w.scfsi_band=[0,6,11,16,21];ia.Q_MAX=257;ia.Q_MAX2=116;ia.LARGE_BITS=1E5; -ia.IXMAX_VAL=8206;var sa={};sa.SFBMAX=3*c.SBMAX_s;c.ENCDELAY=576;c.POSTDELAY=1152;c.MDCTDELAY=48;c.FFTOFFSET=224+c.MDCTDELAY;c.DECDELAY=528;c.SBLIMIT=32;c.CBANDS=64;c.SBPSY_l=21;c.SBPSY_s=12;c.SBMAX_l=22;c.SBMAX_s=13;c.PSFB21=6;c.PSFB12=6;c.BLKSIZE=1024;c.HBLKSIZE=c.BLKSIZE/2+1;c.BLKSIZE_s=256;c.HBLKSIZE_s=c.BLKSIZE_s/2+1;c.NORM_TYPE=0;c.START_TYPE=1;c.SHORT_TYPE=2;c.STOP_TYPE=3;c.MPG_MD_LR_LR=0;c.MPG_MD_LR_I=1;c.MPG_MD_MS_LR=2;c.MPG_MD_MS_I=3;c.fircoef=[-.1039435,-.1892065,-.0432472*5,-.155915,3.898045E-17, -.0467745*5,.50455,.756825,.187098*5];da.MFSIZE=3456+c.ENCDELAY-c.MDCTDELAY;da.MAX_HEADER_BUF=256;da.MAX_BITS_PER_CHANNEL=4095;da.MAX_BITS_PER_GRANULE=7680;da.BPC=320;Fa.RIFF=cc("RIFF");Fa.WAVE=cc("WAVE");Fa.fmt_=cc("fmt ");Fa.data=cc("data");Fa.readHeader=function(c){var k=new Fa,n=c.getUint32(0,!1);if(Fa.RIFF==n&&(c.getUint32(4,!0),Fa.WAVE==c.getUint32(8,!1)&&Fa.fmt_==c.getUint32(12,!1))){var u=c.getUint32(16,!0),w=20;switch(u){case 16:case 18:k.channels=c.getUint16(w+2,!0);k.sampleRate=c.getUint32(w+ -4,!0);break;default:throw"extended fmt chunk not implemented";}w+=u;u=Fa.data;for(var B=0;u!=n;){n=c.getUint32(w,!1);B=c.getUint32(w+4,!0);if(u==n)break;w+=B+8}k.dataLen=B;k.dataOffset=w+8;return k}};sa.SFBMAX=3*c.SBMAX_s;lamejs.Mp3Encoder=function(c,k,n){3!=arguments.length&&(console.error("WARN: Mp3Encoder(channels, samplerate, kbps) not specified"),c=1,k=44100,n=128);var u=new W,w=new Kc,B=new Y,G=new qa,f=new wc,b=new ia,v=new Ec,a=new zb,m=new mc,z=new Nc,e=new xc,l=new qb,d=new Lc,g=new Mc; -u.setModules(B,G,f,b,v,a,m,z,g);G.setModules(B,g,m,a);z.setModules(G,m);f.setModules(u);v.setModules(G,e,b,l);b.setModules(l,e,u.enc.psy);e.setModules(G);l.setModules(b);a.setModules(u,G,m);w.setModules(d,g);d.setModules(m,z,f);var q=u.lame_init();q.num_channels=c;q.in_samplerate=k;q.brate=n;q.mode=la.STEREO;q.quality=3;q.bWriteVbrTag=!1;q.disable_reservoir=!0;q.write_id3tag_automatic=!1;u.lame_init_params(q);var D=1152,p=0|1.25*D+7200,r=new Int8Array(p);this.encodeBuffer=function(a,b){1==c&&(b=a); -a.length>D&&(D=a.length,p=0|1.25*D+7200,r=new Int8Array(p));a=u.lame_encode_buffer(q,a,b,a.length,r,0,p);return new Int8Array(r.subarray(0,a))};this.flush=function(){var a=u.lame_encode_flush(q,r,0,p);return new Int8Array(r.subarray(0,a))}};lamejs.WavHeader=Fa}lamejs(); -export default lamejs; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/lame.min.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/lame.min.mjs deleted file mode 100644 index 76e0cf6c6..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/lame.min.mjs +++ /dev/null @@ -1,308 +0,0 @@ -function lamejs(){function X(c){return new Int32Array(c)}function K(c){return new Float32Array(c)}function ca(c){if(1==c.length)return K(c[0]);var k=c[0];c=c.slice(1);for(var n=[],u=0;uf.sampleWindow-f.totsamp?f.sampleWindow-f.totsamp:d;if(lMAX_ORDER-l&&(g=MAX_ORDER-l)}else e=v+l,q=b,D=m+l,p=a;c(q,e,f.lstepbuf,f.lstep+f.totsamp,g,B[f.reqindex]);c(p,D,f.rstepbuf,f.rstep+f.totsamp,g,B[f.reqindex]);k(f.lstepbuf,f.lstep+f.totsamp,f.loutbuf,f.lout+f.totsamp,g,w[f.reqindex]);k(f.rstepbuf,f.rstep+f.totsamp,f.routbuf,f.rout+f.totsamp,g,w[f.reqindex]);e=f.lout+f.totsamp;q=f.loutbuf; -D=f.rout+f.totsamp;p=f.routbuf;for(var r=g%8;0!=r--;)f.lsum+=n(q[e++]),f.rsum+=n(p[D++]);for(r=g/8;0!=r--;)f.lsum+=n(q[e+0])+n(q[e+1])+n(q[e+2])+n(q[e+3])+n(q[e+4])+n(q[e+5])+n(q[e+6])+n(q[e+7]),e+=8,f.rsum+=n(p[D+0])+n(p[D+1])+n(p[D+2])+n(p[D+3])+n(p[D+4])+n(p[D+5])+n(p[D+6])+n(p[D+7]),D+=8;d-=g;l+=g;f.totsamp+=g;f.totsamp==f.sampleWindow&&(e=10*Y.STEPS_per_dB*Math.log10((f.lsum+f.rsum)/f.totsamp*.5+1E-37),e=0>=e?0:0|e,e>=f.A.length&&(e=f.A.length-1),f.A[e]++,f.lsum=f.rsum=0,T.arraycopy(f.loutbuf, -f.totsamp,f.loutbuf,0,MAX_ORDER),T.arraycopy(f.routbuf,f.totsamp,f.routbuf,0,MAX_ORDER),T.arraycopy(f.lstepbuf,f.totsamp,f.lstepbuf,0,MAX_ORDER),T.arraycopy(f.rstepbuf,f.totsamp,f.rstepbuf,0,MAX_ORDER),f.totsamp=0);if(f.totsamp>f.sampleWindow)return GAIN_ANALYSIS_ERROR}u=(m-=b[a])););b=64.82-a/Y.STEPS_per_dB}for(c=0;cf&&(f=0);9k&&(k+=64);b.exp_nspsytune|=k<<2}0!=a?b.quant_comp=f[m].quant_comp:0=c)return V(b,c,a);b.preset=0;return c}}function qb(){function u(a){this.bits=0|a}function k(a,d,p,b,e,c){d=.5946/d;for(a>>=1;0!=a--;)e[c++]=d>p[b++]? -0:1,e[c++]=d>p[b++]?0:1}function n(a,d,b,e,c,l){a>>=1;var h=a%2;for(a>>=1;0!=a--;){var p=b[e++]*d;var r=b[e++]*d;var t=0|p;var f=b[e++]*d;var g=0|r;var J=b[e++]*d;var D=0|f;p+=B.adj43[t];t=0|J;r+=B.adj43[g];c[l++]=0|p;f+=B.adj43[D];c[l++]=0|r;J+=B.adj43[t];c[l++]=0|f;c[l++]=0|J}0!=h&&(p=b[e++]*d,r=b[e++]*d,p+=B.adj43[0|p],r+=B.adj43[0|r],c[l++]=0|p,c[l++]=0|r)}function V(a,d,b,e){var p,c=d,h=p=0;do{var r=a[c++],l=a[c++];p>=16;p>a&&(p=a,d++);e.bits+=p;return d;case 4:case 5:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:c=d;d=f[p-1];r=h=p=0;l=w.ht[d].xlen;var g=w.ht[d].hlen,D=w.ht[d+1].hlen,q=w.ht[d+2].hlen;do{var m=a[c+0]*l+a[c+1];c+=2;p+=g[m];h+=D[m];r+=q[m]}while(ch&&(p=h,a++);p>r&&(p=r,a=d+2);e.bits+=p;return a;default:if(p>ia.IXMAX_VAL)return e.bits=ia.LARGE_BITS,-1;p-=15;for(c=24;32>c&&!(w.ht[c].linmax>=p);c++);for(h=c-8;24>h&&!(w.ht[h].linmax>=p);h++);p=h;r=65536*w.ht[p].xlen+w.ht[c].xlen;h=0;do l=a[d++],g=a[d++],0!=l&&(14>=16;h>a&&(h=a,p=c);e.bits+=h;return p}}function E(a,d,p,b,e,l,h,g){for(var r=d.big_values,f=2;f=r)break;var t=e[f-2]+d.count1bits;if(p.part2_3_length<=t)break;t=new u(t);x=V(b,x,r,t);t=t.bits;p.part2_3_length<=t||(p.assign(d),p.part2_3_length=t,p.region0_count=l[f-2],p.region1_count=f-2-l[f-2],p.table_select[0]=h[f-2],p.table_select[1]=g[f-2],p.table_select[2]=x)}}var B=null;this.qupvt=null;this.setModules=function(a){B=this.qupvt=a};var ha=[[0,0],[0,0],[0,0],[0,0],[0,0],[0,1],[1,1],[1,1],[1,2],[2,2],[2,3],[2,3],[3,4],[3,4],[3,4],[4,5],[4,5],[4,6],[5,6],[5,6],[5,7],[6,7],[6,7]],f=[1,2, -5,7,7,10,10,13,13,13,13,13,13,13,13];this.noquant_count_bits=function(a,d,p){var b=d.l3_enc,e=Math.min(576,d.max_nonzero_coeff+2>>1<<1);null!=p&&(p.sfb_count1=0);for(;1h&&(f=h,d.count1table_select=1);d.count1bits=f;d.big_values=e;if(0==e)return f;d.block_type==c.SHORT_TYPE?(l=3*a.scalefac_band.s[3], -l>d.big_values&&(l=d.big_values),h=d.big_values):d.block_type==c.NORM_TYPE?(l=d.region0_count=a.bv_scf[e-2],h=d.region1_count=a.bv_scf[e-1],h=a.scalefac_band.l[l+h+2],l=a.scalefac_band.l[l+1],hh&&(l=h));l=Math.min(l,e);h=Math.min(h,e);0l)return ia.LARGE_BITS;l=B.IPOW20(e.global_gain);var h,f=0,g=0,r=0,D=0,m=0,q=p,v=0,C=d,I=0;var Q=null!=b&&e.global_gain==b.global_gain;var S=e.block_type==c.SHORT_TYPE?38:21;for(h=0;h<=S;h++){var u=-1;if(Q||e.block_type==c.NORM_TYPE)u= -e.global_gain-(e.scalefac[h]+(0!=e.preflag?B.pretab[h]:0)<e.max_nonzero_coeff&&(h=e.max_nonzero_coeff-f+1,na.fill(p,e.max_nonzero_coeff,576,0),Z=h,0>Z&&(Z=0),h=S+1);0==g&&0==r&&(q=p,v=m,C=d,I=D);null!=b&&0=b.sfb_count1&&0=b.step[h]?(0!=g&&(n(g,l,C,I,q,v),g=0,q=p,v=m,C=d,I=D),r+=Z):(0!=r&&(k(r,l,C,I,q,v),r=0,q= -p,v=m,C=d,I=D),g+=Z);if(0>=Z){0!=r&&(k(r,l,C,I,q,v),r=0);0!=g&&(n(g,l,C,I,q,v),g=0);break}}h<=S&&(m+=e.width[h],D+=e.width[h],f+=e.width[h])}0!=g&&n(g,l,C,I,q,v);0!=r&&k(r,l,C,I,q,v);if(0!=(a.substep_shaping&2))for(l=0,S=.634521682242439/B.IPOW20(e.global_gain+e.scalefac_scale),f=0;f=S?p[g]:0;return this.noquant_count_bits(a,e,b)};this.best_huffman_divide=function(a,d){var e=new rb,b=d.l3_enc,l=X(23),f=X(23), -h=X(23),g=X(23);if(d.block_type!=c.SHORT_TYPE||1!=a.mode_gr){e.assign(d);if(d.block_type==c.NORM_TYPE){for(var y=d.big_values,m=0;22>=m;m++)l[m]=ia.LARGE_BITS;for(m=0;16>m;m++){var D=a.scalefac_band.l[m+1];if(D>=y)break;var q=0,k=new u(q),v=V(b,0,D,k);q=k.bits;for(var C=0;8>C;C++){var I=a.scalefac_band.l[m+C+2];if(I>=y)break;k=q;k=new u(k);I=V(b,D,I,k);k=k.bits;l[m+C]>k&&(l[m+C]=k,f[m+C]=m,h[m+C]=v,g[m+C]=I)}}E(a,e,d,b,l,f,h,g)}y=e.big_values;if(!(0==y||1<(b[y-2]|b[y-1])||(y=d.count1+2,576e.big_values;y-=4)q=2*(2*(2*b[y-4]+b[y-3])+b[y-2])+b[y-1],m+=w.t32l[q],D+=w.t33l[q];e.big_values=y;e.count1table_select=0;m>D&&(m=D,e.count1table_select=1);e.count1bits=m;e.block_type==c.NORM_TYPE?E(a,e,d,b,l,f,h,g):(e.part2_3_length=m,m=a.scalefac_band.l[8],m>y&&(m=y),0m&&(a=new u(e.part2_3_length),e.table_select[1]=V(b,m,y,a),e.part2_3_length=a.bits),d.part2_3_length>e.part2_3_length&&d.assign(e))}}}; -var b=[1,1,1,1,8,2,2,2,4,4,4,8,8,8,16,16],v=[1,2,4,8,1,2,4,8,2,4,8,2,4,8,4,8],a=[0,0,0,0,3,1,1,1,2,2,2,3,3,3,4,4],m=[0,1,2,3,0,1,2,3,1,2,3,1,2,3,2,3];qb.slen1_tab=a;qb.slen2_tab=m;this.best_scalefac_store=function(d,e,p,l){var f=l.tt[e][p],g,h,r=0;for(g=h=0;gy&&0==f.l3_enc[y+h];y++);0==y&&(f.scalefac[g]=r=-2)}if(0==f.scalefac_scale&&0==f.preflag){for(g=h=0;g>=1);f.scalefac_scale=r=1}}if(0==f.preflag&&f.block_type!=c.SHORT_TYPE&&2==d.mode_gr){for(g=11;gg;g++)l.scfsi[p][g]=0;if(2==d.mode_gr&&1==e&&l.tt[0][p].block_type!=c.SHORT_TYPE&&l.tt[1][p].block_type!=c.SHORT_TYPE){e=l.tt[1][p];h=l.tt[0][p];for(r=0;rg;g++)-1!=e.scalefac[g]&&(l++,pr;r++)pg&&(e.part2_length=g,e.scalefac_compress=r));r=0}for(g=0;gd;d++)gm[d]&&(a.part2_length=m[d],a.scalefac_compress=d);return a.part2_length==ia.LARGE_BITS};var d=[[15,15,7,7],[15,15,7,0],[7,3,0,0],[15,31,31,0],[7,7,7,0],[3,3,0,0]];this.scale_bitcount_lsf=function(a,e){var b,f,l,m,h=X(4),x=e.scalefac;a=0!=e.preflag?2:0;for(l=0;4>l;l++)h[l]=0;if(e.block_type==c.SHORT_TYPE){var y=1;var k=B.nr_of_sfb_block[a][y]; -for(b=m=0;4>b;b++){var q=k[b]/3;for(l=0;lf;f++)x[3*m+f]>h[b]&&(h[b]=x[3*m+f])}}else for(y=0,k=B.nr_of_sfb_block[a][y],b=m=0;4>b;b++)for(q=k[b],l=0;lh[b]&&(h[b]=x[m]);q=!1;for(b=0;4>b;b++)h[b]>d[a][b]&&(q=!0);if(!q){e.sfb_partition_table=B.nr_of_sfb_block[a][y];for(b=0;4>b;b++)e.slen[b]=g[h[b]];y=e.slen[0];b=e.slen[1];h=e.slen[2];f=e.slen[3];switch(a){case 0:e.scalefac_compress=(5*y+b<<4)+(h<<2)+f;break;case 1:e.scalefac_compress=400+(5*y+b<<2)+h;break;case 2:e.scalefac_compress= -500+3*y+b;break;default:T.err.printf("intensity stereo not implemented yet\n")}}if(!q)for(b=e.part2_length=0;4>b;b++)e.part2_length+=e.slen[b]*e.sfb_partition_table[b];return q};var g=[0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4];this.huffman_init=function(a){for(var d=2;576>=d;d+=2){for(var e=0,b;a.scalefac_band.l[++e]d;)b--;0>b&&(b=ha[e][0]);a.bv_scf[d-2]=b;for(b=ha[e][1];a.scalefac_band.l[b+a.bv_scf[d-2]+2]>d;)b--;0>b&&(b=ha[e][1]);a.bv_scf[d-1]=b}}}function xc(){var c; -this.setModules=function(k){c=k};this.ResvFrameBegin=function(k,n){var u=k.internal_flags,E=u.l3_side,B=c.getframebits(k);n.bits=(B-8*u.sideinfo_len)/u.mode_gr;var w=2048*u.mode_gr-8;if(320w&&(u.ResvMax=w);if(0>u.ResvMax||k.disable_reservoir)u.ResvMax=0;k=n.bits*u.mode_gr+Math.min(u.ResvSize,u.ResvMax);k>f&&(k=f);E.resvDrain_pre=0;null!=u.pinfo&& -(u.pinfo.mean_bits=n.bits/2,u.pinfo.resvsize=u.ResvSize);return k};this.ResvMaxBits=function(c,n,u,E){var k=c.internal_flags,w=k.ResvSize,f=k.ResvMax;0!=E&&(w+=n);0!=(k.substep_shaping&1)&&(f*=.9);u.bits=n;10*w>9*f?(E=w-9*f/10,u.bits+=E,k.substep_shaping|=128):(E=0,k.substep_shaping&=127,c.disable_reservoir||0!=(k.substep_shaping&1)||(u.bits-=.1*n));c=w<6*k.ResvMax/10?w:6*k.ResvMax/10;c-=E;0>c&&(c=0);return c};this.ResvAdjust=function(c,n){c.ResvSize-=n.part2_3_length+n.part2_length};this.ResvFrameEnd= -function(c,n){var k,u=c.l3_side;c.ResvSize+=n*c.mode_gr;n=0;u.resvDrain_post=0;u.resvDrain_pre=0;0!=(k=c.ResvSize%8)&&(n+=k);k=c.ResvSize-n-c.ResvMax;0>b<> -3]|=d>>e<<8-(b&7)-h;b+=h}a.header[a.h_ptr].ptr=b}function V(a,d){a<<=8;for(var e=0;8>e;e++)a<<=1,d<<=1,0!=((d^a)&65536)&&(d^=32773);return d}function E(a,d){var e=w.ht[d.count1table_select+32],b,h=0,c=d.big_values,g=d.big_values;for(b=(d.count1-d.big_values)/4;0d.xr[g+0]&&l++);p=d.l3_enc[c+1];0!=p&&(f+=4,l*=2,0>d.xr[g+1]&&l++);p=d.l3_enc[c+2];0!=p&&(f+=2,l*=2,0>d.xr[g+2]&&l++);p=d.l3_enc[c+3];0!=p&&(f++,l*=2,0>d.xr[g+3]&&l++);c+=4;g+=4;u(a,l+e.table[f], -e.hlen[f]);h+=e.hlen[f]}return h}function B(a,d,e,b,h){var c=w.ht[d],g=0;if(0==d)return g;for(;eh.xr[e]&&m++,l--);15h.xr[e+1]&&m++,l--);C=C*r+k;f-=l;l+=c.hlen[C];u(a,c.table[C],l);u(a,m,f);g+=l+f}return g}function K(a,d){var e=3*a.scalefac_band.s[3];e>d.big_values&&(e=d.big_values);var b=B(a,d.table_select[0],0,e,d);return b+=B(a, -d.table_select[1],e,d.big_values,d)}function f(a,d){var e=d.big_values;var b=d.region0_count+1;var h=a.scalefac_band.l[b];b+=d.region1_count+1;var c=a.scalefac_band.l[b];h>e&&(h=e);c>e&&(c=e);b=B(a,d.table_select[0],0,h,d);b+=B(a,d.table_select[1],h,c,d);return b+=B(a,d.table_select[2],c,e,d)}function b(){this.total=0}function v(d,e){var b=d.internal_flags;var c=b.w_ptr;var h=b.h_ptr-1;-1==h&&(h=da.MAX_HEADER_BUF-1);var l=b.header[h].write_timing-g;e.total=l;if(0<=l){var f=1+h-c;hl&&T.err.println("strange error flushing buffer ... \n");return l}var a=this,m=null,z=null,e=null,l=null;this.setModules=function(a,d,b,c){m=a;z=d;e=b;l=c};var d=null,g=0,q=0,D=0;this.getframebits=function(a){var d=a.internal_flags;return 8*(0|72E3*(a.version+1)*(0!=d.bitrate_index?w.bitrate_table[a.version][d.bitrate_index]:a.brate)/a.out_samplerate+d.padding)};this.CRC_writeheader= -function(a,d){var e=V(d[2]&255,65535);e=V(d[3]&255,e);for(var b=6;b>8);d[5]=byte(e&255)};this.flush_bitstream=function(a){var d=a.internal_flags,e;var c=d.l3_side;0>(e=v(a,new b))||(k(a,e),d.ResvSize=0,c.main_data_begin=0,d.findReplayGain&&(c=m.GetTitleGain(d.rgdata),d.RadioGain=Math.floor(10*c+.5)|0),d.findPeakSample&&(d.noclipGainChange=Math.ceil(200*Math.log10(d.PeakSample/32767))|0,0>h<a.out_samplerate?n(h,4094,12):n(h,4095,12);n(h,a.version,1);n(h,1,2);n(h,a.error_protection?0:1,1);n(h,h.bitrate_index,4);n(h,h.samplerate_index,2);n(h,h.padding,1);n(h,a.extension,1);n(h,a.mode.ordinal(),2);n(h,h.mode_ext,2);n(h,a.copyright,1);n(h,a.original,1);n(h,a.emphasis,2);a.error_protection&&n(h,0,16);if(1==a.version){n(h,m.main_data_begin,9);2==h.channels_out?n(h,m.private_bits,3):n(h,m.private_bits,5);for(y=0;yp;p++)n(h,m.scfsi[y][p], -1);for(p=0;2>p;p++)for(y=0;ym;m++)for(y=0;yQ;Q++){var w=C.sfb_partition_table[Q]/3,Z=C.slen[Q];for(I=0;IQ;Q++)for(w=C.sfb_partition_table[Q],Z=C.slen[Q],I=0;I ResvSize");8*e.main_data_begin!=d.ResvSize&&(T.err.printf("bit reservoir error: \nl3_side.main_data_begin: %d \nResvoir size: %d \nresv drain (post) %d \nresv drain (pre) %d \nheader and sideinfo: %d \ndata bits: %d \ntotal bits: %d (remainder: %d) \nbitsperframe: %d \n", -8*e.main_data_begin,d.ResvSize,e.resvDrain_post,e.resvDrain_pre,8*d.sideinfo_len,h-e.resvDrain_post-8*d.sideinfo_len,h,h%8,l),T.err.println("This is a fatal error. It has several possible causes:"),T.err.println("90%% LAME compiled with buggy version of gcc using advanced optimizations"),T.err.println(" 9%% Your system is overclocked"),T.err.println(" 1%% bug in LAME encoding library"),d.ResvSize=8*e.main_data_begin);if(1E9=g)return 0;if(0!=c&&g>c)return-1;T.arraycopy(d,0,e,b,g);q=-1;D=0;if(0!=h&&(c=X(1),c[0]=a.nMusicCRC,l.updateMusicCRC(c,e,b,g),a.nMusicCRC=c[0],0a.PeakSample?a.PeakSample=c[0][p]:-c[0][p]>a.PeakSample&&(a.PeakSample=-c[0][p]);if(1< -a.channels_out)for(p=0;pa.PeakSample?a.PeakSample=c[1][p]:-c[1][p]>a.PeakSample&&(a.PeakSample=-c[1][p])}if(a.findReplayGain&&m.AnalyzeSamples(a.rgdata,c[0],0,c[1],0,f,a.channels_out)==Y.GAIN_ANALYSIS_ERROR)return-6}}return g};this.init_bit_stream_w=function(a){d=new Int8Array(W.LAME_MAXMP3BUFFER);a.h_ptr=a.w_ptr=0;a.header[a.h_ptr].write_timing=0;q=-1;g=D=0}}function zb(){function c(a,b){var d=a[b+0]&255;d=d<<8|a[b+1]&255;d=d<<8|a[b+2]&255;return d=d<<8|a[b+3]&255}function k(a,b,d){a[b+ -0]=d>>24&255;a[b+1]=d>>16&255;a[b+2]=d>>8&255;a[b+3]=d&255}function n(a,b,d){a[b+0]=d>>8&255;a[b+1]=d&255}function V(a,b,d){return 255&(a<a.out_samplerate?0:1);b[1]=V(b[1],1,a.version);b[1]=V(b[1],2,1);b[1]=V(b[1],1,a.error_protection?0:1);b[2]=V(b[2],4,d.bitrate_index);b[2]=V(b[2],2,d.samplerate_index);b[2]=V(b[2],1,0);b[2]=V(b[2],1,a.extension);b[3]=V(b[3],2,a.mode.ordinal());b[3]=V(b[3], -2,d.mode_ext);b[3]=V(b[3],1,a.copyright);b[3]=V(b[3],1,a.original);b[3]=V(b[3],2,a.emphasis);b[0]=255;d=b[1]&241;var e=1==a.version?128:16E3>a.out_samplerate?32:64;a.VBR==G.vbr_off&&(e=a.brate);e=a.free_format?0:255&16*K.BitrateIndex(e,a.version,a.out_samplerate);b[1]=1==a.version?255&(d|10):255&(d|2);d=b[2]&13;b[2]=255&(e|d)}function B(a,b){return b=b>>8^z[(b^a)&255]}var K,f,b;this.setModules=function(a,c,d){K=a;f=c;b=d};var v=zb.NUMTOCENTRIES,a=zb.MAXFRAMESIZE,m=v+4+4+4+4+4+9+1+1+8+1+1+3+1+1+2+ -4+2+2,z=[0,49345,49537,320,49921,960,640,49729,50689,1728,1920,51009,1280,50625,50305,1088,52225,3264,3456,52545,3840,53185,52865,3648,2560,51905,52097,2880,51457,2496,2176,51265,55297,6336,6528,55617,6912,56257,55937,6720,7680,57025,57217,8E3,56577,7616,7296,56385,5120,54465,54657,5440,55041,6080,5760,54849,53761,4800,4992,54081,4352,53697,53377,4160,61441,12480,12672,61761,13056,62401,62081,12864,13824,63169,63361,14144,62721,13760,13440,62529,15360,64705,64897,15680,65281,16320,16E3,65089,64001, -15040,15232,64321,14592,63937,63617,14400,10240,59585,59777,10560,60161,11200,10880,59969,60929,11968,12160,61249,11520,60865,60545,11328,58369,9408,9600,58689,9984,59329,59009,9792,8704,58049,58241,9024,57601,8640,8320,57409,40961,24768,24960,41281,25344,41921,41601,25152,26112,42689,42881,26432,42241,26048,25728,42049,27648,44225,44417,27968,44801,28608,28288,44609,43521,27328,27520,43841,26880,43457,43137,26688,30720,47297,47489,31040,47873,31680,31360,47681,48641,32448,32640,48961,32E3,48577, -48257,31808,46081,29888,30080,46401,30464,47041,46721,30272,29184,45761,45953,29504,45313,29120,28800,45121,20480,37057,37249,20800,37633,21440,21120,37441,38401,22208,22400,38721,21760,38337,38017,21568,39937,23744,23936,40257,24320,40897,40577,24128,23040,39617,39809,23360,39169,22976,22656,38977,34817,18624,18816,35137,19200,35777,35457,19008,19968,36545,36737,20288,36097,19904,19584,35905,17408,33985,34177,17728,34561,18368,18048,34369,33281,17088,17280,33601,16640,33217,32897,16448];this.addVbrFrame= -function(a){var b=a.internal_flags;var d=b.VBR_seek_table;a=w.bitrate_table[a.version][b.bitrate_index];d.nVbrNumFrames++;d.sum+=a;d.seen++;if(!(d.seen>3&1,f=a[d+2]>>2&3,m=a[d+3]>>6&3,p=a[d+2]>>4&15;p=w.bitrate_table[e][p];b.samprate=14==a[d+1]>>4?w.samplerate_table[2][f]:w.samplerate_table[e][f]; -f=d=0!=e?3!=m?d+36:d+21:3!=m?d+21:d+13;if(!(new String(a,f,4(),null)).equals("Xing")&&!(new String(a,f,4(),null)).equals("Info"))return null;d+=4;b.hId=e;f=b.flags=c(a,d);d+=4;0!=(f&1)&&(b.frames=c(a,d),d+=4);0!=(f&2)&&(b.bytes=c(a,d),d+=4);if(0!=(f&4)){if(null!=b.toc)for(m=0;m>4;p=(a[d+1]&15)<<8;p+=a[d+2]&255;if(0>e||3E3p||3E3b.out_samplerate?32:64;b.VBR==G.vbr_off&&(d=b.brate);d=72E3*(b.version+1)*d/b.out_samplerate;var c=e.sideinfo_len+m;e.VBR_seek_table.TotalFrameSize=d;if(da)b.bWriteVbrTag=!1;else for(e.VBR_seek_table.nVbrNumFrames=0,e.VBR_seek_table.nBytesWritten=0,e.VBR_seek_table.sum=0,e.VBR_seek_table.seen=0,e.VBR_seek_table.want=1,e.VBR_seek_table.pos=0,null==e.VBR_seek_table.bag&&(e.VBR_seek_table.bag= -new int[400],e.VBR_seek_table.size=400),d=new Int8Array(a),E(b,d),e=e.VBR_seek_table.TotalFrameSize,c=0;c=d.VBR_seek_table.pos)return 0;if(c.length=m.pos))for(l=1;lm.pos-1&&(p=m.pos-1);p=0|256*m.bag[p]/m.sum;255t.RadioGain&&(t.RadioGain=-510),w=11264,w=0<=t.RadioGain?w|t.RadioGain:w|512|-t.RadioGain);t.findPeakSample&&(z=Math.abs(0|t.PeakSample/32767*Math.pow(2,23)+.5));-1!=ma&&(0h&&(h=0);switch(a.mode){case MONO:Q=0;break;case STEREO:Q=1;break; -case DUAL_CHANNEL:Q=2;break;case JOINT_STEREO:Q=a.force_ms?4:3;break;default:Q=7}C=32E3>=a.in_samplerate?0:48E3==a.in_samplerate?2:48E3a.scale_right||a.disable_reservoir&&320>a.brate||a.noATH||a.ATHonly||0==L||32E3>=a.in_samplerate)F=1;O=O+(Q<<2)+(F<<5)+(C<<6);t=t.nMusicCRC;k(c,e+p,h);p+=4;for(h=0;9>h;h++)c[e+p+h]= -255&x.charAt(h);p+=9;c[e+p]=255&y;p++;c[e+p]=255&A;p++;k(c,e+p,z);p+=4;n(c,e+p,w);p+=2;n(c,e+p,0);p+=2;c[e+p]=255&I;p++;c[e+p]=255<=V?255:255&V;p++;c[e+p]=255&r>>4;c[e+p+1]=255&(r<<4)+(u>>8);c[e+p+2]=255&u;p+=3;c[e+p]=255&O;p++;c[e+p++]=0;n(c,e+p,a.preset);p+=2;k(c,e+p,m);p+=4;n(c,e+p,t);p+=2;for(a=0;a=b.internal_flags.VBR_seek_table.pos)return-1;c.seek(c.length());if(0==c.length())return-1;c.seek(0); -var d=new Int8Array(10);c.readFully(d);d=(new String(d,"ISO-8859-1")).startsWith("ID3")?0:((d[6]&127)<<21|(d[7]&127)<<14|(d[8]&127)<<7|d[9]&127)+d.length;c.seek(d);d=new Int8Array(a);b=getLameTagFrame(b,d);if(b>d.length)return-1;if(1>b)return 0;c.write(d,0,b);return 0}}function U(c,k,n,w){this.xlen=c;this.linmax=k;this.table=n;this.hlen=w}function xa(c){this.bits=c}function yc(){this.setModules=function(c,k){}}function sb(){this.bits=this.over_SSD=this.over_count=this.max_noise=this.tot_noise=this.over_noise= -0}function zc(){this.scale_right=this.scale_left=this.scale=this.out_samplerate=this.in_samplerate=this.num_channels=this.num_samples=this.class_id=0;this.decode_only=this.bWriteVbrTag=this.analysis=!1;this.quality=0;this.mode=la.STEREO;this.write_id3tag_automatic=this.decode_on_the_fly=this.findReplayGain=this.free_format=this.force_ms=!1;this.error_protection=this.emphasis=this.extension=this.original=this.copyright=this.compression_ratio=this.brate=0;this.disable_reservoir=this.strict_ISO=!1;this.quant_comp_short= -this.quant_comp=0;this.experimentalY=!1;this.preset=this.exp_nspsytune=this.experimentalZ=0;this.VBR=null;this.maskingadjust_short=this.maskingadjust=this.highpasswidth=this.lowpasswidth=this.highpassfreq=this.lowpassfreq=this.VBR_hard_min=this.VBR_max_bitrate_kbps=this.VBR_min_bitrate_kbps=this.VBR_mean_bitrate_kbps=this.VBR_q=this.VBR_q_frac=0;this.noATH=this.ATHshort=this.ATHonly=!1;this.athaa_sensitivity=this.athaa_loudapprox=this.athaa_type=this.ATHlower=this.ATHcurve=this.ATHtype=0;this.short_blocks= -null;this.useTemporal=!1;this.msfix=this.interChRatio=0;this.tune=!1;this.lame_allocated_gfp=this.frameNum=this.framesize=this.encoder_padding=this.encoder_delay=this.version=this.tune_value_a=0;this.internal_flags=null}function Ac(){this.linprebuf=K(2*Y.MAX_ORDER);this.linpre=0;this.lstepbuf=K(Y.MAX_SAMPLES_PER_WINDOW+Y.MAX_ORDER);this.lstep=0;this.loutbuf=K(Y.MAX_SAMPLES_PER_WINDOW+Y.MAX_ORDER);this.lout=0;this.rinprebuf=K(2*Y.MAX_ORDER);this.rinpre=0;this.rstepbuf=K(Y.MAX_SAMPLES_PER_WINDOW+Y.MAX_ORDER); -this.rstep=0;this.routbuf=K(Y.MAX_SAMPLES_PER_WINDOW+Y.MAX_ORDER);this.first=this.freqindex=this.rsum=this.lsum=this.totsamp=this.sampleWindow=this.rout=0;this.A=X(0|Y.STEPS_per_dB*Y.MAX_dB);this.B=X(0|Y.STEPS_per_dB*Y.MAX_dB)}function Bc(u){this.quantize=u;this.iteration_loop=function(k,n,u,w){var B=k.internal_flags,E=K(sa.SFBMAX),f=K(576),b=X(2),v=B.l3_side;var a=new xa(0);this.quantize.rv.ResvFrameBegin(k,a);a=a.bits;for(var m=0;m>2&63;32<=d&&(d-=64);g=Math.pow(10,d/4/10);d=b.exp_nspsytune>>8&63;32<=d&&(d-=64);q=Math.pow(10,d/4/10);d=b.exp_nspsytune>>14&63;32<=d&&(d-=64);k= -Math.pow(10,d/4/10);d=b.exp_nspsytune>>20&63;32<=d&&(d-=64);b=k*Math.pow(10,d/4/10);for(d=0;d=d?g:13>=d?q:20>=d?k:b,e.nsPsy.longfact[d]=p;for(d=0;d=d?g:10>=d?q:11>=d?k:b,e.nsPsy.shortfact[d]=p}};this.on_pe=function(a,b,d,c,f,m){var e=a.internal_flags,g=0,l=X(2),q;g=new xa(g);a=w.ResvMaxBits(a,c,g,m);g=g.bits;var h=g+a;h>da.MAX_BITS_PER_GRANULE&&(h=da.MAX_BITS_PER_GRANULE);for(q=m=0;q3*c/4&&(l[q]=3*c/4),0>l[q]&&(l[q]=0),l[q]+d[q]>da.MAX_BITS_PER_CHANNEL&&(l[q]=Math.max(0,da.MAX_BITS_PER_CHANNEL-d[q])),m+=l[q];if(m>a)for(q=0;qda.MAX_BITS_PER_GRANULE)for(q=0;qb&&(b=0);.5da.MAX_BITS_PER_CHANNEL- -a[0]&&(b=da.MAX_BITS_PER_CHANNEL-a[0]);0>b&&(b=0);125<=a[1]&&(125c&&(a[0]=c*a[0]/b,a[1]=c*a[1]/b)};this.athAdjust=function(a,b,d){b=aa.FAST_LOG10_X(b,10);a*=a;var c=0;b-=d;1E-20c&&(c=0);return Math.pow(10,.1*(b*c+(d+90.30873362-94.82444863)))};this.calc_xmin=function(a,b,d,f){var e=0,g=a.internal_flags,m,l=0,k=0,v=g.ATH,h=d.xr,x=a.VBR==G.vbr_mtrh?1:0,y=g.masking_lower;if(a.VBR== -G.vbr_mtrh||a.VBR==G.vbr_mt)y=1;for(m=0;m>1;var C=0;do{var I=h[l]*h[l];C+=I;B+=IA&&k++;m==c.SBPSY_l&&(u=A*g.nsPsy.longfact[m],BS;S++){C=0;z=n>>1;u=w/n;B=2.220446049250313E-16;do I=h[l]*h[l],C+=I,B+=Iw&&k++;Q==c.SBPSY_s&&(u=w*g.nsPsy.shortfact[Q],Bf[e-3+1]&&(f[e-3+1]+=(f[e-3]-f[e-3+1])*g.decay),f[e-3+1]>f[e-3+2]&&(f[e-3+2]+=(f[e-3+1]-f[e-3+2])*g.decay))}return k};this.calc_noise_core=function(a,b,d,c){var e=0,f=b.s,g=a.l3_enc;if(f>a.count1)for(;0!=d--;){var l=a.xr[f];f++;e+=l*l;l=a.xr[f];f++;e+=l*l}else if(f>a.big_values){var k=K(2);k[0]=0;for(k[1]=c;0!=d--;)l=Math.abs(a.xr[f])-k[g[f]],f++,e+=l*l,l=Math.abs(a.xr[f])- -k[g[f]],f++,e+=l*l}else for(;0!=d--;)l=Math.abs(a.xr[f])-m[g[f]]*c,f++,e+=l*l,l=Math.abs(a.xr[f])-m[g[f]]*c,f++,e+=l*l;b.s=f;return e};this.calc_noise=function(a,c,d,f,m){var e=0,g=0,l,q=0,u=0,h=0,x=-20,y=0,A=a.scalefac,n=0;for(l=f.over_SSD=0;l>1;y+a.width[l]> -a.max_nonzero_coeff&&(w=a.max_nonzero_coeff-y+1,w=0>1:0);y=new k(y);z=this.calc_noise_core(a,y,w,z);y=y.s;null!=m&&(m.step[l]=B,m.noise[l]=z);z=d[e++]=z/c[g++];z=aa.FAST_LOG10(Math.max(z,1E-20));null!=m&&(m.noise_log[l]=z)}null!=m&&(m.global_gain=a.global_gain);h+=z;0I;I++){k=0;for(C=B;Cf;++f){var a=c.tt[b][0].xr[f],m=c.tt[b][1].xr[f];c.tt[b][0].xr[f]=.5*(a+m)*aa.SQRT2; -c.tt[b][1].xr[f]=.5*(a-m)*aa.SQRT2}};this.init_xrpow=function(c,b,k){var a=0|b.max_nonzero_coeff;b.xrpow_max=0;na.fill(k,a,576,0);for(var f,v=f=0;v<=a;++v){var e=Math.abs(b.xr[v]);f+=e;k[v]=Math.sqrt(e*Math.sqrt(e));k[v]>b.xrpow_max&&(b.xrpow_max=k[v])}if(1E-20l;l++)for(var d=n;d=n;e--)if(Math.abs(a[e])l;l++)for(b=!1,m=c.PSFB12-1;0<=m&&!b;m--)for(n=3*f.scalefac_band.s[12]+(f.scalefac_band.s[13]-f.scalefac_band.s[12])*l+(f.scalefac_band.psfb12[m]-f.scalefac_band.psfb12[0]),e=n+(f.scalefac_band.psfb12[m+1]-f.scalefac_band.psfb12[m]),d=E.athAdjust(k.adjust,k.psfb12[m],k.floor),1E-12=n;e--)if(Math.abs(a[e])n;n++){var e=0;0!=b.l3_enc[n]&&(e=Math.abs(b.xr[n]));a[n]=e}n=0;e=8;b.block_type==c.SHORT_TYPE&&(e=6);do{var l,d,g=b.width[e];n+=g;if(!(1<=m[e]||(na.sort(a,n-g,g),qa.EQ(a[n-1],0)))){var q=(1-m[e])*k[e];var v=l=0;do{for(d= -1;v+dh?(z==u.BINSEARCH_DOWN&&(y=!0),y&&(x/=2),z=u.BINSEARCH_UP,H=x):(z==u.BINSEARCH_UP&&(y=!0),y&&(x/=2),z=u.BINSEARCH_DOWN,H=-x);b.global_gain+=H;0>b.global_gain&&(b.global_gain=0,y=!0);255h&&255>b.global_gain;)b.global_gain++,H=ha.count_bits(e,a,b,null);e.CurrentStep[m]=4<=A-b.global_gain?4:2;e.OldValue[m]=b.global_gain;b.part2_3_length=H;if(0==e.noise_shaping)return 100;E.calc_noise(b,n,g,q,v);q.bits=b.part2_3_length; -l.assign(b);m=0;for(T.arraycopy(a,0,d,0,576);!r;){do{h=new sb;y=255;x=0!=(e.substep_shaping&2)?20:3;if(e.sfb21_extra){if(1L;L++)C[Z+L]*=Q,C[Z+L]>O.xrpow_max&&(O.xrpow_max=C[Z+L]);if(2==I.noise_shaping_amp)break}}if(Q=k(A))A=!1;else if(Q=2==z.mode_gr?ha.scale_bitcount(A):ha.scale_bitcount_lsf(z,A)){if(1I;I++)H[O+I]*=1.2968395546510096,H[O+I]>Q.xrpow_max&&(Q.xrpow_max=H[O+I]);Q.scalefac[F]=C>>1}Q.preflag=0;Q.scalefac_scale=1;Q=!1}else if(A.block_type==c.SHORT_TYPE&&0I;I++){ma=S=0;for(H=O.sfb_lmax+I;HS&&8>ma)){if(7<=O.subblock_gain[I]){H= -!0;break b}O.subblock_gain[I]++;S=Q.scalefac_band.l[O.sfb_lmax];for(H=O.sfb_lmax+I;H>O.scalefac_scale,0<=Z)C[H]=Z,S+=3*ma;else{C[H]=0;Z=E.IPOW20(210+(Z<L;L++)F[S+L]*=Z,F[S+L]>O.xrpow_max&&(O.xrpow_max=F[S+L]);S+=ma*(3-I-1)}Z=E.IPOW20(202);S+=O.width[H]*(I+1);for(L=-O.width[H];0>L;L++)F[S+L]*=Z,F[S+L]>O.xrpow_max&&(O.xrpow_max=F[S+L])}}H=!1}Q=H||k(A)}Q||(Q=2==z.mode_gr?ha.scale_bitcount(A):ha.scale_bitcount_lsf(z, -A));A=!Q}else A=!0;if(!A)break;0!=l.scalefac_scale&&(y=254);A=B-l.part2_length;if(0>=A)break;for(;(l.part2_3_length=ha.count_bits(e,a,l,v))>A&&l.global_gain<=y;)l.global_gain++;if(l.global_gain>y)break;if(0==q.over_count){for(;(l.part2_3_length=ha.count_bits(e,a,l,v))>p&&l.global_gain<=y;)l.global_gain++;if(l.global_gain>y)break}E.calc_noise(l,n,g,h,v);h.bits=l.part2_3_length;z=b.block_type!=c.SHORT_TYPE?f.quant_comp:f.quant_comp_short;y=q;A=h;Q=l;H=g;switch(z){default:case 9:0A.max_noise&&10*A.max_noise+A.bits<=10*y.max_noise+y.bits;break;case 0:z=A.over_count=A.max_noise&&.2=A.max_noise&&0>y.max_noise&&y.max_noise>A.max_noise-.2&&A.tot_noise=A.max_noise&&0A.max_noise-.2&&A.tot_noiseA.max_noise-.1&&A.tot_noise+A.over_noiseA.max_noise-.15&&A.tot_noise+A.over_noise+A.over_noisex&&0== -q.over_count)break;if(3==e.noise_shaping_amp&&t&&30l.global_gain+l.scalefac_scale);3==e.noise_shaping_amp?t?r=!0:(l.assign(b),T.arraycopy(d,0,a,0,576),m=0,w=l.global_gain,t=!0):r=!0}f.VBR==G.vbr_rh||f.VBR==G.vbr_mtrh?T.arraycopy(d,0,a,0,576):0!=(e.substep_shaping&1)&&trancate_smallspectrums(e,b,n,a);return q.over_count};this.iteration_finish_one=function(c,b,k){var a=c.l3_side,f=a.tt[b][k];ha.best_scalefac_store(c,b,k,a);1== -c.use_best_huffman&&ha.best_huffman_divide(c,f);w.ResvAdjust(c,f)};this.VBR_encode_granule=function(c,b,k,a,m,n,e){var f=c.internal_flags,d=new rb,g=K(576),q=e,v=(e+n)/2,p=0,r=f.sfb21_extra;na.fill(d.l3_enc,0);do{f.sfb21_extra=v>q-42?!1:r;var t=outer_loop(c,b,k,a,m,v);0>=t?(p=1,e=b.part2_3_length,d.assign(b),T.arraycopy(a,0,g,0,576),e-=32,t=e-n,v=(e+n)/2):(n=v+32,t=e-n,v=(e+n)/2,0!=p&&(p=2,b.assign(d),T.arraycopy(g,0,a,0,576)))}while(12n[g.VBR_max_bitrate]&& -(l[r][t]*=n[g.VBR_max_bitrate],l[r][t]/=v),e[r][t]>l[r][t]&&(e[r][t]=l[r][t]);return q};this.bitpressure_strategy=function(f,b,k,a){for(var m=0;mq&&(n[m][v]*=q,n[m][v]/=g);return l};this.calc_target_bits=function(f,b,k,a,m,u){var e=f.internal_flags,l=e.l3_side;e.bitrate_index=e.VBR_max_bitrate;var d=new xa(0);u[0]=w.ResvFrameBegin(f,d);e.bitrate_index=1;d=n.getframebits(f)-8*e.sideinfo_len;m[0]=d/(e.mode_gr*e.channels_out);d=f.VBR_mean_bitrate_kbps*f.framesize*1E3;0!=(e.substep_shaping&1)&&(d*=1.09);d/=f.out_samplerate; -d-=8*e.sideinfo_len;d/=e.mode_gr*e.channels_out;var g=.93+.07*(11-f.compression_ratio)/5.5;.9>g&&(g=.9);13*d/2?v=3*d/2:0>v&&(v=0);a[f][m]+=v}a[f][m]>da.MAX_BITS_PER_CHANNEL&&(a[f][m]=da.MAX_BITS_PER_CHANNEL);q+=a[f][m]}if(q>da.MAX_BITS_PER_GRANULE)for(m=0;mda.MAX_BITS_PER_CHANNEL&&(a[f][m]=da.MAX_BITS_PER_CHANNEL),b+=a[f][m];if(b>u[0])for(f=0;fe;e++){var l=k[f+-10];var d=b[n+-224]*l;var g=b[c+224]*l;l=k[f+-9];d+=b[n+-160]* -l;g+=b[c+160]*l;l=k[f+-8];d+=b[n+-96]*l;g+=b[c+96]*l;l=k[f+-7];d+=b[n+-32]*l;g+=b[c+32]*l;l=k[f+-6];d+=b[n+32]*l;g+=b[c+-32]*l;l=k[f+-5];d+=b[n+96]*l;g+=b[c+-96]*l;l=k[f+-4];d+=b[n+160]*l;g+=b[c+-160]*l;l=k[f+-3];d+=b[n+224]*l;g+=b[c+-224]*l;l=k[f+-2];d+=b[c+-256]*l;g-=b[n+256]*l;l=k[f+-1];d+=b[c+-192]*l;g-=b[n+192]*l;l=k[f+0];d+=b[c+-128]*l;g-=b[n+128]*l;l=k[f+1];d+=b[c+-64]*l;g-=b[n+64]*l;l=k[f+2];d+=b[c+0]*l;g-=b[n+0]*l;l=k[f+3];d+=b[c+64]*l;g-=b[n+-64]*l;l=k[f+4];d+=b[c+128]*l;g-=b[n+-128]*l; -l=k[f+5];d+=b[c+192]*l;g-=b[n+-192]*l;d*=k[f+6];l=g-d;a[30+2*e]=g+d;a[31+2*e]=k[f+7]*l;f+=18;c--;n++}g=b[c+-16]*k[f+-10];d=b[c+-32]*k[f+-2];g+=(b[c+-48]-b[c+16])*k[f+-9];d+=b[c+-96]*k[f+-1];g+=(b[c+-80]+b[c+48])*k[f+-8];d+=b[c+-160]*k[f+0];g+=(b[c+-112]-b[c+80])*k[f+-7];d+=b[c+-224]*k[f+1];g+=(b[c+-144]+b[c+112])*k[f+-6];d-=b[c+32]*k[f+2];g+=(b[c+-176]-b[c+144])*k[f+-5];d-=b[c+96]*k[f+3];g+=(b[c+-208]+b[c+176])*k[f+-4];d-=b[c+160]*k[f+4];g+=(b[c+-240]-b[c+208])*k[f+-3];d-=b[c+224];b=d-g;c=d+g;g=a[14]; -d=a[15]-g;a[31]=c+g;a[30]=b+d;a[15]=b-d;a[14]=c-g;d=a[28]-a[0];a[0]+=a[28];a[28]=d*k[f+-36+7];d=a[29]-a[1];a[1]+=a[29];a[29]=d*k[f+-36+7];d=a[26]-a[2];a[2]+=a[26];a[26]=d*k[f+-72+7];d=a[27]-a[3];a[3]+=a[27];a[27]=d*k[f+-72+7];d=a[24]-a[4];a[4]+=a[24];a[24]=d*k[f+-108+7];d=a[25]-a[5];a[5]+=a[25];a[25]=d*k[f+-108+7];d=a[22]-a[6];a[6]+=a[22];a[22]=d*aa.SQRT2;d=a[23]-a[7];a[7]+=a[23];a[23]=d*aa.SQRT2-a[7];a[7]-=a[6];a[22]-=a[7];a[23]-=a[22];d=a[6];a[6]=a[31]-d;a[31]+=d;d=a[7];a[7]=a[30]-d;a[30]+=d;d= -a[22];a[22]=a[15]-d;a[15]+=d;d=a[23];a[23]=a[14]-d;a[14]+=d;d=a[20]-a[8];a[8]+=a[20];a[20]=d*k[f+-180+7];d=a[21]-a[9];a[9]+=a[21];a[21]=d*k[f+-180+7];d=a[18]-a[10];a[10]+=a[18];a[18]=d*k[f+-216+7];d=a[19]-a[11];a[11]+=a[19];a[19]=d*k[f+-216+7];d=a[16]-a[12];a[12]+=a[16];a[16]=d*k[f+-252+7];d=a[17]-a[13];a[13]+=a[17];a[17]=d*k[f+-252+7];d=-a[20]+a[24];a[20]+=a[24];a[24]=d*k[f+-216+7];d=-a[21]+a[25];a[21]+=a[25];a[25]=d*k[f+-216+7];d=a[4]-a[8];a[4]+=a[8];a[8]=d*k[f+-216+7];d=a[5]-a[9];a[5]+=a[9];a[9]= -d*k[f+-216+7];d=a[0]-a[12];a[0]+=a[12];a[12]=d*k[f+-72+7];d=a[1]-a[13];a[1]+=a[13];a[13]=d*k[f+-72+7];d=a[16]-a[28];a[16]+=a[28];a[28]=d*k[f+-72+7];d=-a[17]+a[29];a[17]+=a[29];a[29]=d*k[f+-72+7];d=aa.SQRT2*(a[2]-a[10]);a[2]+=a[10];a[10]=d;d=aa.SQRT2*(a[3]-a[11]);a[3]+=a[11];a[11]=d;d=aa.SQRT2*(-a[18]+a[26]);a[18]+=a[26];a[26]=d-a[18];d=aa.SQRT2*(-a[19]+a[27]);a[19]+=a[27];a[27]=d-a[19];d=a[2];a[19]-=a[3];a[3]-=d;a[2]=a[31]-d;a[31]+=d;d=a[3];a[11]-=a[19];a[18]-=d;a[3]=a[30]-d;a[30]+=d;d=a[18];a[27]-= -a[11];a[19]-=d;a[18]=a[15]-d;a[15]+=d;d=a[19];a[10]-=d;a[19]=a[14]-d;a[14]+=d;d=a[10];a[11]-=d;a[10]=a[23]-d;a[23]+=d;d=a[11];a[26]-=d;a[11]=a[22]-d;a[22]+=d;d=a[26];a[27]-=d;a[26]=a[7]-d;a[7]+=d;d=a[27];a[27]=a[6]-d;a[6]+=d;d=aa.SQRT2*(a[0]-a[4]);a[0]+=a[4];a[4]=d;d=aa.SQRT2*(a[1]-a[5]);a[1]+=a[5];a[5]=d;d=aa.SQRT2*(a[16]-a[20]);a[16]+=a[20];a[20]=d;d=aa.SQRT2*(a[17]-a[21]);a[17]+=a[21];a[21]=d;d=-aa.SQRT2*(a[8]-a[12]);a[8]+=a[12];a[12]=d-a[8];d=-aa.SQRT2*(a[9]-a[13]);a[9]+=a[13];a[13]=d-a[9];d= --aa.SQRT2*(a[25]-a[29]);a[25]+=a[29];a[29]=d-a[25];d=-aa.SQRT2*(a[24]+a[28]);a[24]-=a[28];a[28]=d-a[24];d=a[24]-a[16];a[24]=d;d=a[20]-d;a[20]=d;d=a[28]-d;a[28]=d;d=a[25]-a[17];a[25]=d;d=a[21]-d;a[21]=d;d=a[29]-d;a[29]=d;d=a[17]-a[1];a[17]=d;d=a[9]-d;a[9]=d;d=a[25]-d;a[25]=d;d=a[5]-d;a[5]=d;d=a[21]-d;a[21]=d;d=a[13]-d;a[13]=d;d=a[29]-d;a[29]=d;d=a[1]-a[0];a[1]=d;d=a[16]-d;a[16]=d;d=a[17]-d;a[17]=d;d=a[8]-d;a[8]=d;d=a[9]-d;a[9]=d;d=a[24]-d;a[24]=d;d=a[25]-d;a[25]=d;d=a[4]-d;a[4]=d;d=a[5]-d;a[5]=d;d= -a[20]-d;a[20]=d;d=a[21]-d;a[21]=d;d=a[12]-d;a[12]=d;d=a[13]-d;a[13]=d;d=a[28]-d;a[28]=d;d=a[29]-d;a[29]=d;d=a[0];a[0]+=a[31];a[31]-=d;d=a[1];a[1]+=a[30];a[30]-=d;d=a[16];a[16]+=a[15];a[15]-=d;d=a[17];a[17]+=a[14];a[14]-=d;d=a[8];a[8]+=a[23];a[23]-=d;d=a[9];a[9]+=a[22];a[22]-=d;d=a[24];a[24]+=a[7];a[7]-=d;d=a[25];a[25]+=a[6];a[6]-=d;d=a[4];a[4]+=a[27];a[27]-=d;d=a[5];a[5]+=a[26];a[26]-=d;d=a[20];a[20]+=a[11];a[11]-=d;d=a[21];a[21]+=a[10];a[10]-=d;d=a[12];a[12]+=a[19];a[19]-=d;d=a[13];a[13]+=a[18]; -a[18]-=d;d=a[28];a[28]+=a[3];a[3]-=d;d=a[29];a[29]+=a[2];a[2]-=d}var k=[-.1482523854003001,32.308141959636465,296.40344946382766,883.1344870032432,11113.947376231741,1057.2713659324597,305.7402417275812,30.825928907280012,3.8533188138216365,59.42900443849514,709.5899960123345,5281.91112291017,-5829.66483675846,-817.6293103748613,-76.91656988279972,-4.594269939176596,.9063471690191471,.1960342806591213,-.15466694054279598,34.324387823855965,301.8067566458425,817.599602898885,11573.795901679885,1181.2520595540152, -321.59731579894424,31.232021761053772,3.7107095756221318,53.650946155329365,684.167428119626,5224.56624370173,-6366.391851890084,-908.9766368219582,-89.83068876699639,-5.411397422890401,.8206787908286602,.3901806440322567,-.16070888947830023,36.147034243915876,304.11815768187864,732.7429163887613,11989.60988270091,1300.012278487897,335.28490093152146,31.48816102859945,3.373875931311736,47.232241542899175,652.7371796173471,5132.414255594984,-6909.087078780055,-1001.9990371107289,-103.62185754286375, --6.104916304710272,.7416505462720353,.5805693545089249,-.16636367662261495,37.751650073343995,303.01103387567713,627.9747488785183,12358.763425278165,1412.2779918482834,346.7496836825721,31.598286663170416,3.1598635433980946,40.57878626349686,616.1671130880391,5007.833007176154,-7454.040671756168,-1095.7960341867115,-118.24411666465777,-6.818469345853504,.6681786379192989,.7653668647301797,-.1716176790982088,39.11551877123304,298.3413246578966,503.5259106886539,12679.589408408976,1516.5821921214542, -355.9850766329023,31.395241710249053,2.9164211881972335,33.79716964664243,574.8943997801362,4853.234992253242,-7997.57021486075,-1189.7624067269965,-133.6444792601766,-7.7202770609839915,.5993769336819237,.9427934736519954,-.17645823955292173,40.21879108166477,289.9982036694474,359.3226160751053,12950.259102786438,1612.1013903507662,362.85067106591504,31.045922092242872,2.822222032597987,26.988862316190684,529.8996541764288,4671.371946949588,-8535.899136645805,-1282.5898586244496,-149.58553632943463, --8.643494270763135,.5345111359507916,1.111140466039205,-.36174739330527045,41.04429910497807,277.5463268268618,195.6386023135583,13169.43812144731,1697.6433561479398,367.40983966190305,30.557037410382826,2.531473372857427,20.070154905927314,481.50208566532336,4464.970341588308,-9065.36882077239,-1373.62841526722,-166.1660487028118,-9.58289321133207,.4729647758913199,1.268786568327291,-.36970682634889585,41.393213350082036,261.2935935556502,12.935476055240873,13336.131683328815,1772.508612059496,369.76534388639965, -29.751323653701338,2.4023193045459172,13.304795348228817,430.5615775526625,4237.0568611071185,-9581.931701634761,-1461.6913552409758,-183.12733958476446,-10.718010163869403,.41421356237309503,1.414213562373095,-.37677560326535325,41.619486213528496,241.05423794991074,-187.94665032361226,13450.063605744153,1836.153896465782,369.4908799925761,29.001847876923147,2.0714759319987186,6.779591200894186,377.7767837205709,3990.386575512536,-10081.709459700915,-1545.947424837898,-200.3762958015653,-11.864482073055006, -.3578057213145241,1.546020906725474,-.3829366947518991,41.1516456456653,216.47684307105183,-406.1569483347166,13511.136535077321,1887.8076599260432,367.3025214564151,28.136213436723654,1.913880671464418,.3829366947518991,323.85365704338597,3728.1472257487526,-10561.233882199509,-1625.2025997821418,-217.62525175416,-13.015432208941645,.3033466836073424,1.66293922460509,-.5822628872992417,40.35639251440489,188.20071124269245,-640.2706748618148,13519.21490106562,1927.6022433578062,362.8197642637487, -26.968821921868447,1.7463817695935329,-5.62650678237171,269.3016715297017,3453.386536448852,-11016.145278780888,-1698.6569643425091,-234.7658734267683,-14.16351421663124,.2504869601913055,1.76384252869671,-.5887180101749253,39.23429103868072,155.76096234403798,-889.2492977967378,13475.470561874661,1955.0535223723712,356.4450994756727,25.894952980042156,1.5695032905781554,-11.181939564328772,214.80884394039484,3169.1640829158237,-11443.321309975563,-1765.1588461316153,-251.68908574481912,-15.49755935939164, -.198912367379658,1.847759065022573,-.7912582233652842,37.39369355329111,119.699486012458,-1151.0956593239027,13380.446257078214,1970.3952110853447,348.01959814116185,24.731487364283044,1.3850130831637748,-16.421408865300393,161.05030052864092,2878.3322807850063,-11838.991423510031,-1823.985884688674,-268.2854986386903,-16.81724543849939,.1483359875383474,1.913880671464418,-.7960642926861912,35.2322109610459,80.01928065061526,-1424.0212633405113,13235.794061869668,1973.804052543835,337.9908651258184, -23.289159354463873,1.3934255946442087,-21.099669467133474,108.48348407242611,2583.700758091299,-12199.726194855148,-1874.2780658979746,-284.2467154529415,-18.11369784385905,.09849140335716425,1.961570560806461,-.998795456205172,32.56307803611191,36.958364584370486,-1706.075448829146,13043.287458812016,1965.3831106103316,326.43182772364605,22.175018750622293,1.198638339011324,-25.371248002043963,57.53505923036915,2288.41886619975,-12522.674544337233,-1914.8400385312243,-299.26241273417224,-19.37805630698734, -.04912684976946725,1.990369453344394,.0178904535*aa.SQRT2/2.384E-6,.008938074*aa.SQRT2/2.384E-6,.0015673635*aa.SQRT2/2.384E-6,.001228571*aa.SQRT2/2.384E-6,4.856585E-4*aa.SQRT2/2.384E-6,1.09434E-4*aa.SQRT2/2.384E-6,5.0783E-5*aa.SQRT2/2.384E-6,6.914E-6*aa.SQRT2/2.384E-6,12804.797818791945,1945.5515939597317,313.4244966442953,20.801593959731544,1995.1556208053692,9.000838926174497,-29.20218120805369],n=[[2.382191739347913E-13,6.423305872147834E-13,9.400849094049688E-13,1.122435026096556E-12,1.183840321267481E-12, -1.122435026096556E-12,9.40084909404969E-13,6.423305872147839E-13,2.382191739347918E-13,5.456116108943412E-12,4.878985199565852E-12,4.240448995017367E-12,3.559909094758252E-12,2.858043359288075E-12,2.156177623817898E-12,1.475637723558783E-12,8.371015190102974E-13,2.599706096327376E-13,-5.456116108943412E-12,-4.878985199565852E-12,-4.240448995017367E-12,-3.559909094758252E-12,-2.858043359288076E-12,-2.156177623817898E-12,-1.475637723558783E-12,-8.371015190102975E-13,-2.599706096327376E-13,-2.382191739347923E-13, --6.423305872147843E-13,-9.400849094049696E-13,-1.122435026096556E-12,-1.183840321267481E-12,-1.122435026096556E-12,-9.400849094049694E-13,-6.42330587214784E-13,-2.382191739347918E-13],[2.382191739347913E-13,6.423305872147834E-13,9.400849094049688E-13,1.122435026096556E-12,1.183840321267481E-12,1.122435026096556E-12,9.400849094049688E-13,6.423305872147841E-13,2.382191739347918E-13,5.456116108943413E-12,4.878985199565852E-12,4.240448995017367E-12,3.559909094758253E-12,2.858043359288075E-12,2.156177623817898E-12, -1.475637723558782E-12,8.371015190102975E-13,2.599706096327376E-13,-5.461314069809755E-12,-4.921085770524055E-12,-4.343405037091838E-12,-3.732668368707687E-12,-3.093523840190885E-12,-2.430835727329465E-12,-1.734679010007751E-12,-9.74825365660928E-13,-2.797435120168326E-13,0,0,0,0,0,0,-2.283748241799531E-13,-4.037858874020686E-13,-2.146547464825323E-13],[.1316524975873958,.414213562373095,.7673269879789602,1.091308501069271,1.303225372841206,1.56968557711749,1.920982126971166,2.414213562373094,3.171594802363212, -4.510708503662055,7.595754112725146,22.90376554843115,.984807753012208,.6427876096865394,.3420201433256688,.9396926207859084,-.1736481776669303,-.7660444431189779,.8660254037844387,.5,-.5144957554275265,-.4717319685649723,-.3133774542039019,-.1819131996109812,-.09457419252642064,-.04096558288530405,-.01419856857247115,-.003699974673760037,.8574929257125442,.8817419973177052,.9496286491027329,.9833145924917901,.9955178160675857,.9991605581781475,.999899195244447,.9999931550702802],[0,0,0,0,0,0,2.283748241799531E-13, -4.037858874020686E-13,2.146547464825323E-13,5.461314069809755E-12,4.921085770524055E-12,4.343405037091838E-12,3.732668368707687E-12,3.093523840190885E-12,2.430835727329466E-12,1.734679010007751E-12,9.74825365660928E-13,2.797435120168326E-13,-5.456116108943413E-12,-4.878985199565852E-12,-4.240448995017367E-12,-3.559909094758253E-12,-2.858043359288075E-12,-2.156177623817898E-12,-1.475637723558782E-12,-8.371015190102975E-13,-2.599706096327376E-13,-2.382191739347913E-13,-6.423305872147834E-13,-9.400849094049688E-13, --1.122435026096556E-12,-1.183840321267481E-12,-1.122435026096556E-12,-9.400849094049688E-13,-6.423305872147841E-13,-2.382191739347918E-13]],w=n[c.SHORT_TYPE],E=n[c.SHORT_TYPE],B=n[c.SHORT_TYPE],G=n[c.SHORT_TYPE],f=[0,1,16,17,8,9,24,25,4,5,20,21,12,13,28,29,2,3,18,19,10,11,26,27,6,7,22,23,14,15,30,31];this.mdct_sub48=function(b,k,a){for(var m=286,v=0;vr;r++)for(u(k,m,D[p]),u(k, -m+32,D[p+1]),p+=2,m+=64,l=1;32>l;l+=2)D[p-1][l]*=-1;for(l=0;32>l;l++,q+=18){D=d.block_type;p=b.sb_sample[v][e];var t=b.sb_sample[v][1-e];0!=d.mixed_block_flag&&2>l&&(D=0);if(1E-12>b.amp_filter[l])na.fill(g,q+0,q+18,0);else{if(1>b.amp_filter[l])for(r=0;18>r;r++)t[r][f[l]]*=b.amp_filter[l];if(D==c.SHORT_TYPE){for(r=-3;0>r;r++){var J=n[c.SHORT_TYPE][r+3];g[q+3*r+9]=p[9+r][f[l]]*J-p[8-r][f[l]];g[q+3*r+18]=p[14-r][f[l]]*J+p[15+r][f[l]];g[q+3*r+10]=p[15+r][f[l]]*J-p[14-r][f[l]];g[q+3*r+19]=t[2-r][f[l]]* -J+t[3+r][f[l]];g[q+3*r+11]=t[3+r][f[l]]*J-t[2-r][f[l]];g[q+3*r+20]=t[8-r][f[l]]*J+t[9+r][f[l]]}r=g;p=q;for(J=0;3>J;J++){var h=r[p+6]*n[c.SHORT_TYPE][0]-r[p+15];t=r[p+0]*n[c.SHORT_TYPE][2]-r[p+9];var x=h+t;var y=h-t;h=r[p+15]*n[c.SHORT_TYPE][0]+r[p+6];t=r[p+9]*n[c.SHORT_TYPE][2]+r[p+0];var A=h+t;var N=-h+t;t=2.069978111953089E-11*(r[p+3]*n[c.SHORT_TYPE][1]-r[p+12]);h=2.069978111953089E-11*(r[p+12]*n[c.SHORT_TYPE][1]+r[p+3]);r[p+0]=1.90752519173728E-11*x+t;r[p+15]=1.90752519173728E-11*-A+h;y*=1.6519652744032674E-11; -A=9.537625958686404E-12*A+h;r[p+3]=y-A;r[p+6]=y+A;x=9.537625958686404E-12*x-t;N*=1.6519652744032674E-11;r[p+9]=x+N;r[p+12]=x-N;p++}}else{J=K(18);for(r=-9;0>r;r++)x=n[D][r+27]*t[r+9][f[l]]+n[D][r+36]*t[8-r][f[l]],y=n[D][r+9]*p[r+9][f[l]]-n[D][r+18]*p[8-r][f[l]],J[r+9]=x-y*w[3+r+9],J[r+18]=x*w[3+r+9]+y;r=g;p=q;x=J;var H=x[17]-x[9];var O=x[15]-x[11];var F=x[14]-x[12];N=x[0]+x[8];A=x[1]+x[7];h=x[2]+x[6];y=x[3]+x[5];r[p+17]=N+h-y-(A-x[4]);J=(N+h-y)*E[19]+(A-x[4]);t=(H-O-F)*E[18];r[p+5]=t+J;r[p+6]=t-J; -var C=(x[16]-x[10])*E[18];A=A*E[19]+x[4];t=H*E[12]+C+O*E[13]+F*E[14];J=-N*E[16]+A-h*E[17]+y*E[15];r[p+1]=t+J;r[p+2]=t-J;t=H*E[13]-C-O*E[14]+F*E[12];J=-N*E[17]+A-h*E[15]+y*E[16];r[p+9]=t+J;r[p+10]=t-J;t=H*E[14]-C+O*E[12]-F*E[13];J=N*E[15]-A+h*E[16]-y*E[17];r[p+13]=t+J;r[p+14]=t-J;H=x[8]-x[0];O=x[6]-x[2];F=x[5]-x[3];N=x[17]+x[9];A=x[16]+x[10];h=x[15]+x[11];y=x[14]+x[12];r[p+0]=N+h+y+(A+x[13]);t=(N+h+y)*E[19]-(A+x[13]);J=(H-O+F)*E[18];r[p+11]=t+J;r[p+12]=t-J;C=(x[7]-x[1])*E[18];A=x[13]-A*E[19];t=N*E[15]- -A+h*E[16]+y*E[17];J=H*E[14]+C+O*E[12]+F*E[13];r[p+3]=t+J;r[p+4]=t-J;t=-N*E[17]+A-h*E[15]-y*E[16];J=H*E[13]+C-O*E[14]-F*E[12];r[p+7]=t+J;r[p+8]=t-J;t=-N*E[16]+A-h*E[17]-y*E[15];J=H*E[12]-C+O*E[13]-F*E[14];r[p+15]=t+J;r[p+16]=t-J}}if(D!=c.SHORT_TYPE&&0!=l)for(r=7;0<=r;--r)D=g[q+r]*B[20+r]+g[q+-1-r]*G[28+r],p=g[q+r]*G[28+r]-g[q+-1-r]*B[20+r],g[q+-1-r]=D,g[q+r]=p}}k=a;m=286;if(1==b.mode_gr)for(e=0;18>e;e++)T.arraycopy(b.sb_sample[v][1][e],0,b.sb_sample[v][0][e],0,32)}}}function Xa(){this.thm=new Xb;this.en= -new Xb}function c(){var u=c.FFTOFFSET,k=c.MPG_MD_MS_LR,n=null,w=this.psy=null,E=null,B=null;this.setModules=function(c,b,k,a){n=c;w=this.psy=b;E=a;B=k};var ha=new Fc;this.lame_encode_mp3_frame=function(f,b,v,a,m,z){var e=Ob([2,2]);e[0][0]=new Xa;e[0][1]=new Xa;e[1][0]=new Xa;e[1][1]=new Xa;var l=Ob([2,2]);l[0][0]=new Xa;l[0][1]=new Xa;l[1][0]=new Xa;l[1][1]=new Xa;var d=[null,null],g=f.internal_flags,q=ca([2,4]),D=[.5,.5],p=[[0,0],[0,0]],r=[[0,0],[0,0]];d[0]=b;d[1]=v;if(0==g.lame_encode_frame_init){b= -f.internal_flags;var t,J;if(0==b.lame_encode_frame_init){v=K(2014);var h=K(2014);b.lame_encode_frame_init=1;for(J=t=0;t<286+576*(1+b.mode_gr);++t)t<576*b.mode_gr?(v[t]=0,2==b.channels_out&&(h[t]=0)):(v[t]=d[0][J],2==b.channels_out&&(h[t]=d[1][J]),++J);for(J=0;J(g.slot_lag-=g.frac_SpF)&&(g.slot_lag+=f.out_samplerate,g.padding=1);if(0!=g.psymodel)for(h=[null,null],t=0,J=X(2),v= -0;v=q?(g.ATH.adjust*=.075*q+.925,g.ATH.adjust= -q?g.ATH.adjust=q:g.ATH.adjustl;l++)g.nsPsy.pefirbuf[l]=g.nsPsy.pefirbuf[l+ -1];for(v=r=0;vl;l++)r+=(g.nsPsy.pefirbuf[l]+g.nsPsy.pefirbuf[18-l])*c.fircoef[l];r=3350*g.mode_gr*g.channels_out/r;for(v=0;vm;m++)g.pinfo.pcmdata[b][m]=d[b][m-u]}B.set_frame_pinfo(f,e)}g.bitrate_stereoMode_Hist[g.bitrate_index][4]++;g.bitrate_stereoMode_Hist[15][4]++;2==g.channels_out&&(g.bitrate_stereoMode_Hist[g.bitrate_index][g.mode_ext]++,g.bitrate_stereoMode_Hist[15][g.mode_ext]++);for(f=0;fc;c++)for(var k=0;2>k;k++)this.tt[c][k]=new rb}function Ic(){this.last_en_subshort=ca([4,9]);this.lastAttacks=X(4);this.pefirbuf= -K(19);this.longfact=K(c.SBMAX_l);this.shortfact=K(c.SBMAX_s);this.attackthre_s=this.attackthre=0}function Xb(){this.l=K(c.SBMAX_l);this.s=ca([c.SBMAX_s,3]);var u=this;this.assign=function(k){T.arraycopy(k.l,0,u.l,0,c.SBMAX_l);for(var n=0;nw;w++)u.s[n][w]=k.s[n][w]}}function da(){function u(){this.ptr=this.write_timing=0;this.buf=new Int8Array(40)}this.fill_buffer_resample_init=this.iteration_init_init=this.lame_encode_frame_init=this.Class_ID=0;this.mfbuf=ca([2,da.MFSIZE]); -this.full_outer_loop=this.use_best_huffman=this.subblock_gain=this.noise_shaping_stop=this.psymodel=this.substep_shaping=this.noise_shaping_amp=this.noise_shaping=this.highpass2=this.highpass1=this.lowpass2=this.lowpass1=this.mode_ext=this.samplerate_index=this.bitrate_index=this.VBR_max_bitrate=this.VBR_min_bitrate=this.mf_size=this.mf_samples_to_encode=this.resample_ratio=this.channels_out=this.channels_in=this.mode_gr=0;this.l3_side=new Hc;this.ms_ratio=K(2);this.slot_lag=this.frac_SpF=this.padding= -0;this.tag_spec=null;this.nMusicCRC=0;this.OldValue=X(2);this.CurrentStep=X(2);this.masking_lower=0;this.bv_scf=X(576);this.pseudohalf=X(sa.SFBMAX);this.sfb21_extra=!1;this.inbuf_old=Array(2);this.blackfilt=Array(2*da.BPC+1);this.itime=new Float64Array(2);this.sideinfo_len=0;this.sb_sample=ca([2,2,18,c.SBLIMIT]);this.amp_filter=K(32);this.header=Array(da.MAX_HEADER_BUF);this.ResvMax=this.ResvSize=this.ancillary_flag=this.w_ptr=this.h_ptr=0;this.scalefac_band=new za;this.minval_l=K(c.CBANDS);this.minval_s= -K(c.CBANDS);this.nb_1=ca([4,c.CBANDS]);this.nb_2=ca([4,c.CBANDS]);this.nb_s1=ca([4,c.CBANDS]);this.nb_s2=ca([4,c.CBANDS]);this.s3_ll=this.s3_ss=null;this.decay=0;this.thm=Array(4);this.en=Array(4);this.tot_ener=K(4);this.loudness_sq=ca([2,2]);this.loudness_sq_save=K(2);this.mld_l=K(c.SBMAX_l);this.mld_s=K(c.SBMAX_s);this.bm_l=X(c.SBMAX_l);this.bo_l=X(c.SBMAX_l);this.bm_s=X(c.SBMAX_s);this.bo_s=X(c.SBMAX_s);this.npart_s=this.npart_l=0;this.s3ind=Ia([c.CBANDS,2]);this.s3ind_s=Ia([c.CBANDS,2]);this.numlines_s= -X(c.CBANDS);this.numlines_l=X(c.CBANDS);this.rnumlines_l=K(c.CBANDS);this.mld_cb_l=K(c.CBANDS);this.mld_cb_s=K(c.CBANDS);this.numlines_l_num1=this.numlines_s_num1=0;this.pe=K(4);this.ms_ener_ratio_old=this.ms_ratio_l_old=this.ms_ratio_s_old=0;this.blocktype_old=X(2);this.nsPsy=new Ic;this.VBR_seek_table=new Gc;this.PSY=this.ATH=null;this.nogap_current=this.nogap_total=0;this.findPeakSample=this.findReplayGain=this.decode_on_the_fly=!0;this.AudiophileGain=this.RadioGain=this.PeakSample=0;this.rgdata= -null;this.noclipScale=this.noclipGainChange=0;this.bitrate_stereoMode_Hist=Ia([16,5]);this.bitrate_blockType_Hist=Ia([16,6]);this.hip=this.pinfo=null;this.in_buffer_nsamples=0;this.iteration_loop=this.in_buffer_1=this.in_buffer_0=null;for(var k=0;k>1;var e=a;var l=a<<1;var d=l+e; -a=l<<1;var g=k;var q=g+u;do{var B=c[g+0]-c[g+e];var p=c[g+0]+c[g+e];var r=c[g+l]-c[g+d];var t=c[g+l]+c[g+d];c[g+l]=p-t;c[g+0]=p+t;c[g+d]=B-r;c[g+e]=B+r;B=c[q+0]-c[q+e];p=c[q+0]+c[q+e];r=aa.SQRT2*c[q+d];t=aa.SQRT2*c[q+l];c[q+l]=p-t;c[q+0]=p+t;c[q+d]=B-r;c[q+e]=B+r;q+=a;g+=a}while(gk;k++){var a=c.BLKSIZE_s/2,m=65535&192*(k+1),B= -c.BLKSIZE_s/8-1;do{var e=E[B<<2]&255;var l=n[e]*b[f][v+e+m];var d=n[127-e]*b[f][v+e+m+128];var g=l-d;l+=d;var q=n[e+64]*b[f][v+e+m+64];d=n[63-e]*b[f][v+e+m+192];var D=q-d;q+=d;a-=4;w[k][a+0]=l+q;w[k][a+2]=l-q;w[k][a+1]=g+D;w[k][a+3]=g-D;l=n[e+1]*b[f][v+e+m+1];d=n[126-e]*b[f][v+e+m+129];g=l-d;l+=d;q=n[e+65]*b[f][v+e+m+65];d=n[62-e]*b[f][v+e+m+193];D=q-d;q+=d;w[k][a+c.BLKSIZE_s/2+0]=l+q;w[k][a+c.BLKSIZE_s/2+2]=l-q;w[k][a+c.BLKSIZE_s/2+1]=g+D;w[k][a+c.BLKSIZE_s/2+3]=g-D}while(0<=--B);u(w[k],a,c.BLKSIZE_s/ -2)}};this.fft_long=function(n,w,f,b,v){n=c.BLKSIZE/8-1;var a=c.BLKSIZE/2;do{var m=E[n]&255;var B=k[m]*b[f][v+m];var e=k[m+512]*b[f][v+m+512];var l=B-e;B+=e;var d=k[m+256]*b[f][v+m+256];e=k[m+768]*b[f][v+m+768];var g=d-e;d+=e;a-=4;w[a+0]=B+d;w[a+2]=B-d;w[a+1]=l+g;w[a+3]=l-g;B=k[m+1]*b[f][v+m+1];e=k[m+513]*b[f][v+m+513];l=B-e;B+=e;d=k[m+257]*b[f][v+m+257];e=k[m+769]*b[f][v+m+769];g=d-e;d+=e;w[a+c.BLKSIZE/2+0]=B+d;w[a+c.BLKSIZE/2+2]=B-d;w[a+c.BLKSIZE/2+1]=l+g;w[a+c.BLKSIZE/2+3]=l-g}while(0<=--n);u(w, -a,c.BLKSIZE/2)};this.init_fft=function(u){for(u=0;ua)if(c=c*r)return a+c;g=a/c}a+=c;if(6>=b+3){if(g>=p)return a;b=0|aa.FAST_LOG10_X(g,16);return a* -x[b]}b=0|aa.FAST_LOG10_X(g,16);c=0!=e?f.ATH.cb_s[d]*f.ATH.adjust:f.ATH.cb_l[d]*f.ATH.adjust;return ac?(d=1,13>=b&&(d=y[b]),c=aa.FAST_LOG10_X(a/c,10/15),a*((h[b]-d)*c+d)):13a&&(a=0);0>c&&(c=0);if(0>=a)return c;if(0>=c)return a;var b=c>a?c/a:a/c;if(-2<=d&&2>=d){if(b>=p)return a+c;d=0|aa.FAST_LOG10_X(b,16);return(a+c)*A[d]}if(b=y){++e;break}k=a.PSY.bo_s_weight[e];y=1-k;l=k*d[g];k*=b[g];a.en[h].s[e][f]+=l;a.thm[h].s[e][f]+=k;l=y*d[g];k=y*b[g]}for(;e=m){++f;break}l=a.PSY.bo_l_weight[f];m=1-l;g=l*d[e];l*=b[e];a.en[h].l[f]+=g; -a.thm[h].l[f]+=l;g=m*d[e];l=m*b[e]}for(;f=d?c:0f;f++){var e=a.thm.s[h][f];if(0e&&(b=g>1E10*e?b+23.02585092994046*N[h]:b+N[h]*aa.FAST_LOG10(g/e))}}return b}function f(a,d){for(var b=281.0575,h=0;hf&&(b=e>1E10*f?b+23.02585092994046*H[h]: -b+H[h]*aa.FAST_LOG10(e/f))}}return b}function b(a,c,b,d,h){var f,e;for(f=e=0;fh&&(e=h);d[f]=e}else d[f]=0;for(f=1;fh&&(e=h),d[f]=e):d[f]=0;e=b[f-1]+b[f];0h&&(e=h),d[f]=e):d[f]=0}function a(a,c,b,d,f,h,e){var g=2*h;f=0y&&(k=y);l>p&&(l=p);c[2][m]=k;c[3][m]=l}}function m(a,c){a=0<=a?27*-a:a*c;return-72>=a?0:Math.exp(.2302585093*a)}function z(a){0>a&&(a=0);a*=.001;return 13*Math.atan(.76*a)+3.5*Math.atan(a*a/56.25)}function e(a,b,d,f,h,e,g,l,k,m,y,p){var q=K(c.CBANDS+1),n=l/(15z(l*t)- -A&&t<=k/2;t++);a[r]=t-u;for(C=r+1;uk/2){u=k/2;++r;break}}q[r]=l*u;for(u=0;ur&&(r=0),t=0|Math.floor(.5+y*(A-.5)),t>k/2&&(t=k/2),d[u]=(x[r]+x[t])/2,b[u]=x[t],g[u]=(n*A-q[b[u]])/(q[b[u]+1]-q[b[u]]),0>g[u]?g[u]=0:1=y){var p=y-.5;p=8*(p*p-2*p)}else p=0;y+=.474;y=15.811389+7.5*y-17.5*Math.sqrt(1+y*y);-60>=y?p=0:(y=Math.exp(.2302585093*(p+y)),p=y/.6609193);y=p*f[e];g[k][e]=y*h[k]}else for(e=0;e=n;++n)q=y+n*(x-y)/1E3,q=m(q,k),r+=q;q=1001/(r*(x-y));for(k=0;k -a&&(a=3410);a=Math.max(.1,a/1E3);return 3.64*Math.pow(a,-.8)-6.8*Math.exp(-.6*Math.pow(a-3.4,2))+6*Math.exp(-.15*Math.pow(a-8.7,2))+.001*(.6+.04*c)*Math.pow(a,4)}var q=new Jc,D=1/217621504/(c.BLKSIZE/2),p,r,t,J=[1,.79433,.63096,.63096,.63096,.63096,.63096,.25119,.11749],h=[3.3246*3.3246,3.23837*3.23837,9.9500500969,9.0247369744,8.1854926609,7.0440875649,2.46209*2.46209,2.284*2.284,4.4892710641,1.96552*1.96552,1.82335*1.82335,1.69146*1.69146,2.4621061921,2.1508568964,1.37074*1.37074,1.31036*1.31036, -1.5691069696,1.4555939904,1.16203*1.16203,1.2715945225,1.09428*1.09428,1.0659*1.0659,1.0779838276,1.0382591025,1],x=[1.7782755904,1.35879*1.35879,1.38454*1.38454,1.39497*1.39497,1.40548*1.40548,1.3537*1.3537,1.6999465924,1.22321*1.22321,1.3169398564,1],y=[5.5396212496,2.29259*2.29259,4.9868695969,2.12675*2.12675,2.02545*2.02545,1.87894*1.87894,1.74303*1.74303,1.61695*1.61695,2.2499700001,1.39148*1.39148,1.29083*1.29083,1.19746*1.19746,1.2339655056,1.0779838276],A=[1.7782755904,1.35879*1.35879,1.38454* -1.38454,1.39497*1.39497,1.40548*1.40548,1.3537*1.3537,1.6999465924,1.22321*1.22321,1.3169398564,1],N=[11.8,13.6,17.2,32,46.5,51.3,57.5,67.1,71.5,84.6,97.6,130],H=[6.8,5.8,5.8,6.4,6.5,9.9,12.1,14.4,15,18.9,21.6,26.9,34.2,40.2,46.8,56.5,60.7,73.9,85.7,93.4,126.1],O=[-1.730326E-17,-.01703172,-1.349528E-17,.0418072,-6.73278E-17,-.0876324,-3.0835E-17,.1863476,-1.104424E-16,-.627638];this.L3psycho_anal_ns=function(a,d,h,e,g,l,m,y,p,n){var x=a.internal_flags,r=ca([2,c.BLKSIZE]),t=ca([2,3,c.BLKSIZE_s]),A= -K(c.CBANDS+1),I=K(c.CBANDS+1),C=K(c.CBANDS+2),Q=X(2),S=X(2),z,D,F,H,N,Z,L,V=ca([2,576]),ma=X(c.CBANDS+2),R=X(c.CBANDS+2);na.fill(R,0);var T=x.channels_out;a.mode==la.JOINT_STEREO&&(T=4);var M=a.VBR==G.vbr_off?0==x.ResvMax?0:x.ResvSize/x.ResvMax*.5:a.VBR==G.vbr_rh||a.VBR==G.vbr_mtrh||a.VBR==G.vbr_mt?.6:1;for(z=0;zF;F++){var U;var da=Y[ha+F+10];for(H=U=0;9>H;H+=2)da+=O[H]*(Y[ha+F+H]+Y[ha+F+21-H]),U+=O[H+1]*(Y[ha+F+H+1]+Y[ha+F+21-H-1]); -V[z][F]=da+U}g[e][z].en.assign(x.en[z]);g[e][z].thm.assign(x.thm[z]);2F;F++)Qa[F]=x.nsPsy.last_en_subshort[z][F+6],qa[F]=Qa[F]/x.nsPsy.last_en_subshort[z][F+4],ya[0]+=Qa[F];if(2==z)for(F=0;576>F;F++){var Ya=V[0][F];var Xa=V[1][F];V[0][F]=Ya+Xa;V[1][F]=Ya-Xa}var Ia=V[z&1],ec=0;for(F=0;9> -F;F++){for(var xa=ec+64,Ga=1;ecQa[F+3-2]?Ga/Qa[F+3-2]:Qa[F+3-2]>10*Ga?Qa[F+3-2]/(10*Ga):0;qa[F+3]=Ga}if(a.analysis){var Qb=qa[0];for(F=1;12>F;F++)QbF;F++)0==ta[F/3]&&qa[F]>Ma&&(ta[F/3]=F%3+1);for(F=1;4>F;F++)1.7>(ya[F-1]>ya[F]?ya[F-1]/ya[F]:ya[F]/ -ya[F-1])&&(ta[F]=0,1==F&&(ta[0]=0));0!=ta[0]&&0!=x.nsPsy.lastAttacks[z]&&(ta[0]=0);if(3==x.nsPsy.lastAttacks[z]||0!=ta[0]+ta[1]+ta[2]+ta[3])ia=0,0!=ta[1]&&0!=ta[0]&&(ta[1]=0),0!=ta[2]&&0!=ta[1]&&(ta[2]=0),0!=ta[3]&&0!=ta[2]&&(ta[3]=0);2>z?S[z]=ia:0==ia&&(S[0]=S[1]=0);p[z]=x.tot_ener[z];var P=a,Ha=za,Gb=Wb,La=r,kb=z&1,Ra=t,Na=z&1,cb=e,Aa=z,va=d,qb=h,Va=P.internal_flags;if(2>Aa)q.fft_long(Va,La[kb],Aa,va,qb),q.fft_short(Va,Ra[Na],Aa,va,qb);else if(2==Aa){for(var ja=c.BLKSIZE-1;0<=ja;--ja){var Hb=La[kb+ -0][ja],Ib=La[kb+1][ja];La[kb+0][ja]=(Hb+Ib)*aa.SQRT2*.5;La[kb+1][ja]=(Hb-Ib)*aa.SQRT2*.5}for(var Ba=2;0<=Ba;--Ba)for(ja=c.BLKSIZE_s-1;0<=ja;--ja)Hb=Ra[Na+0][Ba][ja],Ib=Ra[Na+1][Ba][ja],Ra[Na+0][Ba][ja]=(Hb+Ib)*aa.SQRT2*.5,Ra[Na+1][Ba][ja]=(Hb-Ib)*aa.SQRT2*.5}Ha[0]=La[kb+0][0];Ha[0]*=Ha[0];for(ja=c.BLKSIZE/2-1;0<=ja;--ja){var fc=La[kb+0][c.BLKSIZE/2-ja],tb=La[kb+0][c.BLKSIZE/2+ja];Ha[c.BLKSIZE/2-ja]=.5*(fc*fc+tb*tb)}for(Ba=2;0<=Ba;--Ba)for(Gb[Ba][0]=Ra[Na+0][Ba][0],Gb[Ba][0]*=Gb[Ba][0],ja=c.BLKSIZE_s/ -2-1;0<=ja;--ja)fc=Ra[Na+0][Ba][c.BLKSIZE_s/2-ja],tb=Ra[Na+0][Ba][c.BLKSIZE_s/2+ja],Gb[Ba][c.BLKSIZE_s/2-ja]=.5*(fc*fc+tb*tb);var oa=0;for(ja=11;jaAa&&(Va.loudness_sq[cb][Aa]=Va.loudness_sq_save[Aa],Va.loudness_sq_save[Aa]=u(Ha,Va));b(x,za,A,sa,Fa);v(x,sa,Fa,ma);for(L= -0;3>L;L++){var ea=void 0,Ab=void 0,Bb=Wb,Sa=I,Za=C,ub=z,zb=L,Ja=a.internal_flags;for(ea=Ab=0;eafb;fb++)Sb=fa.thm[0].s[Ca][fb],Eb=fa.thm[1].s[Ca][fb],fa.thm[0].s[Ca][fb]+=Eb*xb,fa.thm[1].s[Ca][fb]+=Sb*xb}}if(a.mode==la.JOINT_STEREO){for(var Oa,ka=0;ka1.58*x.thm[1].l[ka]||x.thm[1].l[ka]>1.58* -x.thm[0].l[ka])){var Ua=x.mld_l[ka]*x.en[3].l[ka],gb=Math.max(x.thm[2].l[ka],Math.min(x.thm[3].l[ka],Ua));Ua=x.mld_l[ka]*x.en[2].l[ka];var gc=Math.max(x.thm[3].l[ka],Math.min(x.thm[2].l[ka],Ua));x.thm[2].l[ka]=gb;x.thm[3].l[ka]=gc}for(ka=0;kaua;ua++)x.thm[0].s[ka][ua]>1.58*x.thm[1].s[ka][ua]||x.thm[1].s[ka][ua]>1.58*x.thm[0].s[ka][ua]||(Ua=x.mld_s[ka]*x.en[3].s[ka][ua],gb=Math.max(x.thm[2].s[ka][ua],Math.min(x.thm[3].s[ka][ua],Ua)),Ua=x.mld_s[ka]*x.en[2].s[ka][ua],gc= -Math.max(x.thm[3].s[ka][ua],Math.min(x.thm[2].s[ka][ua],Ua)),x.thm[2].s[ka][ua]=gb,x.thm[3].s[ka][ua]=gc);Oa=a.msfix;if(0Da;Da++)ba=x.ATH.cb_s[x.bm_s[wa]]*Zb,Wa=Math.min(Math.max(x.thm[0].s[wa][Da],ba),Math.max(x.thm[1].s[wa][Da],ba)),ab=Math.max(x.thm[2].s[wa][Da],ba),mb=Math.max(x.thm[3].s[wa][Da],ba),Wa*KbM;M++){var Y;var ha=firbuf[T+M+10];for(var U=Y=0;9>U;U+=2)ha+=F[U]*(firbuf[T+M+U]+firbuf[T+M+21-U]),Y+=F[U+1]*(firbuf[T+M+U+1]+firbuf[T+M+21-U-1]);Z[R][M]=ha+Y}l[g][R].en.assign(G.en[R]); -l[g][R].thm.assign(G.thm[R]);2M;M++)ya[M]=G.nsPsy.last_en_subshort[R][M+6],da[M]=ya[M]/G.nsPsy.last_en_subshort[R][M+4],qa[0]+=ya[M];for(M=0;9>M;M++){for(var Xa=sa+64,Ya=1;saya[M+3-2]?Ya/ya[M+3-2]:ya[M+3-2]>10*Ya?ya[M+3-2]/(10*Ya):0;da[M+3]=Ya}for(M=0;3>M;++M){var Ia=ya[3*M+3]+ya[3*M+4]+ya[3*M+5],Wb=1;6*ya[3*M+5]M;M++)xaM;M++)0==L[R][M/3]&&da[M]>Fa&&(L[R][M/3]=M%3+1);for(M=1;4>M;M++){var Qb=qa[M-1],Ga=qa[M];4E4>Math.max(Qb,Ga)&&Qb< -1.7*Ga&&Ga<1.7*Qb&&(1==M&&L[R][0]<=L[R][M]&&(L[R][0]=0),L[R][M]=0)}L[R][0]<=G.nsPsy.lastAttacks[R]&&(L[R][0]=0);if(3==G.nsPsy.lastAttacks[R]||0!=L[R][0]+L[R][1]+L[R][2]+L[R][3])na=0,0!=L[R][1]&&0!=L[R][0]&&(L[R][1]=0),0!=L[R][2]&&0!=L[R][1]&&(L[R][2]=0),0!=L[R][3]&&0!=L[R][2]&&(L[R][3]=0);2>R?H[R]=na:0==na&&(H[0]=H[1]=0);y[R]=G.tot_ener[R]}var qb=d.internal_flags;d.short_blocks!=ra.short_block_coupled||0!=H[0]&&0!=H[1]||(H[0]=H[1]=0);for(var Ma=0;MaLa)q.fft_long(Aa,Na[cb],La,h,e);else if(2==La)for(var va=c.BLKSIZE-1;0<=va;--va){var rb=Na[cb+0][va],Va=Na[cb+1][va];Na[cb+0][va]=(rb+Va)*aa.SQRT2*.5;Na[cb+1][va]=(rb-Va)*aa.SQRT2*.5}Ra[0]=Na[cb+0][0];Ra[0]*=Ra[0];for(va=c.BLKSIZE/2-1;0<=va;--va){var ja=Na[cb+0][c.BLKSIZE/2-va],Hb=Na[cb+0][c.BLKSIZE/2+va];Ra[c.BLKSIZE/2-va]=.5*(ja*ja+Hb*Hb)}var Ib= -0;for(va=11;vaBa&&(tb.loudness_sq[g][Ba]=tb.loudness_sq_save[Ba],tb.loudness_sq_save[Ba]=u(zb,tb));if(0!=H[Ha]){var oa=void 0,ea=r,Ab=I,Bb=S[P],Sa=D[P],Za=P,ub=K(c.CBANDS),sb=K(c.CBANDS),Ja=X(c.CBANDS+2);b(ea,Ab,Bb,ub,sb);v(ea,ub, -sb,Ja);var Rb=0;for(oa=0;oa=Yb&&(Yb=$a);0>=eb&&(eb=$a); -wb=ea.blocktype_old[Za&1]==c.NORM_TYPE?Math.min(eb,Yb):eb;Sa[oa]=Math.min($a,wb)}ea.nb_2[Za][oa]=ea.nb_1[Za][oa];ea.nb_1[Za][oa]=$a;vb=ub[oa];vb*=ea.minval_l[oa];vb*=Ta;Sa[oa]>vb&&(Sa[oa]=vb);1Bb[oa]&&(Sa[oa]=Bb[oa]);1>ea.masking_lower&&(Sa[oa]*=ea.masking_lower)}for(;oafa;fa++){for(P=0;Pfb&&q.fft_short(gc,Ua[gb],fb,h,e);if(2==fb)for(var ua=c.BLKSIZE_s-1;0<=ua;--ua){var Kb=Ua[gb+0][Oa][ua],hc=Ua[gb+1][Oa][ua];Ua[gb+0][Oa][ua]=(Kb+hc)*aa.SQRT2*.5; -Ua[gb+1][Oa][ua]=(Kb-hc)*aa.SQRT2*.5}ka[Oa][0]=Ua[gb+0][Oa][0];ka[Oa][0]*=ka[Oa][0];for(ua=c.BLKSIZE_s/2-1;0<=ua;--ua){var Zb=Ua[gb+0][Oa][c.BLKSIZE_s/2-ua],wa=Ua[gb+0][Oa][c.BLKSIZE_s/2+ua];ka[Oa][c.BLKSIZE_s/2-ua]=.5*(Zb*Zb+wa*wa)}var ba=void 0,Wa=void 0,ab=void 0,mb=C,hb=S[P],Da=D[P],ib=P,Ka=fa,Ea=d.internal_flags,Lb=new float[c.CBANDS],Tb=K(c.CBANDS),Fb=new int[c.CBANDS];for(ba=Wa=0;baac&&(ob=ac);$b[pa]=ob}else $b[pa]=0;for(pa=1;paac&&(ob=ac),$b[pa]=ob):$b[pa]=0;Pa=Ub[pa-1]+Ub[pa];0ac&&(ob=ac),$b[pa]=ob):$b[pa]=0;for(Wa=ba=0;babc&&(Da[ba]=bc);1hb[ba]&&(Da[ba]=hb[ba]);1>Ea.masking_lower&&(Da[ba]*=Ea.masking_lower)}for(;bafa;fa++){var jb=r.thm[P].s[Vb][fa];jb*=.8;if(2<=L[P][fa]||1==L[P][fa+1]){var jc=0!=fa?fa-1:2,kc=B(r.thm[P].s[Vb][jc],jb,.36);jb=Math.min(jb,kc)}else if(1==L[P][fa])jc=0!=fa?fa-1:2,kc=B(r.thm[P].s[Vb][jc],jb,.18),jb=Math.min(jb,kc);else if(0!=fa&&3==L[P][fa-1]||0==fa&&3==r.nsPsy.lastAttacks[P])jc=2!=fa?fa+1:0,kc=B(r.thm[P].s[Vb][jc],jb,.18),jb=Math.min(jb,kc);jb*=O[P][fa];vc[fa]=jb}for(fa=0;3>fa;fa++)r.thm[P].s[Vb][fa]=vc[fa]}for(P=0;Pf;++f){for(var v=0;vv;++v){for(z=0;zv;v++)b.nsPsy.last_en_subshort[f][v]=10}b.loudness_sq_save[0]=b.loudness_sq_save[1]=0;b.npart_l=e(b.numlines_l,b.bo_l,b.bm_l,n,u,b.mld_l,b.PSY.bo_l_weight,w,c.BLKSIZE,b.scalefac_band.l, -c.BLKSIZE/1152,c.SBMAX_l);for(f=0;f=g&&(z=m*(n[f]-g)/(24-g)+k*(24-n[f])/(24-g)),A[f]=Math.pow(10,z/10),b.rnumlines_l[f]=0k&&(m=k);b.ATH.cb_l[f]=m;m=-20+20*n[f]/10;6m&&(m=-15);m-=8;b.minval_l[f]=Math.pow(10,m/10)*b.numlines_l[f]}b.npart_s= -e(b.numlines_s,b.bo_s,b.bm_s,n,u,b.mld_s,b.PSY.bo_s_weight,w,c.BLKSIZE_s,b.scalefac_band.s,c.BLKSIZE_s/384,c.SBMAX_s);for(f=v=0;f=g&&(z=y*(n[f]-g)/(24-g)+x*(24-n[f])/(24-g));A[f]=Math.pow(10,z/10);m=Ma.MAX_VALUE;for(z=0;zk&&(m=k);b.ATH.cb_s[f]=m;m=-7+7*n[f]/12;12n[f]&&(m*=1+2.3*Math.log(1-m));-15>m&&(m=-15);m-=8;b.minval_s[f]= -Math.pow(10,m/10)*b.numlines_s[f]}b.s3_ss=l(b.s3ind_s,b.npart_s,n,u,A,h);p=Math.pow(10,.5625);r=Math.pow(10,1.5);t=Math.pow(10,1.5);q.init_fft(b);b.decay=Math.exp(-2.302585092994046/(.01*w/192));f=3.5;0!=(a.exp_nspsytune&2)&&(f=1);0b.npart_l-1&&(b.s3ind[h][1]=b.npart_l-1);b.ATH.decay=Math.pow(10,576*b.mode_gr/w*-1.2);b.ATH.adjust=.01;b.ATH.adjustLimit=1;if(-1!=a.ATHtype){v=a.out_samplerate/c.BLKSIZE;for(f=k=h=0;f=a?1:Math.cos(Math.PI/2*a)}function E(a,b){switch(a){case 44100:return b.version= -1,0;case 48E3:return b.version=1;case 32E3:return b.version=1,2;case 22050:return b.version=0;case 24E3:return b.version=0,1;case 16E3:return b.version=0,2;case 11025:return b.version=0;case 12E3:return b.version=0,1;case 8E3:return b.version=0,2;default:return b.version=0,-1}}function B(a,b,d){16E3>d&&(b=2);d=w.bitrate_table[b][1];for(var c=2;14>=c;c++)0d&&(b=2);for(d= -0;14>=d;d++)if(0t)return t;n+=t;x+=t;u[0]=g;u[1]=k;if(qa.NEQ(f.scale,0)&&qa.NEQ(f.scale,1))for(t=0;tH.resample_ratio||1.0001da.BPC&&(sa= -da.BPC);var ra=1E-4>Math.abs(ca.resample_ratio-Math.floor(.5+ca.resample_ratio))?1:0;var R=1/ca.resample_ratio;1xa&&(xa=0);1Math.abs(Ma)?Qa/Math.PI:xa*Math.sin(na*Qa*Ma)/(Math.PI*na*Ma)}for(N=0;N<=na;N++)ca.blackfilt[ia][N]/=M}ca.fill_buffer_resample_init=1}M=ca.inbuf_old[la];for(R=0;R=aa)break;za=N-ca.itime[la]-(ia+na%2*.5);za=0|Math.floor(2*za*sa+sa+.5);for(N=Fa=0;N<=na;++N)Ia=0|N+ia-na/2,Fa+=(0>Ia?M[ra+Ia]:W[X+Ia])*ca.blackfilt[za][N];V[T+R]=Fa}ha.num_used=Math.min(aa,na+ia-na/2);ca.itime[la]+=ha.num_used- -R*ca.resample_ratio;if(ha.num_used>=ra)for(N=0;Nh.mf_samples_to_encode&&(h.mf_samples_to_encode=c.ENCDELAY+c.POSTDELAY);h.mf_samples_to_encode+=t;if(h.mf_size>=g){w=r-x;0==r&&(w=0);t=f;w=e.enc.lame_encode_mp3_frame(t,y[0],y[1],q,n,w);t.frameNum++;t=w;if(0>t)return t;n+=t;x+=t;h.mf_size-=f.framesize;h.mf_samples_to_encode-=f.framesize;for(w=0;wh;h++)if(Math.max(a,b[h+1])!=a){d=b[h+1];c=h+1;f=b[h];e=h;break}return d-a>a-f?e:c};this.lame_init_params=function(a){var b=a.internal_flags;b.Class_ID=0;null==b.ATH&&(b.ATH=new Cc);null==b.PSY&&(b.PSY=new u);null==b.rgdata&&(b.rgdata=new Ac);b.channels_in=a.num_channels; -1==b.channels_in&&(a.mode=la.MONO);b.channels_out=a.mode==la.MONO?1:2;b.mode_ext=c.MPG_MD_MS_LR;a.mode==la.MONO&&(a.force_ms=!1);a.VBR==G.vbr_off&&128!=a.VBR_mean_bitrate_kbps&&0==a.brate&&(a.brate=a.VBR_mean_bitrate_kbps);a.VBR!=G.vbr_off&&a.VBR!=G.vbr_mtrh&&a.VBR!=G.vbr_mt&&(a.free_format=!1);a.VBR==G.vbr_off&&0==a.brate&&qa.EQ(a.compression_ratio,0)&&(a.compression_ratio=11.025);a.VBR==G.vbr_off&&0a.out_samplerate?(a.VBR_mean_bitrate_kbps=Math.max(a.VBR_mean_bitrate_kbps,8),a.VBR_mean_bitrate_kbps=Math.min(a.VBR_mean_bitrate_kbps,64)):32E3>a.out_samplerate?(a.VBR_mean_bitrate_kbps=Math.max(a.VBR_mean_bitrate_kbps,8),a.VBR_mean_bitrate_kbps=Math.min(a.VBR_mean_bitrate_kbps,160)):(a.VBR_mean_bitrate_kbps= -Math.max(a.VBR_mean_bitrate_kbps,32),a.VBR_mean_bitrate_kbps=Math.min(a.VBR_mean_bitrate_kbps,320)));if(0==a.lowpassfreq){switch(a.VBR){case G.vbr_off:var e=new k;f(e,a.brate);e=e.lowerlimit;break;case G.vbr_abr:e=new k;f(e,a.VBR_mean_bitrate_kbps);e=e.lowerlimit;break;case G.vbr_rh:var h=[19500,19E3,18600,18E3,17500,16E3,15600,14900,12500,1E4,3950];if(0<=a.VBR_q&&9>=a.VBR_q){e=h[a.VBR_q];h=h[a.VBR_q+1];var m=a.VBR_q_frac;e=linear_int(e,h,m)}else e=19500;break;default:h=[19500,19E3,18500,18E3,17500, -16500,15500,14500,12500,9500,3950],0<=a.VBR_q&&9>=a.VBR_q?(e=h[a.VBR_q],h=h[a.VBR_q+1],m=a.VBR_q_frac,e=linear_int(e,h,m)):e=19500}a.mode!=la.MONO||a.VBR!=G.vbr_off&&a.VBR!=G.vbr_abr||(e*=1.5);a.lowpassfreq=e|0}0==a.out_samplerate&&(2*a.lowpassfreq>a.in_samplerate&&(a.lowpassfreq=a.in_samplerate/2),e=a.lowpassfreq|0,h=a.in_samplerate,m=44100,48E3<=h?m=48E3:44100<=h?m=44100:32E3<=h?m=32E3:24E3<=h?m=24E3:22050<=h?m=22050:16E3<=h?m=16E3:12E3<=h?m=12E3:11025<=h?m=11025:8E3<=h&&(m=8E3),-1==e?e=m:(15960>= -e&&(m=44100),15250>=e&&(m=32E3),11220>=e&&(m=24E3),9970>=e&&(m=22050),7230>=e&&(m=16E3),5420>=e&&(m=12E3),4510>=e&&(m=11025),3970>=e&&(m=8E3),e=h=a.out_samplerate?1:2;a.framesize=576*b.mode_gr;a.encoder_delay=c.ENCDELAY;b.resample_ratio=a.in_samplerate/a.out_samplerate;switch(a.VBR){case G.vbr_mt:case G.vbr_rh:case G.vbr_mtrh:a.compression_ratio=[5.7,6.5,7.3,8.2,10,11.9,13,14,15,16.5][a.VBR_q];break;case G.vbr_abr:a.compression_ratio=16*a.out_samplerate*b.channels_out/(1E3*a.VBR_mean_bitrate_kbps);break;default:a.compression_ratio=16*a.out_samplerate*b.channels_out/(1E3*a.brate)}a.mode==la.NOT_SET&&(a.mode=la.JOINT_STEREO);0b.lowpass1&&(b.lowpass1=0)):b.lowpass1=2*a.lowpassfreq,b.lowpass1/=a.out_samplerate,b.lowpass2/=a.out_samplerate):(b.lowpass1=0,b.lowpass2=0);e=a.internal_flags;var n=32,v=-1;if(0=h;h++)m=h/31,m>=e.lowpass2&&(n=Math.min(n,h)),e.lowpass1=h;h++)m=h/31,m<=e.highpass1&&(v=Math.max(v,h)),e.highpass1h;h++)m=h/31,v=e.highpass2>e.highpass1?V((e.highpass2-m)/(e.highpass2-e.highpass1+1E-20)):1,m=e.lowpass2>e.lowpass1?V((m-e.lowpass1)/(e.lowpass2-e.lowpass1+1E-20)):1,e.amp_filter[h]=v*m;b.samplerate_index=E(a.out_samplerate,a);if(0>b.samplerate_index)return a.internal_flags=null,-1;if(a.VBR==G.vbr_off)if(a.free_format)b.bitrate_index=0;else{if(a.brate=B(a.brate,a.version,a.out_samplerate),b.bitrate_index=U(a.brate,a.version,a.out_samplerate),0>=b.bitrate_index)return a.internal_flags=null,-1}else b.bitrate_index= -1;a.analysis&&(a.bWriteVbrTag=!1);null!=b.pinfo&&(a.bWriteVbrTag=!1);d.init_bit_stream_w(b);e=b.samplerate_index+3*a.version+6*(16E3>a.out_samplerate?1:0);for(h=0;he;e++)b.nsPsy.pefirbuf[e]=700* -b.mode_gr*b.channels_out;-1==a.ATHtype&&(a.ATHtype=4);switch(a.VBR){case G.vbr_mt:a.VBR=G.vbr_mtrh;case G.vbr_mtrh:null==a.useTemporal&&(a.useTemporal=!1);g.apply_preset(a,500-10*a.VBR_q,0);0>a.quality&&(a.quality=LAME_DEFAULT_QUALITY);5>a.quality&&(a.quality=0);5a.quality&&(a.quality=LAME_DEFAULT_QUALITY);b.iteration_loop=new VBROldIterationLoop(D);break;default:b.sfb21_extra=!1,0>a.quality&&(a.quality=LAME_DEFAULT_QUALITY),e=a.VBR,e==G.vbr_off&&(a.VBR_mean_bitrate_kbps=a.brate),g.apply_preset(a,a.VBR_mean_bitrate_kbps,0),a.VBR=e,b.PSY.mask_adjust=a.maskingadjust,b.PSY.mask_adjust_short= -a.maskingadjust_short,b.iteration_loop=e==G.vbr_off?new Bc(D):new ABRIterationLoop(D)}if(a.VBR!=G.vbr_off){b.VBR_min_bitrate=1;b.VBR_max_bitrate=14;16E3>a.out_samplerate&&(b.VBR_max_bitrate=8);if(0!=a.VBR_min_bitrate_kbps&&(a.VBR_min_bitrate_kbps=B(a.VBR_min_bitrate_kbps,a.version,a.out_samplerate),b.VBR_min_bitrate=U(a.VBR_min_bitrate_kbps,a.version,a.out_samplerate),0>b.VBR_min_bitrate)||0!=a.VBR_max_bitrate_kbps&&(a.VBR_max_bitrate_kbps=B(a.VBR_max_bitrate_kbps,a.version,a.out_samplerate),b.VBR_max_bitrate= -U(a.VBR_max_bitrate_kbps,a.version,a.out_samplerate),0>b.VBR_max_bitrate))return-1;a.VBR_min_bitrate_kbps=w.bitrate_table[a.version][b.VBR_min_bitrate];a.VBR_max_bitrate_kbps=w.bitrate_table[a.version][b.VBR_max_bitrate];a.VBR_mean_bitrate_kbps=Math.min(w.bitrate_table[a.version][b.VBR_max_bitrate],a.VBR_mean_bitrate_kbps);a.VBR_mean_bitrate_kbps=Math.max(w.bitrate_table[a.version][b.VBR_min_bitrate],a.VBR_mean_bitrate_kbps)}a.tune&&(b.PSY.mask_adjust+=a.tune_value_a,b.PSY.mask_adjust_short+=a.tune_value_a); -e=a.internal_flags;switch(a.quality){default:case 9:e.psymodel=0;e.noise_shaping=0;e.noise_shaping_amp=0;e.noise_shaping_stop=0;e.use_best_huffman=0;e.full_outer_loop=0;break;case 8:a.quality=7;case 7:e.psymodel=1;e.noise_shaping=0;e.noise_shaping_amp=0;e.noise_shaping_stop=0;e.use_best_huffman=0;e.full_outer_loop=0;break;case 6:e.psymodel=1;0==e.noise_shaping&&(e.noise_shaping=1);e.noise_shaping_amp=0;e.noise_shaping_stop=0;-1==e.subblock_gain&&(e.subblock_gain=1);e.use_best_huffman=0;e.full_outer_loop= -0;break;case 5:e.psymodel=1;0==e.noise_shaping&&(e.noise_shaping=1);e.noise_shaping_amp=0;e.noise_shaping_stop=0;-1==e.subblock_gain&&(e.subblock_gain=1);e.use_best_huffman=0;e.full_outer_loop=0;break;case 4:e.psymodel=1;0==e.noise_shaping&&(e.noise_shaping=1);e.noise_shaping_amp=0;e.noise_shaping_stop=0;-1==e.subblock_gain&&(e.subblock_gain=1);e.use_best_huffman=1;e.full_outer_loop=0;break;case 3:e.psymodel=1;0==e.noise_shaping&&(e.noise_shaping=1);e.noise_shaping_amp=1;e.noise_shaping_stop=1;-1== -e.subblock_gain&&(e.subblock_gain=1);e.use_best_huffman=1;e.full_outer_loop=0;break;case 2:e.psymodel=1;0==e.noise_shaping&&(e.noise_shaping=1);0==e.substep_shaping&&(e.substep_shaping=2);e.noise_shaping_amp=1;e.noise_shaping_stop=1;-1==e.subblock_gain&&(e.subblock_gain=1);e.use_best_huffman=1;e.full_outer_loop=0;break;case 1:e.psymodel=1;0==e.noise_shaping&&(e.noise_shaping=1);0==e.substep_shaping&&(e.substep_shaping=2);e.noise_shaping_amp=2;e.noise_shaping_stop=1;-1==e.subblock_gain&&(e.subblock_gain= -1);e.use_best_huffman=1;e.full_outer_loop=0;break;case 0:e.psymodel=1,0==e.noise_shaping&&(e.noise_shaping=1),0==e.substep_shaping&&(e.substep_shaping=2),e.noise_shaping_amp=2,e.noise_shaping_stop=1,-1==e.subblock_gain&&(e.subblock_gain=1),e.use_best_huffman=1,e.full_outer_loop=0}b.ATH.useAdjust=0>a.athaa_type?3:a.athaa_type;b.ATH.aaSensitivityP=Math.pow(10,a.athaa_sensitivity/-10);null==a.short_blocks&&(a.short_blocks=ra.short_block_allowed);a.short_blocks!=ra.short_block_allowed||a.mode!=la.JOINT_STEREO&& -a.mode!=la.STEREO||(a.short_blocks=ra.short_block_coupled);0>a.quant_comp&&(a.quant_comp=1);0>a.quant_comp_short&&(a.quant_comp_short=0);0>a.msfix&&(a.msfix=0);a.exp_nspsytune|=1;0>a.internal_flags.nsPsy.attackthre&&(a.internal_flags.nsPsy.attackthre=Pb.NSATTACKTHRE);0>a.internal_flags.nsPsy.attackthre_s&&(a.internal_flags.nsPsy.attackthre_s=Pb.NSATTACKTHRE_S);0>a.scale&&(a.scale=1);0>a.ATHtype&&(a.ATHtype=4);0>a.ATHcurve&&(a.ATHcurve=4);0>a.athaa_loudapprox&&(a.athaa_loudapprox=2);0>a.interChRatio&& -(a.interChRatio=0);null==a.useTemporal&&(a.useTemporal=!0);b.slot_lag=b.frac_SpF=0;a.VBR==G.vbr_off&&(b.slot_lag=b.frac_SpF=72E3*(a.version+1)*a.brate%a.out_samplerate|0);q.iteration_init(a);p.psymodel_init(a);return 0};this.lame_encode_flush=function(a,e,f,g){var k=a.internal_flags,l=dc([2,1152]),h=0,m=k.mf_samples_to_encode-c.POSTDELAY,p=b(a);if(1>k.mf_samples_to_encode)return 0;var n=0;a.in_samplerate!=a.out_samplerate&&(m+=16*a.out_samplerate/a.in_samplerate);var q=a.framesize-m%a.framesize;576> -q&&(q+=a.framesize);a.encoder_padding=q;for(q=(m+q)/a.framesize;0r&&(r=1);h=g-n;0==g&&(h=0);h=this.lame_encode_buffer(a,l[0],l[1],r,e,f,h);f+=h;n+=h;q-=m!=a.frameNum?1:0}k.mf_samples_to_encode=0;if(0>h)return h;h=g-n;0==g&&(h=0);d.flush_bitstream(a);h=d.copy_buffer(k,e,f,h,1);if(0>h)return h;f+=h;n+=h;h=g-n;0==g&&(h=0);if(a.write_id3tag_automatic){t.id3tag_write_v1(a);h=d.copy_buffer(k,e,f,h,0);if(0> -h)return h;n+=h}return n};this.lame_encode_buffer=function(a,b,d,c,e,f,g){var h=a.internal_flags,k=[null,null];if(4294479419!=h.Class_ID)return-3;if(0==c)return 0;if(null==h.in_buffer_0||h.in_buffer_nsamplesMath.abs(k)?Math.abs(c-k)<=1E-6*Math.abs(c):Math.abs(c-k)<=1E-6*Math.abs(k)};qa.NEQ=function(c,k){return!qa.EQ(c,k)};zb.NUMTOCENTRIES=100;zb.MAXFRAMESIZE=2880; -var w={t1HB:[1,1,1,0],t2HB:[1,2,1,3,1,1,3,2,0],t3HB:[3,2,1,1,1,1,3,2,0],t5HB:[1,2,6,5,3,1,4,4,7,5,7,1,6,1,1,0],t6HB:[7,3,5,1,6,2,3,2,5,4,4,1,3,3,2,0],t7HB:[1,2,10,19,16,10,3,3,7,10,5,3,11,4,13,17,8,4,12,11,18,15,11,2,7,6,9,14,3,1,6,4,5,3,2,0],t8HB:[3,4,6,18,12,5,5,1,2,16,9,3,7,3,5,14,7,3,19,17,15,13,10,4,13,5,8,11,5,1,12,4,4,1,1,0],t9HB:[7,5,9,14,15,7,6,4,5,5,6,7,7,6,8,8,8,5,15,6,9,10,5,1,11,7,9,6,4,1,14,4,6,2,6,0],t10HB:[1,2,10,23,35,30,12,17,3,3,8,12,18,21,12,7,11,9,15,21,32,40,19,6,14,13,22,34, -46,23,18,7,20,19,33,47,27,22,9,3,31,22,41,26,21,20,5,3,14,13,10,11,16,6,5,1,9,8,7,8,4,4,2,0],t11HB:[3,4,10,24,34,33,21,15,5,3,4,10,32,17,11,10,11,7,13,18,30,31,20,5,25,11,19,59,27,18,12,5,35,33,31,58,30,16,7,5,28,26,32,19,17,15,8,14,14,12,9,13,14,9,4,1,11,4,6,6,6,3,2,0],t12HB:[9,6,16,33,41,39,38,26,7,5,6,9,23,16,26,11,17,7,11,14,21,30,10,7,17,10,15,12,18,28,14,5,32,13,22,19,18,16,9,5,40,17,31,29,17,13,4,2,27,12,11,15,10,7,4,1,27,12,8,12,6,3,1,0],t13HB:[1,5,14,21,34,51,46,71,42,52,68,52,67,44,43,19, -3,4,12,19,31,26,44,33,31,24,32,24,31,35,22,14,15,13,23,36,59,49,77,65,29,40,30,40,27,33,42,16,22,20,37,61,56,79,73,64,43,76,56,37,26,31,25,14,35,16,60,57,97,75,114,91,54,73,55,41,48,53,23,24,58,27,50,96,76,70,93,84,77,58,79,29,74,49,41,17,47,45,78,74,115,94,90,79,69,83,71,50,59,38,36,15,72,34,56,95,92,85,91,90,86,73,77,65,51,44,43,42,43,20,30,44,55,78,72,87,78,61,46,54,37,30,20,16,53,25,41,37,44,59,54,81,66,76,57,54,37,18,39,11,35,33,31,57,42,82,72,80,47,58,55,21,22,26,38,22,53,25,23,38,70,60,51, -36,55,26,34,23,27,14,9,7,34,32,28,39,49,75,30,52,48,40,52,28,18,17,9,5,45,21,34,64,56,50,49,45,31,19,12,15,10,7,6,3,48,23,20,39,36,35,53,21,16,23,13,10,6,1,4,2,16,15,17,27,25,20,29,11,17,12,16,8,1,1,0,1],t15HB:[7,12,18,53,47,76,124,108,89,123,108,119,107,81,122,63,13,5,16,27,46,36,61,51,42,70,52,83,65,41,59,36,19,17,15,24,41,34,59,48,40,64,50,78,62,80,56,33,29,28,25,43,39,63,55,93,76,59,93,72,54,75,50,29,52,22,42,40,67,57,95,79,72,57,89,69,49,66,46,27,77,37,35,66,58,52,91,74,62,48,79,63,90,62,40, -38,125,32,60,56,50,92,78,65,55,87,71,51,73,51,70,30,109,53,49,94,88,75,66,122,91,73,56,42,64,44,21,25,90,43,41,77,73,63,56,92,77,66,47,67,48,53,36,20,71,34,67,60,58,49,88,76,67,106,71,54,38,39,23,15,109,53,51,47,90,82,58,57,48,72,57,41,23,27,62,9,86,42,40,37,70,64,52,43,70,55,42,25,29,18,11,11,118,68,30,55,50,46,74,65,49,39,24,16,22,13,14,7,91,44,39,38,34,63,52,45,31,52,28,19,14,8,9,3,123,60,58,53,47,43,32,22,37,24,17,12,15,10,2,1,71,37,34,30,28,20,17,26,21,16,10,6,8,6,2,0],t16HB:[1,5,14,44,74,63, -110,93,172,149,138,242,225,195,376,17,3,4,12,20,35,62,53,47,83,75,68,119,201,107,207,9,15,13,23,38,67,58,103,90,161,72,127,117,110,209,206,16,45,21,39,69,64,114,99,87,158,140,252,212,199,387,365,26,75,36,68,65,115,101,179,164,155,264,246,226,395,382,362,9,66,30,59,56,102,185,173,265,142,253,232,400,388,378,445,16,111,54,52,100,184,178,160,133,257,244,228,217,385,366,715,10,98,48,91,88,165,157,148,261,248,407,397,372,380,889,884,8,85,84,81,159,156,143,260,249,427,401,392,383,727,713,708,7,154,76,73, -141,131,256,245,426,406,394,384,735,359,710,352,11,139,129,67,125,247,233,229,219,393,743,737,720,885,882,439,4,243,120,118,115,227,223,396,746,742,736,721,712,706,223,436,6,202,224,222,218,216,389,386,381,364,888,443,707,440,437,1728,4,747,211,210,208,370,379,734,723,714,1735,883,877,876,3459,865,2,377,369,102,187,726,722,358,711,709,866,1734,871,3458,870,434,0,12,10,7,11,10,17,11,9,13,12,10,7,5,3,1,3],t24HB:[15,13,46,80,146,262,248,434,426,669,653,649,621,517,1032,88,14,12,21,38,71,130,122,216, -209,198,327,345,319,297,279,42,47,22,41,74,68,128,120,221,207,194,182,340,315,295,541,18,81,39,75,70,134,125,116,220,204,190,178,325,311,293,271,16,147,72,69,135,127,118,112,210,200,188,352,323,306,285,540,14,263,66,129,126,119,114,214,202,192,180,341,317,301,281,262,12,249,123,121,117,113,215,206,195,185,347,330,308,291,272,520,10,435,115,111,109,211,203,196,187,353,332,313,298,283,531,381,17,427,212,208,205,201,193,186,177,169,320,303,286,268,514,377,16,335,199,197,191,189,181,174,333,321,305,289, -275,521,379,371,11,668,184,183,179,175,344,331,314,304,290,277,530,383,373,366,10,652,346,171,168,164,318,309,299,287,276,263,513,375,368,362,6,648,322,316,312,307,302,292,284,269,261,512,376,370,364,359,4,620,300,296,294,288,282,273,266,515,380,374,369,365,361,357,2,1033,280,278,274,267,264,259,382,378,372,367,363,360,358,356,0,43,20,19,17,15,13,11,9,7,6,4,7,5,3,1,3],t32HB:[1,10,8,20,12,20,16,32,14,12,24,0,28,16,24,16],t33HB:[15,28,26,48,22,40,36,64,14,24,20,32,12,16,8,0],t1l:[1,4,3,5],t2l:[1,4, -7,4,5,7,6,7,8],t3l:[2,3,7,4,4,7,6,7,8],t5l:[1,4,7,8,4,5,8,9,7,8,9,10,8,8,9,10],t6l:[3,4,6,8,4,4,6,7,5,6,7,8,7,7,8,9],t7l:[1,4,7,9,9,10,4,6,8,9,9,10,7,7,9,10,10,11,8,9,10,11,11,11,8,9,10,11,11,12,9,10,11,12,12,12],t8l:[2,4,7,9,9,10,4,4,6,10,10,10,7,6,8,10,10,11,9,10,10,11,11,12,9,9,10,11,12,12,10,10,11,11,13,13],t9l:[3,4,6,7,9,10,4,5,6,7,8,10,5,6,7,8,9,10,7,7,8,9,9,10,8,8,9,9,10,11,9,9,10,10,11,11],t10l:[1,4,7,9,10,10,10,11,4,6,8,9,10,11,10,10,7,8,9,10,11,12,11,11,8,9,10,11,12,12,11,12,9,10,11,12, -12,12,12,12,10,11,12,12,13,13,12,13,9,10,11,12,12,12,13,13,10,10,11,12,12,13,13,13],t11l:[2,4,6,8,9,10,9,10,4,5,6,8,10,10,9,10,6,7,8,9,10,11,10,10,8,8,9,11,10,12,10,11,9,10,10,11,11,12,11,12,9,10,11,12,12,13,12,13,9,9,9,10,11,12,12,12,9,9,10,11,12,12,12,12],t12l:[4,4,6,8,9,10,10,10,4,5,6,7,9,9,10,10,6,6,7,8,9,10,9,10,7,7,8,8,9,10,10,10,8,8,9,9,10,10,10,11,9,9,10,10,10,11,10,11,9,9,9,10,10,11,11,12,10,10,10,11,11,11,11,12],t13l:[1,5,7,8,9,10,10,11,10,11,12,12,13,13,14,14,4,6,8,9,10,10,11,11,11,11, -12,12,13,14,14,14,7,8,9,10,11,11,12,12,11,12,12,13,13,14,15,15,8,9,10,11,11,12,12,12,12,13,13,13,13,14,15,15,9,9,11,11,12,12,13,13,12,13,13,14,14,15,15,16,10,10,11,12,12,12,13,13,13,13,14,13,15,15,16,16,10,11,12,12,13,13,13,13,13,14,14,14,15,15,16,16,11,11,12,13,13,13,14,14,14,14,15,15,15,16,18,18,10,10,11,12,12,13,13,14,14,14,14,15,15,16,17,17,11,11,12,12,13,13,13,15,14,15,15,16,16,16,18,17,11,12,12,13,13,14,14,15,14,15,16,15,16,17,18,19,12,12,12,13,14,14,14,14,15,15,15,16,17,17,17,18,12,13,13,14, -14,15,14,15,16,16,17,17,17,18,18,18,13,13,14,15,15,15,16,16,16,16,16,17,18,17,18,18,14,14,14,15,15,15,17,16,16,19,17,17,17,19,18,18,13,14,15,16,16,16,17,16,17,17,18,18,21,20,21,18],t15l:[3,5,6,8,8,9,10,10,10,11,11,12,12,12,13,14,5,5,7,8,9,9,10,10,10,11,11,12,12,12,13,13,6,7,7,8,9,9,10,10,10,11,11,12,12,13,13,13,7,8,8,9,9,10,10,11,11,11,12,12,12,13,13,13,8,8,9,9,10,10,11,11,11,11,12,12,12,13,13,13,9,9,9,10,10,10,11,11,11,11,12,12,13,13,13,14,10,9,10,10,10,11,11,11,11,12,12,12,13,13,14,14,10,10,10, -11,11,11,11,12,12,12,12,12,13,13,13,14,10,10,10,11,11,11,11,12,12,12,12,13,13,14,14,14,10,10,11,11,11,11,12,12,12,13,13,13,13,14,14,14,11,11,11,11,12,12,12,12,12,13,13,13,13,14,15,14,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,15,12,12,11,12,12,12,13,13,13,13,13,13,14,14,15,15,12,12,12,12,12,13,13,13,13,14,14,14,14,14,15,15,13,13,13,13,13,13,13,13,14,14,14,14,15,15,14,15,13,13,13,13,13,13,13,14,14,14,14,14,15,15,15,15],t16_5l:[1,5,7,9,10,10,11,11,12,12,12,13,13,13,14,11,4,6,8,9,10,11,11,11,12,12, -12,13,14,13,14,11,7,8,9,10,11,11,12,12,13,12,13,13,13,14,14,12,9,9,10,11,11,12,12,12,13,13,14,14,14,15,15,13,10,10,11,11,12,12,13,13,13,14,14,14,15,15,15,12,10,10,11,11,12,13,13,14,13,14,14,15,15,15,16,13,11,11,11,12,13,13,13,13,14,14,14,14,15,15,16,13,11,11,12,12,13,13,13,14,14,15,15,15,15,17,17,13,11,12,12,13,13,13,14,14,15,15,15,15,16,16,16,13,12,12,12,13,13,14,14,15,15,15,15,16,15,16,15,14,12,13,12,13,14,14,14,14,15,16,16,16,17,17,16,13,13,13,13,13,14,14,15,16,16,16,16,16,16,15,16,14,13,14,14, -14,14,15,15,15,15,17,16,16,16,16,18,14,15,14,14,14,15,15,16,16,16,18,17,17,17,19,17,14,14,15,13,14,16,16,15,16,16,17,18,17,19,17,16,14,11,11,11,12,12,13,13,13,14,14,14,14,14,14,14,12],t16l:[1,5,7,9,10,10,11,11,12,12,12,13,13,13,14,10,4,6,8,9,10,11,11,11,12,12,12,13,14,13,14,10,7,8,9,10,11,11,12,12,13,12,13,13,13,14,14,11,9,9,10,11,11,12,12,12,13,13,14,14,14,15,15,12,10,10,11,11,12,12,13,13,13,14,14,14,15,15,15,11,10,10,11,11,12,13,13,14,13,14,14,15,15,15,16,12,11,11,11,12,13,13,13,13,14,14,14,14, -15,15,16,12,11,11,12,12,13,13,13,14,14,15,15,15,15,17,17,12,11,12,12,13,13,13,14,14,15,15,15,15,16,16,16,12,12,12,12,13,13,14,14,15,15,15,15,16,15,16,15,13,12,13,12,13,14,14,14,14,15,16,16,16,17,17,16,12,13,13,13,13,14,14,15,16,16,16,16,16,16,15,16,13,13,14,14,14,14,15,15,15,15,17,16,16,16,16,18,13,15,14,14,14,15,15,16,16,16,18,17,17,17,19,17,13,14,15,13,14,16,16,15,16,16,17,18,17,19,17,16,13,10,10,10,11,11,12,12,12,13,13,13,13,13,13,13,10],t24l:[4,5,7,8,9,10,10,11,11,12,12,12,12,12,13,10,5,6,7,8, -9,10,10,11,11,11,12,12,12,12,12,10,7,7,8,9,9,10,10,11,11,11,11,12,12,12,13,9,8,8,9,9,10,10,10,11,11,11,11,12,12,12,12,9,9,9,9,10,10,10,10,11,11,11,12,12,12,12,13,9,10,9,10,10,10,10,11,11,11,11,12,12,12,12,12,9,10,10,10,10,10,11,11,11,11,12,12,12,12,12,13,9,11,10,10,10,11,11,11,11,12,12,12,12,12,13,13,10,11,11,11,11,11,11,11,11,11,12,12,12,12,13,13,10,11,11,11,11,11,11,11,12,12,12,12,12,13,13,13,10,12,11,11,11,11,12,12,12,12,12,12,13,13,13,13,10,12,12,11,11,11,12,12,12,12,12,12,13,13,13,13,10,12,12, -12,12,12,12,12,12,12,12,13,13,13,13,13,10,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,10,13,12,12,12,12,12,12,13,13,13,13,13,13,13,13,10,9,9,9,9,9,9,9,9,9,9,9,10,10,10,10,6],t32l:[1,5,5,7,5,8,7,9,5,7,7,9,7,9,9,10],t33l:[4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8]};w.ht=[new U(0,0,null,null),new U(2,0,w.t1HB,w.t1l),new U(3,0,w.t2HB,w.t2l),new U(3,0,w.t3HB,w.t3l),new U(0,0,null,null),new U(4,0,w.t5HB,w.t5l),new U(4,0,w.t6HB,w.t6l),new U(6,0,w.t7HB,w.t7l),new U(6,0,w.t8HB,w.t8l),new U(6,0,w.t9HB,w.t9l),new U(8, -0,w.t10HB,w.t10l),new U(8,0,w.t11HB,w.t11l),new U(8,0,w.t12HB,w.t12l),new U(16,0,w.t13HB,w.t13l),new U(0,0,null,w.t16_5l),new U(16,0,w.t15HB,w.t15l),new U(1,1,w.t16HB,w.t16l),new U(2,3,w.t16HB,w.t16l),new U(3,7,w.t16HB,w.t16l),new U(4,15,w.t16HB,w.t16l),new U(6,63,w.t16HB,w.t16l),new U(8,255,w.t16HB,w.t16l),new U(10,1023,w.t16HB,w.t16l),new U(13,8191,w.t16HB,w.t16l),new U(4,15,w.t24HB,w.t24l),new U(5,31,w.t24HB,w.t24l),new U(6,63,w.t24HB,w.t24l),new U(7,127,w.t24HB,w.t24l),new U(8,255,w.t24HB,w.t24l), -new U(9,511,w.t24HB,w.t24l),new U(11,2047,w.t24HB,w.t24l),new U(13,8191,w.t24HB,w.t24l),new U(0,0,w.t32HB,w.t32l),new U(0,0,w.t33HB,w.t33l)];w.largetbl=[65540,327685,458759,589832,655369,655370,720906,720907,786443,786444,786444,851980,851980,851980,917517,655370,262149,393222,524295,589832,655369,720906,720906,720907,786443,786443,786444,851980,917516,851980,917516,655370,458759,524295,589832,655369,720905,720906,786442,786443,851979,786443,851979,851980,851980,917516,917517,720905,589832,589832, -655369,720905,720906,786442,786442,786443,851979,851979,917515,917516,917516,983052,983052,786441,655369,655369,720905,720906,786442,786442,851978,851979,851979,917515,917516,917516,983052,983052,983053,720905,655370,655369,720906,720906,786442,851978,851979,917515,851979,917515,917516,983052,983052,983052,1048588,786441,720906,720906,720906,786442,851978,851979,851979,851979,917515,917516,917516,917516,983052,983052,1048589,786441,720907,720906,786442,786442,851979,851979,851979,917515,917516,983052, -983052,983052,983052,1114125,1114125,786442,720907,786443,786443,851979,851979,851979,917515,917515,983051,983052,983052,983052,1048588,1048589,1048589,786442,786443,786443,786443,851979,851979,917515,917515,983052,983052,983052,983052,1048588,983053,1048589,983053,851978,786444,851979,786443,851979,917515,917516,917516,917516,983052,1048588,1048588,1048589,1114125,1114125,1048589,786442,851980,851980,851979,851979,917515,917516,983052,1048588,1048588,1048588,1048588,1048589,1048589,983053,1048589, -851978,851980,917516,917516,917516,917516,983052,983052,983052,983052,1114124,1048589,1048589,1048589,1048589,1179661,851978,983052,917516,917516,917516,983052,983052,1048588,1048588,1048589,1179661,1114125,1114125,1114125,1245197,1114125,851978,917517,983052,851980,917516,1048588,1048588,983052,1048589,1048589,1114125,1179661,1114125,1245197,1114125,1048589,851978,655369,655369,655369,720905,720905,786441,786441,786441,851977,851977,851977,851978,851978,851978,851978,655366];w.table23=[65538,262147, -458759,262148,327684,458759,393222,458759,524296];w.table56=[65539,262148,458758,524296,262148,327684,524294,589831,458757,524294,589831,655368,524295,524295,589832,655369];w.bitrate_table=[[0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,-1],[0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,-1],[0,8,16,24,32,40,48,56,64,-1,-1,-1,-1,-1,-1,-1]];w.samplerate_table=[[22050,24E3,16E3,-1],[44100,48E3,32E3,-1],[11025,12E3,8E3,-1]];w.scfsi_band=[0,6,11,16,21];ia.Q_MAX=257;ia.Q_MAX2=116;ia.LARGE_BITS=1E5; -ia.IXMAX_VAL=8206;var sa={};sa.SFBMAX=3*c.SBMAX_s;c.ENCDELAY=576;c.POSTDELAY=1152;c.MDCTDELAY=48;c.FFTOFFSET=224+c.MDCTDELAY;c.DECDELAY=528;c.SBLIMIT=32;c.CBANDS=64;c.SBPSY_l=21;c.SBPSY_s=12;c.SBMAX_l=22;c.SBMAX_s=13;c.PSFB21=6;c.PSFB12=6;c.BLKSIZE=1024;c.HBLKSIZE=c.BLKSIZE/2+1;c.BLKSIZE_s=256;c.HBLKSIZE_s=c.BLKSIZE_s/2+1;c.NORM_TYPE=0;c.START_TYPE=1;c.SHORT_TYPE=2;c.STOP_TYPE=3;c.MPG_MD_LR_LR=0;c.MPG_MD_LR_I=1;c.MPG_MD_MS_LR=2;c.MPG_MD_MS_I=3;c.fircoef=[-.1039435,-.1892065,-.0432472*5,-.155915,3.898045E-17, -.0467745*5,.50455,.756825,.187098*5];da.MFSIZE=3456+c.ENCDELAY-c.MDCTDELAY;da.MAX_HEADER_BUF=256;da.MAX_BITS_PER_CHANNEL=4095;da.MAX_BITS_PER_GRANULE=7680;da.BPC=320;Fa.RIFF=cc("RIFF");Fa.WAVE=cc("WAVE");Fa.fmt_=cc("fmt ");Fa.data=cc("data");Fa.readHeader=function(c){var k=new Fa,n=c.getUint32(0,!1);if(Fa.RIFF==n&&(c.getUint32(4,!0),Fa.WAVE==c.getUint32(8,!1)&&Fa.fmt_==c.getUint32(12,!1))){var u=c.getUint32(16,!0),w=20;switch(u){case 16:case 18:k.channels=c.getUint16(w+2,!0);k.sampleRate=c.getUint32(w+ -4,!0);break;default:throw"extended fmt chunk not implemented";}w+=u;u=Fa.data;for(var B=0;u!=n;){n=c.getUint32(w,!1);B=c.getUint32(w+4,!0);if(u==n)break;w+=B+8}k.dataLen=B;k.dataOffset=w+8;return k}};sa.SFBMAX=3*c.SBMAX_s;lamejs.Mp3Encoder=function(c,k,n){3!=arguments.length&&(console.error("WARN: Mp3Encoder(channels, samplerate, kbps) not specified"),c=1,k=44100,n=128);var u=new W,w=new Kc,B=new Y,G=new qa,f=new wc,b=new ia,v=new Ec,a=new zb,m=new mc,z=new Nc,e=new xc,l=new qb,d=new Lc,g=new Mc; -u.setModules(B,G,f,b,v,a,m,z,g);G.setModules(B,g,m,a);z.setModules(G,m);f.setModules(u);v.setModules(G,e,b,l);b.setModules(l,e,u.enc.psy);e.setModules(G);l.setModules(b);a.setModules(u,G,m);w.setModules(d,g);d.setModules(m,z,f);var q=u.lame_init();q.num_channels=c;q.in_samplerate=k;q.brate=n;q.mode=la.STEREO;q.quality=3;q.bWriteVbrTag=!1;q.disable_reservoir=!0;q.write_id3tag_automatic=!1;u.lame_init_params(q);var D=1152,p=0|1.25*D+7200,r=new Int8Array(p);this.encodeBuffer=function(a,b){1==c&&(b=a); -a.length>D&&(D=a.length,p=0|1.25*D+7200,r=new Int8Array(p));a=u.lame_encode_buffer(q,a,b,a.length,r,0,p);return new Int8Array(r.subarray(0,a))};this.flush=function(){var a=u.lame_encode_flush(q,r,0,p);return new Int8Array(r.subarray(0,a))}};lamejs.WavHeader=Fa}lamejs(); -export default lamejs; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/makeall.sh b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/makeall.sh deleted file mode 100644 index c9c2bc205..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/makeall.sh +++ /dev/null @@ -1,16 +0,0 @@ -( -echo 'function lamejs() {' -browserify --list src/js/index.js | grep lamejs | grep -v node_modules | xargs cat | grep -v -e 'common\..*;' -e 'require(' -e 'module.exports.*;$' | sed 's/^module.exports = {/var module_exports = {/'; -echo 'L3Side.SFBMAX = (Encoder.SBMAX_s * 3);' -echo '//testFullLength();' -echo 'lamejs.Mp3Encoder = Mp3Encoder;' -echo 'lamejs.WavHeader = WavHeader;' -echo '}' -echo "//fs=require('fs');" -echo 'lamejs();' -)| grep -v -e '^\s*assert\s*(.*);' >lame.all.js - -#cc=closure-compiler -jar=~/java/compiler.jar -cc="java -jar $jar" -$cc lame.all.js --language_in ECMASCRIPT5 --js_output_file lame.min.js diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/minify.sh b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/minify.sh deleted file mode 100644 index e8407561d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/minify.sh +++ /dev/null @@ -1,3 +0,0 @@ -jar=~/java/compiler.jar -cc="java -jar $jar" -$cc lame.all.js --language_in ECMASCRIPT5 --js_output_file lame.min.js diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/package.json b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/package.json deleted file mode 100644 index fa6719051..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "lamejs", - "version": "1.2.1", - "description": "Pure JavaScript MP3 Encoder", - "main": "src/js/index.js", - "type": "module", - "directories": { - "doc": "doc", - "test": "test" - }, - "scripts": { - "test": "node src/js/Tests.js" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/zhuker/lamejs.git" - }, - "keywords": [ - "mp3", - "encoder", - "audio", - "webaudio" - ], - "author": "Alex Zhukov", - "license": "LGPL-3.0", - "bugs": { - "url": "https://github.com/zhuker/lamejs/issues" - }, - "homepage": "https://github.com/zhuker/lamejs#readme", - "dependencies": { - "use-strict": "1.0.1" - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/pom.xml b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/pom.xml deleted file mode 100644 index adc93f943..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/pom.xml +++ /dev/null @@ -1,69 +0,0 @@ - - 4.0.0 - jump3r - jump3r - 1.0.3 - - - - src/main/resources - - LameUI.xml - picture.png - run.bat - run.sh - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - true - ui.LameUI - - - - - - maven-assembly-plugin - - - src/main/assembly/bundle.xml - - jump3r-1.0.3 - - - - make-assembly - package - - single - - - - - - - - - org.jma - jma-api - 1.0.1 - compile - - - org.swixml - swixml - 1.5.144 - - - junit - junit - 4.11 - - - \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/ATH.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/ATH.js deleted file mode 100644 index 6b196669f..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/ATH.js +++ /dev/null @@ -1,79 +0,0 @@ -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -var Encoder = require('./Encoder.js'); - -/** - * ATH related stuff, if something new ATH related has to be added, please plug - * it here into the ATH. - */ -function ATH() { - /** - * Method for the auto adjustment. - */ - this.useAdjust = 0; - /** - * factor for tuning the (sample power) point below which adaptive threshold - * of hearing adjustment occurs - */ - this.aaSensitivityP = 0.; - /** - * Lowering based on peak volume, 1 = no lowering. - */ - this.adjust = 0.; - /** - * Limit for dynamic ATH adjust. - */ - this.adjustLimit = 0.; - /** - * Determined to lower x dB each second. - */ - this.decay = 0.; - /** - * Lowest ATH value. - */ - this.floor = 0.; - /** - * ATH for sfbs in long blocks. - */ - this.l = new_float(Encoder.SBMAX_l); - /** - * ATH for sfbs in short blocks. - */ - this.s = new_float(Encoder.SBMAX_s); - /** - * ATH for partitioned sfb21 in long blocks. - */ - this.psfb21 = new_float(Encoder.PSFB21); - /** - * ATH for partitioned sfb12 in short blocks. - */ - this.psfb12 = new_float(Encoder.PSFB12); - /** - * ATH for long block convolution bands. - */ - this.cb_l = new_float(Encoder.CBANDS); - /** - * ATH for short block convolution bands. - */ - this.cb_s = new_float(Encoder.CBANDS); - /** - * Equal loudness weights (based on ATH). - */ - this.eql_w = new_float(Encoder.BLKSIZE / 2); -} - -module.exports = ATH; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/BitStream.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/BitStream.js deleted file mode 100644 index 054941f68..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/BitStream.js +++ /dev/null @@ -1,1027 +0,0 @@ -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -var Takehiro = require('./Takehiro.js'); -var Tables = require('./Tables.js'); -var Encoder = require('./Encoder.js'); -var LameInternalFlags = require('./LameInternalFlags.js'); - -BitStream.EQ = function (a, b) { - return (Math.abs(a) > Math.abs(b)) ? (Math.abs((a) - (b)) <= (Math - .abs(a) * 1e-6)) - : (Math.abs((a) - (b)) <= (Math.abs(b) * 1e-6)); -}; - -BitStream.NEQ = function (a, b) { - return !BitStream.EQ(a, b); -}; - -function BitStream() { - var Lame = require('./Lame.js'); - var self = this; - var CRC16_POLYNOMIAL = 0x8005; - - /* - * we work with ints, so when doing bit manipulation, we limit ourselves to - * MAX_LENGTH-2 just to be on the safe side - */ - var MAX_LENGTH = 32; - - //GainAnalysis ga; - //MPGLib mpg; - //Version ver; - //VBRTag vbr; - var ga = null; - var mpg = null; - var ver = null; - var vbr = null; - - //public final void setModules(GainAnalysis ga, MPGLib mpg, Version ver, - // VBRTag vbr) { - - this.setModules = function (_ga, _mpg, _ver, _vbr) { - ga = _ga; - mpg = _mpg; - ver = _ver; - vbr = _vbr; - }; - - /** - * Bit stream buffer. - */ - //private byte[] buf; - var buf = null; - /** - * Bit counter of bit stream. - */ - var totbit = 0; - /** - * Pointer to top byte in buffer. - */ - var bufByteIdx = 0; - /** - * Pointer to top bit of top byte in buffer. - */ - var bufBitIdx = 0; - - /** - * compute bitsperframe and mean_bits for a layer III frame - */ - this.getframebits = function (gfp) { - var gfc = gfp.internal_flags; - var bit_rate; - - /* get bitrate in kbps [?] */ - if (gfc.bitrate_index != 0) - bit_rate = Tables.bitrate_table[gfp.version][gfc.bitrate_index]; - else - bit_rate = gfp.brate; - assert(8 <= bit_rate && bit_rate <= 640); - - /* main encoding routine toggles padding on and off */ - /* one Layer3 Slot consists of 8 bits */ - var bytes = 0 | (gfp.version + 1) * 72000 * bit_rate / gfp.out_samplerate + gfc.padding; - return 8 * bytes; - }; - - function putheader_bits(gfc) { - System.arraycopy(gfc.header[gfc.w_ptr].buf, 0, buf, bufByteIdx, gfc.sideinfo_len); - bufByteIdx += gfc.sideinfo_len; - totbit += gfc.sideinfo_len * 8; - gfc.w_ptr = (gfc.w_ptr + 1) & (LameInternalFlags.MAX_HEADER_BUF - 1); - } - - /** - * write j bits into the bit stream - */ - function putbits2(gfc, val, j) { - assert(j < MAX_LENGTH - 2); - - while (j > 0) { - var k; - if (bufBitIdx == 0) { - bufBitIdx = 8; - bufByteIdx++; - assert(bufByteIdx < Lame.LAME_MAXMP3BUFFER); - assert(gfc.header[gfc.w_ptr].write_timing >= totbit); - if (gfc.header[gfc.w_ptr].write_timing == totbit) { - putheader_bits(gfc); - } - buf[bufByteIdx] = 0; - } - - k = Math.min(j, bufBitIdx); - j -= k; - - bufBitIdx -= k; - - assert(j < MAX_LENGTH); - /* 32 too large on 32 bit machines */ - assert(bufBitIdx < MAX_LENGTH); - - buf[bufByteIdx] |= ((val >> j) << bufBitIdx); - totbit += k; - } - } - - /** - * write j bits into the bit stream, ignoring frame headers - */ - function putbits_noheaders(gfc, val, j) { - assert(j < MAX_LENGTH - 2); - - while (j > 0) { - var k; - if (bufBitIdx == 0) { - bufBitIdx = 8; - bufByteIdx++; - assert(bufByteIdx < Lame.LAME_MAXMP3BUFFER); - buf[bufByteIdx] = 0; - } - - k = Math.min(j, bufBitIdx); - j -= k; - - bufBitIdx -= k; - - assert(j < MAX_LENGTH); - /* 32 too large on 32 bit machines */ - assert(bufBitIdx < MAX_LENGTH); - - buf[bufByteIdx] |= ((val >> j) << bufBitIdx); - totbit += k; - } - } - - /** - * Some combinations of bitrate, Fs, and stereo make it impossible to stuff - * out a frame using just main_data, due to the limited number of bits to - * indicate main_data_length. In these situations, we put stuffing bits into - * the ancillary data... - */ - function drain_into_ancillary(gfp, remainingBits) { - var gfc = gfp.internal_flags; - var i; - assert(remainingBits >= 0); - - if (remainingBits >= 8) { - putbits2(gfc, 0x4c, 8); - remainingBits -= 8; - } - if (remainingBits >= 8) { - putbits2(gfc, 0x41, 8); - remainingBits -= 8; - } - if (remainingBits >= 8) { - putbits2(gfc, 0x4d, 8); - remainingBits -= 8; - } - if (remainingBits >= 8) { - putbits2(gfc, 0x45, 8); - remainingBits -= 8; - } - - if (remainingBits >= 32) { - var version = ver.getLameShortVersion(); - if (remainingBits >= 32) - for (i = 0; i < version.length && remainingBits >= 8; ++i) { - remainingBits -= 8; - putbits2(gfc, version.charAt(i), 8); - } - } - - for (; remainingBits >= 1; remainingBits -= 1) { - putbits2(gfc, gfc.ancillary_flag, 1); - gfc.ancillary_flag ^= (!gfp.disable_reservoir ? 1 : 0); - } - - assert(remainingBits == 0); - - } - - /** - * write N bits into the header - */ - function writeheader(gfc, val, j) { - var ptr = gfc.header[gfc.h_ptr].ptr; - - while (j > 0) { - var k = Math.min(j, 8 - (ptr & 7)); - j -= k; - assert(j < MAX_LENGTH); - /* >> 32 too large for 32 bit machines */ - - gfc.header[gfc.h_ptr].buf[ptr >> 3] |= ((val >> j)) << (8 - (ptr & 7) - k); - ptr += k; - } - gfc.header[gfc.h_ptr].ptr = ptr; - } - - function CRC_update(value, crc) { - value <<= 8; - for (var i = 0; i < 8; i++) { - value <<= 1; - crc <<= 1; - - if ((((crc ^ value) & 0x10000) != 0)) - crc ^= CRC16_POLYNOMIAL; - } - return crc; - } - - this.CRC_writeheader = function (gfc, header) { - var crc = 0xffff; - /* (jo) init crc16 for error_protection */ - - crc = CRC_update(header[2] & 0xff, crc); - crc = CRC_update(header[3] & 0xff, crc); - for (var i = 6; i < gfc.sideinfo_len; i++) { - crc = CRC_update(header[i] & 0xff, crc); - } - - header[4] = (byte)(crc >> 8); - header[5] = (byte)(crc & 255); - }; - - function encodeSideInfo2(gfp, bitsPerFrame) { - var gfc = gfp.internal_flags; - var l3_side; - var gr, ch; - - l3_side = gfc.l3_side; - gfc.header[gfc.h_ptr].ptr = 0; - Arrays.fill(gfc.header[gfc.h_ptr].buf, 0, gfc.sideinfo_len, 0); - if (gfp.out_samplerate < 16000) - writeheader(gfc, 0xffe, 12); - else - writeheader(gfc, 0xfff, 12); - writeheader(gfc, (gfp.version), 1); - writeheader(gfc, 4 - 3, 2); - writeheader(gfc, (!gfp.error_protection ? 1 : 0), 1); - writeheader(gfc, (gfc.bitrate_index), 4); - writeheader(gfc, (gfc.samplerate_index), 2); - writeheader(gfc, (gfc.padding), 1); - writeheader(gfc, (gfp.extension), 1); - writeheader(gfc, (gfp.mode.ordinal()), 2); - writeheader(gfc, (gfc.mode_ext), 2); - writeheader(gfc, (gfp.copyright), 1); - writeheader(gfc, (gfp.original), 1); - writeheader(gfc, (gfp.emphasis), 2); - if (gfp.error_protection) { - writeheader(gfc, 0, 16); - /* dummy */ - } - - if (gfp.version == 1) { - /* MPEG1 */ - assert(l3_side.main_data_begin >= 0); - writeheader(gfc, (l3_side.main_data_begin), 9); - - if (gfc.channels_out == 2) - writeheader(gfc, l3_side.private_bits, 3); - else - writeheader(gfc, l3_side.private_bits, 5); - - for (ch = 0; ch < gfc.channels_out; ch++) { - var band; - for (band = 0; band < 4; band++) { - writeheader(gfc, l3_side.scfsi[ch][band], 1); - } - } - - for (gr = 0; gr < 2; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - var gi = l3_side.tt[gr][ch]; - writeheader(gfc, gi.part2_3_length + gi.part2_length, 12); - writeheader(gfc, gi.big_values / 2, 9); - writeheader(gfc, gi.global_gain, 8); - writeheader(gfc, gi.scalefac_compress, 4); - - if (gi.block_type != Encoder.NORM_TYPE) { - writeheader(gfc, 1, 1); - /* window_switching_flag */ - writeheader(gfc, gi.block_type, 2); - writeheader(gfc, gi.mixed_block_flag, 1); - - if (gi.table_select[0] == 14) - gi.table_select[0] = 16; - writeheader(gfc, gi.table_select[0], 5); - if (gi.table_select[1] == 14) - gi.table_select[1] = 16; - writeheader(gfc, gi.table_select[1], 5); - - writeheader(gfc, gi.subblock_gain[0], 3); - writeheader(gfc, gi.subblock_gain[1], 3); - writeheader(gfc, gi.subblock_gain[2], 3); - } else { - writeheader(gfc, 0, 1); - /* window_switching_flag */ - if (gi.table_select[0] == 14) - gi.table_select[0] = 16; - writeheader(gfc, gi.table_select[0], 5); - if (gi.table_select[1] == 14) - gi.table_select[1] = 16; - writeheader(gfc, gi.table_select[1], 5); - if (gi.table_select[2] == 14) - gi.table_select[2] = 16; - writeheader(gfc, gi.table_select[2], 5); - - assert(0 <= gi.region0_count && gi.region0_count < 16); - assert(0 <= gi.region1_count && gi.region1_count < 8); - writeheader(gfc, gi.region0_count, 4); - writeheader(gfc, gi.region1_count, 3); - } - writeheader(gfc, gi.preflag, 1); - writeheader(gfc, gi.scalefac_scale, 1); - writeheader(gfc, gi.count1table_select, 1); - } - } - } else { - /* MPEG2 */ - assert(l3_side.main_data_begin >= 0); - writeheader(gfc, (l3_side.main_data_begin), 8); - writeheader(gfc, l3_side.private_bits, gfc.channels_out); - - gr = 0; - for (ch = 0; ch < gfc.channels_out; ch++) { - var gi = l3_side.tt[gr][ch]; - writeheader(gfc, gi.part2_3_length + gi.part2_length, 12); - writeheader(gfc, gi.big_values / 2, 9); - writeheader(gfc, gi.global_gain, 8); - writeheader(gfc, gi.scalefac_compress, 9); - - if (gi.block_type != Encoder.NORM_TYPE) { - writeheader(gfc, 1, 1); - /* window_switching_flag */ - writeheader(gfc, gi.block_type, 2); - writeheader(gfc, gi.mixed_block_flag, 1); - - if (gi.table_select[0] == 14) - gi.table_select[0] = 16; - writeheader(gfc, gi.table_select[0], 5); - if (gi.table_select[1] == 14) - gi.table_select[1] = 16; - writeheader(gfc, gi.table_select[1], 5); - - writeheader(gfc, gi.subblock_gain[0], 3); - writeheader(gfc, gi.subblock_gain[1], 3); - writeheader(gfc, gi.subblock_gain[2], 3); - } else { - writeheader(gfc, 0, 1); - /* window_switching_flag */ - if (gi.table_select[0] == 14) - gi.table_select[0] = 16; - writeheader(gfc, gi.table_select[0], 5); - if (gi.table_select[1] == 14) - gi.table_select[1] = 16; - writeheader(gfc, gi.table_select[1], 5); - if (gi.table_select[2] == 14) - gi.table_select[2] = 16; - writeheader(gfc, gi.table_select[2], 5); - - assert(0 <= gi.region0_count && gi.region0_count < 16); - assert(0 <= gi.region1_count && gi.region1_count < 8); - writeheader(gfc, gi.region0_count, 4); - writeheader(gfc, gi.region1_count, 3); - } - - writeheader(gfc, gi.scalefac_scale, 1); - writeheader(gfc, gi.count1table_select, 1); - } - } - - if (gfp.error_protection) { - /* (jo) error_protection: add crc16 information to header */ - CRC_writeheader(gfc, gfc.header[gfc.h_ptr].buf); - } - - { - var old = gfc.h_ptr; - assert(gfc.header[old].ptr == gfc.sideinfo_len * 8); - - gfc.h_ptr = (old + 1) & (LameInternalFlags.MAX_HEADER_BUF - 1); - gfc.header[gfc.h_ptr].write_timing = gfc.header[old].write_timing - + bitsPerFrame; - - if (gfc.h_ptr == gfc.w_ptr) { - /* yikes! we are out of header buffer space */ - System.err - .println("Error: MAX_HEADER_BUF too small in bitstream.c \n"); - } - - } - } - - function huffman_coder_count1(gfc, gi) { - /* Write count1 area */ - var h = Tables.ht[gi.count1table_select + 32]; - var i, bits = 0; - - var ix = gi.big_values; - var xr = gi.big_values; - assert(gi.count1table_select < 2); - - for (i = (gi.count1 - gi.big_values) / 4; i > 0; --i) { - var huffbits = 0; - var p = 0, v; - - v = gi.l3_enc[ix + 0]; - if (v != 0) { - p += 8; - if (gi.xr[xr + 0] < 0) - huffbits++; - assert(v <= 1); - } - - v = gi.l3_enc[ix + 1]; - if (v != 0) { - p += 4; - huffbits *= 2; - if (gi.xr[xr + 1] < 0) - huffbits++; - assert(v <= 1); - } - - v = gi.l3_enc[ix + 2]; - if (v != 0) { - p += 2; - huffbits *= 2; - if (gi.xr[xr + 2] < 0) - huffbits++; - assert(v <= 1); - } - - v = gi.l3_enc[ix + 3]; - if (v != 0) { - p++; - huffbits *= 2; - if (gi.xr[xr + 3] < 0) - huffbits++; - assert(v <= 1); - } - - ix += 4; - xr += 4; - putbits2(gfc, huffbits + h.table[p], h.hlen[p]); - bits += h.hlen[p]; - } - return bits; - } - - /** - * Implements the pseudocode of page 98 of the IS - */ - function Huffmancode(gfc, tableindex, start, end, gi) { - var h = Tables.ht[tableindex]; - var bits = 0; - - assert(tableindex < 32); - if (0 == tableindex) - return bits; - - for (var i = start; i < end; i += 2) { - var cbits = 0; - var xbits = 0; - var linbits = h.xlen; - var xlen = h.xlen; - var ext = 0; - var x1 = gi.l3_enc[i]; - var x2 = gi.l3_enc[i + 1]; - - if (x1 != 0) { - if (gi.xr[i] < 0) - ext++; - cbits--; - } - - if (tableindex > 15) { - /* use ESC-words */ - if (x1 > 14) { - var linbits_x1 = x1 - 15; - assert(linbits_x1 <= h.linmax); - ext |= linbits_x1 << 1; - xbits = linbits; - x1 = 15; - } - - if (x2 > 14) { - var linbits_x2 = x2 - 15; - assert(linbits_x2 <= h.linmax); - ext <<= linbits; - ext |= linbits_x2; - xbits += linbits; - x2 = 15; - } - xlen = 16; - } - - if (x2 != 0) { - ext <<= 1; - if (gi.xr[i + 1] < 0) - ext++; - cbits--; - } - - assert((x1 | x2) < 16); - - x1 = x1 * xlen + x2; - xbits -= cbits; - cbits += h.hlen[x1]; - - assert(cbits <= MAX_LENGTH); - assert(xbits <= MAX_LENGTH); - - putbits2(gfc, h.table[x1], cbits); - putbits2(gfc, ext, xbits); - bits += cbits + xbits; - } - return bits; - } - - /** - * Note the discussion of huffmancodebits() on pages 28 and 29 of the IS, as - * well as the definitions of the side information on pages 26 and 27. - */ - function ShortHuffmancodebits(gfc, gi) { - var region1Start = 3 * gfc.scalefac_band.s[3]; - if (region1Start > gi.big_values) - region1Start = gi.big_values; - - /* short blocks do not have a region2 */ - var bits = Huffmancode(gfc, gi.table_select[0], 0, region1Start, gi); - bits += Huffmancode(gfc, gi.table_select[1], region1Start, - gi.big_values, gi); - return bits; - } - - function LongHuffmancodebits(gfc, gi) { - var bigvalues, bits; - var region1Start, region2Start; - - bigvalues = gi.big_values; - assert(0 <= bigvalues && bigvalues <= 576); - - var i = gi.region0_count + 1; - assert(0 <= i); - assert(i < gfc.scalefac_band.l.length); - region1Start = gfc.scalefac_band.l[i]; - i += gi.region1_count + 1; - assert(0 <= i); - assert(i < gfc.scalefac_band.l.length); - region2Start = gfc.scalefac_band.l[i]; - - if (region1Start > bigvalues) - region1Start = bigvalues; - - if (region2Start > bigvalues) - region2Start = bigvalues; - - bits = Huffmancode(gfc, gi.table_select[0], 0, region1Start, gi); - bits += Huffmancode(gfc, gi.table_select[1], region1Start, - region2Start, gi); - bits += Huffmancode(gfc, gi.table_select[2], region2Start, bigvalues, - gi); - return bits; - } - - function writeMainData(gfp) { - var gr, ch, sfb, data_bits, tot_bits = 0; - var gfc = gfp.internal_flags; - var l3_side = gfc.l3_side; - - if (gfp.version == 1) { - /* MPEG 1 */ - for (gr = 0; gr < 2; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - var gi = l3_side.tt[gr][ch]; - var slen1 = Takehiro.slen1_tab[gi.scalefac_compress]; - var slen2 = Takehiro.slen2_tab[gi.scalefac_compress]; - data_bits = 0; - for (sfb = 0; sfb < gi.sfbdivide; sfb++) { - if (gi.scalefac[sfb] == -1) - continue; - /* scfsi is used */ - putbits2(gfc, gi.scalefac[sfb], slen1); - data_bits += slen1; - } - for (; sfb < gi.sfbmax; sfb++) { - if (gi.scalefac[sfb] == -1) - continue; - /* scfsi is used */ - putbits2(gfc, gi.scalefac[sfb], slen2); - data_bits += slen2; - } - assert(data_bits == gi.part2_length); - - if (gi.block_type == Encoder.SHORT_TYPE) { - data_bits += ShortHuffmancodebits(gfc, gi); - } else { - data_bits += LongHuffmancodebits(gfc, gi); - } - data_bits += huffman_coder_count1(gfc, gi); - /* does bitcount in quantize.c agree with actual bit count? */ - assert(data_bits == gi.part2_3_length + gi.part2_length); - tot_bits += data_bits; - } - /* for ch */ - } - /* for gr */ - } else { - /* MPEG 2 */ - gr = 0; - for (ch = 0; ch < gfc.channels_out; ch++) { - var gi = l3_side.tt[gr][ch]; - var i, sfb_partition, scale_bits = 0; - assert(gi.sfb_partition_table != null); - data_bits = 0; - sfb = 0; - sfb_partition = 0; - - if (gi.block_type == Encoder.SHORT_TYPE) { - for (; sfb_partition < 4; sfb_partition++) { - var sfbs = gi.sfb_partition_table[sfb_partition] / 3; - var slen = gi.slen[sfb_partition]; - for (i = 0; i < sfbs; i++, sfb++) { - putbits2(gfc, - Math.max(gi.scalefac[sfb * 3 + 0], 0), slen); - putbits2(gfc, - Math.max(gi.scalefac[sfb * 3 + 1], 0), slen); - putbits2(gfc, - Math.max(gi.scalefac[sfb * 3 + 2], 0), slen); - scale_bits += 3 * slen; - } - } - data_bits += ShortHuffmancodebits(gfc, gi); - } else { - for (; sfb_partition < 4; sfb_partition++) { - var sfbs = gi.sfb_partition_table[sfb_partition]; - var slen = gi.slen[sfb_partition]; - for (i = 0; i < sfbs; i++, sfb++) { - putbits2(gfc, Math.max(gi.scalefac[sfb], 0), slen); - scale_bits += slen; - } - } - data_bits += LongHuffmancodebits(gfc, gi); - } - data_bits += huffman_coder_count1(gfc, gi); - /* does bitcount in quantize.c agree with actual bit count? */ - assert(data_bits == gi.part2_3_length); - assert(scale_bits == gi.part2_length); - tot_bits += scale_bits + data_bits; - } - /* for ch */ - } - /* for gf */ - return tot_bits; - } - - /* main_data */ - - function TotalBytes() { - this.total = 0; - } - - /* - * compute the number of bits required to flush all mp3 frames currently in - * the buffer. This should be the same as the reservoir size. Only call this - * routine between frames - i.e. only after all headers and data have been - * added to the buffer by format_bitstream(). - * - * Also compute total_bits_output = size of mp3 buffer (including frame - * headers which may not have yet been send to the mp3 buffer) + number of - * bits needed to flush all mp3 frames. - * - * total_bytes_output is the size of the mp3 output buffer if - * lame_encode_flush_nogap() was called right now. - */ - function compute_flushbits(gfp, total_bytes_output) { - var gfc = gfp.internal_flags; - var flushbits, remaining_headers; - var bitsPerFrame; - var last_ptr, first_ptr; - first_ptr = gfc.w_ptr; - /* first header to add to bitstream */ - last_ptr = gfc.h_ptr - 1; - /* last header to add to bitstream */ - if (last_ptr == -1) - last_ptr = LameInternalFlags.MAX_HEADER_BUF - 1; - - /* add this many bits to bitstream so we can flush all headers */ - flushbits = gfc.header[last_ptr].write_timing - totbit; - total_bytes_output.total = flushbits; - - if (flushbits >= 0) { - /* if flushbits >= 0, some headers have not yet been written */ - /* reduce flushbits by the size of the headers */ - remaining_headers = 1 + last_ptr - first_ptr; - if (last_ptr < first_ptr) - remaining_headers = 1 + last_ptr - first_ptr - + LameInternalFlags.MAX_HEADER_BUF; - flushbits -= remaining_headers * 8 * gfc.sideinfo_len; - } - - /* - * finally, add some bits so that the last frame is complete these bits - * are not necessary to decode the last frame, but some decoders will - * ignore last frame if these bits are missing - */ - bitsPerFrame = self.getframebits(gfp); - flushbits += bitsPerFrame; - total_bytes_output.total += bitsPerFrame; - /* round up: */ - if ((total_bytes_output.total % 8) != 0) - total_bytes_output.total = 1 + (total_bytes_output.total / 8); - else - total_bytes_output.total = (total_bytes_output.total / 8); - total_bytes_output.total += bufByteIdx + 1; - - if (flushbits < 0) { - System.err.println("strange error flushing buffer ... \n"); - } - return flushbits; - } - - this.flush_bitstream = function (gfp) { - var gfc = gfp.internal_flags; - var l3_side; - var flushbits; - var last_ptr = gfc.h_ptr - 1; - /* last header to add to bitstream */ - if (last_ptr == -1) - last_ptr = LameInternalFlags.MAX_HEADER_BUF - 1; - l3_side = gfc.l3_side; - - if ((flushbits = compute_flushbits(gfp, new TotalBytes())) < 0) - return; - drain_into_ancillary(gfp, flushbits); - - /* check that the 100% of the last frame has been written to bitstream */ - assert(gfc.header[last_ptr].write_timing + this.getframebits(gfp) == totbit); - - /* - * we have padded out all frames with ancillary data, which is the same - * as filling the bitreservoir with ancillary data, so : - */ - gfc.ResvSize = 0; - l3_side.main_data_begin = 0; - - /* save the ReplayGain value */ - if (gfc.findReplayGain) { - var RadioGain = ga.GetTitleGain(gfc.rgdata); - assert(NEQ(RadioGain, GainAnalysis.GAIN_NOT_ENOUGH_SAMPLES)); - gfc.RadioGain = Math.floor(RadioGain * 10.0 + 0.5) | 0; - /* round to nearest */ - } - - /* find the gain and scale change required for no clipping */ - if (gfc.findPeakSample) { - gfc.noclipGainChange = Math.ceil(Math - .log10(gfc.PeakSample / 32767.0) * 20.0 * 10.0) | 0; - /* round up */ - - if (gfc.noclipGainChange > 0) { - /* clipping occurs */ - if (EQ(gfp.scale, 1.0) || EQ(gfp.scale, 0.0)) - gfc.noclipScale = (Math - .floor((32767.0 / gfc.PeakSample) * 100.0) / 100.0); - /* round down */ - else { - /* - * the user specified his own scaling factor. We could - * suggest the scaling factor of - * (32767.0/gfp.PeakSample)*(gfp.scale) but it's usually - * very inaccurate. So we'd rather not advice him on the - * scaling factor. - */ - gfc.noclipScale = -1; - } - } else - /* no clipping */ - gfc.noclipScale = -1; - } - }; - - this.add_dummy_byte = function (gfp, val, n) { - var gfc = gfp.internal_flags; - var i; - - while (n-- > 0) { - putbits_noheaders(gfc, val, 8); - - for (i = 0; i < LameInternalFlags.MAX_HEADER_BUF; ++i) - gfc.header[i].write_timing += 8; - } - }; - - /** - * This is called after a frame of audio has been quantized and coded. It - * will write the encoded audio to the bitstream. Note that from a layer3 - * encoder's perspective the bit stream is primarily a series of main_data() - * blocks, with header and side information inserted at the proper locations - * to maintain framing. (See Figure A.7 in the IS). - */ - this.format_bitstream = function (gfp) { - var gfc = gfp.internal_flags; - var l3_side; - l3_side = gfc.l3_side; - - var bitsPerFrame = this.getframebits(gfp); - drain_into_ancillary(gfp, l3_side.resvDrain_pre); - - encodeSideInfo2(gfp, bitsPerFrame); - var bits = 8 * gfc.sideinfo_len; - bits += writeMainData(gfp); - drain_into_ancillary(gfp, l3_side.resvDrain_post); - bits += l3_side.resvDrain_post; - - l3_side.main_data_begin += (bitsPerFrame - bits) / 8; - - /* - * compare number of bits needed to clear all buffered mp3 frames with - * what we think the resvsize is: - */ - if (compute_flushbits(gfp, new TotalBytes()) != gfc.ResvSize) { - System.err.println("Internal buffer inconsistency. flushbits <> ResvSize"); - } - - /* - * compare main_data_begin for the next frame with what we think the - * resvsize is: - */ - if ((l3_side.main_data_begin * 8) != gfc.ResvSize) { - System.err.printf("bit reservoir error: \n" - + "l3_side.main_data_begin: %d \n" - + "Resvoir size: %d \n" - + "resv drain (post) %d \n" - + "resv drain (pre) %d \n" - + "header and sideinfo: %d \n" - + "data bits: %d \n" - + "total bits: %d (remainder: %d) \n" - + "bitsperframe: %d \n", - 8 * l3_side.main_data_begin, gfc.ResvSize, - l3_side.resvDrain_post, l3_side.resvDrain_pre, - 8 * gfc.sideinfo_len, bits - l3_side.resvDrain_post - 8 - * gfc.sideinfo_len, bits, bits % 8, bitsPerFrame); - - System.err.println("This is a fatal error. It has several possible causes:"); - System.err.println("90%% LAME compiled with buggy version of gcc using advanced optimizations"); - System.err.println(" 9%% Your system is overclocked"); - System.err.println(" 1%% bug in LAME encoding library"); - - gfc.ResvSize = l3_side.main_data_begin * 8; - } - //; - assert(totbit % 8 == 0); - - if (totbit > 1000000000) { - /* - * to avoid totbit overflow, (at 8h encoding at 128kbs) lets reset - * bit counter - */ - var i; - for (i = 0; i < LameInternalFlags.MAX_HEADER_BUF; ++i) - gfc.header[i].write_timing -= totbit; - totbit = 0; - } - - return 0; - }; - - /** - *

-     * copy data out of the internal MP3 bit buffer into a user supplied
-     *       unsigned char buffer.
-     *
-     *       mp3data=0      indicates data in buffer is an id3tags and VBR tags
-     *       mp3data=1      data is real mp3 frame data.
-     * 
- */ - this.copy_buffer = function (gfc, buffer, bufferPos, size, mp3data) { - var minimum = bufByteIdx + 1; - if (minimum <= 0) - return 0; - if (size != 0 && minimum > size) { - /* buffer is too small */ - return -1; - } - System.arraycopy(buf, 0, buffer, bufferPos, minimum); - bufByteIdx = -1; - bufBitIdx = 0; - - if (mp3data != 0) { - var crc = new_int(1); - crc[0] = gfc.nMusicCRC; - vbr.updateMusicCRC(crc, buffer, bufferPos, minimum); - gfc.nMusicCRC = crc[0]; - - /** - * sum number of bytes belonging to the mp3 stream this info will be - * written into the Xing/LAME header for seeking - */ - if (minimum > 0) { - gfc.VBR_seek_table.nBytesWritten += minimum; - } - - if (gfc.decode_on_the_fly) { /* decode the frame */ - var pcm_buf = new_float_n([2, 1152]); - var mp3_in = minimum; - var samples_out = -1; - var i; - - /* re-synthesis to pcm. Repeat until we get a samples_out=0 */ - while (samples_out != 0) { - - samples_out = mpg.hip_decode1_unclipped(gfc.hip, buffer, - bufferPos, mp3_in, pcm_buf[0], pcm_buf[1]); - /* - * samples_out = 0: need more data to decode samples_out = - * -1: error. Lets assume 0 pcm output samples_out = number - * of samples output - */ - - /* - * set the lenght of the mp3 input buffer to zero, so that - * in the next iteration of the loop we will be querying - * mpglib about buffered data - */ - mp3_in = 0; - - if (samples_out == -1) { - /* - * error decoding. Not fatal, but might screw up the - * ReplayGain tag. What should we do? Ignore for now - */ - samples_out = 0; - } - if (samples_out > 0) { - /* process the PCM data */ - - /* - * this should not be possible, and indicates we have - * overflown the pcm_buf buffer - */ - assert(samples_out <= 1152); - - if (gfc.findPeakSample) { - for (i = 0; i < samples_out; i++) { - if (pcm_buf[0][i] > gfc.PeakSample) - gfc.PeakSample = pcm_buf[0][i]; - else if (-pcm_buf[0][i] > gfc.PeakSample) - gfc.PeakSample = -pcm_buf[0][i]; - } - if (gfc.channels_out > 1) - for (i = 0; i < samples_out; i++) { - if (pcm_buf[1][i] > gfc.PeakSample) - gfc.PeakSample = pcm_buf[1][i]; - else if (-pcm_buf[1][i] > gfc.PeakSample) - gfc.PeakSample = -pcm_buf[1][i]; - } - } - - if (gfc.findReplayGain) - if (ga.AnalyzeSamples(gfc.rgdata, pcm_buf[0], 0, - pcm_buf[1], 0, samples_out, - gfc.channels_out) == GainAnalysis.GAIN_ANALYSIS_ERROR) - return -6; - - } - /* if (samples_out>0) */ - } - /* while (samples_out!=0) */ - } - /* if (gfc.decode_on_the_fly) */ - - } - /* if (mp3data) */ - return minimum; - }; - - this.init_bit_stream_w = function (gfc) { - buf = new_byte(Lame.LAME_MAXMP3BUFFER); - - gfc.h_ptr = gfc.w_ptr = 0; - gfc.header[gfc.h_ptr].write_timing = 0; - bufByteIdx = -1; - bufBitIdx = 0; - totbit = 0; - }; - - // From machine.h - - -} - -module.exports = BitStream; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/CBRNewIterationLoop.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/CBRNewIterationLoop.js deleted file mode 100644 index 7ebdd2b39..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/CBRNewIterationLoop.js +++ /dev/null @@ -1,92 +0,0 @@ -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -var MeanBits = require('./MeanBits.js'); -var Encoder = require('./Encoder.js'); -var L3Side = require('./L3Side.js'); -var LameInternalFlags = require('./LameInternalFlags.js'); - -function CBRNewIterationLoop(_quantize) { - var quantize = _quantize; - this.quantize = quantize; - this.iteration_loop = function(gfp, pe, ms_ener_ratio, ratio) { - var gfc = gfp.internal_flags; - var l3_xmin = new_float(L3Side.SFBMAX); - var xrpow = new_float(576); - var targ_bits = new_int(2); - var mean_bits = 0, max_bits; - var l3_side = gfc.l3_side; - - var mb = new MeanBits(mean_bits); - this.quantize.rv.ResvFrameBegin(gfp, mb); - mean_bits = mb.bits; - - /* quantize! */ - for (var gr = 0; gr < gfc.mode_gr; gr++) { - - /* - * calculate needed bits - */ - max_bits = this.quantize.qupvt.on_pe(gfp, pe, targ_bits, mean_bits, - gr, gr); - - if (gfc.mode_ext == Encoder.MPG_MD_MS_LR) { - this.quantize.ms_convert(gfc.l3_side, gr); - this.quantize.qupvt.reduce_side(targ_bits, ms_ener_ratio[gr], - mean_bits, max_bits); - } - - for (var ch = 0; ch < gfc.channels_out; ch++) { - var adjust, masking_lower_db; - var cod_info = l3_side.tt[gr][ch]; - - if (cod_info.block_type != Encoder.SHORT_TYPE) { - // NORM, START or STOP type - adjust = 0; - masking_lower_db = gfc.PSY.mask_adjust - adjust; - } else { - adjust = 0; - masking_lower_db = gfc.PSY.mask_adjust_short - adjust; - } - gfc.masking_lower = Math.pow(10.0, - masking_lower_db * 0.1); - - /* - * init_outer_loop sets up cod_info, scalefac and xrpow - */ - this.quantize.init_outer_loop(gfc, cod_info); - if (this.quantize.init_xrpow(gfc, cod_info, xrpow)) { - /* - * xr contains energy we will have to encode calculate the - * masking abilities find some good quantization in - * outer_loop - */ - this.quantize.qupvt.calc_xmin(gfp, ratio[gr][ch], cod_info, - l3_xmin); - this.quantize.outer_loop(gfp, cod_info, l3_xmin, xrpow, ch, - targ_bits[ch]); - } - - this.quantize.iteration_finish_one(gfc, gr, ch); - assert (cod_info.part2_3_length <= LameInternalFlags.MAX_BITS_PER_CHANNEL); - assert (cod_info.part2_3_length <= targ_bits[ch]); - } /* for ch */ - } /* for gr */ - - this.quantize.rv.ResvFrameEnd(gfc, mean_bits); - } -} -module.exports = CBRNewIterationLoop; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/CalcNoiseData.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/CalcNoiseData.js deleted file mode 100644 index 096353b2c..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/CalcNoiseData.js +++ /dev/null @@ -1,14 +0,0 @@ -var common = require('./common.js'); -var new_float = common.new_float; -var new_int = common.new_int; -var assert = common.assert; - -function CalcNoiseData() { - this.global_gain = 0; - this.sfb_count1 = 0; - this.step = new_int(39); - this.noise = new_float(39); - this.noise_log = new_float(39); -} - -module.exports = CalcNoiseData; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/CalcNoiseResult.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/CalcNoiseResult.js deleted file mode 100644 index a96cb3263..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/CalcNoiseResult.js +++ /dev/null @@ -1,27 +0,0 @@ -//package mp3; - -function CalcNoiseResult() { - /** - * sum of quantization noise > masking - */ - this.over_noise = 0.; - /** - * sum of all quantization noise - */ - this.tot_noise = 0.; - /** - * max quantization noise - */ - this.max_noise = 0.; - /** - * number of quantization noise > masking - */ - this.over_count = 0; - /** - * SSD-like cost of distorted bands - */ - this.over_SSD = 0; - this.bits = 0; -} - -module.exports = CalcNoiseResult; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Encoder.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Encoder.js deleted file mode 100644 index 3c43761a9..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Encoder.js +++ /dev/null @@ -1,663 +0,0 @@ -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -/** - * ENCDELAY The encoder delay. - * - * Minimum allowed is MDCTDELAY (see below) - * - * The first 96 samples will be attenuated, so using a value less than 96 - * will result in corrupt data for the first 96-ENCDELAY samples. - * - * suggested: 576 set to 1160 to sync with FhG. - */ -Encoder.ENCDELAY = 576; -/** - * make sure there is at least one complete frame after the last frame - * containing real data - * - * Using a value of 288 would be sufficient for a a very sophisticated - * decoder that can decode granule-by-granule instead of frame by frame. But - * lets not assume this, and assume the decoder will not decode frame N - * unless it also has data for frame N+1 - */ -Encoder.POSTDELAY = 1152; - -/** - * delay of the MDCT used in mdct.c original ISO routines had a delay of - * 528! Takehiro's routines: - */ -Encoder.MDCTDELAY = 48; -Encoder.FFTOFFSET = (224 + Encoder.MDCTDELAY); - -/** - * Most decoders, including the one we use, have a delay of 528 samples. - */ -Encoder.DECDELAY = 528; - -/** - * number of subbands - */ -Encoder.SBLIMIT = 32; - -/** - * parition bands bands - */ -Encoder.CBANDS = 64; - -/** - * number of critical bands/scale factor bands where masking is computed - */ -Encoder.SBPSY_l = 21; -Encoder.SBPSY_s = 12; - -/** - * total number of scalefactor bands encoded - */ -Encoder.SBMAX_l = 22; -Encoder.SBMAX_s = 13; -Encoder.PSFB21 = 6; -Encoder.PSFB12 = 6; - -/** - * FFT sizes - */ -Encoder.BLKSIZE = 1024; -Encoder.HBLKSIZE = (Encoder.BLKSIZE / 2 + 1); -Encoder.BLKSIZE_s = 256; -Encoder.HBLKSIZE_s = (Encoder.BLKSIZE_s / 2 + 1); - -Encoder.NORM_TYPE = 0; -Encoder.START_TYPE = 1; -Encoder.SHORT_TYPE = 2; -Encoder.STOP_TYPE = 3; - -/** - *
- * Mode Extention:
- * When we are in stereo mode, there are 4 possible methods to store these
- * two channels. The stereo modes -m? are using a subset of them.
- *
- *  -ms: MPG_MD_LR_LR
- *  -mj: MPG_MD_LR_LR and MPG_MD_MS_LR
- *  -mf: MPG_MD_MS_LR
- *  -mi: all
- * 
- */ -Encoder.MPG_MD_LR_LR = 0; -Encoder.MPG_MD_LR_I = 1; -Encoder.MPG_MD_MS_LR = 2; -Encoder.MPG_MD_MS_I = 3; - -Encoder.fircoef = [-0.0207887 * 5, -0.0378413 * 5, - -0.0432472 * 5, -0.031183 * 5, 7.79609e-18 * 5, 0.0467745 * 5, - 0.10091 * 5, 0.151365 * 5, 0.187098 * 5]; - -function Encoder() { - var NewMDCT = require('./NewMDCT.js'); - var III_psy_ratio = require('./III_psy_ratio.js'); - var MPEGMode = require('./MPEGMode.js'); - - var FFTOFFSET = Encoder.FFTOFFSET; - var MPG_MD_MS_LR = Encoder.MPG_MD_MS_LR; - //BitStream bs; - //PsyModel psy; - //VBRTag vbr; - //QuantizePVT qupvt; - var bs = null; - this.psy = null; - var psy = null; - var vbr = null; - var qupvt = null; - - //public final void setModules(BitStream bs, PsyModel psy, QuantizePVT qupvt, - // VBRTag vbr) { - this.setModules = function (_bs, _psy, _qupvt, _vbr) { - bs = _bs; - this.psy = _psy; - psy = _psy; - vbr = _vbr; - qupvt = _qupvt; - }; - - var newMDCT = new NewMDCT(); - - /*********************************************************************** - * - * encoder and decoder delays - * - ***********************************************************************/ - - /** - *
-     * layer III enc->dec delay:  1056 (1057?)   (observed)
-     * layer  II enc->dec delay:   480  (481?)   (observed)
-     *
-     * polyphase 256-16             (dec or enc)        = 240
-     * mdct      256+32  (9*32)     (dec or enc)        = 288
-     * total:    512+16
-     *
-     * My guess is that delay of polyphase filterbank is actualy 240.5
-     * (there are technical reasons for this, see postings in mp3encoder).
-     * So total Encode+Decode delay = ENCDELAY + 528 + 1
-     * 
- */ - - - /** - * auto-adjust of ATH, useful for low volume Gabriel Bouvigne 3 feb 2001 - * - * modifies some values in gfp.internal_flags.ATH (gfc.ATH) - */ -//private void adjust_ATH(final LameInternalFlags gfc) { - function adjust_ATH(gfc) { - var gr2_max, max_pow; - - if (gfc.ATH.useAdjust == 0) { - gfc.ATH.adjust = 1.0; - /* no adjustment */ - return; - } - - /* jd - 2001 mar 12, 27, jun 30 */ - /* loudness based on equal loudness curve; */ - /* use granule with maximum combined loudness */ - max_pow = gfc.loudness_sq[0][0]; - gr2_max = gfc.loudness_sq[1][0]; - if (gfc.channels_out == 2) { - max_pow += gfc.loudness_sq[0][1]; - gr2_max += gfc.loudness_sq[1][1]; - } else { - max_pow += max_pow; - gr2_max += gr2_max; - } - if (gfc.mode_gr == 2) { - max_pow = Math.max(max_pow, gr2_max); - } - max_pow *= 0.5; - /* max_pow approaches 1.0 for full band noise */ - - /* jd - 2001 mar 31, jun 30 */ - /* user tuning of ATH adjustment region */ - max_pow *= gfc.ATH.aaSensitivityP; - - /* - * adjust ATH depending on range of maximum value - */ - - /* jd - 2001 feb27, mar12,20, jun30, jul22 */ - /* continuous curves based on approximation */ - /* to GB's original values. */ - /* For an increase in approximate loudness, */ - /* set ATH adjust to adjust_limit immediately */ - /* after a delay of one frame. */ - /* For a loudness decrease, reduce ATH adjust */ - /* towards adjust_limit gradually. */ - /* max_pow is a loudness squared or a power. */ - if (max_pow > 0.03125) { /* ((1 - 0.000625)/ 31.98) from curve below */ - if (gfc.ATH.adjust >= 1.0) { - gfc.ATH.adjust = 1.0; - } else { - /* preceding frame has lower ATH adjust; */ - /* ascend only to the preceding adjust_limit */ - /* in case there is leading low volume */ - if (gfc.ATH.adjust < gfc.ATH.adjustLimit) { - gfc.ATH.adjust = gfc.ATH.adjustLimit; - } - } - gfc.ATH.adjustLimit = 1.0; - } else { /* adjustment curve */ - /* about 32 dB maximum adjust (0.000625) */ - var adj_lim_new = 31.98 * max_pow + 0.000625; - if (gfc.ATH.adjust >= adj_lim_new) { /* descend gradually */ - gfc.ATH.adjust *= adj_lim_new * 0.075 + 0.925; - if (gfc.ATH.adjust < adj_lim_new) { /* stop descent */ - gfc.ATH.adjust = adj_lim_new; - } - } else { /* ascend */ - if (gfc.ATH.adjustLimit >= adj_lim_new) { - gfc.ATH.adjust = adj_lim_new; - } else { - /* preceding frame has lower ATH adjust; */ - /* ascend only to the preceding adjust_limit */ - if (gfc.ATH.adjust < gfc.ATH.adjustLimit) { - gfc.ATH.adjust = gfc.ATH.adjustLimit; - } - } - } - gfc.ATH.adjustLimit = adj_lim_new; - } - } - - /** - *
-     *  some simple statistics
-     *
-     *  bitrate index 0: free bitrate . not allowed in VBR mode
-     *  : bitrates, kbps depending on MPEG version
-     *  bitrate index 15: forbidden
-     *
-     *  mode_ext:
-     *  0:  LR
-     *  1:  LR-i
-     *  2:  MS
-     *  3:  MS-i
-     * 
- */ - function updateStats(gfc) { - var gr, ch; - assert(0 <= gfc.bitrate_index && gfc.bitrate_index < 16); - assert(0 <= gfc.mode_ext && gfc.mode_ext < 4); - - /* count bitrate indices */ - gfc.bitrate_stereoMode_Hist[gfc.bitrate_index][4]++; - gfc.bitrate_stereoMode_Hist[15][4]++; - - /* count 'em for every mode extension in case of 2 channel encoding */ - if (gfc.channels_out == 2) { - gfc.bitrate_stereoMode_Hist[gfc.bitrate_index][gfc.mode_ext]++; - gfc.bitrate_stereoMode_Hist[15][gfc.mode_ext]++; - } - for (gr = 0; gr < gfc.mode_gr; ++gr) { - for (ch = 0; ch < gfc.channels_out; ++ch) { - var bt = gfc.l3_side.tt[gr][ch].block_type | 0; - if (gfc.l3_side.tt[gr][ch].mixed_block_flag != 0) - bt = 4; - gfc.bitrate_blockType_Hist[gfc.bitrate_index][bt]++; - gfc.bitrate_blockType_Hist[gfc.bitrate_index][5]++; - gfc.bitrate_blockType_Hist[15][bt]++; - gfc.bitrate_blockType_Hist[15][5]++; - } - } - } - - function lame_encode_frame_init(gfp, inbuf) { - var gfc = gfp.internal_flags; - - var ch, gr; - - if (gfc.lame_encode_frame_init == 0) { - /* prime the MDCT/polyphase filterbank with a short block */ - var i, j; - var primebuff0 = new_float(286 + 1152 + 576); - var primebuff1 = new_float(286 + 1152 + 576); - gfc.lame_encode_frame_init = 1; - for (i = 0, j = 0; i < 286 + 576 * (1 + gfc.mode_gr); ++i) { - if (i < 576 * gfc.mode_gr) { - primebuff0[i] = 0; - if (gfc.channels_out == 2) - primebuff1[i] = 0; - } else { - primebuff0[i] = inbuf[0][j]; - if (gfc.channels_out == 2) - primebuff1[i] = inbuf[1][j]; - ++j; - } - } - /* polyphase filtering / mdct */ - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - gfc.l3_side.tt[gr][ch].block_type = Encoder.SHORT_TYPE; - } - } - newMDCT.mdct_sub48(gfc, primebuff0, primebuff1); - - /* check FFT will not use a negative starting offset */ - assert(576 >= Encoder.FFTOFFSET); - /* check if we have enough data for FFT */ - assert(gfc.mf_size >= (Encoder.BLKSIZE + gfp.framesize - Encoder.FFTOFFSET)); - /* check if we have enough data for polyphase filterbank */ - assert(gfc.mf_size >= (512 + gfp.framesize - 32)); - } - - } - - /** - *
-     * encodeframe()           Layer 3
-     *
-     * encode a single frame
-     *
-     *
-     *    lame_encode_frame()
-     *
-     *
-     *                           gr 0            gr 1
-     *    inbuf:           |--------------|--------------|--------------|
-     *
-     *
-     *    Polyphase (18 windows, each shifted 32)
-     *    gr 0:
-     *    window1          <----512---.
-     *    window18                 <----512---.
-     *
-     *    gr 1:
-     *    window1                         <----512---.
-     *    window18                                <----512---.
-     *
-     *
-     *
-     *    MDCT output:  |--------------|--------------|--------------|
-     *
-     *    FFT's                    <---------1024---------.
-     *                                             <---------1024-------.
-     *
-     *
-     *
-     *        inbuf = buffer of PCM data size=MP3 framesize
-     *        encoder acts on inbuf[ch][0], but output is delayed by MDCTDELAY
-     *        so the MDCT coefficints are from inbuf[ch][-MDCTDELAY]
-     *
-     *        psy-model FFT has a 1 granule delay, so we feed it data for the
-     *        next granule.
-     *        FFT is centered over granule:  224+576+224
-     *        So FFT starts at:   576-224-MDCTDELAY
-     *
-     *        MPEG2:  FFT ends at:  BLKSIZE+576-224-MDCTDELAY      (1328)
-     *        MPEG1:  FFT ends at:  BLKSIZE+2*576-224-MDCTDELAY    (1904)
-     *
-     *        MPEG2:  polyphase first window:  [0..511]
-     *                          18th window:   [544..1055]          (1056)
-     *        MPEG1:            36th window:   [1120..1631]         (1632)
-     *                data needed:  512+framesize-32
-     *
-     *        A close look newmdct.c shows that the polyphase filterbank
-     *        only uses data from [0..510] for each window.  Perhaps because the window
-     *        used by the filterbank is zero for the last point, so Takehiro's
-     *        code doesn't bother to compute with it.
-     *
-     *        FFT starts at 576-224-MDCTDELAY (304)  = 576-FFTOFFSET
-     *
-     * 
- */ - - - this.lame_encode_mp3_frame = function (gfp, inbuf_l, inbuf_r, mp3buf, mp3bufPos, mp3buf_size) { - var mp3count; - var masking_LR = new_array_n([2, 2]); - /* - * LR masking & - * energy - */ - masking_LR[0][0] = new III_psy_ratio(); - masking_LR[0][1] = new III_psy_ratio(); - masking_LR[1][0] = new III_psy_ratio(); - masking_LR[1][1] = new III_psy_ratio(); - var masking_MS = new_array_n([2, 2]); - /* MS masking & energy */ - masking_MS[0][0] = new III_psy_ratio(); - masking_MS[0][1] = new III_psy_ratio(); - masking_MS[1][0] = new III_psy_ratio(); - masking_MS[1][1] = new III_psy_ratio(); - //III_psy_ratio masking[][]; - var masking; - /* pointer to selected maskings */ - var inbuf = [null, null]; - var gfc = gfp.internal_flags; - - var tot_ener = new_float_n([2, 4]); - var ms_ener_ratio = [.5, .5]; - var pe = [[0., 0.], [0., 0.]]; - var pe_MS = [[0., 0.], [0., 0.]]; - -//float[][] pe_use; - var pe_use; - - var ch, gr; - - inbuf[0] = inbuf_l; - inbuf[1] = inbuf_r; - - if (gfc.lame_encode_frame_init == 0) { - /* first run? */ - lame_encode_frame_init(gfp, inbuf); - - } - - /********************** padding *****************************/ - /** - *
-         * padding method as described in
-         * "MPEG-Layer3 / Bitstream Syntax and Decoding"
-         * by Martin Sieler, Ralph Sperschneider
-         *
-         * note: there is no padding for the very first frame
-         *
-         * Robert Hegemann 2000-06-22
-         * 
- */ - gfc.padding = 0; - if ((gfc.slot_lag -= gfc.frac_SpF) < 0) { - gfc.slot_lag += gfp.out_samplerate; - gfc.padding = 1; - } - - /**************************************** - * Stage 1: psychoacoustic model * - ****************************************/ - - if (gfc.psymodel != 0) { - /* - * psychoacoustic model psy model has a 1 granule (576) delay that - * we must compensate for (mt 6/99). - */ - var ret; - var bufp = [null, null]; - /* address of beginning of left & right granule */ - var bufpPos = 0; - /* address of beginning of left & right granule */ - var blocktype = new_int(2); - - for (gr = 0; gr < gfc.mode_gr; gr++) { - - for (ch = 0; ch < gfc.channels_out; ch++) { - bufp[ch] = inbuf[ch]; - bufpPos = 576 + gr * 576 - Encoder.FFTOFFSET; - } - if (gfp.VBR == VbrMode.vbr_mtrh || gfp.VBR == VbrMode.vbr_mt) { - ret = psy.L3psycho_anal_vbr(gfp, bufp, bufpPos, gr, - masking_LR, masking_MS, pe[gr], pe_MS[gr], - tot_ener[gr], blocktype); - } else { - ret = psy.L3psycho_anal_ns(gfp, bufp, bufpPos, gr, - masking_LR, masking_MS, pe[gr], pe_MS[gr], - tot_ener[gr], blocktype); - } - if (ret != 0) - return -4; - - if (gfp.mode == MPEGMode.JOINT_STEREO) { - ms_ener_ratio[gr] = tot_ener[gr][2] + tot_ener[gr][3]; - if (ms_ener_ratio[gr] > 0) - ms_ener_ratio[gr] = tot_ener[gr][3] / ms_ener_ratio[gr]; - } - - /* block type flags */ - for (ch = 0; ch < gfc.channels_out; ch++) { - var cod_info = gfc.l3_side.tt[gr][ch]; - cod_info.block_type = blocktype[ch]; - cod_info.mixed_block_flag = 0; - } - } - } else { - /* no psy model */ - for (gr = 0; gr < gfc.mode_gr; gr++) - for (ch = 0; ch < gfc.channels_out; ch++) { - gfc.l3_side.tt[gr][ch].block_type = Encoder.NORM_TYPE; - gfc.l3_side.tt[gr][ch].mixed_block_flag = 0; - pe_MS[gr][ch] = pe[gr][ch] = 700; - } - } - - /* auto-adjust of ATH, useful for low volume */ - adjust_ATH(gfc); - - /**************************************** - * Stage 2: MDCT * - ****************************************/ - - /* polyphase filtering / mdct */ - newMDCT.mdct_sub48(gfc, inbuf[0], inbuf[1]); - - /**************************************** - * Stage 3: MS/LR decision * - ****************************************/ - - /* Here will be selected MS or LR coding of the 2 stereo channels */ - gfc.mode_ext = Encoder.MPG_MD_LR_LR; - - if (gfp.force_ms) { - gfc.mode_ext = Encoder.MPG_MD_MS_LR; - } else if (gfp.mode == MPEGMode.JOINT_STEREO) { - /* - * ms_ratio = is scaled, for historical reasons, to look like a - * ratio of side_channel / total. 0 = signal is 100% mono .5 = L & R - * uncorrelated - */ - - /** - *
-             * [0] and [1] are the results for the two granules in MPEG-1,
-             * in MPEG-2 it's only a faked averaging of the same value
-             * _prev is the value of the last granule of the previous frame
-             * _next is the value of the first granule of the next frame
-             * 
- */ - - var sum_pe_MS = 0.; - var sum_pe_LR = 0.; - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - sum_pe_MS += pe_MS[gr][ch]; - sum_pe_LR += pe[gr][ch]; - } - } - - /* based on PE: M/S coding would not use much more bits than L/R */ - if (sum_pe_MS <= 1.00 * sum_pe_LR) { - - var gi0 = gfc.l3_side.tt[0]; - var gi1 = gfc.l3_side.tt[gfc.mode_gr - 1]; - - if (gi0[0].block_type == gi0[1].block_type - && gi1[0].block_type == gi1[1].block_type) { - - gfc.mode_ext = Encoder.MPG_MD_MS_LR; - } - } - } - - /* bit and noise allocation */ - if (gfc.mode_ext == MPG_MD_MS_LR) { - masking = masking_MS; - /* use MS masking */ - pe_use = pe_MS; - } else { - masking = masking_LR; - /* use LR masking */ - pe_use = pe; - } - - /* copy data for MP3 frame analyzer */ - if (gfp.analysis && gfc.pinfo != null) { - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - gfc.pinfo.ms_ratio[gr] = gfc.ms_ratio[gr]; - gfc.pinfo.ms_ener_ratio[gr] = ms_ener_ratio[gr]; - gfc.pinfo.blocktype[gr][ch] = gfc.l3_side.tt[gr][ch].block_type; - gfc.pinfo.pe[gr][ch] = pe_use[gr][ch]; - System.arraycopy(gfc.l3_side.tt[gr][ch].xr, 0, - gfc.pinfo.xr[gr][ch], 0, 576); - /* - * in psymodel, LR and MS data was stored in pinfo. switch - * to MS data: - */ - if (gfc.mode_ext == MPG_MD_MS_LR) { - gfc.pinfo.ers[gr][ch] = gfc.pinfo.ers[gr][ch + 2]; - System.arraycopy(gfc.pinfo.energy[gr][ch + 2], 0, - gfc.pinfo.energy[gr][ch], 0, - gfc.pinfo.energy[gr][ch].length); - } - } - } - } - - /**************************************** - * Stage 4: quantization loop * - ****************************************/ - - if (gfp.VBR == VbrMode.vbr_off || gfp.VBR == VbrMode.vbr_abr) { - - var i; - var f; - - for (i = 0; i < 18; i++) - gfc.nsPsy.pefirbuf[i] = gfc.nsPsy.pefirbuf[i + 1]; - - f = 0.0; - for (gr = 0; gr < gfc.mode_gr; gr++) - for (ch = 0; ch < gfc.channels_out; ch++) - f += pe_use[gr][ch]; - gfc.nsPsy.pefirbuf[18] = f; - - f = gfc.nsPsy.pefirbuf[9]; - for (i = 0; i < 9; i++) - f += (gfc.nsPsy.pefirbuf[i] + gfc.nsPsy.pefirbuf[18 - i]) - * Encoder.fircoef[i]; - - f = (670 * 5 * gfc.mode_gr * gfc.channels_out) / f; - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - pe_use[gr][ch] *= f; - } - } - } - gfc.iteration_loop.iteration_loop(gfp, pe_use, ms_ener_ratio, masking); - - /**************************************** - * Stage 5: bitstream formatting * - ****************************************/ - - /* write the frame to the bitstream */ - bs.format_bitstream(gfp); - - /* copy mp3 bit buffer into array */ - mp3count = bs.copy_buffer(gfc, mp3buf, mp3bufPos, mp3buf_size, 1); - - if (gfp.bWriteVbrTag) - vbr.addVbrFrame(gfp); - - if (gfp.analysis && gfc.pinfo != null) { - for (ch = 0; ch < gfc.channels_out; ch++) { - var j; - for (j = 0; j < FFTOFFSET; j++) - gfc.pinfo.pcmdata[ch][j] = gfc.pinfo.pcmdata[ch][j - + gfp.framesize]; - for (j = FFTOFFSET; j < 1600; j++) { - gfc.pinfo.pcmdata[ch][j] = inbuf[ch][j - FFTOFFSET]; - } - } - qupvt.set_frame_pinfo(gfp, masking); - } - - updateStats(gfc); - - return mp3count; - } -} - - -module.exports = Encoder; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/FFT.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/FFT.js deleted file mode 100644 index b3bdc269e..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/FFT.js +++ /dev/null @@ -1,246 +0,0 @@ -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -var Encoder = require('./Encoder.js'); - -function FFT() { - - var window = new_float(Encoder.BLKSIZE); - var window_s = new_float(Encoder.BLKSIZE_s / 2); - - var costab = [ - 9.238795325112867e-01, 3.826834323650898e-01, - 9.951847266721969e-01, 9.801714032956060e-02, - 9.996988186962042e-01, 2.454122852291229e-02, - 9.999811752826011e-01, 6.135884649154475e-03 - ]; - - function fht(fz, fzPos, n) { - var tri = 0; - var k4; - var fi; - var gi; - - n <<= 1; - /* to get BLKSIZE, because of 3DNow! ASM routine */ - var fn = fzPos + n; - k4 = 4; - do { - var s1, c1; - var i, k1, k2, k3, kx; - kx = k4 >> 1; - k1 = k4; - k2 = k4 << 1; - k3 = k2 + k1; - k4 = k2 << 1; - fi = fzPos; - gi = fi + kx; - do { - var f0, f1, f2, f3; - f1 = fz[fi + 0] - fz[fi + k1]; - f0 = fz[fi + 0] + fz[fi + k1]; - f3 = fz[fi + k2] - fz[fi + k3]; - f2 = fz[fi + k2] + fz[fi + k3]; - fz[fi + k2] = f0 - f2; - fz[fi + 0] = f0 + f2; - fz[fi + k3] = f1 - f3; - fz[fi + k1] = f1 + f3; - f1 = fz[gi + 0] - fz[gi + k1]; - f0 = fz[gi + 0] + fz[gi + k1]; - f3 = (Util.SQRT2 * fz[gi + k3]); - f2 = (Util.SQRT2 * fz[gi + k2]); - fz[gi + k2] = f0 - f2; - fz[gi + 0] = f0 + f2; - fz[gi + k3] = f1 - f3; - fz[gi + k1] = f1 + f3; - gi += k4; - fi += k4; - } while (fi < fn); - c1 = costab[tri + 0]; - s1 = costab[tri + 1]; - for (i = 1; i < kx; i++) { - var c2, s2; - c2 = 1 - (2 * s1) * s1; - s2 = (2 * s1) * c1; - fi = fzPos + i; - gi = fzPos + k1 - i; - do { - var a, b, g0, f0, f1, g1, f2, g2, f3, g3; - b = s2 * fz[fi + k1] - c2 * fz[gi + k1]; - a = c2 * fz[fi + k1] + s2 * fz[gi + k1]; - f1 = fz[fi + 0] - a; - f0 = fz[fi + 0] + a; - g1 = fz[gi + 0] - b; - g0 = fz[gi + 0] + b; - b = s2 * fz[fi + k3] - c2 * fz[gi + k3]; - a = c2 * fz[fi + k3] + s2 * fz[gi + k3]; - f3 = fz[fi + k2] - a; - f2 = fz[fi + k2] + a; - g3 = fz[gi + k2] - b; - g2 = fz[gi + k2] + b; - b = s1 * f2 - c1 * g3; - a = c1 * f2 + s1 * g3; - fz[fi + k2] = f0 - a; - fz[fi + 0] = f0 + a; - fz[gi + k3] = g1 - b; - fz[gi + k1] = g1 + b; - b = c1 * g2 - s1 * f3; - a = s1 * g2 + c1 * f3; - fz[gi + k2] = g0 - a; - fz[gi + 0] = g0 + a; - fz[fi + k3] = f1 - b; - fz[fi + k1] = f1 + b; - gi += k4; - fi += k4; - } while (fi < fn); - c2 = c1; - c1 = c2 * costab[tri + 0] - s1 * costab[tri + 1]; - s1 = c2 * costab[tri + 1] + s1 * costab[tri + 0]; - } - tri += 2; - } while (k4 < n); - } - - var rv_tbl = [0x00, 0x80, 0x40, - 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, - 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, - 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, - 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, - 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, - 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, - 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, - 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, - 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, - 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, - 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, - 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, - 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, - 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, - 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, - 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, - 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, - 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, - 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, - 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, - 0xde, 0x3e, 0xbe, 0x7e, 0xfe]; - - this.fft_short = function (gfc, x_real, chn, buffer, bufPos) { - for (var b = 0; b < 3; b++) { - var x = Encoder.BLKSIZE_s / 2; - var k = 0xffff & ((576 / 3) * (b + 1)); - var j = Encoder.BLKSIZE_s / 8 - 1; - do { - var f0, f1, f2, f3, w; - var i = rv_tbl[j << 2] & 0xff; - - f0 = window_s[i] * buffer[chn][bufPos + i + k]; - w = window_s[0x7f - i] * buffer[chn][bufPos + i + k + 0x80]; - f1 = f0 - w; - f0 = f0 + w; - f2 = window_s[i + 0x40] * buffer[chn][bufPos + i + k + 0x40]; - w = window_s[0x3f - i] * buffer[chn][bufPos + i + k + 0xc0]; - f3 = f2 - w; - f2 = f2 + w; - - x -= 4; - x_real[b][x + 0] = f0 + f2; - x_real[b][x + 2] = f0 - f2; - x_real[b][x + 1] = f1 + f3; - x_real[b][x + 3] = f1 - f3; - - f0 = window_s[i + 0x01] * buffer[chn][bufPos + i + k + 0x01]; - w = window_s[0x7e - i] * buffer[chn][bufPos + i + k + 0x81]; - f1 = f0 - w; - f0 = f0 + w; - f2 = window_s[i + 0x41] * buffer[chn][bufPos + i + k + 0x41]; - w = window_s[0x3e - i] * buffer[chn][bufPos + i + k + 0xc1]; - f3 = f2 - w; - f2 = f2 + w; - - x_real[b][x + Encoder.BLKSIZE_s / 2 + 0] = f0 + f2; - x_real[b][x + Encoder.BLKSIZE_s / 2 + 2] = f0 - f2; - x_real[b][x + Encoder.BLKSIZE_s / 2 + 1] = f1 + f3; - x_real[b][x + Encoder.BLKSIZE_s / 2 + 3] = f1 - f3; - } while (--j >= 0); - - fht(x_real[b], x, Encoder.BLKSIZE_s / 2); - /* BLKSIZE_s/2 because of 3DNow! ASM routine */ - /* BLKSIZE/2 because of 3DNow! ASM routine */ - } - } - - this.fft_long = function (gfc, y, chn, buffer, bufPos) { - var jj = Encoder.BLKSIZE / 8 - 1; - var x = Encoder.BLKSIZE / 2; - - do { - var f0, f1, f2, f3, w; - var i = rv_tbl[jj] & 0xff; - f0 = window[i] * buffer[chn][bufPos + i]; - w = window[i + 0x200] * buffer[chn][bufPos + i + 0x200]; - f1 = f0 - w; - f0 = f0 + w; - f2 = window[i + 0x100] * buffer[chn][bufPos + i + 0x100]; - w = window[i + 0x300] * buffer[chn][bufPos + i + 0x300]; - f3 = f2 - w; - f2 = f2 + w; - - x -= 4; - y[x + 0] = f0 + f2; - y[x + 2] = f0 - f2; - y[x + 1] = f1 + f3; - y[x + 3] = f1 - f3; - - f0 = window[i + 0x001] * buffer[chn][bufPos + i + 0x001]; - w = window[i + 0x201] * buffer[chn][bufPos + i + 0x201]; - f1 = f0 - w; - f0 = f0 + w; - f2 = window[i + 0x101] * buffer[chn][bufPos + i + 0x101]; - w = window[i + 0x301] * buffer[chn][bufPos + i + 0x301]; - f3 = f2 - w; - f2 = f2 + w; - - y[x + Encoder.BLKSIZE / 2 + 0] = f0 + f2; - y[x + Encoder.BLKSIZE / 2 + 2] = f0 - f2; - y[x + Encoder.BLKSIZE / 2 + 1] = f1 + f3; - y[x + Encoder.BLKSIZE / 2 + 3] = f1 - f3; - } while (--jj >= 0); - - fht(y, x, Encoder.BLKSIZE / 2); - /* BLKSIZE/2 because of 3DNow! ASM routine */ - } - - this.init_fft = function (gfc) { - /* The type of window used here will make no real difference, but */ - /* - * in the interest of merging nspsytune stuff - switch to blackman - * window - */ - for (var i = 0; i < Encoder.BLKSIZE; i++) - /* blackman window */ - window[i] = (0.42 - 0.5 * Math.cos(2 * Math.PI * (i + .5) - / Encoder.BLKSIZE) + 0.08 * Math.cos(4 * Math.PI * (i + .5) - / Encoder.BLKSIZE)); - - for (var i = 0; i < Encoder.BLKSIZE_s / 2; i++) - window_s[i] = (0.5 * (1.0 - Math.cos(2.0 * Math.PI - * (i + 0.5) / Encoder.BLKSIZE_s))); - - } - -} - -module.exports = FFT; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/GainAnalysis.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/GainAnalysis.js deleted file mode 100644 index 7f893554a..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/GainAnalysis.js +++ /dev/null @@ -1,552 +0,0 @@ -/* - * ReplayGainAnalysis - analyzes input samples and give the recommended dB change - * Copyright (C) 2001 David Robinson and Glen Sawyer - * Improvements and optimizations added by Frank Klemm, and by Marcel Muller - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * concept and filter values by David Robinson (David@Robinson.org) - * -- blame him if you think the idea is flawed - * original coding by Glen Sawyer (mp3gain@hotmail.com) - * -- blame him if you think this runs too slowly, or the coding is otherwise flawed - * - * lots of code improvements by Frank Klemm ( http://www.uni-jena.de/~pfk/mpp/ ) - * -- credit him for all the _good_ programming ;) - * - * - * For an explanation of the concepts and the basic algorithms involved, go to: - * http://www.replaygain.org/ - */ - -/* - * Here's the deal. Call - * - * InitGainAnalysis ( long samplefreq ); - * - * to initialize everything. Call - * - * AnalyzeSamples ( var Float_t* left_samples, - * var Float_t* right_samples, - * size_t num_samples, - * int num_channels ); - * - * as many times as you want, with as many or as few samples as you want. - * If mono, pass the sample buffer in through left_samples, leave - * right_samples NULL, and make sure num_channels = 1. - * - * GetTitleGain() - * - * will return the recommended dB level change for all samples analyzed - * SINCE THE LAST TIME you called GetTitleGain() OR InitGainAnalysis(). - * - * GetAlbumGain() - * - * will return the recommended dB level change for all samples analyzed - * since InitGainAnalysis() was called and finalized with GetTitleGain(). - * - * Pseudo-code to process an album: - * - * Float_t l_samples [4096]; - * Float_t r_samples [4096]; - * size_t num_samples; - * unsigned int num_songs; - * unsigned int i; - * - * InitGainAnalysis ( 44100 ); - * for ( i = 1; i <= num_songs; i++ ) { - * while ( ( num_samples = getSongSamples ( song[i], left_samples, right_samples ) ) > 0 ) - * AnalyzeSamples ( left_samples, right_samples, num_samples, 2 ); - * fprintf ("Recommended dB change for song %2d: %+6.2 dB\n", i, GetTitleGain() ); - * } - * fprintf ("Recommended dB change for whole album: %+6.2 dB\n", GetAlbumGain() ); - */ - -/* - * So here's the main source of potential code confusion: - * - * The filters applied to the incoming samples are IIR filters, - * meaning they rely on up to number of previous samples - * AND up to number of previous filtered samples. - * - * I set up the AnalyzeSamples routine to minimize memory usage and interface - * complexity. The speed isn't compromised too much (I don't think), but the - * internal complexity is higher than it should be for such a relatively - * simple routine. - * - * Optimization/clarity suggestions are welcome. - */ -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -/** - * Table entries per dB - */ -GainAnalysis.STEPS_per_dB = 100.; -/** - * Table entries for 0...MAX_dB (normal max. values are 70...80 dB) - */ -GainAnalysis.MAX_dB = 120.; -GainAnalysis.GAIN_NOT_ENOUGH_SAMPLES = -24601; -GainAnalysis.GAIN_ANALYSIS_ERROR = 0; -GainAnalysis.GAIN_ANALYSIS_OK = 1; -GainAnalysis.INIT_GAIN_ANALYSIS_ERROR = 0; -GainAnalysis.INIT_GAIN_ANALYSIS_OK = 1; - -GainAnalysis.YULE_ORDER = 10; -GainAnalysis.MAX_ORDER = GainAnalysis.YULE_ORDER; - -GainAnalysis.MAX_SAMP_FREQ = 48000; -GainAnalysis.RMS_WINDOW_TIME_NUMERATOR = 1; -GainAnalysis.RMS_WINDOW_TIME_DENOMINATOR = 20; -GainAnalysis.MAX_SAMPLES_PER_WINDOW = ((GainAnalysis.MAX_SAMP_FREQ * GainAnalysis.RMS_WINDOW_TIME_NUMERATOR) / GainAnalysis.RMS_WINDOW_TIME_DENOMINATOR + 1); - -function GainAnalysis() { - /** - * calibration value for 89dB - */ - var PINK_REF = 64.82; - - var YULE_ORDER = GainAnalysis.YULE_ORDER; - /** - * percentile which is louder than the proposed level - */ - var RMS_PERCENTILE = 0.95; - /** - * maximum allowed sample frequency [Hz] - */ - var MAX_SAMP_FREQ = GainAnalysis.MAX_SAMP_FREQ; - var RMS_WINDOW_TIME_NUMERATOR = GainAnalysis.RMS_WINDOW_TIME_NUMERATOR; - /** - * numerator / denominator = time slice size [s] - */ - var RMS_WINDOW_TIME_DENOMINATOR = GainAnalysis.RMS_WINDOW_TIME_DENOMINATOR; - /** - * max. Samples per Time slice - */ - var MAX_SAMPLES_PER_WINDOW = GainAnalysis.MAX_SAMPLES_PER_WINDOW; - - - var ABYule = [ - [0.03857599435200, -3.84664617118067, -0.02160367184185, - 7.81501653005538, -0.00123395316851, -11.34170355132042, - -0.00009291677959, 13.05504219327545, -0.01655260341619, - -12.28759895145294, 0.02161526843274, 9.48293806319790, - -0.02074045215285, -5.87257861775999, 0.00594298065125, - 2.75465861874613, 0.00306428023191, -0.86984376593551, - 0.00012025322027, 0.13919314567432, 0.00288463683916], - [0.05418656406430, -3.47845948550071, -0.02911007808948, - 6.36317777566148, -0.00848709379851, -8.54751527471874, - -0.00851165645469, 9.47693607801280, -0.00834990904936, - -8.81498681370155, 0.02245293253339, 6.85401540936998, - -0.02596338512915, -4.39470996079559, 0.01624864962975, - 2.19611684890774, -0.00240879051584, -0.75104302451432, - 0.00674613682247, 0.13149317958808, -0.00187763777362], - [0.15457299681924, -2.37898834973084, -0.09331049056315, - 2.84868151156327, -0.06247880153653, -2.64577170229825, - 0.02163541888798, 2.23697657451713, -0.05588393329856, - -1.67148153367602, 0.04781476674921, 1.00595954808547, - 0.00222312597743, -0.45953458054983, 0.03174092540049, - 0.16378164858596, -0.01390589421898, -0.05032077717131, - 0.00651420667831, 0.02347897407020, -0.00881362733839], - [0.30296907319327, -1.61273165137247, -0.22613988682123, - 1.07977492259970, -0.08587323730772, -0.25656257754070, - 0.03282930172664, -0.16276719120440, -0.00915702933434, - -0.22638893773906, -0.02364141202522, 0.39120800788284, - -0.00584456039913, -0.22138138954925, 0.06276101321749, - 0.04500235387352, -0.00000828086748, 0.02005851806501, - 0.00205861885564, 0.00302439095741, -0.02950134983287], - [0.33642304856132, -1.49858979367799, -0.25572241425570, - 0.87350271418188, -0.11828570177555, 0.12205022308084, - 0.11921148675203, -0.80774944671438, -0.07834489609479, - 0.47854794562326, -0.00469977914380, -0.12453458140019, - -0.00589500224440, -0.04067510197014, 0.05724228140351, - 0.08333755284107, 0.00832043980773, -0.04237348025746, - -0.01635381384540, 0.02977207319925, -0.01760176568150], - [0.44915256608450, -0.62820619233671, -0.14351757464547, - 0.29661783706366, -0.22784394429749, -0.37256372942400, - -0.01419140100551, 0.00213767857124, 0.04078262797139, - -0.42029820170918, -0.12398163381748, 0.22199650564824, - 0.04097565135648, 0.00613424350682, 0.10478503600251, - 0.06747620744683, -0.01863887810927, 0.05784820375801, - -0.03193428438915, 0.03222754072173, 0.00541907748707], - [0.56619470757641, -1.04800335126349, -0.75464456939302, - 0.29156311971249, 0.16242137742230, -0.26806001042947, - 0.16744243493672, 0.00819999645858, -0.18901604199609, - 0.45054734505008, 0.30931782841830, -0.33032403314006, - -0.27562961986224, 0.06739368333110, 0.00647310677246, - -0.04784254229033, 0.08647503780351, 0.01639907836189, - -0.03788984554840, 0.01807364323573, -0.00588215443421], - [0.58100494960553, -0.51035327095184, -0.53174909058578, - -0.31863563325245, -0.14289799034253, -0.20256413484477, - 0.17520704835522, 0.14728154134330, 0.02377945217615, - 0.38952639978999, 0.15558449135573, -0.23313271880868, - -0.25344790059353, -0.05246019024463, 0.01628462406333, - -0.02505961724053, 0.06920467763959, 0.02442357316099, - -0.03721611395801, 0.01818801111503, -0.00749618797172], - [0.53648789255105, -0.25049871956020, -0.42163034350696, - -0.43193942311114, -0.00275953611929, -0.03424681017675, - 0.04267842219415, -0.04678328784242, -0.10214864179676, - 0.26408300200955, 0.14590772289388, 0.15113130533216, - -0.02459864859345, -0.17556493366449, -0.11202315195388, - -0.18823009262115, -0.04060034127000, 0.05477720428674, - 0.04788665548180, 0.04704409688120, -0.02217936801134]]; - - var ABButter = [ - [0.98621192462708, -1.97223372919527, -1.97242384925416, - 0.97261396931306, 0.98621192462708], - [0.98500175787242, -1.96977855582618, -1.97000351574484, - 0.97022847566350, 0.98500175787242], - [0.97938932735214, -1.95835380975398, -1.95877865470428, - 0.95920349965459, 0.97938932735214], - [0.97531843204928, -1.95002759149878, -1.95063686409857, - 0.95124613669835, 0.97531843204928], - [0.97316523498161, -1.94561023566527, -1.94633046996323, - 0.94705070426118, 0.97316523498161], - [0.96454515552826, -1.92783286977036, -1.92909031105652, - 0.93034775234268, 0.96454515552826], - [0.96009142950541, -1.91858953033784, -1.92018285901082, - 0.92177618768381, 0.96009142950541], - [0.95856916599601, -1.91542108074780, -1.91713833199203, - 0.91885558323625, 0.95856916599601], - [0.94597685600279, -1.88903307939452, -1.89195371200558, - 0.89487434461664, 0.94597685600279]]; - - - /** - * When calling this procedure, make sure that ip[-order] and op[-order] - * point to real data - */ - //private void filterYule(final float[] input, int inputPos, float[] output, - //int outputPos, int nSamples, final float[] kernel) { - function filterYule(input, inputPos, output, outputPos, nSamples, kernel) { - - while ((nSamples--) != 0) { - /* 1e-10 is a hack to avoid slowdown because of denormals */ - output[outputPos] = 1e-10 + input[inputPos + 0] * kernel[0] - - output[outputPos - 1] * kernel[1] + input[inputPos - 1] - * kernel[2] - output[outputPos - 2] * kernel[3] - + input[inputPos - 2] * kernel[4] - output[outputPos - 3] - * kernel[5] + input[inputPos - 3] * kernel[6] - - output[outputPos - 4] * kernel[7] + input[inputPos - 4] - * kernel[8] - output[outputPos - 5] * kernel[9] - + input[inputPos - 5] * kernel[10] - output[outputPos - 6] - * kernel[11] + input[inputPos - 6] * kernel[12] - - output[outputPos - 7] * kernel[13] + input[inputPos - 7] - * kernel[14] - output[outputPos - 8] * kernel[15] - + input[inputPos - 8] * kernel[16] - output[outputPos - 9] - * kernel[17] + input[inputPos - 9] * kernel[18] - - output[outputPos - 10] * kernel[19] - + input[inputPos - 10] * kernel[20]; - ++outputPos; - ++inputPos; - } - } - -//private void filterButter(final float[] input, int inputPos, -// float[] output, int outputPos, int nSamples, final float[] kernel) { - function filterButter(input, inputPos, output, outputPos, nSamples, kernel) { - - while ((nSamples--) != 0) { - output[outputPos] = input[inputPos + 0] * kernel[0] - - output[outputPos - 1] * kernel[1] + input[inputPos - 1] - * kernel[2] - output[outputPos - 2] * kernel[3] - + input[inputPos - 2] * kernel[4]; - ++outputPos; - ++inputPos; - } - } - - /** - * @return INIT_GAIN_ANALYSIS_OK if successful, INIT_GAIN_ANALYSIS_ERROR if - * not - */ - function ResetSampleFrequency(rgData, samplefreq) { - /* zero out initial values */ - for (var i = 0; i < MAX_ORDER; i++) - rgData.linprebuf[i] = rgData.lstepbuf[i] = rgData.loutbuf[i] = rgData.rinprebuf[i] = rgData.rstepbuf[i] = rgData.routbuf[i] = 0.; - - switch (0 | (samplefreq)) { - case 48000: - rgData.reqindex = 0; - break; - case 44100: - rgData.reqindex = 1; - break; - case 32000: - rgData.reqindex = 2; - break; - case 24000: - rgData.reqindex = 3; - break; - case 22050: - rgData.reqindex = 4; - break; - case 16000: - rgData.reqindex = 5; - break; - case 12000: - rgData.reqindex = 6; - break; - case 11025: - rgData.reqindex = 7; - break; - case 8000: - rgData.reqindex = 8; - break; - default: - return INIT_GAIN_ANALYSIS_ERROR; - } - - rgData.sampleWindow = 0 | ((samplefreq * RMS_WINDOW_TIME_NUMERATOR - + RMS_WINDOW_TIME_DENOMINATOR - 1) / RMS_WINDOW_TIME_DENOMINATOR); - - rgData.lsum = 0.; - rgData.rsum = 0.; - rgData.totsamp = 0; - - Arrays.ill(rgData.A, 0); - - return INIT_GAIN_ANALYSIS_OK; - } - - this.InitGainAnalysis = function (rgData, samplefreq) { - if (ResetSampleFrequency(rgData, samplefreq) != INIT_GAIN_ANALYSIS_OK) { - return INIT_GAIN_ANALYSIS_ERROR; - } - - rgData.linpre = MAX_ORDER; - rgData.rinpre = MAX_ORDER; - rgData.lstep = MAX_ORDER; - rgData.rstep = MAX_ORDER; - rgData.lout = MAX_ORDER; - rgData.rout = MAX_ORDER; - - Arrays.fill(rgData.B, 0); - - return INIT_GAIN_ANALYSIS_OK; - }; - - /** - * square - */ - function fsqr(d) { - return d * d; - } - - this.AnalyzeSamples = function (rgData, left_samples, left_samplesPos, right_samples, right_samplesPos, num_samples, - num_channels) { - var curleft; - var curleftBase; - var curright; - var currightBase; - var batchsamples; - var cursamples; - var cursamplepos; - - if (num_samples == 0) - return GAIN_ANALYSIS_OK; - - cursamplepos = 0; - batchsamples = num_samples; - - switch (num_channels) { - case 1: - right_samples = left_samples; - right_samplesPos = left_samplesPos; - break; - case 2: - break; - default: - return GAIN_ANALYSIS_ERROR; - } - - if (num_samples < MAX_ORDER) { - System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf, - MAX_ORDER, num_samples); - System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf, - MAX_ORDER, num_samples); - } else { - System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf, - MAX_ORDER, MAX_ORDER); - System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf, - MAX_ORDER, MAX_ORDER); - } - - while (batchsamples > 0) { - cursamples = batchsamples > rgData.sampleWindow - rgData.totsamp ? rgData.sampleWindow - - rgData.totsamp - : batchsamples; - if (cursamplepos < MAX_ORDER) { - curleft = rgData.linpre + cursamplepos; - curleftBase = rgData.linprebuf; - curright = rgData.rinpre + cursamplepos; - currightBase = rgData.rinprebuf; - if (cursamples > MAX_ORDER - cursamplepos) - cursamples = MAX_ORDER - cursamplepos; - } else { - curleft = left_samplesPos + cursamplepos; - curleftBase = left_samples; - curright = right_samplesPos + cursamplepos; - currightBase = right_samples; - } - - filterYule(curleftBase, curleft, rgData.lstepbuf, rgData.lstep - + rgData.totsamp, cursamples, ABYule[rgData.reqindex]); - filterYule(currightBase, curright, rgData.rstepbuf, rgData.rstep - + rgData.totsamp, cursamples, ABYule[rgData.reqindex]); - - filterButter(rgData.lstepbuf, rgData.lstep + rgData.totsamp, - rgData.loutbuf, rgData.lout + rgData.totsamp, cursamples, - ABButter[rgData.reqindex]); - filterButter(rgData.rstepbuf, rgData.rstep + rgData.totsamp, - rgData.routbuf, rgData.rout + rgData.totsamp, cursamples, - ABButter[rgData.reqindex]); - - curleft = rgData.lout + rgData.totsamp; - /* Get the squared values */ - curleftBase = rgData.loutbuf; - curright = rgData.rout + rgData.totsamp; - currightBase = rgData.routbuf; - - var i = cursamples % 8; - while ((i--) != 0) { - rgData.lsum += fsqr(curleftBase[curleft++]); - rgData.rsum += fsqr(currightBase[curright++]); - } - i = cursamples / 8; - while ((i--) != 0) { - rgData.lsum += fsqr(curleftBase[curleft + 0]) - + fsqr(curleftBase[curleft + 1]) - + fsqr(curleftBase[curleft + 2]) - + fsqr(curleftBase[curleft + 3]) - + fsqr(curleftBase[curleft + 4]) - + fsqr(curleftBase[curleft + 5]) - + fsqr(curleftBase[curleft + 6]) - + fsqr(curleftBase[curleft + 7]); - curleft += 8; - rgData.rsum += fsqr(currightBase[curright + 0]) - + fsqr(currightBase[curright + 1]) - + fsqr(currightBase[curright + 2]) - + fsqr(currightBase[curright + 3]) - + fsqr(currightBase[curright + 4]) - + fsqr(currightBase[curright + 5]) - + fsqr(currightBase[curright + 6]) - + fsqr(currightBase[curright + 7]); - curright += 8; - } - - batchsamples -= cursamples; - cursamplepos += cursamples; - rgData.totsamp += cursamples; - if (rgData.totsamp == rgData.sampleWindow) { - /* Get the Root Mean Square (RMS) for this set of samples */ - var val = GainAnalysis.STEPS_per_dB - * 10. - * Math.log10((rgData.lsum + rgData.rsum) - / rgData.totsamp * 0.5 + 1.e-37); - var ival = (val <= 0) ? 0 : 0 | val; - if (ival >= rgData.A.length) - ival = rgData.A.length - 1; - rgData.A[ival]++; - rgData.lsum = rgData.rsum = 0.; - - System.arraycopy(rgData.loutbuf, rgData.totsamp, - rgData.loutbuf, 0, MAX_ORDER); - System.arraycopy(rgData.routbuf, rgData.totsamp, - rgData.routbuf, 0, MAX_ORDER); - System.arraycopy(rgData.lstepbuf, rgData.totsamp, - rgData.lstepbuf, 0, MAX_ORDER); - System.arraycopy(rgData.rstepbuf, rgData.totsamp, - rgData.rstepbuf, 0, MAX_ORDER); - rgData.totsamp = 0; - } - if (rgData.totsamp > rgData.sampleWindow) { - /* - * somehow I really screwed up: Error in programming! Contact - * author about totsamp > sampleWindow - */ - return GAIN_ANALYSIS_ERROR; - } - } - if (num_samples < MAX_ORDER) { - System.arraycopy(rgData.linprebuf, num_samples, rgData.linprebuf, - 0, MAX_ORDER - num_samples); - System.arraycopy(rgData.rinprebuf, num_samples, rgData.rinprebuf, - 0, MAX_ORDER - num_samples); - System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf, - MAX_ORDER - num_samples, num_samples); - System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf, - MAX_ORDER - num_samples, num_samples); - } else { - System.arraycopy(left_samples, left_samplesPos + num_samples - - MAX_ORDER, rgData.linprebuf, 0, MAX_ORDER); - System.arraycopy(right_samples, right_samplesPos + num_samples - - MAX_ORDER, rgData.rinprebuf, 0, MAX_ORDER); - } - - return GAIN_ANALYSIS_OK; - }; - - function analyzeResult(Array, len) { - var i; - - var elems = 0; - for (i = 0; i < len; i++) - elems += Array[i]; - if (elems == 0) - return GAIN_NOT_ENOUGH_SAMPLES; - - var upper = 0 | Math.ceil(elems * (1. - RMS_PERCENTILE)); - for (i = len; i-- > 0;) { - if ((upper -= Array[i]) <= 0) - break; - } - - //return (float) ((float) PINK_REF - (float) i / (float) STEPS_per_dB); - return (PINK_REF - i / GainAnalysis.STEPS_per_dB); - } - - this.GetTitleGain = function (rgData) { - var retval = analyzeResult(rgData.A, rgData.A.length); - - for (var i = 0; i < rgData.A.length; i++) { - rgData.B[i] += rgData.A[i]; - rgData.A[i] = 0; - } - - for (var i = 0; i < MAX_ORDER; i++) - rgData.linprebuf[i] = rgData.lstepbuf[i] = rgData.loutbuf[i] = rgData.rinprebuf[i] = rgData.rstepbuf[i] = rgData.routbuf[i] = 0.; - - rgData.totsamp = 0; - rgData.lsum = rgData.rsum = 0.; - return retval; - } - -} - -module.exports = GainAnalysis; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/GrInfo.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/GrInfo.js deleted file mode 100644 index f62dcee42..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/GrInfo.js +++ /dev/null @@ -1,107 +0,0 @@ -//package mp3; -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -var L3Side = require('./L3Side.js'); - -function GrInfo() { - //float xr[] = new float[576]; - this.xr = new_float(576); - //int l3_enc[] = new int[576]; - this.l3_enc = new_int(576); - //int scalefac[] = new int[L3Side.SFBMAX]; - this.scalefac = new_int(L3Side.SFBMAX); - this.xrpow_max = 0.; - - this.part2_3_length = 0; - this.big_values = 0; - this.count1 = 0; - this.global_gain = 0; - this.scalefac_compress = 0; - this.block_type = 0; - this.mixed_block_flag = 0; - this.table_select = new_int(3); - this.subblock_gain = new_int(3 + 1); - this.region0_count = 0; - this.region1_count = 0; - this.preflag = 0; - this.scalefac_scale = 0; - this.count1table_select = 0; - - this.part2_length = 0; - this.sfb_lmax = 0; - this.sfb_smin = 0; - this.psy_lmax = 0; - this.sfbmax = 0; - this.psymax = 0; - this.sfbdivide = 0; - this.width = new_int(L3Side.SFBMAX); - this.window = new_int(L3Side.SFBMAX); - this.count1bits = 0; - /** - * added for LSF - */ - this.sfb_partition_table = null; - this.slen = new_int(4); - - this.max_nonzero_coeff = 0; - - var self = this; - function clone_int(array) { - return new Int32Array(array); - } - function clone_float(array) { - return new Float32Array(array); - } - this.assign = function (other) { - self.xr = clone_float(other.xr); //.slice(0); //clone(); - self.l3_enc = clone_int(other.l3_enc); //.slice(0); //clone(); - self.scalefac = clone_int(other.scalefac);//.slice(0); //clone(); - self.xrpow_max = other.xrpow_max; - - self.part2_3_length = other.part2_3_length; - self.big_values = other.big_values; - self.count1 = other.count1; - self.global_gain = other.global_gain; - self.scalefac_compress = other.scalefac_compress; - self.block_type = other.block_type; - self.mixed_block_flag = other.mixed_block_flag; - self.table_select = clone_int(other.table_select);//.slice(0); //clone(); - self.subblock_gain = clone_int(other.subblock_gain); //.slice(0); //.clone(); - self.region0_count = other.region0_count; - self.region1_count = other.region1_count; - self.preflag = other.preflag; - self.scalefac_scale = other.scalefac_scale; - self.count1table_select = other.count1table_select; - - self.part2_length = other.part2_length; - self.sfb_lmax = other.sfb_lmax; - self.sfb_smin = other.sfb_smin; - self.psy_lmax = other.psy_lmax; - self.sfbmax = other.sfbmax; - self.psymax = other.psymax; - self.sfbdivide = other.sfbdivide; - self.width = clone_int(other.width); //.slice(0); //.clone(); - self.window = clone_int(other.window); //.slice(0); //.clone(); - self.count1bits = other.count1bits; - - self.sfb_partition_table = other.sfb_partition_table.slice(0); //.clone(); - self.slen = clone_int(other.slen); //.slice(0); //.clone(); - self.max_nonzero_coeff = other.max_nonzero_coeff; - } -} - -module.exports = GrInfo; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/ID3TagSpec.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/ID3TagSpec.js deleted file mode 100644 index 1fd648dec..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/ID3TagSpec.js +++ /dev/null @@ -1,25 +0,0 @@ -//package mp3; - -//import java.util.ArrayList; - -//import mp3.ID3Tag.MimeType; - -function ID3TagSpec() { - this.flags = 0; - this.year = 0; - this.title = null; - this.artist = null; - this.album = null; - this.comment = null; - this.track_id3v1 = 0; - this.genre_id3v1 = 0; - //byte[] albumart; - this.albumart = null; - this.albumart_size = 0; - this.padding_size = 0; - this.albumart_mimetype = null; - this.values = []; - this.num_values = 0; - this.v2_head = null; - this.v2_tail = null; -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/IIISideInfo.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/IIISideInfo.js deleted file mode 100644 index ca1647405..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/IIISideInfo.js +++ /dev/null @@ -1,34 +0,0 @@ -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -var GrInfo = require('./GrInfo.js'); - -function IIISideInfo() { - this.tt = [[null, null], [null, null]]; - this.main_data_begin = 0; - this.private_bits = 0; - this.resvDrain_pre = 0; - this.resvDrain_post = 0; - this.scfsi = [new_int(4), new_int(4)]; - - for (var gr = 0; gr < 2; gr++) { - for (var ch = 0; ch < 2; ch++) { - this.tt[gr][ch] = new GrInfo(); - } - } -} - -module.exports = IIISideInfo; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/III_psy_ratio.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/III_psy_ratio.js deleted file mode 100644 index d2e748608..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/III_psy_ratio.js +++ /dev/null @@ -1,10 +0,0 @@ -//package mp3; - -var III_psy_xmin = require('./III_psy_xmin.js'); - -function III_psy_ratio() { - this.thm = new III_psy_xmin(); - this.en = new III_psy_xmin(); -} - -module.exports = III_psy_ratio; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/III_psy_xmin.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/III_psy_xmin.js deleted file mode 100644 index 466cb93ff..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/III_psy_xmin.js +++ /dev/null @@ -1,33 +0,0 @@ -var Encoder = require('./Encoder.js'); -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -function III_psy_xmin() { - this.l = new_float(Encoder.SBMAX_l); - this.s = new_float_n([Encoder.SBMAX_s, 3]); - - var self = this; - this.assign = function (iii_psy_xmin) { - System.arraycopy(iii_psy_xmin.l, 0, self.l, 0, Encoder.SBMAX_l); - for (var i = 0; i < Encoder.SBMAX_s; i++) { - for (var j = 0; j < 3; j++) { - self.s[i][j] = iii_psy_xmin.s[i][j]; - } - } - } -} - -module.exports = III_psy_xmin; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/L3Side.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/L3Side.js deleted file mode 100644 index 1831f8304..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/L3Side.js +++ /dev/null @@ -1,11 +0,0 @@ -var Encoder = require('./Encoder.js'); - -var L3Side = {}; - - - /** - * max scalefactor band, max(SBMAX_l, SBMAX_s*3, (SBMAX_s-3)*3+8) - */ -L3Side.SFBMAX = (Encoder.SBMAX_s * 3); - -module.exports = L3Side; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Lame.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Lame.js deleted file mode 100644 index b90bdd603..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Lame.js +++ /dev/null @@ -1,1870 +0,0 @@ -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var new_short_n = common.new_short_n; -var assert = common.assert; - -var PsyModel = require('./PsyModel.js'); -var LameGlobalFlags = require('./LameGlobalFlags.js'); -var LameInternalFlags = require('./LameInternalFlags.js'); -var ATH = require('./ATH.js'); -var ReplayGain = require('./ReplayGain.js'); -var CBRNewIterationLoop = require('./CBRNewIterationLoop.js'); -var BitStream = require('./BitStream.js'); -var Tables = require('./Tables.js'); -var Encoder = require('./Encoder.js'); - -function Lame() { - var MPEGMode = require('./MPEGMode.js'); - var self = this; - var LAME_MAXALBUMART = (128 * 1024); - - Lame.V9 = 410; - Lame.V8 = 420; - Lame.V7 = 430; - Lame.V6 = 440; - Lame.V5 = 450; - Lame.V4 = 460; - Lame.V3 = 470; - Lame.V2 = 480; - Lame.V1 = 490; - Lame.V0 = 500; - - /* still there for compatibility */ - - Lame.R3MIX = 1000; - Lame.STANDARD = 1001; - Lame.EXTREME = 1002; - Lame.INSANE = 1003; - Lame.STANDARD_FAST = 1004; - Lame.EXTREME_FAST = 1005; - Lame.MEDIUM = 1006; - Lame.MEDIUM_FAST = 1007; - - /** - * maximum size of mp3buffer needed if you encode at most 1152 samples for - * each call to lame_encode_buffer. see lame_encode_buffer() below - * (LAME_MAXMP3BUFFER is now obsolete) - */ - var LAME_MAXMP3BUFFER = (16384 + LAME_MAXALBUMART); - Lame.LAME_MAXMP3BUFFER = LAME_MAXMP3BUFFER; - - var ga; - var bs; - var p; - var qupvt; - var qu; - var psy = new PsyModel(); - var vbr; - var ver; - var id3; - var mpglib; - this.enc = new Encoder(); - - this.setModules = function (_ga, _bs, _p, _qupvt, _qu, _vbr, _ver, _id3, _mpglib) { - ga = _ga; - bs = _bs; - p = _p; - qupvt = _qupvt; - qu = _qu; - vbr = _vbr; - ver = _ver; - id3 = _id3; - mpglib = _mpglib; - this.enc.setModules(bs, psy, qupvt, vbr); - } - - /** - * PSY Model related stuff - */ - function PSY() { - /** - * The dbQ stuff. - */ - this.mask_adjust = 0.; - /** - * The dbQ stuff. - */ - this.mask_adjust_short = 0.; - /* at transition from one scalefactor band to next */ - /** - * Band weight long scalefactor bands. - */ - this.bo_l_weight = new_float(Encoder.SBMAX_l); - /** - * Band weight short scalefactor bands. - */ - this.bo_s_weight = new_float(Encoder.SBMAX_s); - } - - function LowPassHighPass() { - this.lowerlimit = 0.; - } - - function BandPass(bitrate, lPass) { - this.lowpass = lPass; - } - - var LAME_ID = 0xFFF88E3B; - - function lame_init_old(gfp) { - var gfc; - - gfp.class_id = LAME_ID; - - gfc = gfp.internal_flags = new LameInternalFlags(); - - /* Global flags. set defaults here for non-zero values */ - /* see lame.h for description */ - /* - * set integer values to -1 to mean that LAME will compute the best - * value, UNLESS the calling program as set it (and the value is no - * longer -1) - */ - - gfp.mode = MPEGMode.NOT_SET; - gfp.original = 1; - gfp.in_samplerate = 44100; - gfp.num_channels = 2; - gfp.num_samples = -1; - - gfp.bWriteVbrTag = true; - gfp.quality = -1; - gfp.short_blocks = null; - gfc.subblock_gain = -1; - - gfp.lowpassfreq = 0; - gfp.highpassfreq = 0; - gfp.lowpasswidth = -1; - gfp.highpasswidth = -1; - - gfp.VBR = VbrMode.vbr_off; - gfp.VBR_q = 4; - gfp.ATHcurve = -1; - gfp.VBR_mean_bitrate_kbps = 128; - gfp.VBR_min_bitrate_kbps = 0; - gfp.VBR_max_bitrate_kbps = 0; - gfp.VBR_hard_min = 0; - gfc.VBR_min_bitrate = 1; - /* not 0 ????? */ - gfc.VBR_max_bitrate = 13; - /* not 14 ????? */ - - gfp.quant_comp = -1; - gfp.quant_comp_short = -1; - - gfp.msfix = -1; - - gfc.resample_ratio = 1; - - gfc.OldValue[0] = 180; - gfc.OldValue[1] = 180; - gfc.CurrentStep[0] = 4; - gfc.CurrentStep[1] = 4; - gfc.masking_lower = 1; - gfc.nsPsy.attackthre = -1; - gfc.nsPsy.attackthre_s = -1; - - gfp.scale = -1; - - gfp.athaa_type = -1; - gfp.ATHtype = -1; - /* default = -1 = set in lame_init_params */ - gfp.athaa_loudapprox = -1; - /* 1 = flat loudness approx. (total energy) */ - /* 2 = equal loudness curve */ - gfp.athaa_sensitivity = 0.0; - /* no offset */ - gfp.useTemporal = null; - gfp.interChRatio = -1; - - /* - * The reason for int mf_samples_to_encode = ENCDELAY + POSTDELAY; - * ENCDELAY = internal encoder delay. And then we have to add - * POSTDELAY=288 because of the 50% MDCT overlap. A 576 MDCT granule - * decodes to 1152 samples. To synthesize the 576 samples centered under - * this granule we need the previous granule for the first 288 samples - * (no problem), and the next granule for the next 288 samples (not - * possible if this is last granule). So we need to pad with 288 samples - * to make sure we can encode the 576 samples we are interested in. - */ - gfc.mf_samples_to_encode = Encoder.ENCDELAY + Encoder.POSTDELAY; - gfp.encoder_padding = 0; - gfc.mf_size = Encoder.ENCDELAY - Encoder.MDCTDELAY; - /* - * we pad input with this many 0's - */ - - gfp.findReplayGain = false; - gfp.decode_on_the_fly = false; - - gfc.decode_on_the_fly = false; - gfc.findReplayGain = false; - gfc.findPeakSample = false; - - gfc.RadioGain = 0; - gfc.AudiophileGain = 0; - gfc.noclipGainChange = 0; - gfc.noclipScale = -1.0; - - gfp.preset = 0; - - gfp.write_id3tag_automatic = true; - return 0; - } - - this.lame_init = function () { - var gfp = new LameGlobalFlags(); - - var ret = lame_init_old(gfp); - if (ret != 0) { - return null; - } - - gfp.lame_allocated_gfp = 1; - return gfp; - } - - function filter_coef(x) { - if (x > 1.0) - return 0.0; - if (x <= 0.0) - return 1.0; - - return Math.cos(Math.PI / 2 * x); - } - - this.nearestBitrateFullIndex = function (bitrate) { - /* borrowed from DM abr presets */ - - var full_bitrate_table = [8, 16, 24, 32, 40, 48, 56, 64, 80, - 96, 112, 128, 160, 192, 224, 256, 320]; - - var lower_range = 0, lower_range_kbps = 0, upper_range = 0, upper_range_kbps = 0; - - /* We assume specified bitrate will be 320kbps */ - upper_range_kbps = full_bitrate_table[16]; - upper_range = 16; - lower_range_kbps = full_bitrate_table[16]; - lower_range = 16; - - /* - * Determine which significant bitrates the value specified falls - * between, if loop ends without breaking then we were correct above - * that the value was 320 - */ - for (var b = 0; b < 16; b++) { - if ((Math.max(bitrate, full_bitrate_table[b + 1])) != bitrate) { - upper_range_kbps = full_bitrate_table[b + 1]; - upper_range = b + 1; - lower_range_kbps = full_bitrate_table[b]; - lower_range = (b); - break; - /* We found upper range */ - } - } - - /* Determine which range the value specified is closer to */ - if ((upper_range_kbps - bitrate) > (bitrate - lower_range_kbps)) { - return lower_range; - } - return upper_range; - } - - function optimum_samplefreq(lowpassfreq, input_samplefreq) { - /* - * Rules: - * - * - if possible, sfb21 should NOT be used - */ - var suggested_samplefreq = 44100; - - if (input_samplefreq >= 48000) - suggested_samplefreq = 48000; - else if (input_samplefreq >= 44100) - suggested_samplefreq = 44100; - else if (input_samplefreq >= 32000) - suggested_samplefreq = 32000; - else if (input_samplefreq >= 24000) - suggested_samplefreq = 24000; - else if (input_samplefreq >= 22050) - suggested_samplefreq = 22050; - else if (input_samplefreq >= 16000) - suggested_samplefreq = 16000; - else if (input_samplefreq >= 12000) - suggested_samplefreq = 12000; - else if (input_samplefreq >= 11025) - suggested_samplefreq = 11025; - else if (input_samplefreq >= 8000) - suggested_samplefreq = 8000; - - if (lowpassfreq == -1) - return suggested_samplefreq; - - if (lowpassfreq <= 15960) - suggested_samplefreq = 44100; - if (lowpassfreq <= 15250) - suggested_samplefreq = 32000; - if (lowpassfreq <= 11220) - suggested_samplefreq = 24000; - if (lowpassfreq <= 9970) - suggested_samplefreq = 22050; - if (lowpassfreq <= 7230) - suggested_samplefreq = 16000; - if (lowpassfreq <= 5420) - suggested_samplefreq = 12000; - if (lowpassfreq <= 4510) - suggested_samplefreq = 11025; - if (lowpassfreq <= 3970) - suggested_samplefreq = 8000; - - if (input_samplefreq < suggested_samplefreq) { - /* - * choose a valid MPEG sample frequency above the input sample - * frequency to avoid SFB21/12 bitrate bloat rh 061115 - */ - if (input_samplefreq > 44100) { - return 48000; - } - if (input_samplefreq > 32000) { - return 44100; - } - if (input_samplefreq > 24000) { - return 32000; - } - if (input_samplefreq > 22050) { - return 24000; - } - if (input_samplefreq > 16000) { - return 22050; - } - if (input_samplefreq > 12000) { - return 16000; - } - if (input_samplefreq > 11025) { - return 12000; - } - if (input_samplefreq > 8000) { - return 11025; - } - return 8000; - } - return suggested_samplefreq; - } - - /** - * convert samp freq in Hz to index - */ - function SmpFrqIndex(sample_freq, gpf) { - switch (sample_freq) { - case 44100: - gpf.version = 1; - return 0; - case 48000: - gpf.version = 1; - return 1; - case 32000: - gpf.version = 1; - return 2; - case 22050: - gpf.version = 0; - return 0; - case 24000: - gpf.version = 0; - return 1; - case 16000: - gpf.version = 0; - return 2; - case 11025: - gpf.version = 0; - return 0; - case 12000: - gpf.version = 0; - return 1; - case 8000: - gpf.version = 0; - return 2; - default: - gpf.version = 0; - return -1; - } - } - - /** - * @param bRate - * legal rates from 8 to 320 - */ - function FindNearestBitrate(bRate, version, samplerate) { - /* MPEG-1 or MPEG-2 LSF */ - if (samplerate < 16000) - version = 2; - - var bitrate = Tables.bitrate_table[version][1]; - - for (var i = 2; i <= 14; i++) { - if (Tables.bitrate_table[version][i] > 0) { - if (Math.abs(Tables.bitrate_table[version][i] - bRate) < Math - .abs(bitrate - bRate)) - bitrate = Tables.bitrate_table[version][i]; - } - } - return bitrate; - } - - /** - * @param bRate - * legal rates from 32 to 448 kbps - * @param version - * MPEG-1 or MPEG-2/2.5 LSF - */ - function BitrateIndex(bRate, version, samplerate) { - /* convert bitrate in kbps to index */ - if (samplerate < 16000) - version = 2; - for (var i = 0; i <= 14; i++) { - if (Tables.bitrate_table[version][i] > 0) { - if (Tables.bitrate_table[version][i] == bRate) { - return i; - } - } - } - return -1; - } - - function optimum_bandwidth(lh, bitrate) { - /** - *
-         *  Input:
-         *      bitrate     total bitrate in kbps
-         *
-         *   Output:
-         *      lowerlimit: best lowpass frequency limit for input filter in Hz
-         *      upperlimit: best highpass frequency limit for input filter in Hz
-         * 
- */ - var freq_map = [new BandPass(8, 2000), - new BandPass(16, 3700), new BandPass(24, 3900), - new BandPass(32, 5500), new BandPass(40, 7000), - new BandPass(48, 7500), new BandPass(56, 10000), - new BandPass(64, 11000), new BandPass(80, 13500), - new BandPass(96, 15100), new BandPass(112, 15600), - new BandPass(128, 17000), new BandPass(160, 17500), - new BandPass(192, 18600), new BandPass(224, 19400), - new BandPass(256, 19700), new BandPass(320, 20500)]; - - var table_index = self.nearestBitrateFullIndex(bitrate); - lh.lowerlimit = freq_map[table_index].lowpass; - } - - function lame_init_params_ppflt(gfp) { - var gfc = gfp.internal_flags; - /***************************************************************/ - /* compute info needed for polyphase filter (filter type==0, default) */ - /***************************************************************/ - - var lowpass_band = 32; - var highpass_band = -1; - - if (gfc.lowpass1 > 0) { - var minband = 999; - for (var band = 0; band <= 31; band++) { - var freq = (band / 31.0); - /* this band and above will be zeroed: */ - if (freq >= gfc.lowpass2) { - lowpass_band = Math.min(lowpass_band, band); - } - if (gfc.lowpass1 < freq && freq < gfc.lowpass2) { - minband = Math.min(minband, band); - } - } - - /* - * compute the *actual* transition band implemented by the polyphase - * filter - */ - if (minband == 999) { - gfc.lowpass1 = (lowpass_band - .75) / 31.0; - } else { - gfc.lowpass1 = (minband - .75) / 31.0; - } - gfc.lowpass2 = lowpass_band / 31.0; - } - - /* - * make sure highpass filter is within 90% of what the effective - * highpass frequency will be - */ - if (gfc.highpass2 > 0) { - if (gfc.highpass2 < .9 * (.75 / 31.0)) { - gfc.highpass1 = 0; - gfc.highpass2 = 0; - System.err.println("Warning: highpass filter disabled. " - + "highpass frequency too small\n"); - } - } - - if (gfc.highpass2 > 0) { - var maxband = -1; - for (var band = 0; band <= 31; band++) { - var freq = band / 31.0; - /* this band and below will be zereod */ - if (freq <= gfc.highpass1) { - highpass_band = Math.max(highpass_band, band); - } - if (gfc.highpass1 < freq && freq < gfc.highpass2) { - maxband = Math.max(maxband, band); - } - } - /* - * compute the *actual* transition band implemented by the polyphase - * filter - */ - gfc.highpass1 = highpass_band / 31.0; - if (maxband == -1) { - gfc.highpass2 = (highpass_band + .75) / 31.0; - } else { - gfc.highpass2 = (maxband + .75) / 31.0; - } - } - - for (var band = 0; band < 32; band++) { - var fc1, fc2; - var freq = band / 31.0; - if (gfc.highpass2 > gfc.highpass1) { - fc1 = filter_coef((gfc.highpass2 - freq) - / (gfc.highpass2 - gfc.highpass1 + 1e-20)); - } else { - fc1 = 1.0; - } - if (gfc.lowpass2 > gfc.lowpass1) { - fc2 = filter_coef((freq - gfc.lowpass1) - / (gfc.lowpass2 - gfc.lowpass1 + 1e-20)); - } else { - fc2 = 1.0; - } - gfc.amp_filter[band] = (fc1 * fc2); - } - } - - function lame_init_qval(gfp) { - var gfc = gfp.internal_flags; - - switch (gfp.quality) { - default: - case 9: /* no psymodel, no noise shaping */ - gfc.psymodel = 0; - gfc.noise_shaping = 0; - gfc.noise_shaping_amp = 0; - gfc.noise_shaping_stop = 0; - gfc.use_best_huffman = 0; - gfc.full_outer_loop = 0; - break; - - case 8: - gfp.quality = 7; - //$FALL-THROUGH$ - case 7: - /* - * use psymodel (for short block and m/s switching), but no noise - * shapping - */ - gfc.psymodel = 1; - gfc.noise_shaping = 0; - gfc.noise_shaping_amp = 0; - gfc.noise_shaping_stop = 0; - gfc.use_best_huffman = 0; - gfc.full_outer_loop = 0; - break; - - case 6: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - gfc.noise_shaping_amp = 0; - gfc.noise_shaping_stop = 0; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 0; - gfc.full_outer_loop = 0; - break; - - case 5: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - gfc.noise_shaping_amp = 0; - gfc.noise_shaping_stop = 0; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 0; - gfc.full_outer_loop = 0; - break; - - case 4: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - gfc.noise_shaping_amp = 0; - gfc.noise_shaping_stop = 0; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 1; - gfc.full_outer_loop = 0; - break; - - case 3: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - gfc.noise_shaping_amp = 1; - gfc.noise_shaping_stop = 1; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 1; - gfc.full_outer_loop = 0; - break; - - case 2: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - if (gfc.substep_shaping == 0) - gfc.substep_shaping = 2; - gfc.noise_shaping_amp = 1; - gfc.noise_shaping_stop = 1; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 1; - /* inner loop */ - gfc.full_outer_loop = 0; - break; - - case 1: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - if (gfc.substep_shaping == 0) - gfc.substep_shaping = 2; - gfc.noise_shaping_amp = 2; - gfc.noise_shaping_stop = 1; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 1; - gfc.full_outer_loop = 0; - break; - - case 0: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - if (gfc.substep_shaping == 0) - gfc.substep_shaping = 2; - gfc.noise_shaping_amp = 2; - gfc.noise_shaping_stop = 1; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 1; - /* - * type 2 disabled because of it slowness, in favor of full outer - * loop search - */ - gfc.full_outer_loop = 0; - /* - * full outer loop search disabled because of audible distortions it - * may generate rh 060629 - */ - break; - } - - } - - function lame_init_bitstream(gfp) { - var gfc = gfp.internal_flags; - gfp.frameNum = 0; - - if (gfp.write_id3tag_automatic) { - id3.id3tag_write_v2(gfp); - } - /* initialize histogram data optionally used by frontend */ - - gfc.bitrate_stereoMode_Hist = new_int_n([16, 4 + 1]); - gfc.bitrate_blockType_Hist = new_int_n([16, 4 + 1 + 1]); - - gfc.PeakSample = 0.0; - - /* Write initial VBR Header to bitstream and init VBR data */ - if (gfp.bWriteVbrTag) - vbr.InitVbrTag(gfp); - } - - /******************************************************************** - * initialize internal params based on data in gf (globalflags struct filled - * in by calling program) - * - * OUTLINE: - * - * We first have some complex code to determine bitrate, output samplerate - * and mode. It is complicated by the fact that we allow the user to set - * some or all of these parameters, and need to determine best possible - * values for the rest of them: - * - * 1. set some CPU related flags 2. check if we are mono.mono, stereo.mono - * or stereo.stereo 3. compute bitrate and output samplerate: user may have - * set compression ratio user may have set a bitrate user may have set a - * output samplerate 4. set some options which depend on output samplerate - * 5. compute the actual compression ratio 6. set mode based on compression - * ratio - * - * The remaining code is much simpler - it just sets options based on the - * mode & compression ratio: - * - * set allow_diff_short based on mode select lowpass filter based on - * compression ratio & mode set the bitrate index, and min/max bitrates for - * VBR modes disable VBR tag if it is not appropriate initialize the - * bitstream initialize scalefac_band data set sideinfo_len (based on - * channels, CRC, out_samplerate) write an id3v2 tag into the bitstream - * write VBR tag into the bitstream set mpeg1/2 flag estimate the number of - * frames (based on a lot of data) - * - * now we set more flags: nspsytune: see code VBR modes see code CBR/ABR see - * code - * - * Finally, we set the algorithm flags based on the gfp.quality value - * lame_init_qval(gfp); - * - ********************************************************************/ - this.lame_init_params = function (gfp) { - var gfc = gfp.internal_flags; - - gfc.Class_ID = 0; - if (gfc.ATH == null) - gfc.ATH = new ATH(); - if (gfc.PSY == null) - gfc.PSY = new PSY(); - if (gfc.rgdata == null) - gfc.rgdata = new ReplayGain(); - - gfc.channels_in = gfp.num_channels; - if (gfc.channels_in == 1) - gfp.mode = MPEGMode.MONO; - gfc.channels_out = (gfp.mode == MPEGMode.MONO) ? 1 : 2; - gfc.mode_ext = Encoder.MPG_MD_MS_LR; - if (gfp.mode == MPEGMode.MONO) - gfp.force_ms = false; - /* - * don't allow forced mid/side stereo for mono output - */ - - if (gfp.VBR == VbrMode.vbr_off && gfp.VBR_mean_bitrate_kbps != 128 - && gfp.brate == 0) - gfp.brate = gfp.VBR_mean_bitrate_kbps; - - if (gfp.VBR == VbrMode.vbr_off || gfp.VBR == VbrMode.vbr_mtrh - || gfp.VBR == VbrMode.vbr_mt) { - /* these modes can handle free format condition */ - } else { - gfp.free_format = false; - /* mode can't be mixed with free format */ - } - - if (gfp.VBR == VbrMode.vbr_off && gfp.brate == 0) { - /* no bitrate or compression ratio specified, use 11.025 */ - if (BitStream.EQ(gfp.compression_ratio, 0)) - gfp.compression_ratio = 11.025; - /* - * rate to compress a CD down to exactly 128000 bps - */ - } - - /* find bitrate if user specify a compression ratio */ - if (gfp.VBR == VbrMode.vbr_off && gfp.compression_ratio > 0) { - - if (gfp.out_samplerate == 0) - gfp.out_samplerate = map2MP3Frequency((int)(0.97 * gfp.in_samplerate)); - /* - * round up with a margin of 3 % - */ - - /* - * choose a bitrate for the output samplerate which achieves - * specified compression ratio - */ - gfp.brate = 0 | (gfp.out_samplerate * 16 * gfc.channels_out / (1.e3 * gfp.compression_ratio)); - - /* we need the version for the bitrate table look up */ - gfc.samplerate_index = SmpFrqIndex(gfp.out_samplerate, gfp); - - if (!gfp.free_format) /* - * for non Free Format find the nearest allowed - * bitrate - */ - gfp.brate = FindNearestBitrate(gfp.brate, gfp.version, - gfp.out_samplerate); - } - - if (gfp.out_samplerate != 0) { - if (gfp.out_samplerate < 16000) { - gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps, - 8); - gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps, - 64); - } else if (gfp.out_samplerate < 32000) { - gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps, - 8); - gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps, - 160); - } else { - gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps, - 32); - gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps, - 320); - } - } - - /****************************************************************/ - /* if a filter has not been enabled, see if we should add one: */ - /****************************************************************/ - if (gfp.lowpassfreq == 0) { - var lowpass = 16000.; - - switch (gfp.VBR) { - case VbrMode.vbr_off: - { - var lh = new LowPassHighPass(); - optimum_bandwidth(lh, gfp.brate); - lowpass = lh.lowerlimit; - break; - } - case VbrMode.vbr_abr: - { - var lh = new LowPassHighPass(); - optimum_bandwidth(lh, gfp.VBR_mean_bitrate_kbps); - lowpass = lh.lowerlimit; - break; - } - case VbrMode.vbr_rh: - { - var x = [19500, 19000, 18600, 18000, 17500, 16000, - 15600, 14900, 12500, 10000, 3950]; - if (0 <= gfp.VBR_q && gfp.VBR_q <= 9) { - var a = x[gfp.VBR_q], b = x[gfp.VBR_q + 1], m = gfp.VBR_q_frac; - lowpass = linear_int(a, b, m); - } else { - lowpass = 19500; - } - break; - } - default: - { - var x = [19500, 19000, 18500, 18000, 17500, 16500, - 15500, 14500, 12500, 9500, 3950]; - if (0 <= gfp.VBR_q && gfp.VBR_q <= 9) { - var a = x[gfp.VBR_q], b = x[gfp.VBR_q + 1], m = gfp.VBR_q_frac; - lowpass = linear_int(a, b, m); - } else { - lowpass = 19500; - } - } - } - if (gfp.mode == MPEGMode.MONO - && (gfp.VBR == VbrMode.vbr_off || gfp.VBR == VbrMode.vbr_abr)) - lowpass *= 1.5; - - gfp.lowpassfreq = lowpass | 0; - } - - if (gfp.out_samplerate == 0) { - if (2 * gfp.lowpassfreq > gfp.in_samplerate) { - gfp.lowpassfreq = gfp.in_samplerate / 2; - } - gfp.out_samplerate = optimum_samplefreq(gfp.lowpassfreq | 0, - gfp.in_samplerate); - } - - gfp.lowpassfreq = Math.min(20500, gfp.lowpassfreq); - gfp.lowpassfreq = Math.min(gfp.out_samplerate / 2, gfp.lowpassfreq); - - if (gfp.VBR == VbrMode.vbr_off) { - gfp.compression_ratio = gfp.out_samplerate * 16 * gfc.channels_out - / (1.e3 * gfp.brate); - } - if (gfp.VBR == VbrMode.vbr_abr) { - gfp.compression_ratio = gfp.out_samplerate * 16 * gfc.channels_out - / (1.e3 * gfp.VBR_mean_bitrate_kbps); - } - - /* - * do not compute ReplayGain values and do not find the peak sample if - * we can't store them - */ - if (!gfp.bWriteVbrTag) { - gfp.findReplayGain = false; - gfp.decode_on_the_fly = false; - gfc.findPeakSample = false; - } - gfc.findReplayGain = gfp.findReplayGain; - gfc.decode_on_the_fly = gfp.decode_on_the_fly; - - if (gfc.decode_on_the_fly) - gfc.findPeakSample = true; - - if (gfc.findReplayGain) { - if (ga.InitGainAnalysis(gfc.rgdata, gfp.out_samplerate) == GainAnalysis.INIT_GAIN_ANALYSIS_ERROR) { - gfp.internal_flags = null; - return -6; - } - } - - if (gfc.decode_on_the_fly && !gfp.decode_only) { - if (gfc.hip != null) { - mpglib.hip_decode_exit(gfc.hip); - } - gfc.hip = mpglib.hip_decode_init(); - } - - gfc.mode_gr = gfp.out_samplerate <= 24000 ? 1 : 2; - /* - * Number of granules per frame - */ - gfp.framesize = 576 * gfc.mode_gr; - gfp.encoder_delay = Encoder.ENCDELAY; - - gfc.resample_ratio = gfp.in_samplerate / gfp.out_samplerate; - - /** - *
-         *  sample freq       bitrate     compression ratio
-         *     [kHz]      [kbps/channel]   for 16 bit input
-         *     44.1            56               12.6
-         *     44.1            64               11.025
-         *     44.1            80                8.82
-         *     22.05           24               14.7
-         *     22.05           32               11.025
-         *     22.05           40                8.82
-         *     16              16               16.0
-         *     16              24               10.667
-         * 
- */ - /** - *
-         *  For VBR, take a guess at the compression_ratio.
-         *  For example:
-         *
-         *    VBR_q    compression     like
-         *     -        4.4         320 kbps/44 kHz
-         *   0...1      5.5         256 kbps/44 kHz
-         *     2        7.3         192 kbps/44 kHz
-         *     4        8.8         160 kbps/44 kHz
-         *     6       11           128 kbps/44 kHz
-         *     9       14.7          96 kbps
-         *
-         *  for lower bitrates, downsample with --resample
-         * 
- */ - switch (gfp.VBR) { - case VbrMode.vbr_mt: - case VbrMode.vbr_rh: - case VbrMode.vbr_mtrh: - { - /* numbers are a bit strange, but they determine the lowpass value */ - var cmp = [5.7, 6.5, 7.3, 8.2, 10, 11.9, 13, 14, - 15, 16.5]; - gfp.compression_ratio = cmp[gfp.VBR_q]; - } - break; - case VbrMode.vbr_abr: - gfp.compression_ratio = gfp.out_samplerate * 16 * gfc.channels_out - / (1.e3 * gfp.VBR_mean_bitrate_kbps); - break; - default: - gfp.compression_ratio = gfp.out_samplerate * 16 * gfc.channels_out - / (1.e3 * gfp.brate); - break; - } - - /* - * mode = -1 (not set by user) or mode = MONO (because of only 1 input - * channel). If mode has not been set, then select J-STEREO - */ - if (gfp.mode == MPEGMode.NOT_SET) { - gfp.mode = MPEGMode.JOINT_STEREO; - } - - /* apply user driven high pass filter */ - if (gfp.highpassfreq > 0) { - gfc.highpass1 = 2. * gfp.highpassfreq; - - if (gfp.highpasswidth >= 0) - gfc.highpass2 = 2. * (gfp.highpassfreq + gfp.highpasswidth); - else - /* 0% above on default */ - gfc.highpass2 = (1 + 0.00) * 2. * gfp.highpassfreq; - - gfc.highpass1 /= gfp.out_samplerate; - gfc.highpass2 /= gfp.out_samplerate; - } else { - gfc.highpass1 = 0; - gfc.highpass2 = 0; - } - /* apply user driven low pass filter */ - if (gfp.lowpassfreq > 0) { - gfc.lowpass2 = 2. * gfp.lowpassfreq; - if (gfp.lowpasswidth >= 0) { - gfc.lowpass1 = 2. * (gfp.lowpassfreq - gfp.lowpasswidth); - if (gfc.lowpass1 < 0) /* has to be >= 0 */ - gfc.lowpass1 = 0; - } else { /* 0% below on default */ - gfc.lowpass1 = (1 - 0.00) * 2. * gfp.lowpassfreq; - } - gfc.lowpass1 /= gfp.out_samplerate; - gfc.lowpass2 /= gfp.out_samplerate; - } else { - gfc.lowpass1 = 0; - gfc.lowpass2 = 0; - } - - /**********************************************************************/ - /* compute info needed for polyphase filter (filter type==0, default) */ - /**********************************************************************/ - lame_init_params_ppflt(gfp); - /******************************************************* - * samplerate and bitrate index - *******************************************************/ - gfc.samplerate_index = SmpFrqIndex(gfp.out_samplerate, gfp); - if (gfc.samplerate_index < 0) { - gfp.internal_flags = null; - return -1; - } - - if (gfp.VBR == VbrMode.vbr_off) { - if (gfp.free_format) { - gfc.bitrate_index = 0; - } else { - gfp.brate = FindNearestBitrate(gfp.brate, gfp.version, - gfp.out_samplerate); - gfc.bitrate_index = BitrateIndex(gfp.brate, gfp.version, - gfp.out_samplerate); - if (gfc.bitrate_index <= 0) { - gfp.internal_flags = null; - return -1; - } - } - } else { - gfc.bitrate_index = 1; - } - - /* for CBR, we will write an "info" tag. */ - - if (gfp.analysis) - gfp.bWriteVbrTag = false; - - /* some file options not allowed if output is: not specified or stdout */ - if (gfc.pinfo != null) - gfp.bWriteVbrTag = false; - /* disable Xing VBR tag */ - - bs.init_bit_stream_w(gfc); - - var j = gfc.samplerate_index + (3 * gfp.version) + 6 - * (gfp.out_samplerate < 16000 ? 1 : 0); - for (var i = 0; i < Encoder.SBMAX_l + 1; i++) - gfc.scalefac_band.l[i] = qupvt.sfBandIndex[j].l[i]; - - for (var i = 0; i < Encoder.PSFB21 + 1; i++) { - var size = (gfc.scalefac_band.l[22] - gfc.scalefac_band.l[21]) - / Encoder.PSFB21; - var start = gfc.scalefac_band.l[21] + i * size; - gfc.scalefac_band.psfb21[i] = start; - } - gfc.scalefac_band.psfb21[Encoder.PSFB21] = 576; - - for (var i = 0; i < Encoder.SBMAX_s + 1; i++) - gfc.scalefac_band.s[i] = qupvt.sfBandIndex[j].s[i]; - - for (var i = 0; i < Encoder.PSFB12 + 1; i++) { - var size = (gfc.scalefac_band.s[13] - gfc.scalefac_band.s[12]) - / Encoder.PSFB12; - var start = gfc.scalefac_band.s[12] + i * size; - gfc.scalefac_band.psfb12[i] = start; - } - gfc.scalefac_band.psfb12[Encoder.PSFB12] = 192; - /* determine the mean bitrate for main data */ - if (gfp.version == 1) /* MPEG 1 */ - gfc.sideinfo_len = (gfc.channels_out == 1) ? 4 + 17 : 4 + 32; - else - /* MPEG 2 */ - gfc.sideinfo_len = (gfc.channels_out == 1) ? 4 + 9 : 4 + 17; - - if (gfp.error_protection) - gfc.sideinfo_len += 2; - - lame_init_bitstream(gfp); - - gfc.Class_ID = LAME_ID; - - { - var k; - - for (k = 0; k < 19; k++) - gfc.nsPsy.pefirbuf[k] = 700 * gfc.mode_gr * gfc.channels_out; - - if (gfp.ATHtype == -1) - gfp.ATHtype = 4; - } - assert(gfp.VBR_q <= 9); - assert(gfp.VBR_q >= 0); - - switch (gfp.VBR) { - - case VbrMode.vbr_mt: - gfp.VBR = VbrMode.vbr_mtrh; - //$FALL-THROUGH$ - case VbrMode.vbr_mtrh: - { - if (gfp.useTemporal == null) { - gfp.useTemporal = false; - /* off by default for this VBR mode */ - } - - p.apply_preset(gfp, 500 - (gfp.VBR_q * 10), 0); - /** - *
-                 *   The newer VBR code supports only a limited
-                 *     subset of quality levels:
-                 *     9-5=5 are the same, uses x^3/4 quantization
-                 *   4-0=0 are the same  5 plus best huffman divide code
-                 * 
- */ - if (gfp.quality < 0) - gfp.quality = LAME_DEFAULT_QUALITY; - if (gfp.quality < 5) - gfp.quality = 0; - if (gfp.quality > 5) - gfp.quality = 5; - - gfc.PSY.mask_adjust = gfp.maskingadjust; - gfc.PSY.mask_adjust_short = gfp.maskingadjust_short; - - /* - * sfb21 extra only with MPEG-1 at higher sampling rates - */ - if (gfp.experimentalY) - gfc.sfb21_extra = false; - else - gfc.sfb21_extra = (gfp.out_samplerate > 44000); - - gfc.iteration_loop = new VBRNewIterationLoop(qu); - break; - - } - case VbrMode.vbr_rh: - { - - p.apply_preset(gfp, 500 - (gfp.VBR_q * 10), 0); - - gfc.PSY.mask_adjust = gfp.maskingadjust; - gfc.PSY.mask_adjust_short = gfp.maskingadjust_short; - - /* - * sfb21 extra only with MPEG-1 at higher sampling rates - */ - if (gfp.experimentalY) - gfc.sfb21_extra = false; - else - gfc.sfb21_extra = (gfp.out_samplerate > 44000); - - /* - * VBR needs at least the output of GPSYCHO, so we have to garantee - * that by setting a minimum quality level, actually level 6 does - * it. down to level 6 - */ - if (gfp.quality > 6) - gfp.quality = 6; - - if (gfp.quality < 0) - gfp.quality = LAME_DEFAULT_QUALITY; - - gfc.iteration_loop = new VBROldIterationLoop(qu); - break; - } - - default: /* cbr/abr */ - { - var vbrmode; - - /* - * no sfb21 extra with CBR code - */ - gfc.sfb21_extra = false; - - if (gfp.quality < 0) - gfp.quality = LAME_DEFAULT_QUALITY; - - vbrmode = gfp.VBR; - if (vbrmode == VbrMode.vbr_off) - gfp.VBR_mean_bitrate_kbps = gfp.brate; - /* second, set parameters depending on bitrate */ - p.apply_preset(gfp, gfp.VBR_mean_bitrate_kbps, 0); - gfp.VBR = vbrmode; - - gfc.PSY.mask_adjust = gfp.maskingadjust; - gfc.PSY.mask_adjust_short = gfp.maskingadjust_short; - - if (vbrmode == VbrMode.vbr_off) { - gfc.iteration_loop = new CBRNewIterationLoop(qu); - } else { - gfc.iteration_loop = new ABRIterationLoop(qu); - } - break; - } - } - assert(gfp.scale >= 0); - /* initialize default values common for all modes */ - - if (gfp.VBR != VbrMode.vbr_off) { /* choose a min/max bitrate for VBR */ - /* if the user didn't specify VBR_max_bitrate: */ - gfc.VBR_min_bitrate = 1; - /* - * default: allow 8 kbps (MPEG-2) or 32 kbps (MPEG-1) - */ - gfc.VBR_max_bitrate = 14; - /* - * default: allow 160 kbps (MPEG-2) or 320 kbps (MPEG-1) - */ - if (gfp.out_samplerate < 16000) - gfc.VBR_max_bitrate = 8; - /* default: allow 64 kbps (MPEG-2.5) */ - if (gfp.VBR_min_bitrate_kbps != 0) { - gfp.VBR_min_bitrate_kbps = FindNearestBitrate( - gfp.VBR_min_bitrate_kbps, gfp.version, - gfp.out_samplerate); - gfc.VBR_min_bitrate = BitrateIndex(gfp.VBR_min_bitrate_kbps, - gfp.version, gfp.out_samplerate); - if (gfc.VBR_min_bitrate < 0) - return -1; - } - if (gfp.VBR_max_bitrate_kbps != 0) { - gfp.VBR_max_bitrate_kbps = FindNearestBitrate( - gfp.VBR_max_bitrate_kbps, gfp.version, - gfp.out_samplerate); - gfc.VBR_max_bitrate = BitrateIndex(gfp.VBR_max_bitrate_kbps, - gfp.version, gfp.out_samplerate); - if (gfc.VBR_max_bitrate < 0) - return -1; - } - gfp.VBR_min_bitrate_kbps = Tables.bitrate_table[gfp.version][gfc.VBR_min_bitrate]; - gfp.VBR_max_bitrate_kbps = Tables.bitrate_table[gfp.version][gfc.VBR_max_bitrate]; - gfp.VBR_mean_bitrate_kbps = Math.min( - Tables.bitrate_table[gfp.version][gfc.VBR_max_bitrate], - gfp.VBR_mean_bitrate_kbps); - gfp.VBR_mean_bitrate_kbps = Math.max( - Tables.bitrate_table[gfp.version][gfc.VBR_min_bitrate], - gfp.VBR_mean_bitrate_kbps); - } - - /* just another daily changing developer switch */ - if (gfp.tune) { - gfc.PSY.mask_adjust += gfp.tune_value_a; - gfc.PSY.mask_adjust_short += gfp.tune_value_a; - } - - /* initialize internal qval settings */ - lame_init_qval(gfp); - assert(gfp.scale >= 0); - /* - * automatic ATH adjustment on - */ - if (gfp.athaa_type < 0) - gfc.ATH.useAdjust = 3; - else - gfc.ATH.useAdjust = gfp.athaa_type; - - /* initialize internal adaptive ATH settings -jd */ - gfc.ATH.aaSensitivityP = Math.pow(10.0, gfp.athaa_sensitivity - / -10.0); - - if (gfp.short_blocks == null) { - gfp.short_blocks = ShortBlock.short_block_allowed; - } - - /* - * Note Jan/2003: Many hardware decoders cannot handle short blocks in - * regular stereo mode unless they are coupled (same type in both - * channels) it is a rare event (1 frame per min. or so) that LAME would - * use uncoupled short blocks, so lets turn them off until we decide how - * to handle this. No other encoders allow uncoupled short blocks, even - * though it is in the standard. - */ - /* - * rh 20040217: coupling makes no sense for mono and dual-mono streams - */ - if (gfp.short_blocks == ShortBlock.short_block_allowed - && (gfp.mode == MPEGMode.JOINT_STEREO || gfp.mode == MPEGMode.STEREO)) { - gfp.short_blocks = ShortBlock.short_block_coupled; - } - - if (gfp.quant_comp < 0) - gfp.quant_comp = 1; - if (gfp.quant_comp_short < 0) - gfp.quant_comp_short = 0; - - if (gfp.msfix < 0) - gfp.msfix = 0; - - /* select psychoacoustic model */ - gfp.exp_nspsytune = gfp.exp_nspsytune | 1; - - if (gfp.internal_flags.nsPsy.attackthre < 0) - gfp.internal_flags.nsPsy.attackthre = PsyModel.NSATTACKTHRE; - if (gfp.internal_flags.nsPsy.attackthre_s < 0) - gfp.internal_flags.nsPsy.attackthre_s = PsyModel.NSATTACKTHRE_S; - - assert(gfp.scale >= 0); - - if (gfp.scale < 0) - gfp.scale = 1; - - if (gfp.ATHtype < 0) - gfp.ATHtype = 4; - - if (gfp.ATHcurve < 0) - gfp.ATHcurve = 4; - - if (gfp.athaa_loudapprox < 0) - gfp.athaa_loudapprox = 2; - - if (gfp.interChRatio < 0) - gfp.interChRatio = 0; - - if (gfp.useTemporal == null) - gfp.useTemporal = true; - /* on by default */ - - /* - * padding method as described in - * "MPEG-Layer3 / Bitstream Syntax and Decoding" by Martin Sieler, Ralph - * Sperschneider - * - * note: there is no padding for the very first frame - * - * Robert Hegemann 2000-06-22 - */ - gfc.slot_lag = gfc.frac_SpF = 0; - if (gfp.VBR == VbrMode.vbr_off) - gfc.slot_lag = gfc.frac_SpF = (((gfp.version + 1) * 72000 * gfp.brate) % gfp.out_samplerate) | 0; - - qupvt.iteration_init(gfp); - psy.psymodel_init(gfp); - assert(gfp.scale >= 0); - return 0; - } - - function update_inbuffer_size(gfc, nsamples) { - if (gfc.in_buffer_0 == null || gfc.in_buffer_nsamples < nsamples) { - gfc.in_buffer_0 = new_float(nsamples); - gfc.in_buffer_1 = new_float(nsamples); - gfc.in_buffer_nsamples = nsamples; - } - } - - this.lame_encode_flush = function (gfp, mp3buffer, mp3bufferPos, mp3buffer_size) { - var gfc = gfp.internal_flags; - var buffer = new_short_n([2, 1152]); - var imp3 = 0, mp3count, mp3buffer_size_remaining; - - /* - * we always add POSTDELAY=288 padding to make sure granule with real - * data can be complety decoded (because of 50% overlap with next - * granule - */ - var end_padding; - var frames_left; - var samples_to_encode = gfc.mf_samples_to_encode - Encoder.POSTDELAY; - var mf_needed = calcNeeded(gfp); - - /* Was flush already called? */ - if (gfc.mf_samples_to_encode < 1) { - return 0; - } - mp3count = 0; - - if (gfp.in_samplerate != gfp.out_samplerate) { - /* - * delay due to resampling; needs to be fixed, if resampling code - * gets changed - */ - samples_to_encode += 16. * gfp.out_samplerate / gfp.in_samplerate; - } - end_padding = gfp.framesize - (samples_to_encode % gfp.framesize); - if (end_padding < 576) - end_padding += gfp.framesize; - gfp.encoder_padding = end_padding; - - frames_left = (samples_to_encode + end_padding) / gfp.framesize; - - /* - * send in a frame of 0 padding until all internal sample buffers are - * flushed - */ - while (frames_left > 0 && imp3 >= 0) { - var bunch = mf_needed - gfc.mf_size; - var frame_num = gfp.frameNum; - - bunch *= gfp.in_samplerate; - bunch /= gfp.out_samplerate; - if (bunch > 1152) - bunch = 1152; - if (bunch < 1) - bunch = 1; - - mp3buffer_size_remaining = mp3buffer_size - mp3count; - - /* if user specifed buffer size = 0, dont check size */ - if (mp3buffer_size == 0) - mp3buffer_size_remaining = 0; - - imp3 = this.lame_encode_buffer(gfp, buffer[0], buffer[1], bunch, - mp3buffer, mp3bufferPos, mp3buffer_size_remaining); - - mp3bufferPos += imp3; - mp3count += imp3; - frames_left -= (frame_num != gfp.frameNum) ? 1 : 0; - } - /* - * Set gfc.mf_samples_to_encode to 0, so we may detect and break loops - * calling it more than once in a row. - */ - gfc.mf_samples_to_encode = 0; - - if (imp3 < 0) { - /* some type of fatal error */ - return imp3; - } - - mp3buffer_size_remaining = mp3buffer_size - mp3count; - /* if user specifed buffer size = 0, dont check size */ - if (mp3buffer_size == 0) - mp3buffer_size_remaining = 0; - - /* mp3 related stuff. bit buffer might still contain some mp3 data */ - bs.flush_bitstream(gfp); - imp3 = bs.copy_buffer(gfc, mp3buffer, mp3bufferPos, - mp3buffer_size_remaining, 1); - if (imp3 < 0) { - /* some type of fatal error */ - return imp3; - } - mp3bufferPos += imp3; - mp3count += imp3; - mp3buffer_size_remaining = mp3buffer_size - mp3count; - /* if user specifed buffer size = 0, dont check size */ - if (mp3buffer_size == 0) - mp3buffer_size_remaining = 0; - - if (gfp.write_id3tag_automatic) { - /* write a id3 tag to the bitstream */ - id3.id3tag_write_v1(gfp); - - imp3 = bs.copy_buffer(gfc, mp3buffer, mp3bufferPos, - mp3buffer_size_remaining, 0); - - if (imp3 < 0) { - return imp3; - } - mp3count += imp3; - } - return mp3count; - }; - - this.lame_encode_buffer = function (gfp, buffer_l, buffer_r, nsamples, mp3buf, mp3bufPos, mp3buf_size) { - var gfc = gfp.internal_flags; - var in_buffer = [null, null]; - - if (gfc.Class_ID != LAME_ID) - return -3; - - if (nsamples == 0) - return 0; - - update_inbuffer_size(gfc, nsamples); - - in_buffer[0] = gfc.in_buffer_0; - in_buffer[1] = gfc.in_buffer_1; - - /* make a copy of input buffer, changing type to sample_t */ - for (var i = 0; i < nsamples; i++) { - in_buffer[0][i] = buffer_l[i]; - if (gfc.channels_in > 1) - in_buffer[1][i] = buffer_r[i]; - } - - return lame_encode_buffer_sample(gfp, in_buffer[0], in_buffer[1], - nsamples, mp3buf, mp3bufPos, mp3buf_size); - } - - function calcNeeded(gfp) { - var mf_needed = Encoder.BLKSIZE + gfp.framesize - Encoder.FFTOFFSET; - /* - * amount needed for FFT - */ - mf_needed = Math.max(mf_needed, 512 + gfp.framesize - 32); - assert(LameInternalFlags.MFSIZE >= mf_needed); - - return mf_needed; - } - - function lame_encode_buffer_sample(gfp, buffer_l, buffer_r, nsamples, mp3buf, mp3bufPos, mp3buf_size) { - var gfc = gfp.internal_flags; - var mp3size = 0, ret, i, ch, mf_needed; - var mp3out; - var mfbuf = [null, null]; - var in_buffer = [null, null]; - - if (gfc.Class_ID != LAME_ID) - return -3; - - if (nsamples == 0) - return 0; - - /* copy out any tags that may have been written into bitstream */ - mp3out = bs.copy_buffer(gfc, mp3buf, mp3bufPos, mp3buf_size, 0); - if (mp3out < 0) - return mp3out; - /* not enough buffer space */ - mp3bufPos += mp3out; - mp3size += mp3out; - - in_buffer[0] = buffer_l; - in_buffer[1] = buffer_r; - - /* Apply user defined re-scaling */ - - /* user selected scaling of the samples */ - if (BitStream.NEQ(gfp.scale, 0) && BitStream.NEQ(gfp.scale, 1.0)) { - for (i = 0; i < nsamples; ++i) { - in_buffer[0][i] *= gfp.scale; - if (gfc.channels_out == 2) - in_buffer[1][i] *= gfp.scale; - } - } - - /* user selected scaling of the channel 0 (left) samples */ - if (BitStream.NEQ(gfp.scale_left, 0) - && BitStream.NEQ(gfp.scale_left, 1.0)) { - for (i = 0; i < nsamples; ++i) { - in_buffer[0][i] *= gfp.scale_left; - } - } - - /* user selected scaling of the channel 1 (right) samples */ - if (BitStream.NEQ(gfp.scale_right, 0) - && BitStream.NEQ(gfp.scale_right, 1.0)) { - for (i = 0; i < nsamples; ++i) { - in_buffer[1][i] *= gfp.scale_right; - } - } - - /* Downsample to Mono if 2 channels in and 1 channel out */ - if (gfp.num_channels == 2 && gfc.channels_out == 1) { - for (i = 0; i < nsamples; ++i) { - in_buffer[0][i] = 0.5 * ( in_buffer[0][i] + in_buffer[1][i]); - in_buffer[1][i] = 0.0; - } - } - - mf_needed = calcNeeded(gfp); - - mfbuf[0] = gfc.mfbuf[0]; - mfbuf[1] = gfc.mfbuf[1]; - - var in_bufferPos = 0; - while (nsamples > 0) { - var in_buffer_ptr = [null, null]; - var n_in = 0; - /* number of input samples processed with fill_buffer */ - var n_out = 0; - /* number of samples output with fill_buffer */ - /* n_in <> n_out if we are resampling */ - - in_buffer_ptr[0] = in_buffer[0]; - in_buffer_ptr[1] = in_buffer[1]; - /* copy in new samples into mfbuf, with resampling */ - var inOut = new InOut(); - fill_buffer(gfp, mfbuf, in_buffer_ptr, in_bufferPos, nsamples, - inOut); - n_in = inOut.n_in; - n_out = inOut.n_out; - - /* compute ReplayGain of resampled input if requested */ - if (gfc.findReplayGain && !gfc.decode_on_the_fly) - if (ga.AnalyzeSamples(gfc.rgdata, mfbuf[0], gfc.mf_size, - mfbuf[1], gfc.mf_size, n_out, gfc.channels_out) == GainAnalysis.GAIN_ANALYSIS_ERROR) - return -6; - - /* update in_buffer counters */ - nsamples -= n_in; - in_bufferPos += n_in; - if (gfc.channels_out == 2) - ;// in_bufferPos += n_in; - - /* update mfbuf[] counters */ - gfc.mf_size += n_out; - assert(gfc.mf_size <= LameInternalFlags.MFSIZE); - - /* - * lame_encode_flush may have set gfc.mf_sample_to_encode to 0 so we - * have to reinitialize it here when that happened. - */ - if (gfc.mf_samples_to_encode < 1) { - gfc.mf_samples_to_encode = Encoder.ENCDELAY + Encoder.POSTDELAY; - } - gfc.mf_samples_to_encode += n_out; - - if (gfc.mf_size >= mf_needed) { - /* encode the frame. */ - /* mp3buf = pointer to current location in buffer */ - /* mp3buf_size = size of original mp3 output buffer */ - /* = 0 if we should not worry about the */ - /* buffer size because calling program is */ - /* to lazy to compute it */ - /* mp3size = size of data written to buffer so far */ - /* mp3buf_size-mp3size = amount of space avalable */ - - var buf_size = mp3buf_size - mp3size; - if (mp3buf_size == 0) - buf_size = 0; - - ret = lame_encode_frame(gfp, mfbuf[0], mfbuf[1], mp3buf, - mp3bufPos, buf_size); - - if (ret < 0) - return ret; - mp3bufPos += ret; - mp3size += ret; - - /* shift out old samples */ - gfc.mf_size -= gfp.framesize; - gfc.mf_samples_to_encode -= gfp.framesize; - for (ch = 0; ch < gfc.channels_out; ch++) - for (i = 0; i < gfc.mf_size; i++) - mfbuf[ch][i] = mfbuf[ch][i + gfp.framesize]; - } - } - assert(nsamples == 0); - - return mp3size; - } - - function lame_encode_frame(gfp, inbuf_l, inbuf_r, mp3buf, mp3bufPos, mp3buf_size) { - var ret = self.enc.lame_encode_mp3_frame(gfp, inbuf_l, inbuf_r, mp3buf, - mp3bufPos, mp3buf_size); - gfp.frameNum++; - return ret; - } - - function InOut() { - this.n_in = 0; - this.n_out = 0; - } - - - function NumUsed() { - this.num_used = 0; - } - - /** - * Greatest common divisor. - *

- * Joint work of Euclid and M. Hendry - */ - function gcd(i, j) { - return j != 0 ? gcd(j, i % j) : i; - } - - /** - * Resampling via FIR filter, blackman window. - */ - function blackman(x, fcn, l) { - /* - * This algorithm from: SIGNAL PROCESSING ALGORITHMS IN FORTRAN AND C - * S.D. Stearns and R.A. David, Prentice-Hall, 1992 - */ - var wcn = (Math.PI * fcn); - - x /= l; - if (x < 0) - x = 0; - if (x > 1) - x = 1; - var x2 = x - .5; - - var bkwn = 0.42 - 0.5 * Math.cos(2 * x * Math.PI) + 0.08 * Math.cos(4 * x * Math.PI); - if (Math.abs(x2) < 1e-9) - return (wcn / Math.PI); - else - return (bkwn * Math.sin(l * wcn * x2) / (Math.PI * l * x2)); - } - - function fill_buffer_resample(gfp, outbuf, outbufPos, desired_len, inbuf, in_bufferPos, len, num_used, ch) { - var gfc = gfp.internal_flags; - var i, j = 0, k; - /* number of convolution functions to pre-compute */ - var bpc = gfp.out_samplerate - / gcd(gfp.out_samplerate, gfp.in_samplerate); - if (bpc > LameInternalFlags.BPC) - bpc = LameInternalFlags.BPC; - - var intratio = (Math.abs(gfc.resample_ratio - - Math.floor(.5 + gfc.resample_ratio)) < .0001) ? 1 : 0; - var fcn = 1.00 / gfc.resample_ratio; - if (fcn > 1.00) - fcn = 1.00; - var filter_l = 31; - if (0 == filter_l % 2) - --filter_l; - /* must be odd */ - filter_l += intratio; - /* unless resample_ratio=int, it must be even */ - - var BLACKSIZE = filter_l + 1; - /* size of data needed for FIR */ - - if (gfc.fill_buffer_resample_init == 0) { - gfc.inbuf_old[0] = new_float(BLACKSIZE); - gfc.inbuf_old[1] = new_float(BLACKSIZE); - for (i = 0; i <= 2 * bpc; ++i) - gfc.blackfilt[i] = new_float(BLACKSIZE); - - gfc.itime[0] = 0; - gfc.itime[1] = 0; - - /* precompute blackman filter coefficients */ - for (j = 0; j <= 2 * bpc; j++) { - var sum = 0.; - var offset = (j - bpc) / (2. * bpc); - for (i = 0; i <= filter_l; i++) - sum += gfc.blackfilt[j][i] = blackman(i - offset, fcn, - filter_l); - for (i = 0; i <= filter_l; i++) - gfc.blackfilt[j][i] /= sum; - } - gfc.fill_buffer_resample_init = 1; - } - - var inbuf_old = gfc.inbuf_old[ch]; - - /* time of j'th element in inbuf = itime + j/ifreq; */ - /* time of k'th element in outbuf = j/ofreq */ - for (k = 0; k < desired_len; k++) { - var time0; - var joff; - - time0 = k * gfc.resample_ratio; - /* time of k'th output sample */ - j = 0 | Math.floor(time0 - gfc.itime[ch]); - - /* check if we need more input data */ - if ((filter_l + j - filter_l / 2) >= len) - break; - - /* blackman filter. by default, window centered at j+.5(filter_l%2) */ - /* but we want a window centered at time0. */ - var offset = (time0 - gfc.itime[ch] - (j + .5 * (filter_l % 2))); - assert(Math.abs(offset) <= .501); - - /* find the closest precomputed window for this offset: */ - joff = 0 | Math.floor((offset * 2 * bpc) + bpc + .5); - var xvalue = 0.; - for (i = 0; i <= filter_l; ++i) { - /* force integer index */ - var j2 = 0 | (i + j - filter_l / 2); - var y; - assert(j2 < len); - assert(j2 + BLACKSIZE >= 0); - y = (j2 < 0) ? inbuf_old[BLACKSIZE + j2] : inbuf[in_bufferPos - + j2]; - xvalue += y * gfc.blackfilt[joff][i]; - } - outbuf[outbufPos + k] = xvalue; - } - - /* k = number of samples added to outbuf */ - /* last k sample used data from [j-filter_l/2,j+filter_l-filter_l/2] */ - - /* how many samples of input data were used: */ - num_used.num_used = Math.min(len, filter_l + j - filter_l / 2); - - /* - * adjust our input time counter. Incriment by the number of samples - * used, then normalize so that next output sample is at time 0, next - * input buffer is at time itime[ch] - */ - gfc.itime[ch] += num_used.num_used - k * gfc.resample_ratio; - - /* save the last BLACKSIZE samples into the inbuf_old buffer */ - if (num_used.num_used >= BLACKSIZE) { - for (i = 0; i < BLACKSIZE; i++) - inbuf_old[i] = inbuf[in_bufferPos + num_used.num_used + i - - BLACKSIZE]; - } else { - /* shift in num_used.num_used samples into inbuf_old */ - var n_shift = BLACKSIZE - num_used.num_used; - /* - * number of samples to - * shift - */ - - /* - * shift n_shift samples by num_used.num_used, to make room for the - * num_used new samples - */ - for (i = 0; i < n_shift; ++i) - inbuf_old[i] = inbuf_old[i + num_used.num_used]; - - /* shift in the num_used.num_used samples */ - for (j = 0; i < BLACKSIZE; ++i, ++j) - inbuf_old[i] = inbuf[in_bufferPos + j]; - - assert(j == num_used.num_used); - } - return k; - /* return the number samples created at the new samplerate */ - } - - function fill_buffer(gfp, mfbuf, in_buffer, in_bufferPos, nsamples, io) { - var gfc = gfp.internal_flags; - - /* copy in new samples into mfbuf, with resampling if necessary */ - if ((gfc.resample_ratio < .9999) || (gfc.resample_ratio > 1.0001)) { - for (var ch = 0; ch < gfc.channels_out; ch++) { - var numUsed = new NumUsed(); - io.n_out = fill_buffer_resample(gfp, mfbuf[ch], gfc.mf_size, - gfp.framesize, in_buffer[ch], in_bufferPos, nsamples, - numUsed, ch); - io.n_in = numUsed.num_used; - } - } else { - io.n_out = Math.min(gfp.framesize, nsamples); - io.n_in = io.n_out; - for (var i = 0; i < io.n_out; ++i) { - mfbuf[0][gfc.mf_size + i] = in_buffer[0][in_bufferPos + i]; - if (gfc.channels_out == 2) - mfbuf[1][gfc.mf_size + i] = in_buffer[1][in_bufferPos + i]; - } - } - } - -} - -module.exports = Lame; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/LameGlobalFlags.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/LameGlobalFlags.js deleted file mode 100644 index 67ba833fa..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/LameGlobalFlags.js +++ /dev/null @@ -1,269 +0,0 @@ -var MPEGMode = require('./MPEGMode.js'); - -function LameGlobalFlags() { - - this.class_id = 0; - - /* input description */ - - /** - * number of samples. default=-1 - */ - this.num_samples = 0; - /** - * input number of channels. default=2 - */ - this.num_channels = 0; - /** - * input_samp_rate in Hz. default=44.1 kHz - */ - this.in_samplerate = 0; - /** - * output_samp_rate. default: LAME picks best value at least not used for - * MP3 decoding: Remember 44.1 kHz MP3s and AC97 - */ - this.out_samplerate = 0; - /** - * scale input by this amount before encoding at least not used for MP3 - * decoding - */ - this.scale = 0.; - /** - * scale input of channel 0 (left) by this amount before encoding - */ - this.scale_left = 0.; - /** - * scale input of channel 1 (right) by this amount before encoding - */ - this.scale_right = 0.; - - /* general control params */ - /** - * collect data for a MP3 frame analyzer? - */ - this.analysis = false; - /** - * add Xing VBR tag? - */ - this.bWriteVbrTag = false; - - /** - * use lame/mpglib to convert mp3 to wav - */ - this.decode_only = false; - /** - * quality setting 0=best, 9=worst default=5 - */ - this.quality = 0; - /** - * see enum default = LAME picks best value - */ - this.mode = MPEGMode.STEREO; - /** - * force M/S mode. requires mode=1 - */ - this.force_ms = false; - /** - * use free format? default=0 - */ - this.free_format = false; - /** - * find the RG value? default=0 - */ - this.findReplayGain = false; - /** - * decode on the fly? default=0 - */ - this.decode_on_the_fly = false; - /** - * 1 (default) writes ID3 tags, 0 not - */ - this.write_id3tag_automatic = false; - - /* - * set either brate>0 or compression_ratio>0, LAME will compute the value of - * the variable not set. Default is compression_ratio = 11.025 - */ - /** - * bitrate - */ - this.brate = 0; - /** - * sizeof(wav file)/sizeof(mp3 file) - */ - this.compression_ratio = 0.; - - /* frame params */ - /** - * mark as copyright. default=0 - */ - this.copyright = 0; - /** - * mark as original. default=1 - */ - this.original = 0; - /** - * the MP3 'private extension' bit. Meaningless - */ - this.extension = 0; - /** - * Input PCM is emphased PCM (for instance from one of the rarely emphased - * CDs), it is STRONGLY not recommended to use this, because psycho does not - * take it into account, and last but not least many decoders don't care - * about these bits - */ - this.emphasis = 0; - /** - * use 2 bytes per frame for a CRC checksum. default=0 - */ - this.error_protection = 0; - /** - * enforce ISO spec as much as possible - */ - this.strict_ISO = false; - - /** - * use bit reservoir? - */ - this.disable_reservoir = false; - - /* quantization/noise shaping */ - this.quant_comp = 0; - this.quant_comp_short = 0; - this.experimentalY = false; - this.experimentalZ = 0; - this.exp_nspsytune = 0; - - this.preset = 0; - - /* VBR control */ - this.VBR = null; - /** - * Range [0,...,1[ - */ - this.VBR_q_frac = 0.; - /** - * Range [0,...,9] - */ - this.VBR_q = 0; - this.VBR_mean_bitrate_kbps = 0; - this.VBR_min_bitrate_kbps = 0; - this.VBR_max_bitrate_kbps = 0; - /** - * strictly enforce VBR_min_bitrate normaly, it will be violated for analog - * silence - */ - this.VBR_hard_min = 0; - - /* resampling and filtering */ - - /** - * freq in Hz. 0=lame choses. -1=no filter - */ - this.lowpassfreq = 0; - /** - * freq in Hz. 0=lame choses. -1=no filter - */ - this.highpassfreq = 0; - /** - * freq width of filter, in Hz (default=15%) - */ - this.lowpasswidth = 0; - /** - * freq width of filter, in Hz (default=15%) - */ - this.highpasswidth = 0; - - /* - * psycho acoustics and other arguments which you should not change unless - * you know what you are doing - */ - - this.maskingadjust = 0.; - this.maskingadjust_short = 0.; - /** - * only use ATH - */ - this.ATHonly = false; - /** - * only use ATH for short blocks - */ - this.ATHshort = false; - /** - * disable ATH - */ - this.noATH = false; - /** - * select ATH formula - */ - this.ATHtype = 0; - /** - * change ATH formula 4 shape - */ - this.ATHcurve = 0.; - /** - * lower ATH by this many db - */ - this.ATHlower = 0.; - /** - * select ATH auto-adjust scheme - */ - this.athaa_type = 0; - /** - * select ATH auto-adjust loudness calc - */ - this.athaa_loudapprox = 0; - /** - * dB, tune active region of auto-level - */ - this.athaa_sensitivity = 0.; - this.short_blocks = null; - /** - * use temporal masking effect - */ - this.useTemporal = false; - this.interChRatio = 0.; - /** - * Naoki's adjustment of Mid/Side maskings - */ - this.msfix = 0.; - - /** - * 0 off, 1 on - */ - this.tune = false; - /** - * used to pass values for debugging and stuff - */ - this.tune_value_a = 0.; - - /************************************************************************/ - /* internal variables, do not set... */ - /* provided because they may be of use to calling application */ - /************************************************************************/ - - /** - * 0=MPEG-2/2.5 1=MPEG-1 - */ - this.version = 0; - this.encoder_delay = 0; - /** - * number of samples of padding appended to input - */ - this.encoder_padding = 0; - this.framesize = 0; - /** - * number of frames encoded - */ - this.frameNum = 0; - /** - * is this struct owned by calling program or lame? - */ - this.lame_allocated_gfp = 0; - /**************************************************************************/ - /* more internal variables are stored in this structure: */ - /**************************************************************************/ - this.internal_flags = null; -} - -module.exports = LameGlobalFlags; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/LameInternalFlags.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/LameInternalFlags.js deleted file mode 100644 index c4311e9f6..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/LameInternalFlags.js +++ /dev/null @@ -1,390 +0,0 @@ -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -var IIISideInfo = require('./IIISideInfo.js'); -var ScaleFac = require('./ScaleFac.js'); -var NsPsy = require('./NsPsy.js'); -var VBRSeekInfo = require('./VBRSeekInfo.js'); -var III_psy_xmin = require('./III_psy_xmin.js'); -var Encoder = require('./Encoder.js'); -var L3Side = require('./L3Side.js'); - - -LameInternalFlags.MFSIZE = (3 * 1152 + Encoder.ENCDELAY - Encoder.MDCTDELAY); -LameInternalFlags.MAX_HEADER_BUF = 256; -LameInternalFlags.MAX_BITS_PER_CHANNEL = 4095; -LameInternalFlags.MAX_BITS_PER_GRANULE = 7680; -LameInternalFlags.BPC = 320; - -function LameInternalFlags() { - var MAX_HEADER_LEN = 40; - - - /******************************************************************** - * internal variables NOT set by calling program, and should not be * - * modified by the calling program * - ********************************************************************/ - - /** - * Some remarks to the Class_ID field: The Class ID is an Identifier for a - * pointer to this struct. It is very unlikely that a pointer to - * lame_global_flags has the same 32 bits in it's structure (large and other - * special properties, for instance prime). - * - * To test that the structure is right and initialized, use: if ( gfc . - * Class_ID == LAME_ID ) ... Other remark: If you set a flag to 0 for uninit - * data and 1 for init data, the right test should be "if (flag == 1)" and - * NOT "if (flag)". Unintended modification of this element will be - * otherwise misinterpreted as an init. - */ - this.Class_ID = 0; - - this.lame_encode_frame_init = 0; - this.iteration_init_init = 0; - this.fill_buffer_resample_init = 0; - - //public float mfbuf[][] = new float[2][MFSIZE]; - this.mfbuf = new_float_n([2, LameInternalFlags.MFSIZE]); - - /** - * granules per frame - */ - this.mode_gr = 0; - /** - * number of channels in the input data stream (PCM or decoded PCM) - */ - this.channels_in = 0; - /** - * number of channels in the output data stream (not used for decoding) - */ - this.channels_out = 0; - /** - * input_samp_rate/output_samp_rate - */ - //public double resample_ratio; - this.resample_ratio = 0.; - - this.mf_samples_to_encode = 0; - this.mf_size = 0; - /** - * min bitrate index - */ - this.VBR_min_bitrate = 0; - /** - * max bitrate index - */ - this.VBR_max_bitrate = 0; - this.bitrate_index = 0; - this.samplerate_index = 0; - this.mode_ext = 0; - - /* lowpass and highpass filter control */ - /** - * normalized frequency bounds of passband - */ - this.lowpass1 = 0.; - this.lowpass2 = 0.; - /** - * normalized frequency bounds of passband - */ - this.highpass1 = 0.; - this.highpass2 = 0.; - - /** - * 0 = none 1 = ISO AAC model 2 = allow scalefac_select=1 - */ - this.noise_shaping = 0; - - /** - * 0 = ISO model: amplify all distorted bands
- * 1 = amplify within 50% of max (on db scale)
- * 2 = amplify only most distorted band
- * 3 = method 1 and refine with method 2
- */ - this.noise_shaping_amp = 0; - /** - * 0 = no substep
- * 1 = use substep shaping at last step(VBR only)
- * (not implemented yet)
- * 2 = use substep inside loop
- * 3 = use substep inside loop and last step
- */ - this.substep_shaping = 0; - - /** - * 1 = gpsycho. 0 = none - */ - this.psymodel = 0; - /** - * 0 = stop at over=0, all scalefacs amplified or
- * a scalefac has reached max value
- * 1 = stop when all scalefacs amplified or a scalefac has reached max value
- * 2 = stop when all scalefacs amplified - */ - this.noise_shaping_stop = 0; - - /** - * 0 = no, 1 = yes - */ - this.subblock_gain = 0; - /** - * 0 = no. 1=outside loop 2=inside loop(slow) - */ - this.use_best_huffman = 0; - - /** - * 0 = stop early after 0 distortion found. 1 = full search - */ - this.full_outer_loop = 0; - - //public IIISideInfo l3_side = new IIISideInfo(); - this.l3_side = new IIISideInfo(); - this.ms_ratio = new_float(2); - - /* used for padding */ - /** - * padding for the current frame? - */ - this.padding = 0; - this.frac_SpF = 0; - this.slot_lag = 0; - - /** - * optional ID3 tags - */ - //public ID3TagSpec tag_spec; - this.tag_spec = null; - this.nMusicCRC = 0; - - /* variables used by Quantize */ - //public int OldValue[] = new int[2]; - this.OldValue = new_int(2); - //public int CurrentStep[] = new int[2]; - this.CurrentStep = new_int(2); - - this.masking_lower = 0.; - //public int bv_scf[] = new int[576]; - this.bv_scf = new_int(576); - //public int pseudohalf[] = new int[L3Side.SFBMAX]; - this.pseudohalf = new_int(L3Side.SFBMAX); - - /** - * will be set in lame_init_params - */ - this.sfb21_extra = false; - - /* BPC = maximum number of filter convolution windows to precompute */ - //public float[][] inbuf_old = new float[2][]; - this.inbuf_old = new Array(2); - //public float[][] blackfilt = new float[2 * BPC + 1][]; - this.blackfilt = new Array(2 * LameInternalFlags.BPC + 1); - //public double itime[] = new double[2]; - this.itime = new_double(2); - this.sideinfo_len = 0; - - /* variables for newmdct.c */ - //public float sb_sample[][][][] = new float[2][2][18][Encoder.SBLIMIT]; - this.sb_sample = new_float_n([2, 2, 18, Encoder.SBLIMIT]); - this.amp_filter = new_float(32); - - /* variables for BitStream */ - - /** - *

-     * mpeg1: buffer=511 bytes  smallest frame: 96-38(sideinfo)=58
-     * max number of frames in reservoir:  8
-     * mpeg2: buffer=255 bytes.  smallest frame: 24-23bytes=1
-     * with VBR, if you are encoding all silence, it is possible to
-     * have 8kbs/24khz frames with 1byte of data each, which means we need
-     * to buffer up to 255 headers!
-     * 
- */ - /** - * also, max_header_buf has to be a power of two - */ - /** - * max size of header is 38 - */ - - function Header() { - this.write_timing = 0; - this.ptr = 0; - //public byte buf[] = new byte[MAX_HEADER_LEN]; - this.buf = new_byte(MAX_HEADER_LEN); - } - - this.header = new Array(LameInternalFlags.MAX_HEADER_BUF); - - this.h_ptr = 0; - this.w_ptr = 0; - this.ancillary_flag = 0; - - /* variables for Reservoir */ - /** - * in bits - */ - this.ResvSize = 0; - /** - * in bits - */ - this.ResvMax = 0; - - //public ScaleFac scalefac_band = new ScaleFac(); - this.scalefac_band = new ScaleFac(); - - /* daa from PsyModel */ - /* The static variables "r", "phi_sav", "new", "old" and "oldest" have */ - /* to be remembered for the unpredictability measure. For "r" and */ - /* "phi_sav", the first index from the left is the channel select and */ - /* the second index is the "age" of the data. */ - this.minval_l = new_float(Encoder.CBANDS); - this.minval_s = new_float(Encoder.CBANDS); - this.nb_1 = new_float_n([4, Encoder.CBANDS]); - this.nb_2 = new_float_n([4, Encoder.CBANDS]); - this.nb_s1 = new_float_n([4, Encoder.CBANDS]); - this.nb_s2 = new_float_n([4, Encoder.CBANDS]); - this.s3_ss = null; - this.s3_ll = null; - this.decay = 0.; - - //public III_psy_xmin[] thm = new III_psy_xmin[4]; - //public III_psy_xmin[] en = new III_psy_xmin[4]; - this.thm = new Array(4); - this.en = new Array(4); - - /** - * fft and energy calculation - */ - this.tot_ener = new_float(4); - - /* loudness calculation (for adaptive threshold of hearing) */ - /** - * loudness^2 approx. per granule and channel - */ - this.loudness_sq = new_float_n([2, 2]); - /** - * account for granule delay of L3psycho_anal - */ - this.loudness_sq_save = new_float(2); - - /** - * Scale Factor Bands - */ - this.mld_l = new_float(Encoder.SBMAX_l); - this.mld_s = new_float(Encoder.SBMAX_s); - this.bm_l = new_int(Encoder.SBMAX_l); - this.bo_l = new_int(Encoder.SBMAX_l); - this.bm_s = new_int(Encoder.SBMAX_s); - this.bo_s = new_int(Encoder.SBMAX_s); - this.npart_l = 0; - this.npart_s = 0; - - this.s3ind = new_int_n([Encoder.CBANDS, 2]); - this.s3ind_s = new_int_n([Encoder.CBANDS, 2]); - - this.numlines_s = new_int(Encoder.CBANDS); - this.numlines_l = new_int(Encoder.CBANDS); - this.rnumlines_l = new_float(Encoder.CBANDS); - this.mld_cb_l = new_float(Encoder.CBANDS); - this.mld_cb_s = new_float(Encoder.CBANDS); - this.numlines_s_num1 = 0; - this.numlines_l_num1 = 0; - - /* ratios */ - this.pe = new_float(4); - this.ms_ratio_s_old = 0.; - this.ms_ratio_l_old = 0.; - this.ms_ener_ratio_old = 0.; - - /** - * block type - */ - this.blocktype_old = new_int(2); - - /** - * variables used for --nspsytune - */ - this.nsPsy = new NsPsy(); - - /** - * used for Xing VBR header - */ - this.VBR_seek_table = new VBRSeekInfo(); - - /** - * all ATH related stuff - */ - //public ATH ATH; - this.ATH = null; - - this.PSY = null; - - this.nogap_total = 0; - this.nogap_current = 0; - - /* ReplayGain */ - this.decode_on_the_fly = true; - this.findReplayGain = true; - this.findPeakSample = true; - this.PeakSample = 0.; - this.RadioGain = 0; - this.AudiophileGain = 0; - //public ReplayGain rgdata; - this.rgdata = null; - - /** - * gain change required for preventing clipping - */ - this.noclipGainChange = 0; - /** - * user-specified scale factor required for preventing clipping - */ - this.noclipScale = 0.; - - /* simple statistics */ - this.bitrate_stereoMode_Hist = new_int_n([16, 4 + 1]); - /** - * norm/start/short/stop/mixed(short)/sum - */ - this.bitrate_blockType_Hist = new_int_n([16, 4 + 1 + 1]); - - //public PlottingData pinfo; - //public MPGLib.mpstr_tag hip; - this.pinfo = null; - this.hip = null; - - this.in_buffer_nsamples = 0; - //public float[] in_buffer_0; - //public float[] in_buffer_1; - this.in_buffer_0 = null; - this.in_buffer_1 = null; - - //public IIterationLoop iteration_loop; - this.iteration_loop = null; - - for (var i = 0; i < this.en.length; i++) { - this.en[i] = new III_psy_xmin(); - } - for (var i = 0; i < this.thm.length; i++) { - this.thm[i] = new III_psy_xmin(); - } - for (var i = 0; i < this.header.length; i++) { - this.header[i] = new Header(); - } - -} - -module.exports = LameInternalFlags; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/MPEGMode.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/MPEGMode.js deleted file mode 100644 index c46163771..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/MPEGMode.js +++ /dev/null @@ -1,17 +0,0 @@ -//package mp3; - -/* MPEG modes */ -function MPEGMode(ordinal) { - var _ordinal = ordinal; - this.ordinal = function () { - return _ordinal; - } -} - -MPEGMode.STEREO = new MPEGMode(0); -MPEGMode.JOINT_STEREO = new MPEGMode(1); -MPEGMode.DUAL_CHANNEL = new MPEGMode(2); -MPEGMode.MONO = new MPEGMode(3); -MPEGMode.NOT_SET = new MPEGMode(4); - -module.exports = MPEGMode; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/MeanBits.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/MeanBits.js deleted file mode 100644 index 1294fd74e..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/MeanBits.js +++ /dev/null @@ -1,5 +0,0 @@ -function MeanBits(meanBits) { - this.bits = meanBits; -} - -module.exports = MeanBits; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/NewMDCT.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/NewMDCT.js deleted file mode 100644 index c8223706c..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/NewMDCT.js +++ /dev/null @@ -1,1164 +0,0 @@ -/* - * MP3 window subband -> subband filtering -> mdct routine - * - * Copyright (c) 1999-2000 Takehiro Tominaga - * - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -/* - * Special Thanks to Patrick De Smet for your advices. - */ - -/* $Id: NewMDCT.java,v 1.11 2011/05/24 20:48:06 kenchis Exp $ */ - -//package mp3; - -//import java.util.Arrays; -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -var Encoder = require('./Encoder.js'); - - -function NewMDCT() { - - var enwindow = [ - -4.77e-07 * 0.740951125354959 / 2.384e-06, - 1.03951e-04 * 0.740951125354959 / 2.384e-06, - 9.53674e-04 * 0.740951125354959 / 2.384e-06, - 2.841473e-03 * 0.740951125354959 / 2.384e-06, - 3.5758972e-02 * 0.740951125354959 / 2.384e-06, - 3.401756e-03 * 0.740951125354959 / 2.384e-06, - 9.83715e-04 * 0.740951125354959 / 2.384e-06, - 9.9182e-05 * 0.740951125354959 / 2.384e-06, /* 15 */ - 1.2398e-05 * 0.740951125354959 / 2.384e-06, - 1.91212e-04 * 0.740951125354959 / 2.384e-06, - 2.283096e-03 * 0.740951125354959 / 2.384e-06, - 1.6994476e-02 * 0.740951125354959 / 2.384e-06, - -1.8756866e-02 * 0.740951125354959 / 2.384e-06, - -2.630711e-03 * 0.740951125354959 / 2.384e-06, - -2.47478e-04 * 0.740951125354959 / 2.384e-06, - -1.4782e-05 * 0.740951125354959 / 2.384e-06, - 9.063471690191471e-01, 1.960342806591213e-01, - - -4.77e-07 * 0.773010453362737 / 2.384e-06, - 1.05858e-04 * 0.773010453362737 / 2.384e-06, - 9.30786e-04 * 0.773010453362737 / 2.384e-06, - 2.521515e-03 * 0.773010453362737 / 2.384e-06, - 3.5694122e-02 * 0.773010453362737 / 2.384e-06, - 3.643036e-03 * 0.773010453362737 / 2.384e-06, - 9.91821e-04 * 0.773010453362737 / 2.384e-06, - 9.6321e-05 * 0.773010453362737 / 2.384e-06, /* 14 */ - 1.1444e-05 * 0.773010453362737 / 2.384e-06, - 1.65462e-04 * 0.773010453362737 / 2.384e-06, - 2.110004e-03 * 0.773010453362737 / 2.384e-06, - 1.6112804e-02 * 0.773010453362737 / 2.384e-06, - -1.9634247e-02 * 0.773010453362737 / 2.384e-06, - -2.803326e-03 * 0.773010453362737 / 2.384e-06, - -2.77042e-04 * 0.773010453362737 / 2.384e-06, - -1.6689e-05 * 0.773010453362737 / 2.384e-06, - 8.206787908286602e-01, 3.901806440322567e-01, - - -4.77e-07 * 0.803207531480645 / 2.384e-06, - 1.07288e-04 * 0.803207531480645 / 2.384e-06, - 9.02653e-04 * 0.803207531480645 / 2.384e-06, - 2.174854e-03 * 0.803207531480645 / 2.384e-06, - 3.5586357e-02 * 0.803207531480645 / 2.384e-06, - 3.858566e-03 * 0.803207531480645 / 2.384e-06, - 9.95159e-04 * 0.803207531480645 / 2.384e-06, - 9.3460e-05 * 0.803207531480645 / 2.384e-06, /* 13 */ - 1.0014e-05 * 0.803207531480645 / 2.384e-06, - 1.40190e-04 * 0.803207531480645 / 2.384e-06, - 1.937389e-03 * 0.803207531480645 / 2.384e-06, - 1.5233517e-02 * 0.803207531480645 / 2.384e-06, - -2.0506859e-02 * 0.803207531480645 / 2.384e-06, - -2.974033e-03 * 0.803207531480645 / 2.384e-06, - -3.07560e-04 * 0.803207531480645 / 2.384e-06, - -1.8120e-05 * 0.803207531480645 / 2.384e-06, - 7.416505462720353e-01, 5.805693545089249e-01, - - -4.77e-07 * 0.831469612302545 / 2.384e-06, - 1.08242e-04 * 0.831469612302545 / 2.384e-06, - 8.68797e-04 * 0.831469612302545 / 2.384e-06, - 1.800537e-03 * 0.831469612302545 / 2.384e-06, - 3.5435200e-02 * 0.831469612302545 / 2.384e-06, - 4.049301e-03 * 0.831469612302545 / 2.384e-06, - 9.94205e-04 * 0.831469612302545 / 2.384e-06, - 9.0599e-05 * 0.831469612302545 / 2.384e-06, /* 12 */ - 9.060e-06 * 0.831469612302545 / 2.384e-06, - 1.16348e-04 * 0.831469612302545 / 2.384e-06, - 1.766682e-03 * 0.831469612302545 / 2.384e-06, - 1.4358521e-02 * 0.831469612302545 / 2.384e-06, - -2.1372318e-02 * 0.831469612302545 / 2.384e-06, - -3.14188e-03 * 0.831469612302545 / 2.384e-06, - -3.39031e-04 * 0.831469612302545 / 2.384e-06, - -1.9550e-05 * 0.831469612302545 / 2.384e-06, - 6.681786379192989e-01, 7.653668647301797e-01, - - -4.77e-07 * 0.857728610000272 / 2.384e-06, - 1.08719e-04 * 0.857728610000272 / 2.384e-06, - 8.29220e-04 * 0.857728610000272 / 2.384e-06, - 1.399517e-03 * 0.857728610000272 / 2.384e-06, - 3.5242081e-02 * 0.857728610000272 / 2.384e-06, - 4.215240e-03 * 0.857728610000272 / 2.384e-06, - 9.89437e-04 * 0.857728610000272 / 2.384e-06, - 8.7261e-05 * 0.857728610000272 / 2.384e-06, /* 11 */ - 8.106e-06 * 0.857728610000272 / 2.384e-06, - 9.3937e-05 * 0.857728610000272 / 2.384e-06, - 1.597881e-03 * 0.857728610000272 / 2.384e-06, - 1.3489246e-02 * 0.857728610000272 / 2.384e-06, - -2.2228718e-02 * 0.857728610000272 / 2.384e-06, - -3.306866e-03 * 0.857728610000272 / 2.384e-06, - -3.71456e-04 * 0.857728610000272 / 2.384e-06, - -2.1458e-05 * 0.857728610000272 / 2.384e-06, - 5.993769336819237e-01, 9.427934736519954e-01, - - -4.77e-07 * 0.881921264348355 / 2.384e-06, - 1.08719e-04 * 0.881921264348355 / 2.384e-06, - 7.8392e-04 * 0.881921264348355 / 2.384e-06, - 9.71317e-04 * 0.881921264348355 / 2.384e-06, - 3.5007000e-02 * 0.881921264348355 / 2.384e-06, - 4.357815e-03 * 0.881921264348355 / 2.384e-06, - 9.80854e-04 * 0.881921264348355 / 2.384e-06, - 8.3923e-05 * 0.881921264348355 / 2.384e-06, /* 10 */ - 7.629e-06 * 0.881921264348355 / 2.384e-06, - 7.2956e-05 * 0.881921264348355 / 2.384e-06, - 1.432419e-03 * 0.881921264348355 / 2.384e-06, - 1.2627602e-02 * 0.881921264348355 / 2.384e-06, - -2.3074150e-02 * 0.881921264348355 / 2.384e-06, - -3.467083e-03 * 0.881921264348355 / 2.384e-06, - -4.04358e-04 * 0.881921264348355 / 2.384e-06, - -2.3365e-05 * 0.881921264348355 / 2.384e-06, - 5.345111359507916e-01, 1.111140466039205e+00, - - -9.54e-07 * 0.903989293123443 / 2.384e-06, - 1.08242e-04 * 0.903989293123443 / 2.384e-06, - 7.31945e-04 * 0.903989293123443 / 2.384e-06, - 5.15938e-04 * 0.903989293123443 / 2.384e-06, - 3.4730434e-02 * 0.903989293123443 / 2.384e-06, - 4.477024e-03 * 0.903989293123443 / 2.384e-06, - 9.68933e-04 * 0.903989293123443 / 2.384e-06, - 8.0585e-05 * 0.903989293123443 / 2.384e-06, /* 9 */ - 6.676e-06 * 0.903989293123443 / 2.384e-06, - 5.2929e-05 * 0.903989293123443 / 2.384e-06, - 1.269817e-03 * 0.903989293123443 / 2.384e-06, - 1.1775017e-02 * 0.903989293123443 / 2.384e-06, - -2.3907185e-02 * 0.903989293123443 / 2.384e-06, - -3.622532e-03 * 0.903989293123443 / 2.384e-06, - -4.38213e-04 * 0.903989293123443 / 2.384e-06, - -2.5272e-05 * 0.903989293123443 / 2.384e-06, - 4.729647758913199e-01, 1.268786568327291e+00, - - -9.54e-07 * 0.92387953251128675613 / 2.384e-06, - 1.06812e-04 * 0.92387953251128675613 / 2.384e-06, - 6.74248e-04 * 0.92387953251128675613 / 2.384e-06, - 3.3379e-05 * 0.92387953251128675613 / 2.384e-06, - 3.4412861e-02 * 0.92387953251128675613 / 2.384e-06, - 4.573822e-03 * 0.92387953251128675613 / 2.384e-06, - 9.54151e-04 * 0.92387953251128675613 / 2.384e-06, - 7.6771e-05 * 0.92387953251128675613 / 2.384e-06, - 6.199e-06 * 0.92387953251128675613 / 2.384e-06, - 3.4332e-05 * 0.92387953251128675613 / 2.384e-06, - 1.111031e-03 * 0.92387953251128675613 / 2.384e-06, - 1.0933399e-02 * 0.92387953251128675613 / 2.384e-06, - -2.4725437e-02 * 0.92387953251128675613 / 2.384e-06, - -3.771782e-03 * 0.92387953251128675613 / 2.384e-06, - -4.72546e-04 * 0.92387953251128675613 / 2.384e-06, - -2.7657e-05 * 0.92387953251128675613 / 2.384e-06, - 4.1421356237309504879e-01, /* tan(PI/8) */ - 1.414213562373095e+00, - - -9.54e-07 * 0.941544065183021 / 2.384e-06, - 1.05381e-04 * 0.941544065183021 / 2.384e-06, - 6.10352e-04 * 0.941544065183021 / 2.384e-06, - -4.75883e-04 * 0.941544065183021 / 2.384e-06, - 3.4055710e-02 * 0.941544065183021 / 2.384e-06, - 4.649162e-03 * 0.941544065183021 / 2.384e-06, - 9.35555e-04 * 0.941544065183021 / 2.384e-06, - 7.3433e-05 * 0.941544065183021 / 2.384e-06, /* 7 */ - 5.245e-06 * 0.941544065183021 / 2.384e-06, - 1.7166e-05 * 0.941544065183021 / 2.384e-06, - 9.56535e-04 * 0.941544065183021 / 2.384e-06, - 1.0103703e-02 * 0.941544065183021 / 2.384e-06, - -2.5527000e-02 * 0.941544065183021 / 2.384e-06, - -3.914356e-03 * 0.941544065183021 / 2.384e-06, - -5.07355e-04 * 0.941544065183021 / 2.384e-06, - -3.0041e-05 * 0.941544065183021 / 2.384e-06, - 3.578057213145241e-01, 1.546020906725474e+00, - - -9.54e-07 * 0.956940335732209 / 2.384e-06, - 1.02520e-04 * 0.956940335732209 / 2.384e-06, - 5.39303e-04 * 0.956940335732209 / 2.384e-06, - -1.011848e-03 * 0.956940335732209 / 2.384e-06, - 3.3659935e-02 * 0.956940335732209 / 2.384e-06, - 4.703045e-03 * 0.956940335732209 / 2.384e-06, - 9.15051e-04 * 0.956940335732209 / 2.384e-06, - 7.0095e-05 * 0.956940335732209 / 2.384e-06, /* 6 */ - 4.768e-06 * 0.956940335732209 / 2.384e-06, - 9.54e-07 * 0.956940335732209 / 2.384e-06, - 8.06808e-04 * 0.956940335732209 / 2.384e-06, - 9.287834e-03 * 0.956940335732209 / 2.384e-06, - -2.6310921e-02 * 0.956940335732209 / 2.384e-06, - -4.048824e-03 * 0.956940335732209 / 2.384e-06, - -5.42164e-04 * 0.956940335732209 / 2.384e-06, - -3.2425e-05 * 0.956940335732209 / 2.384e-06, - 3.033466836073424e-01, 1.662939224605090e+00, - - -1.431e-06 * 0.970031253194544 / 2.384e-06, - 9.9182e-05 * 0.970031253194544 / 2.384e-06, - 4.62532e-04 * 0.970031253194544 / 2.384e-06, - -1.573563e-03 * 0.970031253194544 / 2.384e-06, - 3.3225536e-02 * 0.970031253194544 / 2.384e-06, - 4.737377e-03 * 0.970031253194544 / 2.384e-06, - 8.91685e-04 * 0.970031253194544 / 2.384e-06, - 6.6280e-05 * 0.970031253194544 / 2.384e-06, /* 5 */ - 4.292e-06 * 0.970031253194544 / 2.384e-06, - -1.3828e-05 * 0.970031253194544 / 2.384e-06, - 6.61850e-04 * 0.970031253194544 / 2.384e-06, - 8.487225e-03 * 0.970031253194544 / 2.384e-06, - -2.7073860e-02 * 0.970031253194544 / 2.384e-06, - -4.174709e-03 * 0.970031253194544 / 2.384e-06, - -5.76973e-04 * 0.970031253194544 / 2.384e-06, - -3.4809e-05 * 0.970031253194544 / 2.384e-06, - 2.504869601913055e-01, 1.763842528696710e+00, - - -1.431e-06 * 0.98078528040323 / 2.384e-06, - 9.5367e-05 * 0.98078528040323 / 2.384e-06, - 3.78609e-04 * 0.98078528040323 / 2.384e-06, - -2.161503e-03 * 0.98078528040323 / 2.384e-06, - 3.2754898e-02 * 0.98078528040323 / 2.384e-06, - 4.752159e-03 * 0.98078528040323 / 2.384e-06, - 8.66413e-04 * 0.98078528040323 / 2.384e-06, - 6.2943e-05 * 0.98078528040323 / 2.384e-06, /* 4 */ - 3.815e-06 * 0.98078528040323 / 2.384e-06, - -2.718e-05 * 0.98078528040323 / 2.384e-06, - 5.22137e-04 * 0.98078528040323 / 2.384e-06, - 7.703304e-03 * 0.98078528040323 / 2.384e-06, - -2.7815342e-02 * 0.98078528040323 / 2.384e-06, - -4.290581e-03 * 0.98078528040323 / 2.384e-06, - -6.11782e-04 * 0.98078528040323 / 2.384e-06, - -3.7670e-05 * 0.98078528040323 / 2.384e-06, - 1.989123673796580e-01, 1.847759065022573e+00, - - -1.907e-06 * 0.989176509964781 / 2.384e-06, - 9.0122e-05 * 0.989176509964781 / 2.384e-06, - 2.88486e-04 * 0.989176509964781 / 2.384e-06, - -2.774239e-03 * 0.989176509964781 / 2.384e-06, - 3.2248020e-02 * 0.989176509964781 / 2.384e-06, - 4.748821e-03 * 0.989176509964781 / 2.384e-06, - 8.38757e-04 * 0.989176509964781 / 2.384e-06, - 5.9605e-05 * 0.989176509964781 / 2.384e-06, /* 3 */ - 3.338e-06 * 0.989176509964781 / 2.384e-06, - -3.9577e-05 * 0.989176509964781 / 2.384e-06, - 3.88145e-04 * 0.989176509964781 / 2.384e-06, - 6.937027e-03 * 0.989176509964781 / 2.384e-06, - -2.8532982e-02 * 0.989176509964781 / 2.384e-06, - -4.395962e-03 * 0.989176509964781 / 2.384e-06, - -6.46591e-04 * 0.989176509964781 / 2.384e-06, - -4.0531e-05 * 0.989176509964781 / 2.384e-06, - 1.483359875383474e-01, 1.913880671464418e+00, - - -1.907e-06 * 0.995184726672197 / 2.384e-06, - 8.4400e-05 * 0.995184726672197 / 2.384e-06, - 1.91689e-04 * 0.995184726672197 / 2.384e-06, - -3.411293e-03 * 0.995184726672197 / 2.384e-06, - 3.1706810e-02 * 0.995184726672197 / 2.384e-06, - 4.728317e-03 * 0.995184726672197 / 2.384e-06, - 8.09669e-04 * 0.995184726672197 / 2.384e-06, - 5.579e-05 * 0.995184726672197 / 2.384e-06, - 3.338e-06 * 0.995184726672197 / 2.384e-06, - -5.0545e-05 * 0.995184726672197 / 2.384e-06, - 2.59876e-04 * 0.995184726672197 / 2.384e-06, - 6.189346e-03 * 0.995184726672197 / 2.384e-06, - -2.9224873e-02 * 0.995184726672197 / 2.384e-06, - -4.489899e-03 * 0.995184726672197 / 2.384e-06, - -6.80923e-04 * 0.995184726672197 / 2.384e-06, - -4.3392e-05 * 0.995184726672197 / 2.384e-06, - 9.849140335716425e-02, 1.961570560806461e+00, - - -2.384e-06 * 0.998795456205172 / 2.384e-06, - 7.7724e-05 * 0.998795456205172 / 2.384e-06, - 8.8215e-05 * 0.998795456205172 / 2.384e-06, - -4.072189e-03 * 0.998795456205172 / 2.384e-06, - 3.1132698e-02 * 0.998795456205172 / 2.384e-06, - 4.691124e-03 * 0.998795456205172 / 2.384e-06, - 7.79152e-04 * 0.998795456205172 / 2.384e-06, - 5.2929e-05 * 0.998795456205172 / 2.384e-06, - 2.861e-06 * 0.998795456205172 / 2.384e-06, - -6.0558e-05 * 0.998795456205172 / 2.384e-06, - 1.37329e-04 * 0.998795456205172 / 2.384e-06, - 5.462170e-03 * 0.998795456205172 / 2.384e-06, - -2.9890060e-02 * 0.998795456205172 / 2.384e-06, - -4.570484e-03 * 0.998795456205172 / 2.384e-06, - -7.14302e-04 * 0.998795456205172 / 2.384e-06, - -4.6253e-05 * 0.998795456205172 / 2.384e-06, - 4.912684976946725e-02, 1.990369453344394e+00, - - 3.5780907e-02 * Util.SQRT2 * 0.5 / 2.384e-06, - 1.7876148e-02 * Util.SQRT2 * 0.5 / 2.384e-06, - 3.134727e-03 * Util.SQRT2 * 0.5 / 2.384e-06, - 2.457142e-03 * Util.SQRT2 * 0.5 / 2.384e-06, - 9.71317e-04 * Util.SQRT2 * 0.5 / 2.384e-06, - 2.18868e-04 * Util.SQRT2 * 0.5 / 2.384e-06, - 1.01566e-04 * Util.SQRT2 * 0.5 / 2.384e-06, - 1.3828e-05 * Util.SQRT2 * 0.5 / 2.384e-06, - - 3.0526638e-02 / 2.384e-06, 4.638195e-03 / 2.384e-06, - 7.47204e-04 / 2.384e-06, 4.9591e-05 / 2.384e-06, - 4.756451e-03 / 2.384e-06, 2.1458e-05 / 2.384e-06, - -6.9618e-05 / 2.384e-06, /* 2.384e-06/2.384e-06 */ - ]; - - var NS = 12; - var NL = 36; - - var win = [ - [ - 2.382191739347913e-13, - 6.423305872147834e-13, - 9.400849094049688e-13, - 1.122435026096556e-12, - 1.183840321267481e-12, - 1.122435026096556e-12, - 9.400849094049690e-13, - 6.423305872147839e-13, - 2.382191739347918e-13, - - 5.456116108943412e-12, - 4.878985199565852e-12, - 4.240448995017367e-12, - 3.559909094758252e-12, - 2.858043359288075e-12, - 2.156177623817898e-12, - 1.475637723558783e-12, - 8.371015190102974e-13, - 2.599706096327376e-13, - - -5.456116108943412e-12, - -4.878985199565852e-12, - -4.240448995017367e-12, - -3.559909094758252e-12, - -2.858043359288076e-12, - -2.156177623817898e-12, - -1.475637723558783e-12, - -8.371015190102975e-13, - -2.599706096327376e-13, - - -2.382191739347923e-13, - -6.423305872147843e-13, - -9.400849094049696e-13, - -1.122435026096556e-12, - -1.183840321267481e-12, - -1.122435026096556e-12, - -9.400849094049694e-13, - -6.423305872147840e-13, - -2.382191739347918e-13, - ], - [ - 2.382191739347913e-13, - 6.423305872147834e-13, - 9.400849094049688e-13, - 1.122435026096556e-12, - 1.183840321267481e-12, - 1.122435026096556e-12, - 9.400849094049688e-13, - 6.423305872147841e-13, - 2.382191739347918e-13, - - 5.456116108943413e-12, - 4.878985199565852e-12, - 4.240448995017367e-12, - 3.559909094758253e-12, - 2.858043359288075e-12, - 2.156177623817898e-12, - 1.475637723558782e-12, - 8.371015190102975e-13, - 2.599706096327376e-13, - - -5.461314069809755e-12, - -4.921085770524055e-12, - -4.343405037091838e-12, - -3.732668368707687e-12, - -3.093523840190885e-12, - -2.430835727329465e-12, - -1.734679010007751e-12, - -9.748253656609281e-13, - -2.797435120168326e-13, - - 0.000000000000000e+00, - 0.000000000000000e+00, - 0.000000000000000e+00, - 0.000000000000000e+00, - 0.000000000000000e+00, - 0.000000000000000e+00, - -2.283748241799531e-13, - -4.037858874020686e-13, - -2.146547464825323e-13, - ], - [ - 1.316524975873958e-01, /* win[SHORT_TYPE] */ - 4.142135623730950e-01, - 7.673269879789602e-01, - - 1.091308501069271e+00, /* tantab_l */ - 1.303225372841206e+00, - 1.569685577117490e+00, - 1.920982126971166e+00, - 2.414213562373094e+00, - 3.171594802363212e+00, - 4.510708503662055e+00, - 7.595754112725146e+00, - 2.290376554843115e+01, - - 0.98480775301220802032, /* cx */ - 0.64278760968653936292, - 0.34202014332566882393, - 0.93969262078590842791, - -0.17364817766693030343, - -0.76604444311897790243, - 0.86602540378443870761, - 0.500000000000000e+00, - - -5.144957554275265e-01, /* ca */ - -4.717319685649723e-01, - -3.133774542039019e-01, - -1.819131996109812e-01, - -9.457419252642064e-02, - -4.096558288530405e-02, - -1.419856857247115e-02, - -3.699974673760037e-03, - - 8.574929257125442e-01, /* cs */ - 8.817419973177052e-01, - 9.496286491027329e-01, - 9.833145924917901e-01, - 9.955178160675857e-01, - 9.991605581781475e-01, - 9.998991952444470e-01, - 9.999931550702802e-01, - ], - [ - 0.000000000000000e+00, - 0.000000000000000e+00, - 0.000000000000000e+00, - 0.000000000000000e+00, - 0.000000000000000e+00, - 0.000000000000000e+00, - 2.283748241799531e-13, - 4.037858874020686e-13, - 2.146547464825323e-13, - - 5.461314069809755e-12, - 4.921085770524055e-12, - 4.343405037091838e-12, - 3.732668368707687e-12, - 3.093523840190885e-12, - 2.430835727329466e-12, - 1.734679010007751e-12, - 9.748253656609281e-13, - 2.797435120168326e-13, - - -5.456116108943413e-12, - -4.878985199565852e-12, - -4.240448995017367e-12, - -3.559909094758253e-12, - -2.858043359288075e-12, - -2.156177623817898e-12, - -1.475637723558782e-12, - -8.371015190102975e-13, - -2.599706096327376e-13, - - -2.382191739347913e-13, - -6.423305872147834e-13, - -9.400849094049688e-13, - -1.122435026096556e-12, - -1.183840321267481e-12, - -1.122435026096556e-12, - -9.400849094049688e-13, - -6.423305872147841e-13, - -2.382191739347918e-13, - ] - ]; - - var tantab_l = win[Encoder.SHORT_TYPE]; - var cx = win[Encoder.SHORT_TYPE]; - var ca = win[Encoder.SHORT_TYPE]; - var cs = win[Encoder.SHORT_TYPE]; - - /** - * new IDCT routine written by Takehiro TOMINAGA - * - * PURPOSE: Overlapping window on PCM samples
- * - * SEMANTICS:
- * 32 16-bit pcm samples are scaled to fractional 2's complement and - * concatenated to the end of the window buffer #x#. The updated window - * buffer #x# is then windowed by the analysis window #c# to produce the - * windowed sample #z# - */ - var order = [ - 0, 1, 16, 17, 8, 9, 24, 25, 4, 5, 20, 21, 12, 13, 28, 29, - 2, 3, 18, 19, 10, 11, 26, 27, 6, 7, 22, 23, 14, 15, 30, 31 - ]; - - /** - * returns sum_j=0^31 a[j]*cos(PI*j*(k+1/2)/32), 0<=k<32 - */ - function window_subband(x1, x1Pos, a) { - var wp = 10; - - var x2 = x1Pos + 238 - 14 - 286; - - for (var i = -15; i < 0; i++) { - var w, s, t; - - w = enwindow[wp + -10]; - s = x1[x2 + -224] * w; - t = x1[x1Pos + 224] * w; - w = enwindow[wp + -9]; - s += x1[x2 + -160] * w; - t += x1[x1Pos + 160] * w; - w = enwindow[wp + -8]; - s += x1[x2 + -96] * w; - t += x1[x1Pos + 96] * w; - w = enwindow[wp + -7]; - s += x1[x2 + -32] * w; - t += x1[x1Pos + 32] * w; - w = enwindow[wp + -6]; - s += x1[x2 + 32] * w; - t += x1[x1Pos + -32] * w; - w = enwindow[wp + -5]; - s += x1[x2 + 96] * w; - t += x1[x1Pos + -96] * w; - w = enwindow[wp + -4]; - s += x1[x2 + 160] * w; - t += x1[x1Pos + -160] * w; - w = enwindow[wp + -3]; - s += x1[x2 + 224] * w; - t += x1[x1Pos + -224] * w; - - w = enwindow[wp + -2]; - s += x1[x1Pos + -256] * w; - t -= x1[x2 + 256] * w; - w = enwindow[wp + -1]; - s += x1[x1Pos + -192] * w; - t -= x1[x2 + 192] * w; - w = enwindow[wp + 0]; - s += x1[x1Pos + -128] * w; - t -= x1[x2 + 128] * w; - w = enwindow[wp + 1]; - s += x1[x1Pos + -64] * w; - t -= x1[x2 + 64] * w; - w = enwindow[wp + 2]; - s += x1[x1Pos + 0] * w; - t -= x1[x2 + 0] * w; - w = enwindow[wp + 3]; - s += x1[x1Pos + 64] * w; - t -= x1[x2 + -64] * w; - w = enwindow[wp + 4]; - s += x1[x1Pos + 128] * w; - t -= x1[x2 + -128] * w; - w = enwindow[wp + 5]; - s += x1[x1Pos + 192] * w; - t -= x1[x2 + -192] * w; - - /* - * this multiplyer could be removed, but it needs more 256 FLOAT - * data. thinking about the data cache performance, I think we - * should not use such a huge table. tt 2000/Oct/25 - */ - s *= enwindow[wp + 6]; - w = t - s; - a[30 + i * 2] = t + s; - a[31 + i * 2] = enwindow[wp + 7] * w; - wp += 18; - x1Pos--; - x2++; - } - { - var s, t, u, v; - t = x1[x1Pos + -16] * enwindow[wp + -10]; - s = x1[x1Pos + -32] * enwindow[wp + -2]; - t += (x1[x1Pos + -48] - x1[x1Pos + 16]) * enwindow[wp + -9]; - s += x1[x1Pos + -96] * enwindow[wp + -1]; - t += (x1[x1Pos + -80] + x1[x1Pos + 48]) * enwindow[wp + -8]; - s += x1[x1Pos + -160] * enwindow[wp + 0]; - t += (x1[x1Pos + -112] - x1[x1Pos + 80]) * enwindow[wp + -7]; - s += x1[x1Pos + -224] * enwindow[wp + 1]; - t += (x1[x1Pos + -144] + x1[x1Pos + 112]) * enwindow[wp + -6]; - s -= x1[x1Pos + 32] * enwindow[wp + 2]; - t += (x1[x1Pos + -176] - x1[x1Pos + 144]) * enwindow[wp + -5]; - s -= x1[x1Pos + 96] * enwindow[wp + 3]; - t += (x1[x1Pos + -208] + x1[x1Pos + 176]) * enwindow[wp + -4]; - s -= x1[x1Pos + 160] * enwindow[wp + 4]; - t += (x1[x1Pos + -240] - x1[x1Pos + 208]) * enwindow[wp + -3]; - s -= x1[x1Pos + 224]; - - u = s - t; - v = s + t; - - t = a[14]; - s = a[15] - t; - - a[31] = v + t; /* A0 */ - a[30] = u + s; /* A1 */ - a[15] = u - s; /* A2 */ - a[14] = v - t; /* A3 */ - } - { - var xr; - xr = a[28] - a[0]; - a[0] += a[28]; - a[28] = xr * enwindow[wp + -2 * 18 + 7]; - xr = a[29] - a[1]; - a[1] += a[29]; - a[29] = xr * enwindow[wp + -2 * 18 + 7]; - - xr = a[26] - a[2]; - a[2] += a[26]; - a[26] = xr * enwindow[wp + -4 * 18 + 7]; - xr = a[27] - a[3]; - a[3] += a[27]; - a[27] = xr * enwindow[wp + -4 * 18 + 7]; - - xr = a[24] - a[4]; - a[4] += a[24]; - a[24] = xr * enwindow[wp + -6 * 18 + 7]; - xr = a[25] - a[5]; - a[5] += a[25]; - a[25] = xr * enwindow[wp + -6 * 18 + 7]; - - xr = a[22] - a[6]; - a[6] += a[22]; - a[22] = xr * Util.SQRT2; - xr = a[23] - a[7]; - a[7] += a[23]; - a[23] = xr * Util.SQRT2 - a[7]; - a[7] -= a[6]; - a[22] -= a[7]; - a[23] -= a[22]; - - xr = a[6]; - a[6] = a[31] - xr; - a[31] = a[31] + xr; - xr = a[7]; - a[7] = a[30] - xr; - a[30] = a[30] + xr; - xr = a[22]; - a[22] = a[15] - xr; - a[15] = a[15] + xr; - xr = a[23]; - a[23] = a[14] - xr; - a[14] = a[14] + xr; - - xr = a[20] - a[8]; - a[8] += a[20]; - a[20] = xr * enwindow[wp + -10 * 18 + 7]; - xr = a[21] - a[9]; - a[9] += a[21]; - a[21] = xr * enwindow[wp + -10 * 18 + 7]; - - xr = a[18] - a[10]; - a[10] += a[18]; - a[18] = xr * enwindow[wp + -12 * 18 + 7]; - xr = a[19] - a[11]; - a[11] += a[19]; - a[19] = xr * enwindow[wp + -12 * 18 + 7]; - - xr = a[16] - a[12]; - a[12] += a[16]; - a[16] = xr * enwindow[wp + -14 * 18 + 7]; - xr = a[17] - a[13]; - a[13] += a[17]; - a[17] = xr * enwindow[wp + -14 * 18 + 7]; - - xr = -a[20] + a[24]; - a[20] += a[24]; - a[24] = xr * enwindow[wp + -12 * 18 + 7]; - xr = -a[21] + a[25]; - a[21] += a[25]; - a[25] = xr * enwindow[wp + -12 * 18 + 7]; - - xr = a[4] - a[8]; - a[4] += a[8]; - a[8] = xr * enwindow[wp + -12 * 18 + 7]; - xr = a[5] - a[9]; - a[5] += a[9]; - a[9] = xr * enwindow[wp + -12 * 18 + 7]; - - xr = a[0] - a[12]; - a[0] += a[12]; - a[12] = xr * enwindow[wp + -4 * 18 + 7]; - xr = a[1] - a[13]; - a[1] += a[13]; - a[13] = xr * enwindow[wp + -4 * 18 + 7]; - xr = a[16] - a[28]; - a[16] += a[28]; - a[28] = xr * enwindow[wp + -4 * 18 + 7]; - xr = -a[17] + a[29]; - a[17] += a[29]; - a[29] = xr * enwindow[wp + -4 * 18 + 7]; - - xr = Util.SQRT2 * (a[2] - a[10]); - a[2] += a[10]; - a[10] = xr; - xr = Util.SQRT2 * (a[3] - a[11]); - a[3] += a[11]; - a[11] = xr; - xr = Util.SQRT2 * (-a[18] + a[26]); - a[18] += a[26]; - a[26] = xr - a[18]; - xr = Util.SQRT2 * (-a[19] + a[27]); - a[19] += a[27]; - a[27] = xr - a[19]; - - xr = a[2]; - a[19] -= a[3]; - a[3] -= xr; - a[2] = a[31] - xr; - a[31] += xr; - xr = a[3]; - a[11] -= a[19]; - a[18] -= xr; - a[3] = a[30] - xr; - a[30] += xr; - xr = a[18]; - a[27] -= a[11]; - a[19] -= xr; - a[18] = a[15] - xr; - a[15] += xr; - - xr = a[19]; - a[10] -= xr; - a[19] = a[14] - xr; - a[14] += xr; - xr = a[10]; - a[11] -= xr; - a[10] = a[23] - xr; - a[23] += xr; - xr = a[11]; - a[26] -= xr; - a[11] = a[22] - xr; - a[22] += xr; - xr = a[26]; - a[27] -= xr; - a[26] = a[7] - xr; - a[7] += xr; - - xr = a[27]; - a[27] = a[6] - xr; - a[6] += xr; - - xr = Util.SQRT2 * (a[0] - a[4]); - a[0] += a[4]; - a[4] = xr; - xr = Util.SQRT2 * (a[1] - a[5]); - a[1] += a[5]; - a[5] = xr; - xr = Util.SQRT2 * (a[16] - a[20]); - a[16] += a[20]; - a[20] = xr; - xr = Util.SQRT2 * (a[17] - a[21]); - a[17] += a[21]; - a[21] = xr; - - xr = -Util.SQRT2 * (a[8] - a[12]); - a[8] += a[12]; - a[12] = xr - a[8]; - xr = -Util.SQRT2 * (a[9] - a[13]); - a[9] += a[13]; - a[13] = xr - a[9]; - xr = -Util.SQRT2 * (a[25] - a[29]); - a[25] += a[29]; - a[29] = xr - a[25]; - xr = -Util.SQRT2 * (a[24] + a[28]); - a[24] -= a[28]; - a[28] = xr - a[24]; - - xr = a[24] - a[16]; - a[24] = xr; - xr = a[20] - xr; - a[20] = xr; - xr = a[28] - xr; - a[28] = xr; - - xr = a[25] - a[17]; - a[25] = xr; - xr = a[21] - xr; - a[21] = xr; - xr = a[29] - xr; - a[29] = xr; - - xr = a[17] - a[1]; - a[17] = xr; - xr = a[9] - xr; - a[9] = xr; - xr = a[25] - xr; - a[25] = xr; - xr = a[5] - xr; - a[5] = xr; - xr = a[21] - xr; - a[21] = xr; - xr = a[13] - xr; - a[13] = xr; - xr = a[29] - xr; - a[29] = xr; - - xr = a[1] - a[0]; - a[1] = xr; - xr = a[16] - xr; - a[16] = xr; - xr = a[17] - xr; - a[17] = xr; - xr = a[8] - xr; - a[8] = xr; - xr = a[9] - xr; - a[9] = xr; - xr = a[24] - xr; - a[24] = xr; - xr = a[25] - xr; - a[25] = xr; - xr = a[4] - xr; - a[4] = xr; - xr = a[5] - xr; - a[5] = xr; - xr = a[20] - xr; - a[20] = xr; - xr = a[21] - xr; - a[21] = xr; - xr = a[12] - xr; - a[12] = xr; - xr = a[13] - xr; - a[13] = xr; - xr = a[28] - xr; - a[28] = xr; - xr = a[29] - xr; - a[29] = xr; - - xr = a[0]; - a[0] += a[31]; - a[31] -= xr; - xr = a[1]; - a[1] += a[30]; - a[30] -= xr; - xr = a[16]; - a[16] += a[15]; - a[15] -= xr; - xr = a[17]; - a[17] += a[14]; - a[14] -= xr; - xr = a[8]; - a[8] += a[23]; - a[23] -= xr; - xr = a[9]; - a[9] += a[22]; - a[22] -= xr; - xr = a[24]; - a[24] += a[7]; - a[7] -= xr; - xr = a[25]; - a[25] += a[6]; - a[6] -= xr; - xr = a[4]; - a[4] += a[27]; - a[27] -= xr; - xr = a[5]; - a[5] += a[26]; - a[26] -= xr; - xr = a[20]; - a[20] += a[11]; - a[11] -= xr; - xr = a[21]; - a[21] += a[10]; - a[10] -= xr; - xr = a[12]; - a[12] += a[19]; - a[19] -= xr; - xr = a[13]; - a[13] += a[18]; - a[18] -= xr; - xr = a[28]; - a[28] += a[3]; - a[3] -= xr; - xr = a[29]; - a[29] += a[2]; - a[2] -= xr; - } - } - - /** - * Function: Calculation of the MDCT In the case of long blocks (type 0,1,3) - * there are 36 coefficents in the time domain and 18 in the frequency - * domain.
- * In the case of short blocks (type 2) there are 3 transformations with - * short length. This leads to 12 coefficents in the time and 6 in the - * frequency domain. In this case the results are stored side by side in the - * vector out[]. - * - * New layer3 - */ - function mdct_short(inout, inoutPos) { - for (var l = 0; l < 3; l++) { - var tc0, tc1, tc2, ts0, ts1, ts2; - - ts0 = inout[inoutPos + 2 * 3] * win[Encoder.SHORT_TYPE][0] - - inout[inoutPos + 5 * 3]; - tc0 = inout[inoutPos + 0 * 3] * win[Encoder.SHORT_TYPE][2] - - inout[inoutPos + 3 * 3]; - tc1 = ts0 + tc0; - tc2 = ts0 - tc0; - - ts0 = inout[inoutPos + 5 * 3] * win[Encoder.SHORT_TYPE][0] - + inout[inoutPos + 2 * 3]; - tc0 = inout[inoutPos + 3 * 3] * win[Encoder.SHORT_TYPE][2] - + inout[inoutPos + 0 * 3]; - ts1 = ts0 + tc0; - ts2 = -ts0 + tc0; - - tc0 = (inout[inoutPos + 1 * 3] * win[Encoder.SHORT_TYPE][1] - inout[inoutPos + 4 * 3]) * 2.069978111953089e-11; - /* - * tritab_s [ 1 ] - */ - ts0 = (inout[inoutPos + 4 * 3] * win[Encoder.SHORT_TYPE][1] + inout[inoutPos + 1 * 3]) * 2.069978111953089e-11; - /* - * tritab_s [ 1 ] - */ - inout[inoutPos + 3 * 0] = tc1 * 1.907525191737280e-11 + tc0; - /* - * tritab_s[ 2 ] - */ - inout[inoutPos + 3 * 5] = -ts1 * 1.907525191737280e-11 + ts0; - /* - * tritab_s[0 ] - */ - tc2 = tc2 * 0.86602540378443870761 * 1.907525191737281e-11; - /* - * tritab_s[ 2] - */ - ts1 = ts1 * 0.5 * 1.907525191737281e-11 + ts0; - inout[inoutPos + 3 * 1] = tc2 - ts1; - inout[inoutPos + 3 * 2] = tc2 + ts1; - - tc1 = tc1 * 0.5 * 1.907525191737281e-11 - tc0; - ts2 = ts2 * 0.86602540378443870761 * 1.907525191737281e-11; - /* - * tritab_s[ 0] - */ - inout[inoutPos + 3 * 3] = tc1 + ts2; - inout[inoutPos + 3 * 4] = tc1 - ts2; - - inoutPos++; - } - } - - function mdct_long(out, outPos, _in) { - var ct, st; - { - var tc1, tc2, tc3, tc4, ts5, ts6, ts7, ts8; - /* 1,2, 5,6, 9,10, 13,14, 17 */ - tc1 = _in[17] - _in[9]; - tc3 = _in[15] - _in[11]; - tc4 = _in[14] - _in[12]; - ts5 = _in[0] + _in[8]; - ts6 = _in[1] + _in[7]; - ts7 = _in[2] + _in[6]; - ts8 = _in[3] + _in[5]; - - out[outPos + 17] = (ts5 + ts7 - ts8) - (ts6 - _in[4]); - st = (ts5 + ts7 - ts8) * cx[12 + 7] + (ts6 - _in[4]); - ct = (tc1 - tc3 - tc4) * cx[12 + 6]; - out[outPos + 5] = ct + st; - out[outPos + 6] = ct - st; - - tc2 = (_in[16] - _in[10]) * cx[12 + 6]; - ts6 = ts6 * cx[12 + 7] + _in[4]; - ct = tc1 * cx[12 + 0] + tc2 + tc3 * cx[12 + 1] + tc4 * cx[12 + 2]; - st = -ts5 * cx[12 + 4] + ts6 - ts7 * cx[12 + 5] + ts8 * cx[12 + 3]; - out[outPos + 1] = ct + st; - out[outPos + 2] = ct - st; - - ct = tc1 * cx[12 + 1] - tc2 - tc3 * cx[12 + 2] + tc4 * cx[12 + 0]; - st = -ts5 * cx[12 + 5] + ts6 - ts7 * cx[12 + 3] + ts8 * cx[12 + 4]; - out[outPos + 9] = ct + st; - out[outPos + 10] = ct - st; - - ct = tc1 * cx[12 + 2] - tc2 + tc3 * cx[12 + 0] - tc4 * cx[12 + 1]; - st = ts5 * cx[12 + 3] - ts6 + ts7 * cx[12 + 4] - ts8 * cx[12 + 5]; - out[outPos + 13] = ct + st; - out[outPos + 14] = ct - st; - } - { - var ts1, ts2, ts3, ts4, tc5, tc6, tc7, tc8; - - ts1 = _in[8] - _in[0]; - ts3 = _in[6] - _in[2]; - ts4 = _in[5] - _in[3]; - tc5 = _in[17] + _in[9]; - tc6 = _in[16] + _in[10]; - tc7 = _in[15] + _in[11]; - tc8 = _in[14] + _in[12]; - - out[outPos + 0] = (tc5 + tc7 + tc8) + (tc6 + _in[13]); - ct = (tc5 + tc7 + tc8) * cx[12 + 7] - (tc6 + _in[13]); - st = (ts1 - ts3 + ts4) * cx[12 + 6]; - out[outPos + 11] = ct + st; - out[outPos + 12] = ct - st; - - ts2 = (_in[7] - _in[1]) * cx[12 + 6]; - tc6 = _in[13] - tc6 * cx[12 + 7]; - ct = tc5 * cx[12 + 3] - tc6 + tc7 * cx[12 + 4] + tc8 * cx[12 + 5]; - st = ts1 * cx[12 + 2] + ts2 + ts3 * cx[12 + 0] + ts4 * cx[12 + 1]; - out[outPos + 3] = ct + st; - out[outPos + 4] = ct - st; - - ct = -tc5 * cx[12 + 5] + tc6 - tc7 * cx[12 + 3] - tc8 * cx[12 + 4]; - st = ts1 * cx[12 + 1] + ts2 - ts3 * cx[12 + 2] - ts4 * cx[12 + 0]; - out[outPos + 7] = ct + st; - out[outPos + 8] = ct - st; - - ct = -tc5 * cx[12 + 4] + tc6 - tc7 * cx[12 + 5] - tc8 * cx[12 + 3]; - st = ts1 * cx[12 + 0] - ts2 + ts3 * cx[12 + 1] - ts4 * cx[12 + 2]; - out[outPos + 15] = ct + st; - out[outPos + 16] = ct - st; - } - } - - this.mdct_sub48 = function(gfc, w0, w1) { - var wk = w0; - var wkPos = 286; - /* thinking cache performance, ch->gr loop is better than gr->ch loop */ - for (var ch = 0; ch < gfc.channels_out; ch++) { - for (var gr = 0; gr < gfc.mode_gr; gr++) { - var band; - var gi = (gfc.l3_side.tt[gr][ch]); - var mdct_enc = gi.xr; - var mdct_encPos = 0; - var samp = gfc.sb_sample[ch][1 - gr]; - var sampPos = 0; - - for (var k = 0; k < 18 / 2; k++) { - window_subband(wk, wkPos, samp[sampPos]); - window_subband(wk, wkPos + 32, samp[sampPos + 1]); - sampPos += 2; - wkPos += 64; - /* - * Compensate for inversion in the analysis filter - */ - for (band = 1; band < 32; band += 2) { - samp[sampPos - 1][band] *= -1; - } - } - - /* - * Perform imdct of 18 previous subband samples + 18 current - * subband samples - */ - for (band = 0; band < 32; band++, mdct_encPos += 18) { - var type = gi.block_type; - var band0 = gfc.sb_sample[ch][gr]; - var band1 = gfc.sb_sample[ch][1 - gr]; - if (gi.mixed_block_flag != 0 && band < 2) - type = 0; - if (gfc.amp_filter[band] < 1e-12) { - Arrays.fill(mdct_enc, mdct_encPos + 0, - mdct_encPos + 18, 0); - } else { - if (gfc.amp_filter[band] < 1.0) { - for (var k = 0; k < 18; k++) - band1[k][order[band]] *= gfc.amp_filter[band]; - } - if (type == Encoder.SHORT_TYPE) { - for (var k = -NS / 4; k < 0; k++) { - var w = win[Encoder.SHORT_TYPE][k + 3]; - mdct_enc[mdct_encPos + k * 3 + 9] = band0[9 + k][order[band]] - * w - band0[8 - k][order[band]]; - mdct_enc[mdct_encPos + k * 3 + 18] = band0[14 - k][order[band]] - * w + band0[15 + k][order[band]]; - mdct_enc[mdct_encPos + k * 3 + 10] = band0[15 + k][order[band]] - * w - band0[14 - k][order[band]]; - mdct_enc[mdct_encPos + k * 3 + 19] = band1[2 - k][order[band]] - * w + band1[3 + k][order[band]]; - mdct_enc[mdct_encPos + k * 3 + 11] = band1[3 + k][order[band]] - * w - band1[2 - k][order[band]]; - mdct_enc[mdct_encPos + k * 3 + 20] = band1[8 - k][order[band]] - * w + band1[9 + k][order[band]]; - } - mdct_short(mdct_enc, mdct_encPos); - } else { - var work = new_float(18); - for (var k = -NL / 4; k < 0; k++) { - var a, b; - a = win[type][k + 27] - * band1[k + 9][order[band]] - + win[type][k + 36] - * band1[8 - k][order[band]]; - b = win[type][k + 9] - * band0[k + 9][order[band]] - - win[type][k + 18] - * band0[8 - k][order[band]]; - work[k + 9] = a - b * tantab_l[3 + k + 9]; - work[k + 18] = a * tantab_l[3 + k + 9] + b; - } - - mdct_long(mdct_enc, mdct_encPos, work); - } - } - /* - * Perform aliasing reduction butterfly - */ - if (type != Encoder.SHORT_TYPE && band != 0) { - for (var k = 7; k >= 0; --k) { - var bu, bd; - bu = mdct_enc[mdct_encPos + k] * ca[20 + k] - + mdct_enc[mdct_encPos + -1 - k] - * cs[28 + k]; - bd = mdct_enc[mdct_encPos + k] * cs[28 + k] - - mdct_enc[mdct_encPos + -1 - k] - * ca[20 + k]; - - mdct_enc[mdct_encPos + -1 - k] = bu; - mdct_enc[mdct_encPos + k] = bd; - } - } - } - } - wk = w1; - wkPos = 286; - if (gfc.mode_gr == 1) { - for (var i = 0; i < 18; i++) { - System.arraycopy(gfc.sb_sample[ch][1][i], 0, - gfc.sb_sample[ch][0][i], 0, 32); - } - } - } - } -} - -module.exports = NewMDCT; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/NsPsy.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/NsPsy.js deleted file mode 100644 index b36d74295..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/NsPsy.js +++ /dev/null @@ -1,41 +0,0 @@ -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -var Encoder = require('./Encoder.js'); - -//package mp3; - -/** - * Variables used for --nspsytune - * - * @author Ken - * - */ -function NsPsy() { - this.last_en_subshort = new_float_n([4, 9]); - this.lastAttacks = new_int(4); - this.pefirbuf = new_float(19); - this.longfact = new_float(Encoder.SBMAX_l); - this.shortfact = new_float(Encoder.SBMAX_s); - - /** - * short block tuning - */ - this.attackthre = 0.; - this.attackthre_s = 0.; -} - -module.exports = NsPsy; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Presets.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Presets.js deleted file mode 100644 index dd329a68b..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Presets.js +++ /dev/null @@ -1,488 +0,0 @@ -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -function Presets() { - var Lame = require('./Lame.js'); - function VBRPresets(qual, comp, compS, - y, shThreshold, shThresholdS, - adj, adjShort, lower, - curve, sens, inter, - joint, mod, fix) { - this.vbr_q = qual; - this.quant_comp = comp; - this.quant_comp_s = compS; - this.expY = y; - this.st_lrm = shThreshold; - this.st_s = shThresholdS; - this.masking_adj = adj; - this.masking_adj_short = adjShort; - this.ath_lower = lower; - this.ath_curve = curve; - this.ath_sensitivity = sens; - this.interch = inter; - this.safejoint = joint; - this.sfb21mod = mod; - this.msfix = fix; - } - - function ABRPresets(kbps, comp, compS, - joint, fix, shThreshold, - shThresholdS, bass, sc, - mask, lower, curve, - interCh, sfScale) { - this.quant_comp = comp; - this.quant_comp_s = compS; - this.safejoint = joint; - this.nsmsfix = fix; - this.st_lrm = shThreshold; - this.st_s = shThresholdS; - this.nsbass = bass; - this.scale = sc; - this.masking_adj = mask; - this.ath_lower = lower; - this.ath_curve = curve; - this.interch = interCh; - this.sfscale = sfScale; - } - - var lame; - - this.setModules = function (_lame) { - lame = _lame; - }; - - /** - *
-     * Switch mappings for VBR mode VBR_RH
-     *             vbr_q  qcomp_l  qcomp_s  expY  st_lrm   st_s  mask adj_l  adj_s  ath_lower  ath_curve  ath_sens  interChR  safejoint sfb21mod  msfix
-     * 
- */ - var vbr_old_switch_map = [ - new VBRPresets(0, 9, 9, 0, 5.20, 125.0, -4.2, -6.3, 4.8, 1, 0, 0, 2, 21, 0.97), - new VBRPresets(1, 9, 9, 0, 5.30, 125.0, -3.6, -5.6, 4.5, 1.5, 0, 0, 2, 21, 1.35), - new VBRPresets(2, 9, 9, 0, 5.60, 125.0, -2.2, -3.5, 2.8, 2, 0, 0, 2, 21, 1.49), - new VBRPresets(3, 9, 9, 1, 5.80, 130.0, -1.8, -2.8, 2.6, 3, -4, 0, 2, 20, 1.64), - new VBRPresets(4, 9, 9, 1, 6.00, 135.0, -0.7, -1.1, 1.1, 3.5, -8, 0, 2, 0, 1.79), - new VBRPresets(5, 9, 9, 1, 6.40, 140.0, 0.5, 0.4, -7.5, 4, -12, 0.0002, 0, 0, 1.95), - new VBRPresets(6, 9, 9, 1, 6.60, 145.0, 0.67, 0.65, -14.7, 6.5, -19, 0.0004, 0, 0, 2.30), - new VBRPresets(7, 9, 9, 1, 6.60, 145.0, 0.8, 0.75, -19.7, 8, -22, 0.0006, 0, 0, 2.70), - new VBRPresets(8, 9, 9, 1, 6.60, 145.0, 1.2, 1.15, -27.5, 10, -23, 0.0007, 0, 0, 0), - new VBRPresets(9, 9, 9, 1, 6.60, 145.0, 1.6, 1.6, -36, 11, -25, 0.0008, 0, 0, 0), - new VBRPresets(10, 9, 9, 1, 6.60, 145.0, 2.0, 2.0, -36, 12, -25, 0.0008, 0, 0, 0) - ]; - - /** - *
-     *                 vbr_q  qcomp_l  qcomp_s  expY  st_lrm   st_s  mask adj_l  adj_s  ath_lower  ath_curve  ath_sens  interChR  safejoint sfb21mod  msfix
-     * 
- */ - var vbr_psy_switch_map = [ - new VBRPresets(0, 9, 9, 0, 4.20, 25.0, -7.0, -4.0, 7.5, 1, 0, 0, 2, 26, 0.97), - new VBRPresets(1, 9, 9, 0, 4.20, 25.0, -5.6, -3.6, 4.5, 1.5, 0, 0, 2, 21, 1.35), - new VBRPresets(2, 9, 9, 0, 4.20, 25.0, -4.4, -1.8, 2, 2, 0, 0, 2, 18, 1.49), - new VBRPresets(3, 9, 9, 1, 4.20, 25.0, -3.4, -1.25, 1.1, 3, -4, 0, 2, 15, 1.64), - new VBRPresets(4, 9, 9, 1, 4.20, 25.0, -2.2, 0.1, 0, 3.5, -8, 0, 2, 0, 1.79), - new VBRPresets(5, 9, 9, 1, 4.20, 25.0, -1.0, 1.65, -7.7, 4, -12, 0.0002, 0, 0, 1.95), - new VBRPresets(6, 9, 9, 1, 4.20, 25.0, -0.0, 2.47, -7.7, 6.5, -19, 0.0004, 0, 0, 2), - new VBRPresets(7, 9, 9, 1, 4.20, 25.0, 0.5, 2.0, -14.5, 8, -22, 0.0006, 0, 0, 2), - new VBRPresets(8, 9, 9, 1, 4.20, 25.0, 1.0, 2.4, -22.0, 10, -23, 0.0007, 0, 0, 2), - new VBRPresets(9, 9, 9, 1, 4.20, 25.0, 1.5, 2.95, -30.0, 11, -25, 0.0008, 0, 0, 2), - new VBRPresets(10, 9, 9, 1, 4.20, 25.0, 2.0, 2.95, -36.0, 12, -30, 0.0008, 0, 0, 2) - ]; - - function apply_vbr_preset(gfp, a, enforce) { - var vbr_preset = gfp.VBR == VbrMode.vbr_rh ? vbr_old_switch_map - : vbr_psy_switch_map; - - var x = gfp.VBR_q_frac; - var p = vbr_preset[a]; - var q = vbr_preset[a + 1]; - var set = p; - - // NOOP(vbr_q); - // NOOP(quant_comp); - // NOOP(quant_comp_s); - // NOOP(expY); - p.st_lrm = p.st_lrm + x * (q.st_lrm - p.st_lrm); - // LERP(st_lrm); - p.st_s = p.st_s + x * (q.st_s - p.st_s); - // LERP(st_s); - p.masking_adj = p.masking_adj + x * (q.masking_adj - p.masking_adj); - // LERP(masking_adj); - p.masking_adj_short = p.masking_adj_short + x - * (q.masking_adj_short - p.masking_adj_short); - // LERP(masking_adj_short); - p.ath_lower = p.ath_lower + x * (q.ath_lower - p.ath_lower); - // LERP(ath_lower); - p.ath_curve = p.ath_curve + x * (q.ath_curve - p.ath_curve); - // LERP(ath_curve); - p.ath_sensitivity = p.ath_sensitivity + x - * (q.ath_sensitivity - p.ath_sensitivity); - // LERP(ath_sensitivity); - p.interch = p.interch + x * (q.interch - p.interch); - // LERP(interch); - // NOOP(safejoint); - // NOOP(sfb21mod); - p.msfix = p.msfix + x * (q.msfix - p.msfix); - // LERP(msfix); - - lame_set_VBR_q(gfp, set.vbr_q); - - if (enforce != 0) - gfp.quant_comp = set.quant_comp; - else if (!(Math.abs(gfp.quant_comp - -1) > 0)) - gfp.quant_comp = set.quant_comp; - // SET_OPTION(quant_comp, set.quant_comp, -1); - if (enforce != 0) - gfp.quant_comp_short = set.quant_comp_s; - else if (!(Math.abs(gfp.quant_comp_short - -1) > 0)) - gfp.quant_comp_short = set.quant_comp_s; - // SET_OPTION(quant_comp_short, set.quant_comp_s, -1); - if (set.expY != 0) { - gfp.experimentalY = set.expY != 0; - } - if (enforce != 0) - gfp.internal_flags.nsPsy.attackthre = set.st_lrm; - else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre - -1) > 0)) - gfp.internal_flags.nsPsy.attackthre = set.st_lrm; - // SET_OPTION(short_threshold_lrm, set.st_lrm, -1); - if (enforce != 0) - gfp.internal_flags.nsPsy.attackthre_s = set.st_s; - else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre_s - -1) > 0)) - gfp.internal_flags.nsPsy.attackthre_s = set.st_s; - // SET_OPTION(short_threshold_s, set.st_s, -1); - if (enforce != 0) - gfp.maskingadjust = set.masking_adj; - else if (!(Math.abs(gfp.maskingadjust - 0) > 0)) - gfp.maskingadjust = set.masking_adj; - // SET_OPTION(maskingadjust, set.masking_adj, 0); - if (enforce != 0) - gfp.maskingadjust_short = set.masking_adj_short; - else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0)) - gfp.maskingadjust_short = set.masking_adj_short; - // SET_OPTION(maskingadjust_short, set.masking_adj_short, 0); - if (enforce != 0) - gfp.ATHlower = -set.ath_lower / 10.0; - else if (!(Math.abs((-gfp.ATHlower * 10.0) - 0) > 0)) - gfp.ATHlower = -set.ath_lower / 10.0; - // SET_OPTION(ATHlower, set.ath_lower, 0); - if (enforce != 0) - gfp.ATHcurve = set.ath_curve; - else if (!(Math.abs(gfp.ATHcurve - -1) > 0)) - gfp.ATHcurve = set.ath_curve; - // SET_OPTION(ATHcurve, set.ath_curve, -1); - if (enforce != 0) - gfp.athaa_sensitivity = set.ath_sensitivity; - else if (!(Math.abs(gfp.athaa_sensitivity - -1) > 0)) - gfp.athaa_sensitivity = set.ath_sensitivity; - // SET_OPTION(athaa_sensitivity, set.ath_sensitivity, 0); - if (set.interch > 0) { - if (enforce != 0) - gfp.interChRatio = set.interch; - else if (!(Math.abs(gfp.interChRatio - -1) > 0)) - gfp.interChRatio = set.interch; - // SET_OPTION(interChRatio, set.interch, -1); - } - - /* parameters for which there is no proper set/get interface */ - if (set.safejoint > 0) { - gfp.exp_nspsytune = gfp.exp_nspsytune | set.safejoint; - } - if (set.sfb21mod > 0) { - gfp.exp_nspsytune = gfp.exp_nspsytune | (set.sfb21mod << 20); - } - if (enforce != 0) - gfp.msfix = set.msfix; - else if (!(Math.abs(gfp.msfix - -1) > 0)) - gfp.msfix = set.msfix; - // SET_OPTION(msfix, set.msfix, -1); - - if (enforce == 0) { - gfp.VBR_q = a; - gfp.VBR_q_frac = x; - } - } - - /** - *
-     *  Switch mappings for ABR mode
-     *
-     *              kbps  quant q_s safejoint nsmsfix st_lrm  st_s  ns-bass scale   msk ath_lwr ath_curve  interch , sfscale
-     * 
- */ - var abr_switch_map = [ - new ABRPresets(8, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -30.0, 11, 0.0012, 1), /* 8, impossible to use in stereo */ - new ABRPresets(16, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -25.0, 11, 0.0010, 1), /* 16 */ - new ABRPresets(24, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -20.0, 11, 0.0010, 1), /* 24 */ - new ABRPresets(32, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -15.0, 11, 0.0010, 1), /* 32 */ - new ABRPresets(40, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -10.0, 11, 0.0009, 1), /* 40 */ - new ABRPresets(48, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -10.0, 11, 0.0009, 1), /* 48 */ - new ABRPresets(56, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -6.0, 11, 0.0008, 1), /* 56 */ - new ABRPresets(64, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, -2.0, 11, 0.0008, 1), /* 64 */ - new ABRPresets(80, 9, 9, 0, 0, 6.60, 145, 0, 0.95, 0, .0, 8, 0.0007, 1), /* 80 */ - new ABRPresets(96, 9, 9, 0, 2.50, 6.60, 145, 0, 0.95, 0, 1.0, 5.5, 0.0006, 1), /* 96 */ - new ABRPresets(112, 9, 9, 0, 2.25, 6.60, 145, 0, 0.95, 0, 2.0, 4.5, 0.0005, 1), /* 112 */ - new ABRPresets(128, 9, 9, 0, 1.95, 6.40, 140, 0, 0.95, 0, 3.0, 4, 0.0002, 1), /* 128 */ - new ABRPresets(160, 9, 9, 1, 1.79, 6.00, 135, 0, 0.95, -2, 5.0, 3.5, 0, 1), /* 160 */ - new ABRPresets(192, 9, 9, 1, 1.49, 5.60, 125, 0, 0.97, -4, 7.0, 3, 0, 0), /* 192 */ - new ABRPresets(224, 9, 9, 1, 1.25, 5.20, 125, 0, 0.98, -6, 9.0, 2, 0, 0), /* 224 */ - new ABRPresets(256, 9, 9, 1, 0.97, 5.20, 125, 0, 1.00, -8, 10.0, 1, 0, 0), /* 256 */ - new ABRPresets(320, 9, 9, 1, 0.90, 5.20, 125, 0, 1.00, -10, 12.0, 0, 0, 0) /* 320 */ - ]; - - function apply_abr_preset(gfp, preset, enforce) { - /* Variables for the ABR stuff */ - var actual_bitrate = preset; - - var r = lame.nearestBitrateFullIndex(preset); - - gfp.VBR = VbrMode.vbr_abr; - gfp.VBR_mean_bitrate_kbps = actual_bitrate; - gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps, 320); - gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps, 8); - gfp.brate = gfp.VBR_mean_bitrate_kbps; - if (gfp.VBR_mean_bitrate_kbps > 320) { - gfp.disable_reservoir = true; - } - - /* parameters for which there is no proper set/get interface */ - if (abr_switch_map[r].safejoint > 0) - gfp.exp_nspsytune = gfp.exp_nspsytune | 2; - /* safejoint */ - - if (abr_switch_map[r].sfscale > 0) { - gfp.internal_flags.noise_shaping = 2; - } - /* ns-bass tweaks */ - if (Math.abs(abr_switch_map[r].nsbass) > 0) { - var k = (int)(abr_switch_map[r].nsbass * 4); - if (k < 0) - k += 64; - gfp.exp_nspsytune = gfp.exp_nspsytune | (k << 2); - } - - if (enforce != 0) - gfp.quant_comp = abr_switch_map[r].quant_comp; - else if (!(Math.abs(gfp.quant_comp - -1) > 0)) - gfp.quant_comp = abr_switch_map[r].quant_comp; - // SET_OPTION(quant_comp, abr_switch_map[r].quant_comp, -1); - if (enforce != 0) - gfp.quant_comp_short = abr_switch_map[r].quant_comp_s; - else if (!(Math.abs(gfp.quant_comp_short - -1) > 0)) - gfp.quant_comp_short = abr_switch_map[r].quant_comp_s; - // SET_OPTION(quant_comp_short, abr_switch_map[r].quant_comp_s, -1); - - if (enforce != 0) - gfp.msfix = abr_switch_map[r].nsmsfix; - else if (!(Math.abs(gfp.msfix - -1) > 0)) - gfp.msfix = abr_switch_map[r].nsmsfix; - // SET_OPTION(msfix, abr_switch_map[r].nsmsfix, -1); - - if (enforce != 0) - gfp.internal_flags.nsPsy.attackthre = abr_switch_map[r].st_lrm; - else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre - -1) > 0)) - gfp.internal_flags.nsPsy.attackthre = abr_switch_map[r].st_lrm; - // SET_OPTION(short_threshold_lrm, abr_switch_map[r].st_lrm, -1); - if (enforce != 0) - gfp.internal_flags.nsPsy.attackthre_s = abr_switch_map[r].st_s; - else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre_s - -1) > 0)) - gfp.internal_flags.nsPsy.attackthre_s = abr_switch_map[r].st_s; - // SET_OPTION(short_threshold_s, abr_switch_map[r].st_s, -1); - - /* - * ABR seems to have big problems with clipping, especially at low - * bitrates - */ - /* - * so we compensate for that here by using a scale value depending on - * bitrate - */ - if (enforce != 0) - gfp.scale = abr_switch_map[r].scale; - else if (!(Math.abs(gfp.scale - -1) > 0)) - gfp.scale = abr_switch_map[r].scale; - // SET_OPTION(scale, abr_switch_map[r].scale, -1); - - if (enforce != 0) - gfp.maskingadjust = abr_switch_map[r].masking_adj; - else if (!(Math.abs(gfp.maskingadjust - 0) > 0)) - gfp.maskingadjust = abr_switch_map[r].masking_adj; - // SET_OPTION(maskingadjust, abr_switch_map[r].masking_adj, 0); - if (abr_switch_map[r].masking_adj > 0) { - if (enforce != 0) - gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * .9); - else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0)) - gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * .9); - // SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * - // .9, 0); - } else { - if (enforce != 0) - gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * 1.1); - else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0)) - gfp.maskingadjust_short = (abr_switch_map[r].masking_adj * 1.1); - // SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * - // 1.1, 0); - } - - if (enforce != 0) - gfp.ATHlower = -abr_switch_map[r].ath_lower / 10.; - else if (!(Math.abs((-gfp.ATHlower * 10.) - 0) > 0)) - gfp.ATHlower = -abr_switch_map[r].ath_lower / 10.; - // SET_OPTION(ATHlower, abr_switch_map[r].ath_lower, 0); - if (enforce != 0) - gfp.ATHcurve = abr_switch_map[r].ath_curve; - else if (!(Math.abs(gfp.ATHcurve - -1) > 0)) - gfp.ATHcurve = abr_switch_map[r].ath_curve; - // SET_OPTION(ATHcurve, abr_switch_map[r].ath_curve, -1); - - if (enforce != 0) - gfp.interChRatio = abr_switch_map[r].interch; - else if (!(Math.abs(gfp.interChRatio - -1) > 0)) - gfp.interChRatio = abr_switch_map[r].interch; - // SET_OPTION(interChRatio, abr_switch_map[r].interch, -1); - - return preset; - } - - this.apply_preset = function(gfp, preset, enforce) { - /* translate legacy presets */ - switch (preset) { - case Lame.R3MIX: - { - preset = Lame.V3; - gfp.VBR = VbrMode.vbr_mtrh; - break; - } - case Lame.MEDIUM: - { - preset = Lame.V4; - gfp.VBR = VbrMode.vbr_rh; - break; - } - case Lame.MEDIUM_FAST: - { - preset = Lame.V4; - gfp.VBR = VbrMode.vbr_mtrh; - break; - } - case Lame.STANDARD: - { - preset = Lame.V2; - gfp.VBR = VbrMode.vbr_rh; - break; - } - case Lame.STANDARD_FAST: - { - preset = Lame.V2; - gfp.VBR = VbrMode.vbr_mtrh; - break; - } - case Lame.EXTREME: - { - preset = Lame.V0; - gfp.VBR = VbrMode.vbr_rh; - break; - } - case Lame.EXTREME_FAST: - { - preset = Lame.V0; - gfp.VBR = VbrMode.vbr_mtrh; - break; - } - case Lame.INSANE: - { - preset = 320; - gfp.preset = preset; - apply_abr_preset(gfp, preset, enforce); - gfp.VBR = VbrMode.vbr_off; - return preset; - } - } - - gfp.preset = preset; - { - switch (preset) { - case Lame.V9: - apply_vbr_preset(gfp, 9, enforce); - return preset; - case Lame.V8: - apply_vbr_preset(gfp, 8, enforce); - return preset; - case Lame.V7: - apply_vbr_preset(gfp, 7, enforce); - return preset; - case Lame.V6: - apply_vbr_preset(gfp, 6, enforce); - return preset; - case Lame.V5: - apply_vbr_preset(gfp, 5, enforce); - return preset; - case Lame.V4: - apply_vbr_preset(gfp, 4, enforce); - return preset; - case Lame.V3: - apply_vbr_preset(gfp, 3, enforce); - return preset; - case Lame.V2: - apply_vbr_preset(gfp, 2, enforce); - return preset; - case Lame.V1: - apply_vbr_preset(gfp, 1, enforce); - return preset; - case Lame.V0: - apply_vbr_preset(gfp, 0, enforce); - return preset; - default: - break; - } - } - if (8 <= preset && preset <= 320) { - return apply_abr_preset(gfp, preset, enforce); - } - - /* no corresponding preset found */ - gfp.preset = 0; - return preset; - } - - // Rest from getset.c: - - /** - * VBR quality level.
- * 0 = highest
- * 9 = lowest - */ - function lame_set_VBR_q(gfp, VBR_q) { - var ret = 0; - - if (0 > VBR_q) { - /* Unknown VBR quality level! */ - ret = -1; - VBR_q = 0; - } - if (9 < VBR_q) { - ret = -1; - VBR_q = 9; - } - - gfp.VBR_q = VBR_q; - gfp.VBR_q_frac = 0; - return ret; - } - -} - -module.exports = Presets; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/PsyModel.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/PsyModel.js deleted file mode 100644 index 533ca4d18..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/PsyModel.js +++ /dev/null @@ -1,2898 +0,0 @@ -/* - * psymodel.c - * - * Copyright (c) 1999-2000 Mark Taylor - * Copyright (c) 2001-2002 Naoki Shibata - * Copyright (c) 2000-2003 Takehiro Tominaga - * Copyright (c) 2000-2008 Robert Hegemann - * Copyright (c) 2000-2005 Gabriel Bouvigne - * Copyright (c) 2000-2005 Alexander Leidinger - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: PsyModel.java,v 1.27 2011/05/24 20:48:06 kenchis Exp $ */ - - -/* - PSYCHO ACOUSTICS - - - This routine computes the psycho acoustics, delayed by one granule. - - Input: buffer of PCM data (1024 samples). - - This window should be centered over the 576 sample granule window. - The routine will compute the psycho acoustics for - this granule, but return the psycho acoustics computed - for the *previous* granule. This is because the block - type of the previous granule can only be determined - after we have computed the psycho acoustics for the following - granule. - - Output: maskings and energies for each scalefactor band. - block type, PE, and some correlation measures. - The PE is used by CBR modes to determine if extra bits - from the bit reservoir should be used. The correlation - measures are used to determine mid/side or regular stereo. - */ -/* - Notation: - - barks: a non-linear frequency scale. Mapping from frequency to - barks is given by freq2bark() - - scalefactor bands: The spectrum (frequencies) are broken into - SBMAX "scalefactor bands". Thes bands - are determined by the MPEG ISO spec. In - the noise shaping/quantization code, we allocate - bits among the partition bands to achieve the - best possible quality - - partition bands: The spectrum is also broken into about - 64 "partition bands". Each partition - band is about .34 barks wide. There are about 2-5 - partition bands for each scalefactor band. - - LAME computes all psycho acoustic information for each partition - band. Then at the end of the computations, this information - is mapped to scalefactor bands. The energy in each scalefactor - band is taken as the sum of the energy in all partition bands - which overlap the scalefactor band. The maskings can be computed - in the same way (and thus represent the average masking in that band) - or by taking the minmum value multiplied by the number of - partition bands used (which represents a minimum masking in that band). - */ -/* - The general outline is as follows: - - 1. compute the energy in each partition band - 2. compute the tonality in each partition band - 3. compute the strength of each partion band "masker" - 4. compute the masking (via the spreading function applied to each masker) - 5. Modifications for mid/side masking. - - Each partition band is considiered a "masker". The strength - of the i'th masker in band j is given by: - - s3(bark(i)-bark(j))*strength(i) - - The strength of the masker is a function of the energy and tonality. - The more tonal, the less masking. LAME uses a simple linear formula - (controlled by NMT and TMN) which says the strength is given by the - energy divided by a linear function of the tonality. - */ -/* - s3() is the "spreading function". It is given by a formula - determined via listening tests. - - The total masking in the j'th partition band is the sum over - all maskings i. It is thus given by the convolution of - the strength with s3(), the "spreading function." - - masking(j) = sum_over_i s3(i-j)*strength(i) = s3 o strength - - where "o" = convolution operator. s3 is given by a formula determined - via listening tests. It is normalized so that s3 o 1 = 1. - - Note: instead of a simple convolution, LAME also has the - option of using "additive masking" - - The most critical part is step 2, computing the tonality of each - partition band. LAME has two tonality estimators. The first - is based on the ISO spec, and measures how predictiable the - signal is over time. The more predictable, the more tonal. - The second measure is based on looking at the spectrum of - a single granule. The more peaky the spectrum, the more - tonal. By most indications, the latter approach is better. - - Finally, in step 5, the maskings for the mid and side - channel are possibly increased. Under certain circumstances, - noise in the mid & side channels is assumed to also - be masked by strong maskers in the L or R channels. - - - Other data computed by the psy-model: - - ms_ratio side-channel / mid-channel masking ratio (for previous granule) - ms_ratio_next side-channel / mid-channel masking ratio for this granule - - percep_entropy[2] L and R values (prev granule) of PE - A measure of how - much pre-echo is in the previous granule - percep_entropy_MS[2] mid and side channel values (prev granule) of percep_entropy - energy[4] L,R,M,S energy in each channel, prev granule - blocktype_d[2] block type to use for previous granule - */ -//package mp3; - -//import java.util.Arrays; -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -var FFT = require("./FFT.js"); -var Encoder = require("./Encoder.js"); - -function PsyModel() { - var MPEGMode = require('./MPEGMode.js'); - var fft = new FFT(); - - var LOG10 = 2.30258509299404568402; - - var rpelev = 2; - var rpelev2 = 16; - var rpelev_s = 2; - var rpelev2_s = 16; - - /* size of each partition band, in barks: */ - var DELBARK = .34; - - /* tuned for output level (sensitive to energy scale) */ - var VO_SCALE = (1. / (14752 * 14752) / (Encoder.BLKSIZE / 2)); - - var temporalmask_sustain_sec = 0.01; - - var NS_PREECHO_ATT0 = 0.8; - var NS_PREECHO_ATT1 = 0.6; - var NS_PREECHO_ATT2 = 0.3; - - var NS_MSFIX = 3.5; - - var NSATTACKTHRE = 4.4; - var NSATTACKTHRE_S = 25; - - var NSFIRLEN = 21; - - /* size of each partition band, in barks: */ - var LN_TO_LOG10 = 0.2302585093; - - function NON_LINEAR_SCALE_ENERGY(x) { - return x; - } - - /** - *
-     *       L3psycho_anal.  Compute psycho acoustics.
-     *
-     *       Data returned to the calling program must be delayed by one
-     *       granule.
-     *
-     *       This is done in two places.
-     *       If we do not need to know the blocktype, the copying
-     *       can be done here at the top of the program: we copy the data for
-     *       the last granule (computed during the last call) before it is
-     *       overwritten with the new data.  It looks like this:
-     *
-     *       0. static psymodel_data
-     *       1. calling_program_data = psymodel_data
-     *       2. compute psymodel_data
-     *
-     *       For data which needs to know the blocktype, the copying must be
-     *       done at the end of this loop, and the old values must be saved:
-     *
-     *       0. static psymodel_data_old
-     *       1. compute psymodel_data
-     *       2. compute possible block type of this granule
-     *       3. compute final block type of previous granule based on #2.
-     *       4. calling_program_data = psymodel_data_old
-     *       5. psymodel_data_old = psymodel_data
-     *     psycho_loudness_approx
-     *       jd - 2001 mar 12
-     *    in:  energy   - BLKSIZE/2 elements of frequency magnitudes ^ 2
-     *         gfp      - uses out_samplerate, ATHtype (also needed for ATHformula)
-     *    returns: loudness^2 approximation, a positive value roughly tuned for a value
-     *             of 1.0 for signals near clipping.
-     *    notes:   When calibrated, feeding this function binary white noise at sample
-     *             values +32767 or -32768 should return values that approach 3.
-     *             ATHformula is used to approximate an equal loudness curve.
-     *    future:  Data indicates that the shape of the equal loudness curve varies
-     *             with intensity.  This function might be improved by using an equal
-     *             loudness curve shaped for typical playback levels (instead of the
-     *             ATH, that is shaped for the threshold).  A flexible realization might
-     *             simply bend the existing ATH curve to achieve the desired shape.
-     *             However, the potential gain may not be enough to justify an effort.
-     * 
- */ - function psycho_loudness_approx(energy, gfc) { - var loudness_power = 0.0; - /* apply weights to power in freq. bands */ - for (var i = 0; i < Encoder.BLKSIZE / 2; ++i) - loudness_power += energy[i] * gfc.ATH.eql_w[i]; - loudness_power *= VO_SCALE; - - return loudness_power; - } - - function compute_ffts(gfp, fftenergy, fftenergy_s, wsamp_l, wsamp_lPos, wsamp_s, wsamp_sPos, gr_out, chn, buffer, bufPos) { - var gfc = gfp.internal_flags; - if (chn < 2) { - fft.fft_long(gfc, wsamp_l[wsamp_lPos], chn, buffer, bufPos); - fft.fft_short(gfc, wsamp_s[wsamp_sPos], chn, buffer, bufPos); - } - /* FFT data for mid and side channel is derived from L & R */ - else if (chn == 2) { - for (var j = Encoder.BLKSIZE - 1; j >= 0; --j) { - var l = wsamp_l[wsamp_lPos + 0][j]; - var r = wsamp_l[wsamp_lPos + 1][j]; - wsamp_l[wsamp_lPos + 0][j] = (l + r) * Util.SQRT2 * 0.5; - wsamp_l[wsamp_lPos + 1][j] = (l - r) * Util.SQRT2 * 0.5; - } - for (var b = 2; b >= 0; --b) { - for (var j = Encoder.BLKSIZE_s - 1; j >= 0; --j) { - var l = wsamp_s[wsamp_sPos + 0][b][j]; - var r = wsamp_s[wsamp_sPos + 1][b][j]; - wsamp_s[wsamp_sPos + 0][b][j] = (l + r) * Util.SQRT2 * 0.5; - wsamp_s[wsamp_sPos + 1][b][j] = (l - r) * Util.SQRT2 * 0.5; - } - } - } - - /********************************************************************* - * compute energies - *********************************************************************/ - fftenergy[0] = NON_LINEAR_SCALE_ENERGY(wsamp_l[wsamp_lPos + 0][0]); - fftenergy[0] *= fftenergy[0]; - - for (var j = Encoder.BLKSIZE / 2 - 1; j >= 0; --j) { - var re = (wsamp_l[wsamp_lPos + 0])[Encoder.BLKSIZE / 2 - j]; - var im = (wsamp_l[wsamp_lPos + 0])[Encoder.BLKSIZE / 2 + j]; - fftenergy[Encoder.BLKSIZE / 2 - j] = NON_LINEAR_SCALE_ENERGY((re - * re + im * im) * 0.5); - } - for (var b = 2; b >= 0; --b) { - fftenergy_s[b][0] = (wsamp_s[wsamp_sPos + 0])[b][0]; - fftenergy_s[b][0] *= fftenergy_s[b][0]; - for (var j = Encoder.BLKSIZE_s / 2 - 1; j >= 0; --j) { - var re = (wsamp_s[wsamp_sPos + 0])[b][Encoder.BLKSIZE_s - / 2 - j]; - var im = (wsamp_s[wsamp_sPos + 0])[b][Encoder.BLKSIZE_s - / 2 + j]; - fftenergy_s[b][Encoder.BLKSIZE_s / 2 - j] = NON_LINEAR_SCALE_ENERGY((re - * re + im * im) * 0.5); - } - } - /* total energy */ - { - var totalenergy = 0.0; - for (var j = 11; j < Encoder.HBLKSIZE; j++) - totalenergy += fftenergy[j]; - - gfc.tot_ener[chn] = totalenergy; - } - - if (gfp.analysis) { - for (var j = 0; j < Encoder.HBLKSIZE; j++) { - gfc.pinfo.energy[gr_out][chn][j] = gfc.pinfo.energy_save[chn][j]; - gfc.pinfo.energy_save[chn][j] = fftenergy[j]; - } - gfc.pinfo.pe[gr_out][chn] = gfc.pe[chn]; - } - - /********************************************************************* - * compute loudness approximation (used for ATH auto-level adjustment) - *********************************************************************/ - if (gfp.athaa_loudapprox == 2 && chn < 2) { - // no loudness for mid/side ch - gfc.loudness_sq[gr_out][chn] = gfc.loudness_sq_save[chn]; - gfc.loudness_sq_save[chn] = psycho_loudness_approx(fftenergy, gfc); - } - } - - /* mask_add optimization */ - /* init the limit values used to avoid computing log in mask_add when it is not necessary */ - - /** - *
-     *  For example, with i = 10*log10(m2/m1)/10*16         (= log10(m2/m1)*16)
-     *
-     * abs(i)>8 is equivalent (as i is an integer) to
-     * abs(i)>=9
-     * i>=9 || i<=-9
-     * equivalent to (as i is the biggest integer smaller than log10(m2/m1)*16
-     * or the smallest integer bigger than log10(m2/m1)*16 depending on the sign of log10(m2/m1)*16)
-     * log10(m2/m1)>=9/16 || log10(m2/m1)<=-9/16
-     * exp10 is strictly increasing thus this is equivalent to
-     * m2/m1 >= 10^(9/16) || m2/m1<=10^(-9/16) which are comparisons to constants
-     * 
- */ - - /** - * as in if(i>8) - */ - var I1LIMIT = 8; - /** - * as in if(i>24) . changed 23 - */ - var I2LIMIT = 23; - /** - * as in if(m<15) - */ - var MLIMIT = 15; - - var ma_max_i1; - var ma_max_i2; - var ma_max_m; - - /** - * This is the masking table:
- * According to tonality, values are going from 0dB (TMN) to 9.3dB (NMT).
- * After additive masking computation, 8dB are added, so final values are - * going from 8dB to 17.3dB - * - * pow(10, -0.0..-0.6) - */ - var tab = [1.0, 0.79433, 0.63096, 0.63096, - 0.63096, 0.63096, 0.63096, 0.25119, 0.11749]; - - function init_mask_add_max_values() { - ma_max_i1 = Math.pow(10, (I1LIMIT + 1) / 16.0); - ma_max_i2 = Math.pow(10, (I2LIMIT + 1) / 16.0); - ma_max_m = Math.pow(10, (MLIMIT) / 10.0); - } - - var table1 = [3.3246 * 3.3246, - 3.23837 * 3.23837, 3.15437 * 3.15437, 3.00412 * 3.00412, - 2.86103 * 2.86103, 2.65407 * 2.65407, 2.46209 * 2.46209, - 2.284 * 2.284, 2.11879 * 2.11879, 1.96552 * 1.96552, - 1.82335 * 1.82335, 1.69146 * 1.69146, 1.56911 * 1.56911, - 1.46658 * 1.46658, 1.37074 * 1.37074, 1.31036 * 1.31036, - 1.25264 * 1.25264, 1.20648 * 1.20648, 1.16203 * 1.16203, - 1.12765 * 1.12765, 1.09428 * 1.09428, 1.0659 * 1.0659, - 1.03826 * 1.03826, 1.01895 * 1.01895, 1]; - - var table2 = [1.33352 * 1.33352, - 1.35879 * 1.35879, 1.38454 * 1.38454, 1.39497 * 1.39497, - 1.40548 * 1.40548, 1.3537 * 1.3537, 1.30382 * 1.30382, - 1.22321 * 1.22321, 1.14758 * 1.14758, 1]; - - var table3 = [2.35364 * 2.35364, - 2.29259 * 2.29259, 2.23313 * 2.23313, 2.12675 * 2.12675, - 2.02545 * 2.02545, 1.87894 * 1.87894, 1.74303 * 1.74303, - 1.61695 * 1.61695, 1.49999 * 1.49999, 1.39148 * 1.39148, - 1.29083 * 1.29083, 1.19746 * 1.19746, 1.11084 * 1.11084, - 1.03826 * 1.03826]; - - /** - * addition of simultaneous masking Naoki Shibata 2000/7 - */ - function mask_add(m1, m2, kk, b, gfc, shortblock) { - var ratio; - - if (m2 > m1) { - if (m2 < (m1 * ma_max_i2)) - ratio = m2 / m1; - else - return (m1 + m2); - } else { - if (m1 >= (m2 * ma_max_i2)) - return (m1 + m2); - ratio = m1 / m2; - } - - /* Should always be true, just checking */ - assert(m1 >= 0); - assert(m2 >= 0); - - m1 += m2; - //if (((long)(b + 3) & 0xffffffff) <= 3 + 3) { - if ((b + 3) <= 3 + 3) { - /* approximately, 1 bark = 3 partitions */ - /* 65% of the cases */ - /* originally 'if(i > 8)' */ - if (ratio >= ma_max_i1) { - /* 43% of the total */ - return m1; - } - - /* 22% of the total */ - var i = 0 | (Util.FAST_LOG10_X(ratio, 16.0)); - return m1 * table2[i]; - } - - /** - *
-         * m<15 equ log10((m1+m2)/gfc.ATH.cb[k])<1.5
-         * equ (m1+m2)/gfc.ATH.cb[k]<10^1.5
-         * equ (m1+m2)<10^1.5 * gfc.ATH.cb[k]
-         * 
- */ - var i = 0 | Util.FAST_LOG10_X(ratio, 16.0); - if (shortblock != 0) { - m2 = gfc.ATH.cb_s[kk] * gfc.ATH.adjust; - } else { - m2 = gfc.ATH.cb_l[kk] * gfc.ATH.adjust; - } - assert(m2 >= 0); - if (m1 < ma_max_m * m2) { - /* 3% of the total */ - /* Originally if (m > 0) { */ - if (m1 > m2) { - var f, r; - - f = 1.0; - if (i <= 13) - f = table3[i]; - - r = Util.FAST_LOG10_X(m1 / m2, 10.0 / 15.0); - return m1 * ((table1[i] - f) * r + f); - } - - if (i > 13) - return m1; - - return m1 * table3[i]; - } - - /* 10% of total */ - return m1 * table1[i]; - } - - var table2_ = [1.33352 * 1.33352, - 1.35879 * 1.35879, 1.38454 * 1.38454, 1.39497 * 1.39497, - 1.40548 * 1.40548, 1.3537 * 1.3537, 1.30382 * 1.30382, - 1.22321 * 1.22321, 1.14758 * 1.14758, 1]; - - /** - * addition of simultaneous masking Naoki Shibata 2000/7 - */ - function vbrpsy_mask_add(m1, m2, b) { - var ratio; - - if (m1 < 0) { - m1 = 0; - } - if (m2 < 0) { - m2 = 0; - } - if (m1 <= 0) { - return m2; - } - if (m2 <= 0) { - return m1; - } - if (m2 > m1) { - ratio = m2 / m1; - } else { - ratio = m1 / m2; - } - if (-2 <= b && b <= 2) { - /* approximately, 1 bark = 3 partitions */ - /* originally 'if(i > 8)' */ - if (ratio >= ma_max_i1) { - return m1 + m2; - } else { - var i = 0 | (Util.FAST_LOG10_X(ratio, 16.0)); - return (m1 + m2) * table2_[i]; - } - } - if (ratio < ma_max_i2) { - return m1 + m2; - } - if (m1 < m2) { - m1 = m2; - } - return m1; - } - - /** - * compute interchannel masking effects - */ - function calc_interchannel_masking(gfp, ratio) { - var gfc = gfp.internal_flags; - if (gfc.channels_out > 1) { - for (var sb = 0; sb < Encoder.SBMAX_l; sb++) { - var l = gfc.thm[0].l[sb]; - var r = gfc.thm[1].l[sb]; - gfc.thm[0].l[sb] += r * ratio; - gfc.thm[1].l[sb] += l * ratio; - } - for (var sb = 0; sb < Encoder.SBMAX_s; sb++) { - for (var sblock = 0; sblock < 3; sblock++) { - var l = gfc.thm[0].s[sb][sblock]; - var r = gfc.thm[1].s[sb][sblock]; - gfc.thm[0].s[sb][sblock] += r * ratio; - gfc.thm[1].s[sb][sblock] += l * ratio; - } - } - } - } - - /** - * compute M/S thresholds from Johnston & Ferreira 1992 ICASSP paper - */ - function msfix1(gfc) { - for (var sb = 0; sb < Encoder.SBMAX_l; sb++) { - /* use this fix if L & R masking differs by 2db or less */ - /* if db = 10*log10(x2/x1) < 2 */ - /* if (x2 < 1.58*x1) { */ - if (gfc.thm[0].l[sb] > 1.58 * gfc.thm[1].l[sb] - || gfc.thm[1].l[sb] > 1.58 * gfc.thm[0].l[sb]) - continue; - var mld = gfc.mld_l[sb] * gfc.en[3].l[sb]; - var rmid = Math.max(gfc.thm[2].l[sb], - Math.min(gfc.thm[3].l[sb], mld)); - - mld = gfc.mld_l[sb] * gfc.en[2].l[sb]; - var rside = Math.max(gfc.thm[3].l[sb], - Math.min(gfc.thm[2].l[sb], mld)); - gfc.thm[2].l[sb] = rmid; - gfc.thm[3].l[sb] = rside; - } - - for (var sb = 0; sb < Encoder.SBMAX_s; sb++) { - for (var sblock = 0; sblock < 3; sblock++) { - if (gfc.thm[0].s[sb][sblock] > 1.58 * gfc.thm[1].s[sb][sblock] - || gfc.thm[1].s[sb][sblock] > 1.58 * gfc.thm[0].s[sb][sblock]) - continue; - var mld = gfc.mld_s[sb] * gfc.en[3].s[sb][sblock]; - var rmid = Math.max(gfc.thm[2].s[sb][sblock], - Math.min(gfc.thm[3].s[sb][sblock], mld)); - - mld = gfc.mld_s[sb] * gfc.en[2].s[sb][sblock]; - var rside = Math.max(gfc.thm[3].s[sb][sblock], - Math.min(gfc.thm[2].s[sb][sblock], mld)); - - gfc.thm[2].s[sb][sblock] = rmid; - gfc.thm[3].s[sb][sblock] = rside; - } - } - } - - /** - * Adjust M/S maskings if user set "msfix" - * - * Naoki Shibata 2000 - */ - function ns_msfix(gfc, msfix, athadjust) { - var msfix2 = msfix; - var athlower = Math.pow(10, athadjust); - - msfix *= 2.0; - msfix2 *= 2.0; - for (var sb = 0; sb < Encoder.SBMAX_l; sb++) { - var thmLR, thmM, thmS, ath; - ath = (gfc.ATH.cb_l[gfc.bm_l[sb]]) * athlower; - thmLR = Math.min(Math.max(gfc.thm[0].l[sb], ath), - Math.max(gfc.thm[1].l[sb], ath)); - thmM = Math.max(gfc.thm[2].l[sb], ath); - thmS = Math.max(gfc.thm[3].l[sb], ath); - if (thmLR * msfix < thmM + thmS) { - var f = thmLR * msfix2 / (thmM + thmS); - thmM *= f; - thmS *= f; - assert(thmM + thmS > 0); - } - gfc.thm[2].l[sb] = Math.min(thmM, gfc.thm[2].l[sb]); - gfc.thm[3].l[sb] = Math.min(thmS, gfc.thm[3].l[sb]); - } - - athlower *= ( Encoder.BLKSIZE_s / Encoder.BLKSIZE); - for (var sb = 0; sb < Encoder.SBMAX_s; sb++) { - for (var sblock = 0; sblock < 3; sblock++) { - var thmLR, thmM, thmS, ath; - ath = (gfc.ATH.cb_s[gfc.bm_s[sb]]) * athlower; - thmLR = Math.min(Math.max(gfc.thm[0].s[sb][sblock], ath), - Math.max(gfc.thm[1].s[sb][sblock], ath)); - thmM = Math.max(gfc.thm[2].s[sb][sblock], ath); - thmS = Math.max(gfc.thm[3].s[sb][sblock], ath); - - if (thmLR * msfix < thmM + thmS) { - var f = thmLR * msfix / (thmM + thmS); - thmM *= f; - thmS *= f; - assert(thmM + thmS > 0); - } - gfc.thm[2].s[sb][sblock] = Math.min(gfc.thm[2].s[sb][sblock], - thmM); - gfc.thm[3].s[sb][sblock] = Math.min(gfc.thm[3].s[sb][sblock], - thmS); - } - } - } - - /** - * short block threshold calculation (part 2) - * - * partition band bo_s[sfb] is at the transition from scalefactor band sfb - * to the next one sfb+1; enn and thmm have to be split between them - */ - function convert_partition2scalefac_s(gfc, eb, thr, chn, sblock) { - var sb, b; - var enn = 0.0; - var thmm = 0.0; - for (sb = b = 0; sb < Encoder.SBMAX_s; ++b, ++sb) { - var bo_s_sb = gfc.bo_s[sb]; - var npart_s = gfc.npart_s; - var b_lim = bo_s_sb < npart_s ? bo_s_sb : npart_s; - while (b < b_lim) { - assert(eb[b] >= 0); - // iff failed, it may indicate some index error elsewhere - assert(thr[b] >= 0); - enn += eb[b]; - thmm += thr[b]; - b++; - } - gfc.en[chn].s[sb][sblock] = enn; - gfc.thm[chn].s[sb][sblock] = thmm; - - if (b >= npart_s) { - ++sb; - break; - } - assert(eb[b] >= 0); - // iff failed, it may indicate some index error elsewhere - assert(thr[b] >= 0); - { - /* at transition sfb . sfb+1 */ - var w_curr = gfc.PSY.bo_s_weight[sb]; - var w_next = 1.0 - w_curr; - enn = w_curr * eb[b]; - thmm = w_curr * thr[b]; - gfc.en[chn].s[sb][sblock] += enn; - gfc.thm[chn].s[sb][sblock] += thmm; - enn = w_next * eb[b]; - thmm = w_next * thr[b]; - } - } - /* zero initialize the rest */ - for (; sb < Encoder.SBMAX_s; ++sb) { - gfc.en[chn].s[sb][sblock] = 0; - gfc.thm[chn].s[sb][sblock] = 0; - } - } - - /** - * longblock threshold calculation (part 2) - */ - function convert_partition2scalefac_l(gfc, eb, thr, chn) { - var sb, b; - var enn = 0.0; - var thmm = 0.0; - for (sb = b = 0; sb < Encoder.SBMAX_l; ++b, ++sb) { - var bo_l_sb = gfc.bo_l[sb]; - var npart_l = gfc.npart_l; - var b_lim = bo_l_sb < npart_l ? bo_l_sb : npart_l; - while (b < b_lim) { - assert(eb[b] >= 0); - // iff failed, it may indicate some index error elsewhere - assert(thr[b] >= 0); - enn += eb[b]; - thmm += thr[b]; - b++; - } - gfc.en[chn].l[sb] = enn; - gfc.thm[chn].l[sb] = thmm; - - if (b >= npart_l) { - ++sb; - break; - } - assert(eb[b] >= 0); - assert(thr[b] >= 0); - { - /* at transition sfb . sfb+1 */ - var w_curr = gfc.PSY.bo_l_weight[sb]; - var w_next = 1.0 - w_curr; - enn = w_curr * eb[b]; - thmm = w_curr * thr[b]; - gfc.en[chn].l[sb] += enn; - gfc.thm[chn].l[sb] += thmm; - enn = w_next * eb[b]; - thmm = w_next * thr[b]; - } - } - /* zero initialize the rest */ - for (; sb < Encoder.SBMAX_l; ++sb) { - gfc.en[chn].l[sb] = 0; - gfc.thm[chn].l[sb] = 0; - } - } - - function compute_masking_s(gfp, fftenergy_s, eb, thr, chn, sblock) { - var gfc = gfp.internal_flags; - var j, b; - - for (b = j = 0; b < gfc.npart_s; ++b) { - var ebb = 0, m = 0; - var n = gfc.numlines_s[b]; - for (var i = 0; i < n; ++i, ++j) { - var el = fftenergy_s[sblock][j]; - ebb += el; - if (m < el) - m = el; - } - eb[b] = ebb; - } - assert(b == gfc.npart_s); - assert(j == 129); - for (j = b = 0; b < gfc.npart_s; b++) { - var kk = gfc.s3ind_s[b][0]; - var ecb = gfc.s3_ss[j++] * eb[kk]; - ++kk; - while (kk <= gfc.s3ind_s[b][1]) { - ecb += gfc.s3_ss[j] * eb[kk]; - ++j; - ++kk; - } - - { /* limit calculated threshold by previous granule */ - var x = rpelev_s * gfc.nb_s1[chn][b]; - thr[b] = Math.min(ecb, x); - } - if (gfc.blocktype_old[chn & 1] == Encoder.SHORT_TYPE) { - /* limit calculated threshold by even older granule */ - var x = rpelev2_s * gfc.nb_s2[chn][b]; - var y = thr[b]; - thr[b] = Math.min(x, y); - } - - gfc.nb_s2[chn][b] = gfc.nb_s1[chn][b]; - gfc.nb_s1[chn][b] = ecb; - assert(thr[b] >= 0); - } - for (; b <= Encoder.CBANDS; ++b) { - eb[b] = 0; - thr[b] = 0; - } - } - - function block_type_set(gfp, uselongblock, blocktype_d, blocktype) { - var gfc = gfp.internal_flags; - - if (gfp.short_blocks == ShortBlock.short_block_coupled - /* force both channels to use the same block type */ - /* this is necessary if the frame is to be encoded in ms_stereo. */ - /* But even without ms_stereo, FhG does this */ - && !(uselongblock[0] != 0 && uselongblock[1] != 0)) - uselongblock[0] = uselongblock[1] = 0; - - /* - * update the blocktype of the previous granule, since it depends on - * what happend in this granule - */ - for (var chn = 0; chn < gfc.channels_out; chn++) { - blocktype[chn] = Encoder.NORM_TYPE; - /* disable short blocks */ - if (gfp.short_blocks == ShortBlock.short_block_dispensed) - uselongblock[chn] = 1; - if (gfp.short_blocks == ShortBlock.short_block_forced) - uselongblock[chn] = 0; - - if (uselongblock[chn] != 0) { - /* no attack : use long blocks */ - assert(gfc.blocktype_old[chn] != Encoder.START_TYPE); - if (gfc.blocktype_old[chn] == Encoder.SHORT_TYPE) - blocktype[chn] = Encoder.STOP_TYPE; - } else { - /* attack : use short blocks */ - blocktype[chn] = Encoder.SHORT_TYPE; - if (gfc.blocktype_old[chn] == Encoder.NORM_TYPE) { - gfc.blocktype_old[chn] = Encoder.START_TYPE; - } - if (gfc.blocktype_old[chn] == Encoder.STOP_TYPE) - gfc.blocktype_old[chn] = Encoder.SHORT_TYPE; - } - - blocktype_d[chn] = gfc.blocktype_old[chn]; - // value returned to calling program - gfc.blocktype_old[chn] = blocktype[chn]; - // save for next call to l3psy_anal - } - } - - function NS_INTERP(x, y, r) { - /* was pow((x),(r))*pow((y),1-(r)) */ - if (r >= 1.0) { - /* 99.7% of the time */ - return x; - } - if (r <= 0.0) - return y; - if (y > 0.0) { - /* rest of the time */ - return (Math.pow(x / y, r) * y); - } - /* never happens */ - return 0.0; - } - - /** - * these values are tuned only for 44.1kHz... - */ - var regcoef_s = [11.8, 13.6, 17.2, 32, 46.5, - 51.3, 57.5, 67.1, 71.5, 84.6, 97.6, 130, - /* 255.8 */ - ]; - - function pecalc_s(mr, masking_lower) { - var pe_s = 1236.28 / 4; - for (var sb = 0; sb < Encoder.SBMAX_s - 1; sb++) { - for (var sblock = 0; sblock < 3; sblock++) { - var thm = mr.thm.s[sb][sblock]; - assert(sb < regcoef_s.length); - if (thm > 0.0) { - var x = thm * masking_lower; - var en = mr.en.s[sb][sblock]; - if (en > x) { - if (en > x * 1e10) { - pe_s += regcoef_s[sb] * (10.0 * LOG10); - } else { - assert(x > 0); - pe_s += regcoef_s[sb] * Util.FAST_LOG10(en / x); - } - } - } - } - } - - return pe_s; - } - - /** - * these values are tuned only for 44.1kHz... - */ - var regcoef_l = [6.8, 5.8, 5.8, 6.4, 6.5, 9.9, - 12.1, 14.4, 15, 18.9, 21.6, 26.9, 34.2, 40.2, 46.8, 56.5, - 60.7, 73.9, 85.7, 93.4, 126.1, - /* 241.3 */ - ]; - - function pecalc_l(mr, masking_lower) { - var pe_l = 1124.23 / 4; - for (var sb = 0; sb < Encoder.SBMAX_l - 1; sb++) { - var thm = mr.thm.l[sb]; - assert(sb < regcoef_l.length); - if (thm > 0.0) { - var x = thm * masking_lower; - var en = mr.en.l[sb]; - if (en > x) { - if (en > x * 1e10) { - pe_l += regcoef_l[sb] * (10.0 * LOG10); - } else { - assert(x > 0); - pe_l += regcoef_l[sb] * Util.FAST_LOG10(en / x); - } - } - } - } - return pe_l; - } - - function calc_energy(gfc, fftenergy, eb, max, avg) { - var b, j; - - for (b = j = 0; b < gfc.npart_l; ++b) { - var ebb = 0, m = 0; - var i; - for (i = 0; i < gfc.numlines_l[b]; ++i, ++j) { - var el = fftenergy[j]; - assert(el >= 0); - ebb += el; - if (m < el) - m = el; - } - eb[b] = ebb; - max[b] = m; - avg[b] = ebb * gfc.rnumlines_l[b]; - assert(gfc.rnumlines_l[b] >= 0); - assert(ebb >= 0); - assert(eb[b] >= 0); - assert(max[b] >= 0); - assert(avg[b] >= 0); - } - } - - function calc_mask_index_l(gfc, max, avg, mask_idx) { - var last_tab_entry = tab.length - 1; - var b = 0; - var a = avg[b] + avg[b + 1]; - assert(a >= 0); - if (a > 0.0) { - var m = max[b]; - if (m < max[b + 1]) - m = max[b + 1]; - assert((gfc.numlines_l[b] + gfc.numlines_l[b + 1] - 1) > 0); - a = 20.0 * (m * 2.0 - a) - / (a * (gfc.numlines_l[b] + gfc.numlines_l[b + 1] - 1)); - var k = 0 | a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - - for (b = 1; b < gfc.npart_l - 1; b++) { - a = avg[b - 1] + avg[b] + avg[b + 1]; - assert(a >= 0); - if (a > 0.0) { - var m = max[b - 1]; - if (m < max[b]) - m = max[b]; - if (m < max[b + 1]) - m = max[b + 1]; - assert((gfc.numlines_l[b - 1] + gfc.numlines_l[b] + gfc.numlines_l[b + 1] - 1) > 0); - a = 20.0 - * (m * 3.0 - a) - / (a * (gfc.numlines_l[b - 1] + gfc.numlines_l[b] - + gfc.numlines_l[b + 1] - 1)); - var k = 0 | a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - } - assert(b > 0); - assert(b == gfc.npart_l - 1); - - a = avg[b - 1] + avg[b]; - assert(a >= 0); - if (a > 0.0) { - var m = max[b - 1]; - if (m < max[b]) - m = max[b]; - assert((gfc.numlines_l[b - 1] + gfc.numlines_l[b] - 1) > 0); - a = 20.0 * (m * 2.0 - a) - / (a * (gfc.numlines_l[b - 1] + gfc.numlines_l[b] - 1)); - var k = 0 | a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - assert(b == (gfc.npart_l - 1)); - } - - var fircoef = [ - -8.65163e-18 * 2, -0.00851586 * 2, -6.74764e-18 * 2, 0.0209036 * 2, - -3.36639e-17 * 2, -0.0438162 * 2, -1.54175e-17 * 2, 0.0931738 * 2, - -5.52212e-17 * 2, -0.313819 * 2 - ]; - - this.L3psycho_anal_ns = function (gfp, buffer, bufPos, gr_out, masking_ratio, masking_MS_ratio, percep_entropy, percep_MS_entropy, energy, blocktype_d) { - /* - * to get a good cache performance, one has to think about the sequence, - * in which the variables are used. - */ - var gfc = gfp.internal_flags; - - /* fft and energy calculation */ - var wsamp_L = new_float_n([2, Encoder.BLKSIZE]); - var wsamp_S = new_float_n([2, 3, Encoder.BLKSIZE_s]); - - /* convolution */ - var eb_l = new_float(Encoder.CBANDS + 1); - var eb_s = new_float(Encoder.CBANDS + 1); - var thr = new_float(Encoder.CBANDS + 2); - - /* block type */ - var blocktype = new_int(2), uselongblock = new_int(2); - - /* usual variables like loop indices, etc.. */ - var numchn, chn; - var b, i, j, k; - var sb, sblock; - - /* variables used for --nspsytune */ - var ns_hpfsmpl = new_float_n([2, 576]); - var pcfact; - var mask_idx_l = new_int(Encoder.CBANDS + 2), mask_idx_s = new_int(Encoder.CBANDS + 2); - - Arrays.fill(mask_idx_s, 0); - - numchn = gfc.channels_out; - /* chn=2 and 3 = Mid and Side channels */ - if (gfp.mode == MPEGMode.JOINT_STEREO) - numchn = 4; - - if (gfp.VBR == VbrMode.vbr_off) - pcfact = gfc.ResvMax == 0 ? 0 : ( gfc.ResvSize) - / gfc.ResvMax * 0.5; - else if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh - || gfp.VBR == VbrMode.vbr_mt) { - pcfact = 0.6; - } else - pcfact = 1.0; - - /********************************************************************** - * Apply HPF of fs/4 to the input signal. This is used for attack - * detection / handling. - **********************************************************************/ - /* Don't copy the input buffer into a temporary buffer */ - /* unroll the loop 2 times */ - for (chn = 0; chn < gfc.channels_out; chn++) { - /* apply high pass filter of fs/4 */ - var firbuf = buffer[chn]; - var firbufPos = bufPos + 576 - 350 - NSFIRLEN + 192; - assert(fircoef.length == ((NSFIRLEN - 1) / 2)); - for (i = 0; i < 576; i++) { - var sum1, sum2; - sum1 = firbuf[firbufPos + i + 10]; - sum2 = 0.0; - for (j = 0; j < ((NSFIRLEN - 1) / 2) - 1; j += 2) { - sum1 += fircoef[j] - * (firbuf[firbufPos + i + j] + firbuf[firbufPos + i - + NSFIRLEN - j]); - sum2 += fircoef[j + 1] - * (firbuf[firbufPos + i + j + 1] + firbuf[firbufPos - + i + NSFIRLEN - j - 1]); - } - ns_hpfsmpl[chn][i] = sum1 + sum2; - } - masking_ratio[gr_out][chn].en.assign(gfc.en[chn]); - masking_ratio[gr_out][chn].thm.assign(gfc.thm[chn]); - if (numchn > 2) { - /* MS maskings */ - /* percep_MS_entropy [chn-2] = gfc . pe [chn]; */ - masking_MS_ratio[gr_out][chn].en.assign(gfc.en[chn + 2]); - masking_MS_ratio[gr_out][chn].thm.assign(gfc.thm[chn + 2]); - } - } - - for (chn = 0; chn < numchn; chn++) { - var wsamp_l; - var wsamp_s; - var en_subshort = new_float(12); - var en_short = [0, 0, 0, 0]; - var attack_intensity = new_float(12); - var ns_uselongblock = 1; - var attackThreshold; - var max = new_float(Encoder.CBANDS), avg = new_float(Encoder.CBANDS); - var ns_attacks = [0, 0, 0, 0]; - var fftenergy = new_float(Encoder.HBLKSIZE); - var fftenergy_s = new_float_n([3, Encoder.HBLKSIZE_s]); - - /* - * rh 20040301: the following loops do access one off the limits so - * I increase the array dimensions by one and initialize the - * accessed values to zero - */ - assert(gfc.npart_s <= Encoder.CBANDS); - assert(gfc.npart_l <= Encoder.CBANDS); - - /*************************************************************** - * determine the block type (window type) - ***************************************************************/ - /* calculate energies of each sub-shortblocks */ - for (i = 0; i < 3; i++) { - en_subshort[i] = gfc.nsPsy.last_en_subshort[chn][i + 6]; - assert(gfc.nsPsy.last_en_subshort[chn][i + 4] > 0); - attack_intensity[i] = en_subshort[i] - / gfc.nsPsy.last_en_subshort[chn][i + 4]; - en_short[0] += en_subshort[i]; - } - - if (chn == 2) { - for (i = 0; i < 576; i++) { - var l, r; - l = ns_hpfsmpl[0][i]; - r = ns_hpfsmpl[1][i]; - ns_hpfsmpl[0][i] = l + r; - ns_hpfsmpl[1][i] = l - r; - } - } - { - var pf = ns_hpfsmpl[chn & 1]; - var pfPos = 0; - for (i = 0; i < 9; i++) { - var pfe = pfPos + 576 / 9; - var p = 1.; - for (; pfPos < pfe; pfPos++) - if (p < Math.abs(pf[pfPos])) - p = Math.abs(pf[pfPos]); - - gfc.nsPsy.last_en_subshort[chn][i] = en_subshort[i + 3] = p; - en_short[1 + i / 3] += p; - if (p > en_subshort[i + 3 - 2]) { - assert(en_subshort[i + 3 - 2] > 0); - p = p / en_subshort[i + 3 - 2]; - } else if (en_subshort[i + 3 - 2] > p * 10.0) { - assert(p > 0); - p = en_subshort[i + 3 - 2] / (p * 10.0); - } else - p = 0.0; - attack_intensity[i + 3] = p; - } - } - - if (gfp.analysis) { - var x = attack_intensity[0]; - for (i = 1; i < 12; i++) - if (x < attack_intensity[i]) - x = attack_intensity[i]; - gfc.pinfo.ers[gr_out][chn] = gfc.pinfo.ers_save[chn]; - gfc.pinfo.ers_save[chn] = x; - } - - /* compare energies between sub-shortblocks */ - attackThreshold = (chn == 3) ? gfc.nsPsy.attackthre_s - : gfc.nsPsy.attackthre; - for (i = 0; i < 12; i++) - if (0 == ns_attacks[i / 3] - && attack_intensity[i] > attackThreshold) - ns_attacks[i / 3] = (i % 3) + 1; - - /* - * should have energy change between short blocks, in order to avoid - * periodic signals - */ - for (i = 1; i < 4; i++) { - var ratio; - if (en_short[i - 1] > en_short[i]) { - assert(en_short[i] > 0); - ratio = en_short[i - 1] / en_short[i]; - } else { - assert(en_short[i - 1] > 0); - ratio = en_short[i] / en_short[i - 1]; - } - if (ratio < 1.7) { - ns_attacks[i] = 0; - if (i == 1) - ns_attacks[0] = 0; - } - } - - if (ns_attacks[0] != 0 && gfc.nsPsy.lastAttacks[chn] != 0) - ns_attacks[0] = 0; - - if (gfc.nsPsy.lastAttacks[chn] == 3 - || (ns_attacks[0] + ns_attacks[1] + ns_attacks[2] + ns_attacks[3]) != 0) { - ns_uselongblock = 0; - - if (ns_attacks[1] != 0 && ns_attacks[0] != 0) - ns_attacks[1] = 0; - if (ns_attacks[2] != 0 && ns_attacks[1] != 0) - ns_attacks[2] = 0; - if (ns_attacks[3] != 0 && ns_attacks[2] != 0) - ns_attacks[3] = 0; - } - - if (chn < 2) { - uselongblock[chn] = ns_uselongblock; - } else { - if (ns_uselongblock == 0) { - uselongblock[0] = uselongblock[1] = 0; - } - } - - /* - * there is a one granule delay. Copy maskings computed last call - * into masking_ratio to return to calling program. - */ - energy[chn] = gfc.tot_ener[chn]; - - /********************************************************************* - * compute FFTs - *********************************************************************/ - wsamp_s = wsamp_S; - wsamp_l = wsamp_L; - compute_ffts(gfp, fftenergy, fftenergy_s, wsamp_l, (chn & 1), - wsamp_s, (chn & 1), gr_out, chn, buffer, bufPos); - - /********************************************************************* - * Calculate the energy and the tonality of each partition. - *********************************************************************/ - calc_energy(gfc, fftenergy, eb_l, max, avg); - calc_mask_index_l(gfc, max, avg, mask_idx_l); - /* compute masking thresholds for short blocks */ - for (sblock = 0; sblock < 3; sblock++) { - var enn, thmm; - compute_masking_s(gfp, fftenergy_s, eb_s, thr, chn, sblock); - convert_partition2scalefac_s(gfc, eb_s, thr, chn, sblock); - /**** short block pre-echo control ****/ - for (sb = 0; sb < Encoder.SBMAX_s; sb++) { - thmm = gfc.thm[chn].s[sb][sblock]; - - thmm *= NS_PREECHO_ATT0; - if (ns_attacks[sblock] >= 2 || ns_attacks[sblock + 1] == 1) { - var idx = (sblock != 0) ? sblock - 1 : 2; - var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT1 * pcfact); - thmm = Math.min(thmm, p); - } - - if (ns_attacks[sblock] == 1) { - var idx = (sblock != 0) ? sblock - 1 : 2; - var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT2 * pcfact); - thmm = Math.min(thmm, p); - } else if ((sblock != 0 && ns_attacks[sblock - 1] == 3) - || (sblock == 0 && gfc.nsPsy.lastAttacks[chn] == 3)) { - var idx = (sblock != 2) ? sblock + 1 : 0; - var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT2 * pcfact); - thmm = Math.min(thmm, p); - } - - /* pulse like signal detection for fatboy.wav and so on */ - enn = en_subshort[sblock * 3 + 3] - + en_subshort[sblock * 3 + 4] - + en_subshort[sblock * 3 + 5]; - if (en_subshort[sblock * 3 + 5] * 6 < enn) { - thmm *= 0.5; - if (en_subshort[sblock * 3 + 4] * 6 < enn) - thmm *= 0.5; - } - - gfc.thm[chn].s[sb][sblock] = thmm; - } - } - gfc.nsPsy.lastAttacks[chn] = ns_attacks[2]; - - /********************************************************************* - * convolve the partitioned energy and unpredictability with the - * spreading function, s3_l[b][k] - ********************************************************************/ - k = 0; - { - for (b = 0; b < gfc.npart_l; b++) { - /* - * convolve the partitioned energy with the spreading - * function - */ - var kk = gfc.s3ind[b][0]; - var eb2 = eb_l[kk] * tab[mask_idx_l[kk]]; - var ecb = gfc.s3_ll[k++] * eb2; - while (++kk <= gfc.s3ind[b][1]) { - eb2 = eb_l[kk] * tab[mask_idx_l[kk]]; - ecb = mask_add(ecb, gfc.s3_ll[k++] * eb2, kk, kk - b, - gfc, 0); - } - ecb *= 0.158489319246111; - /* pow(10,-0.8) */ - - /**** long block pre-echo control ****/ - /** - *
-                     * dont use long block pre-echo control if previous granule was
-                     * a short block.  This is to avoid the situation:
-                     * frame0:  quiet (very low masking)
-                     * frame1:  surge  (triggers short blocks)
-                     * frame2:  regular frame.  looks like pre-echo when compared to
-                     *          frame0, but all pre-echo was in frame1.
-                     * 
- */ - /* - * chn=0,1 L and R channels - * - * chn=2,3 S and M channels. - */ - - if (gfc.blocktype_old[chn & 1] == Encoder.SHORT_TYPE) - thr[b] = ecb; - else - thr[b] = NS_INTERP( - Math.min(ecb, Math.min(rpelev - * gfc.nb_1[chn][b], rpelev2 - * gfc.nb_2[chn][b])), ecb, pcfact); - - gfc.nb_2[chn][b] = gfc.nb_1[chn][b]; - gfc.nb_1[chn][b] = ecb; - } - } - for (; b <= Encoder.CBANDS; ++b) { - eb_l[b] = 0; - thr[b] = 0; - } - /* compute masking thresholds for long blocks */ - convert_partition2scalefac_l(gfc, eb_l, thr, chn); - } - /* end loop over chn */ - - if (gfp.mode == MPEGMode.STEREO || gfp.mode == MPEGMode.JOINT_STEREO) { - if (gfp.interChRatio > 0.0) { - calc_interchannel_masking(gfp, gfp.interChRatio); - } - } - - if (gfp.mode == MPEGMode.JOINT_STEREO) { - var msfix; - msfix1(gfc); - msfix = gfp.msfix; - if (Math.abs(msfix) > 0.0) - ns_msfix(gfc, msfix, gfp.ATHlower * gfc.ATH.adjust); - } - - /*************************************************************** - * determine final block type - ***************************************************************/ - block_type_set(gfp, uselongblock, blocktype_d, blocktype); - - /********************************************************************* - * compute the value of PE to return ... no delay and advance - *********************************************************************/ - for (chn = 0; chn < numchn; chn++) { - var ppe; - var ppePos = 0; - var type; - var mr; - - if (chn > 1) { - ppe = percep_MS_entropy; - ppePos = -2; - type = Encoder.NORM_TYPE; - if (blocktype_d[0] == Encoder.SHORT_TYPE - || blocktype_d[1] == Encoder.SHORT_TYPE) - type = Encoder.SHORT_TYPE; - mr = masking_MS_ratio[gr_out][chn - 2]; - } else { - ppe = percep_entropy; - ppePos = 0; - type = blocktype_d[chn]; - mr = masking_ratio[gr_out][chn]; - } - - if (type == Encoder.SHORT_TYPE) - ppe[ppePos + chn] = pecalc_s(mr, gfc.masking_lower); - else - ppe[ppePos + chn] = pecalc_l(mr, gfc.masking_lower); - - if (gfp.analysis) - gfc.pinfo.pe[gr_out][chn] = ppe[ppePos + chn]; - - } - return 0; - } - - function vbrpsy_compute_fft_l(gfp, buffer, bufPos, chn, gr_out, fftenergy, wsamp_l, wsamp_lPos) { - var gfc = gfp.internal_flags; - if (chn < 2) { - fft.fft_long(gfc, wsamp_l[wsamp_lPos], chn, buffer, bufPos); - } else if (chn == 2) { - /* FFT data for mid and side channel is derived from L & R */ - for (var j = Encoder.BLKSIZE - 1; j >= 0; --j) { - var l = wsamp_l[wsamp_lPos + 0][j]; - var r = wsamp_l[wsamp_lPos + 1][j]; - wsamp_l[wsamp_lPos + 0][j] = (l + r) * Util.SQRT2 * 0.5; - wsamp_l[wsamp_lPos + 1][j] = (l - r) * Util.SQRT2 * 0.5; - } - } - - /********************************************************************* - * compute energies - *********************************************************************/ - fftenergy[0] = NON_LINEAR_SCALE_ENERGY(wsamp_l[wsamp_lPos + 0][0]); - fftenergy[0] *= fftenergy[0]; - - for (var j = Encoder.BLKSIZE / 2 - 1; j >= 0; --j) { - var re = wsamp_l[wsamp_lPos + 0][Encoder.BLKSIZE / 2 - j]; - var im = wsamp_l[wsamp_lPos + 0][Encoder.BLKSIZE / 2 + j]; - fftenergy[Encoder.BLKSIZE / 2 - j] = NON_LINEAR_SCALE_ENERGY((re - * re + im * im) * 0.5); - } - /* total energy */ - { - var totalenergy = 0.0; - for (var j = 11; j < Encoder.HBLKSIZE; j++) - totalenergy += fftenergy[j]; - - gfc.tot_ener[chn] = totalenergy; - } - - if (gfp.analysis) { - for (var j = 0; j < Encoder.HBLKSIZE; j++) { - gfc.pinfo.energy[gr_out][chn][j] = gfc.pinfo.energy_save[chn][j]; - gfc.pinfo.energy_save[chn][j] = fftenergy[j]; - } - gfc.pinfo.pe[gr_out][chn] = gfc.pe[chn]; - } - } - - function vbrpsy_compute_fft_s(gfp, buffer, bufPos, chn, sblock, fftenergy_s, wsamp_s, wsamp_sPos) { - var gfc = gfp.internal_flags; - - if (sblock == 0 && chn < 2) { - fft.fft_short(gfc, wsamp_s[wsamp_sPos], chn, buffer, bufPos); - } - if (chn == 2) { - /* FFT data for mid and side channel is derived from L & R */ - for (var j = Encoder.BLKSIZE_s - 1; j >= 0; --j) { - var l = wsamp_s[wsamp_sPos + 0][sblock][j]; - var r = wsamp_s[wsamp_sPos + 1][sblock][j]; - wsamp_s[wsamp_sPos + 0][sblock][j] = (l + r) * Util.SQRT2 * 0.5; - wsamp_s[wsamp_sPos + 1][sblock][j] = (l - r) * Util.SQRT2 * 0.5; - } - } - - /********************************************************************* - * compute energies - *********************************************************************/ - fftenergy_s[sblock][0] = wsamp_s[wsamp_sPos + 0][sblock][0]; - fftenergy_s[sblock][0] *= fftenergy_s[sblock][0]; - for (var j = Encoder.BLKSIZE_s / 2 - 1; j >= 0; --j) { - var re = wsamp_s[wsamp_sPos + 0][sblock][Encoder.BLKSIZE_s / 2 - j]; - var im = wsamp_s[wsamp_sPos + 0][sblock][Encoder.BLKSIZE_s / 2 + j]; - fftenergy_s[sblock][Encoder.BLKSIZE_s / 2 - j] = NON_LINEAR_SCALE_ENERGY((re - * re + im * im) * 0.5); - } - } - - /** - * compute loudness approximation (used for ATH auto-level adjustment) - */ - function vbrpsy_compute_loudness_approximation_l(gfp, gr_out, chn, fftenergy) { - var gfc = gfp.internal_flags; - if (gfp.athaa_loudapprox == 2 && chn < 2) { - // no loudness for mid/side ch - gfc.loudness_sq[gr_out][chn] = gfc.loudness_sq_save[chn]; - gfc.loudness_sq_save[chn] = psycho_loudness_approx(fftenergy, gfc); - } - } - - var fircoef_ = [-8.65163e-18 * 2, - -0.00851586 * 2, -6.74764e-18 * 2, 0.0209036 * 2, - -3.36639e-17 * 2, -0.0438162 * 2, -1.54175e-17 * 2, - 0.0931738 * 2, -5.52212e-17 * 2, -0.313819 * 2]; - - /** - * Apply HPF of fs/4 to the input signal. This is used for attack detection - * / handling. - */ - function vbrpsy_attack_detection(gfp, buffer, bufPos, gr_out, masking_ratio, masking_MS_ratio, energy, sub_short_factor, ns_attacks, uselongblock) { - var ns_hpfsmpl = new_float_n([2, 576]); - var gfc = gfp.internal_flags; - var n_chn_out = gfc.channels_out; - /* chn=2 and 3 = Mid and Side channels */ - var n_chn_psy = (gfp.mode == MPEGMode.JOINT_STEREO) ? 4 : n_chn_out; - /* Don't copy the input buffer into a temporary buffer */ - /* unroll the loop 2 times */ - for (var chn = 0; chn < n_chn_out; chn++) { - /* apply high pass filter of fs/4 */ - firbuf = buffer[chn]; - var firbufPos = bufPos + 576 - 350 - NSFIRLEN + 192; - assert(fircoef_.length == ((NSFIRLEN - 1) / 2)); - for (var i = 0; i < 576; i++) { - var sum1, sum2; - sum1 = firbuf[firbufPos + i + 10]; - sum2 = 0.0; - for (var j = 0; j < ((NSFIRLEN - 1) / 2) - 1; j += 2) { - sum1 += fircoef_[j] - * (firbuf[firbufPos + i + j] + firbuf[firbufPos + i - + NSFIRLEN - j]); - sum2 += fircoef_[j + 1] - * (firbuf[firbufPos + i + j + 1] + firbuf[firbufPos - + i + NSFIRLEN - j - 1]); - } - ns_hpfsmpl[chn][i] = sum1 + sum2; - } - masking_ratio[gr_out][chn].en.assign(gfc.en[chn]); - masking_ratio[gr_out][chn].thm.assign(gfc.thm[chn]); - if (n_chn_psy > 2) { - /* MS maskings */ - /* percep_MS_entropy [chn-2] = gfc . pe [chn]; */ - masking_MS_ratio[gr_out][chn].en.assign(gfc.en[chn + 2]); - masking_MS_ratio[gr_out][chn].thm.assign(gfc.thm[chn + 2]); - } - } - for (var chn = 0; chn < n_chn_psy; chn++) { - var attack_intensity = new_float(12); - var en_subshort = new_float(12); - var en_short = [0, 0, 0, 0]; - var pf = ns_hpfsmpl[chn & 1]; - var pfPos = 0; - var attackThreshold = (chn == 3) ? gfc.nsPsy.attackthre_s - : gfc.nsPsy.attackthre; - var ns_uselongblock = 1; - - if (chn == 2) { - for (var i = 0, j = 576; j > 0; ++i, --j) { - var l = ns_hpfsmpl[0][i]; - var r = ns_hpfsmpl[1][i]; - ns_hpfsmpl[0][i] = l + r; - ns_hpfsmpl[1][i] = l - r; - } - } - /*************************************************************** - * determine the block type (window type) - ***************************************************************/ - /* calculate energies of each sub-shortblocks */ - for (var i = 0; i < 3; i++) { - en_subshort[i] = gfc.nsPsy.last_en_subshort[chn][i + 6]; - assert(gfc.nsPsy.last_en_subshort[chn][i + 4] > 0); - attack_intensity[i] = en_subshort[i] - / gfc.nsPsy.last_en_subshort[chn][i + 4]; - en_short[0] += en_subshort[i]; - } - - for (var i = 0; i < 9; i++) { - var pfe = pfPos + 576 / 9; - var p = 1.; - for (; pfPos < pfe; pfPos++) - if (p < Math.abs(pf[pfPos])) - p = Math.abs(pf[pfPos]); - - gfc.nsPsy.last_en_subshort[chn][i] = en_subshort[i + 3] = p; - en_short[1 + i / 3] += p; - if (p > en_subshort[i + 3 - 2]) { - assert(en_subshort[i + 3 - 2] > 0); - p = p / en_subshort[i + 3 - 2]; - } else if (en_subshort[i + 3 - 2] > p * 10.0) { - assert(p > 0); - p = en_subshort[i + 3 - 2] / (p * 10.0); - } else { - p = 0.0; - } - attack_intensity[i + 3] = p; - } - /* pulse like signal detection for fatboy.wav and so on */ - for (var i = 0; i < 3; ++i) { - var enn = en_subshort[i * 3 + 3] - + en_subshort[i * 3 + 4] + en_subshort[i * 3 + 5]; - var factor = 1.; - if (en_subshort[i * 3 + 5] * 6 < enn) { - factor *= 0.5; - if (en_subshort[i * 3 + 4] * 6 < enn) { - factor *= 0.5; - } - } - sub_short_factor[chn][i] = factor; - } - - if (gfp.analysis) { - var x = attack_intensity[0]; - for (var i = 1; i < 12; i++) { - if (x < attack_intensity[i]) { - x = attack_intensity[i]; - } - } - gfc.pinfo.ers[gr_out][chn] = gfc.pinfo.ers_save[chn]; - gfc.pinfo.ers_save[chn] = x; - } - - /* compare energies between sub-shortblocks */ - for (var i = 0; i < 12; i++) { - if (0 == ns_attacks[chn][i / 3] - && attack_intensity[i] > attackThreshold) { - ns_attacks[chn][i / 3] = (i % 3) + 1; - } - } - - /* - * should have energy change between short blocks, in order to avoid - * periodic signals - */ - /* Good samples to show the effect are Trumpet test songs */ - /* - * GB: tuned (1) to avoid too many short blocks for test sample - * TRUMPET - */ - /* - * RH: tuned (2) to let enough short blocks through for test sample - * FSOL and SNAPS - */ - for (var i = 1; i < 4; i++) { - var u = en_short[i - 1]; - var v = en_short[i]; - var m = Math.max(u, v); - if (m < 40000) { /* (2) */ - if (u < 1.7 * v && v < 1.7 * u) { /* (1) */ - if (i == 1 && ns_attacks[chn][0] <= ns_attacks[chn][i]) { - ns_attacks[chn][0] = 0; - } - ns_attacks[chn][i] = 0; - } - } - } - - if (ns_attacks[chn][0] <= gfc.nsPsy.lastAttacks[chn]) { - ns_attacks[chn][0] = 0; - } - - if (gfc.nsPsy.lastAttacks[chn] == 3 - || (ns_attacks[chn][0] + ns_attacks[chn][1] - + ns_attacks[chn][2] + ns_attacks[chn][3]) != 0) { - ns_uselongblock = 0; - - if (ns_attacks[chn][1] != 0 && ns_attacks[chn][0] != 0) { - ns_attacks[chn][1] = 0; - } - if (ns_attacks[chn][2] != 0 && ns_attacks[chn][1] != 0) { - ns_attacks[chn][2] = 0; - } - if (ns_attacks[chn][3] != 0 && ns_attacks[chn][2] != 0) { - ns_attacks[chn][3] = 0; - } - } - if (chn < 2) { - uselongblock[chn] = ns_uselongblock; - } else { - if (ns_uselongblock == 0) { - uselongblock[0] = uselongblock[1] = 0; - } - } - - /* - * there is a one granule delay. Copy maskings computed last call - * into masking_ratio to return to calling program. - */ - energy[chn] = gfc.tot_ener[chn]; - } - } - - function vbrpsy_skip_masking_s(gfc, chn, sblock) { - if (sblock == 0) { - for (var b = 0; b < gfc.npart_s; b++) { - gfc.nb_s2[chn][b] = gfc.nb_s1[chn][b]; - gfc.nb_s1[chn][b] = 0; - } - } - } - - function vbrpsy_skip_masking_l(gfc, chn) { - for (var b = 0; b < gfc.npart_l; b++) { - gfc.nb_2[chn][b] = gfc.nb_1[chn][b]; - gfc.nb_1[chn][b] = 0; - } - } - - function psyvbr_calc_mask_index_s(gfc, max, avg, mask_idx) { - var last_tab_entry = tab.length - 1; - var b = 0; - var a = avg[b] + avg[b + 1]; - assert(a >= 0); - if (a > 0.0) { - var m = max[b]; - if (m < max[b + 1]) - m = max[b + 1]; - assert((gfc.numlines_s[b] + gfc.numlines_s[b + 1] - 1) > 0); - a = 20.0 * (m * 2.0 - a) - / (a * (gfc.numlines_s[b] + gfc.numlines_s[b + 1] - 1)); - var k = 0 | a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - - for (b = 1; b < gfc.npart_s - 1; b++) { - a = avg[b - 1] + avg[b] + avg[b + 1]; - assert(b + 1 < gfc.npart_s); - assert(a >= 0); - if (a > 0.0) { - var m = max[b - 1]; - if (m < max[b]) - m = max[b]; - if (m < max[b + 1]) - m = max[b + 1]; - assert((gfc.numlines_s[b - 1] + gfc.numlines_s[b] + gfc.numlines_s[b + 1] - 1) > 0); - a = 20.0 - * (m * 3.0 - a) - / (a * (gfc.numlines_s[b - 1] + gfc.numlines_s[b] - + gfc.numlines_s[b + 1] - 1)); - var k = 0 | a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - } - assert(b > 0); - assert(b == gfc.npart_s - 1); - - a = avg[b - 1] + avg[b]; - assert(a >= 0); - if (a > 0.0) { - var m = max[b - 1]; - if (m < max[b]) - m = max[b]; - assert((gfc.numlines_s[b - 1] + gfc.numlines_s[b] - 1) > 0); - a = 20.0 * (m * 2.0 - a) - / (a * (gfc.numlines_s[b - 1] + gfc.numlines_s[b] - 1)); - var k = 0 | a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - assert(b == (gfc.npart_s - 1)); - } - - function vbrpsy_compute_masking_s(gfp, fftenergy_s, eb, thr, chn, sblock) { - var gfc = gfp.internal_flags; - var max = new float[Encoder.CBANDS], avg = new_float(Encoder.CBANDS); - var i, j, b; - var mask_idx_s = new int[Encoder.CBANDS]; - - for (b = j = 0; b < gfc.npart_s; ++b) { - var ebb = 0, m = 0; - var n = gfc.numlines_s[b]; - for (i = 0; i < n; ++i, ++j) { - var el = fftenergy_s[sblock][j]; - ebb += el; - if (m < el) - m = el; - } - eb[b] = ebb; - assert(ebb >= 0); - max[b] = m; - assert(n > 0); - avg[b] = ebb / n; - assert(avg[b] >= 0); - } - assert(b == gfc.npart_s); - assert(j == 129); - for (; b < Encoder.CBANDS; ++b) { - max[b] = 0; - avg[b] = 0; - } - psyvbr_calc_mask_index_s(gfc, max, avg, mask_idx_s); - for (j = b = 0; b < gfc.npart_s; b++) { - var kk = gfc.s3ind_s[b][0]; - var last = gfc.s3ind_s[b][1]; - var dd, dd_n; - var x, ecb, avg_mask; - dd = mask_idx_s[kk]; - dd_n = 1; - ecb = gfc.s3_ss[j] * eb[kk] * tab[mask_idx_s[kk]]; - ++j; - ++kk; - while (kk <= last) { - dd += mask_idx_s[kk]; - dd_n += 1; - x = gfc.s3_ss[j] * eb[kk] * tab[mask_idx_s[kk]]; - ecb = vbrpsy_mask_add(ecb, x, kk - b); - ++j; - ++kk; - } - dd = (1 + 2 * dd) / (2 * dd_n); - avg_mask = tab[dd] * 0.5; - ecb *= avg_mask; - thr[b] = ecb; - gfc.nb_s2[chn][b] = gfc.nb_s1[chn][b]; - gfc.nb_s1[chn][b] = ecb; - { - /* - * if THR exceeds EB, the quantization routines will take the - * difference from other bands. in case of strong tonal samples - * (tonaltest.wav) this leads to heavy distortions. that's why - * we limit THR here. - */ - x = max[b]; - x *= gfc.minval_s[b]; - x *= avg_mask; - if (thr[b] > x) { - thr[b] = x; - } - } - if (gfc.masking_lower > 1) { - thr[b] *= gfc.masking_lower; - } - if (thr[b] > eb[b]) { - thr[b] = eb[b]; - } - if (gfc.masking_lower < 1) { - thr[b] *= gfc.masking_lower; - } - - assert(thr[b] >= 0); - } - for (; b < Encoder.CBANDS; ++b) { - eb[b] = 0; - thr[b] = 0; - } - } - - function vbrpsy_compute_masking_l(gfc, fftenergy, eb_l, thr, chn) { - var max = new_float(Encoder.CBANDS), avg = new_float(Encoder.CBANDS); - var mask_idx_l = new_int(Encoder.CBANDS + 2); - var b; - - /********************************************************************* - * Calculate the energy and the tonality of each partition. - *********************************************************************/ - calc_energy(gfc, fftenergy, eb_l, max, avg); - calc_mask_index_l(gfc, max, avg, mask_idx_l); - - /********************************************************************* - * convolve the partitioned energy and unpredictability with the - * spreading function, s3_l[b][k] - ********************************************************************/ - var k = 0; - for (b = 0; b < gfc.npart_l; b++) { - var x, ecb, avg_mask, t; - /* convolve the partitioned energy with the spreading function */ - var kk = gfc.s3ind[b][0]; - var last = gfc.s3ind[b][1]; - var dd = 0, dd_n = 0; - dd = mask_idx_l[kk]; - dd_n += 1; - ecb = gfc.s3_ll[k] * eb_l[kk] * tab[mask_idx_l[kk]]; - ++k; - ++kk; - while (kk <= last) { - dd += mask_idx_l[kk]; - dd_n += 1; - x = gfc.s3_ll[k] * eb_l[kk] * tab[mask_idx_l[kk]]; - t = vbrpsy_mask_add(ecb, x, kk - b); - ecb = t; - ++k; - ++kk; - } - dd = (1 + 2 * dd) / (2 * dd_n); - avg_mask = tab[dd] * 0.5; - ecb *= avg_mask; - - /**** long block pre-echo control ****/ - /** - *
-             * dont use long block pre-echo control if previous granule was
-             * a short block.  This is to avoid the situation:
-             * frame0:  quiet (very low masking)
-             * frame1:  surge  (triggers short blocks)
-             * frame2:  regular frame.  looks like pre-echo when compared to
-             *          frame0, but all pre-echo was in frame1.
-             * 
- */ - /* - * chn=0,1 L and R channels chn=2,3 S and M channels. - */ - if (gfc.blocktype_old[chn & 0x01] == Encoder.SHORT_TYPE) { - var ecb_limit = rpelev * gfc.nb_1[chn][b]; - if (ecb_limit > 0) { - thr[b] = Math.min(ecb, ecb_limit); - } else { - /** - *
-                     * Robert 071209:
-                     * Because we don't calculate long block psy when we know a granule
-                     * should be of short blocks, we don't have any clue how the granule
-                     * before would have looked like as a long block. So we have to guess
-                     * a little bit for this END_TYPE block.
-                     * Most of the time we get away with this sloppyness. (fingers crossed :)
-                     * The speed increase is worth it.
-                     * 
- */ - thr[b] = Math.min(ecb, eb_l[b] * NS_PREECHO_ATT2); - } - } else { - var ecb_limit_2 = rpelev2 * gfc.nb_2[chn][b]; - var ecb_limit_1 = rpelev * gfc.nb_1[chn][b]; - var ecb_limit; - if (ecb_limit_2 <= 0) { - ecb_limit_2 = ecb; - } - if (ecb_limit_1 <= 0) { - ecb_limit_1 = ecb; - } - if (gfc.blocktype_old[chn & 0x01] == Encoder.NORM_TYPE) { - ecb_limit = Math.min(ecb_limit_1, ecb_limit_2); - } else { - ecb_limit = ecb_limit_1; - } - thr[b] = Math.min(ecb, ecb_limit); - } - gfc.nb_2[chn][b] = gfc.nb_1[chn][b]; - gfc.nb_1[chn][b] = ecb; - { - /* - * if THR exceeds EB, the quantization routines will take the - * difference from other bands. in case of strong tonal samples - * (tonaltest.wav) this leads to heavy distortions. that's why - * we limit THR here. - */ - x = max[b]; - x *= gfc.minval_l[b]; - x *= avg_mask; - if (thr[b] > x) { - thr[b] = x; - } - } - if (gfc.masking_lower > 1) { - thr[b] *= gfc.masking_lower; - } - if (thr[b] > eb_l[b]) { - thr[b] = eb_l[b]; - } - if (gfc.masking_lower < 1) { - thr[b] *= gfc.masking_lower; - } - assert(thr[b] >= 0); - } - for (; b < Encoder.CBANDS; ++b) { - eb_l[b] = 0; - thr[b] = 0; - } - } - - function vbrpsy_compute_block_type(gfp, uselongblock) { - var gfc = gfp.internal_flags; - - if (gfp.short_blocks == ShortBlock.short_block_coupled - /* force both channels to use the same block type */ - /* this is necessary if the frame is to be encoded in ms_stereo. */ - /* But even without ms_stereo, FhG does this */ - && !(uselongblock[0] != 0 && uselongblock[1] != 0)) - uselongblock[0] = uselongblock[1] = 0; - - for (var chn = 0; chn < gfc.channels_out; chn++) { - /* disable short blocks */ - if (gfp.short_blocks == ShortBlock.short_block_dispensed) { - uselongblock[chn] = 1; - } - if (gfp.short_blocks == ShortBlock.short_block_forced) { - uselongblock[chn] = 0; - } - } - } - - function vbrpsy_apply_block_type(gfp, uselongblock, blocktype_d) { - var gfc = gfp.internal_flags; - - /* - * update the blocktype of the previous granule, since it depends on - * what happend in this granule - */ - for (var chn = 0; chn < gfc.channels_out; chn++) { - var blocktype = Encoder.NORM_TYPE; - /* disable short blocks */ - - if (uselongblock[chn] != 0) { - /* no attack : use long blocks */ - assert(gfc.blocktype_old[chn] != Encoder.START_TYPE); - if (gfc.blocktype_old[chn] == Encoder.SHORT_TYPE) - blocktype = Encoder.STOP_TYPE; - } else { - /* attack : use short blocks */ - blocktype = Encoder.SHORT_TYPE; - if (gfc.blocktype_old[chn] == Encoder.NORM_TYPE) { - gfc.blocktype_old[chn] = Encoder.START_TYPE; - } - if (gfc.blocktype_old[chn] == Encoder.STOP_TYPE) - gfc.blocktype_old[chn] = Encoder.SHORT_TYPE; - } - - blocktype_d[chn] = gfc.blocktype_old[chn]; - // value returned to calling program - gfc.blocktype_old[chn] = blocktype; - // save for next call to l3psy_anal - } - } - - /** - * compute M/S thresholds from Johnston & Ferreira 1992 ICASSP paper - */ - function vbrpsy_compute_MS_thresholds(eb, thr, cb_mld, ath_cb, athadjust, msfix, n) { - var msfix2 = msfix * 2; - var athlower = msfix > 0 ? Math.pow(10, athadjust) : 1; - var rside, rmid; - for (var b = 0; b < n; ++b) { - var ebM = eb[2][b]; - var ebS = eb[3][b]; - var thmL = thr[0][b]; - var thmR = thr[1][b]; - var thmM = thr[2][b]; - var thmS = thr[3][b]; - - /* use this fix if L & R masking differs by 2db or less */ - if (thmL <= 1.58 * thmR && thmR <= 1.58 * thmL) { - var mld_m = cb_mld[b] * ebS; - var mld_s = cb_mld[b] * ebM; - rmid = Math.max(thmM, Math.min(thmS, mld_m)); - rside = Math.max(thmS, Math.min(thmM, mld_s)); - } else { - rmid = thmM; - rside = thmS; - } - if (msfix > 0) { - /***************************************************************/ - /* Adjust M/S maskings if user set "msfix" */ - /***************************************************************/ - /* Naoki Shibata 2000 */ - var thmLR, thmMS; - var ath = ath_cb[b] * athlower; - thmLR = Math.min(Math.max(thmL, ath), Math.max(thmR, ath)); - thmM = Math.max(rmid, ath); - thmS = Math.max(rside, ath); - thmMS = thmM + thmS; - if (thmMS > 0 && (thmLR * msfix2) < thmMS) { - var f = thmLR * msfix2 / thmMS; - thmM *= f; - thmS *= f; - assert(thmMS > 0); - } - rmid = Math.min(thmM, rmid); - rside = Math.min(thmS, rside); - } - if (rmid > ebM) { - rmid = ebM; - } - if (rside > ebS) { - rside = ebS; - } - thr[2][b] = rmid; - thr[3][b] = rside; - } - } - - this.L3psycho_anal_vbr = function (gfp, buffer, bufPos, gr_out, masking_ratio, masking_MS_ratio, percep_entropy, percep_MS_entropy, energy, blocktype_d) { - var gfc = gfp.internal_flags; - - /* fft and energy calculation */ - var wsamp_l; - var wsamp_s; - var fftenergy = new_float(Encoder.HBLKSIZE); - var fftenergy_s = new_float_n([3, Encoder.HBLKSIZE_s]); - var wsamp_L = new_float_n([2, Encoder.BLKSIZE]); - var wsamp_S = new_float_n([2, 3, Encoder.BLKSIZE_s]); - var eb = new_float_n([4, Encoder.CBANDS]), thr = new_float_n([4, Encoder.CBANDS]); - var sub_short_factor = new_float_n([4, 3]); - var pcfact = 0.6; - - /* block type */ - var ns_attacks = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], - [0, 0, 0, 0]]; - var uselongblock = new_int(2); - - /* usual variables like loop indices, etc.. */ - - /* chn=2 and 3 = Mid and Side channels */ - var n_chn_psy = (gfp.mode == MPEGMode.JOINT_STEREO) ? 4 - : gfc.channels_out; - - vbrpsy_attack_detection(gfp, buffer, bufPos, gr_out, masking_ratio, - masking_MS_ratio, energy, sub_short_factor, ns_attacks, - uselongblock); - - vbrpsy_compute_block_type(gfp, uselongblock); - - /* LONG BLOCK CASE */ - { - for (var chn = 0; chn < n_chn_psy; chn++) { - var ch01 = chn & 0x01; - wsamp_l = wsamp_L; - vbrpsy_compute_fft_l(gfp, buffer, bufPos, chn, gr_out, - fftenergy, wsamp_l, ch01); - - vbrpsy_compute_loudness_approximation_l(gfp, gr_out, chn, - fftenergy); - - if (uselongblock[ch01] != 0) { - vbrpsy_compute_masking_l(gfc, fftenergy, eb[chn], thr[chn], - chn); - } else { - vbrpsy_skip_masking_l(gfc, chn); - } - } - if ((uselongblock[0] + uselongblock[1]) == 2) { - /* M/S channel */ - if (gfp.mode == MPEGMode.JOINT_STEREO) { - vbrpsy_compute_MS_thresholds(eb, thr, gfc.mld_cb_l, - gfc.ATH.cb_l, gfp.ATHlower * gfc.ATH.adjust, - gfp.msfix, gfc.npart_l); - } - } - /* TODO: apply adaptive ATH masking here ?? */ - for (var chn = 0; chn < n_chn_psy; chn++) { - var ch01 = chn & 0x01; - if (uselongblock[ch01] != 0) { - convert_partition2scalefac_l(gfc, eb[chn], thr[chn], chn); - } - } - } - - /* SHORT BLOCKS CASE */ - { - for (var sblock = 0; sblock < 3; sblock++) { - for (var chn = 0; chn < n_chn_psy; ++chn) { - var ch01 = chn & 0x01; - - if (uselongblock[ch01] != 0) { - vbrpsy_skip_masking_s(gfc, chn, sblock); - } else { - /* compute masking thresholds for short blocks */ - wsamp_s = wsamp_S; - vbrpsy_compute_fft_s(gfp, buffer, bufPos, chn, sblock, - fftenergy_s, wsamp_s, ch01); - vbrpsy_compute_masking_s(gfp, fftenergy_s, eb[chn], - thr[chn], chn, sblock); - } - } - if ((uselongblock[0] + uselongblock[1]) == 0) { - /* M/S channel */ - if (gfp.mode == MPEGMode.JOINT_STEREO) { - vbrpsy_compute_MS_thresholds(eb, thr, gfc.mld_cb_s, - gfc.ATH.cb_s, gfp.ATHlower * gfc.ATH.adjust, - gfp.msfix, gfc.npart_s); - } - /* L/R channel */ - } - /* TODO: apply adaptive ATH masking here ?? */ - for (var chn = 0; chn < n_chn_psy; ++chn) { - var ch01 = chn & 0x01; - if (0 == uselongblock[ch01]) { - convert_partition2scalefac_s(gfc, eb[chn], thr[chn], - chn, sblock); - } - } - } - - /**** short block pre-echo control ****/ - for (var chn = 0; chn < n_chn_psy; chn++) { - var ch01 = chn & 0x01; - - if (uselongblock[ch01] != 0) { - continue; - } - for (var sb = 0; sb < Encoder.SBMAX_s; sb++) { - var new_thmm = new_float(3); - for (var sblock = 0; sblock < 3; sblock++) { - var thmm = gfc.thm[chn].s[sb][sblock]; - thmm *= NS_PREECHO_ATT0; - - if (ns_attacks[chn][sblock] >= 2 - || ns_attacks[chn][sblock + 1] == 1) { - var idx = (sblock != 0) ? sblock - 1 : 2; - var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT1 * pcfact); - thmm = Math.min(thmm, p); - } else if (ns_attacks[chn][sblock] == 1) { - var idx = (sblock != 0) ? sblock - 1 : 2; - var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT2 * pcfact); - thmm = Math.min(thmm, p); - } else if ((sblock != 0 && ns_attacks[chn][sblock - 1] == 3) - || (sblock == 0 && gfc.nsPsy.lastAttacks[chn] == 3)) { - var idx = (sblock != 2) ? sblock + 1 : 0; - var p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT2 * pcfact); - thmm = Math.min(thmm, p); - } - - /* pulse like signal detection for fatboy.wav and so on */ - thmm *= sub_short_factor[chn][sblock]; - - new_thmm[sblock] = thmm; - } - for (var sblock = 0; sblock < 3; sblock++) { - gfc.thm[chn].s[sb][sblock] = new_thmm[sblock]; - } - } - } - } - for (var chn = 0; chn < n_chn_psy; chn++) { - gfc.nsPsy.lastAttacks[chn] = ns_attacks[chn][2]; - } - - /*************************************************************** - * determine final block type - ***************************************************************/ - vbrpsy_apply_block_type(gfp, uselongblock, blocktype_d); - - /********************************************************************* - * compute the value of PE to return ... no delay and advance - *********************************************************************/ - for (var chn = 0; chn < n_chn_psy; chn++) { - var ppe; - var ppePos; - var type; - var mr; - - if (chn > 1) { - ppe = percep_MS_entropy; - ppePos = -2; - type = Encoder.NORM_TYPE; - if (blocktype_d[0] == Encoder.SHORT_TYPE - || blocktype_d[1] == Encoder.SHORT_TYPE) - type = Encoder.SHORT_TYPE; - mr = masking_MS_ratio[gr_out][chn - 2]; - } else { - ppe = percep_entropy; - ppePos = 0; - type = blocktype_d[chn]; - mr = masking_ratio[gr_out][chn]; - } - - if (type == Encoder.SHORT_TYPE) { - ppe[ppePos + chn] = pecalc_s(mr, gfc.masking_lower); - } else { - ppe[ppePos + chn] = pecalc_l(mr, gfc.masking_lower); - } - - if (gfp.analysis) { - gfc.pinfo.pe[gr_out][chn] = ppe[ppePos + chn]; - } - } - return 0; - } - - function s3_func_x(bark, hf_slope) { - var tempx = bark, tempy; - - if (tempx >= 0) { - tempy = -tempx * 27; - } else { - tempy = tempx * hf_slope; - } - if (tempy <= -72.0) { - return 0; - } - return Math.exp(tempy * LN_TO_LOG10); - } - - function norm_s3_func_x(hf_slope) { - var lim_a = 0, lim_b = 0; - { - var x = 0, l, h; - for (x = 0; s3_func_x(x, hf_slope) > 1e-20; x -= 1) - ; - l = x; - h = 0; - while (Math.abs(h - l) > 1e-12) { - x = (h + l) / 2; - if (s3_func_x(x, hf_slope) > 0) { - h = x; - } else { - l = x; - } - } - lim_a = l; - } - { - var x = 0, l, h; - for (x = 0; s3_func_x(x, hf_slope) > 1e-20; x += 1) - ; - l = 0; - h = x; - while (Math.abs(h - l) > 1e-12) { - x = (h + l) / 2; - if (s3_func_x(x, hf_slope) > 0) { - l = x; - } else { - h = x; - } - } - lim_b = h; - } - { - var sum = 0; - var m = 1000; - var i; - for (i = 0; i <= m; ++i) { - var x = lim_a + i * (lim_b - lim_a) / m; - var y = s3_func_x(x, hf_slope); - sum += y; - } - { - var norm = (m + 1) / (sum * (lim_b - lim_a)); - /* printf( "norm = %lf\n",norm); */ - return norm; - } - } - } - - /** - * The spreading function. Values returned in units of energy - */ - function s3_func(bark) { - var tempx, x, tempy, temp; - tempx = bark; - if (tempx >= 0) - tempx *= 3; - else - tempx *= 1.5; - - if (tempx >= 0.5 && tempx <= 2.5) { - temp = tempx - 0.5; - x = 8.0 * (temp * temp - 2.0 * temp); - } else - x = 0.0; - tempx += 0.474; - tempy = 15.811389 + 7.5 * tempx - 17.5 - * Math.sqrt(1.0 + tempx * tempx); - - if (tempy <= -60.0) - return 0.0; - - tempx = Math.exp((x + tempy) * LN_TO_LOG10); - - /** - *
-         * Normalization.  The spreading function should be normalized so that:
-         * +inf
-         * /
-         * |  s3 [ bark ]  d(bark)   =  1
-         * /
-         * -inf
-         * 
- */ - tempx /= .6609193; - return tempx; - } - - /** - * see for example "Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 - */ - function freq2bark(freq) { - /* input: freq in hz output: barks */ - if (freq < 0) - freq = 0; - freq = freq * 0.001; - return 13.0 * Math.atan(.76 * freq) + 3.5 - * Math.atan(freq * freq / (7.5 * 7.5)); - } - - function init_numline(numlines, bo, bm, bval, bval_width, mld, bo_w, sfreq, blksize, scalepos, deltafreq, sbmax) { - var b_frq = new_float(Encoder.CBANDS + 1); - var sample_freq_frac = sfreq / (sbmax > 15 ? 2 * 576 : 2 * 192); - var partition = new_int(Encoder.HBLKSIZE); - var i; - sfreq /= blksize; - var j = 0; - var ni = 0; - /* compute numlines, the number of spectral lines in each partition band */ - /* each partition band should be about DELBARK wide. */ - for (i = 0; i < Encoder.CBANDS; i++) { - var bark1; - var j2; - bark1 = freq2bark(sfreq * j); - - b_frq[i] = sfreq * j; - - for (j2 = j; freq2bark(sfreq * j2) - bark1 < DELBARK - && j2 <= blksize / 2; j2++) - ; - - numlines[i] = j2 - j; - ni = i + 1; - - while (j < j2) { - assert(j < Encoder.HBLKSIZE); - partition[j++] = i; - } - if (j > blksize / 2) { - j = blksize / 2; - ++i; - break; - } - } - assert(i < Encoder.CBANDS); - b_frq[i] = sfreq * j; - - for (var sfb = 0; sfb < sbmax; sfb++) { - var i1, i2, start, end; - var arg; - start = scalepos[sfb]; - end = scalepos[sfb + 1]; - - i1 = 0 | Math.floor(.5 + deltafreq * (start - .5)); - if (i1 < 0) - i1 = 0; - i2 = 0 | Math.floor(.5 + deltafreq * (end - .5)); - - if (i2 > blksize / 2) - i2 = blksize / 2; - - bm[sfb] = (partition[i1] + partition[i2]) / 2; - bo[sfb] = partition[i2]; - var f_tmp = sample_freq_frac * end; - /* - * calculate how much of this band belongs to current scalefactor - * band - */ - bo_w[sfb] = (f_tmp - b_frq[bo[sfb]]) - / (b_frq[bo[sfb] + 1] - b_frq[bo[sfb]]); - if (bo_w[sfb] < 0) { - bo_w[sfb] = 0; - } else { - if (bo_w[sfb] > 1) { - bo_w[sfb] = 1; - } - } - /* setup stereo demasking thresholds */ - /* formula reverse enginerred from plot in paper */ - arg = freq2bark(sfreq * scalepos[sfb] * deltafreq); - arg = ( Math.min(arg, 15.5) / 15.5); - - mld[sfb] = Math.pow(10.0, - 1.25 * (1 - Math.cos(Math.PI * arg)) - 2.5); - } - - /* compute bark values of each critical band */ - j = 0; - for (var k = 0; k < ni; k++) { - var w = numlines[k]; - var bark1, bark2; - - bark1 = freq2bark(sfreq * (j)); - bark2 = freq2bark(sfreq * (j + w - 1)); - bval[k] = .5 * (bark1 + bark2); - - bark1 = freq2bark(sfreq * (j - .5)); - bark2 = freq2bark(sfreq * (j + w - .5)); - bval_width[k] = bark2 - bark1; - j += w; - } - - return ni; - } - - function init_s3_values(s3ind, npart, bval, bval_width, norm, use_old_s3) { - var s3 = new_float_n([Encoder.CBANDS, Encoder.CBANDS]); - /* - * The s3 array is not linear in the bark scale. - * - * bval[x] should be used to get the bark value. - */ - var j; - var numberOfNoneZero = 0; - - /** - *
-         * s[i][j], the value of the spreading function,
-         * centered at band j (masker), for band i (maskee)
-         *
-         * i.e.: sum over j to spread into signal barkval=i
-         * NOTE: i and j are used opposite as in the ISO docs
-         * 
- */ - if (use_old_s3) { - for (var i = 0; i < npart; i++) { - for (j = 0; j < npart; j++) { - var v = s3_func(bval[i] - bval[j]) * bval_width[j]; - s3[i][j] = v * norm[i]; - } - } - } else { - for (j = 0; j < npart; j++) { - var hf_slope = 15 + Math.min(21 / bval[j], 12); - var s3_x_norm = norm_s3_func_x(hf_slope); - for (var i = 0; i < npart; i++) { - var v = s3_x_norm - * s3_func_x(bval[i] - bval[j], hf_slope) - * bval_width[j]; - s3[i][j] = v * norm[i]; - } - } - } - for (var i = 0; i < npart; i++) { - for (j = 0; j < npart; j++) { - if (s3[i][j] > 0.0) - break; - } - s3ind[i][0] = j; - - for (j = npart - 1; j > 0; j--) { - if (s3[i][j] > 0.0) - break; - } - s3ind[i][1] = j; - numberOfNoneZero += (s3ind[i][1] - s3ind[i][0] + 1); - } - - var p = new_float(numberOfNoneZero); - var k = 0; - for (var i = 0; i < npart; i++) - for (j = s3ind[i][0]; j <= s3ind[i][1]; j++) - p[k++] = s3[i][j]; - - return p; - } - - function stereo_demask(f) { - /* setup stereo demasking thresholds */ - /* formula reverse enginerred from plot in paper */ - var arg = freq2bark(f); - arg = (Math.min(arg, 15.5) / 15.5); - - return Math.pow(10.0, - 1.25 * (1 - Math.cos(Math.PI * arg)) - 2.5); - } - - /** - * NOTE: the bitrate reduction from the inter-channel masking effect is low - * compared to the chance of getting annyoing artefacts. L3psycho_anal_vbr - * does not use this feature. (Robert 071216) - */ - this.psymodel_init = function (gfp) { - var gfc = gfp.internal_flags; - var i; - var useOldS3 = true; - var bvl_a = 13, bvl_b = 24; - var snr_l_a = 0, snr_l_b = 0; - var snr_s_a = -8.25, snr_s_b = -4.5; - var bval = new_float(Encoder.CBANDS); - var bval_width = new_float(Encoder.CBANDS); - var norm = new_float(Encoder.CBANDS); - var sfreq = gfp.out_samplerate; - - switch (gfp.experimentalZ) { - default: - case 0: - useOldS3 = true; - break; - case 1: - useOldS3 = (gfp.VBR == VbrMode.vbr_mtrh || gfp.VBR == VbrMode.vbr_mt) ? false - : true; - break; - case 2: - useOldS3 = false; - break; - case 3: - bvl_a = 8; - snr_l_a = -1.75; - snr_l_b = -0.0125; - snr_s_a = -8.25; - snr_s_b = -2.25; - break; - } - gfc.ms_ener_ratio_old = .25; - gfc.blocktype_old[0] = gfc.blocktype_old[1] = Encoder.NORM_TYPE; - // the vbr header is long blocks - - for (i = 0; i < 4; ++i) { - for (var j = 0; j < Encoder.CBANDS; ++j) { - gfc.nb_1[i][j] = 1e20; - gfc.nb_2[i][j] = 1e20; - gfc.nb_s1[i][j] = gfc.nb_s2[i][j] = 1.0; - } - for (var sb = 0; sb < Encoder.SBMAX_l; sb++) { - gfc.en[i].l[sb] = 1e20; - gfc.thm[i].l[sb] = 1e20; - } - for (var j = 0; j < 3; ++j) { - for (var sb = 0; sb < Encoder.SBMAX_s; sb++) { - gfc.en[i].s[sb][j] = 1e20; - gfc.thm[i].s[sb][j] = 1e20; - } - gfc.nsPsy.lastAttacks[i] = 0; - } - for (var j = 0; j < 9; j++) - gfc.nsPsy.last_en_subshort[i][j] = 10.; - } - - /* init. for loudness approx. -jd 2001 mar 27 */ - gfc.loudness_sq_save[0] = gfc.loudness_sq_save[1] = 0.0; - - /************************************************************************* - * now compute the psychoacoustic model specific constants - ************************************************************************/ - /* compute numlines, bo, bm, bval, bval_width, mld */ - - gfc.npart_l = init_numline(gfc.numlines_l, gfc.bo_l, gfc.bm_l, bval, - bval_width, gfc.mld_l, gfc.PSY.bo_l_weight, sfreq, - Encoder.BLKSIZE, gfc.scalefac_band.l, Encoder.BLKSIZE - / (2.0 * 576), Encoder.SBMAX_l); - assert(gfc.npart_l < Encoder.CBANDS); - /* compute the spreading function */ - for (i = 0; i < gfc.npart_l; i++) { - var snr = snr_l_a; - if (bval[i] >= bvl_a) { - snr = snr_l_b * (bval[i] - bvl_a) / (bvl_b - bvl_a) + snr_l_a - * (bvl_b - bval[i]) / (bvl_b - bvl_a); - } - norm[i] = Math.pow(10.0, snr / 10.0); - if (gfc.numlines_l[i] > 0) { - gfc.rnumlines_l[i] = 1.0 / gfc.numlines_l[i]; - } else { - gfc.rnumlines_l[i] = 0; - } - } - gfc.s3_ll = init_s3_values(gfc.s3ind, gfc.npart_l, bval, bval_width, - norm, useOldS3); - - /* compute long block specific values, ATH and MINVAL */ - var j = 0; - for (i = 0; i < gfc.npart_l; i++) { - var x; - - /* ATH */ - x = Float.MAX_VALUE; - for (var k = 0; k < gfc.numlines_l[i]; k++, j++) { - var freq = sfreq * j / (1000.0 * Encoder.BLKSIZE); - var level; - /* - * ATH below 100 Hz constant, not further climbing - */ - level = this.ATHformula(freq * 1000, gfp) - 20; - // scale to FFT units; returned value is in dB - level = Math.pow(10., 0.1 * level); - // convert from dB . energy - level *= gfc.numlines_l[i]; - if (x > level) - x = level; - } - gfc.ATH.cb_l[i] = x; - - /* - * MINVAL. For low freq, the strength of the masking is limited by - * minval this is an ISO MPEG1 thing, dont know if it is really - * needed - */ - /* - * FIXME: it does work to reduce low-freq problems in S53-Wind-Sax - * and lead-voice samples, but introduces some 3 kbps bit bloat too. - * TODO: Further refinement of the shape of this hack. - */ - x = -20 + bval[i] * 20 / 10; - if (x > 6) { - x = 100; - } - if (x < -15) { - x = -15; - } - x -= 8.; - gfc.minval_l[i] = (Math.pow(10.0, x / 10.) * gfc.numlines_l[i]); - } - - /************************************************************************ - * do the same things for short blocks - ************************************************************************/ - gfc.npart_s = init_numline(gfc.numlines_s, gfc.bo_s, gfc.bm_s, bval, - bval_width, gfc.mld_s, gfc.PSY.bo_s_weight, sfreq, - Encoder.BLKSIZE_s, gfc.scalefac_band.s, Encoder.BLKSIZE_s - / (2.0 * 192), Encoder.SBMAX_s); - assert(gfc.npart_s < Encoder.CBANDS); - - /* SNR formula. short block is normalized by SNR. is it still right ? */ - j = 0; - for (i = 0; i < gfc.npart_s; i++) { - var x; - var snr = snr_s_a; - if (bval[i] >= bvl_a) { - snr = snr_s_b * (bval[i] - bvl_a) / (bvl_b - bvl_a) + snr_s_a - * (bvl_b - bval[i]) / (bvl_b - bvl_a); - } - norm[i] = Math.pow(10.0, snr / 10.0); - - /* ATH */ - x = Float.MAX_VALUE; - for (var k = 0; k < gfc.numlines_s[i]; k++, j++) { - var freq = sfreq * j / (1000.0 * Encoder.BLKSIZE_s); - var level; - /* freq = Min(.1,freq); */ - /* - * ATH below 100 Hz constant, not - * further climbing - */ - level = this.ATHformula(freq * 1000, gfp) - 20; - // scale to FFT units; returned value is in dB - level = Math.pow(10., 0.1 * level); - // convert from dB . energy - level *= gfc.numlines_s[i]; - if (x > level) - x = level; - } - gfc.ATH.cb_s[i] = x; - - /* - * MINVAL. For low freq, the strength of the masking is limited by - * minval this is an ISO MPEG1 thing, dont know if it is really - * needed - */ - x = (-7.0 + bval[i] * 7.0 / 12.0); - if (bval[i] > 12) { - x *= 1 + Math.log(1 + x) * 3.1; - } - if (bval[i] < 12) { - x *= 1 + Math.log(1 - x) * 2.3; - } - if (x < -15) { - x = -15; - } - x -= 8; - gfc.minval_s[i] = Math.pow(10.0, x / 10) - * gfc.numlines_s[i]; - } - - gfc.s3_ss = init_s3_values(gfc.s3ind_s, gfc.npart_s, bval, bval_width, - norm, useOldS3); - - init_mask_add_max_values(); - fft.init_fft(gfc); - - /* setup temporal masking */ - gfc.decay = Math.exp(-1.0 * LOG10 - / (temporalmask_sustain_sec * sfreq / 192.0)); - - { - var msfix; - msfix = NS_MSFIX; - if ((gfp.exp_nspsytune & 2) != 0) - msfix = 1.0; - if (Math.abs(gfp.msfix) > 0.0) - msfix = gfp.msfix; - gfp.msfix = msfix; - - /* - * spread only from npart_l bands. Normally, we use the spreading - * function to convolve from npart_l down to npart_l bands - */ - for (var b = 0; b < gfc.npart_l; b++) - if (gfc.s3ind[b][1] > gfc.npart_l - 1) - gfc.s3ind[b][1] = gfc.npart_l - 1; - } - - /* - * prepare for ATH auto adjustment: we want to decrease the ATH by 12 dB - * per second - */ - var frame_duration = (576. * gfc.mode_gr / sfreq); - gfc.ATH.decay = Math.pow(10., -12. / 10. * frame_duration); - gfc.ATH.adjust = 0.01; - /* minimum, for leading low loudness */ - gfc.ATH.adjustLimit = 1.0; - /* on lead, allow adjust up to maximum */ - - assert(gfc.bo_l[Encoder.SBMAX_l - 1] <= gfc.npart_l); - assert(gfc.bo_s[Encoder.SBMAX_s - 1] <= gfc.npart_s); - - if (gfp.ATHtype != -1) { - /* compute equal loudness weights (eql_w) */ - var freq; - var freq_inc = gfp.out_samplerate - / (Encoder.BLKSIZE); - var eql_balance = 0.0; - freq = 0.0; - for (i = 0; i < Encoder.BLKSIZE / 2; ++i) { - /* convert ATH dB to relative power (not dB) */ - /* to determine eql_w */ - freq += freq_inc; - gfc.ATH.eql_w[i] = 1. / Math.pow(10, this.ATHformula(freq, gfp) / 10); - eql_balance += gfc.ATH.eql_w[i]; - } - eql_balance = 1.0 / eql_balance; - for (i = Encoder.BLKSIZE / 2; --i >= 0;) { /* scale weights */ - gfc.ATH.eql_w[i] *= eql_balance; - } - } - { - for (var b = j = 0; b < gfc.npart_s; ++b) { - for (i = 0; i < gfc.numlines_s[b]; ++i) { - ++j; - } - } - assert(j == 129); - for (var b = j = 0; b < gfc.npart_l; ++b) { - for (i = 0; i < gfc.numlines_l[b]; ++i) { - ++j; - } - } - assert(j == 513); - } - j = 0; - for (i = 0; i < gfc.npart_l; i++) { - var freq = sfreq * (j + gfc.numlines_l[i] / 2) / (1.0 * Encoder.BLKSIZE); - gfc.mld_cb_l[i] = stereo_demask(freq); - j += gfc.numlines_l[i]; - } - for (; i < Encoder.CBANDS; ++i) { - gfc.mld_cb_l[i] = 1; - } - j = 0; - for (i = 0; i < gfc.npart_s; i++) { - var freq = sfreq * (j + gfc.numlines_s[i] / 2) / (1.0 * Encoder.BLKSIZE_s); - gfc.mld_cb_s[i] = stereo_demask(freq); - j += gfc.numlines_s[i]; - } - for (; i < Encoder.CBANDS; ++i) { - gfc.mld_cb_s[i] = 1; - } - return 0; - } - - /** - * Those ATH formulas are returning their minimum value for input = -1 - */ - function ATHformula_GB(f, value) { - /** - *
-         *  from Painter & Spanias
-         *           modified by Gabriel Bouvigne to better fit the reality
-         *           ath =    3.640 * pow(f,-0.8)
-         *           - 6.800 * exp(-0.6*pow(f-3.4,2.0))
-         *           + 6.000 * exp(-0.15*pow(f-8.7,2.0))
-         *           + 0.6* 0.001 * pow(f,4.0);
-         *
-         *
-         *           In the past LAME was using the Painter &Spanias formula.
-         *           But we had some recurrent problems with HF content.
-         *           We measured real ATH values, and found the older formula
-         *           to be inaccurate in the higher part. So we made this new
-         *           formula and this solved most of HF problematic test cases.
-         *           The tradeoff is that in VBR mode it increases a lot the
-         *           bitrate.
-         * 
- */ - - /* - * This curve can be adjusted according to the VBR scale: it adjusts - * from something close to Painter & Spanias on V9 up to Bouvigne's - * formula for V0. This way the VBR bitrate is more balanced according - * to the -V value. - */ - - // the following Hack allows to ask for the lowest value - if (f < -.3) - f = 3410; - - // convert to khz - f /= 1000; - f = Math.max(0.1, f); - var ath = 3.640 * Math.pow(f, -0.8) - 6.800 - * Math.exp(-0.6 * Math.pow(f - 3.4, 2.0)) + 6.000 - * Math.exp(-0.15 * Math.pow(f - 8.7, 2.0)) - + (0.6 + 0.04 * value) * 0.001 * Math.pow(f, 4.0); - return ath; - } - - this.ATHformula = function (f, gfp) { - var ath; - switch (gfp.ATHtype) { - case 0: - ath = ATHformula_GB(f, 9); - break; - case 1: - // over sensitive, should probably be removed - ath = ATHformula_GB(f, -1); - break; - case 2: - ath = ATHformula_GB(f, 0); - break; - case 3: - // modification of GB formula by Roel - ath = ATHformula_GB(f, 1) + 6; - break; - case 4: - ath = ATHformula_GB(f, gfp.ATHcurve); - break; - default: - ath = ATHformula_GB(f, 0); - break; - } - return ath; - } - -} - -module.exports = PsyModel; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Quantize.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Quantize.js deleted file mode 100644 index f7b0519a4..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Quantize.js +++ /dev/null @@ -1,1498 +0,0 @@ -/* - * MP3 quantization - * - * Copyright (c) 1999-2000 Mark Taylor - * Copyright (c) 1999-2003 Takehiro Tominaga - * Copyright (c) 2000-2007 Robert Hegemann - * Copyright (c) 2001-2005 Gabriel Bouvigne - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: Quantize.java,v 1.24 2011/05/24 20:48:06 kenchis Exp $ */ - -//package mp3; - -//import java.util.Arrays; -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -var VBRQuantize = require('./VBRQuantize.js'); -var CalcNoiseResult = require('./CalcNoiseResult.js'); -var CalcNoiseData = require('./CalcNoiseData.js'); -var Encoder = require('./Encoder.js'); -var GrInfo = require('./GrInfo.js'); -var L3Side = require('./L3Side.js'); - -function Quantize() { - var bs; - this.rv = null; - var rv; - this.qupvt = null; - var qupvt; - - var vbr = new VBRQuantize(); - var tk; - - this.setModules = function (_bs, _rv, _qupvt, _tk) { - bs = _bs; - rv = _rv; - this.rv = _rv; - qupvt = _qupvt; - this.qupvt = _qupvt; - tk = _tk; - vbr.setModules(qupvt, tk); - } - - /** - * convert from L/R <. Mid/Side - */ - this.ms_convert = function (l3_side, gr) { - for (var i = 0; i < 576; ++i) { - var l = l3_side.tt[gr][0].xr[i]; - var r = l3_side.tt[gr][1].xr[i]; - l3_side.tt[gr][0].xr[i] = (l + r) * (Util.SQRT2 * 0.5); - l3_side.tt[gr][1].xr[i] = (l - r) * (Util.SQRT2 * 0.5); - } - }; - - /** - * mt 6/99 - * - * initializes cod_info, scalefac and xrpow - * - * returns 0 if all energies in xr are zero, else 1 - */ - function init_xrpow_core(cod_info, xrpow, upper, sum) { - sum = 0; - for (var i = 0; i <= upper; ++i) { - var tmp = Math.abs(cod_info.xr[i]); - sum += tmp; - xrpow[i] = Math.sqrt(tmp * Math.sqrt(tmp)); - - if (xrpow[i] > cod_info.xrpow_max) - cod_info.xrpow_max = xrpow[i]; - } - return sum; - } - - this.init_xrpow = function (gfc, cod_info, xrpow) { - var sum = 0; - var upper = 0 | cod_info.max_nonzero_coeff; - - assert(xrpow != null); - cod_info.xrpow_max = 0; - - /* - * check if there is some energy we have to quantize and calculate xrpow - * matching our fresh scalefactors - */ - assert(0 <= upper && upper <= 575); - - Arrays.fill(xrpow, upper, 576, 0); - - sum = init_xrpow_core(cod_info, xrpow, upper, sum); - - /* - * return 1 if we have something to quantize, else 0 - */ - if (sum > 1E-20) { - var j = 0; - if ((gfc.substep_shaping & 2) != 0) - j = 1; - - for (var i = 0; i < cod_info.psymax; i++) - gfc.pseudohalf[i] = j; - - return true; - } - - Arrays.fill(cod_info.l3_enc, 0, 576, 0); - return false; - } - - /** - * Gabriel Bouvigne feb/apr 2003
- * Analog silence detection in partitionned sfb21 or sfb12 for short blocks - * - * From top to bottom of sfb, changes to 0 coeffs which are below ath. It - * stops on the first coeff higher than ath. - */ - function psfb21_analogsilence(gfc, cod_info) { - var ath = gfc.ATH; - var xr = cod_info.xr; - - if (cod_info.block_type != Encoder.SHORT_TYPE) { - /* NORM, START or STOP type, but not SHORT blocks */ - var stop = false; - for (var gsfb = Encoder.PSFB21 - 1; gsfb >= 0 && !stop; gsfb--) { - var start = gfc.scalefac_band.psfb21[gsfb]; - var end = gfc.scalefac_band.psfb21[gsfb + 1]; - var ath21 = qupvt.athAdjust(ath.adjust, ath.psfb21[gsfb], - ath.floor); - - if (gfc.nsPsy.longfact[21] > 1e-12) - ath21 *= gfc.nsPsy.longfact[21]; - - for (var j = end - 1; j >= start; j--) { - if (Math.abs(xr[j]) < ath21) - xr[j] = 0; - else { - stop = true; - break; - } - } - } - } else { - /* note: short blocks coeffs are reordered */ - for (var block = 0; block < 3; block++) { - var stop = false; - for (var gsfb = Encoder.PSFB12 - 1; gsfb >= 0 && !stop; gsfb--) { - var start = gfc.scalefac_band.s[12] - * 3 - + (gfc.scalefac_band.s[13] - gfc.scalefac_band.s[12]) - * block - + (gfc.scalefac_band.psfb12[gsfb] - gfc.scalefac_band.psfb12[0]); - var end = start - + (gfc.scalefac_band.psfb12[gsfb + 1] - gfc.scalefac_band.psfb12[gsfb]); - var ath12 = qupvt.athAdjust(ath.adjust, ath.psfb12[gsfb], - ath.floor); - - if (gfc.nsPsy.shortfact[12] > 1e-12) - ath12 *= gfc.nsPsy.shortfact[12]; - - for (var j = end - 1; j >= start; j--) { - if (Math.abs(xr[j]) < ath12) - xr[j] = 0; - else { - stop = true; - break; - } - } - } - } - } - - } - - this.init_outer_loop = function (gfc, cod_info) { - /* - * initialize fresh cod_info - */ - cod_info.part2_3_length = 0; - cod_info.big_values = 0; - cod_info.count1 = 0; - cod_info.global_gain = 210; - cod_info.scalefac_compress = 0; - /* mixed_block_flag, block_type was set in psymodel.c */ - cod_info.table_select[0] = 0; - cod_info.table_select[1] = 0; - cod_info.table_select[2] = 0; - cod_info.subblock_gain[0] = 0; - cod_info.subblock_gain[1] = 0; - cod_info.subblock_gain[2] = 0; - cod_info.subblock_gain[3] = 0; - /* this one is always 0 */ - cod_info.region0_count = 0; - cod_info.region1_count = 0; - cod_info.preflag = 0; - cod_info.scalefac_scale = 0; - cod_info.count1table_select = 0; - cod_info.part2_length = 0; - cod_info.sfb_lmax = Encoder.SBPSY_l; - cod_info.sfb_smin = Encoder.SBPSY_s; - cod_info.psy_lmax = gfc.sfb21_extra ? Encoder.SBMAX_l : Encoder.SBPSY_l; - cod_info.psymax = cod_info.psy_lmax; - cod_info.sfbmax = cod_info.sfb_lmax; - cod_info.sfbdivide = 11; - for (var sfb = 0; sfb < Encoder.SBMAX_l; sfb++) { - cod_info.width[sfb] = gfc.scalefac_band.l[sfb + 1] - - gfc.scalefac_band.l[sfb]; - /* which is always 0. */ - cod_info.window[sfb] = 3; - } - if (cod_info.block_type == Encoder.SHORT_TYPE) { - var ixwork = new_float(576); - - cod_info.sfb_smin = 0; - cod_info.sfb_lmax = 0; - if (cod_info.mixed_block_flag != 0) { - /* - * MPEG-1: sfbs 0-7 long block, 3-12 short blocks MPEG-2(.5): - * sfbs 0-5 long block, 3-12 short blocks - */ - cod_info.sfb_smin = 3; - cod_info.sfb_lmax = gfc.mode_gr * 2 + 4; - } - cod_info.psymax = cod_info.sfb_lmax - + 3 - * ((gfc.sfb21_extra ? Encoder.SBMAX_s : Encoder.SBPSY_s) - cod_info.sfb_smin); - cod_info.sfbmax = cod_info.sfb_lmax + 3 - * (Encoder.SBPSY_s - cod_info.sfb_smin); - cod_info.sfbdivide = cod_info.sfbmax - 18; - cod_info.psy_lmax = cod_info.sfb_lmax; - /* re-order the short blocks, for more efficient encoding below */ - /* By Takehiro TOMINAGA */ - /* - * Within each scalefactor band, data is given for successive time - * windows, beginning with window 0 and ending with window 2. Within - * each window, the quantized values are then arranged in order of - * increasing frequency... - */ - var ix = gfc.scalefac_band.l[cod_info.sfb_lmax]; - System.arraycopy(cod_info.xr, 0, ixwork, 0, 576); - for (var sfb = cod_info.sfb_smin; sfb < Encoder.SBMAX_s; sfb++) { - var start = gfc.scalefac_band.s[sfb]; - var end = gfc.scalefac_band.s[sfb + 1]; - for (var window = 0; window < 3; window++) { - for (var l = start; l < end; l++) { - cod_info.xr[ix++] = ixwork[3 * l + window]; - } - } - } - - var j = cod_info.sfb_lmax; - for (var sfb = cod_info.sfb_smin; sfb < Encoder.SBMAX_s; sfb++) { - cod_info.width[j] = cod_info.width[j + 1] = cod_info.width[j + 2] = gfc.scalefac_band.s[sfb + 1] - - gfc.scalefac_band.s[sfb]; - cod_info.window[j] = 0; - cod_info.window[j + 1] = 1; - cod_info.window[j + 2] = 2; - j += 3; - } - } - - cod_info.count1bits = 0; - cod_info.sfb_partition_table = qupvt.nr_of_sfb_block[0][0]; - cod_info.slen[0] = 0; - cod_info.slen[1] = 0; - cod_info.slen[2] = 0; - cod_info.slen[3] = 0; - - cod_info.max_nonzero_coeff = 575; - - /* - * fresh scalefactors are all zero - */ - Arrays.fill(cod_info.scalefac, 0); - - psfb21_analogsilence(gfc, cod_info); - }; - - function BinSearchDirection(ordinal) { - this.ordinal = ordinal; - } - - BinSearchDirection.BINSEARCH_NONE = new BinSearchDirection(0); - BinSearchDirection.BINSEARCH_UP = new BinSearchDirection(1); - BinSearchDirection.BINSEARCH_DOWN = new BinSearchDirection(2); - - /** - * author/date?? - * - * binary step size search used by outer_loop to get a quantizer step size - * to start with - */ - function bin_search_StepSize(gfc, cod_info, desired_rate, ch, xrpow) { - var nBits; - var CurrentStep = gfc.CurrentStep[ch]; - var flagGoneOver = false; - var start = gfc.OldValue[ch]; - var Direction = BinSearchDirection.BINSEARCH_NONE; - cod_info.global_gain = start; - desired_rate -= cod_info.part2_length; - - assert(CurrentStep != 0); - for (; ;) { - var step; - nBits = tk.count_bits(gfc, xrpow, cod_info, null); - - if (CurrentStep == 1 || nBits == desired_rate) - break; - /* nothing to adjust anymore */ - - if (nBits > desired_rate) { - /* increase Quantize_StepSize */ - if (Direction == BinSearchDirection.BINSEARCH_DOWN) - flagGoneOver = true; - - if (flagGoneOver) - CurrentStep /= 2; - Direction = BinSearchDirection.BINSEARCH_UP; - step = CurrentStep; - } else { - /* decrease Quantize_StepSize */ - if (Direction == BinSearchDirection.BINSEARCH_UP) - flagGoneOver = true; - - if (flagGoneOver) - CurrentStep /= 2; - Direction = BinSearchDirection.BINSEARCH_DOWN; - step = -CurrentStep; - } - cod_info.global_gain += step; - if (cod_info.global_gain < 0) { - cod_info.global_gain = 0; - flagGoneOver = true; - } - if (cod_info.global_gain > 255) { - cod_info.global_gain = 255; - flagGoneOver = true; - } - } - - assert(cod_info.global_gain >= 0); - assert(cod_info.global_gain < 256); - - while (nBits > desired_rate && cod_info.global_gain < 255) { - cod_info.global_gain++; - nBits = tk.count_bits(gfc, xrpow, cod_info, null); - } - gfc.CurrentStep[ch] = (start - cod_info.global_gain >= 4) ? 4 : 2; - gfc.OldValue[ch] = cod_info.global_gain; - cod_info.part2_3_length = nBits; - return nBits; - } - - this.trancate_smallspectrums = function (gfc, gi, l3_xmin, work) { - var distort = new_float(L3Side.SFBMAX); - - if ((0 == (gfc.substep_shaping & 4) && gi.block_type == Encoder.SHORT_TYPE) - || (gfc.substep_shaping & 0x80) != 0) - return; - qupvt.calc_noise(gi, l3_xmin, distort, new CalcNoiseResult(), null); - for (var j = 0; j < 576; j++) { - var xr = 0.0; - if (gi.l3_enc[j] != 0) - xr = Math.abs(gi.xr[j]); - work[j] = xr; - } - - var j = 0; - var sfb = 8; - if (gi.block_type == Encoder.SHORT_TYPE) - sfb = 6; - do { - var allowedNoise, trancateThreshold; - var nsame, start; - - var width = gi.width[sfb]; - j += width; - if (distort[sfb] >= 1.0) - continue; - - Arrays.sort(work, j - width, width); - if (BitStream.EQ(work[j - 1], 0.0)) - continue; - /* all zero sfb */ - - allowedNoise = (1.0 - distort[sfb]) * l3_xmin[sfb]; - trancateThreshold = 0.0; - start = 0; - do { - var noise; - for (nsame = 1; start + nsame < width; nsame++) - if (BitStream.NEQ(work[start + j - width], work[start + j - + nsame - width])) - break; - - noise = work[start + j - width] * work[start + j - width] - * nsame; - if (allowedNoise < noise) { - if (start != 0) - trancateThreshold = work[start + j - width - 1]; - break; - } - allowedNoise -= noise; - start += nsame; - } while (start < width); - if (BitStream.EQ(trancateThreshold, 0.0)) - continue; - - do { - if (Math.abs(gi.xr[j - width]) <= trancateThreshold) - gi.l3_enc[j - width] = 0; - } while (--width > 0); - } while (++sfb < gi.psymax); - - gi.part2_3_length = tk.noquant_count_bits(gfc, gi, null); - }; - - /** - * author/date?? - * - * Function: Returns zero if there is a scalefac which has not been - * amplified. Otherwise it returns one. - */ - function loop_break(cod_info) { - for (var sfb = 0; sfb < cod_info.sfbmax; sfb++) - if (cod_info.scalefac[sfb] - + cod_info.subblock_gain[cod_info.window[sfb]] == 0) - return false; - - return true; - } - - /* mt 5/99: Function: Improved calc_noise for a single channel */ - - function penalties(noise) { - return Util.FAST_LOG10((0.368 + 0.632 * noise * noise * noise)); - } - - /** - * author/date?? - * - * several different codes to decide which quantization is better - */ - function get_klemm_noise(distort, gi) { - var klemm_noise = 1E-37; - for (var sfb = 0; sfb < gi.psymax; sfb++) - klemm_noise += penalties(distort[sfb]); - - return Math.max(1e-20, klemm_noise); - } - - function quant_compare(quant_comp, best, calc, gi, distort) { - /** - * noise is given in decibels (dB) relative to masking thesholds.
- * - * over_noise: ??? (the previous comment is fully wrong)
- * tot_noise: ??? (the previous comment is fully wrong)
- * max_noise: max quantization noise - */ - var better; - - switch (quant_comp) { - default: - case 9: - { - if (best.over_count > 0) { - /* there are distorted sfb */ - better = calc.over_SSD <= best.over_SSD; - if (calc.over_SSD == best.over_SSD) - better = calc.bits < best.bits; - } else { - /* no distorted sfb */ - better = ((calc.max_noise < 0) && ((calc.max_noise * 10 + calc.bits) <= (best.max_noise * 10 + best.bits))); - } - break; - } - - case 0: - better = calc.over_count < best.over_count - || (calc.over_count == best.over_count && calc.over_noise < best.over_noise) - || (calc.over_count == best.over_count - && BitStream.EQ(calc.over_noise, best.over_noise) && calc.tot_noise < best.tot_noise); - break; - - case 8: - calc.max_noise = get_klemm_noise(distort, gi); - //$FALL-THROUGH$ - case 1: - better = calc.max_noise < best.max_noise; - break; - case 2: - better = calc.tot_noise < best.tot_noise; - break; - case 3: - better = (calc.tot_noise < best.tot_noise) - && (calc.max_noise < best.max_noise); - break; - case 4: - better = (calc.max_noise <= 0.0 && best.max_noise > 0.2) - || (calc.max_noise <= 0.0 && best.max_noise < 0.0 - && best.max_noise > calc.max_noise - 0.2 && calc.tot_noise < best.tot_noise) - || (calc.max_noise <= 0.0 && best.max_noise > 0.0 - && best.max_noise > calc.max_noise - 0.2 && calc.tot_noise < best.tot_noise - + best.over_noise) - || (calc.max_noise > 0.0 && best.max_noise > -0.05 - && best.max_noise > calc.max_noise - 0.1 && calc.tot_noise - + calc.over_noise < best.tot_noise - + best.over_noise) - || (calc.max_noise > 0.0 && best.max_noise > -0.1 - && best.max_noise > calc.max_noise - 0.15 && calc.tot_noise - + calc.over_noise + calc.over_noise < best.tot_noise - + best.over_noise + best.over_noise); - break; - case 5: - better = calc.over_noise < best.over_noise - || (BitStream.EQ(calc.over_noise, best.over_noise) && calc.tot_noise < best.tot_noise); - break; - case 6: - better = calc.over_noise < best.over_noise - || (BitStream.EQ(calc.over_noise, best.over_noise) && (calc.max_noise < best.max_noise || (BitStream - .EQ(calc.max_noise, best.max_noise) && calc.tot_noise <= best.tot_noise))); - break; - case 7: - better = calc.over_count < best.over_count - || calc.over_noise < best.over_noise; - break; - } - - if (best.over_count == 0) { - /* - * If no distorted bands, only use this quantization if it is - * better, and if it uses less bits. Unfortunately, part2_3_length - * is sometimes a poor estimator of the final size at low bitrates. - */ - better = better && calc.bits < best.bits; - } - - return better; - } - - /** - * author/date?? - * - *
-     *  Amplify the scalefactor bands that violate the masking threshold.
-     *  See ISO 11172-3 Section C.1.5.4.3.5
-     *
-     *  distort[] = noise/masking
-     *  distort[] > 1   ==> noise is not masked
-     *  distort[] < 1   ==> noise is masked
-     *  max_dist = maximum value of distort[]
-     *
-     *  Three algorithms:
-     *  noise_shaping_amp
-     *        0             Amplify all bands with distort[]>1.
-     *
-     *        1             Amplify all bands with distort[] >= max_dist^(.5);
-     *                     ( 50% in the db scale)
-     *
-     *        2             Amplify first band with distort[] >= max_dist;
-     *
-     *
-     *  For algorithms 0 and 1, if max_dist < 1, then amplify all bands
-     *  with distort[] >= .95*max_dist.  This is to make sure we always
-     *  amplify at least one band.
-     * 
- */ - function amp_scalefac_bands(gfp, cod_info, distort, xrpow, bRefine) { - var gfc = gfp.internal_flags; - var ifqstep34; - - if (cod_info.scalefac_scale == 0) { - ifqstep34 = 1.29683955465100964055; - /* 2**(.75*.5) */ - } else { - ifqstep34 = 1.68179283050742922612; - /* 2**(.75*1) */ - } - - /* compute maximum value of distort[] */ - var trigger = 0; - for (var sfb = 0; sfb < cod_info.sfbmax; sfb++) { - if (trigger < distort[sfb]) - trigger = distort[sfb]; - } - - var noise_shaping_amp = gfc.noise_shaping_amp; - if (noise_shaping_amp == 3) { - if (bRefine) - noise_shaping_amp = 2; - else - noise_shaping_amp = 1; - } - switch (noise_shaping_amp) { - case 2: - /* amplify exactly 1 band */ - break; - - case 1: - /* amplify bands within 50% of max (on db scale) */ - if (trigger > 1.0) - trigger = Math.pow(trigger, .5); - else - trigger *= .95; - break; - - case 0: - default: - /* ISO algorithm. amplify all bands with distort>1 */ - if (trigger > 1.0) - trigger = 1.0; - else - trigger *= .95; - break; - } - - var j = 0; - for (var sfb = 0; sfb < cod_info.sfbmax; sfb++) { - var width = cod_info.width[sfb]; - var l; - j += width; - if (distort[sfb] < trigger) - continue; - - if ((gfc.substep_shaping & 2) != 0) { - gfc.pseudohalf[sfb] = (0 == gfc.pseudohalf[sfb]) ? 1 : 0; - if (0 == gfc.pseudohalf[sfb] && gfc.noise_shaping_amp == 2) - return; - } - cod_info.scalefac[sfb]++; - for (l = -width; l < 0; l++) { - xrpow[j + l] *= ifqstep34; - if (xrpow[j + l] > cod_info.xrpow_max) - cod_info.xrpow_max = xrpow[j + l]; - } - - if (gfc.noise_shaping_amp == 2) - return; - } - } - - /** - * Takehiro Tominaga 2000-xx-xx - * - * turns on scalefac scale and adjusts scalefactors - */ - function inc_scalefac_scale(cod_info, xrpow) { - var ifqstep34 = 1.29683955465100964055; - - var j = 0; - for (var sfb = 0; sfb < cod_info.sfbmax; sfb++) { - var width = cod_info.width[sfb]; - var s = cod_info.scalefac[sfb]; - if (cod_info.preflag != 0) - s += qupvt.pretab[sfb]; - j += width; - if ((s & 1) != 0) { - s++; - for (var l = -width; l < 0; l++) { - xrpow[j + l] *= ifqstep34; - if (xrpow[j + l] > cod_info.xrpow_max) - cod_info.xrpow_max = xrpow[j + l]; - } - } - cod_info.scalefac[sfb] = s >> 1; - } - cod_info.preflag = 0; - cod_info.scalefac_scale = 1; - } - - /** - * Takehiro Tominaga 2000-xx-xx - * - * increases the subblock gain and adjusts scalefactors - */ - function inc_subblock_gain(gfc, cod_info, xrpow) { - var sfb; - var scalefac = cod_info.scalefac; - - /* subbloc_gain can't do anything in the long block region */ - for (sfb = 0; sfb < cod_info.sfb_lmax; sfb++) { - if (scalefac[sfb] >= 16) - return true; - } - - for (var window = 0; window < 3; window++) { - var s1 = 0; - var s2 = 0; - - for (sfb = cod_info.sfb_lmax + window; sfb < cod_info.sfbdivide; sfb += 3) { - if (s1 < scalefac[sfb]) - s1 = scalefac[sfb]; - } - for (; sfb < cod_info.sfbmax; sfb += 3) { - if (s2 < scalefac[sfb]) - s2 = scalefac[sfb]; - } - - if (s1 < 16 && s2 < 8) - continue; - - if (cod_info.subblock_gain[window] >= 7) - return true; - - /* - * even though there is no scalefactor for sfb12 subblock gain - * affects upper frequencies too, that's why we have to go up to - * SBMAX_s - */ - cod_info.subblock_gain[window]++; - var j = gfc.scalefac_band.l[cod_info.sfb_lmax]; - for (sfb = cod_info.sfb_lmax + window; sfb < cod_info.sfbmax; sfb += 3) { - var amp; - var width = cod_info.width[sfb]; - var s = scalefac[sfb]; - assert(s >= 0); - s = s - (4 >> cod_info.scalefac_scale); - if (s >= 0) { - scalefac[sfb] = s; - j += width * 3; - continue; - } - - scalefac[sfb] = 0; - { - var gain = 210 + (s << (cod_info.scalefac_scale + 1)); - amp = qupvt.IPOW20(gain); - } - j += width * (window + 1); - for (var l = -width; l < 0; l++) { - xrpow[j + l] *= amp; - if (xrpow[j + l] > cod_info.xrpow_max) - cod_info.xrpow_max = xrpow[j + l]; - } - j += width * (3 - window - 1); - } - - { - var amp = qupvt.IPOW20(202); - j += cod_info.width[sfb] * (window + 1); - for (var l = -cod_info.width[sfb]; l < 0; l++) { - xrpow[j + l] *= amp; - if (xrpow[j + l] > cod_info.xrpow_max) - cod_info.xrpow_max = xrpow[j + l]; - } - } - } - return false; - } - - /** - *
-     *  Takehiro Tominaga /date??
-     *  Robert Hegemann 2000-09-06: made a function of it
-     *
-     *  amplifies scalefactor bands,
-     *   - if all are already amplified returns 0
-     *   - if some bands are amplified too much:
-     *      * try to increase scalefac_scale
-     *      * if already scalefac_scale was set
-     *          try on short blocks to increase subblock gain
-     * 
- */ - function balance_noise(gfp, cod_info, distort, xrpow, bRefine) { - var gfc = gfp.internal_flags; - - amp_scalefac_bands(gfp, cod_info, distort, xrpow, bRefine); - - /* - * check to make sure we have not amplified too much loop_break returns - * 0 if there is an unamplified scalefac scale_bitcount returns 0 if no - * scalefactors are too large - */ - - var status = loop_break(cod_info); - - if (status) - return false; - /* all bands amplified */ - - /* - * not all scalefactors have been amplified. so these scalefacs are - * possibly valid. encode them: - */ - if (gfc.mode_gr == 2) - status = tk.scale_bitcount(cod_info); - else - status = tk.scale_bitcount_lsf(gfc, cod_info); - - if (!status) - return true; - /* amplified some bands not exceeding limits */ - - /* - * some scalefactors are too large. lets try setting scalefac_scale=1 - */ - if (gfc.noise_shaping > 1) { - Arrays.fill(gfc.pseudohalf, 0); - if (0 == cod_info.scalefac_scale) { - inc_scalefac_scale(cod_info, xrpow); - status = false; - } else { - if (cod_info.block_type == Encoder.SHORT_TYPE - && gfc.subblock_gain > 0) { - status = (inc_subblock_gain(gfc, cod_info, xrpow) || loop_break(cod_info)); - } - } - } - - if (!status) { - if (gfc.mode_gr == 2) - status = tk.scale_bitcount(cod_info); - else - status = tk.scale_bitcount_lsf(gfc, cod_info); - } - return !status; - } - - /** - *
-     *  Function: The outer iteration loop controls the masking conditions
-     *  of all scalefactorbands. It computes the best scalefac and
-     *  global gain. This module calls the inner iteration loop
-     *
-     *  mt 5/99 completely rewritten to allow for bit reservoir control,
-     *  mid/side channels with L/R or mid/side masking thresholds,
-     *  and chooses best quantization instead of last quantization when
-     *  no distortion free quantization can be found.
-     *
-     *  added VBR support mt 5/99
-     *
-     *  some code shuffle rh 9/00
-     * 
- * - * @param l3_xmin - * allowed distortion - * @param xrpow - * coloured magnitudes of spectral - * @param targ_bits - * maximum allowed bits - */ - this.outer_loop = function (gfp, cod_info, l3_xmin, xrpow, ch, targ_bits) { - var gfc = gfp.internal_flags; - var cod_info_w = new GrInfo(); - var save_xrpow = new_float(576); - var distort = new_float(L3Side.SFBMAX); - var best_noise_info = new CalcNoiseResult(); - var better; - var prev_noise = new CalcNoiseData(); - var best_part2_3_length = 9999999; - var bEndOfSearch = false; - var bRefine = false; - var best_ggain_pass1 = 0; - - bin_search_StepSize(gfc, cod_info, targ_bits, ch, xrpow); - - if (0 == gfc.noise_shaping) - /* fast mode, no noise shaping, we are ready */ - return 100; - /* default noise_info.over_count */ - - /* compute the distortion in this quantization */ - /* coefficients and thresholds both l/r (or both mid/side) */ - qupvt.calc_noise(cod_info, l3_xmin, distort, best_noise_info, - prev_noise); - best_noise_info.bits = cod_info.part2_3_length; - - cod_info_w.assign(cod_info); - var age = 0; - System.arraycopy(xrpow, 0, save_xrpow, 0, 576); - - while (!bEndOfSearch) { - /* BEGIN MAIN LOOP */ - do { - var noise_info = new CalcNoiseResult(); - var search_limit; - var maxggain = 255; - - /* - * When quantization with no distorted bands is found, allow up - * to X new unsuccesful tries in serial. This gives us more - * possibilities for different quant_compare modes. Much more - * than 3 makes not a big difference, it is only slower. - */ - - if ((gfc.substep_shaping & 2) != 0) { - search_limit = 20; - } else { - search_limit = 3; - } - - /* - * Check if the last scalefactor band is distorted. in VBR mode - * we can't get rid of the distortion, so quit now and VBR mode - * will try again with more bits. (makes a 10% speed increase, - * the files I tested were binary identical, 2000/05/20 Robert - * Hegemann) distort[] > 1 means noise > allowed noise - */ - if (gfc.sfb21_extra) { - if (distort[cod_info_w.sfbmax] > 1.0) - break; - if (cod_info_w.block_type == Encoder.SHORT_TYPE - && (distort[cod_info_w.sfbmax + 1] > 1.0 || distort[cod_info_w.sfbmax + 2] > 1.0)) - break; - } - - /* try a new scalefactor conbination on cod_info_w */ - if (!balance_noise(gfp, cod_info_w, distort, xrpow, bRefine)) - break; - if (cod_info_w.scalefac_scale != 0) - maxggain = 254; - - /* - * inner_loop starts with the initial quantization step computed - * above and slowly increases until the bits < huff_bits. Thus - * it is important not to start with too large of an inital - * quantization step. Too small is ok, but inner_loop will take - * longer - */ - var huff_bits = targ_bits - cod_info_w.part2_length; - if (huff_bits <= 0) - break; - - /* - * increase quantizer stepsize until needed bits are below - * maximum - */ - while ((cod_info_w.part2_3_length = tk.count_bits(gfc, xrpow, - cod_info_w, prev_noise)) > huff_bits - && cod_info_w.global_gain <= maxggain) - cod_info_w.global_gain++; - - if (cod_info_w.global_gain > maxggain) - break; - - if (best_noise_info.over_count == 0) { - - while ((cod_info_w.part2_3_length = tk.count_bits(gfc, - xrpow, cod_info_w, prev_noise)) > best_part2_3_length - && cod_info_w.global_gain <= maxggain) - cod_info_w.global_gain++; - - if (cod_info_w.global_gain > maxggain) - break; - } - - /* compute the distortion in this quantization */ - qupvt.calc_noise(cod_info_w, l3_xmin, distort, noise_info, - prev_noise); - noise_info.bits = cod_info_w.part2_3_length; - - /* - * check if this quantization is better than our saved - * quantization - */ - if (cod_info.block_type != Encoder.SHORT_TYPE) { - // NORM, START or STOP type - better = gfp.quant_comp; - } else - better = gfp.quant_comp_short; - - better = quant_compare(better, best_noise_info, noise_info, - cod_info_w, distort) ? 1 : 0; - - /* save data so we can restore this quantization later */ - if (better != 0) { - best_part2_3_length = cod_info.part2_3_length; - best_noise_info = noise_info; - cod_info.assign(cod_info_w); - age = 0; - /* save data so we can restore this quantization later */ - /* store for later reuse */ - System.arraycopy(xrpow, 0, save_xrpow, 0, 576); - } else { - /* early stop? */ - if (gfc.full_outer_loop == 0) { - if (++age > search_limit - && best_noise_info.over_count == 0) - break; - if ((gfc.noise_shaping_amp == 3) && bRefine && age > 30) - break; - if ((gfc.noise_shaping_amp == 3) - && bRefine - && (cod_info_w.global_gain - best_ggain_pass1) > 15) - break; - } - } - } while ((cod_info_w.global_gain + cod_info_w.scalefac_scale) < 255); - - if (gfc.noise_shaping_amp == 3) { - if (!bRefine) { - /* refine search */ - cod_info_w.assign(cod_info); - System.arraycopy(save_xrpow, 0, xrpow, 0, 576); - age = 0; - best_ggain_pass1 = cod_info_w.global_gain; - - bRefine = true; - } else { - /* search already refined, stop */ - bEndOfSearch = true; - } - - } else { - bEndOfSearch = true; - } - } - - assert((cod_info.global_gain + cod_info.scalefac_scale) <= 255); - /* - * finish up - */ - if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh) - /* restore for reuse on next try */ - System.arraycopy(save_xrpow, 0, xrpow, 0, 576); - /* - * do the 'substep shaping' - */ - else if ((gfc.substep_shaping & 1) != 0) - trancate_smallspectrums(gfc, cod_info, l3_xmin, xrpow); - - return best_noise_info.over_count; - } - - /** - * Robert Hegemann 2000-09-06 - * - * update reservoir status after FINAL quantization/bitrate - */ - this.iteration_finish_one = function (gfc, gr, ch) { - var l3_side = gfc.l3_side; - var cod_info = l3_side.tt[gr][ch]; - - /* - * try some better scalefac storage - */ - tk.best_scalefac_store(gfc, gr, ch, l3_side); - - /* - * best huffman_divide may save some bits too - */ - if (gfc.use_best_huffman == 1) - tk.best_huffman_divide(gfc, cod_info); - - /* - * update reservoir status after FINAL quantization/bitrate - */ - rv.ResvAdjust(gfc, cod_info); - }; - - /** - * - * 2000-09-04 Robert Hegemann - * - * @param l3_xmin - * allowed distortion of the scalefactor - * @param xrpow - * coloured magnitudes of spectral values - */ - this.VBR_encode_granule = function (gfp, cod_info, l3_xmin, xrpow, ch, min_bits, max_bits) { - var gfc = gfp.internal_flags; - var bst_cod_info = new GrInfo(); - var bst_xrpow = new_float(576); - var Max_bits = max_bits; - var real_bits = max_bits + 1; - var this_bits = (max_bits + min_bits) / 2; - var dbits, over, found = 0; - var sfb21_extra = gfc.sfb21_extra; - - assert(Max_bits <= LameInternalFlags.MAX_BITS_PER_CHANNEL); - Arrays.fill(bst_cod_info.l3_enc, 0); - - /* - * search within round about 40 bits of optimal - */ - do { - assert(this_bits >= min_bits); - assert(this_bits <= max_bits); - assert(min_bits <= max_bits); - - if (this_bits > Max_bits - 42) - gfc.sfb21_extra = false; - else - gfc.sfb21_extra = sfb21_extra; - - over = outer_loop(gfp, cod_info, l3_xmin, xrpow, ch, this_bits); - - /* - * is quantization as good as we are looking for ? in this case: is - * no scalefactor band distorted? - */ - if (over <= 0) { - found = 1; - /* - * now we know it can be done with "real_bits" and maybe we can - * skip some iterations - */ - real_bits = cod_info.part2_3_length; - - /* - * store best quantization so far - */ - bst_cod_info.assign(cod_info); - System.arraycopy(xrpow, 0, bst_xrpow, 0, 576); - - /* - * try with fewer bits - */ - max_bits = real_bits - 32; - dbits = max_bits - min_bits; - this_bits = (max_bits + min_bits) / 2; - } else { - /* - * try with more bits - */ - min_bits = this_bits + 32; - dbits = max_bits - min_bits; - this_bits = (max_bits + min_bits) / 2; - - if (found != 0) { - found = 2; - /* - * start again with best quantization so far - */ - cod_info.assign(bst_cod_info); - System.arraycopy(bst_xrpow, 0, xrpow, 0, 576); - } - } - } while (dbits > 12); - - gfc.sfb21_extra = sfb21_extra; - - /* - * found=0 => nothing found, use last one found=1 => we just found the - * best and left the loop found=2 => we restored a good one and have now - * l3_enc to restore too - */ - if (found == 2) { - System.arraycopy(bst_cod_info.l3_enc, 0, cod_info.l3_enc, 0, 576); - } - assert(cod_info.part2_3_length <= Max_bits); - } - - /** - * Robert Hegemann 2000-09-05 - * - * calculates * how many bits are available for analog silent granules * how - * many bits to use for the lowest allowed bitrate * how many bits each - * bitrate would provide - */ - this.get_framebits = function (gfp, frameBits) { - var gfc = gfp.internal_flags; - - /* - * always use at least this many bits per granule per channel unless we - * detect analog silence, see below - */ - gfc.bitrate_index = gfc.VBR_min_bitrate; - var bitsPerFrame = bs.getframebits(gfp); - - /* - * bits for analog silence - */ - gfc.bitrate_index = 1; - bitsPerFrame = bs.getframebits(gfp); - - for (var i = 1; i <= gfc.VBR_max_bitrate; i++) { - gfc.bitrate_index = i; - var mb = new MeanBits(bitsPerFrame); - frameBits[i] = rv.ResvFrameBegin(gfp, mb); - bitsPerFrame = mb.bits; - } - }; - - /* RH: this one needs to be overhauled sometime */ - - /** - *
-     *  2000-09-04 Robert Hegemann
-     *
-     *  * converts LR to MS coding when necessary
-     *  * calculates allowed/adjusted quantization noise amounts
-     *  * detects analog silent frames
-     *
-     *  some remarks:
-     *  - lower masking depending on Quality setting
-     *  - quality control together with adjusted ATH MDCT scaling
-     *    on lower quality setting allocate more noise from
-     *    ATH masking, and on higher quality setting allocate
-     *    less noise from ATH masking.
-     *  - experiments show that going more than 2dB over GPSYCHO's
-     *    limits ends up in very annoying artefacts
-     * 
- */ - this.VBR_old_prepare = function (gfp, pe, ms_ener_ratio, ratio, l3_xmin, frameBits, min_bits, - max_bits, bands) { - var gfc = gfp.internal_flags; - - var masking_lower_db, adjust = 0.0; - var analog_silence = 1; - var bits = 0; - - gfc.bitrate_index = gfc.VBR_max_bitrate; - var avg = rv.ResvFrameBegin(gfp, new MeanBits(0)) / gfc.mode_gr; - - get_framebits(gfp, frameBits); - - for (var gr = 0; gr < gfc.mode_gr; gr++) { - var mxb = qupvt.on_pe(gfp, pe, max_bits[gr], avg, gr, 0); - if (gfc.mode_ext == Encoder.MPG_MD_MS_LR) { - ms_convert(gfc.l3_side, gr); - qupvt.reduce_side(max_bits[gr], ms_ener_ratio[gr], avg, mxb); - } - for (var ch = 0; ch < gfc.channels_out; ++ch) { - var cod_info = gfc.l3_side.tt[gr][ch]; - - if (cod_info.block_type != Encoder.SHORT_TYPE) { - // NORM, START or STOP type - adjust = 1.28 / (1 + Math - .exp(3.5 - pe[gr][ch] / 300.)) - 0.05; - masking_lower_db = gfc.PSY.mask_adjust - adjust; - } else { - adjust = 2.56 / (1 + Math - .exp(3.5 - pe[gr][ch] / 300.)) - 0.14; - masking_lower_db = gfc.PSY.mask_adjust_short - adjust; - } - gfc.masking_lower = Math.pow(10.0, - masking_lower_db * 0.1); - - init_outer_loop(gfc, cod_info); - bands[gr][ch] = qupvt.calc_xmin(gfp, ratio[gr][ch], cod_info, - l3_xmin[gr][ch]); - if (bands[gr][ch] != 0) - analog_silence = 0; - - min_bits[gr][ch] = 126; - - bits += max_bits[gr][ch]; - } - } - for (var gr = 0; gr < gfc.mode_gr; gr++) { - for (var ch = 0; ch < gfc.channels_out; ch++) { - if (bits > frameBits[gfc.VBR_max_bitrate]) { - max_bits[gr][ch] *= frameBits[gfc.VBR_max_bitrate]; - max_bits[gr][ch] /= bits; - } - if (min_bits[gr][ch] > max_bits[gr][ch]) - min_bits[gr][ch] = max_bits[gr][ch]; - - } - /* for ch */ - } - /* for gr */ - - return analog_silence; - }; - - this.bitpressure_strategy = function (gfc, l3_xmin, min_bits, max_bits) { - for (var gr = 0; gr < gfc.mode_gr; gr++) { - for (var ch = 0; ch < gfc.channels_out; ch++) { - var gi = gfc.l3_side.tt[gr][ch]; - var pxmin = l3_xmin[gr][ch]; - var pxminPos = 0; - for (var sfb = 0; sfb < gi.psy_lmax; sfb++) - pxmin[pxminPos++] *= 1. + .029 * sfb * sfb - / Encoder.SBMAX_l / Encoder.SBMAX_l; - - if (gi.block_type == Encoder.SHORT_TYPE) { - for (var sfb = gi.sfb_smin; sfb < Encoder.SBMAX_s; sfb++) { - pxmin[pxminPos++] *= 1. + .029 * sfb * sfb - / Encoder.SBMAX_s / Encoder.SBMAX_s; - pxmin[pxminPos++] *= 1. + .029 * sfb * sfb - / Encoder.SBMAX_s / Encoder.SBMAX_s; - pxmin[pxminPos++] *= 1. + .029 * sfb * sfb - / Encoder.SBMAX_s / Encoder.SBMAX_s; - } - } - max_bits[gr][ch] = 0 | Math.max(min_bits[gr][ch], - 0.9 * max_bits[gr][ch]); - } - } - }; - - this.VBR_new_prepare = function (gfp, pe, ratio, l3_xmin, frameBits, max_bits) { - var gfc = gfp.internal_flags; - - var analog_silence = 1; - var avg = 0, bits = 0; - var maximum_framebits; - - if (!gfp.free_format) { - gfc.bitrate_index = gfc.VBR_max_bitrate; - - var mb = new MeanBits(avg); - rv.ResvFrameBegin(gfp, mb); - avg = mb.bits; - - get_framebits(gfp, frameBits); - maximum_framebits = frameBits[gfc.VBR_max_bitrate]; - } else { - gfc.bitrate_index = 0; - var mb = new MeanBits(avg); - maximum_framebits = rv.ResvFrameBegin(gfp, mb); - avg = mb.bits; - frameBits[0] = maximum_framebits; - } - - for (var gr = 0; gr < gfc.mode_gr; gr++) { - qupvt.on_pe(gfp, pe, max_bits[gr], avg, gr, 0); - if (gfc.mode_ext == Encoder.MPG_MD_MS_LR) { - ms_convert(gfc.l3_side, gr); - } - for (var ch = 0; ch < gfc.channels_out; ++ch) { - var cod_info = gfc.l3_side.tt[gr][ch]; - - gfc.masking_lower = Math.pow(10.0, - gfc.PSY.mask_adjust * 0.1); - - init_outer_loop(gfc, cod_info); - if (0 != qupvt.calc_xmin(gfp, ratio[gr][ch], cod_info, - l3_xmin[gr][ch])) - analog_silence = 0; - - bits += max_bits[gr][ch]; - } - } - for (var gr = 0; gr < gfc.mode_gr; gr++) { - for (var ch = 0; ch < gfc.channels_out; ch++) { - if (bits > maximum_framebits) { - max_bits[gr][ch] *= maximum_framebits; - max_bits[gr][ch] /= bits; - } - - } - /* for ch */ - } - /* for gr */ - - return analog_silence; - }; - - /** - * calculates target bits for ABR encoding - * - * mt 2000/05/31 - */ - this.calc_target_bits = function (gfp, pe, ms_ener_ratio, targ_bits, analog_silence_bits, max_frame_bits) { - var gfc = gfp.internal_flags; - var l3_side = gfc.l3_side; - var res_factor; - var gr, ch, totbits, mean_bits = 0; - - gfc.bitrate_index = gfc.VBR_max_bitrate; - var mb = new MeanBits(mean_bits); - max_frame_bits[0] = rv.ResvFrameBegin(gfp, mb); - mean_bits = mb.bits; - - gfc.bitrate_index = 1; - mean_bits = bs.getframebits(gfp) - gfc.sideinfo_len * 8; - analog_silence_bits[0] = mean_bits / (gfc.mode_gr * gfc.channels_out); - - mean_bits = gfp.VBR_mean_bitrate_kbps * gfp.framesize * 1000; - if ((gfc.substep_shaping & 1) != 0) - mean_bits *= 1.09; - mean_bits /= gfp.out_samplerate; - mean_bits -= gfc.sideinfo_len * 8; - mean_bits /= (gfc.mode_gr * gfc.channels_out); - - /** - *
-         *           res_factor is the percentage of the target bitrate that should
-         *           be used on average.  the remaining bits are added to the
-         *           bitreservoir and used for difficult to encode frames.
-         *
-         *           Since we are tracking the average bitrate, we should adjust
-         *           res_factor "on the fly", increasing it if the average bitrate
-         *           is greater than the requested bitrate, and decreasing it
-         *           otherwise.  Reasonable ranges are from .9 to 1.0
-         *
-         *           Until we get the above suggestion working, we use the following
-         *           tuning:
-         *           compression ratio    res_factor
-         *           5.5  (256kbps)         1.0      no need for bitreservoir
-         *           11   (128kbps)         .93      7% held for reservoir
-         *
-         *           with linear interpolation for other values.
-         * 
- */ - res_factor = .93 + .07 * (11.0 - gfp.compression_ratio) - / (11.0 - 5.5); - if (res_factor < .90) - res_factor = .90; - if (res_factor > 1.00) - res_factor = 1.00; - - for (gr = 0; gr < gfc.mode_gr; gr++) { - var sum = 0; - for (ch = 0; ch < gfc.channels_out; ch++) { - targ_bits[gr][ch] = (int)(res_factor * mean_bits); - - if (pe[gr][ch] > 700) { - var add_bits = (int)((pe[gr][ch] - 700) / 1.4); - - var cod_info = l3_side.tt[gr][ch]; - targ_bits[gr][ch] = (int)(res_factor * mean_bits); - - /* short blocks use a little extra, no matter what the pe */ - if (cod_info.block_type == Encoder.SHORT_TYPE) { - if (add_bits < mean_bits / 2) - add_bits = mean_bits / 2; - } - /* at most increase bits by 1.5*average */ - if (add_bits > mean_bits * 3 / 2) - add_bits = mean_bits * 3 / 2; - else if (add_bits < 0) - add_bits = 0; - - targ_bits[gr][ch] += add_bits; - } - if (targ_bits[gr][ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL) { - targ_bits[gr][ch] = LameInternalFlags.MAX_BITS_PER_CHANNEL; - } - sum += targ_bits[gr][ch]; - } - /* for ch */ - if (sum > LameInternalFlags.MAX_BITS_PER_GRANULE) { - for (ch = 0; ch < gfc.channels_out; ++ch) { - targ_bits[gr][ch] *= LameInternalFlags.MAX_BITS_PER_GRANULE; - targ_bits[gr][ch] /= sum; - } - } - } - /* for gr */ - - if (gfc.mode_ext == Encoder.MPG_MD_MS_LR) - for (gr = 0; gr < gfc.mode_gr; gr++) { - qupvt.reduce_side(targ_bits[gr], ms_ener_ratio[gr], mean_bits - * gfc.channels_out, - LameInternalFlags.MAX_BITS_PER_GRANULE); - } - - /* - * sum target bits - */ - totbits = 0; - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - if (targ_bits[gr][ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL) - targ_bits[gr][ch] = LameInternalFlags.MAX_BITS_PER_CHANNEL; - totbits += targ_bits[gr][ch]; - } - } - - /* - * repartion target bits if needed - */ - if (totbits > max_frame_bits[0]) { - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - targ_bits[gr][ch] *= max_frame_bits[0]; - targ_bits[gr][ch] /= totbits; - } - } - } - } - -} - -module.exports = Quantize; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/QuantizePVT.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/QuantizePVT.js deleted file mode 100644 index b849a5883..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/QuantizePVT.js +++ /dev/null @@ -1,1037 +0,0 @@ -/* - * quantize_pvt source file - * - * Copyright (c) 1999-2002 Takehiro Tominaga - * Copyright (c) 2000-2002 Robert Hegemann - * Copyright (c) 2001 Naoki Shibata - * Copyright (c) 2002-2005 Gabriel Bouvigne - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: QuantizePVT.java,v 1.24 2011/05/24 20:48:06 kenchis Exp $ */ -var ScaleFac = require('./ScaleFac.js'); -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -var Encoder = require('./Encoder.js'); -var MeanBits = require('./MeanBits.js'); -var LameInternalFlags = require('./LameInternalFlags.js'); - -QuantizePVT.Q_MAX = (256 + 1); -QuantizePVT.Q_MAX2 = 116; -QuantizePVT.LARGE_BITS = 100000; -QuantizePVT.IXMAX_VAL = 8206; - -function QuantizePVT() { - var BitStream = require('./BitStream.js'); - var tak = null; - var rv = null; - var psy = null; - - this.setModules = function (_tk, _rv, _psy) { - tak = _tk; - rv = _rv; - psy = _psy; - }; - - function POW20(x) { - assert(0 <= (x + QuantizePVT.Q_MAX2) && x < QuantizePVT.Q_MAX); - return pow20[x + QuantizePVT.Q_MAX2]; - } - - this.IPOW20 = function (x) { - assert(0 <= x && x < QuantizePVT.Q_MAX); - return ipow20[x]; - } - - /** - * smallest such that 1.0+DBL_EPSILON != 1.0 - */ - var DBL_EPSILON = 2.2204460492503131e-016; - - /** - * ix always <= 8191+15. see count_bits() - */ - var IXMAX_VAL = QuantizePVT.IXMAX_VAL; - - var PRECALC_SIZE = (IXMAX_VAL + 2); - - var Q_MAX = QuantizePVT.Q_MAX; - - - /** - * - * minimum possible number of - * -cod_info.global_gain + ((scalefac[] + (cod_info.preflag ? pretab[sfb] : 0)) - * << (cod_info.scalefac_scale + 1)) + cod_info.subblock_gain[cod_info.window[sfb]] * 8; - * - * for long block, 0+((15+3)<<2) = 18*4 = 72 - * for short block, 0+(15<<2)+7*8 = 15*4+56 = 116 - * - */ - var Q_MAX2 = QuantizePVT.Q_MAX2; - - var LARGE_BITS = QuantizePVT.LARGE_BITS; - - - /** - * Assuming dynamic range=96dB, this value should be 92 - */ - var NSATHSCALE = 100; - - /** - * The following table is used to implement the scalefactor partitioning for - * MPEG2 as described in section 2.4.3.2 of the IS. The indexing corresponds - * to the way the tables are presented in the IS: - * - * [table_number][row_in_table][column of nr_of_sfb] - */ - this.nr_of_sfb_block = [ - [[6, 5, 5, 5], [9, 9, 9, 9], [6, 9, 9, 9]], - [[6, 5, 7, 3], [9, 9, 12, 6], [6, 9, 12, 6]], - [[11, 10, 0, 0], [18, 18, 0, 0], [15, 18, 0, 0]], - [[7, 7, 7, 0], [12, 12, 12, 0], [6, 15, 12, 0]], - [[6, 6, 6, 3], [12, 9, 9, 6], [6, 12, 9, 6]], - [[8, 8, 5, 0], [15, 12, 9, 0], [6, 18, 9, 0]]]; - - /** - * Table B.6: layer3 preemphasis - */ - var pretab = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, - 2, 2, 3, 3, 3, 2, 0]; - this.pretab = pretab; - - /** - * Here are MPEG1 Table B.8 and MPEG2 Table B.1 -- Layer III scalefactor - * bands.
- * Index into this using a method such as:
- * idx = fr_ps.header.sampling_frequency + (fr_ps.header.version * 3) - */ - this.sfBandIndex = [ - // Table B.2.b: 22.05 kHz - new ScaleFac([0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, - 522, 576], - [0, 4, 8, 12, 18, 24, 32, 42, 56, 74, 100, 132, 174, 192] - , [0, 0, 0, 0, 0, 0, 0] // sfb21 pseudo sub bands - , [0, 0, 0, 0, 0, 0, 0] // sfb12 pseudo sub bands - ), - /* Table B.2.c: 24 kHz */ /* docs: 332. mpg123(broken): 330 */ - new ScaleFac([0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 114, 136, 162, 194, 232, 278, 332, 394, 464, - 540, 576], - [0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 136, 180, 192] - , [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */ - , [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */ - ), - /* Table B.2.a: 16 kHz */ - new ScaleFac([0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, - 522, 576], - [0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192] - , [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */ - , [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */ - ), - /* Table B.8.b: 44.1 kHz */ - new ScaleFac([0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418, - 576], - [0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84, 106, 136, 192] - , [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */ - , [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */ - ), - /* Table B.8.c: 48 kHz */ - new ScaleFac([0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330, 384, - 576], - [0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80, 100, 126, 192] - , [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */ - , [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */ - ), - /* Table B.8.a: 32 kHz */ - new ScaleFac([0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448, 550, - 576], - [0, 4, 8, 12, 16, 22, 30, 42, 58, 78, 104, 138, 180, 192] - , [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */ - , [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */ - ), - /* MPEG-2.5 11.025 kHz */ - new ScaleFac([0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, - 522, 576], - [0 / 3, 12 / 3, 24 / 3, 36 / 3, 54 / 3, 78 / 3, 108 / 3, 144 / 3, 186 / 3, 240 / 3, 312 / 3, - 402 / 3, 522 / 3, 576 / 3] - , [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */ - , [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */ - ), - /* MPEG-2.5 12 kHz */ - new ScaleFac([0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, - 522, 576], - [0 / 3, 12 / 3, 24 / 3, 36 / 3, 54 / 3, 78 / 3, 108 / 3, 144 / 3, 186 / 3, 240 / 3, 312 / 3, - 402 / 3, 522 / 3, 576 / 3] - , [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */ - , [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */ - ), - /* MPEG-2.5 8 kHz */ - new ScaleFac([0, 12, 24, 36, 48, 60, 72, 88, 108, 132, 160, 192, 232, 280, 336, 400, 476, 566, 568, 570, - 572, 574, 576], - [0 / 3, 24 / 3, 48 / 3, 72 / 3, 108 / 3, 156 / 3, 216 / 3, 288 / 3, 372 / 3, 480 / 3, 486 / 3, - 492 / 3, 498 / 3, 576 / 3] - , [0, 0, 0, 0, 0, 0, 0] /* sfb21 pseudo sub bands */ - , [0, 0, 0, 0, 0, 0, 0] /* sfb12 pseudo sub bands */ - ) - ]; - - var pow20 = new_float(Q_MAX + Q_MAX2 + 1); - var ipow20 = new_float(Q_MAX); - var pow43 = new_float(PRECALC_SIZE); - - var adj43 = new_float(PRECALC_SIZE); - this.adj43 = adj43; - - /** - *
-     * compute the ATH for each scalefactor band cd range: 0..96db
-     *
-     * Input: 3.3kHz signal 32767 amplitude (3.3kHz is where ATH is smallest =
-     * -5db) longblocks: sfb=12 en0/bw=-11db max_en0 = 1.3db shortblocks: sfb=5
-     * -9db 0db
-     *
-     * Input: 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated) longblocks: amp=1
-     * sfb=12 en0/bw=-103 db max_en0 = -92db amp=32767 sfb=12 -12 db -1.4db
-     *
-     * Input: 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated) shortblocks: amp=1
-     * sfb=5 en0/bw= -99 -86 amp=32767 sfb=5 -9 db 4db
-     *
-     *
-     * MAX energy of largest wave at 3.3kHz = 1db AVE energy of largest wave at
-     * 3.3kHz = -11db Let's take AVE: -11db = maximum signal in sfb=12. Dynamic
-     * range of CD: 96db. Therefor energy of smallest audible wave in sfb=12 =
-     * -11 - 96 = -107db = ATH at 3.3kHz.
-     *
-     * ATH formula for this wave: -5db. To adjust to LAME scaling, we need ATH =
-     * ATH_formula - 103 (db) ATH = ATH * 2.5e-10 (ener)
-     * 
- */ - function ATHmdct(gfp, f) { - var ath = psy.ATHformula(f, gfp); - - ath -= NSATHSCALE; - - /* modify the MDCT scaling for the ATH and convert to energy */ - ath = Math.pow(10.0, ath / 10.0 + gfp.ATHlower); - return ath; - } - - function compute_ath(gfp) { - var ATH_l = gfp.internal_flags.ATH.l; - var ATH_psfb21 = gfp.internal_flags.ATH.psfb21; - var ATH_s = gfp.internal_flags.ATH.s; - var ATH_psfb12 = gfp.internal_flags.ATH.psfb12; - var gfc = gfp.internal_flags; - var samp_freq = gfp.out_samplerate; - - for (var sfb = 0; sfb < Encoder.SBMAX_l; sfb++) { - var start = gfc.scalefac_band.l[sfb]; - var end = gfc.scalefac_band.l[sfb + 1]; - ATH_l[sfb] = Float.MAX_VALUE; - for (var i = start; i < end; i++) { - var freq = i * samp_freq / (2 * 576); - var ATH_f = ATHmdct(gfp, freq); - /* freq in kHz */ - ATH_l[sfb] = Math.min(ATH_l[sfb], ATH_f); - } - } - - for (var sfb = 0; sfb < Encoder.PSFB21; sfb++) { - var start = gfc.scalefac_band.psfb21[sfb]; - var end = gfc.scalefac_band.psfb21[sfb + 1]; - ATH_psfb21[sfb] = Float.MAX_VALUE; - for (var i = start; i < end; i++) { - var freq = i * samp_freq / (2 * 576); - var ATH_f = ATHmdct(gfp, freq); - /* freq in kHz */ - ATH_psfb21[sfb] = Math.min(ATH_psfb21[sfb], ATH_f); - } - } - - for (var sfb = 0; sfb < Encoder.SBMAX_s; sfb++) { - var start = gfc.scalefac_band.s[sfb]; - var end = gfc.scalefac_band.s[sfb + 1]; - ATH_s[sfb] = Float.MAX_VALUE; - for (var i = start; i < end; i++) { - var freq = i * samp_freq / (2 * 192); - var ATH_f = ATHmdct(gfp, freq); - /* freq in kHz */ - ATH_s[sfb] = Math.min(ATH_s[sfb], ATH_f); - } - ATH_s[sfb] *= (gfc.scalefac_band.s[sfb + 1] - gfc.scalefac_band.s[sfb]); - } - - for (var sfb = 0; sfb < Encoder.PSFB12; sfb++) { - var start = gfc.scalefac_band.psfb12[sfb]; - var end = gfc.scalefac_band.psfb12[sfb + 1]; - ATH_psfb12[sfb] = Float.MAX_VALUE; - for (var i = start; i < end; i++) { - var freq = i * samp_freq / (2 * 192); - var ATH_f = ATHmdct(gfp, freq); - /* freq in kHz */ - ATH_psfb12[sfb] = Math.min(ATH_psfb12[sfb], ATH_f); - } - /* not sure about the following */ - ATH_psfb12[sfb] *= (gfc.scalefac_band.s[13] - gfc.scalefac_band.s[12]); - } - - /* - * no-ATH mode: reduce ATH to -200 dB - */ - if (gfp.noATH) { - for (var sfb = 0; sfb < Encoder.SBMAX_l; sfb++) { - ATH_l[sfb] = 1E-20; - } - for (var sfb = 0; sfb < Encoder.PSFB21; sfb++) { - ATH_psfb21[sfb] = 1E-20; - } - for (var sfb = 0; sfb < Encoder.SBMAX_s; sfb++) { - ATH_s[sfb] = 1E-20; - } - for (var sfb = 0; sfb < Encoder.PSFB12; sfb++) { - ATH_psfb12[sfb] = 1E-20; - } - } - - /* - * work in progress, don't rely on it too much - */ - gfc.ATH.floor = 10. * Math.log10(ATHmdct(gfp, -1.)); - } - - /** - * initialization for iteration_loop - */ - this.iteration_init = function (gfp) { - var gfc = gfp.internal_flags; - var l3_side = gfc.l3_side; - var i; - - if (gfc.iteration_init_init == 0) { - gfc.iteration_init_init = 1; - - l3_side.main_data_begin = 0; - compute_ath(gfp); - - pow43[0] = 0.0; - for (i = 1; i < PRECALC_SIZE; i++) - pow43[i] = Math.pow(i, 4.0 / 3.0); - - for (i = 0; i < PRECALC_SIZE - 1; i++) - adj43[i] = ((i + 1) - Math.pow( - 0.5 * (pow43[i] + pow43[i + 1]), 0.75)); - adj43[i] = 0.5; - - for (i = 0; i < Q_MAX; i++) - ipow20[i] = Math.pow(2.0, (i - 210) * -0.1875); - for (i = 0; i <= Q_MAX + Q_MAX2; i++) - pow20[i] = Math.pow(2.0, (i - 210 - Q_MAX2) * 0.25); - - tak.huffman_init(gfc); - - { - var bass, alto, treble, sfb21; - - i = (gfp.exp_nspsytune >> 2) & 63; - if (i >= 32) - i -= 64; - bass = Math.pow(10, i / 4.0 / 10.0); - - i = (gfp.exp_nspsytune >> 8) & 63; - if (i >= 32) - i -= 64; - alto = Math.pow(10, i / 4.0 / 10.0); - - i = (gfp.exp_nspsytune >> 14) & 63; - if (i >= 32) - i -= 64; - treble = Math.pow(10, i / 4.0 / 10.0); - - /* - * to be compatible with Naoki's original code, the next 6 bits - * define only the amount of changing treble for sfb21 - */ - i = (gfp.exp_nspsytune >> 20) & 63; - if (i >= 32) - i -= 64; - sfb21 = treble * Math.pow(10, i / 4.0 / 10.0); - for (i = 0; i < Encoder.SBMAX_l; i++) { - var f; - if (i <= 6) - f = bass; - else if (i <= 13) - f = alto; - else if (i <= 20) - f = treble; - else - f = sfb21; - - gfc.nsPsy.longfact[i] = f; - } - for (i = 0; i < Encoder.SBMAX_s; i++) { - var f; - if (i <= 5) - f = bass; - else if (i <= 10) - f = alto; - else if (i <= 11) - f = treble; - else - f = sfb21; - - gfc.nsPsy.shortfact[i] = f; - } - } - } - } - - /** - * allocate bits among 2 channels based on PE
- * mt 6/99
- * bugfixes rh 8/01: often allocated more than the allowed 4095 bits - */ - this.on_pe = function (gfp, pe, - targ_bits, mean_bits, gr, cbr) { - var gfc = gfp.internal_flags; - var tbits = 0, bits; - var add_bits = new_int(2); - var ch; - - /* allocate targ_bits for granule */ - var mb = new MeanBits(tbits); - var extra_bits = rv.ResvMaxBits(gfp, mean_bits, mb, cbr); - tbits = mb.bits; - /* maximum allowed bits for this granule */ - var max_bits = tbits + extra_bits; - if (max_bits > LameInternalFlags.MAX_BITS_PER_GRANULE) { - // hard limit per granule - max_bits = LameInternalFlags.MAX_BITS_PER_GRANULE; - } - for (bits = 0, ch = 0; ch < gfc.channels_out; ++ch) { - /****************************************************************** - * allocate bits for each channel - ******************************************************************/ - targ_bits[ch] = Math.min(LameInternalFlags.MAX_BITS_PER_CHANNEL, - tbits / gfc.channels_out); - - add_bits[ch] = 0 | (targ_bits[ch] * pe[gr][ch] / 700.0 - targ_bits[ch]); - - /* at most increase bits by 1.5*average */ - if (add_bits[ch] > mean_bits * 3 / 4) - add_bits[ch] = mean_bits * 3 / 4; - if (add_bits[ch] < 0) - add_bits[ch] = 0; - - if (add_bits[ch] + targ_bits[ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL) - add_bits[ch] = Math.max(0, - LameInternalFlags.MAX_BITS_PER_CHANNEL - targ_bits[ch]); - - bits += add_bits[ch]; - } - if (bits > extra_bits) { - for (ch = 0; ch < gfc.channels_out; ++ch) { - add_bits[ch] = extra_bits * add_bits[ch] / bits; - } - } - - for (ch = 0; ch < gfc.channels_out; ++ch) { - targ_bits[ch] += add_bits[ch]; - extra_bits -= add_bits[ch]; - } - - for (bits = 0, ch = 0; ch < gfc.channels_out; ++ch) { - bits += targ_bits[ch]; - } - if (bits > LameInternalFlags.MAX_BITS_PER_GRANULE) { - var sum = 0; - for (ch = 0; ch < gfc.channels_out; ++ch) { - targ_bits[ch] *= LameInternalFlags.MAX_BITS_PER_GRANULE; - targ_bits[ch] /= bits; - sum += targ_bits[ch]; - } - assert(sum <= LameInternalFlags.MAX_BITS_PER_GRANULE); - } - - return max_bits; - } - - this.reduce_side = function (targ_bits, ms_ener_ratio, mean_bits, max_bits) { - assert(max_bits <= LameInternalFlags.MAX_BITS_PER_GRANULE); - assert(targ_bits[0] + targ_bits[1] <= LameInternalFlags.MAX_BITS_PER_GRANULE); - - /* - * ms_ener_ratio = 0: allocate 66/33 mid/side fac=.33 ms_ener_ratio =.5: - * allocate 50/50 mid/side fac= 0 - */ - /* 75/25 split is fac=.5 */ - var fac = .33 * (.5 - ms_ener_ratio) / .5; - if (fac < 0) - fac = 0; - if (fac > .5) - fac = .5; - - /* number of bits to move from side channel to mid channel */ - /* move_bits = fac*targ_bits[1]; */ - var move_bits = 0 | (fac * .5 * (targ_bits[0] + targ_bits[1])); - - if (move_bits > LameInternalFlags.MAX_BITS_PER_CHANNEL - targ_bits[0]) { - move_bits = LameInternalFlags.MAX_BITS_PER_CHANNEL - targ_bits[0]; - } - if (move_bits < 0) - move_bits = 0; - - if (targ_bits[1] >= 125) { - /* dont reduce side channel below 125 bits */ - if (targ_bits[1] - move_bits > 125) { - - /* if mid channel already has 2x more than average, dont bother */ - /* mean_bits = bits per granule (for both channels) */ - if (targ_bits[0] < mean_bits) - targ_bits[0] += move_bits; - targ_bits[1] -= move_bits; - } else { - targ_bits[0] += targ_bits[1] - 125; - targ_bits[1] = 125; - } - } - - move_bits = targ_bits[0] + targ_bits[1]; - if (move_bits > max_bits) { - targ_bits[0] = (max_bits * targ_bits[0]) / move_bits; - targ_bits[1] = (max_bits * targ_bits[1]) / move_bits; - } - assert(targ_bits[0] <= LameInternalFlags.MAX_BITS_PER_CHANNEL); - assert(targ_bits[1] <= LameInternalFlags.MAX_BITS_PER_CHANNEL); - assert(targ_bits[0] + targ_bits[1] <= LameInternalFlags.MAX_BITS_PER_GRANULE); - }; - - /** - * Robert Hegemann 2001-04-27: - * this adjusts the ATH, keeping the original noise floor - * affects the higher frequencies more than the lower ones - */ - this.athAdjust = function (a, x, athFloor) { - /* - * work in progress - */ - var o = 90.30873362; - var p = 94.82444863; - var u = Util.FAST_LOG10_X(x, 10.0); - var v = a * a; - var w = 0.0; - u -= athFloor; - /* undo scaling */ - if (v > 1E-20) - w = 1. + Util.FAST_LOG10_X(v, 10.0 / o); - if (w < 0) - w = 0.; - u *= w; - u += athFloor + o - p; - /* redo scaling */ - - return Math.pow(10., 0.1 * u); - }; - - /** - * Calculate the allowed distortion for each scalefactor band, as determined - * by the psychoacoustic model. xmin(sb) = ratio(sb) * en(sb) / bw(sb) - * - * returns number of sfb's with energy > ATH - */ - this.calc_xmin = function (gfp, ratio, cod_info, pxmin) { - var pxminPos = 0; - var gfc = gfp.internal_flags; - var gsfb, j = 0, ath_over = 0; - var ATH = gfc.ATH; - var xr = cod_info.xr; - var enable_athaa_fix = (gfp.VBR == VbrMode.vbr_mtrh) ? 1 : 0; - var masking_lower = gfc.masking_lower; - - if (gfp.VBR == VbrMode.vbr_mtrh || gfp.VBR == VbrMode.vbr_mt) { - /* was already done in PSY-Model */ - masking_lower = 1.0; - } - - for (gsfb = 0; gsfb < cod_info.psy_lmax; gsfb++) { - var en0, xmin; - var rh1, rh2; - var width, l; - - if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh) - xmin = athAdjust(ATH.adjust, ATH.l[gsfb], ATH.floor); - else - xmin = ATH.adjust * ATH.l[gsfb]; - - width = cod_info.width[gsfb]; - rh1 = xmin / width; - rh2 = DBL_EPSILON; - l = width >> 1; - en0 = 0.0; - do { - var xa, xb; - xa = xr[j] * xr[j]; - en0 += xa; - rh2 += (xa < rh1) ? xa : rh1; - j++; - xb = xr[j] * xr[j]; - en0 += xb; - rh2 += (xb < rh1) ? xb : rh1; - j++; - } while (--l > 0); - if (en0 > xmin) - ath_over++; - - if (gsfb == Encoder.SBPSY_l) { - var x = xmin * gfc.nsPsy.longfact[gsfb]; - if (rh2 < x) { - rh2 = x; - } - } - if (enable_athaa_fix != 0) { - xmin = rh2; - } - if (!gfp.ATHonly) { - var e = ratio.en.l[gsfb]; - if (e > 0.0) { - var x; - x = en0 * ratio.thm.l[gsfb] * masking_lower / e; - if (enable_athaa_fix != 0) - x *= gfc.nsPsy.longfact[gsfb]; - if (xmin < x) - xmin = x; - } - } - if (enable_athaa_fix != 0) - pxmin[pxminPos++] = xmin; - else - pxmin[pxminPos++] = xmin * gfc.nsPsy.longfact[gsfb]; - } - /* end of long block loop */ - - /* use this function to determine the highest non-zero coeff */ - var max_nonzero = 575; - if (cod_info.block_type != Encoder.SHORT_TYPE) { - // NORM, START or STOP type, but not SHORT - var k = 576; - while (k-- != 0 && BitStream.EQ(xr[k], 0)) { - max_nonzero = k; - } - } - cod_info.max_nonzero_coeff = max_nonzero; - - for (var sfb = cod_info.sfb_smin; gsfb < cod_info.psymax; sfb++, gsfb += 3) { - var width, b; - var tmpATH; - if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh) - tmpATH = athAdjust(ATH.adjust, ATH.s[sfb], ATH.floor); - else - tmpATH = ATH.adjust * ATH.s[sfb]; - - width = cod_info.width[gsfb]; - for (b = 0; b < 3; b++) { - var en0 = 0.0, xmin; - var rh1, rh2; - var l = width >> 1; - - rh1 = tmpATH / width; - rh2 = DBL_EPSILON; - do { - var xa, xb; - xa = xr[j] * xr[j]; - en0 += xa; - rh2 += (xa < rh1) ? xa : rh1; - j++; - xb = xr[j] * xr[j]; - en0 += xb; - rh2 += (xb < rh1) ? xb : rh1; - j++; - } while (--l > 0); - if (en0 > tmpATH) - ath_over++; - if (sfb == Encoder.SBPSY_s) { - var x = tmpATH * gfc.nsPsy.shortfact[sfb]; - if (rh2 < x) { - rh2 = x; - } - } - if (enable_athaa_fix != 0) - xmin = rh2; - else - xmin = tmpATH; - - if (!gfp.ATHonly && !gfp.ATHshort) { - var e = ratio.en.s[sfb][b]; - if (e > 0.0) { - var x; - x = en0 * ratio.thm.s[sfb][b] * masking_lower / e; - if (enable_athaa_fix != 0) - x *= gfc.nsPsy.shortfact[sfb]; - if (xmin < x) - xmin = x; - } - } - if (enable_athaa_fix != 0) - pxmin[pxminPos++] = xmin; - else - pxmin[pxminPos++] = xmin * gfc.nsPsy.shortfact[sfb]; - } - /* b */ - if (gfp.useTemporal) { - if (pxmin[pxminPos - 3] > pxmin[pxminPos - 3 + 1]) - pxmin[pxminPos - 3 + 1] += (pxmin[pxminPos - 3] - pxmin[pxminPos - 3 + 1]) - * gfc.decay; - if (pxmin[pxminPos - 3 + 1] > pxmin[pxminPos - 3 + 2]) - pxmin[pxminPos - 3 + 2] += (pxmin[pxminPos - 3 + 1] - pxmin[pxminPos - 3 + 2]) - * gfc.decay; - } - } - /* end of short block sfb loop */ - - return ath_over; - }; - - function StartLine(j) { - this.s = j; - } - - this.calc_noise_core = function (cod_info, startline, l, step) { - var noise = 0; - var j = startline.s; - var ix = cod_info.l3_enc; - - if (j > cod_info.count1) { - while ((l--) != 0) { - var temp; - temp = cod_info.xr[j]; - j++; - noise += temp * temp; - temp = cod_info.xr[j]; - j++; - noise += temp * temp; - } - } else if (j > cod_info.big_values) { - var ix01 = new_float(2); - ix01[0] = 0; - ix01[1] = step; - while ((l--) != 0) { - var temp; - temp = Math.abs(cod_info.xr[j]) - ix01[ix[j]]; - j++; - noise += temp * temp; - temp = Math.abs(cod_info.xr[j]) - ix01[ix[j]]; - j++; - noise += temp * temp; - } - } else { - while ((l--) != 0) { - var temp; - temp = Math.abs(cod_info.xr[j]) - pow43[ix[j]] * step; - j++; - noise += temp * temp; - temp = Math.abs(cod_info.xr[j]) - pow43[ix[j]] * step; - j++; - noise += temp * temp; - } - } - - startline.s = j; - return noise; - } - - /** - *
-     * -oo dB  =>  -1.00
-     * - 6 dB  =>  -0.97
-     * - 3 dB  =>  -0.80
-     * - 2 dB  =>  -0.64
-     * - 1 dB  =>  -0.38
-     *   0 dB  =>   0.00
-     * + 1 dB  =>  +0.49
-     * + 2 dB  =>  +1.06
-     * + 3 dB  =>  +1.68
-     * + 6 dB  =>  +3.69
-     * +10 dB  =>  +6.45
-     * 
- */ - this.calc_noise = function (cod_info, l3_xmin, distort, res, prev_noise) { - var distortPos = 0; - var l3_xminPos = 0; - var sfb, l, over = 0; - var over_noise_db = 0; - /* 0 dB relative to masking */ - var tot_noise_db = 0; - /* -200 dB relative to masking */ - var max_noise = -20.0; - var j = 0; - var scalefac = cod_info.scalefac; - var scalefacPos = 0; - - res.over_SSD = 0; - - for (sfb = 0; sfb < cod_info.psymax; sfb++) { - var s = cod_info.global_gain - - (((scalefac[scalefacPos++]) + (cod_info.preflag != 0 ? pretab[sfb] - : 0)) << (cod_info.scalefac_scale + 1)) - - cod_info.subblock_gain[cod_info.window[sfb]] * 8; - var noise = 0.0; - - if (prev_noise != null && (prev_noise.step[sfb] == s)) { - - /* use previously computed values */ - noise = prev_noise.noise[sfb]; - j += cod_info.width[sfb]; - distort[distortPos++] = noise / l3_xmin[l3_xminPos++]; - - noise = prev_noise.noise_log[sfb]; - - } else { - var step = POW20(s); - l = cod_info.width[sfb] >> 1; - - if ((j + cod_info.width[sfb]) > cod_info.max_nonzero_coeff) { - var usefullsize; - usefullsize = cod_info.max_nonzero_coeff - j + 1; - - if (usefullsize > 0) - l = usefullsize >> 1; - else - l = 0; - } - - var sl = new StartLine(j); - noise = this.calc_noise_core(cod_info, sl, l, step); - j = sl.s; - - if (prev_noise != null) { - /* save noise values */ - prev_noise.step[sfb] = s; - prev_noise.noise[sfb] = noise; - } - - noise = distort[distortPos++] = noise / l3_xmin[l3_xminPos++]; - - /* multiplying here is adding in dB, but can overflow */ - noise = Util.FAST_LOG10(Math.max(noise, 1E-20)); - - if (prev_noise != null) { - /* save noise values */ - prev_noise.noise_log[sfb] = noise; - } - } - - if (prev_noise != null) { - /* save noise values */ - prev_noise.global_gain = cod_info.global_gain; - } - - tot_noise_db += noise; - - if (noise > 0.0) { - var tmp; - - tmp = Math.max(0 | (noise * 10 + .5), 1); - res.over_SSD += tmp * tmp; - - over++; - /* multiplying here is adding in dB -but can overflow */ - /* over_noise *= noise; */ - over_noise_db += noise; - } - max_noise = Math.max(max_noise, noise); - - } - - res.over_count = over; - res.tot_noise = tot_noise_db; - res.over_noise = over_noise_db; - res.max_noise = max_noise; - - return over; - } - - /** - * updates plotting data - * - * Mark Taylor 2000-??-?? - * - * Robert Hegemann: moved noise/distortion calc into it - */ - this.set_pinfo = function (gfp, cod_info, ratio, gr, ch) { - var gfc = gfp.internal_flags; - var sfb, sfb2; - var l; - var en0, en1; - var ifqstep = (cod_info.scalefac_scale == 0) ? .5 : 1.0; - var scalefac = cod_info.scalefac; - - var l3_xmin = new_float(L3Side.SFBMAX); - var xfsf = new_float(L3Side.SFBMAX); - var noise = new CalcNoiseResult(); - - calc_xmin(gfp, ratio, cod_info, l3_xmin); - calc_noise(cod_info, l3_xmin, xfsf, noise, null); - - var j = 0; - sfb2 = cod_info.sfb_lmax; - if (cod_info.block_type != Encoder.SHORT_TYPE - && 0 == cod_info.mixed_block_flag) - sfb2 = 22; - for (sfb = 0; sfb < sfb2; sfb++) { - var start = gfc.scalefac_band.l[sfb]; - var end = gfc.scalefac_band.l[sfb + 1]; - var bw = end - start; - for (en0 = 0.0; j < end; j++) - en0 += cod_info.xr[j] * cod_info.xr[j]; - en0 /= bw; - /* convert to MDCT units */ - /* scaling so it shows up on FFT plot */ - en1 = 1e15; - gfc.pinfo.en[gr][ch][sfb] = en1 * en0; - gfc.pinfo.xfsf[gr][ch][sfb] = en1 * l3_xmin[sfb] * xfsf[sfb] / bw; - - if (ratio.en.l[sfb] > 0 && !gfp.ATHonly) - en0 = en0 / ratio.en.l[sfb]; - else - en0 = 0.0; - - gfc.pinfo.thr[gr][ch][sfb] = en1 - * Math.max(en0 * ratio.thm.l[sfb], gfc.ATH.l[sfb]); - - /* there is no scalefactor bands >= SBPSY_l */ - gfc.pinfo.LAMEsfb[gr][ch][sfb] = 0; - if (cod_info.preflag != 0 && sfb >= 11) - gfc.pinfo.LAMEsfb[gr][ch][sfb] = -ifqstep * pretab[sfb]; - - if (sfb < Encoder.SBPSY_l) { - /* scfsi should be decoded by caller side */ - assert(scalefac[sfb] >= 0); - gfc.pinfo.LAMEsfb[gr][ch][sfb] -= ifqstep * scalefac[sfb]; - } - } - /* for sfb */ - - if (cod_info.block_type == Encoder.SHORT_TYPE) { - sfb2 = sfb; - for (sfb = cod_info.sfb_smin; sfb < Encoder.SBMAX_s; sfb++) { - var start = gfc.scalefac_band.s[sfb]; - var end = gfc.scalefac_band.s[sfb + 1]; - var bw = end - start; - for (var i = 0; i < 3; i++) { - for (en0 = 0.0, l = start; l < end; l++) { - en0 += cod_info.xr[j] * cod_info.xr[j]; - j++; - } - en0 = Math.max(en0 / bw, 1e-20); - /* convert to MDCT units */ - /* scaling so it shows up on FFT plot */ - en1 = 1e15; - - gfc.pinfo.en_s[gr][ch][3 * sfb + i] = en1 * en0; - gfc.pinfo.xfsf_s[gr][ch][3 * sfb + i] = en1 * l3_xmin[sfb2] - * xfsf[sfb2] / bw; - if (ratio.en.s[sfb][i] > 0) - en0 = en0 / ratio.en.s[sfb][i]; - else - en0 = 0.0; - if (gfp.ATHonly || gfp.ATHshort) - en0 = 0; - - gfc.pinfo.thr_s[gr][ch][3 * sfb + i] = en1 - * Math.max(en0 * ratio.thm.s[sfb][i], - gfc.ATH.s[sfb]); - - /* there is no scalefactor bands >= SBPSY_s */ - gfc.pinfo.LAMEsfb_s[gr][ch][3 * sfb + i] = -2.0 - * cod_info.subblock_gain[i]; - if (sfb < Encoder.SBPSY_s) { - gfc.pinfo.LAMEsfb_s[gr][ch][3 * sfb + i] -= ifqstep - * scalefac[sfb2]; - } - sfb2++; - } - } - } - /* block type short */ - gfc.pinfo.LAMEqss[gr][ch] = cod_info.global_gain; - gfc.pinfo.LAMEmainbits[gr][ch] = cod_info.part2_3_length - + cod_info.part2_length; - gfc.pinfo.LAMEsfbits[gr][ch] = cod_info.part2_length; - - gfc.pinfo.over[gr][ch] = noise.over_count; - gfc.pinfo.max_noise[gr][ch] = noise.max_noise * 10.0; - gfc.pinfo.over_noise[gr][ch] = noise.over_noise * 10.0; - gfc.pinfo.tot_noise[gr][ch] = noise.tot_noise * 10.0; - gfc.pinfo.over_SSD[gr][ch] = noise.over_SSD; - } - - /** - * updates plotting data for a whole frame - * - * Robert Hegemann 2000-10-21 - */ - function set_frame_pinfo(gfp, ratio) { - var gfc = gfp.internal_flags; - - gfc.masking_lower = 1.0; - - /* - * for every granule and channel patch l3_enc and set info - */ - for (var gr = 0; gr < gfc.mode_gr; gr++) { - for (var ch = 0; ch < gfc.channels_out; ch++) { - var cod_info = gfc.l3_side.tt[gr][ch]; - var scalefac_sav = new_int(L3Side.SFBMAX); - System.arraycopy(cod_info.scalefac, 0, scalefac_sav, 0, - scalefac_sav.length); - - /* - * reconstruct the scalefactors in case SCFSI was used - */ - if (gr == 1) { - var sfb; - for (sfb = 0; sfb < cod_info.sfb_lmax; sfb++) { - if (cod_info.scalefac[sfb] < 0) /* scfsi */ - cod_info.scalefac[sfb] = gfc.l3_side.tt[0][ch].scalefac[sfb]; - } - } - - set_pinfo(gfp, cod_info, ratio[gr][ch], gr, ch); - System.arraycopy(scalefac_sav, 0, cod_info.scalefac, 0, - scalefac_sav.length); - } - /* for ch */ - } - /* for gr */ - } - -} - -module.exports = QuantizePVT; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/ReplayGain.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/ReplayGain.js deleted file mode 100644 index 9dd85e5a3..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/ReplayGain.js +++ /dev/null @@ -1,59 +0,0 @@ -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -var GainAnalysis = require('./GainAnalysis.js'); - -function ReplayGain() { - this.linprebuf = new_float(GainAnalysis.MAX_ORDER * 2); - /** - * left input samples, with pre-buffer - */ - this.linpre = 0; - this.lstepbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER); - /** - * left "first step" (i.e. post first filter) samples - */ - this.lstep = 0; - this.loutbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER); - /** - * left "out" (i.e. post second filter) samples - */ - this.lout = 0; - this.rinprebuf = new_float(GainAnalysis.MAX_ORDER * 2); - /** - * right input samples ... - */ - this.rinpre = 0; - this.rstepbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER); - this.rstep = 0; - this.routbuf = new_float(GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER); - this.rout = 0; - /** - * number of samples required to reach number of milliseconds required - * for RMS window - */ - this.sampleWindow = 0; - this.totsamp = 0; - this.lsum = 0.; - this.rsum = 0.; - this.freqindex = 0; - this.first = 0; - this.A = new_int(0 | (GainAnalysis.STEPS_per_dB * GainAnalysis.MAX_dB)); - this.B = new_int(0 | (GainAnalysis.STEPS_per_dB * GainAnalysis.MAX_dB)); - -} - -module.exports = ReplayGain; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Reservoir.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Reservoir.js deleted file mode 100644 index d0ce4d53c..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Reservoir.js +++ /dev/null @@ -1,297 +0,0 @@ -/* - * bit reservoir source file - * - * Copyright (c) 1999-2000 Mark Taylor - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: Reservoir.java,v 1.9 2011/05/24 20:48:06 kenchis Exp $ */ - -//package mp3; - -/** - * ResvFrameBegin:
- * Called (repeatedly) at the beginning of a frame. Updates the maximum size of - * the reservoir, and checks to make sure main_data_begin was set properly by - * the formatter
- * Background information: - * - * This is the original text from the ISO standard. Because of sooo many bugs - * and irritations correcting comments are added in brackets []. A '^W' means - * you should remove the last word. - * - *
- *  1. The following rule can be used to calculate the maximum
- *     number of bits used for one granule [^W frame]:
- * At the highest possible bitrate of Layer III (320 kbps - * per stereo signal [^W^W^W], 48 kHz) the frames must be of - * [^W^W^W are designed to have] constant length, i.e. - * one buffer [^W^W the frame] length is:
- * - * 320 kbps * 1152/48 kHz = 7680 bit = 960 byte - * - * This value is used as the maximum buffer per channel [^W^W] at - * lower bitrates [than 320 kbps]. At 64 kbps mono or 128 kbps - * stereo the main granule length is 64 kbps * 576/48 kHz = 768 bit - * [per granule and channel] at 48 kHz sampling frequency. - * This means that there is a maximum deviation (short time buffer - * [= reservoir]) of 7680 - 2*2*768 = 4608 bits is allowed at 64 kbps. - * The actual deviation is equal to the number of bytes [with the - * meaning of octets] denoted by the main_data_end offset pointer. - * The actual maximum deviation is (2^9-1)*8 bit = 4088 bits - * [for MPEG-1 and (2^8-1)*8 bit for MPEG-2, both are hard limits]. - * ... The xchange of buffer bits between the left and right channel - * is allowed without restrictions [exception: dual channel]. - * Because of the [constructed] constraint on the buffer size - * main_data_end is always set to 0 in the case of bit_rate_index==14, - * i.e. data rate 320 kbps per stereo signal [^W^W^W]. In this case - * all data are allocated between adjacent header [^W sync] words - * [, i.e. there is no buffering at all]. - *
- */ - -var common = require('./common.js'); -var assert = common.assert; - -function Reservoir() { - var bs; - - this.setModules = function(_bs) { - bs = _bs; - } - - this.ResvFrameBegin = function(gfp, mean_bits) { - var gfc = gfp.internal_flags; - var maxmp3buf; - var l3_side = gfc.l3_side; - - var frameLength = bs.getframebits(gfp); - mean_bits.bits = (frameLength - gfc.sideinfo_len * 8) / gfc.mode_gr; - - /** - *
-		 *  Meaning of the variables:
-		 *      resvLimit: (0, 8, ..., 8*255 (MPEG-2), 8*511 (MPEG-1))
-		 *          Number of bits can be stored in previous frame(s) due to
-		 *          counter size constaints
-		 *      maxmp3buf: ( ??? ... 8*1951 (MPEG-1 and 2), 8*2047 (MPEG-2.5))
-		 *          Number of bits allowed to encode one frame (you can take 8*511 bit
-		 *          from the bit reservoir and at most 8*1440 bit from the current
-		 *          frame (320 kbps, 32 kHz), so 8*1951 bit is the largest possible
-		 *          value for MPEG-1 and -2)
-		 * 
-		 *          maximum allowed granule/channel size times 4 = 8*2047 bits.,
-		 *          so this is the absolute maximum supported by the format.
-		 * 
-		 * 
-		 *      fullFrameBits:  maximum number of bits available for encoding
-		 *                      the current frame.
-		 * 
-		 *      mean_bits:      target number of bits per granule.
-		 * 
-		 *      frameLength:
-		 * 
-		 *      gfc.ResvMax:   maximum allowed reservoir
-		 * 
-		 *      gfc.ResvSize:  current reservoir size
-		 * 
-		 *      l3_side.resvDrain_pre:
-		 *         ancillary data to be added to previous frame:
-		 *         (only usefull in VBR modes if it is possible to have
-		 *         maxmp3buf < fullFrameBits)).  Currently disabled,
-		 *         see #define NEW_DRAIN
-		 *         2010-02-13: RH now enabled, it seems to be needed for CBR too,
-		 *                     as there exists one example, where the FhG decoder
-		 *                     can't decode a -b320 CBR file anymore.
-		 * 
-		 *      l3_side.resvDrain_post:
-		 *         ancillary data to be added to this frame:
-		 * 
-		 * 
- */ - - /* main_data_begin has 9 bits in MPEG-1, 8 bits MPEG-2 */ - var resvLimit = (8 * 256) * gfc.mode_gr - 8; - - /* - * maximum allowed frame size. dont use more than this number of bits, - * even if the frame has the space for them: - */ - if (gfp.brate > 320) { - /* in freeformat the buffer is constant */ - maxmp3buf = 8 * ((int) ((gfp.brate * 1000) - / (gfp.out_samplerate / 1152) / 8 + .5)); - } else { - /* - * all mp3 decoders should have enough buffer to handle this value: - * size of a 320kbps 32kHz frame - */ - maxmp3buf = 8 * 1440; - - /* - * Bouvigne suggests this more lax interpretation of the ISO doc - * instead of using 8*960. - */ - - if (gfp.strict_ISO) { - maxmp3buf = 8 * ((int) (320000 / (gfp.out_samplerate / 1152) / 8 + .5)); - } - } - - gfc.ResvMax = maxmp3buf - frameLength; - if (gfc.ResvMax > resvLimit) - gfc.ResvMax = resvLimit; - if (gfc.ResvMax < 0 || gfp.disable_reservoir) - gfc.ResvMax = 0; - - var fullFrameBits = mean_bits.bits * gfc.mode_gr - + Math.min(gfc.ResvSize, gfc.ResvMax); - - if (fullFrameBits > maxmp3buf) - fullFrameBits = maxmp3buf; - - assert (0 == gfc.ResvMax % 8); - assert (gfc.ResvMax >= 0); - - l3_side.resvDrain_pre = 0; - - // frame analyzer code - if (gfc.pinfo != null) { - /* - * expected bits per channel per granule [is this also right for - * mono/stereo, MPEG-1/2 ?] - */ - gfc.pinfo.mean_bits = mean_bits.bits / 2; - gfc.pinfo.resvsize = gfc.ResvSize; - } - - return fullFrameBits; - } - - /** - * returns targ_bits: target number of bits to use for 1 granule
- * extra_bits: amount extra available from reservoir
- * Mark Taylor 4/99 - */ - this.ResvMaxBits = function(gfp, mean_bits, targ_bits, cbr) { - var gfc = gfp.internal_flags; - var add_bits; - var ResvSize = gfc.ResvSize, ResvMax = gfc.ResvMax; - - /* compensate the saved bits used in the 1st granule */ - if (cbr != 0) - ResvSize += mean_bits; - - if ((gfc.substep_shaping & 1) != 0) - ResvMax *= 0.9; - - targ_bits.bits = mean_bits; - - /* extra bits if the reservoir is almost full */ - if (ResvSize * 10 > ResvMax * 9) { - add_bits = ResvSize - (ResvMax * 9) / 10; - targ_bits.bits += add_bits; - gfc.substep_shaping |= 0x80; - } else { - add_bits = 0; - gfc.substep_shaping &= 0x7f; - /* - * build up reservoir. this builds the reservoir a little slower - * than FhG. It could simple be mean_bits/15, but this was rigged to - * always produce 100 (the old value) at 128kbs - */ - if (!gfp.disable_reservoir && 0 == (gfc.substep_shaping & 1)) - targ_bits.bits -= .1 * mean_bits; - } - - /* amount from the reservoir we are allowed to use. ISO says 6/10 */ - var extra_bits = (ResvSize < (gfc.ResvMax * 6) / 10 ? ResvSize - : (gfc.ResvMax * 6) / 10); - extra_bits -= add_bits; - - if (extra_bits < 0) - extra_bits = 0; - return extra_bits; - } - - /** - * Called after a granule's bit allocation. Readjusts the size of the - * reservoir to reflect the granule's usage. - */ - this.ResvAdjust = function(gfc, gi) { - gfc.ResvSize -= gi.part2_3_length + gi.part2_length; - } - - /** - * Called after all granules in a frame have been allocated. Makes sure that - * the reservoir size is within limits, possibly by adding stuffing bits. - */ - this.ResvFrameEnd = function(gfc, mean_bits) { - var over_bits; - var l3_side = gfc.l3_side; - - gfc.ResvSize += mean_bits * gfc.mode_gr; - var stuffingBits = 0; - l3_side.resvDrain_post = 0; - l3_side.resvDrain_pre = 0; - - /* we must be byte aligned */ - if ((over_bits = gfc.ResvSize % 8) != 0) - stuffingBits += over_bits; - - over_bits = (gfc.ResvSize - stuffingBits) - gfc.ResvMax; - if (over_bits > 0) { - assert (0 == over_bits % 8); - assert (over_bits >= 0); - stuffingBits += over_bits; - } - - /* - * NOTE: enabling the NEW_DRAIN code fixes some problems with FhG - * decoder shipped with MS Windows operating systems. Using this, it is - * even possible to use Gabriel's lax buffer consideration again, which - * assumes, any decoder should have a buffer large enough for a 320 kbps - * frame at 32 kHz sample rate. - * - * old drain code: lame -b320 BlackBird.wav --. does not play with - * GraphEdit.exe using FhG decoder V1.5 Build 50 - * - * new drain code: lame -b320 BlackBird.wav --. plays fine with - * GraphEdit.exe using FhG decoder V1.5 Build 50 - * - * Robert Hegemann, 2010-02-13. - */ - /* - * drain as many bits as possible into previous frame ancillary data In - * particular, in VBR mode ResvMax may have changed, and we have to make - * sure main_data_begin does not create a reservoir bigger than ResvMax - * mt 4/00 - */ - { - var mdb_bytes = Math.min(l3_side.main_data_begin * 8, stuffingBits) / 8; - l3_side.resvDrain_pre += 8 * mdb_bytes; - stuffingBits -= 8 * mdb_bytes; - gfc.ResvSize -= 8 * mdb_bytes; - l3_side.main_data_begin -= mdb_bytes; - } - /* drain the rest into this frames ancillary data */ - l3_side.resvDrain_post += stuffingBits; - gfc.ResvSize -= stuffingBits; - } -} - -module.exports = Reservoir; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/ScaleFac.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/ScaleFac.js deleted file mode 100644 index 67197c441..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/ScaleFac.js +++ /dev/null @@ -1,52 +0,0 @@ -//package mp3; - -/** - * Layer III side information. - * - * @author Ken - * - */ - -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -var Encoder = require('./Encoder.js'); - -function ScaleFac(arrL, arrS, arr21, arr12) { - - this.l = new_int(1 + Encoder.SBMAX_l); - this.s = new_int(1 + Encoder.SBMAX_s); - this.psfb21 = new_int(1 + Encoder.PSFB21); - this.psfb12 = new_int(1 + Encoder.PSFB12); - var l = this.l; - var s = this.s; - - if (arguments.length == 4) { - //public ScaleFac(final int[] arrL, final int[] arrS, final int[] arr21, - // final int[] arr12) { - this.arrL = arguments[0]; - this.arrS = arguments[1]; - this.arr21 = arguments[2]; - this.arr12 = arguments[3]; - - System.arraycopy(this.arrL, 0, l, 0, Math.min(this.arrL.length, this.l.length)); - System.arraycopy(this.arrS, 0, s, 0, Math.min(this.arrS.length, this.s.length)); - System.arraycopy(this.arr21, 0, this.psfb21, 0, Math.min(this.arr21.length, this.psfb21.length)); - System.arraycopy(this.arr12, 0, this.psfb12, 0, Math.min(this.arr12.length, this.psfb12.length)); - } -} - -module.exports = ScaleFac; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Tables.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Tables.js deleted file mode 100644 index 7620e1e1d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Tables.js +++ /dev/null @@ -1,514 +0,0 @@ -function HuffCodeTab(len, max, tab, hl) { - this.xlen = len; - this.linmax = max; - this.table = tab; - this.hlen = hl; -} - -var Tables = {}; - - -Tables.t1HB = [ - 1, 1, - 1, 0 -]; - -Tables.t2HB = [ - 1, 2, 1, - 3, 1, 1, - 3, 2, 0 -]; - -Tables.t3HB = [ - 3, 2, 1, - 1, 1, 1, - 3, 2, 0 -]; - -Tables.t5HB = [ - 1, 2, 6, 5, - 3, 1, 4, 4, - 7, 5, 7, 1, - 6, 1, 1, 0 -]; - -Tables.t6HB = [ - 7, 3, 5, 1, - 6, 2, 3, 2, - 5, 4, 4, 1, - 3, 3, 2, 0 -]; - -Tables.t7HB = [ - 1, 2, 10, 19, 16, 10, - 3, 3, 7, 10, 5, 3, - 11, 4, 13, 17, 8, 4, - 12, 11, 18, 15, 11, 2, - 7, 6, 9, 14, 3, 1, - 6, 4, 5, 3, 2, 0 -]; - -Tables.t8HB = [ - 3, 4, 6, 18, 12, 5, - 5, 1, 2, 16, 9, 3, - 7, 3, 5, 14, 7, 3, - 19, 17, 15, 13, 10, 4, - 13, 5, 8, 11, 5, 1, - 12, 4, 4, 1, 1, 0 -]; - -Tables.t9HB = [ - 7, 5, 9, 14, 15, 7, - 6, 4, 5, 5, 6, 7, - 7, 6, 8, 8, 8, 5, - 15, 6, 9, 10, 5, 1, - 11, 7, 9, 6, 4, 1, - 14, 4, 6, 2, 6, 0 -]; - -Tables.t10HB = [ - 1, 2, 10, 23, 35, 30, 12, 17, - 3, 3, 8, 12, 18, 21, 12, 7, - 11, 9, 15, 21, 32, 40, 19, 6, - 14, 13, 22, 34, 46, 23, 18, 7, - 20, 19, 33, 47, 27, 22, 9, 3, - 31, 22, 41, 26, 21, 20, 5, 3, - 14, 13, 10, 11, 16, 6, 5, 1, - 9, 8, 7, 8, 4, 4, 2, 0 -]; - -Tables.t11HB = [ - 3, 4, 10, 24, 34, 33, 21, 15, - 5, 3, 4, 10, 32, 17, 11, 10, - 11, 7, 13, 18, 30, 31, 20, 5, - 25, 11, 19, 59, 27, 18, 12, 5, - 35, 33, 31, 58, 30, 16, 7, 5, - 28, 26, 32, 19, 17, 15, 8, 14, - 14, 12, 9, 13, 14, 9, 4, 1, - 11, 4, 6, 6, 6, 3, 2, 0 -]; - -Tables.t12HB = [ - 9, 6, 16, 33, 41, 39, 38, 26, - 7, 5, 6, 9, 23, 16, 26, 11, - 17, 7, 11, 14, 21, 30, 10, 7, - 17, 10, 15, 12, 18, 28, 14, 5, - 32, 13, 22, 19, 18, 16, 9, 5, - 40, 17, 31, 29, 17, 13, 4, 2, - 27, 12, 11, 15, 10, 7, 4, 1, - 27, 12, 8, 12, 6, 3, 1, 0 -]; - -Tables.t13HB = [ - 1, 5, 14, 21, 34, 51, 46, 71, 42, 52, 68, 52, 67, 44, 43, 19, - 3, 4, 12, 19, 31, 26, 44, 33, 31, 24, 32, 24, 31, 35, 22, 14, - 15, 13, 23, 36, 59, 49, 77, 65, 29, 40, 30, 40, 27, 33, 42, 16, - 22, 20, 37, 61, 56, 79, 73, 64, 43, 76, 56, 37, 26, 31, 25, 14, - 35, 16, 60, 57, 97, 75, 114, 91, 54, 73, 55, 41, 48, 53, 23, 24, - 58, 27, 50, 96, 76, 70, 93, 84, 77, 58, 79, 29, 74, 49, 41, 17, - 47, 45, 78, 74, 115, 94, 90, 79, 69, 83, 71, 50, 59, 38, 36, 15, - 72, 34, 56, 95, 92, 85, 91, 90, 86, 73, 77, 65, 51, 44, 43, 42, - 43, 20, 30, 44, 55, 78, 72, 87, 78, 61, 46, 54, 37, 30, 20, 16, - 53, 25, 41, 37, 44, 59, 54, 81, 66, 76, 57, 54, 37, 18, 39, 11, - 35, 33, 31, 57, 42, 82, 72, 80, 47, 58, 55, 21, 22, 26, 38, 22, - 53, 25, 23, 38, 70, 60, 51, 36, 55, 26, 34, 23, 27, 14, 9, 7, - 34, 32, 28, 39, 49, 75, 30, 52, 48, 40, 52, 28, 18, 17, 9, 5, - 45, 21, 34, 64, 56, 50, 49, 45, 31, 19, 12, 15, 10, 7, 6, 3, - 48, 23, 20, 39, 36, 35, 53, 21, 16, 23, 13, 10, 6, 1, 4, 2, - 16, 15, 17, 27, 25, 20, 29, 11, 17, 12, 16, 8, 1, 1, 0, 1 -]; - -Tables.t15HB = [ - 7, 12, 18, 53, 47, 76, 124, 108, 89, 123, 108, 119, 107, 81, 122, 63, - 13, 5, 16, 27, 46, 36, 61, 51, 42, 70, 52, 83, 65, 41, 59, 36, - 19, 17, 15, 24, 41, 34, 59, 48, 40, 64, 50, 78, 62, 80, 56, 33, - 29, 28, 25, 43, 39, 63, 55, 93, 76, 59, 93, 72, 54, 75, 50, 29, - 52, 22, 42, 40, 67, 57, 95, 79, 72, 57, 89, 69, 49, 66, 46, 27, - 77, 37, 35, 66, 58, 52, 91, 74, 62, 48, 79, 63, 90, 62, 40, 38, - 125, 32, 60, 56, 50, 92, 78, 65, 55, 87, 71, 51, 73, 51, 70, 30, - 109, 53, 49, 94, 88, 75, 66, 122, 91, 73, 56, 42, 64, 44, 21, 25, - 90, 43, 41, 77, 73, 63, 56, 92, 77, 66, 47, 67, 48, 53, 36, 20, - 71, 34, 67, 60, 58, 49, 88, 76, 67, 106, 71, 54, 38, 39, 23, 15, - 109, 53, 51, 47, 90, 82, 58, 57, 48, 72, 57, 41, 23, 27, 62, 9, - 86, 42, 40, 37, 70, 64, 52, 43, 70, 55, 42, 25, 29, 18, 11, 11, - 118, 68, 30, 55, 50, 46, 74, 65, 49, 39, 24, 16, 22, 13, 14, 7, - 91, 44, 39, 38, 34, 63, 52, 45, 31, 52, 28, 19, 14, 8, 9, 3, - 123, 60, 58, 53, 47, 43, 32, 22, 37, 24, 17, 12, 15, 10, 2, 1, - 71, 37, 34, 30, 28, 20, 17, 26, 21, 16, 10, 6, 8, 6, 2, 0 -]; - -Tables.t16HB = [ - 1, 5, 14, 44, 74, 63, 110, 93, 172, 149, 138, 242, 225, 195, 376, 17, - 3, 4, 12, 20, 35, 62, 53, 47, 83, 75, 68, 119, 201, 107, 207, 9, - 15, 13, 23, 38, 67, 58, 103, 90, 161, 72, 127, 117, 110, 209, 206, 16, - 45, 21, 39, 69, 64, 114, 99, 87, 158, 140, 252, 212, 199, 387, 365, 26, - 75, 36, 68, 65, 115, 101, 179, 164, 155, 264, 246, 226, 395, 382, 362, 9, - 66, 30, 59, 56, 102, 185, 173, 265, 142, 253, 232, 400, 388, 378, 445, 16, - 111, 54, 52, 100, 184, 178, 160, 133, 257, 244, 228, 217, 385, 366, 715, 10, - 98, 48, 91, 88, 165, 157, 148, 261, 248, 407, 397, 372, 380, 889, 884, 8, - 85, 84, 81, 159, 156, 143, 260, 249, 427, 401, 392, 383, 727, 713, 708, 7, - 154, 76, 73, 141, 131, 256, 245, 426, 406, 394, 384, 735, 359, 710, 352, 11, - 139, 129, 67, 125, 247, 233, 229, 219, 393, 743, 737, 720, 885, 882, 439, 4, - 243, 120, 118, 115, 227, 223, 396, 746, 742, 736, 721, 712, 706, 223, 436, 6, - 202, 224, 222, 218, 216, 389, 386, 381, 364, 888, 443, 707, 440, 437, 1728, 4, - 747, 211, 210, 208, 370, 379, 734, 723, 714, 1735, 883, 877, 876, 3459, 865, 2, - 377, 369, 102, 187, 726, 722, 358, 711, 709, 866, 1734, 871, 3458, 870, 434, 0, - 12, 10, 7, 11, 10, 17, 11, 9, 13, 12, 10, 7, 5, 3, 1, 3 -]; - -Tables.t24HB = [ - 15, 13, 46, 80, 146, 262, 248, 434, 426, 669, 653, 649, 621, 517, 1032, 88, - 14, 12, 21, 38, 71, 130, 122, 216, 209, 198, 327, 345, 319, 297, 279, 42, - 47, 22, 41, 74, 68, 128, 120, 221, 207, 194, 182, 340, 315, 295, 541, 18, - 81, 39, 75, 70, 134, 125, 116, 220, 204, 190, 178, 325, 311, 293, 271, 16, - 147, 72, 69, 135, 127, 118, 112, 210, 200, 188, 352, 323, 306, 285, 540, 14, - 263, 66, 129, 126, 119, 114, 214, 202, 192, 180, 341, 317, 301, 281, 262, 12, - 249, 123, 121, 117, 113, 215, 206, 195, 185, 347, 330, 308, 291, 272, 520, 10, - 435, 115, 111, 109, 211, 203, 196, 187, 353, 332, 313, 298, 283, 531, 381, 17, - 427, 212, 208, 205, 201, 193, 186, 177, 169, 320, 303, 286, 268, 514, 377, 16, - 335, 199, 197, 191, 189, 181, 174, 333, 321, 305, 289, 275, 521, 379, 371, 11, - 668, 184, 183, 179, 175, 344, 331, 314, 304, 290, 277, 530, 383, 373, 366, 10, - 652, 346, 171, 168, 164, 318, 309, 299, 287, 276, 263, 513, 375, 368, 362, 6, - 648, 322, 316, 312, 307, 302, 292, 284, 269, 261, 512, 376, 370, 364, 359, 4, - 620, 300, 296, 294, 288, 282, 273, 266, 515, 380, 374, 369, 365, 361, 357, 2, - 1033, 280, 278, 274, 267, 264, 259, 382, 378, 372, 367, 363, 360, 358, 356, 0, - 43, 20, 19, 17, 15, 13, 11, 9, 7, 6, 4, 7, 5, 3, 1, 3 -]; - -Tables.t32HB = [ - 1 << 0, 5 << 1, 4 << 1, 5 << 2, 6 << 1, 5 << 2, 4 << 2, 4 << 3, - 7 << 1, 3 << 2, 6 << 2, 0 << 3, 7 << 2, 2 << 3, 3 << 3, 1 << 4 -]; - -Tables.t33HB = [ - 15 << 0, 14 << 1, 13 << 1, 12 << 2, 11 << 1, 10 << 2, 9 << 2, 8 << 3, - 7 << 1, 6 << 2, 5 << 2, 4 << 3, 3 << 2, 2 << 3, 1 << 3, 0 << 4 -]; - -Tables.t1l = [ - 1, 4, - 3, 5 -]; - -Tables.t2l = [ - 1, 4, 7, - 4, 5, 7, - 6, 7, 8 -]; - -Tables.t3l = [ - 2, 3, 7, - 4, 4, 7, - 6, 7, 8 -]; - -Tables.t5l = [ - 1, 4, 7, 8, - 4, 5, 8, 9, - 7, 8, 9, 10, - 8, 8, 9, 10 -]; - -Tables.t6l = [ - 3, 4, 6, 8, - 4, 4, 6, 7, - 5, 6, 7, 8, - 7, 7, 8, 9 -]; - -Tables.t7l = [ - 1, 4, 7, 9, 9, 10, - 4, 6, 8, 9, 9, 10, - 7, 7, 9, 10, 10, 11, - 8, 9, 10, 11, 11, 11, - 8, 9, 10, 11, 11, 12, - 9, 10, 11, 12, 12, 12 -]; - -Tables.t8l = [ - 2, 4, 7, 9, 9, 10, - 4, 4, 6, 10, 10, 10, - 7, 6, 8, 10, 10, 11, - 9, 10, 10, 11, 11, 12, - 9, 9, 10, 11, 12, 12, - 10, 10, 11, 11, 13, 13 -]; - -Tables.t9l = [ - 3, 4, 6, 7, 9, 10, - 4, 5, 6, 7, 8, 10, - 5, 6, 7, 8, 9, 10, - 7, 7, 8, 9, 9, 10, - 8, 8, 9, 9, 10, 11, - 9, 9, 10, 10, 11, 11 -]; - -Tables.t10l = [ - 1, 4, 7, 9, 10, 10, 10, 11, - 4, 6, 8, 9, 10, 11, 10, 10, - 7, 8, 9, 10, 11, 12, 11, 11, - 8, 9, 10, 11, 12, 12, 11, 12, - 9, 10, 11, 12, 12, 12, 12, 12, - 10, 11, 12, 12, 13, 13, 12, 13, - 9, 10, 11, 12, 12, 12, 13, 13, - 10, 10, 11, 12, 12, 13, 13, 13 -]; - -Tables.t11l = [ - 2, 4, 6, 8, 9, 10, 9, 10, - 4, 5, 6, 8, 10, 10, 9, 10, - 6, 7, 8, 9, 10, 11, 10, 10, - 8, 8, 9, 11, 10, 12, 10, 11, - 9, 10, 10, 11, 11, 12, 11, 12, - 9, 10, 11, 12, 12, 13, 12, 13, - 9, 9, 9, 10, 11, 12, 12, 12, - 9, 9, 10, 11, 12, 12, 12, 12 -]; - -Tables.t12l = [ - 4, 4, 6, 8, 9, 10, 10, 10, - 4, 5, 6, 7, 9, 9, 10, 10, - 6, 6, 7, 8, 9, 10, 9, 10, - 7, 7, 8, 8, 9, 10, 10, 10, - 8, 8, 9, 9, 10, 10, 10, 11, - 9, 9, 10, 10, 10, 11, 10, 11, - 9, 9, 9, 10, 10, 11, 11, 12, - 10, 10, 10, 11, 11, 11, 11, 12 -]; - -Tables.t13l = [ - 1, 5, 7, 8, 9, 10, 10, 11, 10, 11, 12, 12, 13, 13, 14, 14, - 4, 6, 8, 9, 10, 10, 11, 11, 11, 11, 12, 12, 13, 14, 14, 14, - 7, 8, 9, 10, 11, 11, 12, 12, 11, 12, 12, 13, 13, 14, 15, 15, - 8, 9, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 15, 15, - 9, 9, 11, 11, 12, 12, 13, 13, 12, 13, 13, 14, 14, 15, 15, 16, - 10, 10, 11, 12, 12, 12, 13, 13, 13, 13, 14, 13, 15, 15, 16, 16, - 10, 11, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, - 11, 11, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 16, 18, 18, - 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 15, 15, 16, 17, 17, - 11, 11, 12, 12, 13, 13, 13, 15, 14, 15, 15, 16, 16, 16, 18, 17, - 11, 12, 12, 13, 13, 14, 14, 15, 14, 15, 16, 15, 16, 17, 18, 19, - 12, 12, 12, 13, 14, 14, 14, 14, 15, 15, 15, 16, 17, 17, 17, 18, - 12, 13, 13, 14, 14, 15, 14, 15, 16, 16, 17, 17, 17, 18, 18, 18, - 13, 13, 14, 15, 15, 15, 16, 16, 16, 16, 16, 17, 18, 17, 18, 18, - 14, 14, 14, 15, 15, 15, 17, 16, 16, 19, 17, 17, 17, 19, 18, 18, - 13, 14, 15, 16, 16, 16, 17, 16, 17, 17, 18, 18, 21, 20, 21, 18 -]; - -Tables.t15l = [ - 3, 5, 6, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 14, - 5, 5, 7, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, - 6, 7, 7, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 13, - 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, - 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, - 9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 13, 13, 13, 14, - 10, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14, - 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 14, - 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 14, 14, - 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, - 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 15, 14, - 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, - 12, 12, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 14, 14, 15, 15, - 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, - 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 14, 15, - 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15 -]; - -Tables.t16_5l = [ - 1, 5, 7, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 11, - 4, 6, 8, 9, 10, 11, 11, 11, 12, 12, 12, 13, 14, 13, 14, 11, - 7, 8, 9, 10, 11, 11, 12, 12, 13, 12, 13, 13, 13, 14, 14, 12, - 9, 9, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 13, - 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 12, - 10, 10, 11, 11, 12, 13, 13, 14, 13, 14, 14, 15, 15, 15, 16, 13, - 11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 13, - 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 17, 17, 13, - 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 13, - 12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 16, 15, 14, - 12, 13, 12, 13, 14, 14, 14, 14, 15, 16, 16, 16, 17, 17, 16, 13, - 13, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 14, - 13, 14, 14, 14, 14, 15, 15, 15, 15, 17, 16, 16, 16, 16, 18, 14, - 15, 14, 14, 14, 15, 15, 16, 16, 16, 18, 17, 17, 17, 19, 17, 14, - 14, 15, 13, 14, 16, 16, 15, 16, 16, 17, 18, 17, 19, 17, 16, 14, - 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 12 -]; - -Tables.t16l = [ - 1, 5, 7, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 10, - 4, 6, 8, 9, 10, 11, 11, 11, 12, 12, 12, 13, 14, 13, 14, 10, - 7, 8, 9, 10, 11, 11, 12, 12, 13, 12, 13, 13, 13, 14, 14, 11, - 9, 9, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 12, - 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 11, - 10, 10, 11, 11, 12, 13, 13, 14, 13, 14, 14, 15, 15, 15, 16, 12, - 11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 12, - 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 17, 17, 12, - 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 12, - 12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 16, 15, 13, - 12, 13, 12, 13, 14, 14, 14, 14, 15, 16, 16, 16, 17, 17, 16, 12, - 13, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 13, - 13, 14, 14, 14, 14, 15, 15, 15, 15, 17, 16, 16, 16, 16, 18, 13, - 15, 14, 14, 14, 15, 15, 16, 16, 16, 18, 17, 17, 17, 19, 17, 13, - 14, 15, 13, 14, 16, 16, 15, 16, 16, 17, 18, 17, 19, 17, 16, 13, - 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 10 -]; - -Tables.t24l = [ - 4, 5, 7, 8, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 13, 10, - 5, 6, 7, 8, 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 10, - 7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 9, - 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 9, - 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, 9, - 10, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 9, - 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 9, - 11, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 10, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 10, - 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 10, - 12, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 10, - 12, 12, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 10, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 10, - 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 10, - 13, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 10, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 6 -]; - -Tables.t32l = [ - 1 + 0, 4 + 1, 4 + 1, 5 + 2, 4 + 1, 6 + 2, 5 + 2, 6 + 3, - 4 + 1, 5 + 2, 5 + 2, 6 + 3, 5 + 2, 6 + 3, 6 + 3, 6 + 4 -]; - -Tables.t33l = [ - 4 + 0, 4 + 1, 4 + 1, 4 + 2, 4 + 1, 4 + 2, 4 + 2, 4 + 3, - 4 + 1, 4 + 2, 4 + 2, 4 + 3, 4 + 2, 4 + 3, 4 + 3, 4 + 4 -]; - -Tables.ht = [ - /* xlen, linmax, table, hlen */ - new HuffCodeTab(0, 0, null, null), - new HuffCodeTab(2, 0, Tables.t1HB, Tables.t1l), - new HuffCodeTab(3, 0, Tables.t2HB, Tables.t2l), - new HuffCodeTab(3, 0, Tables.t3HB, Tables.t3l), - new HuffCodeTab(0, 0, null, null), /* Apparently not used */ - new HuffCodeTab(4, 0, Tables.t5HB, Tables.t5l), - new HuffCodeTab(4, 0, Tables.t6HB, Tables.t6l), - new HuffCodeTab(6, 0, Tables.t7HB, Tables.t7l), - new HuffCodeTab(6, 0, Tables.t8HB, Tables.t8l), - new HuffCodeTab(6, 0, Tables.t9HB, Tables.t9l), - new HuffCodeTab(8, 0, Tables.t10HB, Tables.t10l), - new HuffCodeTab(8, 0, Tables.t11HB, Tables.t11l), - new HuffCodeTab(8, 0, Tables.t12HB, Tables.t12l), - new HuffCodeTab(16, 0, Tables.t13HB, Tables.t13l), - new HuffCodeTab(0, 0, null, Tables.t16_5l), /* Apparently not used */ - new HuffCodeTab(16, 0, Tables.t15HB, Tables.t15l), - - new HuffCodeTab(1, 1, Tables.t16HB, Tables.t16l), - new HuffCodeTab(2, 3, Tables.t16HB, Tables.t16l), - new HuffCodeTab(3, 7, Tables.t16HB, Tables.t16l), - new HuffCodeTab(4, 15, Tables.t16HB, Tables.t16l), - new HuffCodeTab(6, 63, Tables.t16HB, Tables.t16l), - new HuffCodeTab(8, 255, Tables.t16HB, Tables.t16l), - new HuffCodeTab(10, 1023, Tables.t16HB, Tables.t16l), - new HuffCodeTab(13, 8191, Tables.t16HB, Tables.t16l), - - new HuffCodeTab(4, 15, Tables.t24HB, Tables.t24l), - new HuffCodeTab(5, 31, Tables.t24HB, Tables.t24l), - new HuffCodeTab(6, 63, Tables.t24HB, Tables.t24l), - new HuffCodeTab(7, 127, Tables.t24HB, Tables.t24l), - new HuffCodeTab(8, 255, Tables.t24HB, Tables.t24l), - new HuffCodeTab(9, 511, Tables.t24HB, Tables.t24l), - new HuffCodeTab(11, 2047, Tables.t24HB, Tables.t24l), - new HuffCodeTab(13, 8191, Tables.t24HB, Tables.t24l), - - new HuffCodeTab(0, 0, Tables.t32HB, Tables.t32l), - new HuffCodeTab(0, 0, Tables.t33HB, Tables.t33l), -]; - -/** - * - * for (i = 0; i < 16*16; i++) [ - * largetbl[i] = ((ht[16].hlen[i]) << 16) + ht[24].hlen[i]; - * ] - * - * - */ -Tables.largetbl = [ - 0x010004, 0x050005, 0x070007, 0x090008, 0x0a0009, 0x0a000a, 0x0b000a, 0x0b000b, - 0x0c000b, 0x0c000c, 0x0c000c, 0x0d000c, 0x0d000c, 0x0d000c, 0x0e000d, 0x0a000a, - 0x040005, 0x060006, 0x080007, 0x090008, 0x0a0009, 0x0b000a, 0x0b000a, 0x0b000b, - 0x0c000b, 0x0c000b, 0x0c000c, 0x0d000c, 0x0e000c, 0x0d000c, 0x0e000c, 0x0a000a, - 0x070007, 0x080007, 0x090008, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000b, - 0x0d000b, 0x0c000b, 0x0d000b, 0x0d000c, 0x0d000c, 0x0e000c, 0x0e000d, 0x0b0009, - 0x090008, 0x090008, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000a, 0x0c000b, - 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0c0009, - 0x0a0009, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000a, 0x0d000a, 0x0d000b, - 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000d, 0x0b0009, - 0x0a000a, 0x0a0009, 0x0b000a, 0x0b000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0e000b, - 0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x0c0009, - 0x0b000a, 0x0b000a, 0x0b000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0d000b, 0x0d000b, - 0x0e000b, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x10000d, 0x0c0009, - 0x0b000b, 0x0b000a, 0x0c000a, 0x0c000a, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b, - 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x11000d, 0x11000d, 0x0c000a, - 0x0b000b, 0x0c000b, 0x0c000b, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000b, - 0x0f000b, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x10000d, 0x10000d, 0x0c000a, - 0x0c000b, 0x0c000b, 0x0c000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000b, 0x0f000c, - 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x0f000d, 0x10000d, 0x0f000d, 0x0d000a, - 0x0c000c, 0x0d000b, 0x0c000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0e000c, - 0x0f000c, 0x10000c, 0x10000c, 0x10000d, 0x11000d, 0x11000d, 0x10000d, 0x0c000a, - 0x0d000c, 0x0d000c, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x10000c, - 0x10000c, 0x10000c, 0x10000c, 0x10000d, 0x10000d, 0x0f000d, 0x10000d, 0x0d000a, - 0x0d000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, - 0x0f000c, 0x11000c, 0x10000d, 0x10000d, 0x10000d, 0x10000d, 0x12000d, 0x0d000a, - 0x0f000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x10000c, 0x10000c, - 0x10000d, 0x12000d, 0x11000d, 0x11000d, 0x11000d, 0x13000d, 0x11000d, 0x0d000a, - 0x0e000d, 0x0f000c, 0x0d000c, 0x0e000c, 0x10000c, 0x10000c, 0x0f000c, 0x10000d, - 0x10000d, 0x11000d, 0x12000d, 0x11000d, 0x13000d, 0x11000d, 0x10000d, 0x0d000a, - 0x0a0009, 0x0a0009, 0x0a0009, 0x0b0009, 0x0b0009, 0x0c0009, 0x0c0009, 0x0c0009, - 0x0d0009, 0x0d0009, 0x0d0009, 0x0d000a, 0x0d000a, 0x0d000a, 0x0d000a, 0x0a0006 -]; -/** - * - * for (i = 0; i < 3*3; i++) [ - * table23[i] = ((ht[2].hlen[i]) << 16) + ht[3].hlen[i]; - * ] - * - * - */ -Tables.table23 = [ - 0x010002, 0x040003, 0x070007, - 0x040004, 0x050004, 0x070007, - 0x060006, 0x070007, 0x080008 -]; - -/** - * - * for (i = 0; i < 4*4; i++) [ - * table56[i] = ((ht[5].hlen[i]) << 16) + ht[6].hlen[i]; - * ] - * - * - */ -Tables.table56 = [ - 0x010003, 0x040004, 0x070006, 0x080008, 0x040004, 0x050004, 0x080006, 0x090007, - 0x070005, 0x080006, 0x090007, 0x0a0008, 0x080007, 0x080007, 0x090008, 0x0a0009 -]; - -Tables.bitrate_table = [ - [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1], /* MPEG 2 */ - [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1], /* MPEG 1 */ - [0, 8, 16, 24, 32, 40, 48, 56, 64, -1, -1, -1, -1, -1, -1, -1], /* MPEG 2.5 */ -]; - -/** - * MPEG 2, MPEG 1, MPEG 2.5. - */ -Tables.samplerate_table = [ - [22050, 24000, 16000, -1], - [44100, 48000, 32000, -1], - [11025, 12000, 8000, -1], -]; - -/** - * This is the scfsi_band table from 2.4.2.7 of the IS. - */ -Tables.scfsi_band = [0, 6, 11, 16, 21]; - -module.exports = Tables; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Takehiro.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Takehiro.js deleted file mode 100644 index 493ee0697..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Takehiro.js +++ /dev/null @@ -1,1175 +0,0 @@ -/* - * MP3 huffman table selecting and bit counting - * - * Copyright (c) 1999-2005 Takehiro TOMINAGA - * Copyright (c) 2002-2005 Gabriel Bouvigne - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: Takehiro.java,v 1.26 2011/05/24 20:48:06 kenchis Exp $ */ - -//package mp3; - -//import java.util.Arrays; -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -var Encoder = require('./Encoder.js'); -var Tables = require('./Tables.js'); -var GrInfo = require('./GrInfo.js'); -var QuantizePVT = require('./QuantizePVT.js'); - - -function Takehiro() { - - var qupvt = null; - this.qupvt = null; - - this.setModules = function (_qupvt) { - this.qupvt = _qupvt; - qupvt = _qupvt; - } - - function Bits(b) { - this.bits = 0 | b; - } - - var subdv_table = [[0, 0], /* 0 bands */ - [0, 0], /* 1 bands */ - [0, 0], /* 2 bands */ - [0, 0], /* 3 bands */ - [0, 0], /* 4 bands */ - [0, 1], /* 5 bands */ - [1, 1], /* 6 bands */ - [1, 1], /* 7 bands */ - [1, 2], /* 8 bands */ - [2, 2], /* 9 bands */ - [2, 3], /* 10 bands */ - [2, 3], /* 11 bands */ - [3, 4], /* 12 bands */ - [3, 4], /* 13 bands */ - [3, 4], /* 14 bands */ - [4, 5], /* 15 bands */ - [4, 5], /* 16 bands */ - [4, 6], /* 17 bands */ - [5, 6], /* 18 bands */ - [5, 6], /* 19 bands */ - [5, 7], /* 20 bands */ - [6, 7], /* 21 bands */ - [6, 7], /* 22 bands */ - ]; - - /** - * nonlinear quantization of xr More accurate formula than the ISO formula. - * Takes into account the fact that we are quantizing xr . ix, but we want - * ix^4/3 to be as close as possible to x^4/3. (taking the nearest int would - * mean ix is as close as possible to xr, which is different.) - * - * From Segher Boessenkool 11/1999 - * - * 09/2000: ASM code removed in favor of IEEE754 hack by Takehiro Tominaga. - * If you need the ASM code, check CVS circa Aug 2000. - * - * 01/2004: Optimizations by Gabriel Bouvigne - */ - function quantize_lines_xrpow_01(l, istep, xr, xrPos, ix, ixPos) { - var compareval0 = (1.0 - 0.4054) / istep; - - assert(l > 0); - l = l >> 1; - while ((l--) != 0) { - ix[ixPos++] = (compareval0 > xr[xrPos++]) ? 0 : 1; - ix[ixPos++] = (compareval0 > xr[xrPos++]) ? 0 : 1; - } - } - - /** - * XRPOW_FTOI is a macro to convert floats to ints.
- * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x]
- * ROUNDFAC= -0.0946
- * - * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x]
- * ROUNDFAC=0.4054
- * - * Note: using floor() or 0| is extremely slow. On machines where the - * TAKEHIRO_IEEE754_HACK code above does not work, it is worthwile to write - * some ASM for XRPOW_FTOI(). - */ - function quantize_lines_xrpow(l, istep, xr, xrPos, ix, ixPos) { - assert(l > 0); - - l = l >> 1; - var remaining = l % 2; - l = l >> 1; - while (l-- != 0) { - var x0, x1, x2, x3; - var rx0, rx1, rx2, rx3; - - x0 = xr[xrPos++] * istep; - x1 = xr[xrPos++] * istep; - rx0 = 0 | x0; - x2 = xr[xrPos++] * istep; - rx1 = 0 | x1; - x3 = xr[xrPos++] * istep; - rx2 = 0 | x2; - x0 += qupvt.adj43[rx0]; - rx3 = 0 | x3; - x1 += qupvt.adj43[rx1]; - ix[ixPos++] = 0 | x0; - x2 += qupvt.adj43[rx2]; - ix[ixPos++] = 0 | x1; - x3 += qupvt.adj43[rx3]; - ix[ixPos++] = 0 | x2; - ix[ixPos++] = 0 | x3; - } - if (remaining != 0) { - var x0, x1; - var rx0, rx1; - - x0 = xr[xrPos++] * istep; - x1 = xr[xrPos++] * istep; - rx0 = 0 | x0; - rx1 = 0 | x1; - x0 += qupvt.adj43[rx0]; - x1 += qupvt.adj43[rx1]; - ix[ixPos++] = 0 | x0; - ix[ixPos++] = 0 | x1; - } - } - - /** - * Quantization function This function will select which lines to quantize - * and call the proper quantization function - */ - function quantize_xrpow(xp, pi, istep, codInfo, prevNoise) { - /* quantize on xr^(3/4) instead of xr */ - var sfb; - var sfbmax; - var j = 0; - var prev_data_use; - var accumulate = 0; - var accumulate01 = 0; - var xpPos = 0; - var iData = pi; - var iDataPos = 0; - var acc_iData = iData; - var acc_iDataPos = 0; - var acc_xp = xp; - var acc_xpPos = 0; - - /* - * Reusing previously computed data does not seems to work if global - * gain is changed. Finding why it behaves this way would allow to use a - * cache of previously computed values (let's 10 cached values per sfb) - * that would probably provide a noticeable speedup - */ - prev_data_use = (prevNoise != null && (codInfo.global_gain == prevNoise.global_gain)); - - if (codInfo.block_type == Encoder.SHORT_TYPE) - sfbmax = 38; - else - sfbmax = 21; - - for (sfb = 0; sfb <= sfbmax; sfb++) { - var step = -1; - - if (prev_data_use || codInfo.block_type == Encoder.NORM_TYPE) { - step = codInfo.global_gain - - ((codInfo.scalefac[sfb] + (codInfo.preflag != 0 ? qupvt.pretab[sfb] - : 0)) << (codInfo.scalefac_scale + 1)) - - codInfo.subblock_gain[codInfo.window[sfb]] * 8; - } - assert(codInfo.width[sfb] >= 0); - if (prev_data_use && (prevNoise.step[sfb] == step)) { - /* - * do not recompute this part, but compute accumulated lines - */ - if (accumulate != 0) { - quantize_lines_xrpow(accumulate, istep, acc_xp, acc_xpPos, - acc_iData, acc_iDataPos); - accumulate = 0; - } - if (accumulate01 != 0) { - quantize_lines_xrpow_01(accumulate01, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate01 = 0; - } - } else { /* should compute this part */ - var l = codInfo.width[sfb]; - - if ((j + codInfo.width[sfb]) > codInfo.max_nonzero_coeff) { - /* do not compute upper zero part */ - var usefullsize; - usefullsize = codInfo.max_nonzero_coeff - j + 1; - Arrays.fill(pi, codInfo.max_nonzero_coeff, 576, 0); - l = usefullsize; - - if (l < 0) { - l = 0; - } - - /* no need to compute higher sfb values */ - sfb = sfbmax + 1; - } - - /* accumulate lines to quantize */ - if (0 == accumulate && 0 == accumulate01) { - acc_iData = iData; - acc_iDataPos = iDataPos; - acc_xp = xp; - acc_xpPos = xpPos; - } - if (prevNoise != null && prevNoise.sfb_count1 > 0 - && sfb >= prevNoise.sfb_count1 - && prevNoise.step[sfb] > 0 - && step >= prevNoise.step[sfb]) { - - if (accumulate != 0) { - quantize_lines_xrpow(accumulate, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate = 0; - acc_iData = iData; - acc_iDataPos = iDataPos; - acc_xp = xp; - acc_xpPos = xpPos; - } - accumulate01 += l; - } else { - if (accumulate01 != 0) { - quantize_lines_xrpow_01(accumulate01, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate01 = 0; - acc_iData = iData; - acc_iDataPos = iDataPos; - acc_xp = xp; - acc_xpPos = xpPos; - } - accumulate += l; - } - - if (l <= 0) { - /* - * rh: 20040215 may happen due to "prev_data_use" - * optimization - */ - if (accumulate01 != 0) { - quantize_lines_xrpow_01(accumulate01, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate01 = 0; - } - if (accumulate != 0) { - quantize_lines_xrpow(accumulate, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate = 0; - } - - break; - /* ends for-loop */ - } - } - if (sfb <= sfbmax) { - iDataPos += codInfo.width[sfb]; - xpPos += codInfo.width[sfb]; - j += codInfo.width[sfb]; - } - } - if (accumulate != 0) { /* last data part */ - quantize_lines_xrpow(accumulate, istep, acc_xp, acc_xpPos, - acc_iData, acc_iDataPos); - accumulate = 0; - } - if (accumulate01 != 0) { /* last data part */ - quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_xpPos, - acc_iData, acc_iDataPos); - accumulate01 = 0; - } - - } - - /** - * ix_max - */ - function ix_max(ix, ixPos, endPos) { - var max1 = 0, max2 = 0; - - do { - var x1 = ix[ixPos++]; - var x2 = ix[ixPos++]; - if (max1 < x1) - max1 = x1; - - if (max2 < x2) - max2 = x2; - } while (ixPos < endPos); - if (max1 < max2) - max1 = max2; - return max1; - } - - function count_bit_ESC(ix, ixPos, end, t1, t2, s) { - /* ESC-table is used */ - var linbits = Tables.ht[t1].xlen * 65536 + Tables.ht[t2].xlen; - var sum = 0, sum2; - - do { - var x = ix[ixPos++]; - var y = ix[ixPos++]; - - if (x != 0) { - if (x > 14) { - x = 15; - sum += linbits; - } - x *= 16; - } - - if (y != 0) { - if (y > 14) { - y = 15; - sum += linbits; - } - x += y; - } - - sum += Tables.largetbl[x]; - } while (ixPos < end); - - sum2 = sum & 0xffff; - sum >>= 16; - - if (sum > sum2) { - sum = sum2; - t1 = t2; - } - - s.bits += sum; - return t1; - } - - function count_bit_noESC(ix, ixPos, end, s) { - /* No ESC-words */ - var sum1 = 0; - var hlen1 = Tables.ht[1].hlen; - - do { - var x = ix[ixPos + 0] * 2 + ix[ixPos + 1]; - ixPos += 2; - sum1 += hlen1[x]; - } while (ixPos < end); - - s.bits += sum1; - return 1; - } - - function count_bit_noESC_from2(ix, ixPos, end, t1, s) { - /* No ESC-words */ - var sum = 0, sum2; - var xlen = Tables.ht[t1].xlen; - var hlen; - if (t1 == 2) - hlen = Tables.table23; - else - hlen = Tables.table56; - - do { - var x = ix[ixPos + 0] * xlen + ix[ixPos + 1]; - ixPos += 2; - sum += hlen[x]; - } while (ixPos < end); - - sum2 = sum & 0xffff; - sum >>= 16; - - if (sum > sum2) { - sum = sum2; - t1++; - } - - s.bits += sum; - return t1; - } - - function count_bit_noESC_from3(ix, ixPos, end, t1, s) { - /* No ESC-words */ - var sum1 = 0; - var sum2 = 0; - var sum3 = 0; - var xlen = Tables.ht[t1].xlen; - var hlen1 = Tables.ht[t1].hlen; - var hlen2 = Tables.ht[t1 + 1].hlen; - var hlen3 = Tables.ht[t1 + 2].hlen; - - do { - var x = ix[ixPos + 0] * xlen + ix[ixPos + 1]; - ixPos += 2; - sum1 += hlen1[x]; - sum2 += hlen2[x]; - sum3 += hlen3[x]; - } while (ixPos < end); - var t = t1; - if (sum1 > sum2) { - sum1 = sum2; - t++; - } - if (sum1 > sum3) { - sum1 = sum3; - t = t1 + 2; - } - s.bits += sum1; - - return t; - } - - /*************************************************************************/ - /* choose table */ - /*************************************************************************/ - - var huf_tbl_noESC = [1, 2, 5, 7, 7, 10, 10, 13, 13, - 13, 13, 13, 13, 13, 13]; - - /** - * Choose the Huffman table that will encode ix[begin..end] with the fewest - * bits. - * - * Note: This code contains knowledge about the sizes and characteristics of - * the Huffman tables as defined in the IS (Table B.7), and will not work - * with any arbitrary tables. - */ - function choose_table(ix, ixPos, endPos, s) { - var max = ix_max(ix, ixPos, endPos); - - switch (max) { - case 0: - return max; - - case 1: - return count_bit_noESC(ix, ixPos, endPos, s); - - case 2: - case 3: - return count_bit_noESC_from2(ix, ixPos, endPos, - huf_tbl_noESC[max - 1], s); - - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - return count_bit_noESC_from3(ix, ixPos, endPos, - huf_tbl_noESC[max - 1], s); - - default: - /* try tables with linbits */ - if (max > QuantizePVT.IXMAX_VAL) { - s.bits = QuantizePVT.LARGE_BITS; - return -1; - } - max -= 15; - var choice2; - for (choice2 = 24; choice2 < 32; choice2++) { - if (Tables.ht[choice2].linmax >= max) { - break; - } - } - var choice; - for (choice = choice2 - 8; choice < 24; choice++) { - if (Tables.ht[choice].linmax >= max) { - break; - } - } - return count_bit_ESC(ix, ixPos, endPos, choice, choice2, s); - } - } - - /** - * count_bit - */ - this.noquant_count_bits = function (gfc, gi, prev_noise) { - var ix = gi.l3_enc; - var i = Math.min(576, ((gi.max_nonzero_coeff + 2) >> 1) << 1); - - if (prev_noise != null) - prev_noise.sfb_count1 = 0; - - /* Determine count1 region */ - for (; i > 1; i -= 2) - if ((ix[i - 1] | ix[i - 2]) != 0) - break; - gi.count1 = i; - - /* Determines the number of bits to encode the quadruples. */ - var a1 = 0; - var a2 = 0; - for (; i > 3; i -= 4) { - var p; - /* hack to check if all values <= 1 */ - //throw "TODO: HACK if ((((long) ix[i - 1] | (long) ix[i - 2] | (long) ix[i - 3] | (long) ix[i - 4]) & 0xffffffffL) > 1L " - //if (true) { - if (((ix[i - 1] | ix[i - 2] | ix[i - 3] | ix[i - 4]) & 0x7fffffff) > 1) { - break; - } - p = ((ix[i - 4] * 2 + ix[i - 3]) * 2 + ix[i - 2]) * 2 + ix[i - 1]; - a1 += Tables.t32l[p]; - a2 += Tables.t33l[p]; - } - var bits = a1; - gi.count1table_select = 0; - if (a1 > a2) { - bits = a2; - gi.count1table_select = 1; - } - - gi.count1bits = bits; - gi.big_values = i; - if (i == 0) - return bits; - - if (gi.block_type == Encoder.SHORT_TYPE) { - a1 = 3 * gfc.scalefac_band.s[3]; - if (a1 > gi.big_values) - a1 = gi.big_values; - a2 = gi.big_values; - - } else if (gi.block_type == Encoder.NORM_TYPE) { - assert(i <= 576); - /* bv_scf has 576 entries (0..575) */ - a1 = gi.region0_count = gfc.bv_scf[i - 2]; - a2 = gi.region1_count = gfc.bv_scf[i - 1]; - - assert(a1 + a2 + 2 < Encoder.SBPSY_l); - a2 = gfc.scalefac_band.l[a1 + a2 + 2]; - a1 = gfc.scalefac_band.l[a1 + 1]; - if (a2 < i) { - var bi = new Bits(bits); - gi.table_select[2] = choose_table(ix, a2, i, bi); - bits = bi.bits; - } - } else { - gi.region0_count = 7; - /* gi.region1_count = SBPSY_l - 7 - 1; */ - gi.region1_count = Encoder.SBMAX_l - 1 - 7 - 1; - a1 = gfc.scalefac_band.l[7 + 1]; - a2 = i; - if (a1 > a2) { - a1 = a2; - } - } - - /* have to allow for the case when bigvalues < region0 < region1 */ - /* (and region0, region1 are ignored) */ - a1 = Math.min(a1, i); - a2 = Math.min(a2, i); - - assert(a1 >= 0); - assert(a2 >= 0); - - /* Count the number of bits necessary to code the bigvalues region. */ - if (0 < a1) { - var bi = new Bits(bits); - gi.table_select[0] = choose_table(ix, 0, a1, bi); - bits = bi.bits; - } - if (a1 < a2) { - var bi = new Bits(bits); - gi.table_select[1] = choose_table(ix, a1, a2, bi); - bits = bi.bits; - } - if (gfc.use_best_huffman == 2) { - gi.part2_3_length = bits; - best_huffman_divide(gfc, gi); - bits = gi.part2_3_length; - } - - if (prev_noise != null) { - if (gi.block_type == Encoder.NORM_TYPE) { - var sfb = 0; - while (gfc.scalefac_band.l[sfb] < gi.big_values) { - sfb++; - } - prev_noise.sfb_count1 = sfb; - } - } - - return bits; - } - - this.count_bits = function (gfc, xr, gi, prev_noise) { - var ix = gi.l3_enc; - - /* since quantize_xrpow uses table lookup, we need to check this first: */ - var w = (QuantizePVT.IXMAX_VAL) / qupvt.IPOW20(gi.global_gain); - - if (gi.xrpow_max > w) - return QuantizePVT.LARGE_BITS; - - quantize_xrpow(xr, ix, qupvt.IPOW20(gi.global_gain), gi, prev_noise); - - if ((gfc.substep_shaping & 2) != 0) { - var j = 0; - /* 0.634521682242439 = 0.5946*2**(.5*0.1875) */ - var gain = gi.global_gain + gi.scalefac_scale; - var roundfac = 0.634521682242439 / qupvt.IPOW20(gain); - for (var sfb = 0; sfb < gi.sfbmax; sfb++) { - var width = gi.width[sfb]; - assert(width >= 0); - if (0 == gfc.pseudohalf[sfb]) { - j += width; - } else { - var k; - for (k = j, j += width; k < j; ++k) { - ix[k] = (xr[k] >= roundfac) ? ix[k] : 0; - } - } - } - } - return this.noquant_count_bits(gfc, gi, prev_noise); - } - - /** - * re-calculate the best scalefac_compress using scfsi the saved bits are - * kept in the bit reservoir. - */ - function recalc_divide_init(gfc, cod_info, ix, r01_bits, r01_div, r0_tbl, r1_tbl) { - var bigv = cod_info.big_values; - - for (var r0 = 0; r0 <= 7 + 15; r0++) { - r01_bits[r0] = QuantizePVT.LARGE_BITS; - } - - for (var r0 = 0; r0 < 16; r0++) { - var a1 = gfc.scalefac_band.l[r0 + 1]; - if (a1 >= bigv) - break; - var r0bits = 0; - var bi = new Bits(r0bits); - var r0t = choose_table(ix, 0, a1, bi); - r0bits = bi.bits; - - for (var r1 = 0; r1 < 8; r1++) { - var a2 = gfc.scalefac_band.l[r0 + r1 + 2]; - if (a2 >= bigv) - break; - var bits = r0bits; - bi = new Bits(bits); - var r1t = choose_table(ix, a1, a2, bi); - bits = bi.bits; - if (r01_bits[r0 + r1] > bits) { - r01_bits[r0 + r1] = bits; - r01_div[r0 + r1] = r0; - r0_tbl[r0 + r1] = r0t; - r1_tbl[r0 + r1] = r1t; - } - } - } - } - - function recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl) { - var bigv = cod_info2.big_values; - - for (var r2 = 2; r2 < Encoder.SBMAX_l + 1; r2++) { - var a2 = gfc.scalefac_band.l[r2]; - if (a2 >= bigv) - break; - var bits = r01_bits[r2 - 2] + cod_info2.count1bits; - if (gi.part2_3_length <= bits) - break; - - var bi = new Bits(bits); - var r2t = choose_table(ix, a2, bigv, bi); - bits = bi.bits; - if (gi.part2_3_length <= bits) - continue; - - gi.assign(cod_info2); - gi.part2_3_length = bits; - gi.region0_count = r01_div[r2 - 2]; - gi.region1_count = r2 - 2 - r01_div[r2 - 2]; - gi.table_select[0] = r0_tbl[r2 - 2]; - gi.table_select[1] = r1_tbl[r2 - 2]; - gi.table_select[2] = r2t; - } - } - - this.best_huffman_divide = function (gfc, gi) { - var cod_info2 = new GrInfo(); - var ix = gi.l3_enc; - var r01_bits = new_int(7 + 15 + 1); - var r01_div = new_int(7 + 15 + 1); - var r0_tbl = new_int(7 + 15 + 1); - var r1_tbl = new_int(7 + 15 + 1); - - /* SHORT BLOCK stuff fails for MPEG2 */ - if (gi.block_type == Encoder.SHORT_TYPE && gfc.mode_gr == 1) - return; - - cod_info2.assign(gi); - if (gi.block_type == Encoder.NORM_TYPE) { - recalc_divide_init(gfc, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl); - recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div, - r0_tbl, r1_tbl); - } - var i = cod_info2.big_values; - if (i == 0 || (ix[i - 2] | ix[i - 1]) > 1) - return; - - i = gi.count1 + 2; - if (i > 576) - return; - - /* Determines the number of bits to encode the quadruples. */ - cod_info2.assign(gi); - cod_info2.count1 = i; - var a1 = 0; - var a2 = 0; - - assert(i <= 576); - - for (; i > cod_info2.big_values; i -= 4) { - var p = ((ix[i - 4] * 2 + ix[i - 3]) * 2 + ix[i - 2]) * 2 - + ix[i - 1]; - a1 += Tables.t32l[p]; - a2 += Tables.t33l[p]; - } - cod_info2.big_values = i; - - cod_info2.count1table_select = 0; - if (a1 > a2) { - a1 = a2; - cod_info2.count1table_select = 1; - } - - cod_info2.count1bits = a1; - - if (cod_info2.block_type == Encoder.NORM_TYPE) - recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div, - r0_tbl, r1_tbl); - else { - /* Count the number of bits necessary to code the bigvalues region. */ - cod_info2.part2_3_length = a1; - a1 = gfc.scalefac_band.l[7 + 1]; - if (a1 > i) { - a1 = i; - } - if (a1 > 0) { - var bi = new Bits(cod_info2.part2_3_length); - cod_info2.table_select[0] = choose_table(ix, 0, a1, bi); - cod_info2.part2_3_length = bi.bits; - } - if (i > a1) { - var bi = new Bits(cod_info2.part2_3_length); - cod_info2.table_select[1] = choose_table(ix, a1, i, bi); - cod_info2.part2_3_length = bi.bits; - } - if (gi.part2_3_length > cod_info2.part2_3_length) - gi.assign(cod_info2); - } - } - - var slen1_n = [1, 1, 1, 1, 8, 2, 2, 2, 4, 4, 4, 8, 8, 8, 16, 16]; - var slen2_n = [1, 2, 4, 8, 1, 2, 4, 8, 2, 4, 8, 2, 4, 8, 4, 8]; - var slen1_tab = [0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4]; - var slen2_tab = [0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3]; - Takehiro.slen1_tab = slen1_tab; - Takehiro.slen2_tab = slen2_tab; - - function scfsi_calc(ch, l3_side) { - var sfb; - var gi = l3_side.tt[1][ch]; - var g0 = l3_side.tt[0][ch]; - - for (var i = 0; i < Tables.scfsi_band.length - 1; i++) { - for (sfb = Tables.scfsi_band[i]; sfb < Tables.scfsi_band[i + 1]; sfb++) { - if (g0.scalefac[sfb] != gi.scalefac[sfb] - && gi.scalefac[sfb] >= 0) - break; - } - if (sfb == Tables.scfsi_band[i + 1]) { - for (sfb = Tables.scfsi_band[i]; sfb < Tables.scfsi_band[i + 1]; sfb++) { - gi.scalefac[sfb] = -1; - } - l3_side.scfsi[ch][i] = 1; - } - } - var s1 = 0; - var c1 = 0; - for (sfb = 0; sfb < 11; sfb++) { - if (gi.scalefac[sfb] == -1) - continue; - c1++; - if (s1 < gi.scalefac[sfb]) - s1 = gi.scalefac[sfb]; - } - var s2 = 0; - var c2 = 0; - for (; sfb < Encoder.SBPSY_l; sfb++) { - if (gi.scalefac[sfb] == -1) - continue; - c2++; - if (s2 < gi.scalefac[sfb]) - s2 = gi.scalefac[sfb]; - } - - for (var i = 0; i < 16; i++) { - if (s1 < slen1_n[i] && s2 < slen2_n[i]) { - var c = slen1_tab[i] * c1 + slen2_tab[i] * c2; - if (gi.part2_length > c) { - gi.part2_length = c; - gi.scalefac_compress = i; - } - } - } - } - - /** - * Find the optimal way to store the scalefactors. Only call this routine - * after final scalefactors have been chosen and the channel/granule will - * not be re-encoded. - */ - this.best_scalefac_store = function (gfc, gr, ch, l3_side) { - /* use scalefac_scale if we can */ - var gi = l3_side.tt[gr][ch]; - var sfb, i, j, l; - var recalc = 0; - - /* - * remove scalefacs from bands with ix=0. This idea comes from the AAC - * ISO docs. added mt 3/00 - */ - /* check if l3_enc=0 */ - j = 0; - for (sfb = 0; sfb < gi.sfbmax; sfb++) { - var width = gi.width[sfb]; - assert(width >= 0); - j += width; - for (l = -width; l < 0; l++) { - if (gi.l3_enc[l + j] != 0) - break; - } - if (l == 0) - gi.scalefac[sfb] = recalc = -2; - /* anything goes. */ - /* - * only best_scalefac_store and calc_scfsi know--and only they - * should know--about the magic number -2. - */ - } - - if (0 == gi.scalefac_scale && 0 == gi.preflag) { - var s = 0; - for (sfb = 0; sfb < gi.sfbmax; sfb++) - if (gi.scalefac[sfb] > 0) - s |= gi.scalefac[sfb]; - - if (0 == (s & 1) && s != 0) { - for (sfb = 0; sfb < gi.sfbmax; sfb++) - if (gi.scalefac[sfb] > 0) - gi.scalefac[sfb] >>= 1; - - gi.scalefac_scale = recalc = 1; - } - } - - if (0 == gi.preflag && gi.block_type != Encoder.SHORT_TYPE - && gfc.mode_gr == 2) { - for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) - if (gi.scalefac[sfb] < qupvt.pretab[sfb] - && gi.scalefac[sfb] != -2) - break; - if (sfb == Encoder.SBPSY_l) { - for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) - if (gi.scalefac[sfb] > 0) - gi.scalefac[sfb] -= qupvt.pretab[sfb]; - - gi.preflag = recalc = 1; - } - } - - for (i = 0; i < 4; i++) - l3_side.scfsi[ch][i] = 0; - - if (gfc.mode_gr == 2 && gr == 1 - && l3_side.tt[0][ch].block_type != Encoder.SHORT_TYPE - && l3_side.tt[1][ch].block_type != Encoder.SHORT_TYPE) { - scfsi_calc(ch, l3_side); - recalc = 0; - } - for (sfb = 0; sfb < gi.sfbmax; sfb++) { - if (gi.scalefac[sfb] == -2) { - gi.scalefac[sfb] = 0; - /* if anything goes, then 0 is a good choice */ - } - } - if (recalc != 0) { - if (gfc.mode_gr == 2) { - this.scale_bitcount(gi); - } else { - this.scale_bitcount_lsf(gfc, gi); - } - } - } - - function all_scalefactors_not_negative(scalefac, n) { - for (var i = 0; i < n; ++i) { - if (scalefac[i] < 0) - return false; - } - return true; - } - - /** - * number of bits used to encode scalefacs. - * - * 18*slen1_tab[i] + 18*slen2_tab[i] - */ - var scale_short = [0, 18, 36, 54, 54, 36, 54, 72, - 54, 72, 90, 72, 90, 108, 108, 126]; - - /** - * number of bits used to encode scalefacs. - * - * 17*slen1_tab[i] + 18*slen2_tab[i] - */ - var scale_mixed = [0, 18, 36, 54, 51, 35, 53, 71, - 52, 70, 88, 69, 87, 105, 104, 122]; - - /** - * number of bits used to encode scalefacs. - * - * 11*slen1_tab[i] + 10*slen2_tab[i] - */ - var scale_long = [0, 10, 20, 30, 33, 21, 31, 41, 32, 42, - 52, 43, 53, 63, 64, 74]; - - /** - * Also calculates the number of bits necessary to code the scalefactors. - */ - this.scale_bitcount = function (cod_info) { - var k, sfb, max_slen1 = 0, max_slen2 = 0; - - /* maximum values */ - var tab; - var scalefac = cod_info.scalefac; - - assert(all_scalefactors_not_negative(scalefac, cod_info.sfbmax)); - - if (cod_info.block_type == Encoder.SHORT_TYPE) { - tab = scale_short; - if (cod_info.mixed_block_flag != 0) - tab = scale_mixed; - } else { /* block_type == 1,2,or 3 */ - tab = scale_long; - if (0 == cod_info.preflag) { - for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) - if (scalefac[sfb] < qupvt.pretab[sfb]) - break; - - if (sfb == Encoder.SBPSY_l) { - cod_info.preflag = 1; - for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) - scalefac[sfb] -= qupvt.pretab[sfb]; - } - } - } - - for (sfb = 0; sfb < cod_info.sfbdivide; sfb++) - if (max_slen1 < scalefac[sfb]) - max_slen1 = scalefac[sfb]; - - for (; sfb < cod_info.sfbmax; sfb++) - if (max_slen2 < scalefac[sfb]) - max_slen2 = scalefac[sfb]; - - /* - * from Takehiro TOMINAGA 10/99 loop over *all* - * posible values of scalefac_compress to find the one which uses the - * smallest number of bits. ISO would stop at first valid index - */ - cod_info.part2_length = QuantizePVT.LARGE_BITS; - for (k = 0; k < 16; k++) { - if (max_slen1 < slen1_n[k] && max_slen2 < slen2_n[k] - && cod_info.part2_length > tab[k]) { - cod_info.part2_length = tab[k]; - cod_info.scalefac_compress = k; - } - } - return cod_info.part2_length == QuantizePVT.LARGE_BITS; - } - - /** - * table of largest scalefactor values for MPEG2 - */ - var max_range_sfac_tab = [[15, 15, 7, 7], - [15, 15, 7, 0], [7, 3, 0, 0], [15, 31, 31, 0], - [7, 7, 7, 0], [3, 3, 0, 0]]; - - /** - * Also counts the number of bits to encode the scalefacs but for MPEG 2 - * Lower sampling frequencies (24, 22.05 and 16 kHz.) - * - * This is reverse-engineered from section 2.4.3.2 of the MPEG2 IS, - * "Audio Decoding Layer III" - */ - this.scale_bitcount_lsf = function (gfc, cod_info) { - var table_number, row_in_table, partition, nr_sfb, window; - var over; - var i, sfb; - var max_sfac = new_int(4); -//var partition_table; - var scalefac = cod_info.scalefac; - - /* - * Set partition table. Note that should try to use table one, but do - * not yet... - */ - if (cod_info.preflag != 0) - table_number = 2; - else - table_number = 0; - - for (i = 0; i < 4; i++) - max_sfac[i] = 0; - - if (cod_info.block_type == Encoder.SHORT_TYPE) { - row_in_table = 1; - var partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table]; - for (sfb = 0, partition = 0; partition < 4; partition++) { - nr_sfb = partition_table[partition] / 3; - for (i = 0; i < nr_sfb; i++, sfb++) - for (window = 0; window < 3; window++) - if (scalefac[sfb * 3 + window] > max_sfac[partition]) - max_sfac[partition] = scalefac[sfb * 3 + window]; - } - } else { - row_in_table = 0; - var partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table]; - for (sfb = 0, partition = 0; partition < 4; partition++) { - nr_sfb = partition_table[partition]; - for (i = 0; i < nr_sfb; i++, sfb++) - if (scalefac[sfb] > max_sfac[partition]) - max_sfac[partition] = scalefac[sfb]; - } - } - - for (over = false, partition = 0; partition < 4; partition++) { - if (max_sfac[partition] > max_range_sfac_tab[table_number][partition]) - over = true; - } - if (!over) { - var slen1, slen2, slen3, slen4; - - cod_info.sfb_partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table]; - for (partition = 0; partition < 4; partition++) - cod_info.slen[partition] = log2tab[max_sfac[partition]]; - - /* set scalefac_compress */ - slen1 = cod_info.slen[0]; - slen2 = cod_info.slen[1]; - slen3 = cod_info.slen[2]; - slen4 = cod_info.slen[3]; - - switch (table_number) { - case 0: - cod_info.scalefac_compress = (((slen1 * 5) + slen2) << 4) - + (slen3 << 2) + slen4; - break; - - case 1: - cod_info.scalefac_compress = 400 + (((slen1 * 5) + slen2) << 2) - + slen3; - break; - - case 2: - cod_info.scalefac_compress = 500 + (slen1 * 3) + slen2; - break; - - default: - System.err.printf("intensity stereo not implemented yet\n"); - break; - } - } - if (!over) { - assert(cod_info.sfb_partition_table != null); - cod_info.part2_length = 0; - for (partition = 0; partition < 4; partition++) - cod_info.part2_length += cod_info.slen[partition] - * cod_info.sfb_partition_table[partition]; - } - return over; - } - - /* - * Since no bands have been over-amplified, we can set scalefac_compress and - * slen[] for the formatter - */ - var log2tab = [0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, - 4, 4, 4, 4]; - - this.huffman_init = function (gfc) { - for (var i = 2; i <= 576; i += 2) { - var scfb_anz = 0, bv_index; - while (gfc.scalefac_band.l[++scfb_anz] < i) - ; - - bv_index = subdv_table[scfb_anz][0]; // .region0_count - while (gfc.scalefac_band.l[bv_index + 1] > i) - bv_index--; - - if (bv_index < 0) { - /* - * this is an indication that everything is going to be encoded - * as region0: bigvalues < region0 < region1 so lets set - * region0, region1 to some value larger than bigvalues - */ - bv_index = subdv_table[scfb_anz][0]; // .region0_count - } - - gfc.bv_scf[i - 2] = bv_index; - - bv_index = subdv_table[scfb_anz][1]; // .region1_count - while (gfc.scalefac_band.l[bv_index + gfc.bv_scf[i - 2] + 2] > i) - bv_index--; - - if (bv_index < 0) { - bv_index = subdv_table[scfb_anz][1]; // .region1_count - } - - gfc.bv_scf[i - 1] = bv_index; - } - } -} - -module.exports = Takehiro; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Tests.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Tests.js deleted file mode 100644 index e65e23c07..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Tests.js +++ /dev/null @@ -1,84 +0,0 @@ -var fs = require("fs"); -var path = require("path") -var common = require("./common.js"); - -var lamejs = require("./index"); - -var WavHeader = lamejs.WavHeader; -var Mp3Encoder = lamejs.Mp3Encoder; - -var assert = common.assert; - -function testFullLength() { - var r = fs.readFileSync(path.join("testdata", "Left44100.wav")); - var sampleBuf = new Uint8Array(r).buffer; - var w = WavHeader.readHeader(new DataView(sampleBuf)); - var samples = new Int16Array(sampleBuf, w.dataOffset, w.dataLen / 2); - var remaining = samples.length; - var lameEnc = new Mp3Encoder(); //w.channels, w.sampleRate, 128); - var maxSamples = 1152; - - var fd = fs.openSync(path.join("testdata", "testjs2.mp3"), "w"); - var time = new Date().getTime(); - for (var i = 0; remaining >= maxSamples; i += maxSamples) { - var left = samples.subarray(i, i + maxSamples); - var right = samples.subarray(i, i + maxSamples); - - var mp3buf = lameEnc.encodeBuffer(left, right); - if (mp3buf.length > 0) { - fs.writeSync(fd, new Buffer(mp3buf), 0, mp3buf.length); - } - remaining -= maxSamples; - } - var mp3buf = lameEnc.flush(); - if (mp3buf.length > 0) { - fs.writeSync(fd, new Buffer(mp3buf), 0, mp3buf.length); - } - fs.closeSync(fd); - time = new Date().getTime() - time; - console.log('done in ' + time + 'msec'); -} - -function testStereo44100() { - var r1 = fs.readFileSync(path.join("testdata", "Left44100.wav")); - var r2 = fs.readFileSync(path.join("testdata", "Right44100.wav")); - var fd = fs.openSync(path.join("testdata", "stereo.mp3"), "w"); - - var sampleBuf1 = new Uint8Array(r1).buffer; - var sampleBuf2 = new Uint8Array(r2).buffer; - var w1 = WavHeader.readHeader(new DataView(sampleBuf1)); - var w2 = WavHeader.readHeader(new DataView(sampleBuf2)); - - var samples1 = new Int16Array(sampleBuf1, w1.dataOffset, w1.dataLen / 2); - var samples2 = new Int16Array(sampleBuf2, w2.dataOffset, w2.dataLen / 2); - var remaining1 = samples1.length; - var remaining2 = samples2.length; - assert(remaining1 == remaining2); - assert(w1.sampleRate == w2.sampleRate); - - var lameEnc = new Mp3Encoder(2, w1.sampleRate, 128); - var maxSamples = 1152; - - var time = new Date().getTime(); - for (var i = 0; remaining1 >= maxSamples; i += maxSamples) { - var left = samples1.subarray(i, i + maxSamples); - var right = samples2.subarray(i, i + maxSamples); - - var mp3buf = lameEnc.encodeBuffer(left, right); - if (mp3buf.length > 0) { - fs.writeSync(fd, new Buffer(mp3buf), 0, mp3buf.length); - } - remaining1 -= maxSamples; - - } - var mp3buf = lameEnc.flush(); - if (mp3buf.length > 0) { - fs.writeSync(fd, new Buffer(mp3buf), 0, mp3buf.length); - } - fs.closeSync(fd); - time = new Date().getTime() - time; - console.log('done in ' + time + 'msec'); -} - -testStereo44100(); -testFullLength(); \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/VBRQuantize.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/VBRQuantize.js deleted file mode 100644 index 3cde95727..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/VBRQuantize.js +++ /dev/null @@ -1,13 +0,0 @@ -function VBRQuantize() { - var qupvt; - var tak; - - this.setModules = function (_qupvt, _tk) { - qupvt = _qupvt; - tak = _tk; - } - //TODO - -} - -module.exports = VBRQuantize; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/VBRSeekInfo.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/VBRSeekInfo.js deleted file mode 100644 index 24d284f3e..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/VBRSeekInfo.js +++ /dev/null @@ -1,34 +0,0 @@ -//package mp3; - -function VBRSeekInfo() { - /** - * What we have seen so far. - */ - this.sum = 0; - /** - * How many frames we have seen in this chunk. - */ - this.seen = 0; - /** - * How many frames we want to collect into one chunk. - */ - this.want = 0; - /** - * Actual position in our bag. - */ - this.pos = 0; - /** - * Size of our bag. - */ - this.size = 0; - /** - * Pointer to our bag. - */ - this.bag = null; - this.nVbrNumFrames = 0; - this.nBytesWritten = 0; - /* VBR tag data */ - this.TotalFrameSize = 0; -} - -module.exports = VBRSeekInfo; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/VBRTag.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/VBRTag.js deleted file mode 100644 index 164405a92..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/VBRTag.js +++ /dev/null @@ -1,970 +0,0 @@ -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -/** - * A Vbr header may be present in the ancillary data field of the first frame of - * an mp3 bitstream
- * The Vbr header (optionally) contains - *
    - *
  • frames total number of audio frames in the bitstream - *
  • bytes total number of bytes in the bitstream - *
  • toc table of contents - *
- * - * toc (table of contents) gives seek points for random access.
- * The ith entry determines the seek point for i-percent duration.
- * seek point in bytes = (toc[i]/256.0) * total_bitstream_bytes
- * e.g. half duration seek point = (toc[50]/256.0) * total_bitstream_bytes - */ -VBRTag.NUMTOCENTRIES = 100; -VBRTag.MAXFRAMESIZE = 2880; - -function VBRTag() { - - var lame; - var bs; - var v; - - this.setModules = function (_lame, _bs, _v) { - lame = _lame; - bs = _bs; - v = _v; - }; - - var FRAMES_FLAG = 0x0001; - var BYTES_FLAG = 0x0002; - var TOC_FLAG = 0x0004; - var VBR_SCALE_FLAG = 0x0008; - - var NUMTOCENTRIES = VBRTag.NUMTOCENTRIES; - - /** - * (0xB40) the max freeformat 640 32kHz framesize. - */ - var MAXFRAMESIZE = VBRTag.MAXFRAMESIZE; - - /** - *
-     *    4 bytes for Header Tag
-     *    4 bytes for Header Flags
-     *  100 bytes for entry (toc)
-     *    4 bytes for frame size
-     *    4 bytes for stream size
-     *    4 bytes for VBR scale. a VBR quality indicator: 0=best 100=worst
-     *   20 bytes for LAME tag.  for example, "LAME3.12 (beta 6)"
-     * ___________
-     *  140 bytes
-     * 
- */ - var VBRHEADERSIZE = (NUMTOCENTRIES + 4 + 4 + 4 + 4 + 4); - - var LAMEHEADERSIZE = (VBRHEADERSIZE + 9 + 1 + 1 + 8 - + 1 + 1 + 3 + 1 + 1 + 2 + 4 + 2 + 2); - - /** - * The size of the Xing header MPEG-1, bit rate in kbps. - */ - var XING_BITRATE1 = 128; - /** - * The size of the Xing header MPEG-2, bit rate in kbps. - */ - var XING_BITRATE2 = 64; - /** - * The size of the Xing header MPEG-2.5, bit rate in kbps. - */ - var XING_BITRATE25 = 32; - - /** - * ISO-8859-1 charset for byte to string operations. - */ - var ISO_8859_1 = null; //Charset.forName("ISO-8859-1"); - - /** - * VBR header magic string. - */ - var VBRTag0 = "Xing"; - /** - * VBR header magic string (VBR == VBRMode.vbr_off). - */ - var VBRTag1 = "Info"; - - /** - * Lookup table for fast CRC-16 computation. Uses the polynomial - * x^16+x^15+x^2+1 - */ - var crc16Lookup = [0x0000, 0xC0C1, 0xC181, 0x0140, - 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, - 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, - 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, - 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, - 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, - 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, - 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, - 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, - 0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, - 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, - 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, - 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, - 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, - 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, - 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, - 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, - 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, - 0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, - 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, - 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, - 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, - 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, - 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, - 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, - 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, - 0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, - 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, - 0x9901, 0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, - 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, - 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, - 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, - 0x4100, 0x81C1, 0x8081, 0x4040]; - - /*********************************************************************** - * Robert Hegemann 2001-01-17 - ***********************************************************************/ - - function addVbr(v, bitrate) { - v.nVbrNumFrames++; - v.sum += bitrate; - v.seen++; - - if (v.seen < v.want) { - return; - } - - if (v.pos < v.size) { - v.bag[v.pos] = v.sum; - v.pos++; - v.seen = 0; - } - if (v.pos == v.size) { - for (var i = 1; i < v.size; i += 2) { - v.bag[i / 2] = v.bag[i]; - } - v.want *= 2; - v.pos /= 2; - } - } - - function xingSeekTable(v, t) { - if (v.pos <= 0) - return; - - for (var i = 1; i < NUMTOCENTRIES; ++i) { - var j = i / NUMTOCENTRIES, act, sum; - var indx = 0 | (Math.floor(j * v.pos)); - if (indx > v.pos - 1) - indx = v.pos - 1; - act = v.bag[indx]; - sum = v.sum; - var seek_point = 0 | (256. * act / sum); - if (seek_point > 255) - seek_point = 255; - t[i] = 0xff & seek_point; - } - } - - /** - * Add VBR entry, used to fill the VBR TOC entries. - * - * @param gfp - * global flags - */ - this.addVbrFrame = function (gfp) { - var gfc = gfp.internal_flags; - var kbps = Tables.bitrate_table[gfp.version][gfc.bitrate_index]; - assert(gfc.VBR_seek_table.bag != null); - addVbr(gfc.VBR_seek_table, kbps); - } - - /** - * Read big endian integer (4-bytes) from header. - * - * @param buf - * header containing the integer - * @param bufPos - * offset into the header - * @return extracted integer - */ - function extractInteger(buf, bufPos) { - var x = buf[bufPos + 0] & 0xff; - x <<= 8; - x |= buf[bufPos + 1] & 0xff; - x <<= 8; - x |= buf[bufPos + 2] & 0xff; - x <<= 8; - x |= buf[bufPos + 3] & 0xff; - return x; - } - - /** - * Write big endian integer (4-bytes) in the header. - * - * @param buf - * header to write the integer into - * @param bufPos - * offset into the header - * @param value - * integer value to write - */ - function createInteger(buf, bufPos, value) { - buf[bufPos + 0] = 0xff & ((value >> 24) & 0xff); - buf[bufPos + 1] = 0xff & ((value >> 16) & 0xff); - buf[bufPos + 2] = 0xff & ((value >> 8) & 0xff); - buf[bufPos + 3] = 0xff & (value & 0xff); - } - - /** - * Write big endian short (2-bytes) in the header. - * - * @param buf - * header to write the integer into - * @param bufPos - * offset into the header - * @param value - * integer value to write - */ - function createShort(buf, bufPos, value) { - buf[bufPos + 0] = 0xff & ((value >> 8) & 0xff); - buf[bufPos + 1] = 0xff & (value & 0xff); - } - - /** - * Check for magic strings (Xing/Info). - * - * @param buf - * header to check - * @param bufPos - * header offset to check - * @return magic string found - */ - function isVbrTag(buf, bufPos) { - return new String(buf, bufPos, VBRTag0.length(), ISO_8859_1) - .equals(VBRTag0) - || new String(buf, bufPos, VBRTag1.length(), ISO_8859_1) - .equals(VBRTag1); - } - - function shiftInBitsValue(x, n, v) { - return 0xff & ((x << n) | (v & ~(-1 << n))); - } - - /** - * Construct the MP3 header using the settings of the global flags. - * - * - * - * @param gfp - * global flags - * @param buffer - * header - */ - function setLameTagFrameHeader(gfp, buffer) { - var gfc = gfp.internal_flags; - - // MP3 Sync Word - buffer[0] = shiftInBitsValue(buffer[0], 8, 0xff); - - buffer[1] = shiftInBitsValue(buffer[1], 3, 7); - buffer[1] = shiftInBitsValue(buffer[1], 1, - (gfp.out_samplerate < 16000) ? 0 : 1); - // Version - buffer[1] = shiftInBitsValue(buffer[1], 1, gfp.version); - // 01 == Layer 3 - buffer[1] = shiftInBitsValue(buffer[1], 2, 4 - 3); - // Error protection - buffer[1] = shiftInBitsValue(buffer[1], 1, (!gfp.error_protection) ? 1 - : 0); - - // Bit rate - buffer[2] = shiftInBitsValue(buffer[2], 4, gfc.bitrate_index); - // Frequency - buffer[2] = shiftInBitsValue(buffer[2], 2, gfc.samplerate_index); - // Pad. Bit - buffer[2] = shiftInBitsValue(buffer[2], 1, 0); - // Priv. Bit - buffer[2] = shiftInBitsValue(buffer[2], 1, gfp.extension); - - // Mode - buffer[3] = shiftInBitsValue(buffer[3], 2, gfp.mode.ordinal()); - // Mode extension (Used with Joint Stereo) - buffer[3] = shiftInBitsValue(buffer[3], 2, gfc.mode_ext); - // Copy - buffer[3] = shiftInBitsValue(buffer[3], 1, gfp.copyright); - // Original - buffer[3] = shiftInBitsValue(buffer[3], 1, gfp.original); - // Emphasis - buffer[3] = shiftInBitsValue(buffer[3], 2, gfp.emphasis); - - /* the default VBR header. 48 kbps layer III, no padding, no crc */ - /* but sampling freq, mode and copyright/copy protection taken */ - /* from first valid frame */ - buffer[0] = 0xff; - var abyte = 0xff & (buffer[1] & 0xf1); - var bitrate; - if (1 == gfp.version) { - bitrate = XING_BITRATE1; - } else { - if (gfp.out_samplerate < 16000) - bitrate = XING_BITRATE25; - else - bitrate = XING_BITRATE2; - } - - if (gfp.VBR == VbrMode.vbr_off) - bitrate = gfp.brate; - - var bbyte; - if (gfp.free_format) - bbyte = 0x00; - else - bbyte = 0xff & (16 * lame.BitrateIndex(bitrate, gfp.version, - gfp.out_samplerate)); - - /* - * Use as much of the info from the real frames in the Xing header: - * samplerate, channels, crc, etc... - */ - if (gfp.version == 1) { - /* MPEG1 */ - buffer[1] = 0xff & (abyte | 0x0a); - /* was 0x0b; */ - abyte = 0xff & (buffer[2] & 0x0d); - /* AF keep also private bit */ - buffer[2] = 0xff & (bbyte | abyte); - /* 64kbs MPEG1 frame */ - } else { - /* MPEG2 */ - buffer[1] = 0xff & (abyte | 0x02); - /* was 0x03; */ - abyte = 0xff & (buffer[2] & 0x0d); - /* AF keep also private bit */ - buffer[2] = 0xff & (bbyte | abyte); - /* 64kbs MPEG2 frame */ - } - } - - /** - * Get VBR tag information - * - * @param buf - * header to analyze - * @param bufPos - * offset into the header - * @return VBR tag data - */ - this.getVbrTag = function (buf) { - var pTagData = new VBRTagData(); - var bufPos = 0; - - /* get Vbr header data */ - pTagData.flags = 0; - - /* get selected MPEG header data */ - var hId = (buf[bufPos + 1] >> 3) & 1; - var hSrIndex = (buf[bufPos + 2] >> 2) & 3; - var hMode = (buf[bufPos + 3] >> 6) & 3; - var hBitrate = ((buf[bufPos + 2] >> 4) & 0xf); - hBitrate = Tables.bitrate_table[hId][hBitrate]; - - /* check for FFE syncword */ - if ((buf[bufPos + 1] >> 4) == 0xE) - pTagData.samprate = Tables.samplerate_table[2][hSrIndex]; - else - pTagData.samprate = Tables.samplerate_table[hId][hSrIndex]; - - /* determine offset of header */ - if (hId != 0) { - /* mpeg1 */ - if (hMode != 3) - bufPos += (32 + 4); - else - bufPos += (17 + 4); - } else { - /* mpeg2 */ - if (hMode != 3) - bufPos += (17 + 4); - else - bufPos += (9 + 4); - } - - if (!isVbrTag(buf, bufPos)) - return null; - - bufPos += 4; - - pTagData.hId = hId; - - /* get flags */ - var head_flags = pTagData.flags = extractInteger(buf, bufPos); - bufPos += 4; - - if ((head_flags & FRAMES_FLAG) != 0) { - pTagData.frames = extractInteger(buf, bufPos); - bufPos += 4; - } - - if ((head_flags & BYTES_FLAG) != 0) { - pTagData.bytes = extractInteger(buf, bufPos); - bufPos += 4; - } - - if ((head_flags & TOC_FLAG) != 0) { - if (pTagData.toc != null) { - for (var i = 0; i < NUMTOCENTRIES; i++) - pTagData.toc[i] = buf[bufPos + i]; - } - bufPos += NUMTOCENTRIES; - } - - pTagData.vbrScale = -1; - - if ((head_flags & VBR_SCALE_FLAG) != 0) { - pTagData.vbrScale = extractInteger(buf, bufPos); - bufPos += 4; - } - - pTagData.headersize = ((hId + 1) * 72000 * hBitrate) - / pTagData.samprate; - - bufPos += 21; - var encDelay = buf[bufPos + 0] << 4; - encDelay += buf[bufPos + 1] >> 4; - var encPadding = (buf[bufPos + 1] & 0x0F) << 8; - encPadding += buf[bufPos + 2] & 0xff; - /* check for reasonable values (this may be an old Xing header, */ - /* not a INFO tag) */ - if (encDelay < 0 || encDelay > 3000) - encDelay = -1; - if (encPadding < 0 || encPadding > 3000) - encPadding = -1; - - pTagData.encDelay = encDelay; - pTagData.encPadding = encPadding; - - /* success */ - return pTagData; - } - - /** - * Initializes the header - * - * @param gfp - * global flags - */ - this.InitVbrTag = function (gfp) { - var gfc = gfp.internal_flags; - - /** - *
-         * Xing VBR pretends to be a 48kbs layer III frame.  (at 44.1kHz).
-         * (at 48kHz they use 56kbs since 48kbs frame not big enough for
-         * table of contents)
-         * let's always embed Xing header inside a 64kbs layer III frame.
-         * this gives us enough room for a LAME version string too.
-         * size determined by sampling frequency (MPEG1)
-         * 32kHz:    216 bytes@48kbs    288bytes@ 64kbs
-         * 44.1kHz:  156 bytes          208bytes@64kbs     (+1 if padding = 1)
-         * 48kHz:    144 bytes          192
-         *
-         * MPEG 2 values are the same since the framesize and samplerate
-         * are each reduced by a factor of 2.
-         * 
- */ - var kbps_header; - if (1 == gfp.version) { - kbps_header = XING_BITRATE1; - } else { - if (gfp.out_samplerate < 16000) - kbps_header = XING_BITRATE25; - else - kbps_header = XING_BITRATE2; - } - - if (gfp.VBR == VbrMode.vbr_off) - kbps_header = gfp.brate; - - // make sure LAME Header fits into Frame - var totalFrameSize = ((gfp.version + 1) * 72000 * kbps_header) - / gfp.out_samplerate; - var headerSize = (gfc.sideinfo_len + LAMEHEADERSIZE); - gfc.VBR_seek_table.TotalFrameSize = totalFrameSize; - if (totalFrameSize < headerSize || totalFrameSize > MAXFRAMESIZE) { - /* disable tag, it wont fit */ - gfp.bWriteVbrTag = false; - return; - } - - gfc.VBR_seek_table.nVbrNumFrames = 0; - gfc.VBR_seek_table.nBytesWritten = 0; - gfc.VBR_seek_table.sum = 0; - - gfc.VBR_seek_table.seen = 0; - gfc.VBR_seek_table.want = 1; - gfc.VBR_seek_table.pos = 0; - - if (gfc.VBR_seek_table.bag == null) { - gfc.VBR_seek_table.bag = new int[400]; - gfc.VBR_seek_table.size = 400; - } - - // write dummy VBR tag of all 0's into bitstream - var buffer = new_byte(MAXFRAMESIZE); - - setLameTagFrameHeader(gfp, buffer); - var n = gfc.VBR_seek_table.TotalFrameSize; - for (var i = 0; i < n; ++i) { - bs.add_dummy_byte(gfp, buffer[i] & 0xff, 1); - } - } - - /** - * Fast CRC-16 computation (uses table crc16Lookup). - * - * @param value - * @param crc - * @return - */ - function crcUpdateLookup(value, crc) { - var tmp = crc ^ value; - crc = (crc >> 8) ^ crc16Lookup[tmp & 0xff]; - return crc; - } - - this.updateMusicCRC = function (crc, buffer, bufferPos, size) { - for (var i = 0; i < size; ++i) - crc[0] = crcUpdateLookup(buffer[bufferPos + i], crc[0]); - } - - /** - * Write LAME info: mini version + info on various switches used (Jonathan - * Dee 2001/08/31). - * - * @param gfp - * global flags - * @param musicLength - * music length - * @param streamBuffer - * pointer to output buffer - * @param streamBufferPos - * offset into the output buffer - * @param crc - * computation of CRC-16 of Lame Tag so far (starting at frame - * sync) - * @return number of bytes written to the stream - */ - function putLameVBR(gfp, musicLength, streamBuffer, streamBufferPos, crc) { - var gfc = gfp.internal_flags; - var bytesWritten = 0; - - /* encoder delay */ - var encDelay = gfp.encoder_delay; - /* encoder padding */ - var encPadding = gfp.encoder_padding; - - /* recall: gfp.VBR_q is for example set by the switch -V */ - /* gfp.quality by -q, -h, -f, etc */ - var quality = (100 - 10 * gfp.VBR_q - gfp.quality); - - var version = v.getLameVeryShortVersion(); - var vbr; - var revision = 0x00; - var revMethod; - // numbering different in vbr_mode vs. Lame tag - var vbrTypeTranslator = [1, 5, 3, 2, 4, 0, 3]; - var lowpass = 0 | (((gfp.lowpassfreq / 100.0) + .5) > 255 ? 255 - : (gfp.lowpassfreq / 100.0) + .5); - var peakSignalAmplitude = 0; - var radioReplayGain = 0; - var audiophileReplayGain = 0; - var noiseShaping = gfp.internal_flags.noise_shaping; - var stereoMode = 0; - var nonOptimal = 0; - var sourceFreq = 0; - var misc = 0; - var musicCRC = 0; - - // psy model type: Gpsycho or NsPsytune - var expNPsyTune = (gfp.exp_nspsytune & 1) != 0; - var safeJoint = (gfp.exp_nspsytune & 2) != 0; - var noGapMore = false; - var noGapPrevious = false; - var noGapCount = gfp.internal_flags.nogap_total; - var noGapCurr = gfp.internal_flags.nogap_current; - - // 4 bits - var athType = gfp.ATHtype; - var flags = 0; - - // vbr modes - var abrBitrate; - switch (gfp.VBR) { - case vbr_abr: - abrBitrate = gfp.VBR_mean_bitrate_kbps; - break; - case vbr_off: - abrBitrate = gfp.brate; - break; - default: - abrBitrate = gfp.VBR_min_bitrate_kbps; - } - - // revision and vbr method - if (gfp.VBR.ordinal() < vbrTypeTranslator.length) - vbr = vbrTypeTranslator[gfp.VBR.ordinal()]; - else - vbr = 0x00; // unknown - - revMethod = 0x10 * revision + vbr; - - // ReplayGain - if (gfc.findReplayGain) { - if (gfc.RadioGain > 0x1FE) - gfc.RadioGain = 0x1FE; - if (gfc.RadioGain < -0x1FE) - gfc.RadioGain = -0x1FE; - - // set name code - radioReplayGain = 0x2000; - // set originator code to `determined automatically' - radioReplayGain |= 0xC00; - - if (gfc.RadioGain >= 0) { - // set gain adjustment - radioReplayGain |= gfc.RadioGain; - } else { - // set the sign bit - radioReplayGain |= 0x200; - // set gain adjustment - radioReplayGain |= -gfc.RadioGain; - } - } - - // peak sample - if (gfc.findPeakSample) - peakSignalAmplitude = Math - .abs(0 | ((( gfc.PeakSample) / 32767.0) * Math.pow(2, 23) + .5)); - - // nogap - if (noGapCount != -1) { - if (noGapCurr > 0) - noGapPrevious = true; - - if (noGapCurr < noGapCount - 1) - noGapMore = true; - } - - // flags - flags = athType + ((expNPsyTune ? 1 : 0) << 4) - + ((safeJoint ? 1 : 0) << 5) + ((noGapMore ? 1 : 0) << 6) - + ((noGapPrevious ? 1 : 0) << 7); - - if (quality < 0) - quality = 0; - - // stereo mode field (Intensity stereo is not implemented) - switch (gfp.mode) { - case MONO: - stereoMode = 0; - break; - case STEREO: - stereoMode = 1; - break; - case DUAL_CHANNEL: - stereoMode = 2; - break; - case JOINT_STEREO: - if (gfp.force_ms) - stereoMode = 4; - else - stereoMode = 3; - break; - case NOT_SET: - //$FALL-THROUGH$ - default: - stereoMode = 7; - break; - } - - if (gfp.in_samplerate <= 32000) - sourceFreq = 0x00; - else if (gfp.in_samplerate == 48000) - sourceFreq = 0x02; - else if (gfp.in_samplerate > 48000) - sourceFreq = 0x03; - else { - // default is 44100Hz - sourceFreq = 0x01; - } - - // Check if the user overrided the default LAME behavior with some - // nasty options - if (gfp.short_blocks == ShortBlock.short_block_forced - || gfp.short_blocks == ShortBlock.short_block_dispensed - || ((gfp.lowpassfreq == -1) && (gfp.highpassfreq == -1)) || /* "-k" */ - (gfp.scale_left < gfp.scale_right) - || (gfp.scale_left > gfp.scale_right) - || (gfp.disable_reservoir && gfp.brate < 320) || gfp.noATH - || gfp.ATHonly || (athType == 0) || gfp.in_samplerate <= 32000) - nonOptimal = 1; - - misc = noiseShaping + (stereoMode << 2) + (nonOptimal << 5) - + (sourceFreq << 6); - - musicCRC = gfc.nMusicCRC; - - // Write all this information into the stream - - createInteger(streamBuffer, streamBufferPos + bytesWritten, quality); - bytesWritten += 4; - - for (var j = 0; j < 9; j++) { - streamBuffer[streamBufferPos + bytesWritten + j] = 0xff & version .charAt(j); - } - bytesWritten += 9; - - streamBuffer[streamBufferPos + bytesWritten] = 0xff & revMethod; - bytesWritten++; - - streamBuffer[streamBufferPos + bytesWritten] = 0xff & lowpass; - bytesWritten++; - - createInteger(streamBuffer, streamBufferPos + bytesWritten, - peakSignalAmplitude); - bytesWritten += 4; - - createShort(streamBuffer, streamBufferPos + bytesWritten, - radioReplayGain); - bytesWritten += 2; - - createShort(streamBuffer, streamBufferPos + bytesWritten, - audiophileReplayGain); - bytesWritten += 2; - - streamBuffer[streamBufferPos + bytesWritten] = 0xff & flags; - bytesWritten++; - - if (abrBitrate >= 255) - streamBuffer[streamBufferPos + bytesWritten] = 0xFF; - else - streamBuffer[streamBufferPos + bytesWritten] = 0xff & abrBitrate; - bytesWritten++; - - streamBuffer[streamBufferPos + bytesWritten] = 0xff & (encDelay >> 4); - streamBuffer[streamBufferPos + bytesWritten + 1] = 0xff & ((encDelay << 4) + (encPadding >> 8)); - streamBuffer[streamBufferPos + bytesWritten + 2] = 0xff & encPadding; - - bytesWritten += 3; - - streamBuffer[streamBufferPos + bytesWritten] = 0xff & misc; - bytesWritten++; - - // unused in rev0 - streamBuffer[streamBufferPos + bytesWritten++] = 0; - - createShort(streamBuffer, streamBufferPos + bytesWritten, gfp.preset); - bytesWritten += 2; - - createInteger(streamBuffer, streamBufferPos + bytesWritten, musicLength); - bytesWritten += 4; - - createShort(streamBuffer, streamBufferPos + bytesWritten, musicCRC); - bytesWritten += 2; - - // Calculate tag CRC.... must be done here, since it includes previous - // information - - for (var i = 0; i < bytesWritten; i++) - crc = crcUpdateLookup(streamBuffer[streamBufferPos + i], crc); - - createShort(streamBuffer, streamBufferPos + bytesWritten, crc); - bytesWritten += 2; - - return bytesWritten; - } - - function skipId3v2(fpStream) { - // seek to the beginning of the stream - fpStream.seek(0); - // read 10 bytes in case there's an ID3 version 2 header here - var id3v2Header = new_byte(10); - fpStream.readFully(id3v2Header); - /* does the stream begin with the ID3 version 2 file identifier? */ - var id3v2TagSize; - if (!new String(id3v2Header, "ISO-8859-1").startsWith("ID3")) { - /* - * the tag size (minus the 10-byte header) is encoded into four - * bytes where the most significant bit is clear in each byte - */ - id3v2TagSize = (((id3v2Header[6] & 0x7f) << 21) - | ((id3v2Header[7] & 0x7f) << 14) - | ((id3v2Header[8] & 0x7f) << 7) | (id3v2Header[9] & 0x7f)) - + id3v2Header.length; - } else { - /* no ID3 version 2 tag in this stream */ - id3v2TagSize = 0; - } - return id3v2TagSize; - } - - this.getLameTagFrame = function (gfp, buffer) { - var gfc = gfp.internal_flags; - - if (!gfp.bWriteVbrTag) { - return 0; - } - if (gfc.Class_ID != Lame.LAME_ID) { - return 0; - } - if (gfc.VBR_seek_table.pos <= 0) { - return 0; - } - if (buffer.length < gfc.VBR_seek_table.TotalFrameSize) { - return gfc.VBR_seek_table.TotalFrameSize; - } - - Arrays.fill(buffer, 0, gfc.VBR_seek_table.TotalFrameSize, 0); - - // 4 bytes frame header - setLameTagFrameHeader(gfp, buffer); - - // Create TOC entries - var toc = new_byte(NUMTOCENTRIES); - - if (gfp.free_format) { - for (var i = 1; i < NUMTOCENTRIES; ++i) - toc[i] = 0xff & (255 * i / 100); - } else { - xingSeekTable(gfc.VBR_seek_table, toc); - } - - // Start writing the tag after the zero frame - var streamIndex = gfc.sideinfo_len; - /** - * Note: Xing header specifies that Xing data goes in the ancillary data - * with NO ERROR PROTECTION. If error protecton in enabled, the Xing - * data still starts at the same offset, and now it is in sideinfo data - * block, and thus will not decode correctly by non-Xing tag aware - * players - */ - if (gfp.error_protection) - streamIndex -= 2; - - // Put Vbr tag - if (gfp.VBR == VbrMode.vbr_off) { - buffer[streamIndex++] = 0xff & VBRTag1.charAt(0); - buffer[streamIndex++] = 0xff & VBRTag1.charAt(1); - buffer[streamIndex++] = 0xff & VBRTag1.charAt(2); - buffer[streamIndex++] = 0xff & VBRTag1.charAt(3); - - } else { - buffer[streamIndex++] = 0xff & VBRTag0.charAt(0); - buffer[streamIndex++] = 0xff & VBRTag0.charAt(1); - buffer[streamIndex++] = 0xff & VBRTag0.charAt(2); - buffer[streamIndex++] = 0xff & VBRTag0.charAt(3); - } - - // Put header flags - createInteger(buffer, streamIndex, FRAMES_FLAG + BYTES_FLAG + TOC_FLAG - + VBR_SCALE_FLAG); - streamIndex += 4; - - // Put Total Number of frames - createInteger(buffer, streamIndex, gfc.VBR_seek_table.nVbrNumFrames); - streamIndex += 4; - - // Put total audio stream size, including Xing/LAME Header - var streamSize = (gfc.VBR_seek_table.nBytesWritten + gfc.VBR_seek_table.TotalFrameSize); - createInteger(buffer, streamIndex, 0 | streamSize); - streamIndex += 4; - - /* Put TOC */ - System.arraycopy(toc, 0, buffer, streamIndex, toc.length); - streamIndex += toc.length; - - if (gfp.error_protection) { - // (jo) error_protection: add crc16 information to header - bs.CRC_writeheader(gfc, buffer); - } - - // work out CRC so far: initially crc = 0 - var crc = 0x00; - for (var i = 0; i < streamIndex; i++) - crc = crcUpdateLookup(buffer[i], crc); - // Put LAME VBR info - streamIndex += putLameVBR(gfp, streamSize, buffer, streamIndex, crc); - - return gfc.VBR_seek_table.TotalFrameSize; - } - - /** - * Write final VBR tag to the file. - * - * @param gfp - * global flags - * @param stream - * stream to add the VBR tag to - * @return 0 (OK), -1 else - * @throws IOException - * I/O error - */ - this.putVbrTag = function (gfp, stream) { - var gfc = gfp.internal_flags; - - if (gfc.VBR_seek_table.pos <= 0) - return -1; - - // Seek to end of file - stream.seek(stream.length()); - - // Get file size, abort if file has zero length. - if (stream.length() == 0) - return -1; - - // The VBR tag may NOT be located at the beginning of the stream. If an - // ID3 version 2 tag was added, then it must be skipped to write the VBR - // tag data. - var id3v2TagSize = skipId3v2(stream); - - // Seek to the beginning of the stream - stream.seek(id3v2TagSize); - - var buffer = new_byte(MAXFRAMESIZE); - var bytes = getLameTagFrame(gfp, buffer); - if (bytes > buffer.length) { - return -1; - } - - if (bytes < 1) { - return 0; - } - - // Put it all to disk again - stream.write(buffer, 0, bytes); - // success - return 0; - } - -} - -module.exports = VBRTag; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Version.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Version.js deleted file mode 100644 index e8c0d0dbd..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/Version.js +++ /dev/null @@ -1,90 +0,0 @@ -function Version() { - - /** - * URL for the LAME website. - */ - var LAME_URL = "http://www.mp3dev.org/"; - - /** - * Major version number. - */ - var LAME_MAJOR_VERSION = 3; - /** - * Minor version number. - */ - var LAME_MINOR_VERSION = 98; - /** - * Patch level. - */ - var LAME_PATCH_VERSION = 4; - - /** - * Major version number. - */ - var PSY_MAJOR_VERSION = 0; - /** - * Minor version number. - */ - var PSY_MINOR_VERSION = 93; - - /** - * A string which describes the version of LAME. - * - * @return string which describes the version of LAME - */ - this.getLameVersion = function () { - // primary to write screen reports - return (LAME_MAJOR_VERSION + "." + LAME_MINOR_VERSION + "." + LAME_PATCH_VERSION); - } - - /** - * The short version of the LAME version string. - * - * @return short version of the LAME version string - */ - this.getLameShortVersion = function () { - // Adding date and time to version string makes it harder for output - // validation - return (LAME_MAJOR_VERSION + "." + LAME_MINOR_VERSION + "." + LAME_PATCH_VERSION); - } - - /** - * The shortest version of the LAME version string. - * - * @return shortest version of the LAME version string - */ - this.getLameVeryShortVersion = function () { - // Adding date and time to version string makes it harder for output - return ("LAME" + LAME_MAJOR_VERSION + "." + LAME_MINOR_VERSION + "r"); - } - - /** - * String which describes the version of GPSYCHO - * - * @return string which describes the version of GPSYCHO - */ - this.getPsyVersion = function () { - return (PSY_MAJOR_VERSION + "." + PSY_MINOR_VERSION); - } - - /** - * String which is a URL for the LAME website. - * - * @return string which is a URL for the LAME website - */ - this.getLameUrl = function () { - return LAME_URL; - } - - /** - * Quite useless for a java version, however we are compatible ;-) - * - * @return "32bits" - */ - this.getLameOsBitness = function () { - return "32bits"; - } - -} - -module.exports = Version; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/common.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/common.js deleted file mode 100644 index a179be631..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/common.js +++ /dev/null @@ -1,169 +0,0 @@ -function new_byte(count) { - return new Int8Array(count); -} - -function new_short(count) { - return new Int16Array(count); -} - -function new_int(count) { - return new Int32Array(count); -} - -function new_float(count) { - return new Float32Array(count); -} - -function new_double(count) { - return new Float64Array(count); -} - -function new_float_n(args) { - if (args.length == 1) { - return new_float(args[0]); - } - var sz = args[0]; - args = args.slice(1); - var A = []; - for (var i = 0; i < sz; i++) { - A.push(new_float_n(args)); - } - return A; -} -function new_int_n(args) { - if (args.length == 1) { - return new_int(args[0]); - } - var sz = args[0]; - args = args.slice(1); - var A = []; - for (var i = 0; i < sz; i++) { - A.push(new_int_n(args)); - } - return A; -} - -function new_short_n(args) { - if (args.length == 1) { - return new_short(args[0]); - } - var sz = args[0]; - args = args.slice(1); - var A = []; - for (var i = 0; i < sz; i++) { - A.push(new_short_n(args)); - } - return A; -} - -function new_array_n(args) { - if (args.length == 1) { - return new Array(args[0]); - } - var sz = args[0]; - args = args.slice(1); - var A = []; - for (var i = 0; i < sz; i++) { - A.push(new_array_n(args)); - } - return A; -} - - -var Arrays = {}; - -Arrays.fill = function (a, fromIndex, toIndex, val) { - if (arguments.length == 2) { - for (var i = 0; i < a.length; i++) { - a[i] = arguments[1]; - } - } else { - for (var i = fromIndex; i < toIndex; i++) { - a[i] = val; - } - } -}; - -var System = {}; - -System.arraycopy = function (src, srcPos, dest, destPos, length) { - var srcEnd = srcPos + length; - while (srcPos < srcEnd) - dest[destPos++] = src[srcPos++]; -}; - -System.out = {}; -System.out.println = function (message) { - console.log(message); -} - -System.out.printf = function () { - console.log.apply(console, arguments); -} - - -var Util = {}; -Util.SQRT2 = 1.41421356237309504880; -Util.FAST_LOG10 = function (x) { - return Math.log10(x); -}; - -Util.FAST_LOG10_X = function (x, y) { - return Math.log10(x) * y; -}; - -function ShortBlock(ordinal) { - this.ordinal = ordinal; -} -/** - * LAME may use them, even different block types for L/R. - */ -ShortBlock.short_block_allowed = new ShortBlock(0); -/** - * LAME may use them, but always same block types in L/R. - */ -ShortBlock.short_block_coupled = new ShortBlock(1); -/** - * LAME will not use short blocks, long blocks only. - */ -ShortBlock.short_block_dispensed = new ShortBlock(2); -/** - * LAME will not use long blocks, short blocks only. - */ -ShortBlock.short_block_forced = new ShortBlock(3); - -var Float = {}; -Float.MAX_VALUE = 3.4028235e+38; - -function VbrMode(ordinal) { - this.ordinal = ordinal; -} -VbrMode.vbr_off = new VbrMode(0); -VbrMode.vbr_mt = new VbrMode(1); -VbrMode.vbr_rh = new VbrMode(2); -VbrMode.vbr_abr = new VbrMode(3); -VbrMode.vbr_mtrh = new VbrMode(4); -VbrMode.vbr_default = VbrMode.vbr_mtrh; - -var assert = function (x) { - //console.assert(x); -}; - -module.exports = { - "System": System, - "VbrMode": VbrMode, - "Float": Float, - "ShortBlock": ShortBlock, - "Util": Util, - "Arrays": Arrays, - "new_array_n": new_array_n, - "new_byte": new_byte, - "new_double": new_double, - "new_float": new_float, - "new_float_n": new_float_n, - "new_int": new_int, - "new_int_n": new_int_n, - "new_short": new_short, - "new_short_n": new_short_n, - "assert": assert -}; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/index.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/index.js deleted file mode 100644 index 156f72b06..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/js/index.js +++ /dev/null @@ -1,196 +0,0 @@ -var common = require('./common.js'); -var System = common.System; -var VbrMode = common.VbrMode; -var Float = common.Float; -var ShortBlock = common.ShortBlock; -var Util = common.Util; -var Arrays = common.Arrays; -var new_array_n = common.new_array_n; -var new_byte = common.new_byte; -var new_double = common.new_double; -var new_float = common.new_float; -var new_float_n = common.new_float_n; -var new_int = common.new_int; -var new_int_n = common.new_int_n; -var assert = common.assert; - -var Lame = require('./Lame.js'); -var Presets = require('./Presets.js'); -var GainAnalysis = require('./GainAnalysis.js'); -var QuantizePVT = require('./QuantizePVT.js'); -var Quantize = require('./Quantize.js'); -var Takehiro = require('./Takehiro.js'); -var Reservoir = require('./Reservoir.js'); -var MPEGMode = require('./MPEGMode.js'); -var BitStream = require('./BitStream.js'); -var Encoder = require('./Encoder.js'); -var Version = require('./Version.js'); -var VBRTag = require('./VBRTag.js'); - -function GetAudio() { - var parse; - var mpg; - - this.setModules = function (parse2, mpg2) { - parse = parse2; - mpg = mpg2; - } -} - - -function Parse() { - var ver; - var id3; - var pre; - - this.setModules = function (ver2, id32, pre2) { - ver = ver2; - id3 = id32; - pre = pre2; - } -} - -function MPGLib() { -} - -function ID3Tag() { - var bits; - var ver; - - this.setModules = function (_bits, _ver) { - bits = _bits; - ver = _ver; - } -} - -function Mp3Encoder(channels, samplerate, kbps) { - if (arguments.length != 3) { - console.error('WARN: Mp3Encoder(channels, samplerate, kbps) not specified'); - channels = 1; - samplerate = 44100; - kbps = 128; - } - var lame = new Lame(); - var gaud = new GetAudio(); - var ga = new GainAnalysis(); - var bs = new BitStream(); - var p = new Presets(); - var qupvt = new QuantizePVT(); - var qu = new Quantize(); - var vbr = new VBRTag(); - var ver = new Version(); - var id3 = new ID3Tag(); - var rv = new Reservoir(); - var tak = new Takehiro(); - var parse = new Parse(); - var mpg = new MPGLib(); - - lame.setModules(ga, bs, p, qupvt, qu, vbr, ver, id3, mpg); - bs.setModules(ga, mpg, ver, vbr); - id3.setModules(bs, ver); - p.setModules(lame); - qu.setModules(bs, rv, qupvt, tak); - qupvt.setModules(tak, rv, lame.enc.psy); - rv.setModules(bs); - tak.setModules(qupvt); - vbr.setModules(lame, bs, ver); - gaud.setModules(parse, mpg); - parse.setModules(ver, id3, p); - - var gfp = lame.lame_init(); - - gfp.num_channels = channels; - gfp.in_samplerate = samplerate; - gfp.brate = kbps; - gfp.mode = MPEGMode.STEREO; - gfp.quality = 3; - gfp.bWriteVbrTag = false; - gfp.disable_reservoir = true; - gfp.write_id3tag_automatic = false; - - var retcode = lame.lame_init_params(gfp); - assert(0 == retcode); - var maxSamples = 1152; - var mp3buf_size = 0 | (1.25 * maxSamples + 7200); - var mp3buf = new_byte(mp3buf_size); - - this.encodeBuffer = function (left, right) { - if (channels == 1) { - right = left; - } - assert(left.length == right.length); - if (left.length > maxSamples) { - maxSamples = left.length; - mp3buf_size = 0 | (1.25 * maxSamples + 7200); - mp3buf = new_byte(mp3buf_size); - } - - var _sz = lame.lame_encode_buffer(gfp, left, right, left.length, mp3buf, 0, mp3buf_size); - return new Int8Array(mp3buf.subarray(0, _sz)); - }; - - this.flush = function () { - var _sz = lame.lame_encode_flush(gfp, mp3buf, 0, mp3buf_size); - return new Int8Array(mp3buf.subarray(0, _sz)); - }; -} - -function WavHeader() { - this.dataOffset = 0; - this.dataLen = 0; - this.channels = 0; - this.sampleRate = 0; -} - -function fourccToInt(fourcc) { - return fourcc.charCodeAt(0) << 24 | fourcc.charCodeAt(1) << 16 | fourcc.charCodeAt(2) << 8 | fourcc.charCodeAt(3); -} - -WavHeader.RIFF = fourccToInt("RIFF"); -WavHeader.WAVE = fourccToInt("WAVE"); -WavHeader.fmt_ = fourccToInt("fmt "); -WavHeader.data = fourccToInt("data"); - -WavHeader.readHeader = function (dataView) { - var w = new WavHeader(); - - var header = dataView.getUint32(0, false); - if (WavHeader.RIFF != header) { - return; - } - var fileLen = dataView.getUint32(4, true); - if (WavHeader.WAVE != dataView.getUint32(8, false)) { - return; - } - if (WavHeader.fmt_ != dataView.getUint32(12, false)) { - return; - } - var fmtLen = dataView.getUint32(16, true); - var pos = 16 + 4; - switch (fmtLen) { - case 16: - case 18: - w.channels = dataView.getUint16(pos + 2, true); - w.sampleRate = dataView.getUint32(pos + 4, true); - break; - default: - throw 'extended fmt chunk not implemented'; - } - pos += fmtLen; - var data = WavHeader.data; - var len = 0; - while (data != header) { - header = dataView.getUint32(pos, false); - len = dataView.getUint32(pos + 4, true); - if (data == header) { - break; - } - pos += (len + 8); - } - w.dataLen = len; - w.dataOffset = pos + 8; - return w; -}; - -module.exports.Mp3Encoder = Mp3Encoder; -module.exports.WavHeader = WavHeader; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/assembly/bundle.xml b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/assembly/bundle.xml deleted file mode 100644 index f0c32f953..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/assembly/bundle.xml +++ /dev/null @@ -1,37 +0,0 @@ - - bundle - - dir - zip - - - - /lib - - - - - src/main/resources/run.bat - /bin - true - - - src/main/resources/run.sh - /bin - true - unix - - - src/main/resources/LameUI.xml - /conf - true - - - src/main/resources/picture.png - /images - false - - - \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/COPYING b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/COPYING deleted file mode 100644 index f5030495b..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/COPYING +++ /dev/null @@ -1,481 +0,0 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/LICENSE b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/LICENSE deleted file mode 100644 index 3d186e3c8..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ -Can I use LAME in my commercial program? - -Yes, you can, under the restrictions of the LGPL. The easiest -way to do this is to: - -1. Link to LAME as separate jar (jump3r.jar) - -2. Fully acknowledge that you are using LAME, and give a link - to our web site, www.mp3dev.org - -3. If you make modifications to LAME, you *must* release these - these modifications back to the LAME project, under the LGPL. diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/README b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/README deleted file mode 100644 index 826fbfb58..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/README +++ /dev/null @@ -1,7 +0,0 @@ -jump3r - Java Unofficial MP3 EncodeR - -...is a Java version of lame-3.98.4 - -Java port created by Ken Händel. -Original sources by the authors of Lame: -http://www.sourceforge.net/projects/lame \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/USAGE b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/USAGE deleted file mode 100644 index a1136ed55..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/USAGE +++ /dev/null @@ -1,707 +0,0 @@ - -java -jar jump3r.jar [options] inputfile [outputfile] - -For more options, just type: -java -jar jump3r.jar --help - - -======================================================================= -Constant Bitrate Examples: -======================================================================= -fixed bit rate jstereo 128 kbps encoding: -java -jar jump3r.jar sample.wav sample.mp3 - -fixed bit rate jstereo 128 kbps encoding, higher quality: (recommended) -java -jar jump3r.jar -h sample.wav sample.mp3 - -Fast encode, low quality (no noise shaping) -java -jar jump3r.jar -f sample.wav sample.mp3 - -======================================================================= -Variable Bitrate Examples: -======================================================================= -LAME has two types of variable bitrate: ABR and VBR. - -ABR is the type of variable bitrate encoding usually found in other -MP3 encoders, Vorbis and AAC. The number of bits is determined by -some metric (like perceptual entropy, or just the number of bits -needed for a certain set of encoding tables), and it is not based on -computing the actual encoding/quantization error. ABR should always -give results equal or better than CBR: - -ABR: (--abr means encode with an average bitrate of around x kbps) -java -jar jump3r.jar -h --abr 128 sample.wav sample.mp3 - - -VBR is a true variable bitrate mode which bases the number of bits for -each frame on the measured quantization error relative to the -estimated allowed masking. There are 10 compression levels defined, -ranging from 0=lowest compression to 9 highest compression. The resulting -filesizes depend on the input material. On typical music you can expect --V 5 resulting in files averaging 132 kbps, -V 2 averaging 200 kbps. - -Variable Bitrate (VBR): (use -V n to adjust quality/filesize) -java -jar jump3r.jar -V 2 sample.wav sample.mp3 - - - -======================================================================= -LOW BITRATES -======================================================================= -At lower bitrates, (like 24 kbps per channel), it is recommended that -you use a 16 kHz sampling rate combined with lowpass filtering. LAME, -as well as commercial encoders (FhG, Xing) will do this automatically. -However, if you feel there is too much (or not enough) lowpass -filtering, you may need to try different values of the lowpass cutoff -and passband width (--resample, --lowpass and --lowpass-width options). - - -======================================================================= -options guide: -======================================================================= -These options are explained in detail below. - - -Quality related: - --m m/s/j/f/a mode selection --q n Internal algorithm quality setting 0..9. - 0 = slowest algorithms, but potentially highest quality - 9 = faster algorithms, very poor quality --h same as -q2 --f same as -q7 - - -Constant Bit Rate (CBR) --b n set bitrate (8, 16, 24, ..., 320) ---freeformat produce a free format bitstream. User must also specify - a bitrate with -b, between 8 and 640 kbps. - -Variable Bit Rate (VBR) --v VBR ---vbr-old use old variable bitrate (VBR) routine ---vbr-new use new variable bitrate (VBR) routine (default) --V n VBR quality setting (0=highest quality, 9=lowest) --b n specify a minimum allowed bitrate (8,16,24,...,320) --B n specify a maximum allowed bitrate (8,16,24,...,320) --F strictly enforce minimum bitrate --t disable VBR informational tag ---nohist disable display of VBR bitrate histogram - ---abr n specify average bitrate desired - - -Operational: - --r assume input file is raw PCM --s n input sampling frequency in kHz (for raw PCM input files) ---resample n output sampling frequency ---mp3input input file is an MP3 file. decode using mpglib/mpg123 --x swap bytes of input file ---scale multiply PCM input by ---scale-l scale channel 0 (left) input (multiply PCM data) by ---scale-r scale channel 1 (right) input (multiply PCM data) by --a downmix stereo input file to mono .mp3 --e n/5/c de-emphasis --p add CRC error protection --c mark the encoded file as copyrighted --o mark the encoded file as a copy --S don't print progress report, VBR histogram ---strictly-enforce-ISO comply as much as possible to ISO MPEG spec ---replaygain-fast compute RG fast but slightly inaccurately (default) ---replaygain-accurate compute RG more accurately and find the peak sample ---noreplaygain disable ReplayGain analysis ---clipdetect enable --replaygain-accurate and print a message whether - clipping occurs and how far the waveform is from full scale - ---decode assume input file is an mp3 file, and decode to wav. --t disable writing of WAV header when using --decode - (decode to raw pcm, native endian format (use -x to swap)) - - - -ID3 tagging: - ---tt audio/song title (max 30 chars for version 1 tag) ---ta <artist> audio/song artist (max 30 chars for version 1 tag) ---tl <album> audio/song album (max 30 chars for version 1 tag) ---ty <year> audio/song year of issue (1 to 9999) ---tc <comment> user-defined text (max 30 chars for v1 tag, 28 for v1.1) ---tn <track> audio/song track number (1 to 255, creates v1.1 tag) ---tg <genre> audio/song genre (name or number in list) ---add-id3v2 force addition of version 2 tag ---id3v1-only add only a version 1 tag ---id3v2-only add only a version 2 tag ---space-id3v1 pad version 1 tag with spaces instead of nulls ---pad-id3v2 same as '--pad-id3v2-size 128' ---pad-id3v2-size <num> adds version 2 tag, pad with extra <num> bytes ---genre-list print alphabetically sorted ID3 genre list and exit - -Note: A version 2 tag will NOT be added unless one of the input fields -won't fit in a version 1 tag (e.g. the title string is longer than 30 -characters), or the '--add-id3v2' or '--id3v2-only' options are used. - -Windows and OS/2-specific options: - --priority <type> sets the process priority - - -options not yet described: ---nores disable bit reservoir ---disptime - ---lowpass ---lowpass-width ---highpass ---highpass-width - - - - - -======================================================================= -Detailed description of all options in alphabetical order -======================================================================= - - -======================================================================= -downmix -======================================================================= --a - -mix the stereo input file to mono and encode as mono. - -This option is only needed in the case of raw PCM stereo input -(because LAME cannot determine the number of channels in the input file). -To encode a stereo PCM input file as mono, use "java -jar jump3r.jar -m s -a" - -For WAV and AIFF input files, using "-m m" will always produce a -mono .mp3 file from both mono and stereo input. - - -======================================================================= -average bitrate encoding (aka Safe VBR) -======================================================================= ---abr n - -turns on encoding with a targeted average bitrate of n kbps, allowing -to use frames of different sizes. The allowed range of n is 8...320 -kbps, you can use any integer value within that range. - - - - - -======================================================================= -bitrate -======================================================================= --b n - -For MPEG-1 (sampling frequencies of 32, 44.1 and 48 kHz) -n = 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 - -For MPEG-2 (sampling frequencies of 16, 22.05 and 24 kHz) -n = 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 - -For MPEG-2.5 (sampling frequencies of 8, 11.025 and 12 kHz) -n = 8, 16, 24, 32, 40, 48, 56, 64 - - -The bitrate to be used. Default is 128 kbps MPEG1, 80 kbps MPEG2. - -When used with variable bitrate encodings (VBR), -b specifies the -minimum bitrate to use. This is useful only if you need to circumvent -a buggy hardware device with strange bitrate constrains. - - -======================================================================= -max bitrate -======================================================================= --B n - -see also option "-b" for allowed bitrates. - -Maximum allowed bitrate when using VBR/ABR. - -Using -B is NOT RECOMMENDED. A 128 kbps CBR bitstream, because of the -bit reservoir, can actually have frames which use as many bits as a -320 kbps frame. ABR/VBR modes minimize the use of the bit reservoir, and -thus need to allow 320 kbps frames to get the same flexability as CBR -streams. This is useful only if you need to circumvent a buggy hardware -device with strange bitrate constrains. - - - - -======================================================================= -copyright -======================================================================= --c - -mark the encoded file as copyrighted - - - -======================================================================= -clipping detection -======================================================================= ---clipdetect - -Enable --replaygain-accurate and print a message whether clipping -occurs and how far in dB the waveform is from full scale. - -See also: --replaygain-accurate - - - -======================================================================= -mpglib decode capability -======================================================================= ---decode - -This just uses LAME's mpg123/mpglib interface to decode an MP3 file to -a wav file. The input file can be any input type supported by -encoding, including .mp3 (layers 1, 2 and 3). - -If -t is used (disable wav header), LAME will output -raw pcm in native endian format (use -x to swap bytes). - - -======================================================================= -de-emphasis -======================================================================= --e n/5/c - - n = (none, default) - 5 = 0/15 microseconds - c = citt j.17 - -All this does is set a flag in the bitstream. If you have a PCM -input file where one of the above types of (obsolete) emphasis has -been applied, you can set this flag in LAME. Then the mp3 decoder -should de-emphasize the output during playback, although most -decoders ignore this flag. - -A better solution would be to apply the de-emphasis with a standalone -utility before encoding, and then encode without -e. - - - -======================================================================= -fast mode -======================================================================= --f - -Same as -q 7. - -NOT RECOMMENDED. Use when encoding speed is critical and encoding -quality does not matter. Disable noise shaping. Psycho acoustics are -used only for bit allocation and pre-echo detection. - -======================================================================= -strictly enforce VBR minimum bitrate -======================================================================= --F - -strictly enforce VBR minimum bitrate. With out this option, the minimum -bitrate will be ignored for passages of analog silence. - - - -======================================================================= -free format bitstreams -======================================================================= ---freeformat - -LAME will produce a fixed bitrate, free format bitstream. -User must specify the desired bitrate in kbps, which can -be any integer between 8 and 640. - -Not supported by most decoders. Complient decoders (of which there -are few) are only required to support up to 320 kbps. - -Decoders which can handle free format: - - supports up to -MAD 640 kbps -jump3r 550 kbps -Freeamp: 440 kbps -l3dec: 310 kbps - - - - - -======================================================================= -high quality -======================================================================= --h - -use some quality improvements. The same as -q 2. - - - -======================================================================= -Modes: -======================================================================= - --m m mono --m s stereo --m j joint stereo --m f forced mid/side stereo --m d dual (independent) channels --m a auto - -MONO is the default mode for mono input files. If "-m m" is specified -for a stereo input file, the two channels will be averaged into a mono -signal. - -STEREO - -JOINT STEREO is the default mode for stereo files with fixed bitrates of -128 kbps or less. At higher fixed bitrates, the default is stereo. -For VBR encoding, jstereo is the default for VBR_q >4, and stereo -is the default for VBR_q <=4. You can override all of these defaults -by specifing the mode on the command line. - -jstereo means the encoder can use (on a frame by frame bases) either -regular stereo (just encode left and right channels independently) -or mid/side stereo. In mid/side stereo, the mid (L+R) and side (L-R) -channels are encoded, and more bits are allocated to the mid channel -than the side channel. This will effectively increase the bandwidth -if the signal does not have too much stereo separation. - -Mid/side stereo is basically a trick to increase bandwidth. At 128 kbps, -it is clearly worth while. At higher bitrates it is less useful. - -For truly mono content, use -m m, which will automatically down -sample your input file to mono. This will produce 30% better results -over -m j. - -Using mid/side stereo inappropriately can result in audible -compression artifacts. To much switching between mid/side and regular -stereo can also sound bad. To determine when to switch to mid/side -stereo, LAME uses a much more sophisticated algorithm than that -described in the ISO documentation. - -FORCED MID/SIDE STEREO forces all frames to be encoded mid/side stereo. It -should only be used if you are sure every frame of the input file -has very little stereo seperation. - -DUAL CHANNELS Not supported. - -AUTO - -Auto select should select (if input is stereo) - 8 kbps Mono - 16- 96 kbps Intensity Stereo (if available, otherwise Joint Stereo) - 112-128 kbps Joint Stereo -mj - 160-192 kbps -mj with variable mid/side threshold - 224-320 kbps Independent Stereo -ms - - - -======================================================================= -MP3 input file -======================================================================= ---mp3input - -Assume the input file is a MP3 file. LAME will decode the input file -before re-encoding it. Since MP3 is a lossy format, this is -not recommended in general. But it is useful for creating low bitrate -mp3s from high bitrate mp3s. If the filename ends in ".mp3" LAME will assume -it is an MP3. - - -======================================================================= -disable histogram display -======================================================================= ---nohist - -By default, LAME will display a bitrate histogram while producing -VBR mp3 files. This will disable that feature. - - -======================================================================= -disable ReplayGain analysis -======================================================================= ---noreplaygain - -By default ReplayGain analysis is enabled. This switch disables it. - -See also: --replaygain-accurate, --replaygain-fast - - -======================================================================= -non-original -======================================================================= --o - -mark the encoded file as a copy - - - -======================================================================= -CRC error protection -======================================================================= --p - -turn on CRC error protection. -Yes this really does work correctly in LAME. However, it takes -16 bits per frame that would otherwise be used for encoding. - - -======================================================================= -algorithm quality selection -======================================================================= --q n - -Bitrate is of course the main influence on quality. The higher the -bitrate, the higher the quality. But for a given bitrate, -we have a choice of algorithms to determine the best -scalefactors and huffman encoding (noise shaping). - --q 0: use slowest & best possible version of all algorithms. - --q 2: recommended. Same as -h. -q 0 and -q 1 are slow and may not produce - significantly higher quality. - --q 5: default value. Good speed, reasonable quality - --q 7: same as -f. Very fast, ok quality. (psycho acoustics are - used for pre-echo & M/S, but no noise shaping is done. - --q 9: disables almost all algorithms including psy-model. poor quality. - - - -======================================================================= -input file is raw pcm -======================================================================= --r - -Assume the input file is raw pcm. Sampling rate and mono/stereo/jstereo -must be specified on the command line. Without -r, LAME will perform -several fseek()'s on the input file looking for WAV and AIFF headers. - - - -======================================================================= -slightly more accurate ReplayGain analysis and finding the peak sample -======================================================================= ---replaygain-accurate - -Enable decoding on the fly. Compute "Radio" ReplayGain on the decoded -data stream. Find the peak sample of the decoded data stream and store -it in the file. - - -ReplayGain analysis does _not_ affect the content of a compressed data -stream itself, it is a value stored in the header of a sound file. -Information on the purpose of ReplayGain and the algorithms used is -available from http://www.replaygain.org/ - -By default, LAME performs ReplayGain analysis on the input data (after -the user-specified volume scaling). This behaviour might give slightly -inaccurate results because the data on the output of a lossy -compression/decompression sequence differs from the initial input data. -When --replaygain-accurate is specified the mp3 stream gets decoded on -the fly and the analysis is performed on the decoded data stream. -Although theoretically this method gives more accurate results, it has -several disadvantages: - * tests have shown that the difference between the ReplayGain values - computed on the input data and decoded data is usually no greater - than 0.5dB, although the minimum volume difference the human ear - can perceive is about 1.0dB - * decoding on the fly significantly slows down the encoding process -The apparent advantage is that: - * with --replaygain-accurate the peak sample is determined and - stored in the file. The knowledge of the peak sample can be useful - to decoders (players) to prevent a negative effect called 'clipping' - that introduces distortion into sound. - - -Only the "Radio" ReplayGain value is computed. It is stored in the LAME tag. -The analysis is performed with the reference volume equal to 89dB. -Note: the reference volume has been changed from 83dB on transition -from version 3.95 to 3.95.1. - -See also: --replaygain-fast, --noreplaygain, --clipdetect - - -======================================================================= -fast ReplayGain analysis -======================================================================= ---replaygain-fast - -Compute "Radio" ReplayGain of the input data stream after user-specified -volume scaling and/or resampling. - -ReplayGain analysis does _not_ affect the content of a compressed data -stream itself, it is a value stored in the header of a sound file. -Information on the purpose of ReplayGain and the algorithms used is -available from http://www.replaygain.org/ - -Only the "Radio" ReplayGain value is computed. It is stored in the LAME tag. -The analysis is performed with the reference volume equal to 89dB. -Note: the reference volume has been changed from 83dB on transition -from version 3.95 to 3.95.1. - -This switch is enabled by default. - -See also: --replaygain-accurate, --noreplaygain - - - -======================================================================= -output sampling frequency in kHz -======================================================================= ---resample n - -where n = 8, 11.025, 12, 16, 22.05, 24, 32, 44.1, 48 - -Output sampling frequency. Resample the input if necessary. - -If not specified, LAME may sometimes resample automatically -when faced with extreme compression conditions (like encoding -a 44.1 kHz input file at 32 kbps). To disable this automatic -resampling, you have to use --resamle to set the output samplerate -equal to the input samplerate. In that case, LAME will not -perform any extra computations. - - - -======================================================================= -sampling frequency in kHz -======================================================================= --s n - -where n = sampling rate in kHz. - -Required for raw PCM input files. Otherwise it will be determined -from the header information in the input file. - -LAME will automatically resample the input file to one of the -supported MP3 samplerates if necessary. - - -======================================================================= -silent operation -======================================================================= --S - -don't print progress report - -======================================================================= -scale -======================================================================= ---scale <arg> - -Scales input by <arg>. This just multiplies the PCM data -(after it has been converted to floating point) by <arg>. - -<arg> > 1: increase volume -<arg> = 1: no effect -<arg> < 1: reduce volume - -Use with care, since most MP3 decoders will truncate data -which decodes to values greater than 32768. - - -======================================================================= -strict ISO complience -======================================================================= ---strictly-enforce-ISO - -With this option, LAME will enforce the 7680 bit limitation on -total frame size. This results in many wasted bits for -high bitrate encodings. - - -======================================================================= -disable VBR tag -======================================================================= --t - -Disable writing of the VBR Tag (only valid if -v flag is -specified) This tag in embedded in frame 0 of the MP3 file. It lets -VBR aware players correctly seek and compute playing times of VBR -files. - -When '--decode' is specified (decode mp3 to wav), this flag will -disable writing the WAV header. The output will be raw pcm, -native endian format. Use -x to swap bytes. - - - -======================================================================= -variable bit rate (VBR) -======================================================================= --v - -Turn on VBR. There are several ways you can use VBR. I personally -like using VBR to get files slightly bigger than 128 kbps files, where -the extra bits are used for the occasional difficult-to-encode frame. -For this, try specifying a minimum bitrate to use with VBR: - -java -jar jump3r.jar -v -b 112 input.wav output.mp3 - -If the file is too big, use -V n, where n = 0...9 - -java -jar jump3r.jar -v -V n -b 112 input.wav output.mp3 - - -If you want to use VBR to get the maximum compression possible, -and for this, you can try: - -java -jar jump3r.jar -v input.wav output.mp3 -java -jar jump3r.jar -v -V n input.wav output.mp3 (to vary quality/filesize) - - - - - - -======================================================================= -VBR quality setting -======================================================================= --V n - -n = 0...9. Specifies the value of VBR_q. -default = 4, highest quality = 0, smallest files = 9 - -Using -V 6 or higher (lower quality) is NOT RECOMMENDED. -ABR will produce better results. - - -How is VBR_q used? - -The value of VBR_q influences two basic parameters of LAME's psycho -acoustics: - a) the absolute threshold of hearing - b) the sample to noise ratio -The lower the VBR_q value the lower the injected quantization noise -will be. - -*NOTE* No psy-model is perfect, so there can often be distortion which -is audible even though the psy-model claims it is not! Thus using a -small minimum bitrate can result in some aggressive compression and -audible distortion even with -V 0. Thus using -V 0 does not sound -better than a fixed 256 kbps encoding. For example: suppose in the 1 kHz -frequency band the psy-model claims 20 dB of distortion will not be -detectable by the human ear, so LAME VBR-0 will compress that -frequency band as much as possible and introduce at most 20 dB of -distortion. Using a fixed 256 kbps framesize, LAME could end up -introducing only 2 dB of distortion. If the psy-model was correct, -they will both sound the same. If the psy-model was wrong, the VBR-0 -result can sound worse. - - -======================================================================= -swapbytes -======================================================================= --x - -swap bytes in the input file (and output file when using --decode). -For sorting out little endian/big endian type problems. If your -encodings sound like static, try this first. - diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/lowlevel/LameDecoder.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/lowlevel/LameDecoder.java deleted file mode 100644 index 851984ba3..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/lowlevel/LameDecoder.java +++ /dev/null @@ -1,171 +0,0 @@ -package lowlevel; - -import java.nio.ByteBuffer; - -import mp3.BitStream; -import mp3.Enc; -import mp3.GainAnalysis; -import mp3.GetAudio; -import mp3.ID3Tag; -import mp3.Lame; -import mp3.LameGlobalFlags; -import mp3.Parse; -import mp3.Presets; -import mp3.Quantize; -import mp3.QuantizePVT; -import mp3.Reservoir; -import mp3.Takehiro; -import mp3.VBRTag; -import mp3.Version; -import mpg.Common; -import mpg.Interface; -import mpg.MPGLib; - -public class LameDecoder { - - private GetAudio gaud; - private ID3Tag id3; - private Lame lame; - private GainAnalysis ga; - private BitStream bs; - private Presets p; - private QuantizePVT qupvt; - private Quantize qu; - private VBRTag vbr; - private Version ver; - private Reservoir rv; - private Takehiro tak; - private Parse parse; - - private MPGLib mpg; - private Interface intf; - private Common common; - - private int wavsize; - private short buffer[][] = new short[2][1152]; - // private DataOutput outf; - private LameGlobalFlags gfp; - - public LameDecoder(String mp3File) { - // encoder modules - lame = new Lame(); - gaud = new GetAudio(); - ga = new GainAnalysis(); - bs = new BitStream(); - p = new Presets(); - qupvt = new QuantizePVT(); - qu = new Quantize(); - vbr = new VBRTag(); - ver = new Version(); - id3 = new ID3Tag(); - rv = new Reservoir(); - tak = new Takehiro(); - parse = new Parse(); - - mpg = new MPGLib(); - intf = new Interface(); - common = new Common(); - - lame.setModules(ga, bs, p, qupvt, qu, vbr, ver, id3, mpg); - bs.setModules(ga, mpg, ver, vbr); - id3.setModules(bs, ver); - p.setModules(lame); - qu.setModules(bs, rv, qupvt, tak); - qupvt.setModules(tak, rv, lame.enc.psy); - rv.setModules(bs); - tak.setModules(qupvt); - vbr.setModules(lame, bs, ver); - gaud.setModules(parse, mpg); - parse.setModules(ver, id3, p); - - // decoder modules - mpg.setModules(intf, common); - intf.setModules(vbr, common); - - gfp = lame.lame_init(); - - /* - * turn off automatic writing of ID3 tag data into mp3 stream we have to - * call it before 'lame_init_params', because that function would spit - * out ID3v2 tag data. - */ - gfp.write_id3tag_automatic = false; - - /* - * Now that all the options are set, lame needs to analyze them and set - * some more internal options and check for problems - */ - lame.lame_init_params(gfp); - - parse.input_format = GetAudio.sound_file_format.sf_mp3; - - StringBuilder inPath = new StringBuilder(mp3File); - Enc enc = new Enc(); - - gaud.init_infile(gfp, inPath.toString(), enc); - - int skip_start = 0; - int skip_end = 0; - - if (parse.silent < 10) - System.out.printf("\rinput: %s%s(%g kHz, %d channel%s, ", inPath, - inPath.length() > 26 ? "\n\t" : " ", - gfp.in_samplerate / 1.e3, gfp.num_channels, - gfp.num_channels != 1 ? "s" : ""); - - if (enc.enc_delay > -1 || enc.enc_padding > -1) { - if (enc.enc_delay > -1) - skip_start = enc.enc_delay + 528 + 1; - if (enc.enc_padding > -1) - skip_end = enc.enc_padding - (528 + 1); - } else - skip_start = gfp.encoder_delay + 528 + 1; - - System.out.printf("MPEG-%d%s Layer %s", 2 - gfp.version, - gfp.out_samplerate < 16000 ? ".5" : "", "III"); - - System.out.printf(")\noutput: (16 bit, Microsoft WAVE)\n"); - - if (skip_start > 0) - System.out.printf( - "skipping initial %d samples (encoder+decoder delay)\n", - skip_start); - if (skip_end > 0) - System.out - .printf("skipping final %d samples (encoder padding-decoder delay)\n", - skip_end); - - wavsize = -(skip_start + skip_end); - parse.mp3input_data.totalframes = parse.mp3input_data.nsamp - / parse.mp3input_data.framesize; - - assert (gfp.num_channels >= 1 && gfp.num_channels <= 2); - } - - public void decode(final ByteBuffer sampleBuffer, final boolean playOriginal) { - int iread = gaud.get_audio16(gfp, buffer); - if (iread >= 0) { - parse.mp3input_data.framenum += iread - / parse.mp3input_data.framesize; - wavsize += iread; - - for (int i = 0; i < iread; i++) { - if (playOriginal) { - // We put mp3 data into the sample buffer here! - sampleBuffer.array()[i * 2] = (byte) (buffer[0][i] & 0xff); - sampleBuffer.array()[i * 2 + 1] = (byte) (((buffer[0][i] & 0xffff) >> 8) & 0xff); - } - - if (gfp.num_channels == 2) { - // gaud.write16BitsLowHigh(outf, buffer[1][i] & 0xffff); - // TODO two channels? - } - } - } - - } - - public void close() { - lame.lame_close(gfp); - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/lowlevel/LameEncoder.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/lowlevel/LameEncoder.java deleted file mode 100644 index b7dc5b41d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/lowlevel/LameEncoder.java +++ /dev/null @@ -1,694 +0,0 @@ -package lowlevel; - -import static javax.sound.sampled.AudioSystem.NOT_SPECIFIED; - -import java.nio.ByteOrder; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import javax.sound.sampled.AudioFormat; -import javax.sound.sampled.AudioFormat.Encoding; - -import mp3.BRHist; -import mp3.BitStream; -import mp3.GainAnalysis; -import mp3.GetAudio; -import mp3.ID3Tag; -import mp3.Lame; -import mp3.LameGlobalFlags; -import mp3.MPEGMode; -import mp3.Parse; -import mp3.Presets; -import mp3.Quantize; -import mp3.QuantizePVT; -import mp3.Reservoir; -import mp3.Takehiro; -import mp3.Util; -import mp3.VBRTag; -import mp3.VbrMode; -import mp3.Version; -import mpg.Common; -import mpg.Interface; -import mpg.MPGLib; - -/** - * Wrapper for the jump3r encoder. - * - * @author Ken Handel - */ -public class LameEncoder { - - public static final AudioFormat.Encoding MPEG1L3 = new AudioFormat.Encoding( - "MPEG1L3"); - // Lame converts automagically to MPEG2 or MPEG2.5, if necessary. - public static final AudioFormat.Encoding MPEG2L3 = new AudioFormat.Encoding( - "MPEG2L3"); - public static final AudioFormat.Encoding MPEG2DOT5L3 = new AudioFormat.Encoding( - "MPEG2DOT5L3"); - - // property constants - /** - * property key to read/set the VBR mode: an instance of Boolean (default: - * false) - */ - public static final String P_VBR = "vbr"; - /** - * property key to read/set the channel mode: a String, one of - * "jointstereo", "dual", "mono", - * "auto" (default). - */ - public static final String P_CHMODE = "chmode"; - /** - * property key to read/set the bitrate: an Integer value. Set to -1 for - * default bitrate. - */ - public static final String P_BITRATE = "bitrate"; - /** - * property key to read/set the quality: an Integer from 1 (highest) to 9 - * (lowest). - */ - public static final String P_QUALITY = "quality"; - - // constants from lame.h - public static final int MPEG_VERSION_2 = 0; // MPEG-2 - public static final int MPEG_VERSION_1 = 1; // MPEG-1 - public static final int MPEG_VERSION_2DOT5 = 2; // MPEG-2.5 - - // low mean bitrate in VBR mode - public static final int QUALITY_LOWEST = 9; - public static final int QUALITY_LOW = 7; - public static final int QUALITY_MIDDLE = 5; - public static final int QUALITY_HIGH = 2; - // quality==0 not yet coded in LAME (3.83alpha) - // high mean bitrate in VBR // mode - public static final int QUALITY_HIGHEST = 1; - - public static final int CHANNEL_MODE_STEREO = 0; - public static final int CHANNEL_MODE_JOINT_STEREO = 1; - public static final int CHANNEL_MODE_DUAL_CHANNEL = 2; - public static final int CHANNEL_MODE_MONO = 3; - - // channel mode has no influence on mono files. - public static final int CHANNEL_MODE_AUTO = -1; - public static final int BITRATE_AUTO = -1; - - // suggested maximum buffer size for an mpeg frame - private static final int DEFAULT_PCM_BUFFER_SIZE = 2048 * 16; - - // frame size=576 for MPEG2 and MPEG2.5 - // =576*2 for MPEG1 - - private static int DEFAULT_QUALITY = QUALITY_MIDDLE; - private static int DEFAULT_BITRATE = BITRATE_AUTO; - private static int DEFAULT_CHANNEL_MODE = CHANNEL_MODE_AUTO; - // in VBR mode, bitrate is ignored. - private static boolean DEFAULT_VBR = false; - - // encoding source values - private Encoding sourceEncoding; - private ByteOrder sourceByteOrder; - private int sourceChannels; - private int sourceSampleRate; - private int sourceSampleSizeInBits; - private boolean sourceIsBigEndian; - - private int quality = DEFAULT_QUALITY; - private int bitRate = DEFAULT_BITRATE; - private boolean vbrMode = DEFAULT_VBR; - private int chMode = DEFAULT_CHANNEL_MODE; - - // these fields are set upon successful initialization to show effective - // values. - private int effQuality; - private int effBitRate; - private int effVbr; - private int effChMode; - private int effSampleRate; - private int effEncoding; - private LameGlobalFlags gfp; - private AudioFormat sourceFormat; - private AudioFormat targetFormat; - - - - public LameEncoder() { - - } - - /** - * Initializes the encoder with the given source/PCM format. The default mp3 - * encoding parameters are used, see DEFAULT_BITRATE, DEFAULT_CHANNEL_MODE, - * DEFAULT_QUALITY, and DEFAULT_VBR. - * - * @throws IllegalArgumentException - * when parameters are not supported by LAME. - */ - - - - - public LameEncoder(AudioFormat sourceFormat) { - readParams(sourceFormat, null); - setFormat(sourceFormat, null); - } - - /** - * Initializes the encoder with the given source/PCM format. The mp3 - * parameters are read from the targetFormat's properties. For any parameter - * that is not set, global system properties are queried for backwards - * tritonus compatibility. Last, parameters will use the default values - * DEFAULT_BITRATE, DEFAULT_CHANNEL_MODE, DEFAULT_QUALITY, and DEFAULT_VBR. - * - * @throws IllegalArgumentException - * when parameters are not supported by LAME. - */ - public LameEncoder(AudioFormat sourceFormat, AudioFormat targetFormat) { - readParams(sourceFormat, targetFormat.properties()); - setFormat(sourceFormat, targetFormat); - } - - - /** - * Initializes the encoder, overriding any parameters set in the audio - * format's properties or in the system properties. - * - * @throws IllegalArgumentException - * when parameters are not supported by LAME. - */ - public LameEncoder(AudioFormat sourceFormat, int bitRate, int channelMode, int quality, boolean VBR) { - this.bitRate = bitRate; - this.chMode = channelMode; - this.quality = quality; - this.vbrMode = VBR; - setFormat(sourceFormat, null); - } - - private void readParams(AudioFormat sourceFormat, Map<String, Object> props) { - if (props != null) { - readProps(props); - } - } - - public void setSourceFormat(AudioFormat sourceFormat) { - setFormat(sourceFormat, null); - } - - public void setTargetFormat(AudioFormat targetFormat) { - setFormat(null, targetFormat); - } - - public void setFormat(AudioFormat sourceFormat, AudioFormat targetFormat) { - this.sourceFormat = sourceFormat; - if (sourceFormat!=null){ - sourceEncoding = sourceFormat.getEncoding(); - sourceSampleSizeInBits = sourceFormat.getSampleSizeInBits(); - sourceByteOrder = sourceFormat.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; - sourceChannels = sourceFormat.getChannels(); - sourceSampleRate = Math.round(sourceFormat.getSampleRate()); - sourceIsBigEndian = sourceFormat.isBigEndian(); - // simple check that bitrate is not too high for MPEG2 and MPEG2.5 - // todo: exception ? - if (sourceFormat.getSampleRate() < 32000 && bitRate > 160) { - bitRate = 160; - } - } - //-1 means do not change the sample rate - int targetSampleRate = -1; - this.targetFormat = targetFormat; - if (targetFormat!=null){ - targetSampleRate = Math.round(targetFormat.getSampleRate()); - } - int result = nInitParams(sourceChannels, - sourceSampleRate, - targetSampleRate, - bitRate, - chMode, - quality, - vbrMode, - sourceIsBigEndian); - if (result < 0) { - throw new IllegalArgumentException("parameters not supported by LAME (returned " + result + ")"); - } - } - - GetAudio gaud; - ID3Tag id3; - Lame lame; - GainAnalysis ga; - BitStream bs; - Presets p; - QuantizePVT qupvt; - Quantize qu; - VBRTag vbr; - Version ver; - Util util; - Reservoir rv; - Takehiro tak; - Parse parse; - BRHist hist; - - MPGLib mpg; - Interface intf; - Common common; - - /** - * Initializes the lame encoder. Throws IllegalArgumentException when - * parameters are not supported by LAME. - */ - private int nInitParams(int channels, int inSampleRate, int outSampleRate, int bitrate, - int mode, int quality, boolean VBR, boolean bigEndian) { - // encoder modules - lame = new Lame(); - gaud = new GetAudio(); - ga = new GainAnalysis(); - bs = new BitStream(); - p = new Presets(); - qupvt = new QuantizePVT(); - qu = new Quantize(); - vbr = new VBRTag(); - ver = new Version(); - id3 = new ID3Tag(); - rv = new Reservoir(); - tak = new Takehiro(); - parse = new Parse(); - hist = new BRHist(); - - mpg = new MPGLib(); - intf = new Interface(); - common = new Common(); - - lame.setModules(ga, bs, p, qupvt, qu, vbr, ver, id3, mpg); - bs.setModules(ga, mpg, ver, vbr); - id3.setModules(bs, ver); - p.setModules(lame); - qu.setModules(bs, rv, qupvt, tak); - qupvt.setModules(tak, rv, lame.enc.psy); - rv.setModules(bs); - tak.setModules(qupvt); - vbr.setModules(lame, bs, ver); - gaud.setModules(parse, mpg); - parse.setModules(ver, id3, p); - - - // decoder modules - mpg.setModules(intf, common); - intf.setModules(vbr, common); - - gfp = lame.lame_init(); - gfp.num_channels = channels; - gfp.in_samplerate = inSampleRate; - if (outSampleRate>=0) - gfp.out_samplerate = outSampleRate; - if (mode != CHANNEL_MODE_AUTO) { - gfp.mode = Enum.valueOf(MPEGMode.class, chmode2string(mode)); - } - if (VBR) { - gfp.VBR = VbrMode.vbr_default; - gfp.VBR_q = quality; - } else { - if (bitrate != BITRATE_AUTO) { - gfp.brate = bitrate; - } - } - gfp.quality = quality; - - id3.id3tag_init(gfp); - /* - * turn off automatic writing of ID3 tag data into mp3 stream we have to - * call it before 'lame_init_params', because that function would spit - * out ID3v2 tag data. - */ - gfp.write_id3tag_automatic = false; - gfp.findReplayGain = true; - - int rc = lame.lame_init_params(gfp); - // return effective values - effSampleRate = gfp.out_samplerate; - effBitRate = gfp.brate; - effChMode = gfp.mode.ordinal(); - effVbr = gfp.VBR.ordinal(); - effQuality = (VBR) ? gfp.VBR_q : gfp.quality; - return rc; - } - - /** - * returns -1 if string is too short or returns one of the exception - * constants if everything OK, returns the length of the string - */ - public String getEncoderVersion() { - return ver.getLameVersion(); - } - - /** - * Returns the buffer needed pcm buffer size. The passed parameter is a - * wished buffer size. The implementation of the encoder may return a lower - * or higher buffer size. The encoder must be initalized (i.e. not closed) - * at this point. A return value of <0 denotes an error. - */ - public int getPCMBufferSize() { - return DEFAULT_PCM_BUFFER_SIZE; - } - - public int getMP3BufferSize() { - // bad estimate :) - return getPCMBufferSize() / 2 + 1024; - } - - - public int getInputBufferSize() { - return getPCMBufferSize(); - } - - public int getOutputBufferSize() { - return getMP3BufferSize(); - } - - private int doEncodeBuffer(byte[] pcm, int offset, int length, byte[] encoded) { - int bytes_per_sample = sourceSampleSizeInBits >> 3; - int samples_read = length / bytes_per_sample; - - - - int[] sample_buffer = new int[samples_read]; - - int sample_index = samples_read; - if (!sourceEncoding.toString().equals("PCM_FLOAT")){ - if (sourceByteOrder == ByteOrder.LITTLE_ENDIAN) { - if (bytes_per_sample == 1) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;) - sample_buffer[--sample_index] = (pcm[offset + i] & 0xff) << 24; - if (bytes_per_sample == 2) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;) - sample_buffer[--sample_index] = (pcm[offset + i] & 0xff) << 16 - | (pcm[offset + i + 1] & 0xff) << 24; - if (bytes_per_sample == 3) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;) - sample_buffer[--sample_index] = (pcm[offset + i] & 0xff) << 8 - | (pcm[offset + i + 1] & 0xff) << 16 - | (pcm[offset + i + 2] & 0xff) << 24; - if (bytes_per_sample == 4) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;) - sample_buffer[--sample_index] = (pcm[offset + i] & 0xff) - | (pcm[offset + i + 1] & 0xff) << 8 - | (pcm[offset + i + 2] & 0xff) << 16 - | (pcm[offset + i + 3] & 0xff) << 24; - } else { - if (bytes_per_sample == 1) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;) - sample_buffer[--sample_index] = ((pcm[offset + i] & 0xff) ^ 0x80) << 24 - | 0x7f << 16; - if (bytes_per_sample == 2) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;) - sample_buffer[--sample_index] = (pcm[offset + i] & 0xff) << 24 - | (pcm[offset + i + 1] & 0xff) << 16; - if (bytes_per_sample == 3) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;) - sample_buffer[--sample_index] = (pcm[offset + i] & 0xff) << 24 - | (pcm[offset + i + 1] & 0xff) << 16 - | (pcm[offset + i + 2] & 0xff) << 8; - if (bytes_per_sample == 4) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;) - sample_buffer[--sample_index] = (pcm[offset + i] & 0xff) << 24 - | (pcm[offset + i + 1] & 0xff) << 16 - | (pcm[offset + i + 2] & 0xff) << 8 - | (pcm[offset + i + 3] & 0xff); - } - } else { - if (bytes_per_sample == 4) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;){ - byte[] sample = new byte[4]; - sample[0] = pcm [offset + i]; - sample[1] = pcm [offset + i + 1]; - sample[2] = pcm [offset + i + 2]; - sample[3] = pcm [offset + i + 3]; - float amlitude = convertByteArrayToFloat(sample, 0, sourceByteOrder); - if (Math.abs(amlitude)>=1.0) continue; - int sampleInt = Math.round(Integer.MAX_VALUE*amlitude); - sample_buffer[--sample_index]=sampleInt; -// System.out.print(sample_buffer[--sample_index]=sampleInt); -// System.out.println(Arrays.toString(sample)); - } - } - int p = samples_read; - samples_read /= gfp.num_channels; - - int buffer[][] = new int[2][samples_read]; - if (gfp.num_channels == 2) { - for (int i = samples_read; --i >= 0;) { - buffer[1][i] = sample_buffer[--p]; - buffer[0][i] = sample_buffer[--p]; - } - } else if (gfp.num_channels == 1) { - Arrays.fill(buffer[1], 0, samples_read, 0); - for (int i = samples_read; --i >= 0;) { - buffer[0][i] = buffer[1][i] = sample_buffer[--p]; - } - } - - int res = lame.lame_encode_buffer_int(gfp, buffer[0], buffer[1], samples_read, encoded, 0, encoded.length); - return res; - } - - /** - * Encode a block of data. Throws IllegalArgumentException when parameters - * are wrong. When the <code>encoded</code> array is too small, an - * ArrayIndexOutOfBoundsException is thrown. <code>length</code> should be - * the value returned by getPCMBufferSize. - * - * @return the number of bytes written to <code>encoded</code>. May be 0. - */ - public int encodeBuffer(byte[] pcm, int offset, int length, byte[] encoded) - throws ArrayIndexOutOfBoundsException { - if (length < 0 || (offset + length) > pcm.length) { - throw new IllegalArgumentException("inconsistent parameters"); - } - int result = doEncodeBuffer(pcm, offset, length, encoded); - if (result < 0) { - if (result == -1) { - throw new ArrayIndexOutOfBoundsException( - "Encode buffer too small"); - } - throw new RuntimeException("crucial error in encodeBuffer."); - } - return result; - } - - public int encodeFinish(byte[] encoded) { - return lame.lame_encode_flush(gfp, encoded, 0, encoded.length); - } - - public void close() { - lame.lame_close(gfp); - } - - // properties - private void readProps(Map<String, Object> props) { - Object q = props.get(P_QUALITY); - if (q instanceof String) { - quality = string2quality(((String) q).toLowerCase(), quality); - } else if (q instanceof Integer) { - quality = (Integer) q; - } else if (q != null) { - throw new IllegalArgumentException( - "illegal type of quality property: " + q); - } - q = props.get(P_BITRATE); - if (q instanceof String) { - bitRate = Integer.parseInt((String) q); - } else if (q instanceof Integer) { - bitRate = (Integer) q; - } else if (q != null) { - throw new IllegalArgumentException( - "illegal type of bitrate property: " + q); - } - q = props.get(P_CHMODE); - if (q instanceof String) { - chMode = string2chmode(((String) q).toLowerCase(), chMode); - } else if (q != null) { - throw new IllegalArgumentException( - "illegal type of chmode property: " + q); - } - q = props.get(P_VBR); - if (q instanceof String) { - vbrMode = string2bool(((String) q)); - } else if (q instanceof Boolean) { - vbrMode = (Boolean) q; - } else if (q != null) { - throw new IllegalArgumentException("illegal type of vbr property: " - + q); - } - } - - /** - * Return the audioformat representing the encoded mp3 stream. The format - * object will have the following properties: - * <ul> - * <li>quality: an Integer, 1 (highest) to 9 (lowest) - * <li>bitrate: an Integer, 32...320 kbit/s - * <li>chmode: channel mode, a String, one of "jointstereo", - * "dual", "mono", "auto" (default). - * <li>vbr: a Boolean - * <li>encoder.version: a string with the version of the encoder - * <li>encoder.name: a string with the name of the encoder - * </ul> - */ - public AudioFormat getEffectiveFormat() { - // first gather properties - HashMap<String, Object> map = new HashMap<String, Object>(); - map.put(P_QUALITY, getEffectiveQuality()); - map.put(P_BITRATE, getEffectiveBitRate()); - map.put(P_CHMODE, chmode2string(getEffectiveChannelMode())); - map.put(P_VBR, getEffectiveVBR()); - // map.put(P_SAMPLERATE, getEffectiveSampleRate()); - // map.put(P_ENCODING,getEffectiveEncoding()); - map.put("encoder.name", "LAME"); - map.put("encoder.version", getEncoderVersion()); - int channels = 2; - if (chMode == CHANNEL_MODE_MONO) { - channels = 1; - } - return new AudioFormat(getEffectiveEncoding(), - getEffectiveSampleRate(), NOT_SPECIFIED, channels, - NOT_SPECIFIED, NOT_SPECIFIED, false, map); - } - - public int getEffectiveQuality() { - if (effQuality >= QUALITY_LOWEST) { - return QUALITY_LOWEST; - } else if (effQuality >= QUALITY_LOW) { - return QUALITY_LOW; - } else if (effQuality >= QUALITY_MIDDLE) { - return QUALITY_MIDDLE; - } else if (effQuality >= QUALITY_HIGH) { - return QUALITY_HIGH; - } - return QUALITY_HIGHEST; - } - - public int getEffectiveBitRate() { - return effBitRate; - } - - public int getEffectiveChannelMode() { - return effChMode; - } - - public boolean getEffectiveVBR() { - return effVbr != 0; - } - - public int getEffectiveSampleRate() { - return effSampleRate; - } - - public AudioFormat.Encoding getEffectiveEncoding() { - if (effEncoding == MPEG_VERSION_2) { - if (getEffectiveSampleRate() < 16000) { - return MPEG2DOT5L3; - } - return MPEG2L3; - } else if (effEncoding == MPEG_VERSION_2DOT5) { - return MPEG2DOT5L3; - } - // default - return MPEG1L3; - } - - private int string2quality(String quality, int def) { - if (quality.equals("lowest")) { - return QUALITY_LOWEST; - } else if (quality.equals("low")) { - return QUALITY_LOW; - } else if (quality.equals("middle")) { - return QUALITY_MIDDLE; - } else if (quality.equals("high")) { - return QUALITY_HIGH; - } else if (quality.equals("highest")) { - return QUALITY_HIGHEST; - } - return def; - } - - private String chmode2string(int chmode) { - if (chmode == CHANNEL_MODE_STEREO) { - return "stereo"; - } else if (chmode == CHANNEL_MODE_JOINT_STEREO) { - return "jointstereo"; - } else if (chmode == CHANNEL_MODE_DUAL_CHANNEL) { - return "dual"; - } else if (chmode == CHANNEL_MODE_MONO) { - return "mono"; - } else if (chmode == CHANNEL_MODE_AUTO) { - return "auto"; - } - return "auto"; - } - - private int string2chmode(String chmode, int def) { - if (chmode.equals("stereo")) { - return CHANNEL_MODE_STEREO; - } else if (chmode.equals("jointstereo")) { - return CHANNEL_MODE_JOINT_STEREO; - } else if (chmode.equals("dual")) { - return CHANNEL_MODE_DUAL_CHANNEL; - } else if (chmode.equals("mono")) { - return CHANNEL_MODE_MONO; - } else if (chmode.equals("auto")) { - return CHANNEL_MODE_AUTO; - } - return def; - } - - /** - * @return true if val is starts with t or y or on, false if val starts with - * f or n or off. - * @throws IllegalArgumentException - * if val is neither true nor false - */ - private static boolean string2bool(String val) { - if (val.length() > 0) { - if ((val.charAt(0) == 'f') // false - || (val.charAt(0) == 'n') // no - || (val.equals("off"))) { - return false; - } - if ((val.charAt(0) == 't') // true - || (val.charAt(0) == 'y') // yes - || (val.equals("on"))) { - return true; - } - } - throw new IllegalArgumentException( - "wrong string for boolean property: " + val); - } - - public final float convertByteArrayToFloat(byte bytes[], int offset, ByteOrder byteOrder) - { - byte byte0 = bytes[offset + 0]; - byte byte1 = bytes[offset + 1]; - byte byte2 = bytes[offset + 2]; - byte byte3 = bytes[offset + 3]; - int bits; - if (byteOrder == ByteOrder.BIG_ENDIAN) //big endian - { - bits = ((0xff & byte0) << 24) | ((0xff & byte1) << 16) | ((0xff & byte2) << 8) | ((0xff & byte3) << 0); - } else{ - // little endian - bits = ((0xff & byte3) << 24) | ((0xff & byte2) << 16) | ((0xff & byte1) << 8) | ((0xff & byte0) << 0); - } - float result = Float.intBitsToFloat(bits); - return result; - } - - public AudioFormat getSourceFormat() { - return sourceFormat; - } - - public AudioFormat getTargetFormat() { - return targetFormat; - } - - /** * Lame.java ** */ - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ABRIterationLoop.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ABRIterationLoop.java deleted file mode 100644 index 6adee499a..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ABRIterationLoop.java +++ /dev/null @@ -1,102 +0,0 @@ -package mp3; - -/** - * encode a frame with a disired average bitrate - * - * mt 2000/05/31 - * - * @author Ken - * - */ -public final class ABRIterationLoop implements IIterationLoop { - - /** - * - */ - private final Quantize quantize; - - /** - * @param quantize - */ - ABRIterationLoop(Quantize quantize) { - this.quantize = quantize; - } - - public final void iteration_loop(final LameGlobalFlags gfp, - final float pe[][], final float ms_ener_ratio[], - final III_psy_ratio ratio[][]) { - final LameInternalFlags gfc = gfp.internal_flags; - float l3_xmin[] = new float[L3Side.SFBMAX]; - float xrpow[] = new float[576]; - int targ_bits[][] = new int[2][2]; - int max_frame_bits[] = new int[1]; - int analog_silence_bits[] = new int[1]; - final IIISideInfo l3_side = gfc.l3_side; - - int mean_bits = 0; - - this.quantize.calc_target_bits(gfp, pe, ms_ener_ratio, targ_bits, - analog_silence_bits, max_frame_bits); - - /* - * encode granules - */ - for (int gr = 0; gr < gfc.mode_gr; gr++) { - - if (gfc.mode_ext == Encoder.MPG_MD_MS_LR) { - this.quantize.ms_convert(gfc.l3_side, gr); - } - for (int ch = 0; ch < gfc.channels_out; ch++) { - float adjust, masking_lower_db; - GrInfo cod_info = l3_side.tt[gr][ch]; - - if (cod_info.block_type != Encoder.SHORT_TYPE) { - // NORM, START or STOP type - adjust = 0; - masking_lower_db = gfc.PSY.mask_adjust - adjust; - } else { - adjust = 0; - masking_lower_db = gfc.PSY.mask_adjust_short - adjust; - } - gfc.masking_lower = (float) Math.pow(10.0, - masking_lower_db * 0.1); - - /* - * cod_info, scalefac and xrpow get initialized in - * init_outer_loop - */ - this.quantize.init_outer_loop(gfc, cod_info); - if (this.quantize.init_xrpow(gfc, cod_info, xrpow)) { - /* - * xr contains energy we will have to encode calculate the - * masking abilities find some good quantization in - * outer_loop - */ - int ath_over = this.quantize.qupvt.calc_xmin(gfp, - ratio[gr][ch], cod_info, l3_xmin); - if (0 == ath_over) /* analog silence */ - targ_bits[gr][ch] = analog_silence_bits[0]; - - this.quantize.outer_loop(gfp, cod_info, l3_xmin, xrpow, ch, - targ_bits[gr][ch]); - } - this.quantize.iteration_finish_one(gfc, gr, ch); - } /* ch */ - } /* gr */ - - /* - * find a bitrate which can refill the resevoir to positive size. - */ - for (gfc.bitrate_index = gfc.VBR_min_bitrate; gfc.bitrate_index <= gfc.VBR_max_bitrate; gfc.bitrate_index++) { - - MeanBits mb = new MeanBits(mean_bits); - int rc = this.quantize.rv.ResvFrameBegin(gfp, mb); - mean_bits = mb.bits; - if (rc >= 0) - break; - } - assert (gfc.bitrate_index <= gfc.VBR_max_bitrate); - - this.quantize.rv.ResvFrameEnd(gfc, mean_bits); - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ABRPresets.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ABRPresets.java deleted file mode 100644 index 7ef8a2d28..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ABRPresets.java +++ /dev/null @@ -1,40 +0,0 @@ -package mp3; - -class ABRPresets { - public ABRPresets(final int kbps, final int comp, final int compS, - final int joint, final float fix, final float shThreshold, - final float shThresholdS, final float bass, final float sc, - final float mask, final float lower, final float curve, - final float interCh, final int sfScale) { - quant_comp = comp; - quant_comp_s = compS; - safejoint = joint; - nsmsfix = fix; - st_lrm = shThreshold; - st_s = shThresholdS; - nsbass = bass; - scale = sc; - masking_adj = mask; - ath_lower = lower; - ath_curve = curve; - interch = interCh; - sfscale = sfScale; - } - - int quant_comp; - int quant_comp_s; - int safejoint; - float nsmsfix; - /** - * short threshold - */ - float st_lrm; - float st_s; - float nsbass; - float scale; - float masking_adj; - float ath_lower; - float ath_curve; - float interch; - int sfscale; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ATH.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ATH.java deleted file mode 100644 index d9b943960..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ATH.java +++ /dev/null @@ -1,61 +0,0 @@ -package mp3; - -/** - * ATH related stuff, if something new ATH related has to be added, please plug - * it here into the ATH. - */ -public class ATH { - /** - * Method for the auto adjustment. - */ - int useAdjust; - /** - * factor for tuning the (sample power) point below which adaptive threshold - * of hearing adjustment occurs - */ - float aaSensitivityP; - /** - * Lowering based on peak volume, 1 = no lowering. - */ - float adjust; - /** - * Limit for dynamic ATH adjust. - */ - float adjustLimit; - /** - * Determined to lower x dB each second. - */ - float decay; - /** - * Lowest ATH value. - */ - float floor; - /** - * ATH for sfbs in long blocks. - */ - float l[] = new float[Encoder.SBMAX_l]; - /** - * ATH for sfbs in short blocks. - */ - float s[] = new float[Encoder.SBMAX_s]; - /** - * ATH for partitioned sfb21 in long blocks. - */ - float psfb21[] = new float[Encoder.PSFB21]; - /** - * ATH for partitioned sfb12 in short blocks. - */ - float psfb12[] = new float[Encoder.PSFB12]; - /** - * ATH for long block convolution bands. - */ - float cb_l[] = new float[Encoder.CBANDS]; - /** - * ATH for short block convolution bands. - */ - float cb_s[] = new float[Encoder.CBANDS]; - /** - * Equal loudness weights (based on ATH). - */ - float eql_w[] = new float[Encoder.BLKSIZE / 2]; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/BRHist.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/BRHist.java deleted file mode 100644 index b0c7aa6e4..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/BRHist.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Bitrate histogram source file - * - * Copyright (c) 2000 Mark Taylor - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: BRHist.java,v 1.3 2011/05/24 22:02:42 kenchis Exp $ */ - -package mp3; - -// XXX VBR histogram console output is unsupported in java. -// Console features like cursor-up etc. are missing! -public class BRHist { - - int brhist_init(final LameGlobalFlags gf, final int bitrate_kbps_min, - final int bitrate_kbps_max) { - return 0; - } - - public void brhist_jump_back() { - - } - - public void brhist_disp(LameGlobalFlags gf) { - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/BitStream.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/BitStream.java deleted file mode 100644 index 3c14175b2..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/BitStream.java +++ /dev/null @@ -1,1019 +0,0 @@ -/* - * MP3 bitstream Output interface for LAME - * - * Copyright (c) 1999-2000 Mark Taylor - * Copyright (c) 1999-2002 Takehiro Tominaga - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * $Id: BitStream.java,v 1.23 2011/05/24 22:02:42 kenchis Exp $ - */ -package mp3; - -import java.util.Arrays; - -import mpg.MPGLib; - -public class BitStream { - - private static final int CRC16_POLYNOMIAL = 0x8005; - - /* - * we work with ints, so when doing bit manipulation, we limit ourselves to - * MAX_LENGTH-2 just to be on the safe side - */ - private static final int MAX_LENGTH = 32; - - GainAnalysis ga; - MPGLib mpg; - Version ver; - VBRTag vbr; - - public final void setModules(GainAnalysis ga, MPGLib mpg, Version ver, - VBRTag vbr) { - this.ga = ga; - this.mpg = mpg; - this.ver = ver; - this.vbr = vbr; - } - - /** - * Bit stream buffer. - */ - private byte[] buf; - /** - * Bit counter of bit stream. - */ - private int totbit; - /** - * Pointer to top byte in buffer. - */ - private int bufByteIdx; - /** - * Pointer to top bit of top byte in buffer. - */ - private int bufBitIdx; - - /** - * compute bitsperframe and mean_bits for a layer III frame - */ - public final int getframebits(final LameGlobalFlags gfp) { - final LameInternalFlags gfc = gfp.internal_flags; - int bit_rate; - - /* get bitrate in kbps [?] */ - if (gfc.bitrate_index != 0) - bit_rate = Tables.bitrate_table[gfp.version][gfc.bitrate_index]; - else - bit_rate = gfp.brate; - assert (8 <= bit_rate && bit_rate <= 640); - - /* main encoding routine toggles padding on and off */ - /* one Layer3 Slot consists of 8 bits */ - return 8 * ((gfp.version + 1) * 72000 * bit_rate / gfp.out_samplerate + gfc.padding); - } - - private void putheader_bits(final LameInternalFlags gfc) { - System.arraycopy(gfc.header[gfc.w_ptr].buf, 0, buf, bufByteIdx, - gfc.sideinfo_len); - bufByteIdx += gfc.sideinfo_len; - totbit += gfc.sideinfo_len * 8; - gfc.w_ptr = (gfc.w_ptr + 1) & (LameInternalFlags.MAX_HEADER_BUF - 1); - } - - /** - * write j bits into the bit stream - */ - private void putbits2(final LameInternalFlags gfc, final int val, int j) { - assert (j < MAX_LENGTH - 2); - - while (j > 0) { - int k; - if (bufBitIdx == 0) { - bufBitIdx = 8; - bufByteIdx++; - assert (bufByteIdx < Lame.LAME_MAXMP3BUFFER); - assert (gfc.header[gfc.w_ptr].write_timing >= totbit); - if (gfc.header[gfc.w_ptr].write_timing == totbit) { - putheader_bits(gfc); - } - buf[bufByteIdx] = 0; - } - - k = Math.min(j, bufBitIdx); - j -= k; - - bufBitIdx -= k; - - assert (j < MAX_LENGTH); - /* 32 too large on 32 bit machines */ - assert (bufBitIdx < MAX_LENGTH); - - buf[bufByteIdx] |= ((val >> j) << bufBitIdx); - totbit += k; - } - } - - /** - * write j bits into the bit stream, ignoring frame headers - */ - private void putbits_noheaders(final LameInternalFlags gfc, final int val, - int j) { - assert (j < MAX_LENGTH - 2); - - while (j > 0) { - int k; - if (bufBitIdx == 0) { - bufBitIdx = 8; - bufByteIdx++; - assert (bufByteIdx < Lame.LAME_MAXMP3BUFFER); - buf[bufByteIdx] = 0; - } - - k = Math.min(j, bufBitIdx); - j -= k; - - bufBitIdx -= k; - - assert (j < MAX_LENGTH); /* 32 too large on 32 bit machines */ - assert (bufBitIdx < MAX_LENGTH); - - buf[bufByteIdx] |= ((val >> j) << bufBitIdx); - totbit += k; - } - } - - /** - * Some combinations of bitrate, Fs, and stereo make it impossible to stuff - * out a frame using just main_data, due to the limited number of bits to - * indicate main_data_length. In these situations, we put stuffing bits into - * the ancillary data... - */ - private void drain_into_ancillary(final LameGlobalFlags gfp, - int remainingBits) { - final LameInternalFlags gfc = gfp.internal_flags; - int i; - assert (remainingBits >= 0); - - if (remainingBits >= 8) { - putbits2(gfc, 0x4c, 8); - remainingBits -= 8; - } - if (remainingBits >= 8) { - putbits2(gfc, 0x41, 8); - remainingBits -= 8; - } - if (remainingBits >= 8) { - putbits2(gfc, 0x4d, 8); - remainingBits -= 8; - } - if (remainingBits >= 8) { - putbits2(gfc, 0x45, 8); - remainingBits -= 8; - } - - if (remainingBits >= 32) { - final String version = ver.getLameShortVersion(); - if (remainingBits >= 32) - for (i = 0; i < version.length() && remainingBits >= 8; ++i) { - remainingBits -= 8; - putbits2(gfc, version.charAt(i), 8); - } - } - - for (; remainingBits >= 1; remainingBits -= 1) { - putbits2(gfc, gfc.ancillary_flag, 1); - gfc.ancillary_flag ^= (!gfp.disable_reservoir ? 1 : 0); - } - - assert (remainingBits == 0); - - } - - /** - * write N bits into the header - */ - private void writeheader(final LameInternalFlags gfc, final int val, int j) { - int ptr = gfc.header[gfc.h_ptr].ptr; - - while (j > 0) { - final int k = Math.min(j, 8 - (ptr & 7)); - j -= k; - assert (j < MAX_LENGTH); /* >> 32 too large for 32 bit machines */ - - gfc.header[gfc.h_ptr].buf[ptr >> 3] |= ((val >> j)) << (8 - (ptr & 7) - k); - ptr += k; - } - gfc.header[gfc.h_ptr].ptr = ptr; - } - - private int CRC_update(int value, int crc) { - value <<= 8; - for (int i = 0; i < 8; i++) { - value <<= 1; - crc <<= 1; - - if ((((crc ^ value) & 0x10000) != 0)) - crc ^= CRC16_POLYNOMIAL; - } - return crc; - } - - public final void CRC_writeheader(final LameInternalFlags gfc, - final byte[] header) { - int crc = 0xffff; - /* (jo) init crc16 for error_protection */ - - crc = CRC_update(header[2] & 0xff, crc); - crc = CRC_update(header[3] & 0xff, crc); - for (int i = 6; i < gfc.sideinfo_len; i++) { - crc = CRC_update(header[i] & 0xff, crc); - } - - header[4] = (byte) (crc >> 8); - header[5] = (byte) (crc & 255); - } - - private void encodeSideInfo2(final LameGlobalFlags gfp, - final int bitsPerFrame) { - final LameInternalFlags gfc = gfp.internal_flags; - IIISideInfo l3_side; - int gr, ch; - - l3_side = gfc.l3_side; - gfc.header[gfc.h_ptr].ptr = 0; - Arrays.fill(gfc.header[gfc.h_ptr].buf, 0, gfc.sideinfo_len, (byte) 0); - if (gfp.out_samplerate < 16000) - writeheader(gfc, 0xffe, 12); - else - writeheader(gfc, 0xfff, 12); - writeheader(gfc, (gfp.version), 1); - writeheader(gfc, 4 - 3, 2); - writeheader(gfc, (!gfp.error_protection ? 1 : 0), 1); - writeheader(gfc, (gfc.bitrate_index), 4); - writeheader(gfc, (gfc.samplerate_index), 2); - writeheader(gfc, (gfc.padding), 1); - writeheader(gfc, (gfp.extension), 1); - writeheader(gfc, (gfp.mode.ordinal()), 2); - writeheader(gfc, (gfc.mode_ext), 2); - writeheader(gfc, (gfp.copyright), 1); - writeheader(gfc, (gfp.original), 1); - writeheader(gfc, (gfp.emphasis), 2); - if (gfp.error_protection) { - writeheader(gfc, 0, 16); /* dummy */ - } - - if (gfp.version == 1) { - /* MPEG1 */ - assert (l3_side.main_data_begin >= 0); - writeheader(gfc, (l3_side.main_data_begin), 9); - - if (gfc.channels_out == 2) - writeheader(gfc, l3_side.private_bits, 3); - else - writeheader(gfc, l3_side.private_bits, 5); - - for (ch = 0; ch < gfc.channels_out; ch++) { - int band; - for (band = 0; band < 4; band++) { - writeheader(gfc, l3_side.scfsi[ch][band], 1); - } - } - - for (gr = 0; gr < 2; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - final GrInfo gi = l3_side.tt[gr][ch]; - writeheader(gfc, gi.part2_3_length + gi.part2_length, 12); - writeheader(gfc, gi.big_values / 2, 9); - writeheader(gfc, gi.global_gain, 8); - writeheader(gfc, gi.scalefac_compress, 4); - - if (gi.block_type != Encoder.NORM_TYPE) { - writeheader(gfc, 1, 1); /* window_switching_flag */ - writeheader(gfc, gi.block_type, 2); - writeheader(gfc, gi.mixed_block_flag, 1); - - if (gi.table_select[0] == 14) - gi.table_select[0] = 16; - writeheader(gfc, gi.table_select[0], 5); - if (gi.table_select[1] == 14) - gi.table_select[1] = 16; - writeheader(gfc, gi.table_select[1], 5); - - writeheader(gfc, gi.subblock_gain[0], 3); - writeheader(gfc, gi.subblock_gain[1], 3); - writeheader(gfc, gi.subblock_gain[2], 3); - } else { - writeheader(gfc, 0, 1); /* window_switching_flag */ - if (gi.table_select[0] == 14) - gi.table_select[0] = 16; - writeheader(gfc, gi.table_select[0], 5); - if (gi.table_select[1] == 14) - gi.table_select[1] = 16; - writeheader(gfc, gi.table_select[1], 5); - if (gi.table_select[2] == 14) - gi.table_select[2] = 16; - writeheader(gfc, gi.table_select[2], 5); - - assert (0 <= gi.region0_count && gi.region0_count < 16); - assert (0 <= gi.region1_count && gi.region1_count < 8); - writeheader(gfc, gi.region0_count, 4); - writeheader(gfc, gi.region1_count, 3); - } - writeheader(gfc, gi.preflag, 1); - writeheader(gfc, gi.scalefac_scale, 1); - writeheader(gfc, gi.count1table_select, 1); - } - } - } else { - /* MPEG2 */ - assert (l3_side.main_data_begin >= 0); - writeheader(gfc, (l3_side.main_data_begin), 8); - writeheader(gfc, l3_side.private_bits, gfc.channels_out); - - gr = 0; - for (ch = 0; ch < gfc.channels_out; ch++) { - final GrInfo gi = l3_side.tt[gr][ch]; - writeheader(gfc, gi.part2_3_length + gi.part2_length, 12); - writeheader(gfc, gi.big_values / 2, 9); - writeheader(gfc, gi.global_gain, 8); - writeheader(gfc, gi.scalefac_compress, 9); - - if (gi.block_type != Encoder.NORM_TYPE) { - writeheader(gfc, 1, 1); /* window_switching_flag */ - writeheader(gfc, gi.block_type, 2); - writeheader(gfc, gi.mixed_block_flag, 1); - - if (gi.table_select[0] == 14) - gi.table_select[0] = 16; - writeheader(gfc, gi.table_select[0], 5); - if (gi.table_select[1] == 14) - gi.table_select[1] = 16; - writeheader(gfc, gi.table_select[1], 5); - - writeheader(gfc, gi.subblock_gain[0], 3); - writeheader(gfc, gi.subblock_gain[1], 3); - writeheader(gfc, gi.subblock_gain[2], 3); - } else { - writeheader(gfc, 0, 1); /* window_switching_flag */ - if (gi.table_select[0] == 14) - gi.table_select[0] = 16; - writeheader(gfc, gi.table_select[0], 5); - if (gi.table_select[1] == 14) - gi.table_select[1] = 16; - writeheader(gfc, gi.table_select[1], 5); - if (gi.table_select[2] == 14) - gi.table_select[2] = 16; - writeheader(gfc, gi.table_select[2], 5); - - assert (0 <= gi.region0_count && gi.region0_count < 16); - assert (0 <= gi.region1_count && gi.region1_count < 8); - writeheader(gfc, gi.region0_count, 4); - writeheader(gfc, gi.region1_count, 3); - } - - writeheader(gfc, gi.scalefac_scale, 1); - writeheader(gfc, gi.count1table_select, 1); - } - } - - if (gfp.error_protection) { - /* (jo) error_protection: add crc16 information to header */ - CRC_writeheader(gfc, gfc.header[gfc.h_ptr].buf); - } - - { - final int old = gfc.h_ptr; - assert (gfc.header[old].ptr == gfc.sideinfo_len * 8); - - gfc.h_ptr = (old + 1) & (LameInternalFlags.MAX_HEADER_BUF - 1); - gfc.header[gfc.h_ptr].write_timing = gfc.header[old].write_timing - + bitsPerFrame; - - if (gfc.h_ptr == gfc.w_ptr) { - /* yikes! we are out of header buffer space */ - System.err - .println("Error: MAX_HEADER_BUF too small in bitstream.c \n"); - } - - } - } - - private int huffman_coder_count1(final LameInternalFlags gfc, - final GrInfo gi) { - /* Write count1 area */ - final HuffCodeTab h = Tables.ht[gi.count1table_select + 32]; - int i, bits = 0; - - int ix = gi.big_values; - int xr = gi.big_values; - assert (gi.count1table_select < 2); - - for (i = (gi.count1 - gi.big_values) / 4; i > 0; --i) { - int huffbits = 0; - int p = 0, v; - - v = gi.l3_enc[ix + 0]; - if (v != 0) { - p += 8; - if (gi.xr[xr + 0] < 0) - huffbits++; - assert (v <= 1); - } - - v = gi.l3_enc[ix + 1]; - if (v != 0) { - p += 4; - huffbits *= 2; - if (gi.xr[xr + 1] < 0) - huffbits++; - assert (v <= 1); - } - - v = gi.l3_enc[ix + 2]; - if (v != 0) { - p += 2; - huffbits *= 2; - if (gi.xr[xr + 2] < 0) - huffbits++; - assert (v <= 1); - } - - v = gi.l3_enc[ix + 3]; - if (v != 0) { - p++; - huffbits *= 2; - if (gi.xr[xr + 3] < 0) - huffbits++; - assert (v <= 1); - } - - ix += 4; - xr += 4; - putbits2(gfc, huffbits + h.table[p], h.hlen[p]); - bits += h.hlen[p]; - } - return bits; - } - - /** - * Implements the pseudocode of page 98 of the IS - */ - private int Huffmancode(final LameInternalFlags gfc, final int tableindex, - final int start, final int end, final GrInfo gi) { - final HuffCodeTab h = Tables.ht[tableindex]; - int bits = 0; - - assert (tableindex < 32); - if (0 == tableindex) - return bits; - - for (int i = start; i < end; i += 2) { - int cbits = 0; - int xbits = 0; - final int linbits = h.xlen; - int xlen = h.xlen; - int ext = 0; - int x1 = gi.l3_enc[i]; - int x2 = gi.l3_enc[i + 1]; - - if (x1 != 0) { - if (gi.xr[i] < 0) - ext++; - cbits--; - } - - if (tableindex > 15) { - /* use ESC-words */ - if (x1 > 14) { - final int linbits_x1 = x1 - 15; - assert (linbits_x1 <= h.linmax); - ext |= linbits_x1 << 1; - xbits = linbits; - x1 = 15; - } - - if (x2 > 14) { - final int linbits_x2 = x2 - 15; - assert (linbits_x2 <= h.linmax); - ext <<= linbits; - ext |= linbits_x2; - xbits += linbits; - x2 = 15; - } - xlen = 16; - } - - if (x2 != 0) { - ext <<= 1; - if (gi.xr[i + 1] < 0) - ext++; - cbits--; - } - - assert ((x1 | x2) < 16); - - x1 = x1 * xlen + x2; - xbits -= cbits; - cbits += h.hlen[x1]; - - assert (cbits <= MAX_LENGTH); - assert (xbits <= MAX_LENGTH); - - putbits2(gfc, h.table[x1], cbits); - putbits2(gfc, ext, xbits); - bits += cbits + xbits; - } - return bits; - } - - /** - * Note the discussion of huffmancodebits() on pages 28 and 29 of the IS, as - * well as the definitions of the side information on pages 26 and 27. - */ - private int ShortHuffmancodebits(final LameInternalFlags gfc, - final GrInfo gi) { - int region1Start = 3 * gfc.scalefac_band.s[3]; - if (region1Start > gi.big_values) - region1Start = gi.big_values; - - /* short blocks do not have a region2 */ - int bits = Huffmancode(gfc, gi.table_select[0], 0, region1Start, gi); - bits += Huffmancode(gfc, gi.table_select[1], region1Start, - gi.big_values, gi); - return bits; - } - - private int LongHuffmancodebits(final LameInternalFlags gfc, final GrInfo gi) { - int bigvalues, bits; - int region1Start, region2Start; - - bigvalues = gi.big_values; - assert (0 <= bigvalues && bigvalues <= 576); - - int i = gi.region0_count + 1; - assert (0 <= i); - assert (i < gfc.scalefac_band.l.length); - region1Start = gfc.scalefac_band.l[i]; - i += gi.region1_count + 1; - assert (0 <= i); - assert (i < gfc.scalefac_band.l.length); - region2Start = gfc.scalefac_band.l[i]; - - if (region1Start > bigvalues) - region1Start = bigvalues; - - if (region2Start > bigvalues) - region2Start = bigvalues; - - bits = Huffmancode(gfc, gi.table_select[0], 0, region1Start, gi); - bits += Huffmancode(gfc, gi.table_select[1], region1Start, - region2Start, gi); - bits += Huffmancode(gfc, gi.table_select[2], region2Start, bigvalues, - gi); - return bits; - } - - private int writeMainData(final LameGlobalFlags gfp) { - int gr, ch, sfb, data_bits, tot_bits = 0; - final LameInternalFlags gfc = gfp.internal_flags; - final IIISideInfo l3_side = gfc.l3_side; - - if (gfp.version == 1) { - /* MPEG 1 */ - for (gr = 0; gr < 2; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - final GrInfo gi = l3_side.tt[gr][ch]; - final int slen1 = Takehiro.slen1_tab[gi.scalefac_compress]; - final int slen2 = Takehiro.slen2_tab[gi.scalefac_compress]; - data_bits = 0; - for (sfb = 0; sfb < gi.sfbdivide; sfb++) { - if (gi.scalefac[sfb] == -1) - continue; /* scfsi is used */ - putbits2(gfc, gi.scalefac[sfb], slen1); - data_bits += slen1; - } - for (; sfb < gi.sfbmax; sfb++) { - if (gi.scalefac[sfb] == -1) - continue; /* scfsi is used */ - putbits2(gfc, gi.scalefac[sfb], slen2); - data_bits += slen2; - } - assert (data_bits == gi.part2_length); - - if (gi.block_type == Encoder.SHORT_TYPE) { - data_bits += ShortHuffmancodebits(gfc, gi); - } else { - data_bits += LongHuffmancodebits(gfc, gi); - } - data_bits += huffman_coder_count1(gfc, gi); - /* does bitcount in quantize.c agree with actual bit count? */ - assert (data_bits == gi.part2_3_length + gi.part2_length); - tot_bits += data_bits; - } /* for ch */ - } /* for gr */ - } else { - /* MPEG 2 */ - gr = 0; - for (ch = 0; ch < gfc.channels_out; ch++) { - final GrInfo gi = l3_side.tt[gr][ch]; - int i, sfb_partition, scale_bits = 0; - assert (gi.sfb_partition_table != null); - data_bits = 0; - sfb = 0; - sfb_partition = 0; - - if (gi.block_type == Encoder.SHORT_TYPE) { - for (; sfb_partition < 4; sfb_partition++) { - final int sfbs = gi.sfb_partition_table[sfb_partition] / 3; - final int slen = gi.slen[sfb_partition]; - for (i = 0; i < sfbs; i++, sfb++) { - putbits2(gfc, - Math.max(gi.scalefac[sfb * 3 + 0], 0), slen); - putbits2(gfc, - Math.max(gi.scalefac[sfb * 3 + 1], 0), slen); - putbits2(gfc, - Math.max(gi.scalefac[sfb * 3 + 2], 0), slen); - scale_bits += 3 * slen; - } - } - data_bits += ShortHuffmancodebits(gfc, gi); - } else { - for (; sfb_partition < 4; sfb_partition++) { - final int sfbs = gi.sfb_partition_table[sfb_partition]; - final int slen = gi.slen[sfb_partition]; - for (i = 0; i < sfbs; i++, sfb++) { - putbits2(gfc, Math.max(gi.scalefac[sfb], 0), slen); - scale_bits += slen; - } - } - data_bits += LongHuffmancodebits(gfc, gi); - } - data_bits += huffman_coder_count1(gfc, gi); - /* does bitcount in quantize.c agree with actual bit count? */ - assert (data_bits == gi.part2_3_length); - assert (scale_bits == gi.part2_length); - tot_bits += scale_bits + data_bits; - } /* for ch */ - } /* for gf */ - return tot_bits; - } /* main_data */ - - public static class TotalBytes { - public int total; - } - - /* - * compute the number of bits required to flush all mp3 frames currently in - * the buffer. This should be the same as the reservoir size. Only call this - * routine between frames - i.e. only after all headers and data have been - * added to the buffer by format_bitstream(). - * - * Also compute total_bits_output = size of mp3 buffer (including frame - * headers which may not have yet been send to the mp3 buffer) + number of - * bits needed to flush all mp3 frames. - * - * total_bytes_output is the size of the mp3 output buffer if - * lame_encode_flush_nogap() was called right now. - */ - private int compute_flushbits(final LameGlobalFlags gfp, - final TotalBytes total_bytes_output) { - final LameInternalFlags gfc = gfp.internal_flags; - int flushbits, remaining_headers; - int bitsPerFrame; - int last_ptr, first_ptr; - first_ptr = gfc.w_ptr; - /* first header to add to bitstream */ - last_ptr = gfc.h_ptr - 1; - /* last header to add to bitstream */ - if (last_ptr == -1) - last_ptr = LameInternalFlags.MAX_HEADER_BUF - 1; - - /* add this many bits to bitstream so we can flush all headers */ - flushbits = gfc.header[last_ptr].write_timing - totbit; - total_bytes_output.total = flushbits; - - if (flushbits >= 0) { - /* if flushbits >= 0, some headers have not yet been written */ - /* reduce flushbits by the size of the headers */ - remaining_headers = 1 + last_ptr - first_ptr; - if (last_ptr < first_ptr) - remaining_headers = 1 + last_ptr - first_ptr - + LameInternalFlags.MAX_HEADER_BUF; - flushbits -= remaining_headers * 8 * gfc.sideinfo_len; - } - - /* - * finally, add some bits so that the last frame is complete these bits - * are not necessary to decode the last frame, but some decoders will - * ignore last frame if these bits are missing - */ - bitsPerFrame = getframebits(gfp); - flushbits += bitsPerFrame; - total_bytes_output.total += bitsPerFrame; - /* round up: */ - if ((total_bytes_output.total % 8) != 0) - total_bytes_output.total = 1 + (total_bytes_output.total / 8); - else - total_bytes_output.total = (total_bytes_output.total / 8); - total_bytes_output.total += bufByteIdx + 1; - - if (flushbits < 0) { - System.err.println("strange error flushing buffer ... \n"); - } - return flushbits; - } - - public final void flush_bitstream(final LameGlobalFlags gfp) { - final LameInternalFlags gfc = gfp.internal_flags; - IIISideInfo l3_side; - int flushbits; - int last_ptr = gfc.h_ptr - 1; - /* last header to add to bitstream */ - if (last_ptr == -1) - last_ptr = LameInternalFlags.MAX_HEADER_BUF - 1; - l3_side = gfc.l3_side; - - if ((flushbits = compute_flushbits(gfp, new TotalBytes())) < 0) - return; - drain_into_ancillary(gfp, flushbits); - - /* check that the 100% of the last frame has been written to bitstream */ - assert (gfc.header[last_ptr].write_timing + getframebits(gfp) == totbit); - - /* - * we have padded out all frames with ancillary data, which is the same - * as filling the bitreservoir with ancillary data, so : - */ - gfc.ResvSize = 0; - l3_side.main_data_begin = 0; - - /* save the ReplayGain value */ - if (gfc.findReplayGain) { - final float RadioGain = (float) ga.GetTitleGain(gfc.rgdata); - assert (NEQ(RadioGain, GainAnalysis.GAIN_NOT_ENOUGH_SAMPLES)); - gfc.RadioGain = (int) Math.floor(RadioGain * 10.0 + 0.5); - /* round to nearest */ - } - - /* find the gain and scale change required for no clipping */ - if (gfc.findPeakSample) { - gfc.noclipGainChange = (int) Math.ceil(Math - .log10(gfc.PeakSample / 32767.0) * 20.0 * 10.0); - /* round up */ - - if (gfc.noclipGainChange > 0) { - /* clipping occurs */ - if (EQ(gfp.scale, 1.0f) || EQ(gfp.scale, 0.0f)) - gfc.noclipScale = (float) (Math - .floor((32767.0 / gfc.PeakSample) * 100.0f) / 100.0f); - /* round down */ - else { - /* - * the user specified his own scaling factor. We could - * suggest the scaling factor of - * (32767.0/gfp.PeakSample)*(gfp.scale) but it's usually - * very inaccurate. So we'd rather not advice him on the - * scaling factor. - */ - gfc.noclipScale = -1; - } - } else - /* no clipping */ - gfc.noclipScale = -1; - } - } - - public final void add_dummy_byte(final LameGlobalFlags gfp, final int val, - int n) { - final LameInternalFlags gfc = gfp.internal_flags; - int i; - - while (n-- > 0) { - putbits_noheaders(gfc, val, 8); - - for (i = 0; i < LameInternalFlags.MAX_HEADER_BUF; ++i) - gfc.header[i].write_timing += 8; - } - } - - /** - * This is called after a frame of audio has been quantized and coded. It - * will write the encoded audio to the bitstream. Note that from a layer3 - * encoder's perspective the bit stream is primarily a series of main_data() - * blocks, with header and side information inserted at the proper locations - * to maintain framing. (See Figure A.7 in the IS). - */ - public final int format_bitstream(final LameGlobalFlags gfp) { - final LameInternalFlags gfc = gfp.internal_flags; - IIISideInfo l3_side; - l3_side = gfc.l3_side; - - int bitsPerFrame = getframebits(gfp); - drain_into_ancillary(gfp, l3_side.resvDrain_pre); - - encodeSideInfo2(gfp, bitsPerFrame); - int bits = 8 * gfc.sideinfo_len; - bits += writeMainData(gfp); - drain_into_ancillary(gfp, l3_side.resvDrain_post); - bits += l3_side.resvDrain_post; - - l3_side.main_data_begin += (bitsPerFrame - bits) / 8; - - /* - * compare number of bits needed to clear all buffered mp3 frames with - * what we think the resvsize is: - */ - if (compute_flushbits(gfp, new TotalBytes()) != gfc.ResvSize) { - System.err - .println("Internal buffer inconsistency. flushbits <> ResvSize"); - } - - /* - * compare main_data_begin for the next frame with what we think the - * resvsize is: - */ - if ((l3_side.main_data_begin * 8) != gfc.ResvSize) { - System.err.printf("bit reservoir error: \n" - + "l3_side.main_data_begin: %d \n" - + "Resvoir size: %d \n" - + "resv drain (post) %d \n" - + "resv drain (pre) %d \n" - + "header and sideinfo: %d \n" - + "data bits: %d \n" - + "total bits: %d (remainder: %d) \n" - + "bitsperframe: %d \n", - 8 * l3_side.main_data_begin, gfc.ResvSize, - l3_side.resvDrain_post, l3_side.resvDrain_pre, - 8 * gfc.sideinfo_len, bits - l3_side.resvDrain_post - 8 - * gfc.sideinfo_len, bits, bits % 8, bitsPerFrame); - - System.err - .println("This is a fatal error. It has several possible causes:"); - System.err - .println("90%% LAME compiled with buggy version of gcc using advanced optimizations"); - System.err.println(" 9%% Your system is overclocked"); - System.err.println(" 1%% bug in LAME encoding library"); - - gfc.ResvSize = l3_side.main_data_begin * 8; - } - ; - assert (totbit % 8 == 0); - - if (totbit > 1000000000) { - /* - * to avoid totbit overflow, (at 8h encoding at 128kbs) lets reset - * bit counter - */ - int i; - for (i = 0; i < LameInternalFlags.MAX_HEADER_BUF; ++i) - gfc.header[i].write_timing -= totbit; - totbit = 0; - } - - return 0; - } - - /** - * <PRE> - * copy data out of the internal MP3 bit buffer into a user supplied - * unsigned char buffer. - * - * mp3data=0 indicates data in buffer is an id3tags and VBR tags - * mp3data=1 data is real mp3 frame data. - * </PRE> - */ - public final int copy_buffer(final LameInternalFlags gfc, - final byte[] buffer, final int bufferPos, final int size, - final int mp3data) { - final int minimum = bufByteIdx + 1; - if (minimum <= 0) - return 0; - if (size != 0 && minimum > size) { - /* buffer is too small */ - return -1; - } - System.arraycopy(buf, 0, buffer, bufferPos, minimum); - bufByteIdx = -1; - bufBitIdx = 0; - - if (mp3data != 0) { - int[] crc = new int[1]; - crc[0] = gfc.nMusicCRC; - vbr.updateMusicCRC(crc, buffer, bufferPos, minimum); - gfc.nMusicCRC = crc[0]; - - /** - * sum number of bytes belonging to the mp3 stream this info will be - * written into the Xing/LAME header for seeking - */ - if (minimum > 0) { - gfc.VBR_seek_table.nBytesWritten += minimum; - } - - if (gfc.decode_on_the_fly) { /* decode the frame */ - float pcm_buf[][] = new float[2][1152]; - int mp3_in = minimum; - int samples_out = -1; - int i; - - /* re-synthesis to pcm. Repeat until we get a samples_out=0 */ - while (samples_out != 0) { - - samples_out = mpg.hip_decode1_unclipped(gfc.hip, buffer, - bufferPos, mp3_in, pcm_buf[0], pcm_buf[1]); - /* - * samples_out = 0: need more data to decode samples_out = - * -1: error. Lets assume 0 pcm output samples_out = number - * of samples output - */ - - /* - * set the lenght of the mp3 input buffer to zero, so that - * in the next iteration of the loop we will be querying - * mpglib about buffered data - */ - mp3_in = 0; - - if (samples_out == -1) { - /* - * error decoding. Not fatal, but might screw up the - * ReplayGain tag. What should we do? Ignore for now - */ - samples_out = 0; - } - if (samples_out > 0) { - /* process the PCM data */ - - /* - * this should not be possible, and indicates we have - * overflown the pcm_buf buffer - */ - assert (samples_out <= 1152); - - if (gfc.findPeakSample) { - for (i = 0; i < samples_out; i++) { - if (pcm_buf[0][i] > gfc.PeakSample) - gfc.PeakSample = pcm_buf[0][i]; - else if (-pcm_buf[0][i] > gfc.PeakSample) - gfc.PeakSample = -pcm_buf[0][i]; - } - if (gfc.channels_out > 1) - for (i = 0; i < samples_out; i++) { - if (pcm_buf[1][i] > gfc.PeakSample) - gfc.PeakSample = pcm_buf[1][i]; - else if (-pcm_buf[1][i] > gfc.PeakSample) - gfc.PeakSample = -pcm_buf[1][i]; - } - } - - if (gfc.findReplayGain) - if (ga.AnalyzeSamples(gfc.rgdata, pcm_buf[0], 0, - pcm_buf[1], 0, samples_out, - gfc.channels_out) == GainAnalysis.GAIN_ANALYSIS_ERROR) - return -6; - - } /* if (samples_out>0) */ - } /* while (samples_out!=0) */ - } /* if (gfc.decode_on_the_fly) */ - - } /* if (mp3data) */ - return minimum; - } - - public final void init_bit_stream_w(final LameInternalFlags gfc) { - buf = new byte[Lame.LAME_MAXMP3BUFFER]; - - gfc.h_ptr = gfc.w_ptr = 0; - gfc.header[gfc.h_ptr].write_timing = 0; - bufByteIdx = -1; - bufBitIdx = 0; - totbit = 0; - } - - // From machine.h - - public static boolean EQ(float a, float b) { - return (Math.abs(a) > Math.abs(b)) ? (Math.abs((a) - (b)) <= (Math - .abs(a) * 1e-6f)) - : (Math.abs((a) - (b)) <= (Math.abs(b) * 1e-6f)); - } - - public static boolean NEQ(float a, float b) { - return !EQ(a, b); - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/CBRNewIterationLoop.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/CBRNewIterationLoop.java deleted file mode 100644 index 0e0be8a1e..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/CBRNewIterationLoop.java +++ /dev/null @@ -1,91 +0,0 @@ -package mp3; - -/** - * author/date?? - * - * encodes one frame of MP3 data with constant bitrate - * - * @author Ken - * - */ -public final class CBRNewIterationLoop implements IIterationLoop { - /** - * - */ - private final Quantize quantize; - - /** - * @param quantize - */ - CBRNewIterationLoop(Quantize quantize) { - this.quantize = quantize; - } - - public void iteration_loop(final LameGlobalFlags gfp, final float pe[][], - final float ms_ener_ratio[], final III_psy_ratio ratio[][]) { - final LameInternalFlags gfc = gfp.internal_flags; - float l3_xmin[] = new float[L3Side.SFBMAX]; - float xrpow[] = new float[576]; - int targ_bits[] = new int[2]; - int mean_bits = 0, max_bits; - final IIISideInfo l3_side = gfc.l3_side; - - MeanBits mb = new MeanBits(mean_bits); - this.quantize.rv.ResvFrameBegin(gfp, mb); - mean_bits = mb.bits; - - /* quantize! */ - for (int gr = 0; gr < gfc.mode_gr; gr++) { - - /* - * calculate needed bits - */ - max_bits = this.quantize.qupvt.on_pe(gfp, pe, targ_bits, mean_bits, - gr, gr); - - if (gfc.mode_ext == Encoder.MPG_MD_MS_LR) { - this.quantize.ms_convert(gfc.l3_side, gr); - this.quantize.qupvt.reduce_side(targ_bits, ms_ener_ratio[gr], - mean_bits, max_bits); - } - - for (int ch = 0; ch < gfc.channels_out; ch++) { - float adjust, masking_lower_db; - GrInfo cod_info = l3_side.tt[gr][ch]; - - if (cod_info.block_type != Encoder.SHORT_TYPE) { - // NORM, START or STOP type - adjust = 0; - masking_lower_db = gfc.PSY.mask_adjust - adjust; - } else { - adjust = 0; - masking_lower_db = gfc.PSY.mask_adjust_short - adjust; - } - gfc.masking_lower = (float) Math.pow(10.0, - masking_lower_db * 0.1); - - /* - * init_outer_loop sets up cod_info, scalefac and xrpow - */ - this.quantize.init_outer_loop(gfc, cod_info); - if (this.quantize.init_xrpow(gfc, cod_info, xrpow)) { - /* - * xr contains energy we will have to encode calculate the - * masking abilities find some good quantization in - * outer_loop - */ - this.quantize.qupvt.calc_xmin(gfp, ratio[gr][ch], cod_info, - l3_xmin); - this.quantize.outer_loop(gfp, cod_info, l3_xmin, xrpow, ch, - targ_bits[ch]); - } - - this.quantize.iteration_finish_one(gfc, gr, ch); - assert (cod_info.part2_3_length <= LameInternalFlags.MAX_BITS_PER_CHANNEL); - assert (cod_info.part2_3_length <= targ_bits[ch]); - } /* for ch */ - } /* for gr */ - - this.quantize.rv.ResvFrameEnd(gfc, mean_bits); - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/CalcNoiseData.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/CalcNoiseData.java deleted file mode 100644 index 9bf86d334..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/CalcNoiseData.java +++ /dev/null @@ -1,12 +0,0 @@ -package mp3; - -/** - * allows re-use of previously computed noise values - */ -public class CalcNoiseData { - int global_gain; - int sfb_count1; - int step[] = new int[39]; - float noise[] = new float[39]; - float noise_log[] = new float[39]; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/CalcNoiseResult.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/CalcNoiseResult.java deleted file mode 100644 index 05a25ad44..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/CalcNoiseResult.java +++ /dev/null @@ -1,25 +0,0 @@ -package mp3; - -public class CalcNoiseResult { - /** - * sum of quantization noise > masking - */ - float over_noise; - /** - * sum of all quantization noise - */ - float tot_noise; - /** - * max quantization noise - */ - float max_noise; - /** - * number of quantization noise > masking - */ - int over_count; - /** - * SSD-like cost of distorted bands - */ - int over_SSD; - int bits; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Enc.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Enc.java deleted file mode 100644 index 7f2a0fecc..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Enc.java +++ /dev/null @@ -1,6 +0,0 @@ -package mp3; - -public class Enc { - public int enc_delay = -1; - public int enc_padding = -1; -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Encoder.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Encoder.java deleted file mode 100644 index 79bac8eb5..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Encoder.java +++ /dev/null @@ -1,654 +0,0 @@ -/* - * LAME MP3 encoding engine - * - * Copyright (c) 1999 Mark Taylor - * Copyright (c) 2000-2002 Takehiro Tominaga - * Copyright (c) 2000-2005 Robert Hegemann - * Copyright (c) 2001 Gabriel Bouvigne - * Copyright (c) 2001 John Dahlstrom - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: Encoder.java,v 1.21 2011/05/24 21:45:14 kenchis Exp $ */ -package mp3; - -public class Encoder { - BitStream bs; - public PsyModel psy; - VBRTag vbr; - QuantizePVT qupvt; - - public final void setModules(BitStream bs, PsyModel psy, QuantizePVT qupvt, - VBRTag vbr) { - this.bs = bs; - this.psy = psy; - this.vbr = vbr; - this.qupvt = qupvt; - } - - private NewMDCT newMDCT = new NewMDCT(); - - /*********************************************************************** - * - * encoder and decoder delays - * - ***********************************************************************/ - - /** - * <PRE> - * layer III enc->dec delay: 1056 (1057?) (observed) - * layer II enc->dec delay: 480 (481?) (observed) - * - * polyphase 256-16 (dec or enc) = 240 - * mdct 256+32 (9*32) (dec or enc) = 288 - * total: 512+16 - * - * My guess is that delay of polyphase filterbank is actualy 240.5 - * (there are technical reasons for this, see postings in mp3encoder). - * So total Encode+Decode delay = ENCDELAY + 528 + 1 - * </PRE> - */ - - /** - * ENCDELAY The encoder delay. - * - * Minimum allowed is MDCTDELAY (see below) - * - * The first 96 samples will be attenuated, so using a value less than 96 - * will result in corrupt data for the first 96-ENCDELAY samples. - * - * suggested: 576 set to 1160 to sync with FhG. - */ - public static final int ENCDELAY = 576; - - /** - * make sure there is at least one complete frame after the last frame - * containing real data - * - * Using a value of 288 would be sufficient for a a very sophisticated - * decoder that can decode granule-by-granule instead of frame by frame. But - * lets not assume this, and assume the decoder will not decode frame N - * unless it also has data for frame N+1 - */ - public static final int POSTDELAY = 1152; - - /** - * delay of the MDCT used in mdct.c original ISO routines had a delay of - * 528! Takehiro's routines: - */ - public static final int MDCTDELAY = 48; - public static final int FFTOFFSET = (224 + MDCTDELAY); - - /** - * Most decoders, including the one we use, have a delay of 528 samples. - */ - public static final int DECDELAY = 528; - - /** - * number of subbands - */ - public static final int SBLIMIT = 32; - - /** - * parition bands bands - */ - public static final int CBANDS = 64; - - /** - * number of critical bands/scale factor bands where masking is computed - */ - public static final int SBPSY_l = 21; - public static final int SBPSY_s = 12; - - /** - * total number of scalefactor bands encoded - */ - public static final int SBMAX_l = 22; - public static final int SBMAX_s = 13; - public static final int PSFB21 = 6; - public static final int PSFB12 = 6; - - /** - * FFT sizes - */ - public static final int BLKSIZE = 1024; - public static final int HBLKSIZE = (BLKSIZE / 2 + 1); - public static final int BLKSIZE_s = 256; - public static final int HBLKSIZE_s = (BLKSIZE_s / 2 + 1); - - public static final int NORM_TYPE = 0; - public static final int START_TYPE = 1; - public static final int SHORT_TYPE = 2; - public static final int STOP_TYPE = 3; - - /** - * <PRE> - * Mode Extention: - * When we are in stereo mode, there are 4 possible methods to store these - * two channels. The stereo modes -m? are using a subset of them. - * - * -ms: MPG_MD_LR_LR - * -mj: MPG_MD_LR_LR and MPG_MD_MS_LR - * -mf: MPG_MD_MS_LR - * -mi: all - * </PRE> - */ - public static final int MPG_MD_LR_LR = 0; - public static final int MPG_MD_LR_I = 1; - public static final int MPG_MD_MS_LR = 2; - public static final int MPG_MD_MS_I = 3; - - /** - * auto-adjust of ATH, useful for low volume Gabriel Bouvigne 3 feb 2001 - * - * modifies some values in gfp.internal_flags.ATH (gfc.ATH) - */ - private void adjust_ATH(final LameInternalFlags gfc) { - float gr2_max, max_pow; - - if (gfc.ATH.useAdjust == 0) { - gfc.ATH.adjust = 1.0f; - /* no adjustment */ - return; - } - - /* jd - 2001 mar 12, 27, jun 30 */ - /* loudness based on equal loudness curve; */ - /* use granule with maximum combined loudness */ - max_pow = gfc.loudness_sq[0][0]; - gr2_max = gfc.loudness_sq[1][0]; - if (gfc.channels_out == 2) { - max_pow += gfc.loudness_sq[0][1]; - gr2_max += gfc.loudness_sq[1][1]; - } else { - max_pow += max_pow; - gr2_max += gr2_max; - } - if (gfc.mode_gr == 2) { - max_pow = Math.max(max_pow, gr2_max); - } - max_pow *= 0.5; /* max_pow approaches 1.0 for full band noise */ - - /* jd - 2001 mar 31, jun 30 */ - /* user tuning of ATH adjustment region */ - max_pow *= gfc.ATH.aaSensitivityP; - - /* - * adjust ATH depending on range of maximum value - */ - - /* jd - 2001 feb27, mar12,20, jun30, jul22 */ - /* continuous curves based on approximation */ - /* to GB's original values. */ - /* For an increase in approximate loudness, */ - /* set ATH adjust to adjust_limit immediately */ - /* after a delay of one frame. */ - /* For a loudness decrease, reduce ATH adjust */ - /* towards adjust_limit gradually. */ - /* max_pow is a loudness squared or a power. */ - if (max_pow > 0.03125) { /* ((1 - 0.000625)/ 31.98) from curve below */ - if (gfc.ATH.adjust >= 1.0) { - gfc.ATH.adjust = 1.0f; - } else { - /* preceding frame has lower ATH adjust; */ - /* ascend only to the preceding adjust_limit */ - /* in case there is leading low volume */ - if (gfc.ATH.adjust < gfc.ATH.adjustLimit) { - gfc.ATH.adjust = gfc.ATH.adjustLimit; - } - } - gfc.ATH.adjustLimit = 1.0f; - } else { /* adjustment curve */ - /* about 32 dB maximum adjust (0.000625) */ - final float adj_lim_new = 31.98f * max_pow + 0.000625f; - if (gfc.ATH.adjust >= adj_lim_new) { /* descend gradually */ - gfc.ATH.adjust *= adj_lim_new * 0.075 + 0.925; - if (gfc.ATH.adjust < adj_lim_new) { /* stop descent */ - gfc.ATH.adjust = adj_lim_new; - } - } else { /* ascend */ - if (gfc.ATH.adjustLimit >= adj_lim_new) { - gfc.ATH.adjust = adj_lim_new; - } else { - /* preceding frame has lower ATH adjust; */ - /* ascend only to the preceding adjust_limit */ - if (gfc.ATH.adjust < gfc.ATH.adjustLimit) { - gfc.ATH.adjust = gfc.ATH.adjustLimit; - } - } - } - gfc.ATH.adjustLimit = adj_lim_new; - } - } - - /** - * <PRE> - * some simple statistics - * - * bitrate index 0: free bitrate . not allowed in VBR mode - * : bitrates, kbps depending on MPEG version - * bitrate index 15: forbidden - * - * mode_ext: - * 0: LR - * 1: LR-i - * 2: MS - * 3: MS-i - * </PRE> - */ - private void updateStats(final LameInternalFlags gfc) { - int gr, ch; - assert (0 <= gfc.bitrate_index && gfc.bitrate_index < 16); - assert (0 <= gfc.mode_ext && gfc.mode_ext < 4); - - /* count bitrate indices */ - gfc.bitrate_stereoMode_Hist[gfc.bitrate_index][4]++; - gfc.bitrate_stereoMode_Hist[15][4]++; - - /* count 'em for every mode extension in case of 2 channel encoding */ - if (gfc.channels_out == 2) { - gfc.bitrate_stereoMode_Hist[gfc.bitrate_index][gfc.mode_ext]++; - gfc.bitrate_stereoMode_Hist[15][gfc.mode_ext]++; - } - for (gr = 0; gr < gfc.mode_gr; ++gr) { - for (ch = 0; ch < gfc.channels_out; ++ch) { - int bt = gfc.l3_side.tt[gr][ch].block_type; - if (gfc.l3_side.tt[gr][ch].mixed_block_flag != 0) - bt = 4; - gfc.bitrate_blockType_Hist[gfc.bitrate_index][bt]++; - gfc.bitrate_blockType_Hist[gfc.bitrate_index][5]++; - gfc.bitrate_blockType_Hist[15][bt]++; - gfc.bitrate_blockType_Hist[15][5]++; - } - } - } - - private void lame_encode_frame_init(final LameGlobalFlags gfp, - final float inbuf[][]) { - final LameInternalFlags gfc = gfp.internal_flags; - - int ch, gr; - - if (gfc.lame_encode_frame_init == 0) { - /* prime the MDCT/polyphase filterbank with a short block */ - int i, j; - float primebuff0[] = new float[286 + 1152 + 576]; - float primebuff1[] = new float[286 + 1152 + 576]; - gfc.lame_encode_frame_init = 1; - for (i = 0, j = 0; i < 286 + 576 * (1 + gfc.mode_gr); ++i) { - if (i < 576 * gfc.mode_gr) { - primebuff0[i] = 0; - if (gfc.channels_out == 2) - primebuff1[i] = 0; - } else { - primebuff0[i] = inbuf[0][j]; - if (gfc.channels_out == 2) - primebuff1[i] = inbuf[1][j]; - ++j; - } - } - /* polyphase filtering / mdct */ - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - gfc.l3_side.tt[gr][ch].block_type = SHORT_TYPE; - } - } - newMDCT.mdct_sub48(gfc, primebuff0, primebuff1); - - /* check FFT will not use a negative starting offset */ - assert (576 >= FFTOFFSET); - /* check if we have enough data for FFT */ - assert (gfc.mf_size >= (BLKSIZE + gfp.framesize - FFTOFFSET)); - /* check if we have enough data for polyphase filterbank */ - assert (gfc.mf_size >= (512 + gfp.framesize - 32)); - } - - } - - /** - * <PRE> - * encodeframe() Layer 3 - * - * encode a single frame - * - * - * lame_encode_frame() - * - * - * gr 0 gr 1 - * inbuf: |--------------|--------------|--------------| - * - * - * Polyphase (18 windows, each shifted 32) - * gr 0: - * window1 <----512---. - * window18 <----512---. - * - * gr 1: - * window1 <----512---. - * window18 <----512---. - * - * - * - * MDCT output: |--------------|--------------|--------------| - * - * FFT's <---------1024---------. - * <---------1024-------. - * - * - * - * inbuf = buffer of PCM data size=MP3 framesize - * encoder acts on inbuf[ch][0], but output is delayed by MDCTDELAY - * so the MDCT coefficints are from inbuf[ch][-MDCTDELAY] - * - * psy-model FFT has a 1 granule delay, so we feed it data for the - * next granule. - * FFT is centered over granule: 224+576+224 - * So FFT starts at: 576-224-MDCTDELAY - * - * MPEG2: FFT ends at: BLKSIZE+576-224-MDCTDELAY (1328) - * MPEG1: FFT ends at: BLKSIZE+2*576-224-MDCTDELAY (1904) - * - * MPEG2: polyphase first window: [0..511] - * 18th window: [544..1055] (1056) - * MPEG1: 36th window: [1120..1631] (1632) - * data needed: 512+framesize-32 - * - * A close look newmdct.c shows that the polyphase filterbank - * only uses data from [0..510] for each window. Perhaps because the window - * used by the filterbank is zero for the last point, so Takehiro's - * code doesn't bother to compute with it. - * - * FFT starts at 576-224-MDCTDELAY (304) = 576-FFTOFFSET - * - * </PRE> - */ - - private static final float fircoef[] = { -0.0207887f * 5, -0.0378413f * 5, - -0.0432472f * 5, -0.031183f * 5, 7.79609e-18f * 5, 0.0467745f * 5, - 0.10091f * 5, 0.151365f * 5, 0.187098f * 5 }; - - public final int lame_encode_mp3_frame(final LameGlobalFlags gfp, - final float[] inbuf_l, final float[] inbuf_r, byte[] mp3buf, - int mp3bufPos, int mp3buf_size) { - int mp3count; - III_psy_ratio masking_LR[][] = new III_psy_ratio[2][2]; /* - * LR masking & - * energy - */ - masking_LR[0][0] = new III_psy_ratio(); - masking_LR[0][1] = new III_psy_ratio(); - masking_LR[1][0] = new III_psy_ratio(); - masking_LR[1][1] = new III_psy_ratio(); - III_psy_ratio masking_MS[][] = new III_psy_ratio[2][2]; - /* MS masking & energy */ - masking_MS[0][0] = new III_psy_ratio(); - masking_MS[0][1] = new III_psy_ratio(); - masking_MS[1][0] = new III_psy_ratio(); - masking_MS[1][1] = new III_psy_ratio(); - III_psy_ratio masking[][]; - /* pointer to selected maskings */ - final float[] inbuf[] = new float[2][]; - final LameInternalFlags gfc = gfp.internal_flags; - - float tot_ener[][] = new float[2][4]; - float ms_ener_ratio[] = { .5f, .5f }; - float[][] pe = { { 0.f, 0.f }, { 0.f, 0.f } }, pe_MS = { { 0.f, 0.f }, - { 0.f, 0.f } }; - float[][] pe_use; - - int ch, gr; - - inbuf[0] = inbuf_l; - inbuf[1] = inbuf_r; - - if (gfc.lame_encode_frame_init == 0) { - /* first run? */ - lame_encode_frame_init(gfp, inbuf); - - } - - /********************** padding *****************************/ - /** - * <PRE> - * padding method as described in - * "MPEG-Layer3 / Bitstream Syntax and Decoding" - * by Martin Sieler, Ralph Sperschneider - * - * note: there is no padding for the very first frame - * - * Robert Hegemann 2000-06-22 - * </PRE> - */ - gfc.padding = 0; - if ((gfc.slot_lag -= gfc.frac_SpF) < 0) { - gfc.slot_lag += gfp.out_samplerate; - gfc.padding = 1; - } - - /**************************************** - * Stage 1: psychoacoustic model * - ****************************************/ - - if (gfc.psymodel != 0) { - /* - * psychoacoustic model psy model has a 1 granule (576) delay that - * we must compensate for (mt 6/99). - */ - int ret; - final float bufp[][] = new float[2][]; - /* address of beginning of left & right granule */ - int bufpPos = 0; - /* address of beginning of left & right granule */ - int blocktype[] = new int[2]; - - for (gr = 0; gr < gfc.mode_gr; gr++) { - - for (ch = 0; ch < gfc.channels_out; ch++) { - bufp[ch] = inbuf[ch]; - bufpPos = 576 + gr * 576 - FFTOFFSET; - } - if (gfp.VBR == VbrMode.vbr_mtrh || gfp.VBR == VbrMode.vbr_mt) { - ret = psy.L3psycho_anal_vbr(gfp, bufp, bufpPos, gr, - masking_LR, masking_MS, pe[gr], pe_MS[gr], - tot_ener[gr], blocktype); - } else { - ret = psy.L3psycho_anal_ns(gfp, bufp, bufpPos, gr, - masking_LR, masking_MS, pe[gr], pe_MS[gr], - tot_ener[gr], blocktype); - } - if (ret != 0) - return -4; - - if (gfp.mode == MPEGMode.JOINT_STEREO) { - ms_ener_ratio[gr] = tot_ener[gr][2] + tot_ener[gr][3]; - if (ms_ener_ratio[gr] > 0) - ms_ener_ratio[gr] = tot_ener[gr][3] / ms_ener_ratio[gr]; - } - - /* block type flags */ - for (ch = 0; ch < gfc.channels_out; ch++) { - final GrInfo cod_info = gfc.l3_side.tt[gr][ch]; - cod_info.block_type = blocktype[ch]; - cod_info.mixed_block_flag = 0; - } - } - } else { - /* no psy model */ - for (gr = 0; gr < gfc.mode_gr; gr++) - for (ch = 0; ch < gfc.channels_out; ch++) { - gfc.l3_side.tt[gr][ch].block_type = NORM_TYPE; - gfc.l3_side.tt[gr][ch].mixed_block_flag = 0; - pe_MS[gr][ch] = pe[gr][ch] = 700; - } - } - - /* auto-adjust of ATH, useful for low volume */ - adjust_ATH(gfc); - - /**************************************** - * Stage 2: MDCT * - ****************************************/ - - /* polyphase filtering / mdct */ - newMDCT.mdct_sub48(gfc, inbuf[0], inbuf[1]); - - /**************************************** - * Stage 3: MS/LR decision * - ****************************************/ - - /* Here will be selected MS or LR coding of the 2 stereo channels */ - gfc.mode_ext = MPG_MD_LR_LR; - - if (gfp.force_ms) { - gfc.mode_ext = MPG_MD_MS_LR; - } else if (gfp.mode == MPEGMode.JOINT_STEREO) { - /* - * ms_ratio = is scaled, for historical reasons, to look like a - * ratio of side_channel / total. 0 = signal is 100% mono .5 = L & R - * uncorrelated - */ - - /** - * <PRE> - * [0] and [1] are the results for the two granules in MPEG-1, - * in MPEG-2 it's only a faked averaging of the same value - * _prev is the value of the last granule of the previous frame - * _next is the value of the first granule of the next frame - * </PRE> - */ - - float sum_pe_MS = 0; - float sum_pe_LR = 0; - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - sum_pe_MS += pe_MS[gr][ch]; - sum_pe_LR += pe[gr][ch]; - } - } - - /* based on PE: M/S coding would not use much more bits than L/R */ - if (sum_pe_MS <= 1.00 * sum_pe_LR) { - - final GrInfo gi0[] = gfc.l3_side.tt[0]; - final GrInfo gi1[] = gfc.l3_side.tt[gfc.mode_gr - 1]; - - if (gi0[0].block_type == gi0[1].block_type - && gi1[0].block_type == gi1[1].block_type) { - - gfc.mode_ext = MPG_MD_MS_LR; - } - } - } - - /* bit and noise allocation */ - if (gfc.mode_ext == MPG_MD_MS_LR) { - masking = masking_MS; /* use MS masking */ - pe_use = pe_MS; - } else { - masking = masking_LR; /* use LR masking */ - pe_use = pe; - } - - /* copy data for MP3 frame analyzer */ - if (gfp.analysis && gfc.pinfo != null) { - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - gfc.pinfo.ms_ratio[gr] = gfc.ms_ratio[gr]; - gfc.pinfo.ms_ener_ratio[gr] = ms_ener_ratio[gr]; - gfc.pinfo.blocktype[gr][ch] = gfc.l3_side.tt[gr][ch].block_type; - gfc.pinfo.pe[gr][ch] = pe_use[gr][ch]; - System.arraycopy(gfc.l3_side.tt[gr][ch].xr, 0, - gfc.pinfo.xr[gr][ch], 0, 576); - /* - * in psymodel, LR and MS data was stored in pinfo. switch - * to MS data: - */ - if (gfc.mode_ext == MPG_MD_MS_LR) { - gfc.pinfo.ers[gr][ch] = gfc.pinfo.ers[gr][ch + 2]; - System.arraycopy(gfc.pinfo.energy[gr][ch + 2], 0, - gfc.pinfo.energy[gr][ch], 0, - gfc.pinfo.energy[gr][ch].length); - } - } - } - } - - /**************************************** - * Stage 4: quantization loop * - ****************************************/ - - if (gfp.VBR == VbrMode.vbr_off || gfp.VBR == VbrMode.vbr_abr) { - - int i; - float f; - - for (i = 0; i < 18; i++) - gfc.nsPsy.pefirbuf[i] = gfc.nsPsy.pefirbuf[i + 1]; - - f = 0.0f; - for (gr = 0; gr < gfc.mode_gr; gr++) - for (ch = 0; ch < gfc.channels_out; ch++) - f += pe_use[gr][ch]; - gfc.nsPsy.pefirbuf[18] = f; - - f = gfc.nsPsy.pefirbuf[9]; - for (i = 0; i < 9; i++) - f += (gfc.nsPsy.pefirbuf[i] + gfc.nsPsy.pefirbuf[18 - i]) - * fircoef[i]; - - f = (670 * 5 * gfc.mode_gr * gfc.channels_out) / f; - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - pe_use[gr][ch] *= f; - } - } - } - gfc.iteration_loop.iteration_loop(gfp, pe_use, ms_ener_ratio, masking); - - /**************************************** - * Stage 5: bitstream formatting * - ****************************************/ - - /* write the frame to the bitstream */ - bs.format_bitstream(gfp); - - /* copy mp3 bit buffer into array */ - mp3count = bs.copy_buffer(gfc, mp3buf, mp3bufPos, mp3buf_size, 1); - - if (gfp.bWriteVbrTag) - vbr.addVbrFrame(gfp); - - if (gfp.analysis && gfc.pinfo != null) { - for (ch = 0; ch < gfc.channels_out; ch++) { - int j; - for (j = 0; j < FFTOFFSET; j++) - gfc.pinfo.pcmdata[ch][j] = gfc.pinfo.pcmdata[ch][j - + gfp.framesize]; - for (j = FFTOFFSET; j < 1600; j++) { - gfc.pinfo.pcmdata[ch][j] = inbuf[ch][j - FFTOFFSET]; - } - } - qupvt.set_frame_pinfo(gfp, masking); - } - - updateStats(gfc); - - return mp3count; - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/FFT.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/FFT.java deleted file mode 100644 index e06a1f794..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/FFT.java +++ /dev/null @@ -1,267 +0,0 @@ -/* -** FFT and FHT routines -** Copyright 1988, 1993; Ron Mayer -** Copyright (c) 1999-2000 Takehiro Tominaga -** -** fht(fz,n); -** Does a hartley transform of "n" points in the array "fz". -** -** NOTE: This routine uses at least 2 patented algorithms, and may be -** under the restrictions of a bunch of different organizations. -** Although I wrote it completely myself; it is kind of a derivative -** of a routine I once authored and released under the GPL, so it -** may fall under the free software foundation's restrictions; -** it was worked on as a Stanford Univ project, so they claim -** some rights to it; it was further optimized at work here, so -** I think this company claims parts of it. The patents are -** held by R. Bracewell (the FHT algorithm) and O. Buneman (the -** trig generator), both at Stanford Univ. -** If it were up to me, I'd say go do whatever you want with it; -** but it would be polite to give credit to the following people -** if you use this anywhere: -** Euler - probable inventor of the fourier transform. -** Gauss - probable inventor of the FFT. -** Hartley - probable inventor of the hartley transform. -** Buneman - for a really cool trig generator -** Mayer(me) - for authoring this particular version and -** including all the optimizations in one package. -** Thanks, -** Ron Mayer; mayer@acuson.com -** and added some optimization by -** Mather - idea of using lookup table -** Takehiro - some dirty hack for speed up -*/ -package mp3; - - -public class FFT { - - private static float window[] = new float[Encoder.BLKSIZE], - window_s[] = new float[Encoder.BLKSIZE_s / 2]; - - private static final float costab[] = { - 9.238795325112867e-01f, 3.826834323650898e-01f, - 9.951847266721969e-01f, 9.801714032956060e-02f, - 9.996988186962042e-01f, 2.454122852291229e-02f, - 9.999811752826011e-01f, 6.135884649154475e-03f - }; - - private void fht(final float[] fz, final int fzPos, int n) { - int tri = 0; - int k4; - int fi; - int gi; - final int fn; - - n <<= 1; /* to get BLKSIZE, because of 3DNow! ASM routine */ - fn = fzPos + n; - k4 = 4; - do { - float s1, c1; - int i, k1, k2, k3, kx; - kx = k4 >> 1; - k1 = k4; - k2 = k4 << 1; - k3 = k2 + k1; - k4 = k2 << 1; - fi = fzPos; - gi = fi + kx; - do { - float f0, f1, f2, f3; - f1 = fz[fi + 0] - fz[fi + k1]; - f0 = fz[fi + 0] + fz[fi + k1]; - f3 = fz[fi + k2] - fz[fi + k3]; - f2 = fz[fi + k2] + fz[fi + k3]; - fz[fi + k2] = f0 - f2; - fz[fi + 0] = f0 + f2; - fz[fi + k3] = f1 - f3; - fz[fi + k1] = f1 + f3; - f1 = fz[gi + 0] - fz[gi + k1]; - f0 = fz[gi + 0] + fz[gi + k1]; - f3 = (float) (Util.SQRT2 * fz[gi + k3]); - f2 = (float) (Util.SQRT2 * fz[gi + k2]); - fz[gi + k2] = f0 - f2; - fz[gi + 0] = f0 + f2; - fz[gi + k3] = f1 - f3; - fz[gi + k1] = f1 + f3; - gi += k4; - fi += k4; - } while (fi < fn); - c1 = costab[tri + 0]; - s1 = costab[tri + 1]; - for (i = 1; i < kx; i++) { - float c2, s2; - c2 = 1 - (2 * s1) * s1; - s2 = (2 * s1) * c1; - fi = fzPos + i; - gi = fzPos + k1 - i; - do { - float a, b, g0, f0, f1, g1, f2, g2, f3, g3; - b = s2 * fz[fi + k1] - c2 * fz[gi + k1]; - a = c2 * fz[fi + k1] + s2 * fz[gi + k1]; - f1 = fz[fi + 0] - a; - f0 = fz[fi + 0] + a; - g1 = fz[gi + 0] - b; - g0 = fz[gi + 0] + b; - b = s2 * fz[fi + k3] - c2 * fz[gi + k3]; - a = c2 * fz[fi + k3] + s2 * fz[gi + k3]; - f3 = fz[fi + k2] - a; - f2 = fz[fi + k2] + a; - g3 = fz[gi + k2] - b; - g2 = fz[gi + k2] + b; - b = s1 * f2 - c1 * g3; - a = c1 * f2 + s1 * g3; - fz[fi + k2] = f0 - a; - fz[fi + 0] = f0 + a; - fz[gi + k3] = g1 - b; - fz[gi + k1] = g1 + b; - b = c1 * g2 - s1 * f3; - a = s1 * g2 + c1 * f3; - fz[gi + k2] = g0 - a; - fz[gi + 0] = g0 + a; - fz[fi + k3] = f1 - b; - fz[fi + k1] = f1 + b; - gi += k4; - fi += k4; - } while (fi < fn); - c2 = c1; - c1 = c2 * costab[tri + 0] - s1 * costab[tri + 1]; - s1 = c2 * costab[tri + 1] + s1 * costab[tri + 0]; - } - tri += 2; - } while (k4 < n); - } - - private static final byte rv_tbl[] = { 0x00, (byte) 0x80, 0x40, - (byte) 0xc0, 0x20, (byte) 0xa0, 0x60, (byte) 0xe0, 0x10, - (byte) 0x90, 0x50, (byte) 0xd0, 0x30, (byte) 0xb0, 0x70, - (byte) 0xf0, 0x08, (byte) 0x88, 0x48, (byte) 0xc8, 0x28, - (byte) 0xa8, 0x68, (byte) 0xe8, 0x18, (byte) 0x98, 0x58, - (byte) 0xd8, 0x38, (byte) 0xb8, 0x78, (byte) 0xf8, 0x04, - (byte) 0x84, 0x44, (byte) 0xc4, 0x24, (byte) 0xa4, 0x64, - (byte) 0xe4, 0x14, (byte) 0x94, 0x54, (byte) 0xd4, 0x34, - (byte) 0xb4, 0x74, (byte) 0xf4, 0x0c, (byte) 0x8c, 0x4c, - (byte) 0xcc, 0x2c, (byte) 0xac, 0x6c, (byte) 0xec, 0x1c, - (byte) 0x9c, 0x5c, (byte) 0xdc, 0x3c, (byte) 0xbc, 0x7c, - (byte) 0xfc, 0x02, (byte) 0x82, 0x42, (byte) 0xc2, 0x22, - (byte) 0xa2, 0x62, (byte) 0xe2, 0x12, (byte) 0x92, 0x52, - (byte) 0xd2, 0x32, (byte) 0xb2, 0x72, (byte) 0xf2, 0x0a, - (byte) 0x8a, 0x4a, (byte) 0xca, 0x2a, (byte) 0xaa, 0x6a, - (byte) 0xea, 0x1a, (byte) 0x9a, 0x5a, (byte) 0xda, 0x3a, - (byte) 0xba, 0x7a, (byte) 0xfa, 0x06, (byte) 0x86, 0x46, - (byte) 0xc6, 0x26, (byte) 0xa6, 0x66, (byte) 0xe6, 0x16, - (byte) 0x96, 0x56, (byte) 0xd6, 0x36, (byte) 0xb6, 0x76, - (byte) 0xf6, 0x0e, (byte) 0x8e, 0x4e, (byte) 0xce, 0x2e, - (byte) 0xae, 0x6e, (byte) 0xee, 0x1e, (byte) 0x9e, 0x5e, - (byte) 0xde, 0x3e, (byte) 0xbe, 0x7e, (byte) 0xfe }; - - public final void fft_short(final LameInternalFlags gfc, - final float x_real[][], final int chn, final float[] buffer[], - final int bufPos) { - for (int b = 0; b < 3; b++) { - int x = Encoder.BLKSIZE_s / 2; - final short k = (short) ((576 / 3) * (b + 1)); - int j = Encoder.BLKSIZE_s / 8 - 1; - do { - float f0, f1, f2, f3, w; - - int i = rv_tbl[j << 2] & 0xff; - - f0 = window_s[i] * buffer[chn][bufPos + i + k]; - w = window_s[0x7f - i] * buffer[chn][bufPos + i + k + 0x80]; - f1 = f0 - w; - f0 = f0 + w; - f2 = window_s[i + 0x40] * buffer[chn][bufPos + i + k + 0x40]; - w = window_s[0x3f - i] * buffer[chn][bufPos + i + k + 0xc0]; - f3 = f2 - w; - f2 = f2 + w; - - x -= 4; - x_real[b][x + 0] = f0 + f2; - x_real[b][x + 2] = f0 - f2; - x_real[b][x + 1] = f1 + f3; - x_real[b][x + 3] = f1 - f3; - - f0 = window_s[i + 0x01] * buffer[chn][bufPos + i + k + 0x01]; - w = window_s[0x7e - i] * buffer[chn][bufPos + i + k + 0x81]; - f1 = f0 - w; - f0 = f0 + w; - f2 = window_s[i + 0x41] * buffer[chn][bufPos + i + k + 0x41]; - w = window_s[0x3e - i] * buffer[chn][bufPos + i + k + 0xc1]; - f3 = f2 - w; - f2 = f2 + w; - - x_real[b][x + Encoder.BLKSIZE_s / 2 + 0] = f0 + f2; - x_real[b][x + Encoder.BLKSIZE_s / 2 + 2] = f0 - f2; - x_real[b][x + Encoder.BLKSIZE_s / 2 + 1] = f1 + f3; - x_real[b][x + Encoder.BLKSIZE_s / 2 + 3] = f1 - f3; - } while (--j >= 0); - - fht(x_real[b], x, Encoder.BLKSIZE_s / 2); - /* BLKSIZE_s/2 because of 3DNow! ASM routine */ - /* BLKSIZE/2 because of 3DNow! ASM routine */ - } - } - - public final void fft_long(final LameInternalFlags gfc, float y[], int chn, - final float[] buffer[], int bufPos) { - int jj = Encoder.BLKSIZE / 8 - 1; - int x = Encoder.BLKSIZE / 2; - - do { - float f0, f1, f2, f3, w; - - int i = rv_tbl[jj] & 0xff; - f0 = window[i] * buffer[chn][bufPos + i]; - w = window[i + 0x200] * buffer[chn][bufPos + i + 0x200]; - f1 = f0 - w; - f0 = f0 + w; - f2 = window[i + 0x100] * buffer[chn][bufPos + i + 0x100]; - w = window[i + 0x300] * buffer[chn][bufPos + i + 0x300]; - f3 = f2 - w; - f2 = f2 + w; - - x -= 4; - y[x + 0] = f0 + f2; - y[x + 2] = f0 - f2; - y[x + 1] = f1 + f3; - y[x + 3] = f1 - f3; - - f0 = window[i + 0x001] * buffer[chn][bufPos + i + 0x001]; - w = window[i + 0x201] * buffer[chn][bufPos + i + 0x201]; - f1 = f0 - w; - f0 = f0 + w; - f2 = window[i + 0x101] * buffer[chn][bufPos + i + 0x101]; - w = window[i + 0x301] * buffer[chn][bufPos + i + 0x301]; - f3 = f2 - w; - f2 = f2 + w; - - y[x + Encoder.BLKSIZE / 2 + 0] = f0 + f2; - y[x + Encoder.BLKSIZE / 2 + 2] = f0 - f2; - y[x + Encoder.BLKSIZE / 2 + 1] = f1 + f3; - y[x + Encoder.BLKSIZE / 2 + 3] = f1 - f3; - } while (--jj >= 0); - - fht(y, x, Encoder.BLKSIZE / 2); - /* BLKSIZE/2 because of 3DNow! ASM routine */ - } - - public final void init_fft(final LameInternalFlags gfc) { - /* The type of window used here will make no real difference, but */ - /* - * in the interest of merging nspsytune stuff - switch to blackman - * window - */ - for (int i = 0; i < Encoder.BLKSIZE; i++) - /* blackman window */ - window[i] = (float) (0.42 - 0.5 * Math.cos(2 * Math.PI * (i + .5) - / Encoder.BLKSIZE) + 0.08 * Math.cos(4 * Math.PI * (i + .5) - / Encoder.BLKSIZE)); - - for (int i = 0; i < Encoder.BLKSIZE_s / 2; i++) - window_s[i] = (float) (0.5 * (1.0 - Math.cos(2.0 * Math.PI - * (i + 0.5) / Encoder.BLKSIZE_s))); - - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/FrameDataNode.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/FrameDataNode.java deleted file mode 100644 index 3512f51c5..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/FrameDataNode.java +++ /dev/null @@ -1,15 +0,0 @@ -package mp3; - -public final class FrameDataNode { - FrameDataNode nxt; - /** - * Frame Identifier - */ - int fid; - /** - * 3-character language descriptor - */ - String lng; - - Inf dsc = new Inf(), txt = new Inf(); -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/GainAnalysis.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/GainAnalysis.java deleted file mode 100644 index 48111e362..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/GainAnalysis.java +++ /dev/null @@ -1,533 +0,0 @@ -/* - * ReplayGainAnalysis - analyzes input samples and give the recommended dB change - * Copyright (C) 2001 David Robinson and Glen Sawyer - * Improvements and optimizations added by Frank Klemm, and by Marcel Muller - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * concept and filter values by David Robinson (David@Robinson.org) - * -- blame him if you think the idea is flawed - * original coding by Glen Sawyer (mp3gain@hotmail.com) - * -- blame him if you think this runs too slowly, or the coding is otherwise flawed - * - * lots of code improvements by Frank Klemm ( http://www.uni-jena.de/~pfk/mpp/ ) - * -- credit him for all the _good_ programming ;) - * - * - * For an explanation of the concepts and the basic algorithms involved, go to: - * http://www.replaygain.org/ - */ - -/* - * Here's the deal. Call - * - * InitGainAnalysis ( long samplefreq ); - * - * to initialize everything. Call - * - * AnalyzeSamples ( const Float_t* left_samples, - * const Float_t* right_samples, - * size_t num_samples, - * int num_channels ); - * - * as many times as you want, with as many or as few samples as you want. - * If mono, pass the sample buffer in through left_samples, leave - * right_samples NULL, and make sure num_channels = 1. - * - * GetTitleGain() - * - * will return the recommended dB level change for all samples analyzed - * SINCE THE LAST TIME you called GetTitleGain() OR InitGainAnalysis(). - * - * GetAlbumGain() - * - * will return the recommended dB level change for all samples analyzed - * since InitGainAnalysis() was called and finalized with GetTitleGain(). - * - * Pseudo-code to process an album: - * - * Float_t l_samples [4096]; - * Float_t r_samples [4096]; - * size_t num_samples; - * unsigned int num_songs; - * unsigned int i; - * - * InitGainAnalysis ( 44100 ); - * for ( i = 1; i <= num_songs; i++ ) { - * while ( ( num_samples = getSongSamples ( song[i], left_samples, right_samples ) ) > 0 ) - * AnalyzeSamples ( left_samples, right_samples, num_samples, 2 ); - * fprintf ("Recommended dB change for song %2d: %+6.2f dB\n", i, GetTitleGain() ); - * } - * fprintf ("Recommended dB change for whole album: %+6.2f dB\n", GetAlbumGain() ); - */ - -/* - * So here's the main source of potential code confusion: - * - * The filters applied to the incoming samples are IIR filters, - * meaning they rely on up to <filter order> number of previous samples - * AND up to <filter order> number of previous filtered samples. - * - * I set up the AnalyzeSamples routine to minimize memory usage and interface - * complexity. The speed isn't compromised too much (I don't think), but the - * internal complexity is higher than it should be for such a relatively - * simple routine. - * - * Optimization/clarity suggestions are welcome. - */ -package mp3; - -import java.util.Arrays; - -public class GainAnalysis { - /** - * calibration value for 89dB - */ - private static final float PINK_REF = 64.82f; - - private static final int YULE_ORDER = 10; - /** - * percentile which is louder than the proposed level - */ - private static final float RMS_PERCENTILE = 0.95f; - /** - * maximum allowed sample frequency [Hz] - */ - private static final int MAX_SAMP_FREQ = 48000; - private static final int RMS_WINDOW_TIME_NUMERATOR = 1; - /** - * numerator / denominator = time slice size [s] - */ - private static final int RMS_WINDOW_TIME_DENOMINATOR = 20; - /** - * Table entries per dB - */ - static final float STEPS_per_dB = 100.f; - /** - * Table entries for 0...MAX_dB (normal max. values are 70...80 dB) - */ - static final float MAX_dB = 120.f; - - public static final int GAIN_NOT_ENOUGH_SAMPLES = -24601; - public static final int GAIN_ANALYSIS_ERROR = 0; - public static final int GAIN_ANALYSIS_OK = 1; - public static final int INIT_GAIN_ANALYSIS_ERROR = 0; - public static final int INIT_GAIN_ANALYSIS_OK = 1; - - static final int MAX_ORDER = YULE_ORDER; - /** - * max. Samples per Time slice - */ - static final int MAX_SAMPLES_PER_WINDOW = ((MAX_SAMP_FREQ * RMS_WINDOW_TIME_NUMERATOR) - / RMS_WINDOW_TIME_DENOMINATOR + 1); - - private static final float ABYule[][] = { - { 0.03857599435200f, -3.84664617118067f, -0.02160367184185f, - 7.81501653005538f, -0.00123395316851f, -11.34170355132042f, - -0.00009291677959f, 13.05504219327545f, -0.01655260341619f, - -12.28759895145294f, 0.02161526843274f, 9.48293806319790f, - -0.02074045215285f, -5.87257861775999f, 0.00594298065125f, - 2.75465861874613f, 0.00306428023191f, -0.86984376593551f, - 0.00012025322027f, 0.13919314567432f, 0.00288463683916f }, - { 0.05418656406430f, -3.47845948550071f, -0.02911007808948f, - 6.36317777566148f, -0.00848709379851f, -8.54751527471874f, - -0.00851165645469f, 9.47693607801280f, -0.00834990904936f, - -8.81498681370155f, 0.02245293253339f, 6.85401540936998f, - -0.02596338512915f, -4.39470996079559f, 0.01624864962975f, - 2.19611684890774f, -0.00240879051584f, -0.75104302451432f, - 0.00674613682247f, 0.13149317958808f, -0.00187763777362f }, - { 0.15457299681924f, -2.37898834973084f, -0.09331049056315f, - 2.84868151156327f, -0.06247880153653f, -2.64577170229825f, - 0.02163541888798f, 2.23697657451713f, -0.05588393329856f, - -1.67148153367602f, 0.04781476674921f, 1.00595954808547f, - 0.00222312597743f, -0.45953458054983f, 0.03174092540049f, - 0.16378164858596f, -0.01390589421898f, -0.05032077717131f, - 0.00651420667831f, 0.02347897407020f, -0.00881362733839f }, - { 0.30296907319327f, -1.61273165137247f, -0.22613988682123f, - 1.07977492259970f, -0.08587323730772f, -0.25656257754070f, - 0.03282930172664f, -0.16276719120440f, -0.00915702933434f, - -0.22638893773906f, -0.02364141202522f, 0.39120800788284f, - -0.00584456039913f, -0.22138138954925f, 0.06276101321749f, - 0.04500235387352f, -0.00000828086748f, 0.02005851806501f, - 0.00205861885564f, 0.00302439095741f, -0.02950134983287f }, - { 0.33642304856132f, -1.49858979367799f, -0.25572241425570f, - 0.87350271418188f, -0.11828570177555f, 0.12205022308084f, - 0.11921148675203f, -0.80774944671438f, -0.07834489609479f, - 0.47854794562326f, -0.00469977914380f, -0.12453458140019f, - -0.00589500224440f, -0.04067510197014f, 0.05724228140351f, - 0.08333755284107f, 0.00832043980773f, -0.04237348025746f, - -0.01635381384540f, 0.02977207319925f, -0.01760176568150f }, - { 0.44915256608450f, -0.62820619233671f, -0.14351757464547f, - 0.29661783706366f, -0.22784394429749f, -0.37256372942400f, - -0.01419140100551f, 0.00213767857124f, 0.04078262797139f, - -0.42029820170918f, -0.12398163381748f, 0.22199650564824f, - 0.04097565135648f, 0.00613424350682f, 0.10478503600251f, - 0.06747620744683f, -0.01863887810927f, 0.05784820375801f, - -0.03193428438915f, 0.03222754072173f, 0.00541907748707f }, - { 0.56619470757641f, -1.04800335126349f, -0.75464456939302f, - 0.29156311971249f, 0.16242137742230f, -0.26806001042947f, - 0.16744243493672f, 0.00819999645858f, -0.18901604199609f, - 0.45054734505008f, 0.30931782841830f, -0.33032403314006f, - -0.27562961986224f, 0.06739368333110f, 0.00647310677246f, - -0.04784254229033f, 0.08647503780351f, 0.01639907836189f, - -0.03788984554840f, 0.01807364323573f, -0.00588215443421f }, - { 0.58100494960553f, -0.51035327095184f, -0.53174909058578f, - -0.31863563325245f, -0.14289799034253f, -0.20256413484477f, - 0.17520704835522f, 0.14728154134330f, 0.02377945217615f, - 0.38952639978999f, 0.15558449135573f, -0.23313271880868f, - -0.25344790059353f, -0.05246019024463f, 0.01628462406333f, - -0.02505961724053f, 0.06920467763959f, 0.02442357316099f, - -0.03721611395801f, 0.01818801111503f, -0.00749618797172f }, - { 0.53648789255105f, -0.25049871956020f, -0.42163034350696f, - -0.43193942311114f, -0.00275953611929f, -0.03424681017675f, - 0.04267842219415f, -0.04678328784242f, -0.10214864179676f, - 0.26408300200955f, 0.14590772289388f, 0.15113130533216f, - -0.02459864859345f, -0.17556493366449f, -0.11202315195388f, - -0.18823009262115f, -0.04060034127000f, 0.05477720428674f, - 0.04788665548180f, 0.04704409688120f, -0.02217936801134f } }; - - private static final float ABButter[][] = { - { 0.98621192462708f, -1.97223372919527f, -1.97242384925416f, - 0.97261396931306f, 0.98621192462708f }, - { 0.98500175787242f, -1.96977855582618f, -1.97000351574484f, - 0.97022847566350f, 0.98500175787242f }, - { 0.97938932735214f, -1.95835380975398f, -1.95877865470428f, - 0.95920349965459f, 0.97938932735214f }, - { 0.97531843204928f, -1.95002759149878f, -1.95063686409857f, - 0.95124613669835f, 0.97531843204928f }, - { 0.97316523498161f, -1.94561023566527f, -1.94633046996323f, - 0.94705070426118f, 0.97316523498161f }, - { 0.96454515552826f, -1.92783286977036f, -1.92909031105652f, - 0.93034775234268f, 0.96454515552826f }, - { 0.96009142950541f, -1.91858953033784f, -1.92018285901082f, - 0.92177618768381f, 0.96009142950541f }, - { 0.95856916599601f, -1.91542108074780f, -1.91713833199203f, - 0.91885558323625f, 0.95856916599601f }, - { 0.94597685600279f, -1.88903307939452f, -1.89195371200558f, - 0.89487434461664f, 0.94597685600279f } }; - - - /** - * When calling this procedure, make sure that ip[-order] and op[-order] - * point to real data - */ - private void filterYule(final float[] input, int inputPos, float[] output, - int outputPos, int nSamples, final float[] kernel) { - - while ((nSamples--) != 0) { - /* 1e-10 is a hack to avoid slowdown because of denormals */ - output[outputPos] = 1e-10f + input[inputPos + 0] * kernel[0] - - output[outputPos - 1] * kernel[1] + input[inputPos - 1] - * kernel[2] - output[outputPos - 2] * kernel[3] - + input[inputPos - 2] * kernel[4] - output[outputPos - 3] - * kernel[5] + input[inputPos - 3] * kernel[6] - - output[outputPos - 4] * kernel[7] + input[inputPos - 4] - * kernel[8] - output[outputPos - 5] * kernel[9] - + input[inputPos - 5] * kernel[10] - output[outputPos - 6] - * kernel[11] + input[inputPos - 6] * kernel[12] - - output[outputPos - 7] * kernel[13] + input[inputPos - 7] - * kernel[14] - output[outputPos - 8] * kernel[15] - + input[inputPos - 8] * kernel[16] - output[outputPos - 9] - * kernel[17] + input[inputPos - 9] * kernel[18] - - output[outputPos - 10] * kernel[19] - + input[inputPos - 10] * kernel[20]; - ++outputPos; - ++inputPos; - } - } - - private void filterButter(final float[] input, int inputPos, - float[] output, int outputPos, int nSamples, final float[] kernel) { - - while ((nSamples--) != 0) { - output[outputPos] = input[inputPos + 0] * kernel[0] - - output[outputPos - 1] * kernel[1] + input[inputPos - 1] - * kernel[2] - output[outputPos - 2] * kernel[3] - + input[inputPos - 2] * kernel[4]; - ++outputPos; - ++inputPos; - } - } - - /** - * @return INIT_GAIN_ANALYSIS_OK if successful, INIT_GAIN_ANALYSIS_ERROR if - * not - */ - private int ResetSampleFrequency(final ReplayGain rgData, - final long samplefreq) { - /* zero out initial values */ - for (int i = 0; i < MAX_ORDER; i++) - rgData.linprebuf[i] = rgData.lstepbuf[i] = rgData.loutbuf[i] = rgData.rinprebuf[i] = rgData.rstepbuf[i] = rgData.routbuf[i] = 0.f; - - switch ((int) (samplefreq)) { - case 48000: - rgData.freqindex = 0; - break; - case 44100: - rgData.freqindex = 1; - break; - case 32000: - rgData.freqindex = 2; - break; - case 24000: - rgData.freqindex = 3; - break; - case 22050: - rgData.freqindex = 4; - break; - case 16000: - rgData.freqindex = 5; - break; - case 12000: - rgData.freqindex = 6; - break; - case 11025: - rgData.freqindex = 7; - break; - case 8000: - rgData.freqindex = 8; - break; - default: - return INIT_GAIN_ANALYSIS_ERROR; - } - - rgData.sampleWindow = (int) ((samplefreq * RMS_WINDOW_TIME_NUMERATOR - + RMS_WINDOW_TIME_DENOMINATOR - 1) / RMS_WINDOW_TIME_DENOMINATOR); - - rgData.lsum = 0.; - rgData.rsum = 0.; - rgData.totsamp = 0; - - Arrays.fill(rgData.A, 0); - - return INIT_GAIN_ANALYSIS_OK; - } - - public final int InitGainAnalysis(final ReplayGain rgData, - final long samplefreq) { - if (ResetSampleFrequency(rgData, samplefreq) != INIT_GAIN_ANALYSIS_OK) { - return INIT_GAIN_ANALYSIS_ERROR; - } - - rgData.linpre = MAX_ORDER; - rgData.rinpre = MAX_ORDER; - rgData.lstep = MAX_ORDER; - rgData.rstep = MAX_ORDER; - rgData.lout = MAX_ORDER; - rgData.rout = MAX_ORDER; - - Arrays.fill(rgData.B, 0); - - return INIT_GAIN_ANALYSIS_OK; - } - - /** - * square - */ - private double fsqr(final double d) { - return d * d; - } - - public final int AnalyzeSamples(final ReplayGain rgData, - final float[] left_samples, final int left_samplesPos, - float[] right_samples, int right_samplesPos, final int num_samples, - final int num_channels) { - int curleft; - float[] curleftBase; - int curright; - float[] currightBase; - int batchsamples; - int cursamples; - int cursamplepos; - - if (num_samples == 0) - return GAIN_ANALYSIS_OK; - - cursamplepos = 0; - batchsamples = num_samples; - - switch (num_channels) { - case 1: - right_samples = left_samples; - right_samplesPos = left_samplesPos; - break; - case 2: - break; - default: - return GAIN_ANALYSIS_ERROR; - } - - if (num_samples < MAX_ORDER) { - System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf, - MAX_ORDER, num_samples); - System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf, - MAX_ORDER, num_samples); - } else { - System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf, - MAX_ORDER, MAX_ORDER); - System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf, - MAX_ORDER, MAX_ORDER); - } - - while (batchsamples > 0) { - cursamples = batchsamples > rgData.sampleWindow - rgData.totsamp ? rgData.sampleWindow - - rgData.totsamp - : batchsamples; - if (cursamplepos < MAX_ORDER) { - curleft = rgData.linpre + cursamplepos; - curleftBase = rgData.linprebuf; - curright = rgData.rinpre + cursamplepos; - currightBase = rgData.rinprebuf; - if (cursamples > MAX_ORDER - cursamplepos) - cursamples = MAX_ORDER - cursamplepos; - } else { - curleft = left_samplesPos + cursamplepos; - curleftBase = left_samples; - curright = right_samplesPos + cursamplepos; - currightBase = right_samples; - } - - filterYule(curleftBase, curleft, rgData.lstepbuf, rgData.lstep - + rgData.totsamp, cursamples, ABYule[rgData.freqindex]); - filterYule(currightBase, curright, rgData.rstepbuf, rgData.rstep - + rgData.totsamp, cursamples, ABYule[rgData.freqindex]); - - filterButter(rgData.lstepbuf, rgData.lstep + rgData.totsamp, - rgData.loutbuf, rgData.lout + rgData.totsamp, cursamples, - ABButter[rgData.freqindex]); - filterButter(rgData.rstepbuf, rgData.rstep + rgData.totsamp, - rgData.routbuf, rgData.rout + rgData.totsamp, cursamples, - ABButter[rgData.freqindex]); - - curleft = rgData.lout + rgData.totsamp; - /* Get the squared values */ - curleftBase = rgData.loutbuf; - curright = rgData.rout + rgData.totsamp; - currightBase = rgData.routbuf; - - int i = cursamples % 8; - while ((i--) != 0) { - rgData.lsum += fsqr(curleftBase[curleft++]); - rgData.rsum += fsqr(currightBase[curright++]); - } - i = cursamples / 8; - while ((i--) != 0) { - rgData.lsum += fsqr(curleftBase[curleft + 0]) - + fsqr(curleftBase[curleft + 1]) - + fsqr(curleftBase[curleft + 2]) - + fsqr(curleftBase[curleft + 3]) - + fsqr(curleftBase[curleft + 4]) - + fsqr(curleftBase[curleft + 5]) - + fsqr(curleftBase[curleft + 6]) - + fsqr(curleftBase[curleft + 7]); - curleft += 8; - rgData.rsum += fsqr(currightBase[curright + 0]) - + fsqr(currightBase[curright + 1]) - + fsqr(currightBase[curright + 2]) - + fsqr(currightBase[curright + 3]) - + fsqr(currightBase[curright + 4]) - + fsqr(currightBase[curright + 5]) - + fsqr(currightBase[curright + 6]) - + fsqr(currightBase[curright + 7]); - curright += 8; - } - - batchsamples -= cursamples; - cursamplepos += cursamples; - rgData.totsamp += cursamples; - if (rgData.totsamp == rgData.sampleWindow) { - /* Get the Root Mean Square (RMS) for this set of samples */ - final double val = STEPS_per_dB - * 10. - * Math.log10((rgData.lsum + rgData.rsum) - / rgData.totsamp * 0.5 + 1.e-37); - int ival = (val <= 0) ? 0 : (int) val; - if (ival >= rgData.A.length) - ival = rgData.A.length - 1; - rgData.A[ival]++; - rgData.lsum = rgData.rsum = 0.; - - System.arraycopy(rgData.loutbuf, rgData.totsamp, - rgData.loutbuf, 0, MAX_ORDER); - System.arraycopy(rgData.routbuf, rgData.totsamp, - rgData.routbuf, 0, MAX_ORDER); - System.arraycopy(rgData.lstepbuf, rgData.totsamp, - rgData.lstepbuf, 0, MAX_ORDER); - System.arraycopy(rgData.rstepbuf, rgData.totsamp, - rgData.rstepbuf, 0, MAX_ORDER); - rgData.totsamp = 0; - } - if (rgData.totsamp > rgData.sampleWindow) { - /* - * somehow I really screwed up: Error in programming! Contact - * author about totsamp > sampleWindow - */ - return GAIN_ANALYSIS_ERROR; - } - } - if (num_samples < MAX_ORDER) { - System.arraycopy(rgData.linprebuf, num_samples, rgData.linprebuf, - 0, MAX_ORDER - num_samples); - System.arraycopy(rgData.rinprebuf, num_samples, rgData.rinprebuf, - 0, MAX_ORDER - num_samples); - System.arraycopy(left_samples, left_samplesPos, rgData.linprebuf, - MAX_ORDER - num_samples, num_samples); - System.arraycopy(right_samples, right_samplesPos, rgData.rinprebuf, - MAX_ORDER - num_samples, num_samples); - } else { - System.arraycopy(left_samples, left_samplesPos + num_samples - - MAX_ORDER, rgData.linprebuf, 0, MAX_ORDER); - System.arraycopy(right_samples, right_samplesPos + num_samples - - MAX_ORDER, rgData.rinprebuf, 0, MAX_ORDER); - } - - return GAIN_ANALYSIS_OK; - } - - private float analyzeResult(final int[] Array, final int len) { - int i; - - int elems = 0; - for (i = 0; i < len; i++) - elems += Array[i]; - if (elems == 0) - return GAIN_NOT_ENOUGH_SAMPLES; - - int upper = (int) Math.ceil(elems * (1. - RMS_PERCENTILE)); - for (i = len; i-- > 0;) { - if ((upper -= Array[i]) <= 0) - break; - } - - return (float) ((float) PINK_REF - (float) i / (float) STEPS_per_dB); - } - - public final float GetTitleGain(final ReplayGain rgData) { - float retval = analyzeResult(rgData.A, rgData.A.length); - - for (int i = 0; i < rgData.A.length; i++) { - rgData.B[i] += rgData.A[i]; - rgData.A[i] = 0; - } - - for (int i = 0; i < MAX_ORDER; i++) - rgData.linprebuf[i] = rgData.lstepbuf[i] = rgData.loutbuf[i] = rgData.rinprebuf[i] = rgData.rstepbuf[i] = rgData.routbuf[i] = 0.f; - - rgData.totsamp = 0; - rgData.lsum = rgData.rsum = 0.; - return retval; - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/GenreListHandler.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/GenreListHandler.java deleted file mode 100644 index 15facf3c8..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/GenreListHandler.java +++ /dev/null @@ -1,5 +0,0 @@ -package mp3; - -public interface GenreListHandler { - void genre_list_handler(int num, String name); -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/GetAudio.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/GetAudio.java deleted file mode 100644 index 6f40788bf..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/GetAudio.java +++ /dev/null @@ -1,1327 +0,0 @@ -/* - * Get Audio routines source file - * - * Copyright (c) 1999 Albert L Faber - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: GetAudio.java,v 1.26 2011/08/27 18:57:12 kenchis Exp $ */ - -package mp3; - -import java.io.BufferedOutputStream; -import java.io.DataOutput; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.ByteOrder; -import java.nio.charset.Charset; -import java.util.Arrays; - -import mpg.MPGLib; - -public class GetAudio { - - Parse parse; - MPGLib mpg; - - public void setModules(Parse parse2, MPGLib mpg2) { - parse = parse2; - mpg = mpg2; - } - - public enum sound_file_format { - sf_unknown, sf_raw, sf_wave, sf_aiff, - /** - * MPEG Layer 1, aka mpg - */ - sf_mp1, - /** - * MPEG Layer 2 - */ - sf_mp2, - /** - * MPEG Layer 3 - */ - sf_mp3, - /** - * MPEG Layer 1,2 or 3; whatever .mp3, .mp2, .mp1 or .mpg contains - */ - sf_mp123, sf_ogg - } - - protected static final class BlockAlign { - int offset; - int blockSize; - } - - protected static final class IFF_AIFF { - short numChannels; - int numSampleFrames; - short sampleSize; - double sampleRate; - int sampleType; - BlockAlign blkAlgn = new BlockAlign(); - } - - private boolean count_samples_carefully; - private int pcmbitwidth; - private boolean pcmswapbytes; - private boolean pcm_is_unsigned_8bit; - private int num_samples_read; - private RandomAccessFile musicin; - private MPGLib.mpstr_tag hip; - - public DataOutput init_outfile(final String outPath) { - /* open the output file */ - DataOutput outf; - try { - new File(outPath).delete(); - outf = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(outPath), 1<<20)); - } catch (FileNotFoundException e) { - e.printStackTrace(); - return null; - } - return outf; - } - - public final void init_infile(final LameGlobalFlags gfp, - final String inPath, final Enc enc) { - /* open the input file */ - count_samples_carefully = false; - num_samples_read = 0; - pcmbitwidth = parse.in_bitwidth; - pcmswapbytes = parse.swapbytes; - pcm_is_unsigned_8bit = !parse.in_signed; - musicin = OpenSndFile(gfp, inPath, enc); - } - - public final void close_infile() { - closeSndFile(parse.input_format, musicin); - } - - /** - * reads a frame of audio data from a file to the buffer, aligns the data - * for future processing, and separates the left and right channels - */ - public final int get_audio(final LameGlobalFlags gfp, int buffer[][]) { - return get_audio_common(gfp, buffer, null); - } - - /** - * behave as the original get_audio function, with a limited 16 bit per - * sample output - */ - public final int get_audio16(final LameGlobalFlags gfp, - final short buffer[][]) { - return (get_audio_common(gfp, null, buffer)); - } - - /** - * central functionality of get_audio* note: either buffer or buffer16 must - * be allocated upon call - * - * @param gfp - * global flags - * @param buffer - * buffer output to the int buffer or 16-bit buffer - * @param buffer16 - * 16-bit output (if buffer == NULL) - * @return samples read - */ - private int get_audio_common(final LameGlobalFlags gfp, - final int buffer[][], final short buffer16[][]) { - int num_channels = gfp.num_channels; - int insamp[] = new int[2 * 1152]; - short buf_tmp16[][] = new short[2][1152]; - int samples_read; - int framesize; - int samples_to_read; - int remaining, tmp_num_samples; - - /* - * NOTE: LAME can now handle arbritray size input data packets, so there - * is no reason to read the input data in chuncks of size "framesize". - * EXCEPT: the LAME graphical frame analyzer will get out of sync if we - * read more than framesize worth of data. - */ - - samples_to_read = framesize = gfp.framesize; - assert (framesize <= 1152); - - /* get num_samples */ - tmp_num_samples = gfp.num_samples; - - /* - * if this flag has been set, then we are carefull to read exactly - * num_samples and no more. This is useful for .wav and .aiff files - * which have id3 or other tags at the end. Note that if you are using - * LIBSNDFILE, this is not necessary - */ - if (count_samples_carefully) { - remaining = tmp_num_samples - - Math.min(tmp_num_samples, num_samples_read); - if (remaining < framesize && 0 != tmp_num_samples) - /* - * in case the input is a FIFO (at least it's reproducible with - * a FIFO) tmp_num_samples may be 0 and therefore remaining - * would be 0, but we need to read some samples, so don't change - * samples_to_read to the wrong value in this case - */ - samples_to_read = remaining; - } - - if (is_mpeg_file_format(parse.input_format)) { - if (buffer != null) - samples_read = read_samples_mp3(gfp, musicin, buf_tmp16); - else - samples_read = read_samples_mp3(gfp, musicin, buffer16); - if (samples_read < 0) { - return samples_read; - } - } else { /* convert from int; output to 16-bit buffer */ - samples_read = read_samples_pcm(musicin, insamp, num_channels - * samples_to_read); - if (samples_read < 0) { - return samples_read; - } - int p = samples_read; - samples_read /= num_channels; - if (buffer != null) { /* output to int buffer */ - if (num_channels == 2) { - for (int i = samples_read; --i >= 0;) { - buffer[1][i] = insamp[--p]; - buffer[0][i] = insamp[--p]; - } - } else if (num_channels == 1) { - Arrays.fill(buffer[1], 0, samples_read, 0); - for (int i = samples_read; --i >= 0;) { - buffer[0][i] = insamp[--p]; - } - } else - assert (false); - } else { /* convert from int; output to 16-bit buffer */ - if (num_channels == 2) { - for (int i = samples_read; --i >= 0;) { - buffer16[1][i] = (short) ((insamp[--p] >> 16) & 0xffff); - buffer16[0][i] = (short) ((insamp[--p] >> 16) & 0xffff); - } - } else if (num_channels == 1) { - Arrays.fill(buffer16[1], 0, samples_read, (short) 0); - for (int i = samples_read; --i >= 0;) { - buffer16[0][i] = (short) ((insamp[--p] >> 16) & 0xffff); - } - } else - assert (false); - } - } - - /* LAME mp3 output 16bit - convert to int, if necessary */ - if (is_mpeg_file_format(parse.input_format)) { - if (buffer != null) { - for (int i = samples_read; --i >= 0;) - buffer[0][i] = (buf_tmp16[0][i] & 0xffff) << 16; - if (num_channels == 2) { - for (int i = samples_read; --i >= 0;) - buffer[1][i] = (buf_tmp16[1][i] & 0xffff) << 16; - } else if (num_channels == 1) { - Arrays.fill(buffer[1], 0, samples_read, 0); - } else - assert (false); - } - } - - /* - * if num_samples = MAX_U_32_NUM, then it is considered infinitely long. - * Don't count the samples - */ - if (tmp_num_samples != Integer.MAX_VALUE) - num_samples_read += samples_read; - - return samples_read; - } - - private static final String type_name = "MP3 file"; - - int read_samples_mp3(final LameGlobalFlags gfp, RandomAccessFile musicin, - short mpg123pcm[][]) { - int out; - - out = lame_decode_fromfile(musicin, mpg123pcm[0], mpg123pcm[1], - parse.mp3input_data); - /* - * out < 0: error, probably EOF out = 0: not possible with - * lame_decode_fromfile() ??? out > 0: number of output samples - */ - if (out < 0) { - Arrays.fill(mpg123pcm[0], (short) 0); - Arrays.fill(mpg123pcm[1], (short) 0); - return 0; - } - - if (gfp.num_channels != parse.mp3input_data.stereo) { - if (parse.silent < 10) { - System.err - .printf("Error: number of channels has changed in %s - not supported\n", - type_name); - } - out = -1; - } - if (gfp.in_samplerate != parse.mp3input_data.samplerate) { - if (parse.silent < 10) { - System.err - .printf("Error: sample frequency has changed in %s - not supported\n", - type_name); - } - out = -1; - } - return out; - } - - public final int WriteWaveHeader(final DataOutput fp, - final int pcmbytes, final int freq, final int channels, - final int bits) { - try { - int bytes = (bits + 7) / 8; - - /* quick and dirty, but documented */ - fp.writeBytes("RIFF"); /* label */ - write32BitsLowHigh(fp, pcmbytes + 44 - 8); - /* length in bytes without header */ - fp.writeBytes("WAVEfmt "); - /* 2 labels */ - write32BitsLowHigh(fp, 2 + 2 + 4 + 4 + 2 + 2); - /* length of PCM format declaration area */ - write16BitsLowHigh(fp, 1); - /* is PCM? */ - write16BitsLowHigh(fp, channels); - /* number of channels */ - write32BitsLowHigh(fp, freq); - /* sample frequency in [Hz] */ - write32BitsLowHigh(fp, freq * channels * bytes); - /* bytes per second */ - write16BitsLowHigh(fp, channels * bytes); - /* bytes per sample time */ - write16BitsLowHigh(fp, bits); - /* bits per sample */ - fp.writeBytes("data"); - /* label */ - write32BitsLowHigh(fp, pcmbytes); - /* length in bytes of raw PCM data */ - } catch (IOException e) { - return -1; - } - return 0; - } - - /** - * read and unpack signed low-to-high byte or unsigned single byte input. - * (used for read_samples function) Output integers are stored in the native - * byte order (little or big endian). -jd - * - * @param swap_order - * set for high-to-low byte order input stream - * @param sample_buffer - * (must be allocated up to samples_to_read upon call) - * @return number of samples read - */ - private int unpack_read_samples(final int samples_to_read, - final int bytes_per_sample, final boolean swap_order, - final int[] sample_buffer, final RandomAccessFile pcm_in) - throws IOException { - byte[] bytes = new byte[bytes_per_sample * samples_to_read]; - pcm_in.readFully(bytes); - int samples_read = samples_to_read; - - int op = samples_read; - if (!swap_order) { - if (bytes_per_sample == 1) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;) - sample_buffer[--op] = (bytes[i] & 0xff) << 24; - if (bytes_per_sample == 2) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;) - sample_buffer[--op] = (bytes[i] & 0xff) << 16 - | (bytes[i + 1] & 0xff) << 24; - if (bytes_per_sample == 3) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;) - sample_buffer[--op] = (bytes[i] & 0xff) << 8 - | (bytes[i + 1] & 0xff) << 16 - | (bytes[i + 2] & 0xff) << 24; - if (bytes_per_sample == 4) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;) - sample_buffer[--op] = (bytes[i] & 0xff) - | (bytes[i + 1] & 0xff) << 8 - | (bytes[i + 2] & 0xff) << 16 - | (bytes[i + 3] & 0xff) << 24; - } else { - if (bytes_per_sample == 1) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;) - sample_buffer[--op] = ((bytes[i] ^ 0x80) & 0xff) << 24 - | 0x7f << 16; /* convert from unsigned */ - if (bytes_per_sample == 2) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;) - sample_buffer[--op] = (bytes[i] & 0xff) << 24 - | (bytes[i + 1] & 0xff) << 16; - if (bytes_per_sample == 3) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;) - sample_buffer[--op] = (bytes[i] & 0xff) << 24 - | (bytes[i + 1] & 0xff) << 16 - | (bytes[i + 2] & 0xff) << 8; - if (bytes_per_sample == 4) - for (int i = samples_read * bytes_per_sample; (i -= bytes_per_sample) >= 0;) - sample_buffer[--op] = (bytes[i] & 0xff) << 24 - | (bytes[i + 1] & 0xff) << 16 - | (bytes[i + 2] & 0xff) << 8 - | (bytes[i + 3] & 0xff); - } - return (samples_read); - } - - /** - * reads the PCM samples from a file to the buffer - * - * SEMANTICS: Reads #samples_read# number of shorts from #musicin# - * filepointer into #sample_buffer[]#. Returns the number of samples read. - */ - private int read_samples_pcm(final RandomAccessFile musicin, - final int sample_buffer[], final int samples_to_read) { - int samples_read = 0; - boolean swap_byte_order; - /* byte order of input stream */ - - try { - switch (pcmbitwidth) { - case 32: - case 24: - case 16: - if (!parse.in_signed) { - throw new RuntimeException("Unsigned input only supported with bitwidth 8"); - } - { - swap_byte_order = (parse.in_endian != ByteOrder.LITTLE_ENDIAN); - if (pcmswapbytes) { - swap_byte_order = !swap_byte_order; - } - samples_read = unpack_read_samples(samples_to_read, - pcmbitwidth / 8, swap_byte_order, sample_buffer, - musicin); - - } - break; - - case 8: { - samples_read = unpack_read_samples(samples_to_read, 1, - pcm_is_unsigned_8bit, sample_buffer, musicin); - } - break; - - default: { - throw new RuntimeException("Only 8, 16, 24 and 32 bit input files supported"); - } - } - } catch (IOException e) { - throw new RuntimeException("Error reading input file", e); - } - - return samples_read; - } - - /* AIFF Definitions */ - - /** - * "FORM" - */ - private static final int IFF_ID_FORM = 0x464f524d; - /** - * "AIFF" - */ - private static final int IFF_ID_AIFF = 0x41494646; - /** - * "AIFC" - */ - private static final int IFF_ID_AIFC = 0x41494643; - /** - * "COMM" - */ - private static final int IFF_ID_COMM = 0x434f4d4d; - /** - * "SSND" - */ - private static final int IFF_ID_SSND = 0x53534e44; - - /** - * "NONE" AIFF-C data format - */ - private static final int IFF_ID_NONE = 0x4e4f4e45; - /** - * "twos" AIFF-C data format - */ - private static final int IFF_ID_2CBE = 0x74776f73; - /** - * "sowt" AIFF-C data format - */ - private static final int IFF_ID_2CLE = 0x736f7774; - - /** - * "RIFF" - */ - private static final int WAV_ID_RIFF = 0x52494646; - /** - * "WAVE" - */ - private static final int WAV_ID_WAVE = 0x57415645; - /** - * "fmt " - */ - private static final int WAV_ID_FMT = 0x666d7420; - /** - * "data" - */ - private static final int WAV_ID_DATA = 0x64617461; - - private static final short WAVE_FORMAT_PCM = 0x0001; - private static final short WAVE_FORMAT_EXTENSIBLE = (short) 0xFFFE; - - /** - * Read Microsoft Wave headers - * - * By the time we get here the first 32-bits of the file have already been - * read, and we're pretty sure that we're looking at a WAV file. - */ - private int parse_wave_header(final LameGlobalFlags gfp, - final RandomAccessFile sf) { - int format_tag = 0; - int channels = 0; - int bits_per_sample = 0; - int samples_per_sec = 0; - - boolean is_wav = false; - int data_length = 0, subSize = 0; - int loop_sanity = 0; - - /* file_length = */Read32BitsHighLow(sf); - if (Read32BitsHighLow(sf) != WAV_ID_WAVE) - return -1; - - for (loop_sanity = 0; loop_sanity < 20; ++loop_sanity) { - int type = Read32BitsHighLow(sf); - - if (type == WAV_ID_FMT) { - subSize = Read32BitsLowHigh(sf); - if (subSize < 16) { - return -1; - } - - format_tag = Read16BitsLowHigh(sf); - subSize -= 2; - channels = Read16BitsLowHigh(sf); - subSize -= 2; - samples_per_sec = Read32BitsLowHigh(sf); - subSize -= 4; - /* avg_bytes_per_sec = */Read32BitsLowHigh(sf); - subSize -= 4; - /* block_align = */Read16BitsLowHigh(sf); - subSize -= 2; - bits_per_sample = Read16BitsLowHigh(sf); - subSize -= 2; - - /* WAVE_FORMAT_EXTENSIBLE support */ - if ((subSize > 9) && (format_tag == WAVE_FORMAT_EXTENSIBLE)) { - Read16BitsLowHigh(sf); /* cbSize */ - Read16BitsLowHigh(sf); /* ValidBitsPerSample */ - Read32BitsLowHigh(sf); /* ChannelMask */ - /* SubType coincident with format_tag for PCM int or float */ - format_tag = Read16BitsLowHigh(sf); - subSize -= 10; - } - - if (subSize > 0) { - try { - sf.skipBytes(subSize); - } catch (IOException e) { - return -1; - } - } - - } else if (type == WAV_ID_DATA) { - subSize = Read32BitsLowHigh(sf); - data_length = subSize; - is_wav = true; - /* We've found the audio data. Read no further! */ - break; - - } else { - subSize = Read32BitsLowHigh(sf); - try { - sf.skipBytes(subSize); - } catch (IOException e) { - return -1; - } - } - } - - if (is_wav) { - if (format_tag != WAVE_FORMAT_PCM) { - if (parse.silent < 10) { - System.err.printf("Unsupported data format: 0x%04X\n", - format_tag); - } - /* oh no! non-supported format */ - return 0; - } - - /* make sure the header is sane */ - if (-1 == (gfp.num_channels = channels)) { - if (parse.silent < 10) { - System.err.printf("Unsupported number of channels: %d\n", - channels); - } - return 0; - } - gfp.in_samplerate = samples_per_sec; - pcmbitwidth = bits_per_sample; - pcm_is_unsigned_8bit = true; - gfp.num_samples = data_length - / (channels * ((bits_per_sample + 7) / 8)); - return 1; - } - return -1; - } - - /** - * Checks AIFF header information to make sure it is valid. returns 0 on - * success, 1 on errors - */ - private int aiff_check2(final IFF_AIFF pcm_aiff_data) { - if (pcm_aiff_data.sampleType != IFF_ID_SSND) { - if (parse.silent < 10) { - System.err.printf("ERROR: input sound data is not PCM\n"); - } - return 1; - } - switch (pcm_aiff_data.sampleSize) { - case 32: - case 24: - case 16: - case 8: - break; - default: - if (parse.silent < 10) { - System.err - .printf("ERROR: input sound data is not 8, 16, 24 or 32 bits\n"); - } - return 1; - } - if (pcm_aiff_data.numChannels != 1 && pcm_aiff_data.numChannels != 2) { - if (parse.silent < 10) { - System.err - .printf("ERROR: input sound data is not mono or stereo\n"); - } - return 1; - } - if (pcm_aiff_data.blkAlgn.blockSize != 0) { - if (parse.silent < 10) { - System.err - .printf("ERROR: block size of input sound data is not 0 bytes\n"); - } - return 1; - } - return 0; - } - - private long make_even_number_of_bytes_in_length(final int x) { - if ((x & 0x01) != 0) { - return x + 1; - } - return x; - } - - /** - * Read Audio Interchange File Format (AIFF) headers. - * - * By the time we get here the first 32 bits of the file have already been - * read, and we're pretty sure that we're looking at an AIFF file. - */ - private int parse_aiff_header(final LameGlobalFlags gfp, - final RandomAccessFile sf) { - int subSize = 0, dataType = IFF_ID_NONE; - IFF_AIFF aiff_info = new IFF_AIFF(); - int seen_comm_chunk = 0, seen_ssnd_chunk = 0; - long pcm_data_pos = -1; - - int chunkSize = Read32BitsHighLow(sf); - - int typeID = Read32BitsHighLow(sf); - if ((typeID != IFF_ID_AIFF) && (typeID != IFF_ID_AIFC)) - return -1; - - while (chunkSize > 0) { - long ckSize; - int type = Read32BitsHighLow(sf); - chunkSize -= 4; - - /* don't use a switch here to make it easier to use 'break' for SSND */ - if (type == IFF_ID_COMM) { - seen_comm_chunk = seen_ssnd_chunk + 1; - subSize = Read32BitsHighLow(sf); - ckSize = make_even_number_of_bytes_in_length(subSize); - chunkSize -= ckSize; - - aiff_info.numChannels = (short) Read16BitsHighLow(sf); - ckSize -= 2; - aiff_info.numSampleFrames = Read32BitsHighLow(sf); - ckSize -= 4; - aiff_info.sampleSize = (short) Read16BitsHighLow(sf); - ckSize -= 2; - try { - aiff_info.sampleRate = readIeeeExtendedHighLow(sf); - } catch (IOException e1) { - return -1; - } - ckSize -= 10; - if (typeID == IFF_ID_AIFC) { - dataType = Read32BitsHighLow(sf); - ckSize -= 4; - } - try { - sf.skipBytes((int) ckSize); - } catch (IOException e) { - return -1; - } - } else if (type == IFF_ID_SSND) { - seen_ssnd_chunk = 1; - subSize = Read32BitsHighLow(sf); - ckSize = make_even_number_of_bytes_in_length(subSize); - chunkSize -= ckSize; - - aiff_info.blkAlgn.offset = Read32BitsHighLow(sf); - ckSize -= 4; - aiff_info.blkAlgn.blockSize = Read32BitsHighLow(sf); - ckSize -= 4; - - aiff_info.sampleType = IFF_ID_SSND; - - if (seen_comm_chunk > 0) { - try { - sf.skipBytes(aiff_info.blkAlgn.offset); - } catch (IOException e) { - return -1; - } - /* We've found the audio data. Read no further! */ - break; - } - try { - pcm_data_pos = sf.getFilePointer(); - } catch (IOException e) { - return -1; - } - if (pcm_data_pos >= 0) { - pcm_data_pos += aiff_info.blkAlgn.offset; - } - try { - sf.skipBytes((int) ckSize); - } catch (IOException e) { - return -1; - } - } else { - subSize = Read32BitsHighLow(sf); - ckSize = make_even_number_of_bytes_in_length(subSize); - chunkSize -= ckSize; - - try { - sf.skipBytes((int) ckSize); - } catch (IOException e) { - return -1; - } - } - } - if (dataType == IFF_ID_2CLE) { - pcmswapbytes = parse.swapbytes; - } else if (dataType == IFF_ID_2CBE) { - pcmswapbytes = !parse.swapbytes; - } else if (dataType == IFF_ID_NONE) { - pcmswapbytes = !parse.swapbytes; - } else { - return -1; - } - - if (seen_comm_chunk != 0 - && (seen_ssnd_chunk > 0 || aiff_info.numSampleFrames == 0)) { - /* make sure the header is sane */ - if (0 != aiff_check2(aiff_info)) - return 0; - if (-1 == (gfp.num_channels = aiff_info.numChannels)) { - if (parse.silent < 10) { - System.err.printf("Unsupported number of channels: %u\n", - aiff_info.numChannels); - } - return 0; - } - gfp.in_samplerate = (int) aiff_info.sampleRate; - gfp.num_samples = aiff_info.numSampleFrames; - pcmbitwidth = aiff_info.sampleSize; - pcm_is_unsigned_8bit = false; - - if (pcm_data_pos >= 0) { - try { - sf.seek(pcm_data_pos); - } catch (IOException e) { - if (parse.silent < 10) { - System.err - .printf("Can't rewind stream to audio data position\n"); - } - return 0; - } - } - - return 1; - } - return -1; - } - - /** - * Read the header from a bytestream. Try to determine whether it's a WAV - * file or AIFF without rewinding, since rewind doesn't work on pipes and - * there's a good chance we're reading from stdin (otherwise we'd probably - * be using libsndfile). - * - * When this function returns, the file offset will be positioned at the - * beginning of the sound data. - */ - private sound_file_format parse_file_header(final LameGlobalFlags gfp, - final RandomAccessFile sf) { - - int type = Read32BitsHighLow(sf); - count_samples_carefully = false; - pcm_is_unsigned_8bit = !parse.in_signed; - /* - * input_format = sf_raw; commented out, because it is better to fail - * here as to encode some hundreds of input files not supported by LAME - * If you know you have RAW PCM data, use the -r switch - */ - - if (type == WAV_ID_RIFF) { - /* It's probably a WAV file */ - int ret = parse_wave_header(gfp, sf); - if (ret > 0) { - count_samples_carefully = true; - return sound_file_format.sf_wave; - } - if (ret < 0) { - if (parse.silent < 10) { - System.err - .println("Warning: corrupt or unsupported WAVE format"); - } - } - } else if (type == IFF_ID_FORM) { - /* It's probably an AIFF file */ - int ret = parse_aiff_header(gfp, sf); - if (ret > 0) { - count_samples_carefully = true; - return sound_file_format.sf_aiff; - } - if (ret < 0) { - if (parse.silent < 10) { - System.err - .printf("Warning: corrupt or unsupported AIFF format\n"); - } - } - } else { - if (parse.silent < 10) { - System.err.println("Warning: unsupported audio format\n"); - } - } - return sound_file_format.sf_unknown; - } - - private void closeSndFile(final sound_file_format input, - final RandomAccessFile musicin) { - if (musicin != null) { - try { - musicin.close(); - } catch (IOException e) { - throw new RuntimeException("Could not close sound file", e); - } - } - } - - private RandomAccessFile OpenSndFile(final LameGlobalFlags gfp, - final String inPath, final Enc enc) { - - /* set the defaults from info in case we cannot determine them from file */ - gfp.num_samples = -1; - - try { - musicin = new RandomAccessFile(inPath, "r"); - } catch (FileNotFoundException e) { - throw new RuntimeException(String.format("Could not find \"%s\".", inPath), e); - } - - if (is_mpeg_file_format(parse.input_format)) { - if (-1 == lame_decode_initfile(musicin, parse.mp3input_data, enc)) { - throw new RuntimeException(String.format("Error reading headers in mp3 input file %s.", inPath)); - } - gfp.num_channels = parse.mp3input_data.stereo; - gfp.in_samplerate = parse.mp3input_data.samplerate; - gfp.num_samples = parse.mp3input_data.nsamp; - } else if (parse.input_format == sound_file_format.sf_ogg) { - throw new RuntimeException("sorry, vorbis support in LAME is deprecated."); - } else if (parse.input_format == sound_file_format.sf_raw) { - /* assume raw PCM */ - if (parse.silent < 10) { - System.out.println("Assuming raw pcm input file"); - if (parse.swapbytes) - System.out.printf(" : Forcing byte-swapping\n"); - else - System.out.printf("\n"); - } - pcmswapbytes = parse.swapbytes; - } else { - parse.input_format = parse_file_header(gfp, musicin); - } - if (parse.input_format == sound_file_format.sf_unknown) { - throw new RuntimeException("Unknown sound format!"); - } - - if (gfp.num_samples == -1) { - - double flen = new File(inPath).length(); - /* try to figure out num_samples */ - if (flen >= 0) { - /* try file size, assume 2 bytes per sample */ - if (is_mpeg_file_format(parse.input_format)) { - if (parse.mp3input_data.bitrate > 0) { - double totalseconds = (flen * 8.0 / (1000.0 * parse.mp3input_data.bitrate)); - int tmp_num_samples = (int) (totalseconds * gfp.in_samplerate); - - gfp.num_samples = tmp_num_samples; - parse.mp3input_data.nsamp = tmp_num_samples; - } - } else { - gfp.num_samples = (int) (flen / (2 * gfp.num_channels)); - } - } - } - return musicin; - } - - private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); - - private boolean check_aid(final byte[] header) { - return new String(header, ISO_8859_1).startsWith("AiD\1"); - } - - private static final char abl2[] = { 0, 7, 7, 7, 0, 7, 0, 0, 0, 0, 0, 8, 8, - 8, 8, 8 }; - - /** - * Please check this and don't kill me if there's a bug This is a (nearly?) - * complete header analysis for a MPEG-1/2/2.5 Layer I, II or III data - * stream - */ - private boolean is_syncword_mp123(final byte[] headerptr) { - int p = 0; - - if ((headerptr[p + 0] & 0xFF) != 0xFF) { - /* first 8 bits must be '1' */ - return false; - } - if ((headerptr[p + 1] & 0xE0) != 0xE0) { - /* next 3 bits are also */ - return false; - } - if ((headerptr[p + 1] & 0x18) == 0x08) { - /* no MPEG-1, -2 or -2.5 */ - return false; - } - switch (headerptr[p + 1] & 0x06) { - default: - case 0x00: - /* illegal Layer */ - return false; - - case 0x02: - /* Layer3 */ - if (parse.input_format != sound_file_format.sf_mp3 - && parse.input_format != sound_file_format.sf_mp123) { - return false; - } - parse.input_format = sound_file_format.sf_mp3; - break; - - case 0x04: - /* Layer2 */ - if (parse.input_format != sound_file_format.sf_mp2 - && parse.input_format != sound_file_format.sf_mp123) { - return false; - } - parse.input_format = sound_file_format.sf_mp2; - break; - - case 0x06: - /* Layer1 */ - if (parse.input_format != sound_file_format.sf_mp1 - && parse.input_format != sound_file_format.sf_mp123) { - return false; - } - parse.input_format = sound_file_format.sf_mp1; - break; - } - if ((headerptr[p + 1] & 0x06) == 0x00) { - /* no Layer I, II and III */ - return false; - } - if ((headerptr[p + 2] & 0xF0) == 0xF0) { - /* bad bitrate */ - return false; - } - if ((headerptr[p + 2] & 0x0C) == 0x0C) { - /* no sample frequency with (32,44.1,48)/(1,2,4) */ - return false; - } - if ((headerptr[p + 1] & 0x18) == 0x18 - && (headerptr[p + 1] & 0x06) == 0x04 - && (abl2[(headerptr[p + 2] & 0xff) >> 4] & (1 << ((headerptr[p + 3] & 0xff) >> 6))) != 0) - return false; - if ((headerptr[p + 3] & 3) == 2) { - /* reserved enphasis mode */ - return false; - } - return true; - } - - private int lame_decode_initfile(final RandomAccessFile fd, - final MP3Data mp3data, final Enc enc) { - byte buf[] = new byte[100]; - short pcm_l[] = new short[1152], pcm_r[] = new short[1152]; - boolean freeformat = false; - - if (hip != null) { - mpg.hip_decode_exit(hip); - } - hip = mpg.hip_decode_init(); - - int len = 4; - try { - fd.readFully(buf, 0, len); - } catch (IOException e) { - e.printStackTrace(); - return -1; /* failed */ - } - if (buf[0] == 'I' && buf[1] == 'D' && buf[2] == '3') { - if (parse.silent < 10) { - System.out - .println("ID3v2 found. " - + "Be aware that the ID3 tag is currently lost when transcoding."); - } - len = 6; - try { - fd.readFully(buf, 0, len); - } catch (IOException e) { - e.printStackTrace(); - return -1; /* failed */ - } - buf[2] &= 127; - buf[3] &= 127; - buf[4] &= 127; - buf[5] &= 127; - len = (((((buf[2] << 7) + buf[3]) << 7) + buf[4]) << 7) + buf[5]; - try { - fd.skipBytes(len); - } catch (IOException e) { - e.printStackTrace(); - return -1; /* failed */ - } - len = 4; - try { - fd.readFully(buf, 0, len); - } catch (IOException e) { - e.printStackTrace(); - return -1; /* failed */ - } - } - if (check_aid(buf)) { - try { - fd.readFully(buf, 0, 2); - } catch (IOException e) { - e.printStackTrace(); - return -1; /* failed */ - } - int aid_header = (buf[0] & 0xff) + 256 * (buf[1] & 0xff); - if (parse.silent < 10) { - System.out.printf("Album ID found. length=%d \n", aid_header); - } - /* skip rest of AID, except for 6 bytes we have already read */ - try { - fd.skipBytes(aid_header - 6); - } catch (IOException e) { - e.printStackTrace(); - return -1; /* failed */ - } - - /* read 4 more bytes to set up buffer for MP3 header check */ - try { - fd.readFully(buf, 0, len); - } catch (IOException e) { - e.printStackTrace(); - return -1; /* failed */ - } - } - len = 4; - while (!is_syncword_mp123(buf)) { - int i; - for (i = 0; i < len - 1; i++) - buf[i] = buf[i + 1]; - try { - fd.readFully(buf, len - 1, 1); - } catch (IOException e) { - e.printStackTrace(); - return -1; /* failed */ - } - } - - if ((buf[2] & 0xf0) == 0) { - if (parse.silent < 10) { - System.out.println("Input file is freeformat."); - } - freeformat = true; - } - /* now parse the current buffer looking for MP3 headers. */ - /* (as of 11/00: mpglib modified so that for the first frame where */ - /* headers are parsed, no data will be decoded. */ - /* However, for freeformat, we need to decode an entire frame, */ - /* so mp3data->bitrate will be 0 until we have decoded the first */ - /* frame. Cannot decode first frame here because we are not */ - /* yet prepared to handle the output. */ - int ret = mpg.hip_decode1_headersB(hip, buf, len, pcm_l, pcm_r, - mp3data, enc); - if (-1 == ret) - return -1; - - /* repeat until we decode a valid mp3 header. */ - while (!mp3data.header_parsed) { - try { - fd.readFully(buf); - } catch (IOException e) { - e.printStackTrace(); - return -1; /* failed */ - } - ret = mpg.hip_decode1_headersB(hip, buf, buf.length, pcm_l, pcm_r, - mp3data, enc); - if (-1 == ret) - return -1; - } - - if (mp3data.bitrate == 0 && !freeformat) { - if (parse.silent < 10) { - System.err.println("fail to sync..."); - } - return lame_decode_initfile(fd, mp3data, enc); - } - - if (mp3data.totalframes > 0) { - /* mpglib found a Xing VBR header and computed nsamp & totalframes */ - } else { - /* - * set as unknown. Later, we will take a guess based on file size - * ant bitrate - */ - mp3data.nsamp = -1; - } - - return 0; - } - - /** - * @return -1 error n number of samples output. either 576 or 1152 depending - * on MP3 file. - */ - private int lame_decode_fromfile(final RandomAccessFile fd, - final short pcm_l[], final short pcm_r[], final MP3Data mp3data) { - int ret = 0; - int len = 0; - byte buf[] = new byte[1024]; - - /* first see if we still have data buffered in the decoder: */ - ret = -1; - ret = mpg.hip_decode1_headers(hip, buf, len, pcm_l, pcm_r, mp3data); - if (ret != 0) - return ret; - - /* read until we get a valid output frame */ - while (true) { - try { - len = fd.read(buf, 0, 1024); - } catch (IOException e) { - e.printStackTrace(); - return -1; - } - if (len <= 0) { - /* we are done reading the file, but check for buffered data */ - ret = mpg.hip_decode1_headers(hip, buf, 0, pcm_l, pcm_r, - mp3data); - if (ret <= 0) { - mpg.hip_decode_exit(hip); - /* release mp3decoder memory */ - hip = null; - return -1; /* done with file */ - } - break; - } - - ret = mpg.hip_decode1_headers(hip, buf, len, pcm_l, pcm_r, mp3data); - if (ret == -1) { - mpg.hip_decode_exit(hip); - /* release mp3decoder memory */ - hip = null; - return -1; - } - if (ret > 0) - break; - } - return ret; - } - - private boolean is_mpeg_file_format( - final sound_file_format input_file_format) { - switch (input_file_format) { - case sf_mp1: - case sf_mp2: - case sf_mp3: - case sf_mp123: - return true; - default: - break; - } - return false; - } - - // Rest of portableio.c: - - private int Read32BitsLowHigh(final RandomAccessFile fp) { - int first = 0xffff & Read16BitsLowHigh(fp); - int second = 0xffff & Read16BitsLowHigh(fp); - - int result = (second << 16) + first; - return (result); - } - - private int Read16BitsLowHigh(final RandomAccessFile fp) { - try { - int first = 0xff & fp.read(); - int second = 0xff & fp.read(); - - int result = (second << 8) + first; - return (result); - } catch (IOException e) { - e.printStackTrace(); - return 0; - } - } - - private int Read16BitsHighLow(final RandomAccessFile fp) { - try { - int high = fp.readUnsignedByte(); - int low = fp.readUnsignedByte(); - - return (high << 8) | low; - } catch (IOException e) { - e.printStackTrace(); - return 0; - } - } - - private int Read32BitsHighLow(final RandomAccessFile fp) { - int first = 0xffff & Read16BitsHighLow(fp); - int second = 0xffff & Read16BitsHighLow(fp); - - int result = (first << 16) + second; - return (result); - } - - private double unsignedToFloat(final double u) { - return ((double) ((long) (u - 2147483647L - 1))) + 2147483648.0; - } - - private double ldexp(final double x, final double exp) { - return x * Math.pow(2, exp); - } - - /** - * Extended precision IEEE floating-point conversion routines - */ - private double convertFromIeeeExtended(final byte[] bytes) { - double f; - long expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF); - long hiMant = ((long) (bytes[2] & 0xFF) << 24) - | ((long) (bytes[3] & 0xFF) << 16) - | ((long) (bytes[4] & 0xFF) << 8) | ((long) (bytes[5] & 0xFF)); - long loMant = ((long) (bytes[6] & 0xFF) << 24) - | ((long) (bytes[7] & 0xFF) << 16) - | ((long) (bytes[8] & 0xFF) << 8) | ((long) (bytes[9] & 0xFF)); - - /* - * This case should also be called if the number is below the smallest - * positive double variable - */ - if (expon == 0 && hiMant == 0 && loMant == 0) { - f = 0; - } else { - /* - * This case should also be called if the number is too large to fit - * into a double variable - */ - - if (expon == 0x7FFF) { /* Infinity or NaN */ - f = Double.POSITIVE_INFINITY; - } else { - expon -= 16383; - - f = ldexp(unsignedToFloat(hiMant), (int) (expon -= 31)); - f += ldexp(unsignedToFloat(loMant), (int) (expon -= 32)); - } - } - - if ((bytes[0] & 0x80) != 0) - return -f; - else - return f; - } - - private double readIeeeExtendedHighLow(final RandomAccessFile fp) - throws IOException { - byte bytes[] = new byte[10]; - - fp.readFully(bytes); - return convertFromIeeeExtended(bytes); - } - - private void write32BitsLowHigh(final DataOutput fp, final int i) - throws IOException { - write16BitsLowHigh(fp, (int) (i & 0xffffL)); - write16BitsLowHigh(fp, (int) ((i >> 16) & 0xffffL)); - } - - public final void write16BitsLowHigh(final DataOutput fp, final int i) - throws IOException { - fp.write(i & 0xff); - fp.write((i >> 8) & 0xff); - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/GrInfo.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/GrInfo.java deleted file mode 100644 index df5654802..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/GrInfo.java +++ /dev/null @@ -1,78 +0,0 @@ -package mp3; - -public final class GrInfo { - float xr[] = new float[576]; - int l3_enc[] = new int[576]; - int scalefac[] = new int[L3Side.SFBMAX]; - float xrpow_max; - - int part2_3_length; - int big_values; - int count1; - int global_gain; - int scalefac_compress; - int block_type; - int mixed_block_flag; - int table_select[] = new int[3]; - int subblock_gain[] = new int[3 + 1]; - int region0_count; - int region1_count; - int preflag; - int scalefac_scale; - int count1table_select; - - int part2_length; - int sfb_lmax; - int sfb_smin; - int psy_lmax; - int sfbmax; - int psymax; - int sfbdivide; - int width[] = new int[L3Side.SFBMAX]; - int window[] = new int[L3Side.SFBMAX]; - int count1bits; - /** - * added for LSF - */ - int[] sfb_partition_table; - int slen[] = new int[4]; - - int max_nonzero_coeff; - - public final void assign(final GrInfo other) { - xr = other.xr.clone(); - l3_enc = other.l3_enc.clone(); - scalefac = other.scalefac.clone(); - xrpow_max = other.xrpow_max; - - part2_3_length = other.part2_3_length; - big_values = other.big_values; - count1 = other.count1; - global_gain = other.global_gain; - scalefac_compress = other.scalefac_compress; - block_type = other.block_type; - mixed_block_flag = other.mixed_block_flag; - table_select = other.table_select.clone(); - subblock_gain = other.subblock_gain.clone(); - region0_count = other.region0_count; - region1_count = other.region1_count; - preflag = other.preflag; - scalefac_scale = other.scalefac_scale; - count1table_select = other.count1table_select; - - part2_length = other.part2_length; - sfb_lmax = other.sfb_lmax; - sfb_smin = other.sfb_smin; - psy_lmax = other.psy_lmax; - sfbmax = other.sfbmax; - psymax = other.psymax; - sfbdivide = other.sfbdivide; - width = other.width.clone(); - window = other.window.clone(); - count1bits = other.count1bits; - - sfb_partition_table = other.sfb_partition_table.clone(); - slen = other.slen.clone(); - max_nonzero_coeff = other.max_nonzero_coeff; - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/HuffCodeTab.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/HuffCodeTab.java deleted file mode 100644 index fda29b575..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/HuffCodeTab.java +++ /dev/null @@ -1,27 +0,0 @@ -package mp3; - -public class HuffCodeTab { - public HuffCodeTab(final int len, final int max, final int[] tab, final int[] hl) { - xlen = len; - linmax = max; - table = tab; - hlen = hl; - } - - /** - * max. x-index+ - */ - final int xlen; - /** - * max number to be stored in linbits - */ - final int linmax; - /** - * pointer to array[xlen][ylen] - */ - final int[] table; - /** - * pointer to array[xlen][ylen] - */ - final int[] hlen; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ID3Tag.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ID3Tag.java deleted file mode 100644 index 35469327f..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ID3Tag.java +++ /dev/null @@ -1,1205 +0,0 @@ -/* - * id3tag.c -- Write ID3 version 1 and 2 tags. - * - * Copyright (C) 2000 Don Melton. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -/* - * HISTORY: This source file is part of LAME (see http://www.mp3dev.org) - * and was originally adapted by Conrad Sanderson <c.sanderson@me.gu.edu.au> - * from mp3info by Ricardo Cerqueira <rmc@rccn.net> to write only ID3 version 1 - * tags. Don Melton <don@blivet.com> COMPLETELY rewrote it to support version - * 2 tags and be more conformant to other standards while remaining flexible. - * - * NOTE: See http://id3.org/ for more information about ID3 tag formats. - */ -package mp3; - -import java.nio.charset.Charset; -import java.util.Arrays; - -public class ID3Tag { - - BitStream bits; - Version ver; - - public final void setModules(BitStream bits, Version ver) { - this.bits = bits; - this.ver = ver; - } - - private static final int CHANGED_FLAG = (1 << 0); - private static final int ADD_V2_FLAG = (1 << 1); - private static final int V1_ONLY_FLAG = (1 << 2); - private static final int V2_ONLY_FLAG = (1 << 3); - private static final int SPACE_V1_FLAG = (1 << 4); - private static final int PAD_V2_FLAG = (1 << 5); - - enum MimeType { - MIMETYPE_NONE, MIMETYPE_JPEG, MIMETYPE_PNG, MIMETYPE_GIF, - }; - - private static final String genre_names[] = { - /* - * NOTE: The spelling of these genre names is identical to those found in - * Winamp and mp3info. - */ - "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", - "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", - "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", - "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", - "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", - "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", - "Game", "Sound Clip", "Gospel", "Noise", "Alternative Rock", - "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", - "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", - "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", - "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", - "Christian Rap", "Pop/Funk", "Jungle", "Native US", "Cabaret", - "New Wave", "Psychedelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", - "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", - "Rock & Roll", "Hard Rock", "Folk", "Folk-Rock", "National Folk", - "Swing", "Fast Fusion", "Bebob", "Latin", "Revival", "Celtic", - "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", - "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", - "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", - "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", - "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", - "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", - "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", - "A Cappella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass", - "Club-House", "Hardcore", "Terror", "Indie", "BritPop", - "Negerpunk", "Polsk Punk", "Beat", "Christian Gangsta", - "Heavy Metal", "Black Metal", "Crossover", - "Contemporary Christian", "Christian Rock", "Merengue", "Salsa", - "Thrash Metal", "Anime", "JPop", "SynthPop" }; - - private static final int genre_alpha_map[] = { 123, 34, 74, 73, 99, 20, 40, - 26, 145, 90, 116, 41, 135, 85, 96, 138, 89, 0, 107, 132, 65, 88, - 104, 102, 97, 136, 61, 141, 32, 1, 112, 128, 57, 140, 2, 139, 58, - 3, 125, 50, 22, 4, 55, 127, 122, 120, 98, 52, 48, 54, 124, 25, 84, - 80, 115, 81, 119, 5, 30, 36, 59, 126, 38, 49, 91, 6, 129, 79, 137, - 7, 35, 100, 131, 19, 33, 46, 47, 8, 29, 146, 63, 86, 71, 45, 142, - 9, 77, 82, 64, 133, 10, 66, 39, 11, 103, 12, 75, 134, 13, 53, 62, - 109, 117, 23, 108, 92, 67, 93, 43, 121, 15, 68, 14, 16, 76, 87, - 118, 17, 78, 143, 114, 110, 69, 21, 111, 95, 105, 42, 37, 24, 56, - 44, 101, 83, 94, 106, 147, 113, 18, 51, 130, 144, 60, 70, 31, 72, - 27, 28 }; - - private static final int GENRE_INDEX_OTHER = 12; - - private static int FRAME_ID(char a, char b, char c, char d) { - return ((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) - | ((d & 0xff) << 0); - } - - private static final int ID_TITLE = (FRAME_ID('T', 'I', 'T', '2')); - private static final int ID_ARTIST = (FRAME_ID('T', 'P', 'E', '1')); - private static final int ID_ALBUM = (FRAME_ID('T', 'A', 'L', 'B')); - private static final int ID_GENRE = (FRAME_ID('T', 'C', 'O', 'N')); - private static final int ID_ENCODER = (FRAME_ID('T', 'S', 'S', 'E')); - private static final int ID_PLAYLENGTH = (FRAME_ID('T', 'L', 'E', 'N')); - private static final int ID_COMMENT = (FRAME_ID('C', 'O', 'M', 'M')); - - /** - * "ddMM" - */ - private static final int ID_DATE = (FRAME_ID('T', 'D', 'A', 'T')); - /** - * "hhmm" - */ - private static final int ID_TIME = (FRAME_ID('T', 'I', 'M', 'E')); - /** - * '0'-'9' and '/' allowed - */ - private static final int ID_TPOS = (FRAME_ID('T', 'P', 'O', 'S')); - /** - * '0'-'9' and '/' allowed - */ - private static final int ID_TRACK = (FRAME_ID('T', 'R', 'C', 'K')); - /** - * "yyyy" - */ - private static final int ID_YEAR = (FRAME_ID('T', 'Y', 'E', 'R')); - - private static final int ID_TXXX = (FRAME_ID('T', 'X', 'X', 'X')); - private static final int ID_WXXX = (FRAME_ID('W', 'X', 'X', 'X')); - private static final int ID_SYLT = (FRAME_ID('S', 'Y', 'L', 'T')); - private static final int ID_APIC = (FRAME_ID('A', 'P', 'I', 'C')); - private static final int ID_GEOB = (FRAME_ID('G', 'E', 'O', 'B')); - private static final int ID_PCNT = (FRAME_ID('P', 'C', 'N', 'T')); - private static final int ID_AENC = (FRAME_ID('A', 'E', 'N', 'C')); - private static final int ID_LINK = (FRAME_ID('L', 'I', 'N', 'K')); - private static final int ID_ENCR = (FRAME_ID('E', 'N', 'C', 'R')); - private static final int ID_GRID = (FRAME_ID('G', 'R', 'I', 'D')); - private static final int ID_PRIV = (FRAME_ID('P', 'R', 'I', 'V')); - - private void copyV1ToV2(final LameGlobalFlags gfp, final int frame_id, - final String s) { - LameInternalFlags gfc = gfp.internal_flags; - int flags = gfc.tag_spec.flags; - id3v2_add_latin1(gfp, frame_id, null, null, s); - gfc.tag_spec.flags = flags; - } - - private void id3v2AddLameVersion(final LameGlobalFlags gfp) { - String buffer; - String b = ver.getLameOsBitness(); - String v = ver.getLameVersion(); - String u = ver.getLameUrl(); - final int lenb = b.length(); - - if (lenb > 0) { - buffer = String.format("LAME %s version %s (%s)", b, v, u); - } else { - buffer = String.format("LAME version %s (%s)", v, u); - } - copyV1ToV2(gfp, ID_ENCODER, buffer); - } - - private void id3v2AddAudioDuration(final LameGlobalFlags gfp) { - if (gfp.num_samples != -1) { - String buffer; - double max_ulong = Integer.MAX_VALUE; - double ms = gfp.num_samples; - long playlength_ms; - - ms *= 1000; - ms /= gfp.in_samplerate; - if (ms > Integer.MAX_VALUE) { - playlength_ms = (long) max_ulong; - } else if (ms < 0) { - playlength_ms = 0; - } else { - playlength_ms = (long) ms; - } - buffer = String.format("%d", playlength_ms); - copyV1ToV2(gfp, ID_PLAYLENGTH, buffer); - } - } - - public final void id3tag_genre_list(final GenreListHandler handler) { - if (handler != null) { - for (int i = 0; i < genre_names.length; ++i) { - if (i < genre_alpha_map.length) { - int j = genre_alpha_map[i]; - handler.genre_list_handler(j, genre_names[j]); - } - } - } - } - - private static final int GENRE_NUM_UNKNOWN = 255; - private static final Charset ASCII = Charset.forName("US-ASCII"); - - public final void id3tag_init(final LameGlobalFlags gfp) { - LameInternalFlags gfc = gfp.internal_flags; - gfc.tag_spec = new ID3TagSpec(); - gfc.tag_spec.genre_id3v1 = GENRE_NUM_UNKNOWN; - gfc.tag_spec.padding_size = 128; - id3v2AddLameVersion(gfp); - } - - public final void id3tag_add_v2(final LameGlobalFlags gfp) { - LameInternalFlags gfc = gfp.internal_flags; - gfc.tag_spec.flags &= ~V1_ONLY_FLAG; - gfc.tag_spec.flags |= ADD_V2_FLAG; - } - - public final void id3tag_v1_only(final LameGlobalFlags gfp) { - LameInternalFlags gfc = gfp.internal_flags; - gfc.tag_spec.flags &= ~(ADD_V2_FLAG | V2_ONLY_FLAG); - gfc.tag_spec.flags |= V1_ONLY_FLAG; - } - - public final void id3tag_v2_only(final LameGlobalFlags gfp) { - LameInternalFlags gfc = gfp.internal_flags; - gfc.tag_spec.flags &= ~V1_ONLY_FLAG; - gfc.tag_spec.flags |= V2_ONLY_FLAG; - } - - public final void id3tag_space_v1(final LameGlobalFlags gfp) { - LameInternalFlags gfc = gfp.internal_flags; - gfc.tag_spec.flags &= ~V2_ONLY_FLAG; - gfc.tag_spec.flags |= SPACE_V1_FLAG; - } - - public final void id3tag_pad_v2(final LameGlobalFlags gfp) { - id3tag_set_pad(gfp, 128); - } - - public final void id3tag_set_pad(final LameGlobalFlags gfp, final int n) { - LameInternalFlags gfc = gfp.internal_flags; - gfc.tag_spec.flags &= ~V1_ONLY_FLAG; - gfc.tag_spec.flags |= PAD_V2_FLAG; - gfc.tag_spec.flags |= ADD_V2_FLAG; - gfc.tag_spec.padding_size = n; - } - - /** - * <PRE> - * Some existing options for ID3 tag can be specified by --tv option - * as follows. - * --tt <value>, --tv TIT2=value - * --ta <value>, --tv TPE1=value - * --tl <value>, --tv TALB=value - * --ty <value>, --tv TYER=value - * --tn <value>, --tv TRCK=value - * --tg <value>, --tv TCON=value - * (although some are not exactly same) - * </PRE> - */ - - public final boolean id3tag_set_albumart(final LameGlobalFlags gfp, - final byte[] image, final int size) { - MimeType mimetype = MimeType.MIMETYPE_NONE; - byte[] data = image; - LameInternalFlags gfc = gfp.internal_flags; - - /* make sure the image size is no larger than the maximum value */ - if (Lame.LAME_MAXALBUMART < size) { - return false; - } - /* determine MIME type from the actual image data */ - if (2 < size && data[0] == (byte) 0xFF && data[1] == (byte) 0xD8) { - mimetype = MimeType.MIMETYPE_JPEG; - } else if (4 < size && data[0] == 0x89 - && new String(data, 1, 3, ASCII).startsWith("PNG")) { - mimetype = MimeType.MIMETYPE_PNG; - } else if (4 < size && new String(data, 1, 3, ASCII).startsWith("GIF8")) { - mimetype = MimeType.MIMETYPE_GIF; - } else { - return false; - } - if (gfc.tag_spec.albumart != null) { - gfc.tag_spec.albumart = null; - gfc.tag_spec.albumart_size = 0; - gfc.tag_spec.albumart_mimetype = MimeType.MIMETYPE_NONE; - } - if (size < 1) { - return true; - } - gfc.tag_spec.albumart = new byte[size]; - if (gfc.tag_spec.albumart != null) { - System.arraycopy(image, 0, gfc.tag_spec.albumart, 0, size); - gfc.tag_spec.albumart_size = size; - gfc.tag_spec.albumart_mimetype = mimetype; - gfc.tag_spec.flags |= CHANGED_FLAG; - id3tag_add_v2(gfp); - } - return true; - } - - private int set_4_byte_value(final byte[] bytes, final int bytesPos, - int value) { - int i; - for (i = 3; i >= 0; --i) { - bytes[bytesPos + i] = (byte) (value & 0xff); - value >>= 8; - } - return bytesPos + 4; - } - - private int toID3v2TagId(final String s) { - int i, x = 0; - if (s == null) { - return 0; - } - for (i = 0; i < 4 && i < s.length(); ++i) { - char c = s.charAt(i); - int u = 0x0ff & c; - x <<= 8; - x |= u; - if (c < 'A' || 'Z' < c) { - if (c < '0' || '9' < c) { - return 0; - } - } - } - return x; - } - - private boolean isNumericString(final int frame_id) { - if (frame_id == ID_DATE || frame_id == ID_TIME || frame_id == ID_TPOS - || frame_id == ID_TRACK || frame_id == ID_YEAR) { - return true; - } - return false; - } - - private boolean isMultiFrame(final int frame_id) { - if (frame_id == ID_TXXX || frame_id == ID_WXXX - || frame_id == ID_COMMENT || frame_id == ID_SYLT - || frame_id == ID_APIC || frame_id == ID_GEOB - || frame_id == ID_PCNT || frame_id == ID_AENC - || frame_id == ID_LINK || frame_id == ID_ENCR - || frame_id == ID_GRID || frame_id == ID_PRIV) { - return true; - } - return false; - } - - private boolean hasUcs2ByteOrderMarker(final char bom) { - if (bom == 0xFFFE || bom == 0xFEFF) { - return true; - } - return false; - } - - private FrameDataNode findNode(final ID3TagSpec tag, final int frame_id, - final FrameDataNode last) { - FrameDataNode node = last != null ? last.nxt : tag.v2_head; - while (node != null) { - if (node.fid == frame_id) { - return node; - } - node = node.nxt; - } - return null; - } - - private void appendNode(final ID3TagSpec tag, final FrameDataNode node) { - if (tag.v2_tail == null || tag.v2_head == null) { - tag.v2_head = node; - tag.v2_tail = node; - } else { - tag.v2_tail.nxt = node; - tag.v2_tail = node; - } - } - - private String setLang(final String src) { - int i; - if (src == null || src.length() == 0) { - return "XXX"; - } else { - StringBuilder dst = new StringBuilder(); - if (src != null) { - dst.append(src.substring(0, 3)); - } - for (i = dst.length(); i < 3; ++i) { - dst.append(' '); - } - return dst.toString(); - } - } - - private boolean isSameLang(final String l1, final String l2) { - String d = setLang(l2); - for (int i = 0; i < 3; ++i) { - char a = Character.toLowerCase(l1.charAt(i)); - char b = Character.toLowerCase(d.charAt(i)); - if (a < ' ') - a = ' '; - if (b < ' ') - b = ' '; - if (a != b) { - return false; - } - } - return true; - } - - private boolean isSameDescriptor(final FrameDataNode node, final String dsc) { - if (node.dsc.enc == 1 && node.dsc.dim > 0) { - return false; - } - for (int i = 0; i < node.dsc.dim; ++i) { - if (null == dsc || node.dsc.l.charAt(i) != dsc.charAt(i)) { - return false; - } - } - return true; - } - - private boolean isSameDescriptorUcs2(final FrameDataNode node, - final String dsc) { - if (node.dsc.enc != 1 && node.dsc.dim > 0) { - return false; - } - for (int i = 0; i < node.dsc.dim; ++i) { - if (null == dsc || node.dsc.l.charAt(i) != dsc.charAt(i)) { - return false; - } - } - return true; - } - - private void id3v2_add_ucs2(final LameGlobalFlags gfp, final int frame_id, - final String lang, final String desc, final String text) { - LameInternalFlags gfc = gfp.internal_flags; - if (gfc != null) { - FrameDataNode node = findNode(gfc.tag_spec, frame_id, null); - if (isMultiFrame(frame_id)) { - while (node != null) { - if (isSameLang(node.lng, lang)) { - if (isSameDescriptorUcs2(node, desc)) { - break; - } - } - node = findNode(gfc.tag_spec, frame_id, node); - } - } - if (node == null) { - node = new FrameDataNode(); - appendNode(gfc.tag_spec, node); - } - node.fid = frame_id; - node.lng = setLang(lang); - node.dsc.l = desc; - node.dsc.dim = desc != null ? desc.length() : 0; - node.dsc.enc = 1; - node.txt.l = text; - node.txt.dim = text != null ? text.length() : 0; - node.txt.enc = 1; - gfc.tag_spec.flags |= (CHANGED_FLAG | ADD_V2_FLAG); - } - } - - private void id3v2_add_latin1(final LameGlobalFlags gfp, - final int frame_id, final String lang, final String desc, - final String text) { - LameInternalFlags gfc = gfp.internal_flags; - if (gfc != null) { - FrameDataNode node; - node = findNode(gfc.tag_spec, frame_id, null); - if (isMultiFrame(frame_id)) { - while (node != null) { - if (isSameLang(node.lng, lang)) { - if (isSameDescriptor(node, desc)) { - break; - } - } - node = findNode(gfc.tag_spec, frame_id, node); - } - } - if (node == null) { - node = new FrameDataNode(); - appendNode(gfc.tag_spec, node); - } - node.fid = frame_id; - node.lng = setLang(lang); - node.dsc.l = desc; - node.dsc.dim = desc != null ? desc.length() : 0; - node.dsc.enc = 0; - node.txt.l = text; - node.txt.dim = text != null ? text.length() : 0; - node.txt.enc = 0; - gfc.tag_spec.flags |= (CHANGED_FLAG | ADD_V2_FLAG); - } - } - - public final int id3tag_set_textinfo_ucs2(final LameGlobalFlags gfp, - final String id, final String text) { - long t_mask = FRAME_ID('T', (char) 0, (char) 0, (char) 0); - int frame_id = toID3v2TagId(id); - if (frame_id == 0) { - return -1; - } - if ((frame_id & t_mask) == t_mask) { - if (isNumericString(frame_id)) { - return -2; /* must be Latin-1 encoded */ - } - if (text == null) { - return 0; - } - if (!hasUcs2ByteOrderMarker(text.charAt(0))) { - return -3; /* BOM missing */ - } - if (gfp != null) { - id3v2_add_ucs2(gfp, frame_id, null, null, text); - return 0; - } - } - return -255; /* not supported by now */ - } - - private int id3tag_set_textinfo_latin1(final LameGlobalFlags gfp, - final String id, final String text) { - long t_mask = FRAME_ID('T', (char) 0, (char) 0, (char) 0); - int frame_id = toID3v2TagId(id); - if (frame_id == 0) { - return -1; - } - if ((frame_id & t_mask) == t_mask) { - if (text == null) { - return 0; - } - if (gfp != null) { - id3v2_add_latin1(gfp, frame_id, null, null, text); - return 0; - } - } - return -255; /* not supported by now */ - } - - public final int id3tag_set_comment(final LameGlobalFlags gfp, - final String lang, final String desc, final String text, - final int textPos) { - if (gfp != null) { - id3v2_add_latin1(gfp, ID_COMMENT, lang, desc, text); - return 0; - } - return -255; - } - - public final void id3tag_set_title(final LameGlobalFlags gfp, - final String title) { - LameInternalFlags gfc = gfp.internal_flags; - if (title != null && title.length() != 0) { - gfc.tag_spec.title = title; - gfc.tag_spec.flags |= CHANGED_FLAG; - copyV1ToV2(gfp, ID_TITLE, title); - } - } - - public final void id3tag_set_artist(final LameGlobalFlags gfp, - final String artist) { - LameInternalFlags gfc = gfp.internal_flags; - if (artist != null && artist.length() != 0) { - gfc.tag_spec.artist = artist; - gfc.tag_spec.flags |= CHANGED_FLAG; - copyV1ToV2(gfp, ID_ARTIST, artist); - } - } - - public final void id3tag_set_album(final LameGlobalFlags gfp, - final String album) { - LameInternalFlags gfc = gfp.internal_flags; - if (album != null && album.length() != 0) { - gfc.tag_spec.album = album; - gfc.tag_spec.flags |= CHANGED_FLAG; - copyV1ToV2(gfp, ID_ALBUM, album); - } - } - - public final void id3tag_set_year(final LameGlobalFlags gfp, - final String year) { - LameInternalFlags gfc = gfp.internal_flags; - if (year != null && year.length() != 0) { - int num = Integer.valueOf(year); - if (num < 0) { - num = 0; - } - /* limit a year to 4 digits so it fits in a version 1 tag */ - if (num > 9999) { - num = 9999; - } - if (num != 0) { - gfc.tag_spec.year = num; - gfc.tag_spec.flags |= CHANGED_FLAG; - } - copyV1ToV2(gfp, ID_YEAR, year); - } - } - - public final void id3tag_set_comment(final LameGlobalFlags gfp, - final String comment) { - LameInternalFlags gfc = gfp.internal_flags; - if (comment != null && comment.length() != 0) { - gfc.tag_spec.comment = comment; - gfc.tag_spec.flags |= CHANGED_FLAG; - { - int flags = gfc.tag_spec.flags; - id3v2_add_latin1(gfp, ID_COMMENT, "XXX", "", comment); - gfc.tag_spec.flags = flags; - } - } - } - - public final int id3tag_set_track(final LameGlobalFlags gfp, - final String track) { - LameInternalFlags gfc = gfp.internal_flags; - int ret = 0; - - if (track != null && track.length() != 0) { - int trackcount = track.indexOf('/'); - int num; - if (trackcount != -1) { - num = Integer.parseInt(track.substring(0, trackcount)); - } else { - num = Integer.parseInt(track); - } - /* check for valid ID3v1 track number range */ - if (num < 1 || num > 255) { - num = 0; - ret = -1; - /* track number out of ID3v1 range, ignored for ID3v1 */ - gfc.tag_spec.flags |= (CHANGED_FLAG | ADD_V2_FLAG); - } - if (num != 0) { - gfc.tag_spec.track_id3v1 = num; - gfc.tag_spec.flags |= CHANGED_FLAG; - } - /* Look for the total track count after a "/", same restrictions */ - if (trackcount != -1) { - gfc.tag_spec.flags |= (CHANGED_FLAG | ADD_V2_FLAG); - } - copyV1ToV2(gfp, ID_TRACK, track); - } - return ret; - } - - private int nextUpperAlpha(final String p, int pPos, final char x) { - for (char c = Character.toUpperCase(p.charAt(pPos)); pPos < p.length(); c = Character - .toUpperCase(p.charAt(pPos++))) { - if ('A' <= c && c <= 'Z') { - if (c != x) { - return pPos; - } - } - } - return pPos; - } - - private boolean sloppyCompared(final String p, final String q) { - int pPos = nextUpperAlpha(p, 0, (char) 0); - int qPos = nextUpperAlpha(q, 0, (char) 0); - char cp = pPos < p.length() ? Character.toUpperCase(p.charAt(pPos)) : 0; - char cq = Character.toUpperCase(q.charAt(qPos)); - while (cp == cq) { - if (cp == 0) { - return true; - } - if (p.charAt(1) == '.') { /* some abbrevation */ - while (qPos < q.length() && q.charAt(qPos++) != ' ') { - } - } - pPos = nextUpperAlpha(p, pPos, cp); - qPos = nextUpperAlpha(q, qPos, cq); - cp = pPos < p.length() ? Character.toUpperCase(p.charAt(pPos)) : 0; - cq = Character.toUpperCase(q.charAt(qPos)); - } - return false; - } - - private int sloppySearchGenre(final String genre) { - for (int i = 0; i < genre_names.length; ++i) { - if (sloppyCompared(genre, genre_names[i])) { - return i; - } - } - return genre_names.length; - } - - private int searchGenre(final String genre) { - for (int i = 0; i < genre_names.length; ++i) { - if (genre_names[i].equals(genre)) { - return i; - } - } - return genre_names.length; - } - - public final int id3tag_set_genre(final LameGlobalFlags gfp, String genre) { - LameInternalFlags gfc = gfp.internal_flags; - int ret = 0; - if (genre != null && genre.length() != 0) { - int num; - try { - num = Integer.parseInt(genre); - if ((num < 0) || (num >= genre_names.length)) { - return -1; - } - genre = genre_names[num]; - } catch (NumberFormatException e) { - /* is the input a string or a valid number? */ - num = searchGenre(genre); - if (num == genre_names.length) { - num = sloppySearchGenre(genre); - } - if (num == genre_names.length) { - num = GENRE_INDEX_OTHER; - ret = -2; - } else { - genre = genre_names[num]; - } - } - gfc.tag_spec.genre_id3v1 = num; - gfc.tag_spec.flags |= CHANGED_FLAG; - if (ret != 0) { - gfc.tag_spec.flags |= ADD_V2_FLAG; - } - copyV1ToV2(gfp, ID_GENRE, genre); - } - return ret; - } - - private int set_frame_custom(final byte[] frame, int framePos, - final char[] fieldvalue) { - if (fieldvalue != null && fieldvalue[0] != 0) { - int value = 5; - int length = new String(fieldvalue, value, fieldvalue.length - - value).length(); - frame[framePos++] = (byte) fieldvalue[0]; - frame[framePos++] = (byte) fieldvalue[1]; - frame[framePos++] = (byte) fieldvalue[2]; - frame[framePos++] = (byte) fieldvalue[3]; - framePos = set_4_byte_value(frame, value, (new String(fieldvalue, - value, fieldvalue.length - value).length() + 1)); - /* clear 2-byte header flags */ - frame[framePos++] = 0; - frame[framePos++] = 0; - /* clear 1 encoding descriptor byte to indicate ISO-8859-1 format */ - frame[framePos++] = 0; - while (length-- != 0) { - frame[framePos++] = (byte) fieldvalue[value++]; - } - } - return framePos; - } - - private int sizeOfNode(final FrameDataNode node) { - int n = 0; - if (node != null) { - n = 10; - /* header size */ - n += 1; - /* text encoding flag */ - switch (node.txt.enc) { - default: - case 0: - n += node.txt.dim; - break; - case 1: - n += node.txt.dim * 2; - break; - } - } - return n; - } - - private int sizeOfCommentNode(final FrameDataNode node) { - int n = 0; - if (node != null) { - n = 10; - /* header size */ - n += 1; - /* text encoding flag */ - n += 3; - /* language */ - switch (node.dsc.enc) { - default: - case 0: - n += 1 + node.dsc.dim; - break; - case 1: - n += 2 + node.dsc.dim * 2; - break; - } - switch (node.txt.enc) { - default: - case 0: - n += node.txt.dim; - break; - case 1: - n += node.txt.dim * 2; - break; - } - } - return n; - } - - private int writeChars(final byte[] frame, int framePos, final String str, - int strPos, int n) { - while (n-- != 0) { - frame[framePos++] = (byte) str.charAt(strPos++); - } - return framePos; - } - - private int writeUcs2s(final byte[] frame, int framePos, final String str, - int strPos, int n) { - while (n-- != 0) { - frame[framePos++] = (byte) (0xff & (str.charAt(strPos) >> 8)); - frame[framePos++] = (byte) (0xff & (str.charAt(strPos++))); - } - return framePos; - } - - private int set_frame_comment(final byte[] frame, int framePos, - final FrameDataNode node) { - int n = sizeOfCommentNode(node); - if (n > 10) { - framePos = set_4_byte_value(frame, framePos, ID_COMMENT); - framePos = set_4_byte_value(frame, framePos, (int) (n - 10)); - /* clear 2-byte header flags */ - frame[framePos++] = 0; - frame[framePos++] = 0; - /* encoding descriptor byte */ - frame[framePos++] = node.txt.enc == 1 ? (byte) 1 : (byte) 0; - /* 3 bytes language */ - frame[framePos++] = (byte) (node.lng.charAt(0)); - frame[framePos++] = (byte) node.lng.charAt(1); - frame[framePos++] = (byte) node.lng.charAt(2); - /* descriptor with zero byte(s) separator */ - if (node.dsc.enc != 1) { - framePos = writeChars(frame, framePos, node.dsc.l, 0, - node.dsc.dim); - frame[framePos++] = 0; - } else { - framePos = writeUcs2s(frame, framePos, node.dsc.l, 0, - node.dsc.dim); - frame[framePos++] = 0; - frame[framePos++] = 0; - } - /* comment full text */ - if (node.txt.enc != 1) { - framePos = writeChars(frame, framePos, node.txt.l, 0, - node.txt.dim); - } else { - framePos = writeUcs2s(frame, framePos, node.txt.l, 0, - node.txt.dim); - } - } - return framePos; - } - - private int set_frame_custom2(final byte[] frame, int framePos, - final FrameDataNode node) { - int n = sizeOfNode(node); - if (n > 10) { - framePos = set_4_byte_value(frame, framePos, node.fid); - framePos = set_4_byte_value(frame, framePos, (n - 10)); - /* clear 2-byte header flags */ - frame[framePos++] = 0; - frame[framePos++] = 0; - /* clear 1 encoding descriptor byte to indicate ISO-8859-1 format */ - frame[framePos++] = node.txt.enc == 1 ? (byte) 1 : (byte) 0; - if (node.txt.enc != 1) { - framePos = writeChars(frame, framePos, node.txt.l, 0, - node.txt.dim); - } else { - framePos = writeUcs2s(frame, framePos, node.txt.l, 0, - node.txt.dim); - } - } - return framePos; - } - - private int set_frame_apic(final byte[] frame, int framePos, - final char[] mimetype, final byte[] data, int size) { - /** - * <PRE> - * ID3v2.3 standard APIC frame: - * <Header for 'Attached picture', ID: "APIC"> - * Text encoding $xx - * MIME type <text string> $00 - * Picture type $xx - * Description <text string according to encoding> $00 (00) - * Picture data <binary data> - * </PRE> - */ - if (mimetype != null && data != null && size != 0) { - framePos = set_4_byte_value(frame, framePos, - FRAME_ID('A', 'P', 'I', 'C')); - framePos = set_4_byte_value(frame, framePos, - (4 + (mimetype.length) + size)); - /* clear 2-byte header flags */ - frame[framePos++] = 0; - frame[framePos++] = 0; - /* clear 1 encoding descriptor byte to indicate ISO-8859-1 format */ - frame[framePos++] = 0; - /* copy mime_type */ - int mimetypePos = 0; - while (mimetypePos < mimetype.length) { - frame[framePos++] = (byte) mimetype[mimetypePos++]; - } - frame[framePos++] = 0; - /* set picture type to 0 */ - frame[framePos++] = 0; - /* empty description field */ - frame[framePos++] = 0; - /* copy the image data */ - int dataPos = 0; - while (size-- != 0) { - frame[framePos++] = data[dataPos++]; - } - } - return framePos; - } - - public final int id3tag_set_fieldvalue(final LameGlobalFlags gfp, - final String fieldvalue) { - LameInternalFlags gfc = gfp.internal_flags; - if (fieldvalue != null && fieldvalue.length() != 0) { - int frame_id = toID3v2TagId(fieldvalue); - if (fieldvalue.length() < 5 || fieldvalue.charAt(4) != '=') { - return -1; - } - if (frame_id != 0) { - if (id3tag_set_textinfo_latin1(gfp, fieldvalue, - fieldvalue.substring(5)) != 0) { - gfc.tag_spec.values.add(fieldvalue); - gfc.tag_spec.num_values++; - } - } - gfc.tag_spec.flags |= CHANGED_FLAG; - } - id3tag_add_v2(gfp); - return 0; - } - - private static final String mime_jpeg = "image/jpeg"; - private static final String mime_png = "image/png"; - private static final String mime_gif = "image/gif"; - - public final int lame_get_id3v2_tag(final LameGlobalFlags gfp, - final byte[] buffer, final int size) { - LameInternalFlags gfc; - if (gfp == null) { - return 0; - } - gfc = gfp.internal_flags; - if (gfc == null) { - return 0; - } - if ((gfc.tag_spec.flags & V1_ONLY_FLAG) != 0) { - return 0; - } - { - /* calculate length of four fields which may not fit in verion 1 tag */ - int title_length = gfc.tag_spec.title != null ? gfc.tag_spec.title - .length() : 0; - int artist_length = gfc.tag_spec.artist != null ? gfc.tag_spec.artist - .length() : 0; - int album_length = gfc.tag_spec.album != null ? gfc.tag_spec.album - .length() : 0; - int comment_length = gfc.tag_spec.comment != null ? gfc.tag_spec.comment - .length() : 0; - /* write tag if explicitly requested or if fields overflow */ - if ((gfc.tag_spec.flags & (ADD_V2_FLAG | V2_ONLY_FLAG)) != 0 - || (title_length > 30) || (artist_length > 30) - || (album_length > 30) || (comment_length > 30) - || (gfc.tag_spec.track_id3v1 != 0 && (comment_length > 28))) { - int tag_size; - int p; - int adjusted_tag_size; - int i; - String albumart_mime = null; - - id3v2AddAudioDuration(gfp); - - /* calulate size of tag starting with 10-byte tag header */ - tag_size = 10; - for (i = 0; i < gfc.tag_spec.num_values; ++i) { - tag_size += 6 + gfc.tag_spec.values.get(i).length(); - } - if (gfc.tag_spec.albumart != null - && gfc.tag_spec.albumart_size != 0) { - switch (gfc.tag_spec.albumart_mimetype) { - case MIMETYPE_JPEG: - albumart_mime = mime_jpeg; - break; - case MIMETYPE_PNG: - albumart_mime = mime_png; - break; - case MIMETYPE_GIF: - albumart_mime = mime_gif; - break; - } - if (albumart_mime != null) { - tag_size += 10 + 4 + albumart_mime.length() - + gfc.tag_spec.albumart_size; - } - } - { - ID3TagSpec tag = gfc.tag_spec; - if (tag.v2_head != null) { - FrameDataNode node; - for (node = tag.v2_head; node != null; node = node.nxt) { - if (node.fid == ID_COMMENT) { - tag_size += sizeOfCommentNode(node); - } else { - tag_size += sizeOfNode(node); - } - } - } - } - if ((gfc.tag_spec.flags & PAD_V2_FLAG) != 0) { - /* add some bytes of padding */ - tag_size += gfc.tag_spec.padding_size; - } - if (size < tag_size) { - return tag_size; - } - if (buffer == null) { - return 0; - } - p = 0; - /* set tag header starting with file identifier */ - buffer[p++] = 'I'; - buffer[p++] = 'D'; - buffer[p++] = '3'; - /* set version number word */ - buffer[p++] = 3; - buffer[p++] = 0; - /* clear flags byte */ - buffer[p++] = 0; - /* calculate and set tag size = total size - header size */ - adjusted_tag_size = tag_size - 10; - /* - * encode adjusted size into four bytes where most significant - * bit is clear in each byte, for 28-bit total - */ - buffer[p++] = (byte) ((adjusted_tag_size >> 21) & 0x7f); - buffer[p++] = (byte) ((adjusted_tag_size >> 14) & 0x7f); - buffer[p++] = (byte) ((adjusted_tag_size >> 7) & 0x7f); - buffer[p++] = (byte) (adjusted_tag_size & 0x7f); - - /* - * NOTE: The remainder of the tag (frames and padding, if any) - * are not "unsynchronized" to prevent false MPEG audio headers - * from appearing in the bitstream. Why? Well, most players and - * utilities know how to skip the ID3 version 2 tag by now even - * if they don't read its contents, and it's actually very - * unlikely that such a false "sync" pattern would occur in just - * the simple text frames added here. - */ - - /* set each frame in tag */ - { - ID3TagSpec tag = gfc.tag_spec; - if (tag.v2_head != null) { - FrameDataNode node; - for (node = tag.v2_head; node != null; node = node.nxt) { - if (node.fid == ID_COMMENT) { - p = set_frame_comment(buffer, p, node); - } else { - p = set_frame_custom2(buffer, p, node); - } - } - } - } - for (i = 0; i < gfc.tag_spec.num_values; ++i) { - p = set_frame_custom(buffer, p, gfc.tag_spec.values.get(i) - .toCharArray()); - } - if (albumart_mime != null) { - p = set_frame_apic(buffer, p, albumart_mime.toCharArray(), - gfc.tag_spec.albumart, gfc.tag_spec.albumart_size); - } - /* clear any padding bytes */ - Arrays.fill(buffer, p, tag_size, (byte) 0); - return tag_size; - } - } - return 0; - } - - public final int id3tag_write_v2(final LameGlobalFlags gfp) { - LameInternalFlags gfc = gfp.internal_flags; - if ((gfc.tag_spec.flags & CHANGED_FLAG) != 0 - && 0 == (gfc.tag_spec.flags & V1_ONLY_FLAG)) { - byte[] tag = null; - int tag_size, n; - - n = lame_get_id3v2_tag(gfp, null, 0); - tag = new byte[n]; - tag_size = lame_get_id3v2_tag(gfp, tag, n); - if (tag_size > n) { - return -1; - } else { - /* write tag directly into bitstream at current position */ - for (int i = 0; i < tag_size; ++i) { - bits.add_dummy_byte(gfp, tag[i] & 0xff, 1); - } - } - return (int) tag_size; - /* ok, tag should not exceed 2GB */ - } - return 0; - } - - private int set_text_field(final byte[] field, int fieldPos, - final String text, int size, final int pad) { - int textPos = 0; - while (size-- != 0) { - if (text != null && textPos < text.length()) { - field[fieldPos++] = (byte) text.charAt(textPos++); - } else { - field[fieldPos++] = (byte) pad; - } - } - return fieldPos; - } - - public final int lame_get_id3v1_tag(final LameGlobalFlags gfp, - final byte[] buffer, final int size) { - int tag_size = 128; - LameInternalFlags gfc; - - if (gfp == null) { - return 0; - } - if (size < tag_size) { - return tag_size; - } - gfc = gfp.internal_flags; - if (gfc == null) { - return 0; - } - if (buffer == null) { - return 0; - } - if ((gfc.tag_spec.flags & CHANGED_FLAG) != 0 - && 0 == (gfc.tag_spec.flags & V2_ONLY_FLAG)) { - int p = 0; - int pad = (gfc.tag_spec.flags & SPACE_V1_FLAG) != 0 ? ' ' : 0; - String year; - - /* set tag identifier */ - buffer[p++] = 'T'; - buffer[p++] = 'A'; - buffer[p++] = 'G'; - /* set each field in tag */ - p = set_text_field(buffer, p, gfc.tag_spec.title, 30, pad); - p = set_text_field(buffer, p, gfc.tag_spec.artist, 30, pad); - p = set_text_field(buffer, p, gfc.tag_spec.album, 30, pad); - year = String.format("%d", Integer.valueOf(gfc.tag_spec.year)); - p = set_text_field(buffer, p, gfc.tag_spec.year != 0 ? year : null, - 4, pad); - /* limit comment field to 28 bytes if a track is specified */ - p = set_text_field(buffer, p, gfc.tag_spec.comment, - gfc.tag_spec.track_id3v1 != 0 ? 28 : 30, pad); - if (gfc.tag_spec.track_id3v1 != 0) { - /* clear the next byte to indicate a version 1.1 tag */ - buffer[p++] = 0; - buffer[p++] = (byte) gfc.tag_spec.track_id3v1; - } - buffer[p++] = (byte) gfc.tag_spec.genre_id3v1; - return tag_size; - } - return 0; - } - - public final int id3tag_write_v1(final LameGlobalFlags gfp) { - byte tag[] = new byte[128]; - - int m = tag.length; - int n = lame_get_id3v1_tag(gfp, tag, m); - if (n > m) { - return 0; - } - /* write tag directly into bitstream at current position */ - for (int i = 0; i < n; ++i) { - bits.add_dummy_byte(gfp, tag[i] & 0xff, 1); - } - return (int) n; /* ok, tag has fixed size of 128 bytes, well below 2GB */ - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ID3TagSpec.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ID3TagSpec.java deleted file mode 100644 index 5790ebdf0..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ID3TagSpec.java +++ /dev/null @@ -1,23 +0,0 @@ -package mp3; - -import java.util.ArrayList; - -import mp3.ID3Tag.MimeType; - -public final class ID3TagSpec { - int flags; - int year; - String title; - String artist; - String album; - String comment; - int track_id3v1; - int genre_id3v1; - byte[] albumart; - int albumart_size; - int padding_size; - MimeType albumart_mimetype; - ArrayList<String> values = new ArrayList<String>(); - int num_values; - FrameDataNode v2_head, v2_tail; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/IIISideInfo.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/IIISideInfo.java deleted file mode 100644 index affbdae81..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/IIISideInfo.java +++ /dev/null @@ -1,18 +0,0 @@ -package mp3; - -public class IIISideInfo { - public IIISideInfo() { - for (int gr = 0; gr < 2; gr++) { - for (int ch = 0; ch < 2; ch++) { - tt[gr][ch] = new GrInfo(); - } - } - } - - GrInfo tt[][] = new GrInfo[2][2]; - int main_data_begin; - int private_bits; - int resvDrain_pre; - int resvDrain_post; - int scfsi[][] = new int[2][4]; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/III_psy_ratio.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/III_psy_ratio.java deleted file mode 100644 index 729c557b4..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/III_psy_ratio.java +++ /dev/null @@ -1,6 +0,0 @@ -package mp3; - -public final class III_psy_ratio { - III_psy_xmin thm = new III_psy_xmin(); - III_psy_xmin en = new III_psy_xmin(); -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/III_psy_xmin.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/III_psy_xmin.java deleted file mode 100644 index 02318f1fe..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/III_psy_xmin.java +++ /dev/null @@ -1,15 +0,0 @@ -package mp3; - -public final class III_psy_xmin { - float[] l = new float[Encoder.SBMAX_l]; - float[][] s = new float[Encoder.SBMAX_s][3]; - - public void assign(III_psy_xmin iii_psy_xmin) { - System.arraycopy(iii_psy_xmin.l, 0, l, 0, Encoder.SBMAX_l); - for (int i = 0; i < Encoder.SBMAX_s; i++) { - for (int j = 0; j < 3; j++) { - s[i][j] = iii_psy_xmin.s[i][j]; - } - } - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/IIterationLoop.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/IIterationLoop.java deleted file mode 100644 index d7e294c9a..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/IIterationLoop.java +++ /dev/null @@ -1,12 +0,0 @@ -package mp3; - -/** - * Global Type Definitions - * - * @author Ken - * - */ -public interface IIterationLoop { - void iteration_loop(final LameGlobalFlags gfp, float pe[][], - float ms_ratio[], III_psy_ratio ratio[][]); -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Inf.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Inf.java deleted file mode 100644 index 98a47b690..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Inf.java +++ /dev/null @@ -1,10 +0,0 @@ -package mp3; - -public final class Inf { - String l; - int dim; - /** - * 0:Latin-1, 1:UCS-2, 2:RAW - */ - int enc; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/L3Side.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/L3Side.java deleted file mode 100644 index de1485621..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/L3Side.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Layer 3 side include file - * - * Copyright (c) 1999 Mark Taylor - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -package mp3; - -public class L3Side { - - /** - * max scalefactor band, max(SBMAX_l, SBMAX_s*3, (SBMAX_s-3)*3+8) - */ - public static final int SFBMAX = (Encoder.SBMAX_s * 3); - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Lame.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Lame.java deleted file mode 100644 index 78e5517f9..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Lame.java +++ /dev/null @@ -1,2373 +0,0 @@ -/* - * LAME MP3 encoding engine - * - * Copyright (c) 1999-2000 Mark Taylor - * Copyright (c) 2000-2005 Takehiro Tominaga - * Copyright (c) 2000-2005 Robert Hegemann - * Copyright (c) 2000-2005 Gabriel Bouvigne - * Copyright (c) 2000-2004 Alexander Leidinger - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: Lame.java,v 1.38 2011/05/24 21:15:54 kenchis Exp $ */ - -package mp3; - -import mpg.MPGLib; - -public class Lame { - GainAnalysis ga; - BitStream bs; - Presets p; - QuantizePVT qupvt; - Quantize qu; - PsyModel psy = new PsyModel(); - VBRTag vbr; - Version ver; - ID3Tag id3; - MPGLib mpglib; - public Encoder enc = new Encoder(); - - public final void setModules(GainAnalysis ga, BitStream bs, Presets p, - QuantizePVT qupvt, Quantize qu, VBRTag vbr, Version ver, - ID3Tag id3, MPGLib mpglib) { - this.ga = ga; - this.bs = bs; - this.p = p; - this.qupvt = qupvt; - this.qu = qu; - this.vbr = vbr; - this.ver = ver; - this.id3 = id3; - this.mpglib = mpglib; - this.enc.setModules(bs, psy, qupvt, vbr); - } - - public static final long LAME_ID = 0xFFF88E3B; - - /* presets */ - /* values from 8 to 320 should be reserved for abr bitrates */ - /* for abr I'd suggest to directly use the targeted bitrate as a value */ - - public static final int V9 = 410; - public static final int V8 = 420; - public static final int V7 = 430; - public static final int V6 = 440; - public static final int V5 = 450; - public static final int V4 = 460; - public static final int V3 = 470; - public static final int V2 = 480; - public static final int V1 = 490; - public static final int V0 = 500; - - /* still there for compatibility */ - - public static final int R3MIX = 1000; - public static final int STANDARD = 1001; - public static final int EXTREME = 1002; - public static final int INSANE = 1003; - public static final int STANDARD_FAST = 1004; - public static final int EXTREME_FAST = 1005; - public static final int MEDIUM = 1006; - public static final int MEDIUM_FAST = 1007; - - /** - * maximum size of albumart image (128KB), which affects LAME_MAXMP3BUFFER - * as well since lame_encode_buffer() also returns ID3v2 tag data - */ - static final int LAME_MAXALBUMART = (128 * 1024); - - /** - * maximum size of mp3buffer needed if you encode at most 1152 samples for - * each call to lame_encode_buffer. see lame_encode_buffer() below - * (LAME_MAXMP3BUFFER is now obsolete) - */ - public static final int LAME_MAXMP3BUFFER = (16384 + LAME_MAXALBUMART); - - private static final int LAME_DEFAULT_QUALITY = 3; - - private float filter_coef(final float x) { - if (x > 1.0) - return 0.0f; - if (x <= 0.0) - return 1.0f; - - return (float) Math.cos(Math.PI / 2 * x); - } - - private void lame_init_params_ppflt(final LameGlobalFlags gfp) { - final LameInternalFlags gfc = gfp.internal_flags; - /***************************************************************/ - /* compute info needed for polyphase filter (filter type==0, default) */ - /***************************************************************/ - - int lowpass_band = 32; - int highpass_band = -1; - - if (gfc.lowpass1 > 0) { - int minband = 999; - for (int band = 0; band <= 31; band++) { - float freq = (float) (band / 31.0); - /* this band and above will be zeroed: */ - if (freq >= gfc.lowpass2) { - lowpass_band = Math.min(lowpass_band, band); - } - if (gfc.lowpass1 < freq && freq < gfc.lowpass2) { - minband = Math.min(minband, band); - } - } - - /* - * compute the *actual* transition band implemented by the polyphase - * filter - */ - if (minband == 999) { - gfc.lowpass1 = (lowpass_band - .75f) / 31.0f; - } else { - gfc.lowpass1 = (minband - .75f) / 31.0f; - } - gfc.lowpass2 = lowpass_band / 31.0f; - } - - /* - * make sure highpass filter is within 90% of what the effective - * highpass frequency will be - */ - if (gfc.highpass2 > 0) { - if (gfc.highpass2 < .9 * (.75 / 31.0)) { - gfc.highpass1 = 0; - gfc.highpass2 = 0; - System.err.println("Warning: highpass filter disabled. " - + "highpass frequency too small\n"); - } - } - - if (gfc.highpass2 > 0) { - int maxband = -1; - for (int band = 0; band <= 31; band++) { - float freq = band / 31.0f; - /* this band and below will be zereod */ - if (freq <= gfc.highpass1) { - highpass_band = Math.max(highpass_band, band); - } - if (gfc.highpass1 < freq && freq < gfc.highpass2) { - maxband = Math.max(maxband, band); - } - } - /* - * compute the *actual* transition band implemented by the polyphase - * filter - */ - gfc.highpass1 = highpass_band / 31.0f; - if (maxband == -1) { - gfc.highpass2 = (highpass_band + .75f) / 31.0f; - } else { - gfc.highpass2 = (maxband + .75f) / 31.0f; - } - } - - for (int band = 0; band < 32; band++) { - double fc1, fc2; - float freq = band / 31.0f; - if (gfc.highpass2 > gfc.highpass1) { - fc1 = filter_coef((gfc.highpass2 - freq) - / (gfc.highpass2 - gfc.highpass1 + 1e-20f)); - } else { - fc1 = 1.0; - } - if (gfc.lowpass2 > gfc.lowpass1) { - fc2 = filter_coef((freq - gfc.lowpass1) - / (gfc.lowpass2 - gfc.lowpass1 + 1e-20f)); - } else { - fc2 = 1.0; - } - gfc.amp_filter[band] = (float) (fc1 * fc2); - } - } - - protected static class LowPassHighPass { - double lowerlimit; - } - - private static class BandPass { - public BandPass(int bitrate, int lPass) { - lowpass = lPass; - } - - public int lowpass; - } - - private void optimum_bandwidth(final LowPassHighPass lh, final int bitrate) { - /** - * <PRE> - * Input: - * bitrate total bitrate in kbps - * - * Output: - * lowerlimit: best lowpass frequency limit for input filter in Hz - * upperlimit: best highpass frequency limit for input filter in Hz - * </PRE> - */ - final BandPass freq_map[] = new BandPass[] { new BandPass(8, 2000), - new BandPass(16, 3700), new BandPass(24, 3900), - new BandPass(32, 5500), new BandPass(40, 7000), - new BandPass(48, 7500), new BandPass(56, 10000), - new BandPass(64, 11000), new BandPass(80, 13500), - new BandPass(96, 15100), new BandPass(112, 15600), - new BandPass(128, 17000), new BandPass(160, 17500), - new BandPass(192, 18600), new BandPass(224, 19400), - new BandPass(256, 19700), new BandPass(320, 20500) }; - - int table_index = nearestBitrateFullIndex(bitrate); - lh.lowerlimit = freq_map[table_index].lowpass; - } - - private int optimum_samplefreq(final int lowpassfreq, - final int input_samplefreq) { - /* - * Rules: - * - * - if possible, sfb21 should NOT be used - */ - int suggested_samplefreq = 44100; - - if (input_samplefreq >= 48000) - suggested_samplefreq = 48000; - else if (input_samplefreq >= 44100) - suggested_samplefreq = 44100; - else if (input_samplefreq >= 32000) - suggested_samplefreq = 32000; - else if (input_samplefreq >= 24000) - suggested_samplefreq = 24000; - else if (input_samplefreq >= 22050) - suggested_samplefreq = 22050; - else if (input_samplefreq >= 16000) - suggested_samplefreq = 16000; - else if (input_samplefreq >= 12000) - suggested_samplefreq = 12000; - else if (input_samplefreq >= 11025) - suggested_samplefreq = 11025; - else if (input_samplefreq >= 8000) - suggested_samplefreq = 8000; - - if (lowpassfreq == -1) - return suggested_samplefreq; - - if (lowpassfreq <= 15960) - suggested_samplefreq = 44100; - if (lowpassfreq <= 15250) - suggested_samplefreq = 32000; - if (lowpassfreq <= 11220) - suggested_samplefreq = 24000; - if (lowpassfreq <= 9970) - suggested_samplefreq = 22050; - if (lowpassfreq <= 7230) - suggested_samplefreq = 16000; - if (lowpassfreq <= 5420) - suggested_samplefreq = 12000; - if (lowpassfreq <= 4510) - suggested_samplefreq = 11025; - if (lowpassfreq <= 3970) - suggested_samplefreq = 8000; - - if (input_samplefreq < suggested_samplefreq) { - /* - * choose a valid MPEG sample frequency above the input sample - * frequency to avoid SFB21/12 bitrate bloat rh 061115 - */ - if (input_samplefreq > 44100) { - return 48000; - } - if (input_samplefreq > 32000) { - return 44100; - } - if (input_samplefreq > 24000) { - return 32000; - } - if (input_samplefreq > 22050) { - return 24000; - } - if (input_samplefreq > 16000) { - return 22050; - } - if (input_samplefreq > 12000) { - return 16000; - } - if (input_samplefreq > 11025) { - return 12000; - } - if (input_samplefreq > 8000) { - return 11025; - } - return 8000; - } - return suggested_samplefreq; - } - - /** - * set internal feature flags. USER should not access these since some - * combinations will produce strange results - */ - private void lame_init_qval(final LameGlobalFlags gfp) { - final LameInternalFlags gfc = gfp.internal_flags; - - switch (gfp.quality) { - default: - case 9: /* no psymodel, no noise shaping */ - gfc.psymodel = 0; - gfc.noise_shaping = 0; - gfc.noise_shaping_amp = 0; - gfc.noise_shaping_stop = 0; - gfc.use_best_huffman = 0; - gfc.full_outer_loop = 0; - break; - - case 8: - gfp.quality = 7; - //$FALL-THROUGH$ - case 7: - /* - * use psymodel (for short block and m/s switching), but no noise - * shapping - */ - gfc.psymodel = 1; - gfc.noise_shaping = 0; - gfc.noise_shaping_amp = 0; - gfc.noise_shaping_stop = 0; - gfc.use_best_huffman = 0; - gfc.full_outer_loop = 0; - break; - - case 6: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - gfc.noise_shaping_amp = 0; - gfc.noise_shaping_stop = 0; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 0; - gfc.full_outer_loop = 0; - break; - - case 5: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - gfc.noise_shaping_amp = 0; - gfc.noise_shaping_stop = 0; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 0; - gfc.full_outer_loop = 0; - break; - - case 4: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - gfc.noise_shaping_amp = 0; - gfc.noise_shaping_stop = 0; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 1; - gfc.full_outer_loop = 0; - break; - - case 3: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - gfc.noise_shaping_amp = 1; - gfc.noise_shaping_stop = 1; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 1; - gfc.full_outer_loop = 0; - break; - - case 2: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - if (gfc.substep_shaping == 0) - gfc.substep_shaping = 2; - gfc.noise_shaping_amp = 1; - gfc.noise_shaping_stop = 1; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 1; /* inner loop */ - gfc.full_outer_loop = 0; - break; - - case 1: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - if (gfc.substep_shaping == 0) - gfc.substep_shaping = 2; - gfc.noise_shaping_amp = 2; - gfc.noise_shaping_stop = 1; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 1; - gfc.full_outer_loop = 0; - break; - - case 0: - gfc.psymodel = 1; - if (gfc.noise_shaping == 0) - gfc.noise_shaping = 1; - if (gfc.substep_shaping == 0) - gfc.substep_shaping = 2; - gfc.noise_shaping_amp = 2; - gfc.noise_shaping_stop = 1; - if (gfc.subblock_gain == -1) - gfc.subblock_gain = 1; - gfc.use_best_huffman = 1; - /* - * type 2 disabled because of it slowness, in favor of full outer - * loop search - */ - gfc.full_outer_loop = 0; - /* - * full outer loop search disabled because of audible distortions it - * may generate rh 060629 - */ - break; - } - - } - - private double linear_int(final double a, final double b, final double m) { - return a + m * (b - a); - } - - /** - * @param bRate - * legal rates from 8 to 320 - */ - private int FindNearestBitrate(final int bRate, int version, - final int samplerate) { - /* MPEG-1 or MPEG-2 LSF */ - if (samplerate < 16000) - version = 2; - - int bitrate = Tables.bitrate_table[version][1]; - - for (int i = 2; i <= 14; i++) { - if (Tables.bitrate_table[version][i] > 0) { - if (Math.abs(Tables.bitrate_table[version][i] - bRate) < Math - .abs(bitrate - bRate)) - bitrate = Tables.bitrate_table[version][i]; - } - } - return bitrate; - } - - /** - * Used to find table index when we need bitrate-based values determined - * using tables - * - * bitrate in kbps - * - * Gabriel Bouvigne 2002-11-03 - */ - public final int nearestBitrateFullIndex(final int bitrate) { - /* borrowed from DM abr presets */ - - final int full_bitrate_table[] = { 8, 16, 24, 32, 40, 48, 56, 64, 80, - 96, 112, 128, 160, 192, 224, 256, 320 }; - - int lower_range = 0, lower_range_kbps = 0, upper_range = 0, upper_range_kbps = 0; - - /* We assume specified bitrate will be 320kbps */ - upper_range_kbps = full_bitrate_table[16]; - upper_range = 16; - lower_range_kbps = full_bitrate_table[16]; - lower_range = 16; - - /* - * Determine which significant bitrates the value specified falls - * between, if loop ends without breaking then we were correct above - * that the value was 320 - */ - for (int b = 0; b < 16; b++) { - if ((Math.max(bitrate, full_bitrate_table[b + 1])) != bitrate) { - upper_range_kbps = full_bitrate_table[b + 1]; - upper_range = b + 1; - lower_range_kbps = full_bitrate_table[b]; - lower_range = (b); - break; /* We found upper range */ - } - } - - /* Determine which range the value specified is closer to */ - if ((upper_range_kbps - bitrate) > (bitrate - lower_range_kbps)) { - return lower_range; - } - return upper_range; - } - - /** - * map frequency to a valid MP3 sample frequency - * - * Robert Hegemann 2000-07-01 - */ - private int map2MP3Frequency(final int freq) { - if (freq <= 8000) - return 8000; - if (freq <= 11025) - return 11025; - if (freq <= 12000) - return 12000; - if (freq <= 16000) - return 16000; - if (freq <= 22050) - return 22050; - if (freq <= 24000) - return 24000; - if (freq <= 32000) - return 32000; - if (freq <= 44100) - return 44100; - - return 48000; - } - - /** - * convert samp freq in Hz to index - */ - private int SmpFrqIndex(final int sample_freq, final LameGlobalFlags gpf) { - switch (sample_freq) { - case 44100: - gpf.version = 1; - return 0; - case 48000: - gpf.version = 1; - return 1; - case 32000: - gpf.version = 1; - return 2; - case 22050: - gpf.version = 0; - return 0; - case 24000: - gpf.version = 0; - return 1; - case 16000: - gpf.version = 0; - return 2; - case 11025: - gpf.version = 0; - return 0; - case 12000: - gpf.version = 0; - return 1; - case 8000: - gpf.version = 0; - return 2; - default: - gpf.version = 0; - return -1; - } - } - - /** - * @param bRate - * legal rates from 32 to 448 kbps - * @param version - * MPEG-1 or MPEG-2/2.5 LSF - */ - public final int BitrateIndex(final int bRate, int version, - final int samplerate) { - /* convert bitrate in kbps to index */ - if (samplerate < 16000) - version = 2; - for (int i = 0; i <= 14; i++) { - if (Tables.bitrate_table[version][i] > 0) { - if (Tables.bitrate_table[version][i] == bRate) { - return i; - } - } - } - return -1; - } - - /** - * Resampling via FIR filter, blackman window. - */ - private float blackman(float x, final float fcn, final int l) { - /* - * This algorithm from: SIGNAL PROCESSING ALGORITHMS IN FORTRAN AND C - * S.D. Stearns and R.A. David, Prentice-Hall, 1992 - */ - float wcn = (float) (Math.PI * fcn); - - x /= l; - if (x < 0) - x = 0; - if (x > 1) - x = 1; - float x2 = x - .5f; - - float bkwn = 0.42f - 0.5f * (float) Math.cos(2 * x * Math.PI) + 0.08f - * (float) Math.cos(4 * x * Math.PI); - if (Math.abs(x2) < 1e-9) - return (float) (wcn / Math.PI); - else - return (float) (bkwn * Math.sin(l * wcn * x2) / (Math.PI * l * x2)); - } - - /** - * Greatest common divisor. - * - * Joint work of Euclid and M. Hendry - */ - private int gcd(final int i, final int j) { - return j != 0 ? gcd(j, i % j) : i; - } - - protected static class NumUsed { - int num_used; - } - - private int fill_buffer_resample(final LameGlobalFlags gfp, - final float[] outbuf, final int outbufPos, final int desired_len, - final float[] inbuf, final int in_bufferPos, final int len, - final NumUsed num_used, final int ch) { - final LameInternalFlags gfc = gfp.internal_flags; - int i, j = 0, k; - /* number of convolution functions to pre-compute */ - int bpc = gfp.out_samplerate - / gcd(gfp.out_samplerate, gfp.in_samplerate); - if (bpc > LameInternalFlags.BPC) - bpc = LameInternalFlags.BPC; - - float intratio = (Math.abs(gfc.resample_ratio - - Math.floor(.5 + gfc.resample_ratio)) < .0001) ? 1 : 0; - float fcn = 1.00f / (float) gfc.resample_ratio; - if (fcn > 1.00) - fcn = 1.00f; - int filter_l = 31; - if (0 == filter_l % 2) - --filter_l; /* must be odd */ - filter_l += intratio; /* unless resample_ratio=int, it must be even */ - - int BLACKSIZE = filter_l + 1; /* size of data needed for FIR */ - - if (gfc.fill_buffer_resample_init == 0) { - gfc.inbuf_old[0] = new float[BLACKSIZE]; - gfc.inbuf_old[1] = new float[BLACKSIZE]; - for (i = 0; i <= 2 * bpc; ++i) - gfc.blackfilt[i] = new float[BLACKSIZE]; - - gfc.itime[0] = 0; - gfc.itime[1] = 0; - - /* precompute blackman filter coefficients */ - for (j = 0; j <= 2 * bpc; j++) { - float sum = 0.f; - float offset = (j - bpc) / (2.f * bpc); - for (i = 0; i <= filter_l; i++) - sum += gfc.blackfilt[j][i] = blackman(i - offset, fcn, - filter_l); - for (i = 0; i <= filter_l; i++) - gfc.blackfilt[j][i] /= sum; - } - gfc.fill_buffer_resample_init = 1; - } - - float[] inbuf_old = gfc.inbuf_old[ch]; - - /* time of j'th element in inbuf = itime + j/ifreq; */ - /* time of k'th element in outbuf = j/ofreq */ - for (k = 0; k < desired_len; k++) { - double time0; - int joff; - - time0 = k * gfc.resample_ratio; /* time of k'th output sample */ - j = (int) Math.floor(time0 - gfc.itime[ch]); - - /* check if we need more input data */ - if ((filter_l + j - filter_l / 2) >= len) - break; - - /* blackman filter. by default, window centered at j+.5(filter_l%2) */ - /* but we want a window centered at time0. */ - float offset = (float) (time0 - gfc.itime[ch] - (j + .5 * (filter_l % 2))); - assert (Math.abs(offset) <= .501); - - /* find the closest precomputed window for this offset: */ - joff = (int) Math.floor((offset * 2 * bpc) + bpc + .5); - - float xvalue = 0.f; - for (i = 0; i <= filter_l; ++i) { - int j2 = i + j - filter_l / 2; - float y; - assert (j2 < len); - assert (j2 + BLACKSIZE >= 0); - y = (j2 < 0) ? inbuf_old[BLACKSIZE + j2] : inbuf[in_bufferPos - + j2]; - xvalue += y * gfc.blackfilt[joff][i]; - } - outbuf[outbufPos + k] = xvalue; - } - - /* k = number of samples added to outbuf */ - /* last k sample used data from [j-filter_l/2,j+filter_l-filter_l/2] */ - - /* how many samples of input data were used: */ - num_used.num_used = Math.min(len, filter_l + j - filter_l / 2); - - /* - * adjust our input time counter. Incriment by the number of samples - * used, then normalize so that next output sample is at time 0, next - * input buffer is at time itime[ch] - */ - gfc.itime[ch] += num_used.num_used - k * gfc.resample_ratio; - - /* save the last BLACKSIZE samples into the inbuf_old buffer */ - if (num_used.num_used >= BLACKSIZE) { - for (i = 0; i < BLACKSIZE; i++) - inbuf_old[i] = inbuf[in_bufferPos + num_used.num_used + i - - BLACKSIZE]; - } else { - /* shift in num_used.num_used samples into inbuf_old */ - int n_shift = BLACKSIZE - num_used.num_used; /* - * number of samples to - * shift - */ - - /* - * shift n_shift samples by num_used.num_used, to make room for the - * num_used new samples - */ - for (i = 0; i < n_shift; ++i) - inbuf_old[i] = inbuf_old[i + num_used.num_used]; - - /* shift in the num_used.num_used samples */ - for (j = 0; i < BLACKSIZE; ++i, ++j) - inbuf_old[i] = inbuf[in_bufferPos + j]; - - assert (j == num_used.num_used); - } - return k; /* return the number samples created at the new samplerate */ - } - - /* - * copy in new samples from in_buffer into mfbuf, with resampling if - * necessary. n_in = number of samples from the input buffer that were used. - * n_out = number of samples copied into mfbuf - */ - - private void fill_buffer(final LameGlobalFlags gfp, float mfbuf[][], - final float in_buffer[][], final int in_bufferPos, - final int nsamples, final InOut io) { - final LameInternalFlags gfc = gfp.internal_flags; - - /* copy in new samples into mfbuf, with resampling if necessary */ - if ((gfc.resample_ratio < .9999) || (gfc.resample_ratio > 1.0001)) { - for (int ch = 0; ch < gfc.channels_out; ch++) { - NumUsed numUsed = new NumUsed(); - io.n_out = fill_buffer_resample(gfp, mfbuf[ch], gfc.mf_size, - gfp.framesize, in_buffer[ch], in_bufferPos, nsamples, - numUsed, ch); - io.n_in = numUsed.num_used; - } - } else { - io.n_out = Math.min(gfp.framesize, nsamples); - io.n_in = io.n_out; - for (int i = 0; i < io.n_out; ++i) { - mfbuf[0][gfc.mf_size + i] = in_buffer[0][in_bufferPos + i]; - if (gfc.channels_out == 2) - mfbuf[1][gfc.mf_size + i] = in_buffer[1][in_bufferPos + i]; - } - } - } - - /******************************************************************** - * initialize internal params based on data in gf (globalflags struct filled - * in by calling program) - * - * OUTLINE: - * - * We first have some complex code to determine bitrate, output samplerate - * and mode. It is complicated by the fact that we allow the user to set - * some or all of these parameters, and need to determine best possible - * values for the rest of them: - * - * 1. set some CPU related flags 2. check if we are mono.mono, stereo.mono - * or stereo.stereo 3. compute bitrate and output samplerate: user may have - * set compression ratio user may have set a bitrate user may have set a - * output samplerate 4. set some options which depend on output samplerate - * 5. compute the actual compression ratio 6. set mode based on compression - * ratio - * - * The remaining code is much simpler - it just sets options based on the - * mode & compression ratio: - * - * set allow_diff_short based on mode select lowpass filter based on - * compression ratio & mode set the bitrate index, and min/max bitrates for - * VBR modes disable VBR tag if it is not appropriate initialize the - * bitstream initialize scalefac_band data set sideinfo_len (based on - * channels, CRC, out_samplerate) write an id3v2 tag into the bitstream - * write VBR tag into the bitstream set mpeg1/2 flag estimate the number of - * frames (based on a lot of data) - * - * now we set more flags: nspsytune: see code VBR modes see code CBR/ABR see - * code - * - * Finally, we set the algorithm flags based on the gfp.quality value - * lame_init_qval(gfp); - * - ********************************************************************/ - public final int lame_init_params(final LameGlobalFlags gfp) { - LameInternalFlags gfc = gfp.internal_flags; - - gfc.Class_ID = 0; - if (gfc.ATH == null) - gfc.ATH = new ATH(); - if (gfc.PSY == null) - gfc.PSY = new PSY(); - if (gfc.rgdata == null) - gfc.rgdata = new ReplayGain(); - - gfc.channels_in = gfp.num_channels; - if (gfc.channels_in == 1) - gfp.mode = MPEGMode.MONO; - gfc.channels_out = (gfp.mode == MPEGMode.MONO) ? 1 : 2; - gfc.mode_ext = Encoder.MPG_MD_MS_LR; - if (gfp.mode == MPEGMode.MONO) - gfp.force_ms = false; - /* - * don't allow forced mid/side stereo for mono output - */ - - if (gfp.VBR == VbrMode.vbr_off && gfp.VBR_mean_bitrate_kbps != 128 - && gfp.brate == 0) - gfp.brate = gfp.VBR_mean_bitrate_kbps; - - if (gfp.VBR == VbrMode.vbr_off || gfp.VBR == VbrMode.vbr_mtrh - || gfp.VBR == VbrMode.vbr_mt) { - /* these modes can handle free format condition */ - } else { - gfp.free_format = false; /* mode can't be mixed with free format */ - } - - if (gfp.VBR == VbrMode.vbr_off && gfp.brate == 0) { - /* no bitrate or compression ratio specified, use 11.025 */ - if (BitStream.EQ(gfp.compression_ratio, 0)) - gfp.compression_ratio = 11.025f; - /* - * rate to compress a CD down to exactly 128000 bps - */ - } - - /* find bitrate if user specify a compression ratio */ - if (gfp.VBR == VbrMode.vbr_off && gfp.compression_ratio > 0) { - - if (gfp.out_samplerate == 0) - gfp.out_samplerate = map2MP3Frequency((int) (0.97 * gfp.in_samplerate)); - /* - * round up with a margin of 3 % - */ - - /* - * choose a bitrate for the output samplerate which achieves - * specified compression ratio - */ - gfp.brate = (int) (gfp.out_samplerate * 16 * gfc.channels_out / (1.e3f * gfp.compression_ratio)); - - /* we need the version for the bitrate table look up */ - gfc.samplerate_index = SmpFrqIndex(gfp.out_samplerate, gfp); - - if (!gfp.free_format) /* - * for non Free Format find the nearest allowed - * bitrate - */ - gfp.brate = FindNearestBitrate(gfp.brate, gfp.version, - gfp.out_samplerate); - } - - if (gfp.out_samplerate != 0) { - if (gfp.out_samplerate < 16000) { - gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps, - 8); - gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps, - 64); - } else if (gfp.out_samplerate < 32000) { - gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps, - 8); - gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps, - 160); - } else { - gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps, - 32); - gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps, - 320); - } - } - - /****************************************************************/ - /* if a filter has not been enabled, see if we should add one: */ - /****************************************************************/ - if (gfp.lowpassfreq == 0) { - double lowpass = 16000; - - switch (gfp.VBR) { - case vbr_off: { - LowPassHighPass lh = new LowPassHighPass(); - optimum_bandwidth(lh, gfp.brate); - lowpass = lh.lowerlimit; - break; - } - case vbr_abr: { - LowPassHighPass lh = new LowPassHighPass(); - optimum_bandwidth(lh, gfp.VBR_mean_bitrate_kbps); - lowpass = lh.lowerlimit; - break; - } - case vbr_rh: { - final int x[] = { 19500, 19000, 18600, 18000, 17500, 16000, - 15600, 14900, 12500, 10000, 3950 }; - if (0 <= gfp.VBR_q && gfp.VBR_q <= 9) { - double a = x[gfp.VBR_q], b = x[gfp.VBR_q + 1], m = gfp.VBR_q_frac; - lowpass = linear_int(a, b, m); - } else { - lowpass = 19500; - } - break; - } - default: { - final int x[] = { 19500, 19000, 18500, 18000, 17500, 16500, - 15500, 14500, 12500, 9500, 3950 }; - if (0 <= gfp.VBR_q && gfp.VBR_q <= 9) { - double a = x[gfp.VBR_q], b = x[gfp.VBR_q + 1], m = gfp.VBR_q_frac; - lowpass = linear_int(a, b, m); - } else { - lowpass = 19500; - } - } - } - if (gfp.mode == MPEGMode.MONO - && (gfp.VBR == VbrMode.vbr_off || gfp.VBR == VbrMode.vbr_abr)) - lowpass *= 1.5; - - gfp.lowpassfreq = (int) lowpass; - } - - if (gfp.out_samplerate == 0) { - if (2 * gfp.lowpassfreq > gfp.in_samplerate) { - gfp.lowpassfreq = gfp.in_samplerate / 2; - } - gfp.out_samplerate = optimum_samplefreq((int) gfp.lowpassfreq, - gfp.in_samplerate); - } - - gfp.lowpassfreq = Math.min(20500, gfp.lowpassfreq); - gfp.lowpassfreq = Math.min(gfp.out_samplerate / 2, gfp.lowpassfreq); - - if (gfp.VBR == VbrMode.vbr_off) { - gfp.compression_ratio = gfp.out_samplerate * 16 * gfc.channels_out - / (1.e3f * gfp.brate); - } - if (gfp.VBR == VbrMode.vbr_abr) { - gfp.compression_ratio = gfp.out_samplerate * 16 * gfc.channels_out - / (1.e3f * gfp.VBR_mean_bitrate_kbps); - } - - /* - * do not compute ReplayGain values and do not find the peak sample if - * we can't store them - */ - if (!gfp.bWriteVbrTag) { - gfp.findReplayGain = false; - gfp.decode_on_the_fly = false; - gfc.findPeakSample = false; - } - gfc.findReplayGain = gfp.findReplayGain; - gfc.decode_on_the_fly = gfp.decode_on_the_fly; - - if (gfc.decode_on_the_fly) - gfc.findPeakSample = true; - - if (gfc.findReplayGain) { - if (ga.InitGainAnalysis(gfc.rgdata, gfp.out_samplerate) == GainAnalysis.INIT_GAIN_ANALYSIS_ERROR) { - gfp.internal_flags = null; - return -6; - } - } - - if (gfc.decode_on_the_fly && !gfp.decode_only) { - if (gfc.hip != null) { - mpglib.hip_decode_exit(gfc.hip); - } - gfc.hip = mpglib.hip_decode_init(); - } - - gfc.mode_gr = gfp.out_samplerate <= 24000 ? 1 : 2; - /* - * Number of granules per frame - */ - gfp.framesize = 576 * gfc.mode_gr; - gfp.encoder_delay = Encoder.ENCDELAY; - - gfc.resample_ratio = (double) gfp.in_samplerate / gfp.out_samplerate; - - /** - * <PRE> - * sample freq bitrate compression ratio - * [kHz] [kbps/channel] for 16 bit input - * 44.1 56 12.6 - * 44.1 64 11.025 - * 44.1 80 8.82 - * 22.05 24 14.7 - * 22.05 32 11.025 - * 22.05 40 8.82 - * 16 16 16.0 - * 16 24 10.667 - * </PRE> - */ - /** - * <PRE> - * For VBR, take a guess at the compression_ratio. - * For example: - * - * VBR_q compression like - * - 4.4 320 kbps/44 kHz - * 0...1 5.5 256 kbps/44 kHz - * 2 7.3 192 kbps/44 kHz - * 4 8.8 160 kbps/44 kHz - * 6 11 128 kbps/44 kHz - * 9 14.7 96 kbps - * - * for lower bitrates, downsample with --resample - * </PRE> - */ - switch (gfp.VBR) { - case vbr_mt: - case vbr_rh: - case vbr_mtrh: { - /* numbers are a bit strange, but they determine the lowpass value */ - final float cmp[] = { 5.7f, 6.5f, 7.3f, 8.2f, 10f, 11.9f, 13f, 14f, - 15f, 16.5f }; - gfp.compression_ratio = cmp[gfp.VBR_q]; - } - break; - case vbr_abr: - gfp.compression_ratio = gfp.out_samplerate * 16 * gfc.channels_out - / (1.e3f * gfp.VBR_mean_bitrate_kbps); - break; - default: - gfp.compression_ratio = gfp.out_samplerate * 16 * gfc.channels_out - / (1.e3f * gfp.brate); - break; - } - - /* - * mode = -1 (not set by user) or mode = MONO (because of only 1 input - * channel). If mode has not been set, then select J-STEREO - */ - if (gfp.mode == MPEGMode.NOT_SET) { - gfp.mode = MPEGMode.JOINT_STEREO; - } - - /* apply user driven high pass filter */ - if (gfp.highpassfreq > 0) { - gfc.highpass1 = 2.f * gfp.highpassfreq; - - if (gfp.highpasswidth >= 0) - gfc.highpass2 = 2.f * (gfp.highpassfreq + gfp.highpasswidth); - else - /* 0% above on default */ - gfc.highpass2 = (1 + 0.00f) * 2.f * gfp.highpassfreq; - - gfc.highpass1 /= gfp.out_samplerate; - gfc.highpass2 /= gfp.out_samplerate; - } else { - gfc.highpass1 = 0; - gfc.highpass2 = 0; - } - /* apply user driven low pass filter */ - if (gfp.lowpassfreq > 0) { - gfc.lowpass2 = 2.f * gfp.lowpassfreq; - if (gfp.lowpasswidth >= 0) { - gfc.lowpass1 = 2.f * (gfp.lowpassfreq - gfp.lowpasswidth); - if (gfc.lowpass1 < 0) /* has to be >= 0 */ - gfc.lowpass1 = 0; - } else { /* 0% below on default */ - gfc.lowpass1 = (1 - 0.00f) * 2.f * gfp.lowpassfreq; - } - gfc.lowpass1 /= gfp.out_samplerate; - gfc.lowpass2 /= gfp.out_samplerate; - } else { - gfc.lowpass1 = 0; - gfc.lowpass2 = 0; - } - - /**********************************************************************/ - /* compute info needed for polyphase filter (filter type==0, default) */ - /**********************************************************************/ - lame_init_params_ppflt(gfp); - - /******************************************************* - * samplerate and bitrate index - *******************************************************/ - gfc.samplerate_index = SmpFrqIndex(gfp.out_samplerate, gfp); - if (gfc.samplerate_index < 0) { - gfp.internal_flags = null; - return -1; - } - - if (gfp.VBR == VbrMode.vbr_off) { - if (gfp.free_format) { - gfc.bitrate_index = 0; - } else { - gfp.brate = FindNearestBitrate(gfp.brate, gfp.version, - gfp.out_samplerate); - gfc.bitrate_index = BitrateIndex(gfp.brate, gfp.version, - gfp.out_samplerate); - if (gfc.bitrate_index <= 0) { - gfp.internal_flags = null; - return -1; - } - } - } else { - gfc.bitrate_index = 1; - } - - /* for CBR, we will write an "info" tag. */ - - if (gfp.analysis) - gfp.bWriteVbrTag = false; - - /* some file options not allowed if output is: not specified or stdout */ - if (gfc.pinfo != null) - gfp.bWriteVbrTag = false; /* disable Xing VBR tag */ - - bs.init_bit_stream_w(gfc); - - int j = gfc.samplerate_index + (3 * gfp.version) + 6 - * (gfp.out_samplerate < 16000 ? 1 : 0); - for (int i = 0; i < Encoder.SBMAX_l + 1; i++) - gfc.scalefac_band.l[i] = qupvt.sfBandIndex[j].l[i]; - - for (int i = 0; i < Encoder.PSFB21 + 1; i++) { - final int size = (gfc.scalefac_band.l[22] - gfc.scalefac_band.l[21]) - / Encoder.PSFB21; - final int start = gfc.scalefac_band.l[21] + i * size; - gfc.scalefac_band.psfb21[i] = start; - } - gfc.scalefac_band.psfb21[Encoder.PSFB21] = 576; - - for (int i = 0; i < Encoder.SBMAX_s + 1; i++) - gfc.scalefac_band.s[i] = qupvt.sfBandIndex[j].s[i]; - - for (int i = 0; i < Encoder.PSFB12 + 1; i++) { - final int size = (gfc.scalefac_band.s[13] - gfc.scalefac_band.s[12]) - / Encoder.PSFB12; - final int start = gfc.scalefac_band.s[12] + i * size; - gfc.scalefac_band.psfb12[i] = start; - } - gfc.scalefac_band.psfb12[Encoder.PSFB12] = 192; - - /* determine the mean bitrate for main data */ - if (gfp.version == 1) /* MPEG 1 */ - gfc.sideinfo_len = (gfc.channels_out == 1) ? 4 + 17 : 4 + 32; - else - /* MPEG 2 */ - gfc.sideinfo_len = (gfc.channels_out == 1) ? 4 + 9 : 4 + 17; - - if (gfp.error_protection) - gfc.sideinfo_len += 2; - - lame_init_bitstream(gfp); - - gfc.Class_ID = LAME_ID; - - { - int k; - - for (k = 0; k < 19; k++) - gfc.nsPsy.pefirbuf[k] = 700 * gfc.mode_gr * gfc.channels_out; - - if (gfp.ATHtype == -1) - gfp.ATHtype = 4; - } - - assert (gfp.VBR_q <= 9); - assert (gfp.VBR_q >= 0); - - switch (gfp.VBR) { - - case vbr_mt: - gfp.VBR = VbrMode.vbr_mtrh; - //$FALL-THROUGH$ - case vbr_mtrh: { - if (gfp.useTemporal == null) { - gfp.useTemporal = false; /* off by default for this VBR mode */ - } - - p.apply_preset(gfp, 500 - (gfp.VBR_q * 10), 0); - /** - * <PRE> - * The newer VBR code supports only a limited - * subset of quality levels: - * 9-5=5 are the same, uses x^3/4 quantization - * 4-0=0 are the same 5 plus best huffman divide code - * </PRE> - */ - if (gfp.quality < 0) - gfp.quality = LAME_DEFAULT_QUALITY; - if (gfp.quality < 5) - gfp.quality = 0; - if (gfp.quality > 5) - gfp.quality = 5; - - gfc.PSY.mask_adjust = gfp.maskingadjust; - gfc.PSY.mask_adjust_short = gfp.maskingadjust_short; - - /* - * sfb21 extra only with MPEG-1 at higher sampling rates - */ - if (gfp.experimentalY) - gfc.sfb21_extra = false; - else - gfc.sfb21_extra = (gfp.out_samplerate > 44000); - - gfc.iteration_loop = new VBRNewIterationLoop(qu); - break; - - } - case vbr_rh: { - - p.apply_preset(gfp, 500 - (gfp.VBR_q * 10), 0); - - gfc.PSY.mask_adjust = gfp.maskingadjust; - gfc.PSY.mask_adjust_short = gfp.maskingadjust_short; - - /* - * sfb21 extra only with MPEG-1 at higher sampling rates - */ - if (gfp.experimentalY) - gfc.sfb21_extra = false; - else - gfc.sfb21_extra = (gfp.out_samplerate > 44000); - - /* - * VBR needs at least the output of GPSYCHO, so we have to garantee - * that by setting a minimum quality level, actually level 6 does - * it. down to level 6 - */ - if (gfp.quality > 6) - gfp.quality = 6; - - if (gfp.quality < 0) - gfp.quality = LAME_DEFAULT_QUALITY; - - gfc.iteration_loop = new VBROldIterationLoop(qu); - break; - } - - default: /* cbr/abr */{ - VbrMode vbrmode; - - /* - * no sfb21 extra with CBR code - */ - gfc.sfb21_extra = false; - - if (gfp.quality < 0) - gfp.quality = LAME_DEFAULT_QUALITY; - - vbrmode = gfp.VBR; - if (vbrmode == VbrMode.vbr_off) - gfp.VBR_mean_bitrate_kbps = gfp.brate; - /* second, set parameters depending on bitrate */ - p.apply_preset(gfp, gfp.VBR_mean_bitrate_kbps, 0); - gfp.VBR = vbrmode; - - gfc.PSY.mask_adjust = gfp.maskingadjust; - gfc.PSY.mask_adjust_short = gfp.maskingadjust_short; - - if (vbrmode == VbrMode.vbr_off) { - gfc.iteration_loop = new CBRNewIterationLoop(qu); - } else { - gfc.iteration_loop = new ABRIterationLoop(qu); - } - break; - } - } - - /* initialize default values common for all modes */ - - if (gfp.VBR != VbrMode.vbr_off) { /* choose a min/max bitrate for VBR */ - /* if the user didn't specify VBR_max_bitrate: */ - gfc.VBR_min_bitrate = 1; - /* - * default: allow 8 kbps (MPEG-2) or 32 kbps (MPEG-1) - */ - gfc.VBR_max_bitrate = 14; - /* - * default: allow 160 kbps (MPEG-2) or 320 kbps (MPEG-1) - */ - if (gfp.out_samplerate < 16000) - gfc.VBR_max_bitrate = 8; /* default: allow 64 kbps (MPEG-2.5) */ - if (gfp.VBR_min_bitrate_kbps != 0) { - gfp.VBR_min_bitrate_kbps = FindNearestBitrate( - gfp.VBR_min_bitrate_kbps, gfp.version, - gfp.out_samplerate); - gfc.VBR_min_bitrate = BitrateIndex(gfp.VBR_min_bitrate_kbps, - gfp.version, gfp.out_samplerate); - if (gfc.VBR_min_bitrate < 0) - return -1; - } - if (gfp.VBR_max_bitrate_kbps != 0) { - gfp.VBR_max_bitrate_kbps = FindNearestBitrate( - gfp.VBR_max_bitrate_kbps, gfp.version, - gfp.out_samplerate); - gfc.VBR_max_bitrate = BitrateIndex(gfp.VBR_max_bitrate_kbps, - gfp.version, gfp.out_samplerate); - if (gfc.VBR_max_bitrate < 0) - return -1; - } - gfp.VBR_min_bitrate_kbps = Tables.bitrate_table[gfp.version][gfc.VBR_min_bitrate]; - gfp.VBR_max_bitrate_kbps = Tables.bitrate_table[gfp.version][gfc.VBR_max_bitrate]; - gfp.VBR_mean_bitrate_kbps = Math.min( - Tables.bitrate_table[gfp.version][gfc.VBR_max_bitrate], - gfp.VBR_mean_bitrate_kbps); - gfp.VBR_mean_bitrate_kbps = Math.max( - Tables.bitrate_table[gfp.version][gfc.VBR_min_bitrate], - gfp.VBR_mean_bitrate_kbps); - } - - /* just another daily changing developer switch */ - if (gfp.tune) { - gfc.PSY.mask_adjust += gfp.tune_value_a; - gfc.PSY.mask_adjust_short += gfp.tune_value_a; - } - - /* initialize internal qval settings */ - lame_init_qval(gfp); - - /* - * automatic ATH adjustment on - */ - if (gfp.athaa_type < 0) - gfc.ATH.useAdjust = 3; - else - gfc.ATH.useAdjust = gfp.athaa_type; - - /* initialize internal adaptive ATH settings -jd */ - gfc.ATH.aaSensitivityP = (float) Math.pow(10.0, gfp.athaa_sensitivity - / -10.0); - - if (gfp.short_blocks == null) { - gfp.short_blocks = ShortBlock.short_block_allowed; - } - - /* - * Note Jan/2003: Many hardware decoders cannot handle short blocks in - * regular stereo mode unless they are coupled (same type in both - * channels) it is a rare event (1 frame per min. or so) that LAME would - * use uncoupled short blocks, so lets turn them off until we decide how - * to handle this. No other encoders allow uncoupled short blocks, even - * though it is in the standard. - */ - /* - * rh 20040217: coupling makes no sense for mono and dual-mono streams - */ - if (gfp.short_blocks == ShortBlock.short_block_allowed - && (gfp.mode == MPEGMode.JOINT_STEREO || gfp.mode == MPEGMode.STEREO)) { - gfp.short_blocks = ShortBlock.short_block_coupled; - } - - if (gfp.quant_comp < 0) - gfp.quant_comp = 1; - if (gfp.quant_comp_short < 0) - gfp.quant_comp_short = 0; - - if (gfp.msfix < 0) - gfp.msfix = 0; - - /* select psychoacoustic model */ - gfp.exp_nspsytune = gfp.exp_nspsytune | 1; - - if (gfp.internal_flags.nsPsy.attackthre < 0) - gfp.internal_flags.nsPsy.attackthre = PsyModel.NSATTACKTHRE; - if (gfp.internal_flags.nsPsy.attackthre_s < 0) - gfp.internal_flags.nsPsy.attackthre_s = PsyModel.NSATTACKTHRE_S; - - if (gfp.scale < 0) - gfp.scale = 1; - - if (gfp.ATHtype < 0) - gfp.ATHtype = 4; - - if (gfp.ATHcurve < 0) - gfp.ATHcurve = 4; - - if (gfp.athaa_loudapprox < 0) - gfp.athaa_loudapprox = 2; - - if (gfp.interChRatio < 0) - gfp.interChRatio = 0; - - if (gfp.useTemporal == null) - gfp.useTemporal = true; /* on by default */ - - /* - * padding method as described in - * "MPEG-Layer3 / Bitstream Syntax and Decoding" by Martin Sieler, Ralph - * Sperschneider - * - * note: there is no padding for the very first frame - * - * Robert Hegemann 2000-06-22 - */ - gfc.slot_lag = gfc.frac_SpF = 0; - if (gfp.VBR == VbrMode.vbr_off) - gfc.slot_lag = gfc.frac_SpF = (int) (((gfp.version + 1) * 72000L * gfp.brate) % gfp.out_samplerate); - - qupvt.iteration_init(gfp); - psy.psymodel_init(gfp); - - return 0; - } - - /** - * Prints some selected information about the coding parameters via the - * macro command MSGF(), which is currently mapped to lame_errorf (reports - * via a error function?), which is a printf-like function for <stderr>. - */ - public final void lame_print_config(final LameGlobalFlags gfp) { - final LameInternalFlags gfc = gfp.internal_flags; - double out_samplerate = gfp.out_samplerate; - double in_samplerate = gfp.out_samplerate * gfc.resample_ratio; - - System.out.printf("LAME %s %s (%s)\n", ver.getLameVersion(), - ver.getLameOsBitness(), ver.getLameUrl()); - - if (gfp.num_channels == 2 && gfc.channels_out == 1 /* mono */) { - System.out - .printf("Autoconverting from stereo to mono. Setting encoding to mono mode.\n"); - } - - if (BitStream.NEQ((float) gfc.resample_ratio, 1.f)) { - System.out.printf("Resampling: input %g kHz output %g kHz\n", - 1.e-3 * in_samplerate, 1.e-3 * out_samplerate); - } - - if (gfc.highpass2 > 0.) { - System.out - .printf("Using polyphase highpass filter, transition band: %5.0f Hz - %5.0f Hz\n", - 0.5 * gfc.highpass1 * out_samplerate, 0.5 - * gfc.highpass2 * out_samplerate); - } - if (0. < gfc.lowpass1 || 0. < gfc.lowpass2) { - System.out - .printf("Using polyphase lowpass filter, transition band: %5.0f Hz - %5.0f Hz\n", - 0.5 * gfc.lowpass1 * out_samplerate, 0.5 - * gfc.lowpass2 * out_samplerate); - } else { - System.out.printf("polyphase lowpass filter disabled\n"); - } - - if (gfp.free_format) { - System.err - .printf("Warning: many decoders cannot handle free format bitstreams\n"); - if (gfp.brate > 320) { - System.err - .printf("Warning: many decoders cannot handle free format bitrates >320 kbps (see documentation)\n"); - } - } - } - - /** - * rh: some pretty printing is very welcome at this point! so, if someone is - * willing to do so, please do it! add more, if you see more... - */ - public final void lame_print_internals(final LameGlobalFlags gfp) { - final LameInternalFlags gfc = gfp.internal_flags; - - /* - * compiler/processor optimizations, operational, etc. - */ - System.err.printf("\nmisc:\n\n"); - - System.err.printf("\tscaling: %g\n", gfp.scale); - System.err.printf("\tch0 (left) scaling: %g\n", gfp.scale_left); - System.err.printf("\tch1 (right) scaling: %g\n", gfp.scale_right); - String pc; - switch (gfc.use_best_huffman) { - default: - pc = "normal"; - break; - case 1: - pc = "best (outside loop)"; - break; - case 2: - pc = "best (inside loop, slow)"; - break; - } - System.err.printf("\thuffman search: %s\n", pc); - System.err.printf("\texperimental Y=%d\n", gfp.experimentalY); - System.err.printf("\t...\n"); - - /* - * everything controlling the stream format - */ - System.err.printf("\nstream format:\n\n"); - switch (gfp.version) { - case 0: - pc = "2.5"; - break; - case 1: - pc = "1"; - break; - case 2: - pc = "2"; - break; - default: - pc = "?"; - break; - } - System.err.printf("\tMPEG-%s Layer 3\n", pc); - switch (gfp.mode) { - case JOINT_STEREO: - pc = "joint stereo"; - break; - case STEREO: - pc = "stereo"; - break; - case DUAL_CHANNEL: - pc = "dual channel"; - break; - case MONO: - pc = "mono"; - break; - case NOT_SET: - pc = "not set (error)"; - break; - default: - pc = "unknown (error)"; - break; - } - System.err.printf("\t%d channel - %s\n", gfc.channels_out, pc); - - switch (gfp.VBR) { - case vbr_off: - pc = "off"; - break; - default: - pc = "all"; - break; - } - System.err.printf("\tpadding: %s\n", pc); - - if (VbrMode.vbr_default == gfp.VBR) - pc = "(default)"; - else if (gfp.free_format) - pc = "(free format)"; - else - pc = ""; - switch (gfp.VBR) { - case vbr_off: - System.err.printf("\tconstant bitrate - CBR %s\n", pc); - break; - case vbr_abr: - System.err.printf("\tvariable bitrate - ABR %s\n", pc); - break; - case vbr_rh: - System.err.printf("\tvariable bitrate - VBR rh %s\n", pc); - break; - case vbr_mt: - System.err.printf("\tvariable bitrate - VBR mt %s\n", pc); - break; - case vbr_mtrh: - System.err.printf("\tvariable bitrate - VBR mtrh %s\n", pc); - break; - default: - System.err.printf("\t ?? oops, some new one ?? \n"); - break; - } - if (gfp.bWriteVbrTag) { - System.err.printf("\tusing LAME Tag\n"); - } - System.err.printf("\t...\n"); - - /* - * everything controlling psychoacoustic settings, like ATH, etc. - */ - System.err.printf("\npsychoacoustic:\n\n"); - - switch (gfp.short_blocks) { - default: - pc = "?"; - break; - case short_block_allowed: - pc = "allowed"; - break; - case short_block_coupled: - pc = "channel coupled"; - break; - case short_block_dispensed: - pc = "dispensed"; - break; - case short_block_forced: - pc = "forced"; - break; - } - System.err.printf("\tusing short blocks: %s\n", pc); - System.err.printf("\tsubblock gain: %d\n", gfc.subblock_gain); - System.err.printf("\tadjust masking: %g dB\n", gfc.PSY.mask_adjust); - System.err.printf("\tadjust masking short: %g dB\n", - gfc.PSY.mask_adjust_short); - System.err.printf("\tquantization comparison: %d\n", gfp.quant_comp); - System.err.printf("\t ^ comparison short blocks: %d\n", - gfp.quant_comp_short); - System.err.printf("\tnoise shaping: %d\n", gfc.noise_shaping); - System.err.printf("\t ^ amplification: %d\n", gfc.noise_shaping_amp); - System.err.printf("\t ^ stopping: %d\n", gfc.noise_shaping_stop); - - pc = "using"; - if (gfp.ATHshort) - pc = "the only masking for short blocks"; - if (gfp.ATHonly) - pc = "the only masking"; - if (gfp.noATH) - pc = "not used"; - System.err.printf("\tATH: %s\n", pc); - System.err.printf("\t ^ type: %d\n", gfp.ATHtype); - System.err.printf("\t ^ shape: %g%s\n", gfp.ATHcurve, - " (only for type 4)"); - System.err.printf("\t ^ level adjustement: %g\n", gfp.ATHlower); - System.err.printf("\t ^ adjust type: %d\n", gfc.ATH.useAdjust); - System.err.printf("\t ^ adjust sensitivity power: %f\n", - gfc.ATH.aaSensitivityP); - System.err.printf("\t ^ adapt threshold type: %d\n", - gfp.athaa_loudapprox); - - System.err.printf("\texperimental psy tunings by Naoki Shibata\n"); - System.err - .printf("\t adjust masking bass=%g dB, alto=%g dB, treble=%g dB, sfb21=%g dB\n", - 10 * Math.log10(gfc.nsPsy.longfact[0]), - 10 * Math.log10(gfc.nsPsy.longfact[7]), - 10 * Math.log10(gfc.nsPsy.longfact[14]), - 10 * Math.log10(gfc.nsPsy.longfact[21])); - - pc = gfp.useTemporal ? "yes" : "no"; - System.err.printf("\tusing temporal masking effect: %s\n", pc); - System.err.printf("\tinterchannel masking ratio: %g\n", - gfp.interChRatio); - System.err.printf("\t...\n"); - - /* - * that's all ? - */ - System.err.printf("\n"); - } - - /** - * routine to feed exactly one frame (gfp.framesize) worth of data to the - * encoding engine. All buffering, resampling, etc, handled by calling - * program. - */ - private int lame_encode_frame(final LameGlobalFlags gfp, - final float inbuf_l[], final float inbuf_r[], final byte[] mp3buf, - final int mp3bufPos, final int mp3buf_size) { - int ret = enc.lame_encode_mp3_frame(gfp, inbuf_l, inbuf_r, mp3buf, - mp3bufPos, mp3buf_size); - gfp.frameNum++; - return ret; - } - - private void update_inbuffer_size(final LameInternalFlags gfc, - final int nsamples) { - if (gfc.in_buffer_0 == null || gfc.in_buffer_nsamples < nsamples) { - gfc.in_buffer_0 = new float[nsamples]; - gfc.in_buffer_1 = new float[nsamples]; - gfc.in_buffer_nsamples = nsamples; - } - } - - private int calcNeeded(final LameGlobalFlags gfp) { - int mf_needed = Encoder.BLKSIZE + gfp.framesize - Encoder.FFTOFFSET; - /* - * amount needed for FFT - */ - mf_needed = Math.max(mf_needed, 512 + gfp.framesize - 32); - assert (LameInternalFlags.MFSIZE >= mf_needed); - - return mf_needed; - } - - protected static class InOut { - int n_in; - int n_out; - } - - /** - * <PRE> - * THE MAIN LAME ENCODING INTERFACE - * mt 3/00 - * - * input pcm data, output (maybe) mp3 frames. - * This routine handles all buffering, resampling and filtering for you. - * The required mp3buffer_size can be computed from num_samples, - * samplerate and encoding rate, but here is a worst case estimate: - * - * mp3buffer_size in bytes = 1.25*num_samples + 7200 - * - * return code = number of bytes output in mp3buffer. can be 0 - * - * NOTE: this routine uses LAME's internal PCM data representation, - * 'sample_t'. It should not be used by any application. - * applications should use lame_encode_buffer(), - * lame_encode_buffer_float() - * lame_encode_buffer_int() - * etc... depending on what type of data they are working with. - * </PRE> - */ - private int lame_encode_buffer_sample(final LameGlobalFlags gfp, - final float buffer_l[], final float buffer_r[], int nsamples, - final byte[] mp3buf, int mp3bufPos, final int mp3buf_size) { - final LameInternalFlags gfc = gfp.internal_flags; - int mp3size = 0, ret, i, ch, mf_needed; - int mp3out; - float mfbuf[][] = new float[2][]; - float in_buffer[][] = new float[2][]; - - if (gfc.Class_ID != LAME_ID) - return -3; - - if (nsamples == 0) - return 0; - - /* copy out any tags that may have been written into bitstream */ - mp3out = bs.copy_buffer(gfc, mp3buf, mp3bufPos, mp3buf_size, 0); - if (mp3out < 0) - return mp3out; /* not enough buffer space */ - mp3bufPos += mp3out; - mp3size += mp3out; - - in_buffer[0] = buffer_l; - in_buffer[1] = buffer_r; - - /* Apply user defined re-scaling */ - - /* user selected scaling of the samples */ - if (BitStream.NEQ(gfp.scale, 0) && BitStream.NEQ(gfp.scale, 1.0f)) { - for (i = 0; i < nsamples; ++i) { - in_buffer[0][i] *= gfp.scale; - if (gfc.channels_out == 2) - in_buffer[1][i] *= gfp.scale; - } - } - - /* user selected scaling of the channel 0 (left) samples */ - if (BitStream.NEQ(gfp.scale_left, 0) - && BitStream.NEQ(gfp.scale_left, 1.0f)) { - for (i = 0; i < nsamples; ++i) { - in_buffer[0][i] *= gfp.scale_left; - } - } - - /* user selected scaling of the channel 1 (right) samples */ - if (BitStream.NEQ(gfp.scale_right, 0) - && BitStream.NEQ(gfp.scale_right, 1.0f)) { - for (i = 0; i < nsamples; ++i) { - in_buffer[1][i] *= gfp.scale_right; - } - } - - /* Downsample to Mono if 2 channels in and 1 channel out */ - if (gfp.num_channels == 2 && gfc.channels_out == 1) { - for (i = 0; i < nsamples; ++i) { - in_buffer[0][i] = 0.5f * ((float) in_buffer[0][i] + in_buffer[1][i]); - in_buffer[1][i] = 0.0f; - } - } - - mf_needed = calcNeeded(gfp); - - mfbuf[0] = gfc.mfbuf[0]; - mfbuf[1] = gfc.mfbuf[1]; - - int in_bufferPos = 0; - while (nsamples > 0) { - final float in_buffer_ptr[][] = new float[2][]; - int n_in = 0; /* number of input samples processed with fill_buffer */ - int n_out = 0; /* number of samples output with fill_buffer */ - /* n_in <> n_out if we are resampling */ - - in_buffer_ptr[0] = in_buffer[0]; - in_buffer_ptr[1] = in_buffer[1]; - /* copy in new samples into mfbuf, with resampling */ - InOut inOut = new InOut(); - fill_buffer(gfp, mfbuf, in_buffer_ptr, in_bufferPos, nsamples, - inOut); - n_in = inOut.n_in; - n_out = inOut.n_out; - - /* compute ReplayGain of resampled input if requested */ - if (gfc.findReplayGain && !gfc.decode_on_the_fly) - if (ga.AnalyzeSamples(gfc.rgdata, mfbuf[0], gfc.mf_size, - mfbuf[1], gfc.mf_size, n_out, gfc.channels_out) == GainAnalysis.GAIN_ANALYSIS_ERROR) - return -6; - - /* update in_buffer counters */ - nsamples -= n_in; - in_bufferPos += n_in; - if (gfc.channels_out == 2) - ;// in_bufferPos += n_in; - - /* update mfbuf[] counters */ - gfc.mf_size += n_out; - assert (gfc.mf_size <= LameInternalFlags.MFSIZE); - - /* - * lame_encode_flush may have set gfc.mf_sample_to_encode to 0 so we - * have to reinitialize it here when that happened. - */ - if (gfc.mf_samples_to_encode < 1) { - gfc.mf_samples_to_encode = Encoder.ENCDELAY + Encoder.POSTDELAY; - } - gfc.mf_samples_to_encode += n_out; - - if (gfc.mf_size >= mf_needed) { - /* encode the frame. */ - /* mp3buf = pointer to current location in buffer */ - /* mp3buf_size = size of original mp3 output buffer */ - /* = 0 if we should not worry about the */ - /* buffer size because calling program is */ - /* to lazy to compute it */ - /* mp3size = size of data written to buffer so far */ - /* mp3buf_size-mp3size = amount of space avalable */ - - int buf_size = mp3buf_size - mp3size; - if (mp3buf_size == 0) - buf_size = 0; - - ret = lame_encode_frame(gfp, mfbuf[0], mfbuf[1], mp3buf, - mp3bufPos, buf_size); - - if (ret < 0) - return ret; - mp3bufPos += ret; - mp3size += ret; - - /* shift out old samples */ - gfc.mf_size -= gfp.framesize; - gfc.mf_samples_to_encode -= gfp.framesize; - for (ch = 0; ch < gfc.channels_out; ch++) - for (i = 0; i < gfc.mf_size; i++) - mfbuf[ch][i] = mfbuf[ch][i + gfp.framesize]; - } - } - assert (nsamples == 0); - - return mp3size; - } - - private int lame_encode_buffer(final LameGlobalFlags gfp, - final short buffer_l[], final short buffer_r[], final int nsamples, - final byte[] mp3buf, final int mp3bufPos, final int mp3buf_size) { - final LameInternalFlags gfc = gfp.internal_flags; - float in_buffer[][] = new float[2][]; - - if (gfc.Class_ID != LAME_ID) - return -3; - - if (nsamples == 0) - return 0; - - update_inbuffer_size(gfc, nsamples); - - in_buffer[0] = gfc.in_buffer_0; - in_buffer[1] = gfc.in_buffer_1; - - /* make a copy of input buffer, changing type to sample_t */ - for (int i = 0; i < nsamples; i++) { - in_buffer[0][i] = buffer_l[i]; - if (gfc.channels_in > 1) - in_buffer[1][i] = buffer_r[i]; - } - - return lame_encode_buffer_sample(gfp, in_buffer[0], in_buffer[1], - nsamples, mp3buf, mp3bufPos, mp3buf_size); - } - - public int lame_encode_buffer_int(final LameGlobalFlags gfp, - final int buffer_l[], final int buffer_r[], final int nsamples, - byte[] mp3buf, int mp3bufPos, final int mp3buf_size) { - final LameInternalFlags gfc = gfp.internal_flags; - float[][] in_buffer = new float[2][]; - - if (gfc.Class_ID != LAME_ID) - return -3; - - if (nsamples == 0) - return 0; - - update_inbuffer_size(gfc, nsamples); - - in_buffer[0] = gfc.in_buffer_0; - in_buffer[1] = gfc.in_buffer_1; - - /* make a copy of input buffer, changing type to sample_t */ - for (int i = 0; i < nsamples; i++) { - /* internal code expects +/- 32768.0 */ - in_buffer[0][i] = buffer_l[i]; - if (gfc.channels_in > 1) - in_buffer[1][i] = buffer_r[i]; - } - - return lame_encode_buffer_sample(gfp, in_buffer[0], in_buffer[1], - nsamples, mp3buf, mp3bufPos, mp3buf_size); - } - - /** - * Flush mp3 buffer, pad with ancillary data so last frame is complete. - * Reset reservoir size to 0 but keep all PCM samples and MDCT data in - * memory This option is used to break a large file into several mp3 files - * that when concatenated together will decode with no gaps Because we set - * the reservoir=0, they will also decode seperately with no errors. - */ - public final int lame_encode_flush_nogap(final LameGlobalFlags gfp, - final byte[] mp3buffer, final int mp3buffer_size) { - final LameInternalFlags gfc = gfp.internal_flags; - bs.flush_bitstream(gfp); - return bs.copy_buffer(gfc, mp3buffer, 0, mp3buffer_size, 1); - } - - /* - * called by lame_init_params. You can also call this after flush_nogap if - * you want to write new id3v2 and Xing VBR tags into the bitstream - */ - public final void lame_init_bitstream(final LameGlobalFlags gfp) { - final LameInternalFlags gfc = gfp.internal_flags; - gfp.frameNum = 0; - - if (gfp.write_id3tag_automatic) { - id3.id3tag_write_v2(gfp); - } - /* initialize histogram data optionally used by frontend */ - - gfc.bitrate_stereoMode_Hist = new int[16][4 + 1]; - gfc.bitrate_blockType_Hist = new int[16][4 + 1 + 1]; - - gfc.PeakSample = 0.0f; - - /* Write initial VBR Header to bitstream and init VBR data */ - if (gfp.bWriteVbrTag) - vbr.InitVbrTag(gfp); - } - - /** - * flush internal PCM sample buffers, then mp3 buffers then write id3 v1 - * tags into bitstream. - */ - public final int lame_encode_flush(final LameGlobalFlags gfp, - final byte[] mp3buffer, int mp3bufferPos, final int mp3buffer_size) { - final LameInternalFlags gfc = gfp.internal_flags; - short buffer[][] = new short[2][1152]; - int imp3 = 0, mp3count, mp3buffer_size_remaining; - - /* - * we always add POSTDELAY=288 padding to make sure granule with real - * data can be complety decoded (because of 50% overlap with next - * granule - */ - int end_padding; - int frames_left; - int samples_to_encode = gfc.mf_samples_to_encode - Encoder.POSTDELAY; - int mf_needed = calcNeeded(gfp); - - /* Was flush already called? */ - if (gfc.mf_samples_to_encode < 1) { - return 0; - } - mp3count = 0; - - if (gfp.in_samplerate != gfp.out_samplerate) { - /* - * delay due to resampling; needs to be fixed, if resampling code - * gets changed - */ - samples_to_encode += 16. * gfp.out_samplerate / gfp.in_samplerate; - } - end_padding = gfp.framesize - (samples_to_encode % gfp.framesize); - if (end_padding < 576) - end_padding += gfp.framesize; - gfp.encoder_padding = end_padding; - - frames_left = (samples_to_encode + end_padding) / gfp.framesize; - - /* - * send in a frame of 0 padding until all internal sample buffers are - * flushed - */ - while (frames_left > 0 && imp3 >= 0) { - int bunch = mf_needed - gfc.mf_size; - int frame_num = gfp.frameNum; - - bunch *= gfp.in_samplerate; - bunch /= gfp.out_samplerate; - if (bunch > 1152) - bunch = 1152; - if (bunch < 1) - bunch = 1; - - mp3buffer_size_remaining = mp3buffer_size - mp3count; - - /* if user specifed buffer size = 0, dont check size */ - if (mp3buffer_size == 0) - mp3buffer_size_remaining = 0; - - imp3 = lame_encode_buffer(gfp, buffer[0], buffer[1], bunch, - mp3buffer, mp3bufferPos, mp3buffer_size_remaining); - - mp3bufferPos += imp3; - mp3count += imp3; - frames_left -= (frame_num != gfp.frameNum) ? 1 : 0; - } - /* - * Set gfc.mf_samples_to_encode to 0, so we may detect and break loops - * calling it more than once in a row. - */ - gfc.mf_samples_to_encode = 0; - - if (imp3 < 0) { - /* some type of fatal error */ - return imp3; - } - - mp3buffer_size_remaining = mp3buffer_size - mp3count; - /* if user specifed buffer size = 0, dont check size */ - if (mp3buffer_size == 0) - mp3buffer_size_remaining = 0; - - /* mp3 related stuff. bit buffer might still contain some mp3 data */ - bs.flush_bitstream(gfp); - imp3 = bs.copy_buffer(gfc, mp3buffer, mp3bufferPos, - mp3buffer_size_remaining, 1); - if (imp3 < 0) { - /* some type of fatal error */ - return imp3; - } - mp3bufferPos += imp3; - mp3count += imp3; - mp3buffer_size_remaining = mp3buffer_size - mp3count; - /* if user specifed buffer size = 0, dont check size */ - if (mp3buffer_size == 0) - mp3buffer_size_remaining = 0; - - if (gfp.write_id3tag_automatic) { - /* write a id3 tag to the bitstream */ - id3.id3tag_write_v1(gfp); - - imp3 = bs.copy_buffer(gfc, mp3buffer, mp3bufferPos, - mp3buffer_size_remaining, 0); - - if (imp3 < 0) { - return imp3; - } - mp3count += imp3; - } - return mp3count; - } - - /** - * frees internal buffers - */ - public final int lame_close(final LameGlobalFlags gfp) { - int ret = 0; - if (gfp != null && gfp.class_id == LAME_ID) { - final LameInternalFlags gfc = gfp.internal_flags; - gfp.class_id = 0; - if (null == gfc || gfc.Class_ID != LAME_ID) { - ret = -3; - } - gfc.Class_ID = 0; - gfp.internal_flags = null; - gfp.lame_allocated_gfp = 0; - } - return ret; - } - - private int lame_init_old(final LameGlobalFlags gfp) { - LameInternalFlags gfc; - - gfp.class_id = LAME_ID; - - gfc = gfp.internal_flags = new LameInternalFlags(); - - /* Global flags. set defaults here for non-zero values */ - /* see lame.h for description */ - /* - * set integer values to -1 to mean that LAME will compute the best - * value, UNLESS the calling program as set it (and the value is no - * longer -1) - */ - - gfp.mode = MPEGMode.NOT_SET; - gfp.original = 1; - gfp.in_samplerate = 44100; - gfp.num_channels = 2; - gfp.num_samples = -1; - - gfp.bWriteVbrTag = true; - gfp.quality = -1; - gfp.short_blocks = null; - gfc.subblock_gain = -1; - - gfp.lowpassfreq = 0; - gfp.highpassfreq = 0; - gfp.lowpasswidth = -1; - gfp.highpasswidth = -1; - - gfp.VBR = VbrMode.vbr_off; - gfp.VBR_q = 4; - gfp.ATHcurve = -1; - gfp.VBR_mean_bitrate_kbps = 128; - gfp.VBR_min_bitrate_kbps = 0; - gfp.VBR_max_bitrate_kbps = 0; - gfp.VBR_hard_min = 0; - gfc.VBR_min_bitrate = 1; /* not 0 ????? */ - gfc.VBR_max_bitrate = 13; /* not 14 ????? */ - - gfp.quant_comp = -1; - gfp.quant_comp_short = -1; - - gfp.msfix = -1; - - gfc.resample_ratio = 1; - - gfc.OldValue[0] = 180; - gfc.OldValue[1] = 180; - gfc.CurrentStep[0] = 4; - gfc.CurrentStep[1] = 4; - gfc.masking_lower = 1; - gfc.nsPsy.attackthre = -1; - gfc.nsPsy.attackthre_s = -1; - - gfp.scale = -1; - - gfp.athaa_type = -1; - gfp.ATHtype = -1; /* default = -1 = set in lame_init_params */ - gfp.athaa_loudapprox = -1; /* 1 = flat loudness approx. (total energy) */ - /* 2 = equal loudness curve */ - gfp.athaa_sensitivity = 0.0f; /* no offset */ - gfp.useTemporal = null; - gfp.interChRatio = -1; - - /* - * The reason for int mf_samples_to_encode = ENCDELAY + POSTDELAY; - * ENCDELAY = internal encoder delay. And then we have to add - * POSTDELAY=288 because of the 50% MDCT overlap. A 576 MDCT granule - * decodes to 1152 samples. To synthesize the 576 samples centered under - * this granule we need the previous granule for the first 288 samples - * (no problem), and the next granule for the next 288 samples (not - * possible if this is last granule). So we need to pad with 288 samples - * to make sure we can encode the 576 samples we are interested in. - */ - gfc.mf_samples_to_encode = Encoder.ENCDELAY + Encoder.POSTDELAY; - gfp.encoder_padding = 0; - gfc.mf_size = Encoder.ENCDELAY - Encoder.MDCTDELAY; - /* - * we pad input with this many 0's - */ - - gfp.findReplayGain = false; - gfp.decode_on_the_fly = false; - - gfc.decode_on_the_fly = false; - gfc.findReplayGain = false; - gfc.findPeakSample = false; - - gfc.RadioGain = 0; - gfc.AudiophileGain = 0; - gfc.noclipGainChange = 0; - gfc.noclipScale = -1.0f; - - gfp.preset = 0; - - gfp.write_id3tag_automatic = true; - return 0; - } - - public final LameGlobalFlags lame_init() { - LameGlobalFlags gfp = new LameGlobalFlags(); - - int ret = lame_init_old(gfp); - if (ret != 0) { - return null; - } - - gfp.lame_allocated_gfp = 1; - return gfp; - } - - /*********************************************************************** - * - * some simple statistics - * - * Robert Hegemann 2000-10-11 - * - ***********************************************************************/ - - /** - * <PRE> - * histogram of used bitrate indexes: - * One has to weight them to calculate the average bitrate in kbps - * - * bitrate indices: - * there are 14 possible bitrate indices, 0 has the special meaning - * "free format" which is not possible to mix with VBR and 15 is forbidden - * anyway. - * - * stereo modes: - * 0: LR number of left-right encoded frames - * 1: LR-I number of left-right and intensity encoded frames - * 2: MS number of mid-side encoded frames - * 3: MS-I number of mid-side and intensity encoded frames - * - * 4: number of encoded frames - * </PRE> - */ - public final void lame_bitrate_kbps(final LameGlobalFlags gfp, - final int bitrate_kbps[]) { - final LameInternalFlags gfc; - - if (null == bitrate_kbps) - return; - if (null == gfp) - return; - gfc = gfp.internal_flags; - if (null == gfc) - return; - - if (gfp.free_format) { - for (int i = 0; i < 14; i++) - bitrate_kbps[i] = -1; - bitrate_kbps[0] = gfp.brate; - } else { - for (int i = 0; i < 14; i++) - bitrate_kbps[i] = Tables.bitrate_table[gfp.version][i + 1]; - } - } - - public final void lame_bitrate_hist(final LameGlobalFlags gfp, - final int bitrate_count[]) { - - if (null == bitrate_count) - return; - if (null == gfp) - return; - final LameInternalFlags gfc = gfp.internal_flags; - if (null == gfc) - return; - - if (gfp.free_format) { - for (int i = 0; i < 14; i++) - bitrate_count[i] = 0; - bitrate_count[0] = gfc.bitrate_stereoMode_Hist[0][4]; - } else { - for (int i = 0; i < 14; i++) - bitrate_count[i] = gfc.bitrate_stereoMode_Hist[i + 1][4]; - } - } - - public final void lame_stereo_mode_hist(final LameGlobalFlags gfp, - final int stmode_count[]) { - if (null == stmode_count) - return; - if (null == gfp) - return; - final LameInternalFlags gfc = gfp.internal_flags; - if (null == gfc) - return; - - for (int i = 0; i < 4; i++) { - stmode_count[i] = gfc.bitrate_stereoMode_Hist[15][i]; - } - } - - public final void lame_bitrate_stereo_mode_hist(final LameGlobalFlags gfp, - final int bitrate_stmode_count[][]) { - if (null == bitrate_stmode_count) - return; - if (null == gfp) - return; - final LameInternalFlags gfc = gfp.internal_flags; - if (null == gfc) - return; - - if (gfp.free_format) { - for (int j = 0; j < 14; j++) - for (int i = 0; i < 4; i++) - bitrate_stmode_count[j][i] = 0; - for (int i = 0; i < 4; i++) - bitrate_stmode_count[0][i] = gfc.bitrate_stereoMode_Hist[0][i]; - } else { - for (int j = 0; j < 14; j++) - for (int i = 0; i < 4; i++) - bitrate_stmode_count[j][i] = gfc.bitrate_stereoMode_Hist[j + 1][i]; - } - } - - public final void lame_block_type_hist(final LameGlobalFlags gfp, - final int btype_count[]) { - if (null == btype_count) - return; - if (null == gfp) - return; - final LameInternalFlags gfc = gfp.internal_flags; - if (null == gfc) - return; - - for (int i = 0; i < 6; ++i) { - btype_count[i] = gfc.bitrate_blockType_Hist[15][i]; - } - } - - public final void lame_bitrate_block_type_hist(final LameGlobalFlags gfp, - final int bitrate_btype_count[][]) { - if (null == bitrate_btype_count) - return; - if (null == gfp) - return; - final LameInternalFlags gfc = gfp.internal_flags; - if (null == gfc) - return; - - if (gfp.free_format) { - for (int j = 0; j < 14; ++j) - for (int i = 0; i < 6; ++i) - bitrate_btype_count[j][i] = 0; - for (int i = 0; i < 6; ++i) - bitrate_btype_count[0][i] = gfc.bitrate_blockType_Hist[0][i]; - } else { - for (int j = 0; j < 14; ++j) - for (int i = 0; i < 6; ++i) - bitrate_btype_count[j][i] = gfc.bitrate_blockType_Hist[j + 1][i]; - } - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/LameGlobalFlags.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/LameGlobalFlags.java deleted file mode 100644 index 975e7e30a..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/LameGlobalFlags.java +++ /dev/null @@ -1,275 +0,0 @@ -package mp3; - -/** - * Control Parameters set by User. These parameters are here for backwards - * compatibility with the old, non-shared lib API. Please use the - * lame_set_variablename() functions below - * - * @author Ken - * - */ -public class LameGlobalFlags { - - public long class_id; - - /* input description */ - - /** - * number of samples. default=-1 - */ - public int num_samples; - /** - * input number of channels. default=2 - */ - public int num_channels; - /** - * input_samp_rate in Hz. default=44.1 kHz - */ - public int in_samplerate; - /** - * output_samp_rate. default: LAME picks best value at least not used for - * MP3 decoding: Remember 44.1 kHz MP3s and AC97 - */ - public int out_samplerate; - /** - * scale input by this amount before encoding at least not used for MP3 - * decoding - */ - public float scale; - /** - * scale input of channel 0 (left) by this amount before encoding - */ - public float scale_left; - /** - * scale input of channel 1 (right) by this amount before encoding - */ - public float scale_right; - - /* general control params */ - /** - * collect data for a MP3 frame analyzer? - */ - public boolean analysis; - /** - * add Xing VBR tag? - */ - public boolean bWriteVbrTag; - /** - * use lame/mpglib to convert mp3 to wav - */ - public boolean decode_only; - /** - * quality setting 0=best, 9=worst default=5 - */ - public int quality; - /** - * see enum default = LAME picks best value - */ - public MPEGMode mode = MPEGMode.STEREO; - /** - * force M/S mode. requires mode=1 - */ - public boolean force_ms; - /** - * use free format? default=0 - */ - public boolean free_format; - /** - * find the RG value? default=0 - */ - public boolean findReplayGain; - /** - * decode on the fly? default=0 - */ - public boolean decode_on_the_fly; - /** - * 1 (default) writes ID3 tags, 0 not - */ - public boolean write_id3tag_automatic; - - /* - * set either brate>0 or compression_ratio>0, LAME will compute the value of - * the variable not set. Default is compression_ratio = 11.025 - */ - /** - * bitrate - */ - public int brate; - /** - * sizeof(wav file)/sizeof(mp3 file) - */ - public float compression_ratio; - - /* frame params */ - /** - * mark as copyright. default=0 - */ - public int copyright; - /** - * mark as original. default=1 - */ - public int original; - /** - * the MP3 'private extension' bit. Meaningless - */ - public int extension; - /** - * Input PCM is emphased PCM (for instance from one of the rarely emphased - * CDs), it is STRONGLY not recommended to use this, because psycho does not - * take it into account, and last but not least many decoders don't care - * about these bits - */ - public int emphasis; - /** - * use 2 bytes per frame for a CRC checksum. default=0 - */ - public boolean error_protection; - /** - * enforce ISO spec as much as possible - */ - public boolean strict_ISO; - - /** - * use bit reservoir? - */ - public boolean disable_reservoir; - - /* quantization/noise shaping */ - public int quant_comp; - public int quant_comp_short; - public boolean experimentalY; - public int experimentalZ; - public int exp_nspsytune; - - public int preset; - - /* VBR control */ - public VbrMode VBR; - /** - * Range [0,...,1[ - */ - public float VBR_q_frac; - /** - * Range [0,...,9] - */ - public int VBR_q; - public int VBR_mean_bitrate_kbps; - public int VBR_min_bitrate_kbps; - public int VBR_max_bitrate_kbps; - /** - * strictly enforce VBR_min_bitrate normaly, it will be violated for analog - * silence - */ - public int VBR_hard_min; - - /* resampling and filtering */ - - /** - * freq in Hz. 0=lame choses. -1=no filter - */ - public int lowpassfreq; - /** - * freq in Hz. 0=lame choses. -1=no filter - */ - public int highpassfreq; - /** - * freq width of filter, in Hz (default=15%) - */ - public int lowpasswidth; - /** - * freq width of filter, in Hz (default=15%) - */ - public int highpasswidth; - - /* - * psycho acoustics and other arguments which you should not change unless - * you know what you are doing - */ - - public float maskingadjust; - public float maskingadjust_short; - /** - * only use ATH - */ - public boolean ATHonly; - /** - * only use ATH for short blocks - */ - public boolean ATHshort; - /** - * disable ATH - */ - public boolean noATH; - /** - * select ATH formula - */ - public int ATHtype; - /** - * change ATH formula 4 shape - */ - public float ATHcurve; - /** - * lower ATH by this many db - */ - public float ATHlower; - /** - * select ATH auto-adjust scheme - */ - public int athaa_type; - /** - * select ATH auto-adjust loudness calc - */ - public int athaa_loudapprox; - /** - * dB, tune active region of auto-level - */ - public float athaa_sensitivity; - public ShortBlock short_blocks; - /** - * use temporal masking effect - */ - public Boolean useTemporal; - public float interChRatio; - /** - * Naoki's adjustment of Mid/Side maskings - */ - public float msfix; - - /** - * 0 off, 1 on - */ - public boolean tune; - /** - * used to pass values for debugging and stuff - */ - public float tune_value_a; - - /************************************************************************/ - /* internal variables, do not set... */ - /* provided because they may be of use to calling application */ - /************************************************************************/ - - /** - * 0=MPEG-2/2.5 1=MPEG-1 - */ - public int version; - public int encoder_delay; - /** - * number of samples of padding appended to input - */ - public int encoder_padding; - public int framesize; - /** - * number of frames encoded - */ - public int frameNum; - /** - * is this struct owned by calling program or lame? - */ - public int lame_allocated_gfp; - /**************************************************************************/ - /* more internal variables are stored in this structure: */ - /**************************************************************************/ - public LameInternalFlags internal_flags; - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/LameInternalFlags.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/LameInternalFlags.java deleted file mode 100644 index 61c2399f3..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/LameInternalFlags.java +++ /dev/null @@ -1,342 +0,0 @@ -package mp3; - -import mpg.MPGLib; - -public class LameInternalFlags { - - public static final int MFSIZE = (3 * 1152 + Encoder.ENCDELAY - Encoder.MDCTDELAY); - - public LameInternalFlags() { - for (int i = 0; i < en.length; i++) { - en[i] = new III_psy_xmin(); - } - for (int i = 0; i < thm.length; i++) { - thm[i] = new III_psy_xmin(); - } - for (int i = 0; i < header.length; i++) { - header[i] = new Header(); - } - } - - public static final int MAX_BITS_PER_CHANNEL = 4095; - public static final int MAX_BITS_PER_GRANULE = 7680; - - /******************************************************************** - * internal variables NOT set by calling program, and should not be * - * modified by the calling program * - ********************************************************************/ - - /** - * Some remarks to the Class_ID field: The Class ID is an Identifier for a - * pointer to this struct. It is very unlikely that a pointer to - * lame_global_flags has the same 32 bits in it's structure (large and other - * special properties, for instance prime). - * - * To test that the structure is right and initialized, use: if ( gfc . - * Class_ID == LAME_ID ) ... Other remark: If you set a flag to 0 for uninit - * data and 1 for init data, the right test should be "if (flag == 1)" and - * NOT "if (flag)". Unintended modification of this element will be - * otherwise misinterpreted as an init. - */ - public long Class_ID; - - public int lame_encode_frame_init; - public int iteration_init_init; - public int fill_buffer_resample_init; - - public float mfbuf[][] = new float[2][MFSIZE]; - - /** - * granules per frame - */ - public int mode_gr; - /** - * number of channels in the input data stream (PCM or decoded PCM) - */ - public int channels_in; - /** - * number of channels in the output data stream (not used for decoding) - */ - public int channels_out; - /** - * input_samp_rate/output_samp_rate - */ - public double resample_ratio; - - public int mf_samples_to_encode; - public int mf_size; - /** - * min bitrate index - */ - public int VBR_min_bitrate; - /** - * max bitrate index - */ - public int VBR_max_bitrate; - public int bitrate_index; - public int samplerate_index; - public int mode_ext; - - /* lowpass and highpass filter control */ - /** - * normalized frequency bounds of passband - */ - public float lowpass1, lowpass2; - /** - * normalized frequency bounds of passband - */ - public float highpass1, highpass2; - - /** - * 0 = none 1 = ISO AAC model 2 = allow scalefac_select=1 - */ - public int noise_shaping; - - /** - * 0 = ISO model: amplify all distorted bands<BR> - * 1 = amplify within 50% of max (on db scale)<BR> - * 2 = amplify only most distorted band<BR> - * 3 = method 1 and refine with method 2<BR> - */ - public int noise_shaping_amp; - /** - * 0 = no substep<BR> - * 1 = use substep shaping at last step(VBR only)<BR> - * (not implemented yet)<BR> - * 2 = use substep inside loop<BR> - * 3 = use substep inside loop and last step<BR> - */ - public int substep_shaping; - - /** - * 1 = gpsycho. 0 = none - */ - public int psymodel; - /** - * 0 = stop at over=0, all scalefacs amplified or<BR> - * a scalefac has reached max value<BR> - * 1 = stop when all scalefacs amplified or a scalefac has reached max value<BR> - * 2 = stop when all scalefacs amplified - */ - public int noise_shaping_stop; - - /** - * 0 = no, 1 = yes - */ - public int subblock_gain; - /** - * 0 = no. 1=outside loop 2=inside loop(slow) - */ - public int use_best_huffman; - - /** - * 0 = stop early after 0 distortion found. 1 = full search - */ - public int full_outer_loop; - - public IIISideInfo l3_side = new IIISideInfo(); - public float ms_ratio[] = new float[2]; - - /* used for padding */ - /** - * padding for the current frame? - */ - public int padding; - public int frac_SpF; - public int slot_lag; - - /** - * optional ID3 tags - */ - public ID3TagSpec tag_spec; - public int nMusicCRC; - - /* variables used by Quantize */ - public int OldValue[] = new int[2]; - public int CurrentStep[] = new int[2]; - - public float masking_lower; - public int bv_scf[] = new int[576]; - public int pseudohalf[] = new int[L3Side.SFBMAX]; - - /** - * will be set in lame_init_params - */ - public boolean sfb21_extra; - - /* BPC = maximum number of filter convolution windows to precompute */ - public static final int BPC = 320; - public float[][] inbuf_old = new float[2][]; - public float[][] blackfilt = new float[2 * BPC + 1][]; - public double itime[] = new double[2]; - public int sideinfo_len; - - /* variables for newmdct.c */ - public float sb_sample[][][][] = new float[2][2][18][Encoder.SBLIMIT]; - public float amp_filter[] = new float[32]; - - /* variables for BitStream */ - - /** - * <PRE> - * mpeg1: buffer=511 bytes smallest frame: 96-38(sideinfo)=58 - * max number of frames in reservoir: 8 - * mpeg2: buffer=255 bytes. smallest frame: 24-23bytes=1 - * with VBR, if you are encoding all silence, it is possible to - * have 8kbs/24khz frames with 1byte of data each, which means we need - * to buffer up to 255 headers! - * </PRE> - */ - /** - * also, max_header_buf has to be a power of two - */ - public static final int MAX_HEADER_BUF = 256; - /** - * max size of header is 38 - */ - private static final int MAX_HEADER_LEN = 40; - - public static class Header { - public int write_timing; - public int ptr; - public byte buf[] = new byte[MAX_HEADER_LEN]; - } - - public Header[] header = new Header[MAX_HEADER_BUF]; - - public int h_ptr; - public int w_ptr; - public int ancillary_flag; - - /* variables for Reservoir */ - /** - * in bits - */ - public int ResvSize; - /** - * in bits - */ - public int ResvMax; - - public ScaleFac scalefac_band = new ScaleFac(); - - /* daa from PsyModel */ - /* The static variables "r", "phi_sav", "new", "old" and "oldest" have */ - /* to be remembered for the unpredictability measure. For "r" and */ - /* "phi_sav", the first index from the left is the channel select and */ - /* the second index is the "age" of the data. */ - public float minval_l[] = new float[Encoder.CBANDS]; - public float minval_s[] = new float[Encoder.CBANDS]; - public float nb_1[][] = new float[4][Encoder.CBANDS], - nb_2[][] = new float[4][Encoder.CBANDS]; - public float nb_s1[][] = new float[4][Encoder.CBANDS], - nb_s2[][] = new float[4][Encoder.CBANDS]; - public float[] s3_ss; - public float[] s3_ll; - public float decay; - - public III_psy_xmin[] thm = new III_psy_xmin[4]; - public III_psy_xmin[] en = new III_psy_xmin[4]; - - /** - * fft and energy calculation - */ - public float tot_ener[] = new float[4]; - - /* loudness calculation (for adaptive threshold of hearing) */ - /** - * loudness^2 approx. per granule and channel - */ - public float loudness_sq[][] = new float[2][2]; - /** - * account for granule delay of L3psycho_anal - */ - public float loudness_sq_save[] = new float[2]; - - /** - * Scale Factor Bands - */ - public float mld_l[] = new float[Encoder.SBMAX_l], - mld_s[] = new float[Encoder.SBMAX_s]; - public int bm_l[] = new int[Encoder.SBMAX_l], - bo_l[] = new int[Encoder.SBMAX_l]; - public int bm_s[] = new int[Encoder.SBMAX_s], - bo_s[] = new int[Encoder.SBMAX_s]; - public int npart_l, npart_s; - - public int s3ind[][] = new int[Encoder.CBANDS][2]; - public int s3ind_s[][] = new int[Encoder.CBANDS][2]; - - public int numlines_s[] = new int[Encoder.CBANDS]; - public int numlines_l[] = new int[Encoder.CBANDS]; - public float rnumlines_l[] = new float[Encoder.CBANDS]; - public float mld_cb_l[] = new float[Encoder.CBANDS], - mld_cb_s[] = new float[Encoder.CBANDS]; - public int numlines_s_num1; - public int numlines_l_num1; - - /* ratios */ - public float pe[] = new float[4]; - public float ms_ratio_s_old, ms_ratio_l_old; - public float ms_ener_ratio_old; - - /** - * block type - */ - public int blocktype_old[] = new int[2]; - - /** - * variables used for --nspsytune - */ - public NsPsy nsPsy = new NsPsy(); - - /** - * used for Xing VBR header - */ - public VBRSeekInfo VBR_seek_table = new VBRSeekInfo(); - - /** - * all ATH related stuff - */ - public ATH ATH; - - public PSY PSY; - - public int nogap_total; - public int nogap_current; - - /* ReplayGain */ - public boolean decode_on_the_fly = true; - public boolean findReplayGain = true; - public boolean findPeakSample = true; - public float PeakSample; - public int RadioGain; - public int AudiophileGain; - public ReplayGain rgdata; - - /** - * gain change required for preventing clipping - */ - public int noclipGainChange; - /** - * user-specified scale factor required for preventing clipping - */ - public float noclipScale; - - /* simple statistics */ - public int bitrate_stereoMode_Hist[][] = new int[16][4 + 1]; - /** - * norm/start/short/stop/mixed(short)/sum - */ - public int bitrate_blockType_Hist[][] = new int[16][4 + 1 + 1]; - - public PlottingData pinfo; - public MPGLib.mpstr_tag hip; - - public int in_buffer_nsamples; - public float[] in_buffer_0; - public float[] in_buffer_1; - - public IIterationLoop iteration_loop; - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/LameTest.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/LameTest.java deleted file mode 100644 index 348180fda..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/LameTest.java +++ /dev/null @@ -1,180 +0,0 @@ -package mp3; - -import mpg.Common; -import mpg.Interface; -import mpg.MPGLib; -import org.junit.Assert; -import org.junit.Test; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.MappedByteBuffer; -import java.nio.ShortBuffer; -import java.nio.channels.FileChannel; -import java.nio.file.StandardOpenOption; - -public class LameTest { - -/* - @Test - public void testEncode() throws IOException { - Lame lame = new Lame(); - GetAudio gaud = new GetAudio(); - GainAnalysis ga = new GainAnalysis(); - BitStream bs = new BitStream(); - Presets p = new Presets(); - QuantizePVT qupvt = new QuantizePVT(); - Quantize qu = new Quantize(); - VBRTag vbr = new VBRTag(); - Version ver = new Version(); - ID3Tag id3 = new ID3Tag(); - Reservoir rv = new Reservoir(); - Takehiro tak = new Takehiro(); - Parse parse = new Parse(); - BRHist hist = new BRHist(); - - MPGLib mpg = new MPGLib(); - Interface intf = new Interface(); - Common common = new Common(); - - lame.setModules(ga, bs, p, qupvt, qu, vbr, ver, id3, mpg); - bs.setModules(ga, mpg, ver, vbr); - id3.setModules(bs, ver); - p.setModules(lame); - qu.setModules(bs, rv, qupvt, tak); - qupvt.setModules(tak, rv, lame.enc.psy); - rv.setModules(bs); - tak.setModules(qupvt); - vbr.setModules(lame, bs, ver); - gaud.setModules(parse, mpg); - parse.setModules(ver, id3, p); - - LameGlobalFlags gfp = lame.lame_init(); - - gfp.num_channels = 1; - gfp.in_samplerate = 48000; - gfp.brate = 128; - gfp.mode = MPEGMode.STEREO; - gfp.quality = 3; - gfp.bWriteVbrTag = false; - gfp.disable_reservoir = true; - gfp.write_id3tag_automatic = false; - - int retcode = lame.lame_init_params(gfp); - System.out.println("DONE " + retcode); - - File file = new File("/Users/zhukov/git/tle1.3x/test-data/wav/440880.wav"); - MappedByteBuffer map = FileChannel.open(file.toPath(), StandardOpenOption.READ).map(FileChannel.MapMode.READ_ONLY, 0, file.length()); - map.order(ByteOrder.LITTLE_ENDIAN); - int dataLen = map.getInt(0x28); - map.position(0x2c); - map.limit(0x2c + dataLen); - ShortBuffer samples = map.slice().order(ByteOrder.LITTLE_ENDIAN).asShortBuffer(); - short i = samples.get(1); - Assert.assertEquals(0x05e6, i); - System.out.println(samples + " " + Integer.toHexString(i)); - int remaining = samples.remaining(); - short[] left = new short[remaining]; - short[] right = new short[remaining]; - samples.clear(); - samples.get(left); - samples.clear(); - samples.get(right); - - int mp3buf_size = (int) (1.25 * remaining + 7200); - byte[] mp3buf = new byte[mp3buf_size]; - int mp3bufPos = 0; - int _sz = lame.lame_encode_buffer(gfp, left, right, remaining, - mp3buf, mp3bufPos, mp3buf_size); - System.out.println("lame_encode_buffer: " + _sz); - } -*/ - - @Test - public void testEncodeChugai() throws IOException { - Lame lame = new Lame(); - GetAudio gaud = new GetAudio(); - GainAnalysis ga = new GainAnalysis(); - BitStream bs = new BitStream(); - Presets p = new Presets(); - QuantizePVT qupvt = new QuantizePVT(); - Quantize qu = new Quantize(); - VBRTag vbr = new VBRTag(); - Version ver = new Version(); - ID3Tag id3 = new ID3Tag(); - Reservoir rv = new Reservoir(); - Takehiro tak = new Takehiro(); - Parse parse = new Parse(); - BRHist hist = new BRHist(); - - MPGLib mpg = new MPGLib(); - Interface intf = new Interface(); - Common common = new Common(); - - lame.setModules(ga, bs, p, qupvt, qu, vbr, ver, id3, mpg); - bs.setModules(ga, mpg, ver, vbr); - id3.setModules(bs, ver); - p.setModules(lame); - qu.setModules(bs, rv, qupvt, tak); - qupvt.setModules(tak, rv, lame.enc.psy); - rv.setModules(bs); - tak.setModules(qupvt); - vbr.setModules(lame, bs, ver); - gaud.setModules(parse, mpg); - parse.setModules(ver, id3, p); - - LameGlobalFlags gfp = lame.lame_init(); - - gfp.num_channels = 2; - gfp.in_samplerate = 48000; - gfp.brate = 128; - gfp.mode = MPEGMode.STEREO; - gfp.quality = 3; - gfp.bWriteVbrTag = false; - gfp.disable_reservoir = true; - gfp.write_id3tag_automatic = false; - - int retcode = lame.lame_init_params(gfp); - System.out.println("DONE " + retcode); - -// File file = new File("/Users/zhukov/git/tle1.3x/test-data/wav/440880.wav"); - File file = new File("/Users/chugai/dev/DPlayer/merm2/proxy/c00.wav"); - MappedByteBuffer map = FileChannel.open(file.toPath(), StandardOpenOption.READ).map(FileChannel.MapMode.READ_ONLY, 0, file.length()); - map.order(ByteOrder.LITTLE_ENDIAN); - int dataLen = map.getInt(0x28); - map.position(0x2c); - map.limit(0x2c + dataLen); - - ShortBuffer samples = map.slice().order(ByteOrder.LITTLE_ENDIAN).asShortBuffer(); - samples.limit(1152 * 8); - Assert.assertEquals(0, samples.get(0)); - Assert.assertEquals(943, samples.get(1)); - int remaining = samples.remaining(); - - int[] left = new int[remaining]; - for (int i = 0; i < remaining; i++) - left[i] = samples.get(i); - - int mp3buf_size = (int) (1.25 * remaining + 7200); - byte[] mp3buf = new byte[mp3buf_size]; - int mp3bufPos = 0; - - int _sz = lame.lame_encode_buffer_int(gfp, left, left, remaining, - mp3buf, mp3bufPos, mp3buf_size); - mp3bufPos += _sz; - System.out.println("lame_encode_buffer: " + _sz); - - _sz = lame.lame_encode_flush(gfp, mp3buf, mp3bufPos, mp3buf_size); - mp3bufPos += _sz; - System.out.println("lame_encode_flush: " + _sz); - - OutputStream out = new BufferedOutputStream(new FileOutputStream("/Users/chugai/Downloads/generated_java.mp3")); - out.write(mp3buf, 0, mp3bufPos); - out.close(); - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/LongBlockConstrain.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/LongBlockConstrain.java deleted file mode 100644 index d8bff1adc..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/LongBlockConstrain.java +++ /dev/null @@ -1,156 +0,0 @@ -package mp3; - -import mp3.VBRQuantize.algo_t; - -final class LongBlockConstrain implements VBRQuantize.alloc_sf_f { - /** - * - */ - private final VBRQuantize vbrQuantize; - - /** - * @param vbrQuantize - */ - LongBlockConstrain(VBRQuantize vbrQuantize) { - this.vbrQuantize = vbrQuantize; - } - - /****************************************************************** - * - * long block scalefacs - * - ******************************************************************/ - - public void alloc(algo_t that, int[] vbrsf, int[] vbrsfmin, int vbrmax) { - final GrInfo cod_info = that.cod_info; - final LameInternalFlags gfc = that.gfc; - int[] max_rangep; - final int maxminsfb = that.mingain_l; - int sfb; - int maxover0, maxover1, maxover0p, maxover1p, mover, delta = 0; - int v, v0, v1, v0p, v1p, vm0p = 1, vm1p = 1; - final int psymax = cod_info.psymax; - - max_rangep = gfc.mode_gr == 2 ? VBRQuantize.max_range_long - : VBRQuantize.max_range_long_lsf_pretab; - - maxover0 = 0; - maxover1 = 0; - maxover0p = 0; /* pretab */ - maxover1p = 0; /* pretab */ - - for (sfb = 0; sfb < psymax; ++sfb) { - assert (vbrsf[sfb] >= vbrsfmin[sfb]); - v = vbrmax - vbrsf[sfb]; - if (delta < v) { - delta = v; - } - v0 = v - 2 * VBRQuantize.max_range_long[sfb]; - v1 = v - 4 * VBRQuantize.max_range_long[sfb]; - v0p = v - 2 - * (max_rangep[sfb] + this.vbrQuantize.qupvt.pretab[sfb]); - v1p = v - 4 - * (max_rangep[sfb] + this.vbrQuantize.qupvt.pretab[sfb]); - if (maxover0 < v0) { - maxover0 = v0; - } - if (maxover1 < v1) { - maxover1 = v1; - } - if (maxover0p < v0p) { - maxover0p = v0p; - } - if (maxover1p < v1p) { - maxover1p = v1p; - } - } - if (vm0p == 1) { - int gain = vbrmax - maxover0p; - if (gain < maxminsfb) { - gain = maxminsfb; - } - for (sfb = 0; sfb < psymax; ++sfb) { - final int a = (gain - vbrsfmin[sfb]) - 2 - * this.vbrQuantize.qupvt.pretab[sfb]; - if (a <= 0) { - vm0p = 0; - vm1p = 0; - break; - } - } - } - if (vm1p == 1) { - int gain = vbrmax - maxover1p; - if (gain < maxminsfb) { - gain = maxminsfb; - } - for (sfb = 0; sfb < psymax; ++sfb) { - final int b = (gain - vbrsfmin[sfb]) - 4 - * this.vbrQuantize.qupvt.pretab[sfb]; - if (b <= 0) { - vm1p = 0; - break; - } - } - } - if (vm0p == 0) { - maxover0p = maxover0; - } - if (vm1p == 0) { - maxover1p = maxover1; - } - if (gfc.noise_shaping != 2) { - maxover1 = maxover0; - maxover1p = maxover0p; - } - mover = Math.min(maxover0, maxover0p); - mover = Math.min(mover, maxover1); - mover = Math.min(mover, maxover1p); - - if (delta > mover) { - delta = mover; - } - vbrmax -= delta; - if (vbrmax < maxminsfb) { - vbrmax = maxminsfb; - } - maxover0 -= mover; - maxover0p -= mover; - maxover1 -= mover; - maxover1p -= mover; - - if (maxover0 == 0) { - cod_info.scalefac_scale = 0; - cod_info.preflag = 0; - max_rangep = VBRQuantize.max_range_long; - } else if (maxover0p == 0) { - cod_info.scalefac_scale = 0; - cod_info.preflag = 1; - } else if (maxover1 == 0) { - cod_info.scalefac_scale = 1; - cod_info.preflag = 0; - max_rangep = VBRQuantize.max_range_long; - } else if (maxover1p == 0) { - cod_info.scalefac_scale = 1; - cod_info.preflag = 1; - } else { - assert (false); /* this should not happen */ - } - cod_info.global_gain = vbrmax; - if (cod_info.global_gain < 0) { - cod_info.global_gain = 0; - } else if (cod_info.global_gain > 255) { - cod_info.global_gain = 255; - } - { - int sf_temp[] = new int[L3Side.SFBMAX]; - for (sfb = 0; sfb < L3Side.SFBMAX; ++sfb) { - sf_temp[sfb] = vbrsf[sfb] - vbrmax; - } - this.vbrQuantize.set_scalefacs(cod_info, vbrsfmin, sf_temp, - max_rangep); - } - assert (this.vbrQuantize.checkScalefactor(cod_info, vbrsfmin)); - - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/MP3Data.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/MP3Data.java deleted file mode 100644 index a1011ddfd..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/MP3Data.java +++ /dev/null @@ -1,50 +0,0 @@ -package mp3; - -public class MP3Data { - /** - * true if header was parsed and following data was computed - */ - public boolean header_parsed; - /** - * number of channels - */ - public int stereo; - /** - * sample rate - */ - public int samplerate; - /** - * bitrate - */ - public int bitrate; - /** - * mp3 frame type - */ - public int mode; - /** - * mp3 frame type - */ - public int mode_ext; - /** - * number of samples per mp3 frame - */ - public int framesize; - - /* this data is only computed if mpglib detects a Xing VBR header */ - - /** - * number of samples in mp3 file. - */ - public int nsamp; - /** - * total number of frames in mp3 file - */ - public int totalframes; - - /* this data is not currently computed by the mpglib routines */ - - /** - * frames decoded counter - */ - public int framenum; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/MPEGMode.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/MPEGMode.java deleted file mode 100644 index 95cb5bf66..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/MPEGMode.java +++ /dev/null @@ -1,10 +0,0 @@ -package mp3; - -/* MPEG modes */ -public enum MPEGMode { - STEREO, JOINT_STEREO, - /** - * LAME doesn't supports this! - */ - DUAL_CHANNEL, MONO, NOT_SET -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Main.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Main.java deleted file mode 100644 index e982b40d0..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Main.java +++ /dev/null @@ -1,979 +0,0 @@ -/* - * Command line frontend program - * - * Copyright (c) 1999 Mark Taylor - * 2000 Takehiro TOMINAGA - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: Main.java,v 1.38 2011/08/27 18:57:12 kenchis Exp $ */ - -package mp3; - -import java.beans.PropertyChangeSupport; -import java.io.Closeable; -import java.io.DataOutput; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.util.ArrayList; -import java.util.Locale; -import java.util.StringTokenizer; - -import mp3.GetAudio.sound_file_format; -import mpg.Common; -import mpg.Interface; -import mpg.MPGLib; - -public class Main { - - private GetAudio gaud; - private ID3Tag id3; - private Lame lame; - private GainAnalysis ga; - private BitStream bs; - private Presets p; - private QuantizePVT qupvt; - private Quantize qu; - private VBRTag vbr; - private Version ver; - private Reservoir rv; - private Takehiro tak; - private Parse parse; - private BRHist hist; - - private MPGLib mpg; - private Interface intf; - private Common common; - - private PropertyChangeSupport support = new PropertyChangeSupport(this); - - public PropertyChangeSupport getSupport() { - return support; - } - - /** - * PURPOSE: MPEG-1,2 Layer III encoder with GPSYCHO psychoacoustic model. - */ - private int parse_args_from_string(final LameGlobalFlags gfp, - final String argv, final StringBuilder inPath, - final StringBuilder outPath) { - /* Quick & very Dirty */ - if (argv == null || argv.length() == 0) - return 0; - - StringTokenizer tok = new StringTokenizer(argv, " "); - ArrayList<String> args = new ArrayList<String>(); - while (tok.hasMoreTokens()) { - args.add(tok.nextToken()); - } - return parse.parse_args(gfp, args, inPath, outPath, null, null); - } - - public DataOutput init_files(final LameGlobalFlags gf, - final String inPath, final String outPath, final Enc enc) { - /* - * Mostly it is not useful to use the same input and output name. This - * test is very easy and buggy and don't recognize different names - * assigning the same file - */ - if (inPath.equals(outPath)) { - System.err - .println("Input file and Output file are the same. Abort."); - return null; - } - - /* - * open the wav/aiff/raw pcm or mp3 input file. This call will open the - * file, try to parse the headers and set gf.samplerate, - * gf.num_channels, gf.num_samples. if you want to do your own file - * input, skip this call and set samplerate, num_channels and - * num_samples yourself. - */ - gaud.init_infile(gf, inPath, enc); - - DataOutput outf; - if ((outf = gaud.init_outfile(outPath)) == null) { - System.err.printf("Can't init outfile '%s'\n", outPath); - return null; - } - - return outf; - } - - /** - * the simple lame decoder - * - * After calling lame_init(), lame_init_params() and init_infile(), call - * this routine to read the input MP3 file and output .wav data to the - * specified file pointer - * - * lame_decoder will ignore the first 528 samples, since these samples - * represent the mpglib delay (and are all 0). skip = number of additional - * samples to skip, to (for example) compensate for the encoder delay - */ - private void lame_decoder(final LameGlobalFlags gfp, - DataOutput outf, int skip_start, final String inPath, - final String outPath, final Enc enc) throws IOException { - short Buffer[][] = new short[2][1152]; - int iread; - int skip_end = 0; - int i; - int tmp_num_channels = gfp.num_channels; - - if (parse.silent < 10) - System.out.printf("\rinput: %s%s(%g kHz, %d channel%s, ", inPath, - inPath.length() > 26 ? "\n\t" : " ", - gfp.in_samplerate / 1.e3, tmp_num_channels, - tmp_num_channels != 1 ? "s" : ""); - - switch (parse.input_format) { - case sf_mp123: /* FIXME: !!! */ - throw new RuntimeException("Internal error. Aborting."); - - case sf_mp3: - if (skip_start == 0) { - if (enc.enc_delay > -1 || enc.enc_padding > -1) { - if (enc.enc_delay > -1) - skip_start = enc.enc_delay + 528 + 1; - if (enc.enc_padding > -1) - skip_end = enc.enc_padding - (528 + 1); - } else - skip_start = gfp.encoder_delay + 528 + 1; - } else { - /* user specified a value of skip. just add for decoder */ - skip_start += 528 + 1; - /* - * mp3 decoder has a 528 sample delay, plus user supplied "skip" - */ - } - - if (parse.silent < 10) - System.out.printf("MPEG-%d%s Layer %s", 2 - gfp.version, - gfp.out_samplerate < 16000 ? ".5" : "", "III"); - break; - case sf_mp2: - skip_start += 240 + 1; - if (parse.silent < 10) - System.out.printf("MPEG-%d%s Layer %s", 2 - gfp.version, - gfp.out_samplerate < 16000 ? ".5" : "", "II"); - break; - case sf_mp1: - skip_start += 240 + 1; - if (parse.silent < 10) - System.out.printf("MPEG-%d%s Layer %s", 2 - gfp.version, - gfp.out_samplerate < 16000 ? ".5" : "", "I"); - break; - case sf_raw: - if (parse.silent < 10) - System.out.printf("raw PCM data"); - parse.mp3input_data.nsamp = gfp.num_samples; - parse.mp3input_data.framesize = 1152; - skip_start = 0; - /* other formats have no delay */ - break; - case sf_wave: - if (parse.silent < 10) - System.out.printf("Microsoft WAVE"); - parse.mp3input_data.nsamp = gfp.num_samples; - parse.mp3input_data.framesize = 1152; - skip_start = 0; - /* other formats have no delay */ - break; - case sf_aiff: - if (parse.silent < 10) - System.out.printf("SGI/Apple AIFF"); - parse.mp3input_data.nsamp = gfp.num_samples; - parse.mp3input_data.framesize = 1152; - skip_start = 0; - /* other formats have no delay */ - break; - default: - if (parse.silent < 10) - System.out.printf("unknown"); - parse.mp3input_data.nsamp = gfp.num_samples; - parse.mp3input_data.framesize = 1152; - skip_start = 0; - /* other formats have no delay */ - assert (false); - break; - } - - if (parse.silent < 10) { - System.out.printf(")\noutput: %s%s(16 bit, Microsoft WAVE)\n", - outPath, outPath.length() > 45 ? "\n\t" : " "); - - if (skip_start > 0) - System.out - .printf("skipping initial %d samples (encoder+decoder delay)\n", - skip_start); - if (skip_end > 0) - System.out - .printf("skipping final %d samples (encoder padding-decoder delay)\n", - skip_end); - } - - System.out.print("|"); - for (int j = 0; j < MAX_WIDTH - 2; j++) { - System.out.print("="); - } - System.out.println("|"); - oldPercent = curPercent = oldConsoleX = 0; - - if (!parse.disable_wav_header) - gaud.WriteWaveHeader(outf, Integer.MAX_VALUE, gfp.in_samplerate, - tmp_num_channels, 16); - /* unknown size, so write maximum 32 bit signed value */ - - double wavsize = -(skip_start + skip_end); - parse.mp3input_data.totalframes = parse.mp3input_data.nsamp - / parse.mp3input_data.framesize; - - assert (tmp_num_channels >= 1 && tmp_num_channels <= 2); - - do { - iread = gaud.get_audio16(gfp, Buffer); - /* read in 'iread' samples */ - if (iread >= 0) { - parse.mp3input_data.framenum += iread - / parse.mp3input_data.framesize; - wavsize += iread; - - if (parse.silent <= 0) { - timestatus(parse.mp3input_data.framenum, - parse.mp3input_data.totalframes); - } - - skip_start -= (i = skip_start < iread ? skip_start : iread); - /* - * 'i' samples are to skip in this frame - */ - - if (skip_end > 1152 - && parse.mp3input_data.framenum + 2 > parse.mp3input_data.totalframes) { - iread -= (skip_end - 1152); - skip_end = 1152; - } else if (parse.mp3input_data.framenum == parse.mp3input_data.totalframes - && iread != 0) - iread -= skip_end; - - for (; i < iread; i++) { - if (parse.disable_wav_header) { - if (parse.swapbytes) { - WriteBytesSwapped(outf, Buffer[0], i); - } else { - WriteBytes(outf, Buffer[0], i); - } - if (tmp_num_channels == 2) { - if (parse.swapbytes) { - WriteBytesSwapped(outf, Buffer[1], i); - } else { - WriteBytes(outf, Buffer[1], i); - } - } - } else { - gaud.write16BitsLowHigh(outf, Buffer[0][i] & 0xffff); - if (tmp_num_channels == 2) - gaud.write16BitsLowHigh(outf, Buffer[1][i] & 0xffff); - } - } - } - } while (iread > 0); - - i = (16 / 8) * tmp_num_channels; - assert (i > 0); - if (wavsize <= 0) { - if (parse.silent < 10) - System.err.println("WAVE file contains 0 PCM samples"); - wavsize = 0; - } else if (wavsize > 0xFFFFFFD0L / i) { - if (parse.silent < 10) - System.err - .println("Very huge WAVE file, can't set filesize accordingly"); - wavsize = 0xFFFFFFD0; - } else { - wavsize *= i; - } - - ((Closeable)outf).close(); - /* if outf is seekable, rewind and adjust length */ - if (!parse.disable_wav_header) { - RandomAccessFile rf = new RandomAccessFile(outPath, "rw"); - gaud.WriteWaveHeader(rf, (int) wavsize, gfp.in_samplerate, - tmp_num_channels, 16); - rf.close(); - } - - System.out.print("|"); - for (int j = 0; j < MAX_WIDTH - 2; j++) { - System.out.print("="); - } - System.out.println("|"); - } - - private void print_lame_tag_leading_info(final LameGlobalFlags gf) { - if (gf.bWriteVbrTag) - System.out.println("Writing LAME Tag..."); - } - - private void print_trailing_info(final LameGlobalFlags gf) { - if (gf.bWriteVbrTag) - System.out.println("done\n"); - - if (gf.findReplayGain) { - int RadioGain = gf.internal_flags.RadioGain; - System.out.printf("ReplayGain: %s%.1fdB\n", RadioGain > 0 ? "+" - : "", (RadioGain) / 10.0f); - if (RadioGain > 0x1FE || RadioGain < -0x1FE) - System.out - .println("WARNING: ReplayGain exceeds the -51dB to +51dB range. Such a result is too\n" - + " high to be stored in the header."); - } - - /* - * if (the user requested printing info about clipping) and (decoding on - * the fly has actually been performed) - */ - if (parse.print_clipping_info && gf.decode_on_the_fly) { - float noclipGainChange = (float) gf.internal_flags.noclipGainChange / 10.0f; - float noclipScale = gf.internal_flags.noclipScale; - - if (noclipGainChange > 0.0) { - /* clipping occurs */ - System.out - .printf("WARNING: clipping occurs at the current gain. Set your decoder to decrease\n" - + " the gain by at least %.1fdB or encode again ", - noclipGainChange); - - /* advice the user on the scale factor */ - if (noclipScale > 0) { - System.out.printf(Locale.US, "using --scale %.2f\n", noclipScale); - System.out - .print(" or less (the value under --scale is approximate).\n"); - } else { - /* - * the user specified his own scale factor. We could suggest - * the scale factor of - * (32767.0/gfp->PeakSample)*(gfp->scale) but it's usually - * very inaccurate. So we'd rather advice him to disable - * scaling first and see our suggestion on the scale factor - * then. - */ - System.out - .print("using --scale <arg>\n" - + " (For a suggestion on the optimal value of <arg> encode\n" - + " with --scale 1 first)\n"); - } - - } else { /* no clipping */ - if (noclipGainChange > -0.1) - System.out - .print("\nThe waveform does not clip and is less than 0.1dB away from full scale.\n"); - else - System.out - .printf("\nThe waveform does not clip and is at least %.1fdB away from full scale.\n", - -noclipGainChange); - } - } - - } - - private int write_xing_frame(final LameGlobalFlags gf, - final RandomAccessFile outf) { - byte mp3buffer[] = new byte[Lame.LAME_MAXMP3BUFFER]; - - int imp3 = vbr.getLameTagFrame(gf, mp3buffer); - if (imp3 > mp3buffer.length) { - System.err - .printf("Error writing LAME-tag frame: buffer too small: buffer size=%d frame size=%d\n", - mp3buffer.length, imp3); - return -1; - } - if (imp3 <= 0) { - return 0; - } - try { - outf.write(mp3buffer, 0, imp3); - } catch (IOException e) { - System.err.println("Error writing LAME-tag"); - return -1; - } - return imp3; - } - - private int lame_encoder(final LameGlobalFlags gf, - final DataOutput outf, final boolean nogap, - final String inPath, final String outPath) { - byte mp3buffer[] = new byte[Lame.LAME_MAXMP3BUFFER]; - int Buffer[][] = new int[2][1152]; - int iread; - - encoder_progress_begin(gf, inPath, outPath); - - int imp3 = id3.lame_get_id3v2_tag(gf, mp3buffer, mp3buffer.length); - if (imp3 > mp3buffer.length) { - encoder_progress_end(gf); - System.err - .printf("Error writing ID3v2 tag: buffer too small: buffer size=%d ID3v2 size=%d\n", - mp3buffer.length, imp3); - return 1; - } - try { - outf.write(mp3buffer, 0, imp3); - } catch (IOException e) { - encoder_progress_end(gf); - System.err.printf("Error writing ID3v2 tag \n"); - return 1; - } - int id3v2_size = imp3; - - /* encode until we hit eof */ - do { - /* read in 'iread' samples */ - iread = gaud.get_audio(gf, Buffer); - - if (iread >= 0) { - encoder_progress(gf); - - /* encode */ - imp3 = lame.lame_encode_buffer_int(gf, Buffer[0], Buffer[1], - iread, mp3buffer, 0, mp3buffer.length); - - /* was our output buffer big enough? */ - if (imp3 < 0) { - if (imp3 == -1) - System.err.printf("mp3 buffer is not big enough... \n"); - else - System.err.printf( - "mp3 internal error: error code=%d\n", imp3); - return 1; - } - - try { - outf.write(mp3buffer, 0, imp3); - } catch (IOException e) { - encoder_progress_end(gf); - System.err.printf("Error writing mp3 output \n"); - return 1; - } - } - } while (iread > 0); - - if (nogap) - imp3 = lame - .lame_encode_flush_nogap(gf, mp3buffer, mp3buffer.length); - /* - * may return one more mp3 frame - */ - else - imp3 = lame.lame_encode_flush(gf, mp3buffer, 0, mp3buffer.length); - /* - * may return one more mp3 frame - */ - - if (imp3 < 0) { - if (imp3 == -1) - System.err.printf("mp3 buffer is not big enough... \n"); - else - System.err.printf("mp3 internal error: error code=%d\n", imp3); - return 1; - - } - - encoder_progress_end(gf); - - try { - outf.write(mp3buffer, 0, imp3); - } catch (IOException e) { - encoder_progress_end(gf); - System.err.printf("Error writing mp3 output \n"); - return 1; - } - - imp3 = id3.lame_get_id3v1_tag(gf, mp3buffer, mp3buffer.length); - if (imp3 > mp3buffer.length) { - System.err - .printf("Error writing ID3v1 tag: buffer too small: buffer size=%d ID3v1 size=%d\n", - mp3buffer.length, imp3); - } else { - if (imp3 > 0) { - try { - outf.write(mp3buffer, 0, imp3); - } catch (IOException e) { - encoder_progress_end(gf); - System.err.printf("Error writing ID3v1 tag \n"); - return 1; - } - } - } - - if (parse.silent <= 0) { - print_lame_tag_leading_info(gf); - } - try { - ((Closeable)outf).close(); - RandomAccessFile rf = new RandomAccessFile(outPath, "rw"); - rf.seek(id3v2_size); - write_xing_frame(gf, rf); - rf.close(); - } catch (IOException e) { - System.err.printf("fatal error: can't update LAME-tag frame!\n"); - } - - print_trailing_info(gf); - return 0; - } - - private void brhist_init_package(final LameGlobalFlags gf) { - if (parse.brhist) { - if (hist.brhist_init(gf, gf.VBR_min_bitrate_kbps, - gf.VBR_max_bitrate_kbps) != 0) { - /* fail to initialize */ - parse.brhist = false; - } - } else { - hist.brhist_init(gf, 128, 128); - /* Dirty hack */ - } - } - - private void parse_nogap_filenames(final int nogapout, final String inPath, - final StringBuilder outPath, final StringBuilder outdir) { - outPath.setLength(0); - outPath.append(outdir); - if (0 == nogapout) { - outPath.setLength(0); - outPath.append(inPath); - /* nuke old extension, if one */ - if (outPath.toString().endsWith(".wav")) { - outPath.setLength(0); - outPath.append(outPath.substring(0, outPath.length() - 4) - + ".mp3"); - } else { - outPath.setLength(0); - outPath.append(outPath + ".mp3"); - } - } else { - int slasher = inPath.lastIndexOf(System - .getProperty("file.separator")); - - /* backseek to last dir delemiter */ - - /* skip one foward if needed */ - if (slasher != 0 - && (outPath.toString().endsWith( - System.getProperty("file.separator")) || outPath - .toString().endsWith(":"))) - slasher++; - else if (slasher == 0 - && (!outPath.toString().endsWith( - System.getProperty("file.separator")) || outPath - .toString().endsWith(":"))) - outPath.append(System.getProperty("file.separator")); - - outPath.append(inPath.substring(slasher)); - /* nuke old extension */ - if (outPath.toString().endsWith(".wav")) { - String string = outPath.substring(0, outPath.length() - 4) - + ".mp3"; - outPath.setLength(0); - outPath.append(string); - } else { - String string = outPath + ".mp3"; - outPath.setLength(0); - outPath.append(string); - } - } - } - - private static final int MAX_NOGAP = 200; - - public static final void main(final String[] args) { - try { - new Main().run(args); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public int run(String[] args) throws IOException { - // encoder modules - lame = new Lame(); - gaud = new GetAudio(); - ga = new GainAnalysis(); - bs = new BitStream(); - p = new Presets(); - qupvt = new QuantizePVT(); - qu = new Quantize(); - vbr = new VBRTag(); - ver = new Version(); - id3 = new ID3Tag(); - rv = new Reservoir(); - tak = new Takehiro(); - parse = new Parse(); - hist = new BRHist(); - - mpg = new MPGLib(); - intf = new Interface(); - common = new Common(); - - lame.setModules(ga, bs, p, qupvt, qu, vbr, ver, id3, mpg); - bs.setModules(ga, mpg, ver, vbr); - id3.setModules(bs, ver); - p.setModules(lame); - qu.setModules(bs, rv, qupvt, tak); - qupvt.setModules(tak, rv, lame.enc.psy); - rv.setModules(bs); - tak.setModules(qupvt); - vbr.setModules(lame, bs, ver); - gaud.setModules(parse, mpg); - parse.setModules(ver, id3, p); - - // decoder modules - mpg.setModules(intf, common); - intf.setModules(vbr, common); - - StringBuilder outPath = new StringBuilder(); - StringBuilder nogapdir = new StringBuilder(); - StringBuilder inPath = new StringBuilder(); - - /* add variables for encoder delay/padding */ - Enc enc = new Enc(); - - /* support for "nogap" encoding of up to 200 .wav files */ - int nogapout = 0; - int max_nogap = MAX_NOGAP; - String[] nogap_inPath = new String[max_nogap]; - DataOutput outf; - - /* initialize libmp3lame */ - parse.input_format = sound_file_format.sf_unknown; - LameGlobalFlags gf = lame.lame_init(); - if (args.length < 1) { - parse.usage(System.err, "lame"); - /* - * no command-line args, print usage, exit - */ - lame.lame_close(gf); - return 1; - } - - /* - * parse the command line arguments, setting various flags in the struct - * 'gf'. If you want to parse your own arguments, or call libmp3lame - * from a program which uses a GUI to set arguments, skip this call and - * set the values of interest in the gf struct. (see the file API and - * lame.h for documentation about these parameters) - */ - parse_args_from_string(gf, System.getenv("LAMEOPT"), inPath, outPath); - ArrayList<String> argsList = new ArrayList<String>(); - for (int i = 0; i < args.length; i++) { - argsList.add(args[i]); - } - Parse.NoGap ng = new Parse.NoGap(); - int ret = parse.parse_args(gf, argsList, inPath, outPath, nogap_inPath, ng); - max_nogap = ng.num_nogap; - if (ret < 0) { - lame.lame_close(gf); - return ret == -2 ? 0 : 1; - } - - if (parse.update_interval < 0.) - parse.update_interval = 2.f; - - if (outPath.length() != 0 && max_nogap > 0) { - nogapdir = outPath; - nogapout = 1; - } - - /* - * initialize input file. This also sets samplerate and as much other - * data on the input file as available in the headers - */ - if (max_nogap > 0) { - /* - * for nogap encoding of multiple input files, it is not possible to - * specify the output file name, only an optional output directory. - */ - parse_nogap_filenames(nogapout, nogap_inPath[0], outPath, nogapdir); - outf = init_files(gf, nogap_inPath[0], outPath.toString(), enc); - } else { - outf = init_files(gf, inPath.toString(), outPath.toString(), enc); - } - if (outf == null) { - lame.lame_close(gf); - return -1; - } - /* - * turn off automatic writing of ID3 tag data into mp3 stream we have to - * call it before 'lame_init_params', because that function would spit - * out ID3v2 tag data. - */ - gf.write_id3tag_automatic = false; - - /* - * Now that all the options are set, lame needs to analyze them and set - * some more internal options and check for problems - */ - int i = lame.lame_init_params(gf); - if (i < 0) { - if (i == -1) { - parse.display_bitrates(System.err); - } - System.err.println("fatal error during initialization"); - lame.lame_close(gf); - return i; - } - if (parse.silent > 0) { - parse.brhist = false; /* turn off VBR histogram */ - } - - if (gf.decode_only) { - /* decode an mp3 file to a .wav */ - if (parse.mp3_delay_set) - lame_decoder(gf, outf, parse.mp3_delay, inPath.toString(), - outPath.toString(), enc); - else - lame_decoder(gf, outf, 0, inPath.toString(), - outPath.toString(), enc); - - } else { - if (max_nogap > 0) { - /* - * encode multiple input files using nogap option - */ - for (i = 0; i < max_nogap; ++i) { - boolean use_flush_nogap = (i != (max_nogap - 1)); - if (i > 0) { - parse_nogap_filenames(nogapout, nogap_inPath[i], - outPath, nogapdir); - /* - * note: if init_files changes anything, like - * samplerate, num_channels, etc, we are screwed - */ - outf = init_files(gf, nogap_inPath[i], - outPath.toString(), enc); - /* - * reinitialize bitstream for next encoding. this is - * normally done by lame_init_params(), but we cannot - * call that routine twice - */ - lame.lame_init_bitstream(gf); - } - brhist_init_package(gf); - gf.internal_flags.nogap_total = max_nogap; - gf.internal_flags.nogap_current = i; - - ret = lame_encoder(gf, outf, use_flush_nogap, - nogap_inPath[i], outPath.toString()); - - ((Closeable)outf).close(); - gaud.close_infile(); /* close the input file */ - - } - } else { - /* - * encode a single input file - */ - brhist_init_package(gf); - - ret = lame_encoder(gf, outf, false, inPath.toString(), - outPath.toString()); - - ((Closeable)outf).close(); - gaud.close_infile(); /* close the input file */ - } - } - lame.lame_close(gf); - return ret; - } - - private void encoder_progress_begin(final LameGlobalFlags gf, - final String inPath, final String outPath) { - if (parse.silent < 10) { - lame.lame_print_config(gf); - /* print useful information about options being used */ - - System.out.printf("Encoding %s%s to %s\n", inPath, inPath.length() - + outPath.length() < 66 ? "" : "\n ", outPath); - - System.out.printf("Encoding as %g kHz ", 1.e-3 * gf.out_samplerate); - - { - String[][] mode_names = { - { "stereo", "j-stereo", "dual-ch", "single-ch" }, - { "stereo", "force-ms", "dual-ch", "single-ch" } }; - switch (gf.VBR) { - case vbr_rh: - System.out.printf( - "%s MPEG-%d%s Layer III VBR(q=%g) qval=%d\n", - mode_names[gf.force_ms ? 1 : 0][gf.mode.ordinal()], - 2 - gf.version, gf.out_samplerate < 16000 ? ".5" - : "", gf.VBR_q + gf.VBR_q_frac, gf.quality); - break; - case vbr_mt: - case vbr_mtrh: - System.out.printf("%s MPEG-%d%s Layer III VBR(q=%d)\n", - mode_names[gf.force_ms ? 1 : 0][gf.mode.ordinal()], - 2 - gf.version, gf.out_samplerate < 16000 ? ".5" - : "", gf.quality); - break; - case vbr_abr: - System.out - .printf("%s MPEG-%d%s Layer III (%gx) average %d kbps qval=%d\n", - mode_names[gf.force_ms ? 1 : 0][gf.mode - .ordinal()], - 2 - gf.version, - gf.out_samplerate < 16000 ? ".5" : "", - 0.1 * (int) (10. * gf.compression_ratio + 0.5), - gf.VBR_mean_bitrate_kbps, gf.quality); - break; - default: - System.out.printf( - "%s MPEG-%d%s Layer III (%gx) %3d kbps qval=%d\n", - mode_names[gf.force_ms ? 1 : 0][gf.mode.ordinal()], - 2 - gf.version, gf.out_samplerate < 16000 ? ".5" - : "", - 0.1 * (int) (10. * gf.compression_ratio + 0.5), - gf.brate, gf.quality); - break; - } - } - - if (parse.silent <= -10) { - lame.lame_print_internals(gf); - } - System.out.print("|"); - for (int i = 0; i < MAX_WIDTH - 2; i++) { - System.out.print("="); - } - System.out.println("|"); - oldPercent = curPercent = oldConsoleX = 0; - } - } - - private double last_time = 0.0; - - private void encoder_progress(final LameGlobalFlags gf) { - if (parse.silent <= 0) { - int frames = gf.frameNum; - if (parse.update_interval <= 0) { - /* most likely --disptime x not used */ - if ((frames % 100) != 0) { - /* true, most of the time */ - return; - } - } else { - if (frames != 0 && frames != 9) { - double act = System.currentTimeMillis(); - double dif = act - last_time; - if (dif >= 0 && dif < parse.update_interval) { - return; - } - } - last_time = System.currentTimeMillis(); - /* from now! disp_time seconds */ - } - if (parse.brhist) { - hist.brhist_jump_back(); - } - timestatus(gf.frameNum, lame_get_totalframes(gf)); - if (parse.brhist) { - hist.brhist_disp(gf); - } - } - } - - private void encoder_progress_end(final LameGlobalFlags gf) { - if (parse.silent <= 0) { - if (parse.brhist) { - hist.brhist_jump_back(); - } - timestatus(gf.frameNum, lame_get_totalframes(gf)); - if (parse.brhist) { - hist.brhist_disp(gf); - } - System.out.print("|"); - for (int i = 0; i < MAX_WIDTH - 2; i++) { - System.out.print("="); - } - System.out.println("|"); - } - } - - private int oldPercent, curPercent, oldConsoleX; - - private void timestatus(final int frameNum, final int totalframes) { - int percent; - - if (frameNum < totalframes) { - percent = (int) (100. * frameNum / totalframes + 0.5); - } else { - percent = 100; - } - boolean stepped = false; - if (oldPercent != percent) { - progressStep(); - stepped = true; - } - oldPercent = percent; - if (percent == 100) { - for (int i = curPercent; i < 100; i++) { - progressStep(); - stepped = true; - } - } - if (percent == 100 && stepped) { - System.out.println(); - } - } - - private static final int MAX_WIDTH = 79; - - private void progressStep() { - curPercent++; - float consoleX = (float) curPercent * MAX_WIDTH / 100f; - if ((int) consoleX != oldConsoleX) - System.out.print("."); - oldConsoleX = (int) consoleX; - support.firePropertyChange("progress", oldPercent, curPercent); - } - - /** - * LAME's estimate of the total number of frames to be encoded. Only valid - * if calling program set num_samples. - */ - private int lame_get_totalframes(final LameGlobalFlags gfp) { - /* estimate based on user set num_samples: */ - int totalframes = (int) (2 + ((double) gfp.num_samples * gfp.out_samplerate) - / ((double) gfp.in_samplerate * gfp.framesize)); - - return totalframes; - } - - private void WriteBytesSwapped(final DataOutput fp, final short[] p, - final int pPos) throws IOException { - fp.writeShort(p[pPos]); - } - - private void WriteBytes(final DataOutput fp, final short[] p, - final int pPos) throws IOException { - /* No error condition checking */ - fp.write(p[pPos] & 0xff); - fp.write(((p[pPos] & 0xffff) >> 8) & 0xff); - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/MeanBits.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/MeanBits.java deleted file mode 100644 index 477e3ad62..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/MeanBits.java +++ /dev/null @@ -1,9 +0,0 @@ -package mp3; - -public class MeanBits { - public MeanBits(final int meanBits) { - bits = meanBits; - } - - int bits; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/NewMDCT.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/NewMDCT.java deleted file mode 100644 index 8a15b9a53..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/NewMDCT.java +++ /dev/null @@ -1,1145 +0,0 @@ -/* - * MP3 window subband -> subband filtering -> mdct routine - * - * Copyright (c) 1999-2000 Takehiro Tominaga - * - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -/* - * Special Thanks to Patrick De Smet for your advices. - */ - -/* $Id: NewMDCT.java,v 1.11 2011/05/24 20:48:06 kenchis Exp $ */ - -package mp3; - -import java.util.Arrays; - -public class NewMDCT { - - private static final float enwindow[] = { - -4.77e-07f * 0.740951125354959f / 2.384e-06f, - 1.03951e-04f * 0.740951125354959f / 2.384e-06f, - 9.53674e-04f * 0.740951125354959f / 2.384e-06f, - 2.841473e-03f * 0.740951125354959f / 2.384e-06f, - 3.5758972e-02f * 0.740951125354959f / 2.384e-06f, - 3.401756e-03f * 0.740951125354959f / 2.384e-06f, - 9.83715e-04f * 0.740951125354959f / 2.384e-06f, - 9.9182e-05f * 0.740951125354959f / 2.384e-06f, /* 15 */ - 1.2398e-05f * 0.740951125354959f / 2.384e-06f, - 1.91212e-04f * 0.740951125354959f / 2.384e-06f, - 2.283096e-03f * 0.740951125354959f / 2.384e-06f, - 1.6994476e-02f * 0.740951125354959f / 2.384e-06f, - -1.8756866e-02f * 0.740951125354959f / 2.384e-06f, - -2.630711e-03f * 0.740951125354959f / 2.384e-06f, - -2.47478e-04f * 0.740951125354959f / 2.384e-06f, - -1.4782e-05f * 0.740951125354959f / 2.384e-06f, - 9.063471690191471e-01f, 1.960342806591213e-01f, - - -4.77e-07f * 0.773010453362737f / 2.384e-06f, - 1.05858e-04f * 0.773010453362737f / 2.384e-06f, - 9.30786e-04f * 0.773010453362737f / 2.384e-06f, - 2.521515e-03f * 0.773010453362737f / 2.384e-06f, - 3.5694122e-02f * 0.773010453362737f / 2.384e-06f, - 3.643036e-03f * 0.773010453362737f / 2.384e-06f, - 9.91821e-04f * 0.773010453362737f / 2.384e-06f, - 9.6321e-05f * 0.773010453362737f / 2.384e-06f, /* 14 */ - 1.1444e-05f * 0.773010453362737f / 2.384e-06f, - 1.65462e-04f * 0.773010453362737f / 2.384e-06f, - 2.110004e-03f * 0.773010453362737f / 2.384e-06f, - 1.6112804e-02f * 0.773010453362737f / 2.384e-06f, - -1.9634247e-02f * 0.773010453362737f / 2.384e-06f, - -2.803326e-03f * 0.773010453362737f / 2.384e-06f, - -2.77042e-04f * 0.773010453362737f / 2.384e-06f, - -1.6689e-05f * 0.773010453362737f / 2.384e-06f, - 8.206787908286602e-01f, 3.901806440322567e-01f, - - -4.77e-07f * 0.803207531480645f / 2.384e-06f, - 1.07288e-04f * 0.803207531480645f / 2.384e-06f, - 9.02653e-04f * 0.803207531480645f / 2.384e-06f, - 2.174854e-03f * 0.803207531480645f / 2.384e-06f, - 3.5586357e-02f * 0.803207531480645f / 2.384e-06f, - 3.858566e-03f * 0.803207531480645f / 2.384e-06f, - 9.95159e-04f * 0.803207531480645f / 2.384e-06f, - 9.3460e-05f * 0.803207531480645f / 2.384e-06f, /* 13 */ - 1.0014e-05f * 0.803207531480645f / 2.384e-06f, - 1.40190e-04f * 0.803207531480645f / 2.384e-06f, - 1.937389e-03f * 0.803207531480645f / 2.384e-06f, - 1.5233517e-02f * 0.803207531480645f / 2.384e-06f, - -2.0506859e-02f * 0.803207531480645f / 2.384e-06f, - -2.974033e-03f * 0.803207531480645f / 2.384e-06f, - -3.07560e-04f * 0.803207531480645f / 2.384e-06f, - -1.8120e-05f * 0.803207531480645f / 2.384e-06f, - 7.416505462720353e-01f, 5.805693545089249e-01f, - - -4.77e-07f * 0.831469612302545f / 2.384e-06f, - 1.08242e-04f * 0.831469612302545f / 2.384e-06f, - 8.68797e-04f * 0.831469612302545f / 2.384e-06f, - 1.800537e-03f * 0.831469612302545f / 2.384e-06f, - 3.5435200e-02f * 0.831469612302545f / 2.384e-06f, - 4.049301e-03f * 0.831469612302545f / 2.384e-06f, - 9.94205e-04f * 0.831469612302545f / 2.384e-06f, - 9.0599e-05f * 0.831469612302545f / 2.384e-06f, /* 12 */ - 9.060e-06f * 0.831469612302545f / 2.384e-06f, - 1.16348e-04f * 0.831469612302545f / 2.384e-06f, - 1.766682e-03f * 0.831469612302545f / 2.384e-06f, - 1.4358521e-02f * 0.831469612302545f / 2.384e-06f, - -2.1372318e-02f * 0.831469612302545f / 2.384e-06f, - -3.14188e-03f * 0.831469612302545f / 2.384e-06f, - -3.39031e-04f * 0.831469612302545f / 2.384e-06f, - -1.9550e-05f * 0.831469612302545f / 2.384e-06f, - 6.681786379192989e-01f, 7.653668647301797e-01f, - - -4.77e-07f * 0.857728610000272f / 2.384e-06f, - 1.08719e-04f * 0.857728610000272f / 2.384e-06f, - 8.29220e-04f * 0.857728610000272f / 2.384e-06f, - 1.399517e-03f * 0.857728610000272f / 2.384e-06f, - 3.5242081e-02f * 0.857728610000272f / 2.384e-06f, - 4.215240e-03f * 0.857728610000272f / 2.384e-06f, - 9.89437e-04f * 0.857728610000272f / 2.384e-06f, - 8.7261e-05f * 0.857728610000272f / 2.384e-06f, /* 11 */ - 8.106e-06f * 0.857728610000272f / 2.384e-06f, - 9.3937e-05f * 0.857728610000272f / 2.384e-06f, - 1.597881e-03f * 0.857728610000272f / 2.384e-06f, - 1.3489246e-02f * 0.857728610000272f / 2.384e-06f, - -2.2228718e-02f * 0.857728610000272f / 2.384e-06f, - -3.306866e-03f * 0.857728610000272f / 2.384e-06f, - -3.71456e-04f * 0.857728610000272f / 2.384e-06f, - -2.1458e-05f * 0.857728610000272f / 2.384e-06f, - 5.993769336819237e-01f, 9.427934736519954e-01f, - - -4.77e-07f * 0.881921264348355f / 2.384e-06f, - 1.08719e-04f * 0.881921264348355f / 2.384e-06f, - 7.8392e-04f * 0.881921264348355f / 2.384e-06f, - 9.71317e-04f * 0.881921264348355f / 2.384e-06f, - 3.5007000e-02f * 0.881921264348355f / 2.384e-06f, - 4.357815e-03f * 0.881921264348355f / 2.384e-06f, - 9.80854e-04f * 0.881921264348355f / 2.384e-06f, - 8.3923e-05f * 0.881921264348355f / 2.384e-06f, /* 10 */ - 7.629e-06f * 0.881921264348355f / 2.384e-06f, - 7.2956e-05f * 0.881921264348355f / 2.384e-06f, - 1.432419e-03f * 0.881921264348355f / 2.384e-06f, - 1.2627602e-02f * 0.881921264348355f / 2.384e-06f, - -2.3074150e-02f * 0.881921264348355f / 2.384e-06f, - -3.467083e-03f * 0.881921264348355f / 2.384e-06f, - -4.04358e-04f * 0.881921264348355f / 2.384e-06f, - -2.3365e-05f * 0.881921264348355f / 2.384e-06f, - 5.345111359507916e-01f, 1.111140466039205e+00f, - - -9.54e-07f * 0.903989293123443f / 2.384e-06f, - 1.08242e-04f * 0.903989293123443f / 2.384e-06f, - 7.31945e-04f * 0.903989293123443f / 2.384e-06f, - 5.15938e-04f * 0.903989293123443f / 2.384e-06f, - 3.4730434e-02f * 0.903989293123443f / 2.384e-06f, - 4.477024e-03f * 0.903989293123443f / 2.384e-06f, - 9.68933e-04f * 0.903989293123443f / 2.384e-06f, - 8.0585e-05f * 0.903989293123443f / 2.384e-06f, /* 9 */ - 6.676e-06f * 0.903989293123443f / 2.384e-06f, - 5.2929e-05f * 0.903989293123443f / 2.384e-06f, - 1.269817e-03f * 0.903989293123443f / 2.384e-06f, - 1.1775017e-02f * 0.903989293123443f / 2.384e-06f, - -2.3907185e-02f * 0.903989293123443f / 2.384e-06f, - -3.622532e-03f * 0.903989293123443f / 2.384e-06f, - -4.38213e-04f * 0.903989293123443f / 2.384e-06f, - -2.5272e-05f * 0.903989293123443f / 2.384e-06f, - 4.729647758913199e-01f, 1.268786568327291e+00f, - - -9.54e-07f * 0.92387953251128675613f / 2.384e-06f, - 1.06812e-04f * 0.92387953251128675613f / 2.384e-06f, - 6.74248e-04f * 0.92387953251128675613f / 2.384e-06f, - 3.3379e-05f * 0.92387953251128675613f / 2.384e-06f, - 3.4412861e-02f * 0.92387953251128675613f / 2.384e-06f, - 4.573822e-03f * 0.92387953251128675613f / 2.384e-06f, - 9.54151e-04f * 0.92387953251128675613f / 2.384e-06f, - 7.6771e-05f * 0.92387953251128675613f / 2.384e-06f, - 6.199e-06f * 0.92387953251128675613f / 2.384e-06f, - 3.4332e-05f * 0.92387953251128675613f / 2.384e-06f, - 1.111031e-03f * 0.92387953251128675613f / 2.384e-06f, - 1.0933399e-02f * 0.92387953251128675613f / 2.384e-06f, - -2.4725437e-02f * 0.92387953251128675613f / 2.384e-06f, - -3.771782e-03f * 0.92387953251128675613f / 2.384e-06f, - -4.72546e-04f * 0.92387953251128675613f / 2.384e-06f, - -2.7657e-05f * 0.92387953251128675613f / 2.384e-06f, - 4.1421356237309504879e-01f, /* tan(PI/8) */ - 1.414213562373095e+00f, - - -9.54e-07f * 0.941544065183021f / 2.384e-06f, - 1.05381e-04f * 0.941544065183021f / 2.384e-06f, - 6.10352e-04f * 0.941544065183021f / 2.384e-06f, - -4.75883e-04f * 0.941544065183021f / 2.384e-06f, - 3.4055710e-02f * 0.941544065183021f / 2.384e-06f, - 4.649162e-03f * 0.941544065183021f / 2.384e-06f, - 9.35555e-04f * 0.941544065183021f / 2.384e-06f, - 7.3433e-05f * 0.941544065183021f / 2.384e-06f, /* 7 */ - 5.245e-06f * 0.941544065183021f / 2.384e-06f, - 1.7166e-05f * 0.941544065183021f / 2.384e-06f, - 9.56535e-04f * 0.941544065183021f / 2.384e-06f, - 1.0103703e-02f * 0.941544065183021f / 2.384e-06f, - -2.5527000e-02f * 0.941544065183021f / 2.384e-06f, - -3.914356e-03f * 0.941544065183021f / 2.384e-06f, - -5.07355e-04f * 0.941544065183021f / 2.384e-06f, - -3.0041e-05f * 0.941544065183021f / 2.384e-06f, - 3.578057213145241e-01f, 1.546020906725474e+00f, - - -9.54e-07f * 0.956940335732209f / 2.384e-06f, - 1.02520e-04f * 0.956940335732209f / 2.384e-06f, - 5.39303e-04f * 0.956940335732209f / 2.384e-06f, - -1.011848e-03f * 0.956940335732209f / 2.384e-06f, - 3.3659935e-02f * 0.956940335732209f / 2.384e-06f, - 4.703045e-03f * 0.956940335732209f / 2.384e-06f, - 9.15051e-04f * 0.956940335732209f / 2.384e-06f, - 7.0095e-05f * 0.956940335732209f / 2.384e-06f, /* 6 */ - 4.768e-06f * 0.956940335732209f / 2.384e-06f, - 9.54e-07f * 0.956940335732209f / 2.384e-06f, - 8.06808e-04f * 0.956940335732209f / 2.384e-06f, - 9.287834e-03f * 0.956940335732209f / 2.384e-06f, - -2.6310921e-02f * 0.956940335732209f / 2.384e-06f, - -4.048824e-03f * 0.956940335732209f / 2.384e-06f, - -5.42164e-04f * 0.956940335732209f / 2.384e-06f, - -3.2425e-05f * 0.956940335732209f / 2.384e-06f, - 3.033466836073424e-01f, 1.662939224605090e+00f, - - -1.431e-06f * 0.970031253194544f / 2.384e-06f, - 9.9182e-05f * 0.970031253194544f / 2.384e-06f, - 4.62532e-04f * 0.970031253194544f / 2.384e-06f, - -1.573563e-03f * 0.970031253194544f / 2.384e-06f, - 3.3225536e-02f * 0.970031253194544f / 2.384e-06f, - 4.737377e-03f * 0.970031253194544f / 2.384e-06f, - 8.91685e-04f * 0.970031253194544f / 2.384e-06f, - 6.6280e-05f * 0.970031253194544f / 2.384e-06f, /* 5 */ - 4.292e-06f * 0.970031253194544f / 2.384e-06f, - -1.3828e-05f * 0.970031253194544f / 2.384e-06f, - 6.61850e-04f * 0.970031253194544f / 2.384e-06f, - 8.487225e-03f * 0.970031253194544f / 2.384e-06f, - -2.7073860e-02f * 0.970031253194544f / 2.384e-06f, - -4.174709e-03f * 0.970031253194544f / 2.384e-06f, - -5.76973e-04f * 0.970031253194544f / 2.384e-06f, - -3.4809e-05f * 0.970031253194544f / 2.384e-06f, - 2.504869601913055e-01f, 1.763842528696710e+00f, - - -1.431e-06f * 0.98078528040323f / 2.384e-06f, - 9.5367e-05f * 0.98078528040323f / 2.384e-06f, - 3.78609e-04f * 0.98078528040323f / 2.384e-06f, - -2.161503e-03f * 0.98078528040323f / 2.384e-06f, - 3.2754898e-02f * 0.98078528040323f / 2.384e-06f, - 4.752159e-03f * 0.98078528040323f / 2.384e-06f, - 8.66413e-04f * 0.98078528040323f / 2.384e-06f, - 6.2943e-05f * 0.98078528040323f / 2.384e-06f, /* 4 */ - 3.815e-06f * 0.98078528040323f / 2.384e-06f, - -2.718e-05f * 0.98078528040323f / 2.384e-06f, - 5.22137e-04f * 0.98078528040323f / 2.384e-06f, - 7.703304e-03f * 0.98078528040323f / 2.384e-06f, - -2.7815342e-02f * 0.98078528040323f / 2.384e-06f, - -4.290581e-03f * 0.98078528040323f / 2.384e-06f, - -6.11782e-04f * 0.98078528040323f / 2.384e-06f, - -3.7670e-05f * 0.98078528040323f / 2.384e-06f, - 1.989123673796580e-01f, 1.847759065022573e+00f, - - -1.907e-06f * 0.989176509964781f / 2.384e-06f, - 9.0122e-05f * 0.989176509964781f / 2.384e-06f, - 2.88486e-04f * 0.989176509964781f / 2.384e-06f, - -2.774239e-03f * 0.989176509964781f / 2.384e-06f, - 3.2248020e-02f * 0.989176509964781f / 2.384e-06f, - 4.748821e-03f * 0.989176509964781f / 2.384e-06f, - 8.38757e-04f * 0.989176509964781f / 2.384e-06f, - 5.9605e-05f * 0.989176509964781f / 2.384e-06f, /* 3 */ - 3.338e-06f * 0.989176509964781f / 2.384e-06f, - -3.9577e-05f * 0.989176509964781f / 2.384e-06f, - 3.88145e-04f * 0.989176509964781f / 2.384e-06f, - 6.937027e-03f * 0.989176509964781f / 2.384e-06f, - -2.8532982e-02f * 0.989176509964781f / 2.384e-06f, - -4.395962e-03f * 0.989176509964781f / 2.384e-06f, - -6.46591e-04f * 0.989176509964781f / 2.384e-06f, - -4.0531e-05f * 0.989176509964781f / 2.384e-06f, - 1.483359875383474e-01f, 1.913880671464418e+00f, - - -1.907e-06f * 0.995184726672197f / 2.384e-06f, - 8.4400e-05f * 0.995184726672197f / 2.384e-06f, - 1.91689e-04f * 0.995184726672197f / 2.384e-06f, - -3.411293e-03f * 0.995184726672197f / 2.384e-06f, - 3.1706810e-02f * 0.995184726672197f / 2.384e-06f, - 4.728317e-03f * 0.995184726672197f / 2.384e-06f, - 8.09669e-04f * 0.995184726672197f / 2.384e-06f, - 5.579e-05f * 0.995184726672197f / 2.384e-06f, - 3.338e-06f * 0.995184726672197f / 2.384e-06f, - -5.0545e-05f * 0.995184726672197f / 2.384e-06f, - 2.59876e-04f * 0.995184726672197f / 2.384e-06f, - 6.189346e-03f * 0.995184726672197f / 2.384e-06f, - -2.9224873e-02f * 0.995184726672197f / 2.384e-06f, - -4.489899e-03f * 0.995184726672197f / 2.384e-06f, - -6.80923e-04f * 0.995184726672197f / 2.384e-06f, - -4.3392e-05f * 0.995184726672197f / 2.384e-06f, - 9.849140335716425e-02f, 1.961570560806461e+00f, - - -2.384e-06f * 0.998795456205172f / 2.384e-06f, - 7.7724e-05f * 0.998795456205172f / 2.384e-06f, - 8.8215e-05f * 0.998795456205172f / 2.384e-06f, - -4.072189e-03f * 0.998795456205172f / 2.384e-06f, - 3.1132698e-02f * 0.998795456205172f / 2.384e-06f, - 4.691124e-03f * 0.998795456205172f / 2.384e-06f, - 7.79152e-04f * 0.998795456205172f / 2.384e-06f, - 5.2929e-05f * 0.998795456205172f / 2.384e-06f, - 2.861e-06f * 0.998795456205172f / 2.384e-06f, - -6.0558e-05f * 0.998795456205172f / 2.384e-06f, - 1.37329e-04f * 0.998795456205172f / 2.384e-06f, - 5.462170e-03f * 0.998795456205172f / 2.384e-06f, - -2.9890060e-02f * 0.998795456205172f / 2.384e-06f, - -4.570484e-03f * 0.998795456205172f / 2.384e-06f, - -7.14302e-04f * 0.998795456205172f / 2.384e-06f, - -4.6253e-05f * 0.998795456205172f / 2.384e-06f, - 4.912684976946725e-02f, 1.990369453344394e+00f, - - 3.5780907e-02f * Util.SQRT2 * 0.5f / 2.384e-06f, - 1.7876148e-02f * Util.SQRT2 * 0.5f / 2.384e-06f, - 3.134727e-03f * Util.SQRT2 * 0.5f / 2.384e-06f, - 2.457142e-03f * Util.SQRT2 * 0.5f / 2.384e-06f, - 9.71317e-04f * Util.SQRT2 * 0.5f / 2.384e-06f, - 2.18868e-04f * Util.SQRT2 * 0.5f / 2.384e-06f, - 1.01566e-04f * Util.SQRT2 * 0.5f / 2.384e-06f, - 1.3828e-05f * Util.SQRT2 * 0.5f / 2.384e-06f, - - 3.0526638e-02f / 2.384e-06f, 4.638195e-03f / 2.384e-06f, - 7.47204e-04f / 2.384e-06f, 4.9591e-05f / 2.384e-06f, - 4.756451e-03f / 2.384e-06f, 2.1458e-05f / 2.384e-06f, - -6.9618e-05f / 2.384e-06f, /* 2.384e-06/2.384e-06 */ - }; - - private static final int NS = 12; - private static final int NL = 36; - - private static final float win[][] = { - { - 2.382191739347913e-13f, - 6.423305872147834e-13f, - 9.400849094049688e-13f, - 1.122435026096556e-12f, - 1.183840321267481e-12f, - 1.122435026096556e-12f, - 9.400849094049690e-13f, - 6.423305872147839e-13f, - 2.382191739347918e-13f, - - 5.456116108943412e-12f, - 4.878985199565852e-12f, - 4.240448995017367e-12f, - 3.559909094758252e-12f, - 2.858043359288075e-12f, - 2.156177623817898e-12f, - 1.475637723558783e-12f, - 8.371015190102974e-13f, - 2.599706096327376e-13f, - - -5.456116108943412e-12f, - -4.878985199565852e-12f, - -4.240448995017367e-12f, - -3.559909094758252e-12f, - -2.858043359288076e-12f, - -2.156177623817898e-12f, - -1.475637723558783e-12f, - -8.371015190102975e-13f, - -2.599706096327376e-13f, - - -2.382191739347923e-13f, - -6.423305872147843e-13f, - -9.400849094049696e-13f, - -1.122435026096556e-12f, - -1.183840321267481e-12f, - -1.122435026096556e-12f, - -9.400849094049694e-13f, - -6.423305872147840e-13f, - -2.382191739347918e-13f, - }, - { - 2.382191739347913e-13f, - 6.423305872147834e-13f, - 9.400849094049688e-13f, - 1.122435026096556e-12f, - 1.183840321267481e-12f, - 1.122435026096556e-12f, - 9.400849094049688e-13f, - 6.423305872147841e-13f, - 2.382191739347918e-13f, - - 5.456116108943413e-12f, - 4.878985199565852e-12f, - 4.240448995017367e-12f, - 3.559909094758253e-12f, - 2.858043359288075e-12f, - 2.156177623817898e-12f, - 1.475637723558782e-12f, - 8.371015190102975e-13f, - 2.599706096327376e-13f, - - -5.461314069809755e-12f, - -4.921085770524055e-12f, - -4.343405037091838e-12f, - -3.732668368707687e-12f, - -3.093523840190885e-12f, - -2.430835727329465e-12f, - -1.734679010007751e-12f, - -9.748253656609281e-13f, - -2.797435120168326e-13f, - - 0.000000000000000e+00f, - 0.000000000000000e+00f, - 0.000000000000000e+00f, - 0.000000000000000e+00f, - 0.000000000000000e+00f, - 0.000000000000000e+00f, - -2.283748241799531e-13f, - -4.037858874020686e-13f, - -2.146547464825323e-13f, - }, - { - 1.316524975873958e-01f, /* win[SHORT_TYPE] */ - 4.142135623730950e-01f, - 7.673269879789602e-01f, - - 1.091308501069271e+00f, /* tantab_l */ - 1.303225372841206e+00f, - 1.569685577117490e+00f, - 1.920982126971166e+00f, - 2.414213562373094e+00f, - 3.171594802363212e+00f, - 4.510708503662055e+00f, - 7.595754112725146e+00f, - 2.290376554843115e+01f, - - 0.98480775301220802032f, /* cx */ - 0.64278760968653936292f, - 0.34202014332566882393f, - 0.93969262078590842791f, - -0.17364817766693030343f, - -0.76604444311897790243f, - 0.86602540378443870761f, - 0.500000000000000e+00f, - - -5.144957554275265e-01f, /* ca */ - -4.717319685649723e-01f, - -3.133774542039019e-01f, - -1.819131996109812e-01f, - -9.457419252642064e-02f, - -4.096558288530405e-02f, - -1.419856857247115e-02f, - -3.699974673760037e-03f, - - 8.574929257125442e-01f, /* cs */ - 8.817419973177052e-01f, - 9.496286491027329e-01f, - 9.833145924917901e-01f, - 9.955178160675857e-01f, - 9.991605581781475e-01f, - 9.998991952444470e-01f, - 9.999931550702802e-01f, - }, - { - 0.000000000000000e+00f, - 0.000000000000000e+00f, - 0.000000000000000e+00f, - 0.000000000000000e+00f, - 0.000000000000000e+00f, - 0.000000000000000e+00f, - 2.283748241799531e-13f, - 4.037858874020686e-13f, - 2.146547464825323e-13f, - - 5.461314069809755e-12f, - 4.921085770524055e-12f, - 4.343405037091838e-12f, - 3.732668368707687e-12f, - 3.093523840190885e-12f, - 2.430835727329466e-12f, - 1.734679010007751e-12f, - 9.748253656609281e-13f, - 2.797435120168326e-13f, - - -5.456116108943413e-12f, - -4.878985199565852e-12f, - -4.240448995017367e-12f, - -3.559909094758253e-12f, - -2.858043359288075e-12f, - -2.156177623817898e-12f, - -1.475637723558782e-12f, - -8.371015190102975e-13f, - -2.599706096327376e-13f, - - -2.382191739347913e-13f, - -6.423305872147834e-13f, - -9.400849094049688e-13f, - -1.122435026096556e-12f, - -1.183840321267481e-12f, - -1.122435026096556e-12f, - -9.400849094049688e-13f, - -6.423305872147841e-13f, - -2.382191739347918e-13f, - } - }; - - private static final float tantab_l[] = win[Encoder.SHORT_TYPE]; - private static final float[] cx = win[Encoder.SHORT_TYPE]; - private static final float[] ca = win[Encoder.SHORT_TYPE]; - private static final float[] cs = win[Encoder.SHORT_TYPE]; - - /** - * new IDCT routine written by Takehiro TOMINAGA - * - * PURPOSE: Overlapping window on PCM samples<BR> - * - * SEMANTICS:<BR> - * 32 16-bit pcm samples are scaled to fractional 2's complement and - * concatenated to the end of the window buffer #x#. The updated window - * buffer #x# is then windowed by the analysis window #c# to produce the - * windowed sample #z# - */ - private static final int order[] = { - 0, 1, 16, 17, 8, 9, 24, 25, 4, 5, 20, 21, 12, 13, 28, 29, - 2, 3, 18, 19, 10, 11, 26, 27, 6, 7, 22, 23, 14, 15, 30, 31 - }; - - /** - * returns sum_j=0^31 a[j]*cos(PI*j*(k+1/2)/32), 0<=k<32 - */ - private void window_subband(final float[] x1, int x1Pos, final float a[]) { - int wp = 10; - - int x2 = x1Pos + 238 - 14 - 286; - - for (int i = -15; i < 0; i++) { - float w, s, t; - - w = enwindow[wp + -10]; - s = x1[x2 + -224] * w; - t = x1[x1Pos + 224] * w; - w = enwindow[wp + -9]; - s += x1[x2 + -160] * w; - t += x1[x1Pos + 160] * w; - w = enwindow[wp + -8]; - s += x1[x2 + -96] * w; - t += x1[x1Pos + 96] * w; - w = enwindow[wp + -7]; - s += x1[x2 + -32] * w; - t += x1[x1Pos + 32] * w; - w = enwindow[wp + -6]; - s += x1[x2 + 32] * w; - t += x1[x1Pos + -32] * w; - w = enwindow[wp + -5]; - s += x1[x2 + 96] * w; - t += x1[x1Pos + -96] * w; - w = enwindow[wp + -4]; - s += x1[x2 + 160] * w; - t += x1[x1Pos + -160] * w; - w = enwindow[wp + -3]; - s += x1[x2 + 224] * w; - t += x1[x1Pos + -224] * w; - - w = enwindow[wp + -2]; - s += x1[x1Pos + -256] * w; - t -= x1[x2 + 256] * w; - w = enwindow[wp + -1]; - s += x1[x1Pos + -192] * w; - t -= x1[x2 + 192] * w; - w = enwindow[wp + 0]; - s += x1[x1Pos + -128] * w; - t -= x1[x2 + 128] * w; - w = enwindow[wp + 1]; - s += x1[x1Pos + -64] * w; - t -= x1[x2 + 64] * w; - w = enwindow[wp + 2]; - s += x1[x1Pos + 0] * w; - t -= x1[x2 + 0] * w; - w = enwindow[wp + 3]; - s += x1[x1Pos + 64] * w; - t -= x1[x2 + -64] * w; - w = enwindow[wp + 4]; - s += x1[x1Pos + 128] * w; - t -= x1[x2 + -128] * w; - w = enwindow[wp + 5]; - s += x1[x1Pos + 192] * w; - t -= x1[x2 + -192] * w; - - /* - * this multiplyer could be removed, but it needs more 256 FLOAT - * data. thinking about the data cache performance, I think we - * should not use such a huge table. tt 2000/Oct/25 - */ - s *= enwindow[wp + 6]; - w = t - s; - a[30 + i * 2] = t + s; - a[31 + i * 2] = enwindow[wp + 7] * w; - wp += 18; - x1Pos--; - x2++; - } - { - float s, t, u, v; - t = x1[x1Pos + -16] * enwindow[wp + -10]; - s = x1[x1Pos + -32] * enwindow[wp + -2]; - t += (x1[x1Pos + -48] - x1[x1Pos + 16]) * enwindow[wp + -9]; - s += x1[x1Pos + -96] * enwindow[wp + -1]; - t += (x1[x1Pos + -80] + x1[x1Pos + 48]) * enwindow[wp + -8]; - s += x1[x1Pos + -160] * enwindow[wp + 0]; - t += (x1[x1Pos + -112] - x1[x1Pos + 80]) * enwindow[wp + -7]; - s += x1[x1Pos + -224] * enwindow[wp + 1]; - t += (x1[x1Pos + -144] + x1[x1Pos + 112]) * enwindow[wp + -6]; - s -= x1[x1Pos + 32] * enwindow[wp + 2]; - t += (x1[x1Pos + -176] - x1[x1Pos + 144]) * enwindow[wp + -5]; - s -= x1[x1Pos + 96] * enwindow[wp + 3]; - t += (x1[x1Pos + -208] + x1[x1Pos + 176]) * enwindow[wp + -4]; - s -= x1[x1Pos + 160] * enwindow[wp + 4]; - t += (x1[x1Pos + -240] - x1[x1Pos + 208]) * enwindow[wp + -3]; - s -= x1[x1Pos + 224]; - - u = s - t; - v = s + t; - - t = a[14]; - s = a[15] - t; - - a[31] = v + t; /* A0 */ - a[30] = u + s; /* A1 */ - a[15] = u - s; /* A2 */ - a[14] = v - t; /* A3 */ - } - { - float xr; - xr = a[28] - a[0]; - a[0] += a[28]; - a[28] = xr * enwindow[wp + -2 * 18 + 7]; - xr = a[29] - a[1]; - a[1] += a[29]; - a[29] = xr * enwindow[wp + -2 * 18 + 7]; - - xr = a[26] - a[2]; - a[2] += a[26]; - a[26] = xr * enwindow[wp + -4 * 18 + 7]; - xr = a[27] - a[3]; - a[3] += a[27]; - a[27] = xr * enwindow[wp + -4 * 18 + 7]; - - xr = a[24] - a[4]; - a[4] += a[24]; - a[24] = xr * enwindow[wp + -6 * 18 + 7]; - xr = a[25] - a[5]; - a[5] += a[25]; - a[25] = xr * enwindow[wp + -6 * 18 + 7]; - - xr = a[22] - a[6]; - a[6] += a[22]; - a[22] = xr * Util.SQRT2; - xr = a[23] - a[7]; - a[7] += a[23]; - a[23] = xr * Util.SQRT2 - a[7]; - a[7] -= a[6]; - a[22] -= a[7]; - a[23] -= a[22]; - - xr = a[6]; - a[6] = a[31] - xr; - a[31] = a[31] + xr; - xr = a[7]; - a[7] = a[30] - xr; - a[30] = a[30] + xr; - xr = a[22]; - a[22] = a[15] - xr; - a[15] = a[15] + xr; - xr = a[23]; - a[23] = a[14] - xr; - a[14] = a[14] + xr; - - xr = a[20] - a[8]; - a[8] += a[20]; - a[20] = xr * enwindow[wp + -10 * 18 + 7]; - xr = a[21] - a[9]; - a[9] += a[21]; - a[21] = xr * enwindow[wp + -10 * 18 + 7]; - - xr = a[18] - a[10]; - a[10] += a[18]; - a[18] = xr * enwindow[wp + -12 * 18 + 7]; - xr = a[19] - a[11]; - a[11] += a[19]; - a[19] = xr * enwindow[wp + -12 * 18 + 7]; - - xr = a[16] - a[12]; - a[12] += a[16]; - a[16] = xr * enwindow[wp + -14 * 18 + 7]; - xr = a[17] - a[13]; - a[13] += a[17]; - a[17] = xr * enwindow[wp + -14 * 18 + 7]; - - xr = -a[20] + a[24]; - a[20] += a[24]; - a[24] = xr * enwindow[wp + -12 * 18 + 7]; - xr = -a[21] + a[25]; - a[21] += a[25]; - a[25] = xr * enwindow[wp + -12 * 18 + 7]; - - xr = a[4] - a[8]; - a[4] += a[8]; - a[8] = xr * enwindow[wp + -12 * 18 + 7]; - xr = a[5] - a[9]; - a[5] += a[9]; - a[9] = xr * enwindow[wp + -12 * 18 + 7]; - - xr = a[0] - a[12]; - a[0] += a[12]; - a[12] = xr * enwindow[wp + -4 * 18 + 7]; - xr = a[1] - a[13]; - a[1] += a[13]; - a[13] = xr * enwindow[wp + -4 * 18 + 7]; - xr = a[16] - a[28]; - a[16] += a[28]; - a[28] = xr * enwindow[wp + -4 * 18 + 7]; - xr = -a[17] + a[29]; - a[17] += a[29]; - a[29] = xr * enwindow[wp + -4 * 18 + 7]; - - xr = Util.SQRT2 * (a[2] - a[10]); - a[2] += a[10]; - a[10] = xr; - xr = Util.SQRT2 * (a[3] - a[11]); - a[3] += a[11]; - a[11] = xr; - xr = Util.SQRT2 * (-a[18] + a[26]); - a[18] += a[26]; - a[26] = xr - a[18]; - xr = Util.SQRT2 * (-a[19] + a[27]); - a[19] += a[27]; - a[27] = xr - a[19]; - - xr = a[2]; - a[19] -= a[3]; - a[3] -= xr; - a[2] = a[31] - xr; - a[31] += xr; - xr = a[3]; - a[11] -= a[19]; - a[18] -= xr; - a[3] = a[30] - xr; - a[30] += xr; - xr = a[18]; - a[27] -= a[11]; - a[19] -= xr; - a[18] = a[15] - xr; - a[15] += xr; - - xr = a[19]; - a[10] -= xr; - a[19] = a[14] - xr; - a[14] += xr; - xr = a[10]; - a[11] -= xr; - a[10] = a[23] - xr; - a[23] += xr; - xr = a[11]; - a[26] -= xr; - a[11] = a[22] - xr; - a[22] += xr; - xr = a[26]; - a[27] -= xr; - a[26] = a[7] - xr; - a[7] += xr; - - xr = a[27]; - a[27] = a[6] - xr; - a[6] += xr; - - xr = Util.SQRT2 * (a[0] - a[4]); - a[0] += a[4]; - a[4] = xr; - xr = Util.SQRT2 * (a[1] - a[5]); - a[1] += a[5]; - a[5] = xr; - xr = Util.SQRT2 * (a[16] - a[20]); - a[16] += a[20]; - a[20] = xr; - xr = Util.SQRT2 * (a[17] - a[21]); - a[17] += a[21]; - a[21] = xr; - - xr = -Util.SQRT2 * (a[8] - a[12]); - a[8] += a[12]; - a[12] = xr - a[8]; - xr = -Util.SQRT2 * (a[9] - a[13]); - a[9] += a[13]; - a[13] = xr - a[9]; - xr = -Util.SQRT2 * (a[25] - a[29]); - a[25] += a[29]; - a[29] = xr - a[25]; - xr = -Util.SQRT2 * (a[24] + a[28]); - a[24] -= a[28]; - a[28] = xr - a[24]; - - xr = a[24] - a[16]; - a[24] = xr; - xr = a[20] - xr; - a[20] = xr; - xr = a[28] - xr; - a[28] = xr; - - xr = a[25] - a[17]; - a[25] = xr; - xr = a[21] - xr; - a[21] = xr; - xr = a[29] - xr; - a[29] = xr; - - xr = a[17] - a[1]; - a[17] = xr; - xr = a[9] - xr; - a[9] = xr; - xr = a[25] - xr; - a[25] = xr; - xr = a[5] - xr; - a[5] = xr; - xr = a[21] - xr; - a[21] = xr; - xr = a[13] - xr; - a[13] = xr; - xr = a[29] - xr; - a[29] = xr; - - xr = a[1] - a[0]; - a[1] = xr; - xr = a[16] - xr; - a[16] = xr; - xr = a[17] - xr; - a[17] = xr; - xr = a[8] - xr; - a[8] = xr; - xr = a[9] - xr; - a[9] = xr; - xr = a[24] - xr; - a[24] = xr; - xr = a[25] - xr; - a[25] = xr; - xr = a[4] - xr; - a[4] = xr; - xr = a[5] - xr; - a[5] = xr; - xr = a[20] - xr; - a[20] = xr; - xr = a[21] - xr; - a[21] = xr; - xr = a[12] - xr; - a[12] = xr; - xr = a[13] - xr; - a[13] = xr; - xr = a[28] - xr; - a[28] = xr; - xr = a[29] - xr; - a[29] = xr; - - xr = a[0]; - a[0] += a[31]; - a[31] -= xr; - xr = a[1]; - a[1] += a[30]; - a[30] -= xr; - xr = a[16]; - a[16] += a[15]; - a[15] -= xr; - xr = a[17]; - a[17] += a[14]; - a[14] -= xr; - xr = a[8]; - a[8] += a[23]; - a[23] -= xr; - xr = a[9]; - a[9] += a[22]; - a[22] -= xr; - xr = a[24]; - a[24] += a[7]; - a[7] -= xr; - xr = a[25]; - a[25] += a[6]; - a[6] -= xr; - xr = a[4]; - a[4] += a[27]; - a[27] -= xr; - xr = a[5]; - a[5] += a[26]; - a[26] -= xr; - xr = a[20]; - a[20] += a[11]; - a[11] -= xr; - xr = a[21]; - a[21] += a[10]; - a[10] -= xr; - xr = a[12]; - a[12] += a[19]; - a[19] -= xr; - xr = a[13]; - a[13] += a[18]; - a[18] -= xr; - xr = a[28]; - a[28] += a[3]; - a[3] -= xr; - xr = a[29]; - a[29] += a[2]; - a[2] -= xr; - } - } - - /** - * Function: Calculation of the MDCT In the case of long blocks (type 0,1,3) - * there are 36 coefficents in the time domain and 18 in the frequency - * domain.<BR> - * In the case of short blocks (type 2) there are 3 transformations with - * short length. This leads to 12 coefficents in the time and 6 in the - * frequency domain. In this case the results are stored side by side in the - * vector out[]. - * - * New layer3 - */ - private void mdct_short(final float[] inout, int inoutPos) { - for (int l = 0; l < 3; l++) { - float tc0, tc1, tc2, ts0, ts1, ts2; - - ts0 = inout[inoutPos + 2 * 3] * win[Encoder.SHORT_TYPE][0] - - inout[inoutPos + 5 * 3]; - tc0 = inout[inoutPos + 0 * 3] * win[Encoder.SHORT_TYPE][2] - - inout[inoutPos + 3 * 3]; - tc1 = ts0 + tc0; - tc2 = ts0 - tc0; - - ts0 = inout[inoutPos + 5 * 3] * win[Encoder.SHORT_TYPE][0] - + inout[inoutPos + 2 * 3]; - tc0 = inout[inoutPos + 3 * 3] * win[Encoder.SHORT_TYPE][2] - + inout[inoutPos + 0 * 3]; - ts1 = ts0 + tc0; - ts2 = -ts0 + tc0; - - tc0 = (inout[inoutPos + 1 * 3] * win[Encoder.SHORT_TYPE][1] - inout[inoutPos + 4 * 3]) * 2.069978111953089e-11f; - /* - * tritab_s [ 1 ] - */ - ts0 = (inout[inoutPos + 4 * 3] * win[Encoder.SHORT_TYPE][1] + inout[inoutPos + 1 * 3]) * 2.069978111953089e-11f; - /* - * tritab_s [ 1 ] - */ - inout[inoutPos + 3 * 0] = tc1 * 1.907525191737280e-11f + tc0; - /* - * tritab_s[ 2 ] - */ - inout[inoutPos + 3 * 5] = -ts1 * 1.907525191737280e-11f + ts0; - /* - * tritab_s[0 ] - */ - tc2 = tc2 * 0.86602540378443870761f * 1.907525191737281e-11f; - /* - * tritab_s[ 2] - */ - ts1 = ts1 * 0.5f * 1.907525191737281e-11f + ts0; - inout[inoutPos + 3 * 1] = tc2 - ts1; - inout[inoutPos + 3 * 2] = tc2 + ts1; - - tc1 = tc1 * 0.5f * 1.907525191737281e-11f - tc0; - ts2 = ts2 * 0.86602540378443870761f * 1.907525191737281e-11f; - /* - * tritab_s[ 0] - */ - inout[inoutPos + 3 * 3] = tc1 + ts2; - inout[inoutPos + 3 * 4] = tc1 - ts2; - - inoutPos++; - } - } - - final void mdct_long(final float[] out, final int outPos, final float[] in) { - float ct, st; - { - float tc1, tc2, tc3, tc4, ts5, ts6, ts7, ts8; - /* 1,2, 5,6, 9,10, 13,14, 17 */ - tc1 = in[17] - in[9]; - tc3 = in[15] - in[11]; - tc4 = in[14] - in[12]; - ts5 = in[0] + in[8]; - ts6 = in[1] + in[7]; - ts7 = in[2] + in[6]; - ts8 = in[3] + in[5]; - - out[outPos + 17] = (ts5 + ts7 - ts8) - (ts6 - in[4]); - st = (ts5 + ts7 - ts8) * cx[12 + 7] + (ts6 - in[4]); - ct = (tc1 - tc3 - tc4) * cx[12 + 6]; - out[outPos + 5] = ct + st; - out[outPos + 6] = ct - st; - - tc2 = (in[16] - in[10]) * cx[12 + 6]; - ts6 = ts6 * cx[12 + 7] + in[4]; - ct = tc1 * cx[12 + 0] + tc2 + tc3 * cx[12 + 1] + tc4 * cx[12 + 2]; - st = -ts5 * cx[12 + 4] + ts6 - ts7 * cx[12 + 5] + ts8 * cx[12 + 3]; - out[outPos + 1] = ct + st; - out[outPos + 2] = ct - st; - - ct = tc1 * cx[12 + 1] - tc2 - tc3 * cx[12 + 2] + tc4 * cx[12 + 0]; - st = -ts5 * cx[12 + 5] + ts6 - ts7 * cx[12 + 3] + ts8 * cx[12 + 4]; - out[outPos + 9] = ct + st; - out[outPos + 10] = ct - st; - - ct = tc1 * cx[12 + 2] - tc2 + tc3 * cx[12 + 0] - tc4 * cx[12 + 1]; - st = ts5 * cx[12 + 3] - ts6 + ts7 * cx[12 + 4] - ts8 * cx[12 + 5]; - out[outPos + 13] = ct + st; - out[outPos + 14] = ct - st; - } - { - float ts1, ts2, ts3, ts4, tc5, tc6, tc7, tc8; - - ts1 = in[8] - in[0]; - ts3 = in[6] - in[2]; - ts4 = in[5] - in[3]; - tc5 = in[17] + in[9]; - tc6 = in[16] + in[10]; - tc7 = in[15] + in[11]; - tc8 = in[14] + in[12]; - - out[outPos + 0] = (tc5 + tc7 + tc8) + (tc6 + in[13]); - ct = (tc5 + tc7 + tc8) * cx[12 + 7] - (tc6 + in[13]); - st = (ts1 - ts3 + ts4) * cx[12 + 6]; - out[outPos + 11] = ct + st; - out[outPos + 12] = ct - st; - - ts2 = (in[7] - in[1]) * cx[12 + 6]; - tc6 = in[13] - tc6 * cx[12 + 7]; - ct = tc5 * cx[12 + 3] - tc6 + tc7 * cx[12 + 4] + tc8 * cx[12 + 5]; - st = ts1 * cx[12 + 2] + ts2 + ts3 * cx[12 + 0] + ts4 * cx[12 + 1]; - out[outPos + 3] = ct + st; - out[outPos + 4] = ct - st; - - ct = -tc5 * cx[12 + 5] + tc6 - tc7 * cx[12 + 3] - tc8 * cx[12 + 4]; - st = ts1 * cx[12 + 1] + ts2 - ts3 * cx[12 + 2] - ts4 * cx[12 + 0]; - out[outPos + 7] = ct + st; - out[outPos + 8] = ct - st; - - ct = -tc5 * cx[12 + 4] + tc6 - tc7 * cx[12 + 5] - tc8 * cx[12 + 3]; - st = ts1 * cx[12 + 0] - ts2 + ts3 * cx[12 + 1] - ts4 * cx[12 + 2]; - out[outPos + 15] = ct + st; - out[outPos + 16] = ct - st; - } - } - - public final void mdct_sub48(final LameInternalFlags gfc, final float[] w0, - final float[] w1) { - float[] wk = w0; - int wkPos = 286; - /* thinking cache performance, ch->gr loop is better than gr->ch loop */ - for (int ch = 0; ch < gfc.channels_out; ch++) { - for (int gr = 0; gr < gfc.mode_gr; gr++) { - int band; - final GrInfo gi = (gfc.l3_side.tt[gr][ch]); - float[] mdct_enc = gi.xr; - int mdct_encPos = 0; - float[][] samp = gfc.sb_sample[ch][1 - gr]; - int sampPos = 0; - - for (int k = 0; k < 18 / 2; k++) { - window_subband(wk, wkPos, samp[sampPos]); - window_subband(wk, wkPos + 32, samp[sampPos + 1]); - sampPos += 2; - wkPos += 64; - /* - * Compensate for inversion in the analysis filter - */ - for (band = 1; band < 32; band += 2) { - samp[sampPos - 1][band] *= -1; - } - } - - /* - * Perform imdct of 18 previous subband samples + 18 current - * subband samples - */ - for (band = 0; band < 32; band++, mdct_encPos += 18) { - int type = gi.block_type; - float[][] band0 = gfc.sb_sample[ch][gr]; - float[][] band1 = gfc.sb_sample[ch][1 - gr]; - if (gi.mixed_block_flag != 0 && band < 2) - type = 0; - if (gfc.amp_filter[band] < 1e-12) { - Arrays.fill(mdct_enc, mdct_encPos + 0, - mdct_encPos + 18, 0); - } else { - if (gfc.amp_filter[band] < 1.0) { - for (int k = 0; k < 18; k++) - band1[k][order[band]] *= gfc.amp_filter[band]; - } - if (type == Encoder.SHORT_TYPE) { - for (int k = -NS / 4; k < 0; k++) { - float w = win[Encoder.SHORT_TYPE][k + 3]; - mdct_enc[mdct_encPos + k * 3 + 9] = band0[9 + k][order[band]] - * w - band0[8 - k][order[band]]; - mdct_enc[mdct_encPos + k * 3 + 18] = band0[14 - k][order[band]] - * w + band0[15 + k][order[band]]; - mdct_enc[mdct_encPos + k * 3 + 10] = band0[15 + k][order[band]] - * w - band0[14 - k][order[band]]; - mdct_enc[mdct_encPos + k * 3 + 19] = band1[2 - k][order[band]] - * w + band1[3 + k][order[band]]; - mdct_enc[mdct_encPos + k * 3 + 11] = band1[3 + k][order[band]] - * w - band1[2 - k][order[band]]; - mdct_enc[mdct_encPos + k * 3 + 20] = band1[8 - k][order[band]] - * w + band1[9 + k][order[band]]; - } - mdct_short(mdct_enc, mdct_encPos); - } else { - float work[] = new float[18]; - for (int k = -NL / 4; k < 0; k++) { - float a, b; - a = win[type][k + 27] - * band1[k + 9][order[band]] - + win[type][k + 36] - * band1[8 - k][order[band]]; - b = win[type][k + 9] - * band0[k + 9][order[band]] - - win[type][k + 18] - * band0[8 - k][order[band]]; - work[k + 9] = a - b * tantab_l[3 + k + 9]; - work[k + 18] = a * tantab_l[3 + k + 9] + b; - } - - mdct_long(mdct_enc, mdct_encPos, work); - } - } - /* - * Perform aliasing reduction butterfly - */ - if (type != Encoder.SHORT_TYPE && band != 0) { - for (int k = 7; k >= 0; --k) { - float bu, bd; - bu = mdct_enc[mdct_encPos + k] * ca[20 + k] - + mdct_enc[mdct_encPos + -1 - k] - * cs[28 + k]; - bd = mdct_enc[mdct_encPos + k] * cs[28 + k] - - mdct_enc[mdct_encPos + -1 - k] - * ca[20 + k]; - - mdct_enc[mdct_encPos + -1 - k] = bu; - mdct_enc[mdct_encPos + k] = bd; - } - } - } - } - wk = w1; - wkPos = 286; - if (gfc.mode_gr == 1) { - for (int i = 0; i < 18; i++) { - System.arraycopy(gfc.sb_sample[ch][1][i], 0, - gfc.sb_sample[ch][0][i], 0, 32); - } - } - } - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/NsPsy.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/NsPsy.java deleted file mode 100644 index f79b5f8fd..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/NsPsy.java +++ /dev/null @@ -1,21 +0,0 @@ -package mp3; - -/** - * Variables used for --nspsytune - * - * @author Ken - * - */ -public class NsPsy { - float last_en_subshort[][] = new float[4][9]; - int lastAttacks[] = new int[4]; - float pefirbuf[] = new float[19]; - float longfact[] = new float[Encoder.SBMAX_l]; - float shortfact[] = new float[Encoder.SBMAX_s]; - - /** - * short block tuning - */ - float attackthre; - float attackthre_s; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/PSY.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/PSY.java deleted file mode 100644 index d42c44da0..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/PSY.java +++ /dev/null @@ -1,24 +0,0 @@ -package mp3; - -/** - * PSY Model related stuff - */ -public class PSY { - /** - * The dbQ stuff. - */ - float mask_adjust; - /** - * The dbQ stuff. - */ - float mask_adjust_short; - /* at transition from one scalefactor band to next */ - /** - * Band weight long scalefactor bands. - */ - float bo_l_weight[] = new float[Encoder.SBMAX_l]; - /** - * Band weight short scalefactor bands. - */ - float bo_s_weight[] = new float[Encoder.SBMAX_s]; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Parse.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Parse.java deleted file mode 100644 index ef838b8cd..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Parse.java +++ /dev/null @@ -1,1885 +0,0 @@ -/* - * Command line parsing related functions - * - * Copyright (c) 1999 Mark Taylor - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: Parse.java,v 1.28 2011/05/24 22:17:17 kenchis Exp $ */ - -package mp3; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.PrintStream; -import java.io.RandomAccessFile; -import java.nio.ByteOrder; -import java.util.ArrayList; -import java.util.Scanner; - -import mp3.GetAudio.sound_file_format; - -public class Parse { - - private static boolean INTERNAL_OPTS = false; - - Version ver; - ID3Tag id3; - Presets pre; - - public final void setModules(Version ver2, ID3Tag id32, Presets pre2) { - this.ver = ver2; - this.id3 = id32; - this.pre = pre2; - } - - public GetAudio.sound_file_format input_format; - /** - * force byte swapping default=0 - */ - public boolean swapbytes = false; - /** - * Verbosity - */ - public int silent; - /** - * Ignore errors in values passed for tags - */ - private boolean ignore_tag_errors; - public boolean brhist; - /** - * to use Frank's time status display - */ - public float update_interval; - /** - * to adjust the number of samples truncated during decode - */ - public int mp3_delay; - /** - * user specified the value of the mp3 encoder delay to assume for decoding - */ - public boolean mp3_delay_set; - - public boolean disable_wav_header; - /** - * used by MP3 - */ - public MP3Data mp3input_data = new MP3Data(); - /** - * print info whether waveform clips - */ - public boolean print_clipping_info; - - /** - * WAV signed - */ - public boolean in_signed = true; - - public ByteOrder in_endian = ByteOrder.LITTLE_ENDIAN; - - public int in_bitwidth = 16; - - /** - * possible text encodings - */ - private enum TextEncoding { - /** - * bytes will be stored as-is into ID3 tags, which are Latin1/UCS2 per - * definition - */ - TENC_RAW, /** - * text will be converted from local encoding to Latin1, as - * ID3 needs it - */ - TENC_LATIN1, /** - * text will be converted from local encoding to UCS-2, as - * ID3v2 wants it - */ - TENC_UCS2 - } - - private boolean set_id3tag(final LameGlobalFlags gfp, final int type, - final String str) { - switch (type) { - case 'a': - id3.id3tag_set_artist(gfp, str); - return false; - case 't': - id3.id3tag_set_title(gfp, str); - return false; - case 'l': - id3.id3tag_set_album(gfp, str); - return false; - case 'g': - id3.id3tag_set_genre(gfp, str); - return false; - case 'c': - id3.id3tag_set_comment(gfp, str); - return false; - case 'n': - id3.id3tag_set_track(gfp, str); - return false; - case 'y': - id3.id3tag_set_year(gfp, str); - return false; - case 'v': - id3.id3tag_set_fieldvalue(gfp, str); - return false; - } - return false; - } - - private boolean set_id3v2tag(final LameGlobalFlags gfp, final int type, - final String str) { - switch (type) { - case 'a': - id3.id3tag_set_textinfo_ucs2(gfp, "TPE1", str); - return false; - case 't': - id3.id3tag_set_textinfo_ucs2(gfp, "TIT2", str); - return false; - case 'l': - id3.id3tag_set_textinfo_ucs2(gfp, "TALB", str); - return false; - case 'g': - id3.id3tag_set_textinfo_ucs2(gfp, "TCON", str); - return false; - case 'c': - id3.id3tag_set_comment(gfp, null, null, str, 0); - return false; - case 'n': - id3.id3tag_set_textinfo_ucs2(gfp, "TRCK", str); - return false; - } - return false; - } - - private boolean id3_tag(final LameGlobalFlags gfp, final int type, - final TextEncoding enc, final String str) { - String x = null; - boolean result; - switch (enc) { - default: - case TENC_RAW: - x = str; - break; - case TENC_LATIN1: - x = str/* toLatin1(str) */; - break; - case TENC_UCS2: - x = str/* toUcs2(str) */; - break; - } - switch (enc) { - default: - case TENC_RAW: - case TENC_LATIN1: - result = set_id3tag(gfp, type, x); - break; - case TENC_UCS2: - result = set_id3v2tag(gfp, type, x); - break; - } - return result; - } - - /** - * PURPOSE: Writes version and license to the file specified by fp - */ - private void lame_version_print(final PrintStream fp) { - final String b = ver.getLameOsBitness(); - final String v = ver.getLameVersion(); - final String u = ver.getLameUrl(); - final int lenb = b.length(); - final int lenv = v.length(); - final int lenu = u.length(); - /* line width of terminal in characters */ - final int lw = 80; - /* static width of text */ - final int sw = 16; - - if (lw >= lenb + lenv + lenu + sw || lw < lenu + 2) - /* text fits in 80 chars per line, or line even too small for url */ - if (lenb > 0) - fp.printf("LAME %s version %s (%s)\n\n", b, v, u); - else - fp.printf("LAME version %s (%s)\n\n", v, u); - else { - /* text too long, wrap url into next line, right aligned */ - if (lenb > 0) - fp.printf("LAME %s version %s\n%*s(%s)\n\n", b, v, lw - 2 - - lenu, "", u); - else - fp.printf("LAME version %s\n%*s(%s)\n\n", v, lw - 2 - lenu, "", - u); - } - } - - private void print_license(final PrintStream fp) { - /* print version & license */ - lame_version_print(fp); - fp.printf("Can I use LAME in my commercial program?\n" - + "\n" - + "Yes, you can, under the restrictions of the LGPL. In particular, you\n" - + "can include a compiled version of the LAME library (for example,\n" - + "lame.dll) with a commercial program. Some notable requirements of\n" - + "the LGPL:\n" + "\n"); - fp.printf("1. In your program, you cannot include any source code from LAME, with\n" - + " the exception of files whose only purpose is to describe the library\n" - + " interface (such as lame.h).\n" + "\n"); - fp.printf("2. Any modifications of LAME must be released under the LGPL.\n" - + " The LAME project (www.mp3dev.org) would appreciate being\n" - + " notified of any modifications.\n" + "\n"); - fp.printf("3. You must give prominent notice that your program is:\n" - + " A. using LAME (including version number)\n" - + " B. LAME is under the LGPL\n" - + " C. Provide a copy of the LGPL. (the file COPYING contains the LGPL)\n" - + " D. Provide a copy of LAME source, or a pointer where the LAME\n" - + " source can be obtained (such as http://sourceforge.net/projects/jsidplay2/)\n" - + " An example of prominent notice would be an \"About the LAME encoding engine\"\n" - + " button in some pull down menu within the executable of your program.\n" - + "\n"); - fp.printf("4. If you determine that distribution of LAME requires a patent license,\n" - + " you must obtain such license.\n" + "\n" + "\n"); - fp.printf("*** IMPORTANT NOTE ***\n" - + "\n" - + "The decoding functions provided in LAME use the mpglib decoding engine which\n" - + "is under the GPL. They may not be used by any program not released under the\n" - + "GPL unless you obtain such permission from the MPG123 project (www.mpg123.de).\n" - + "\n"); - } - - /** - * PURPOSE: Writes command line syntax to the file specified by fp - */ - public final void usage(final PrintStream fp, final String ProgramName) { - // print general syntax - lame_version_print(fp); - fp.printf( - "usage: %s [options] <infile> [outfile]\n" - + "\n" - + " <infile> and/or <outfile> can be \"-\", which means stdin/stdout.\n" - + "\n" - + "Try:\n" - + " \"%s --help\" for general usage information\n" - + " or:\n" - + " \"%s --preset help\" for information on suggested predefined settings\n" - + " or:\n" - + " \"%s --longhelp\"\n" - + " or \"%s -?\" for a complete options list\n\n", - ProgramName, ProgramName, ProgramName, ProgramName, ProgramName); - } - - /** - * PURPOSE: Writes command line syntax to the file specified by fp but only - * the most important ones, to fit on a vt100 terminal - */ - private void short_help(final LameGlobalFlags gfp, final PrintStream fp, - final String ProgramName) { - /* print short syntax help */ - lame_version_print(fp); - fp.printf( - "usage: %s [options] <infile> [outfile]\n" - + "\n" - + " <infile> and/or <outfile> can be \"-\", which means stdin/stdout.\n" - + "\n" + "RECOMMENDED:\n" - + " lame -V 2 input.wav output.mp3\n" + "\n", - ProgramName); - fp.printf( - "OPTIONS:\n" - + " -b bitrate set the bitrate, default 128 kbps\n" - + " -h higher quality, but a little slower. Recommended.\n" - + " -f fast mode (lower quality)\n" - + " -V n quality setting for VBR. default n=%d\n" - + " 0=high quality,bigger files. 9=smaller files\n", - gfp.VBR_q); - fp.printf(" --preset type type must be \"medium\", \"standard\", \"extreme\", \"insane\",\n" - + " or a value for an average desired bitrate and depending\n" - + " on the value specified, appropriate quality settings will\n" - + " be used.\n" - + " \"--preset help\" gives more info on these\n" - + "\n"); - fp.printf(" --longhelp full list of options\n" + "\n" - + " --license print License information\n\n"); - } - - private void long_help(final LameGlobalFlags gfp, final PrintStream fp, - final String ProgramName, final int lessmode) { - // print long syntax help - lame_version_print(fp); - fp.printf( - "usage: %s [options] <infile> [outfile]\n" - + "\n" - + " <infile> and/or <outfile> can be \"-\", which means stdin/stdout.\n" - + "\n" + "RECOMMENDED:\n" - + " lame -V2 input.wav output.mp3\n" + "\n", - ProgramName); - fp.printf("OPTIONS:\n" - + " Input options:\n" - + " --scale <arg> scale input (multiply PCM data) by <arg>\n" - + " --scale-l <arg> scale channel 0 (left) input (multiply PCM data) by <arg>\n" - + " --scale-r <arg> scale channel 1 (right) input (multiply PCM data) by <arg>\n" - + " --mp1input input file is a MPEG Layer I file\n" - + " --mp2input input file is a MPEG Layer II file\n" - + " --mp3input input file is a MPEG Layer III file\n" - + " --nogap <file1> <file2> <...>\n" - + " gapless encoding for a set of contiguous files\n" - + " --nogapout <dir>\n" - + " output dir for gapless encoding (must precede --nogap)\n" - + " --nogaptags allow the use of VBR tags in gapless encoding\n"); - fp.printf("\n" - + " Input options for RAW PCM:\n" - + " -r input is raw pcm\n" - + " -x force byte-swapping of input\n" - + " -s sfreq sampling frequency of input file (kHz) - default 44.1 kHz\n" - + " --bitwidth w input bit width is w (default 16)\n" - + " --signed input is signed (default)\n" - + " --unsigned input is unsigned\n" - + " --little-endian input is little-endian (default)\n" - + " --big-endian input is big-endian\n"); - - fp.printf(" Operational options:\n" - + " -a downmix from stereo to mono file for mono encoding\n" - + " -m <mode> (j)oint, (s)imple, (f)orce, (d)dual-mono, (m)ono\n" - + " default is (j) or (s) depending on bitrate\n" - + " joint = joins the best possible of MS and LR stereo\n" - + " simple = force LR stereo on all frames\n" - + " force = force MS stereo on all frames.\n" - + " --preset type type must be \"medium\", \"standard\", \"extreme\", \"insane\",\n" - + " or a value for an average desired bitrate and depending\n" - + " on the value specified, appropriate quality settings will\n" - + " be used.\n" - + " \"--preset help\" gives more info on these\n" - + " --comp <arg> choose bitrate to achive a compression ratio of <arg>\n"); - fp.printf(" --replaygain-fast compute RG fast but slightly inaccurately (default)\n" - + " --replaygain-accurate compute RG more accurately and find the peak sample\n" - + " --noreplaygain disable ReplayGain analysis\n" - + " --clipdetect enable --replaygain-accurate and print a message whether\n" - + " clipping occurs and how far the waveform is from full scale\n"); - fp.printf(" --freeformat produce a free format bitstream\n" - + " --decode input=mp3 file, output=wav\n" - + " -t disable writing wav header when using --decode\n"); - - fp.printf(" Verbosity:\n" - + " --disptime <arg>print progress report every arg seconds\n" - + " -S don't print progress report, VBR histograms\n" - + " --nohist disable VBR histogram display\n" - + " --silent don't print anything on screen\n" - + " --quiet don't print anything on screen\n" - + " --brief print more useful information\n" - + " --verbose print a lot of useful information\n" - + "\n"); - fp.printf(" Noise shaping & psycho acoustic algorithms:\n" - + " -q <arg> <arg> = 0...9. Default -q 5 \n" - + " -q 0: Highest quality, very slow \n" - + " -q 9: Poor quality, but fast \n" - + " -h Same as -q 2. Recommended.\n" - + " -f Same as -q 7. Fast, ok quality\n"); - - fp.printf(" CBR (constant bitrate, the default) options:\n" - + " -b <bitrate> set the bitrate in kbps, default 128 kbps\n" - + " --cbr enforce use of constant bitrate\n" - + "\n" - + " ABR options:\n" - + " --abr <bitrate> specify average bitrate desired (instead of quality)\n" - + "\n"); - fp.printf( - " VBR options:\n" - + " -V n quality setting for VBR. default n=%d\n" - + " 0=high quality,bigger files. 9=smaller files\n" - + " -v the same as -V 4\n" - + " --vbr-old use old variable bitrate (VBR) routine\n" - + " --vbr-new use new variable bitrate (VBR) routine (default)\n", - gfp.VBR_q); - fp.printf(" -b <bitrate> specify minimum allowed bitrate, default 32 kbps\n" - + " -B <bitrate> specify maximum allowed bitrate, default 320 kbps\n" - + " -F strictly enforce the -b option, for use with players that\n" - + " do not support low bitrate mp3\n" - + " -t disable writing LAME Tag\n" - + " -T enable and force writing LAME Tag\n"); - - fp.printf(" ATH related:\n" - + " --noath turns ATH down to a flat noise floor\n" - + " --athshort ignore GPSYCHO for short blocks, use ATH only\n" - + " --athonly ignore GPSYCHO completely, use ATH only\n" - + " --athtype n selects between different ATH types [0-4]\n" - + " --athlower x lowers ATH by x dB\n"); - fp.printf(" --athaa-type n ATH auto adjust: 0 'no' else 'loudness based'\n" - + - /** - * OBSOLETE - * " --athaa-loudapprox n n=1 total energy or n=2 equal loudness curve\n" - */ - " --athaa-sensitivity x activation offset in -/+ dB for ATH auto-adjustment\n" - + "\n"); - - fp.printf(" PSY related:\n" - + " --short use short blocks when appropriate\n" - + " --noshort do not use short blocks\n" - + " --allshort use only short blocks\n"); - fp.printf(" --temporal-masking x x=0 disables, x=1 enables temporal masking effect\n" - + " --nssafejoint M/S switching criterion\n" - + " --nsmsfix <arg> M/S switching tuning [effective 0-3.5]\n" - + " --interch x adjust inter-channel masking ratio\n" - + " --ns-bass x adjust masking for sfbs 0 - 6 (long) 0 - 5 (short)\n" - + " --ns-alto x adjust masking for sfbs 7 - 13 (long) 6 - 10 (short)\n" - + " --ns-treble x adjust masking for sfbs 14 - 21 (long) 11 - 12 (short)\n"); - fp.printf(" --ns-sfb21 x change ns-treble by x dB for sfb21\n" - + " --shortthreshold x,y short block switching threshold,\n" - + " x for L/R/M channel, y for S channel\n" - + " Noise Shaping related:\n" - + " --substep n use pseudo substep noise shaping method types 0-2\n"); - - fp.printf(" experimental switches:\n" - + " -X n[,m] selects between different noise measurements\n" - + " n for long block, m for short. if m is omitted, m = n\n" - + " -Y lets LAME ignore noise in sfb21, like in CBR\n" - + " -Z [n] currently no effects\n"); - - fp.printf(" MP3 header/stream options:\n" - + " -e <emp> de-emphasis n/5/c (obsolete)\n" - + " -c mark as copyright\n" - + " -o mark as non-original\n" - + " -p error protection. adds 16 bit checksum to every frame\n" - + " (the checksum is computed correctly)\n" - + " --nores disable the bit reservoir\n" - + " --strictly-enforce-ISO comply as much as possible to ISO MPEG spec\n" - + "\n"); - fp.printf(" Filter options:\n" - + " --lowpass <freq> frequency(kHz), lowpass filter cutoff above freq\n" - + " --lowpass-width <freq> frequency(kHz) - default 15%% of lowpass freq\n" - + " --highpass <freq> frequency(kHz), highpass filter cutoff below freq\n" - + " --highpass-width <freq> frequency(kHz) - default 15%% of highpass freq\n"); - fp.printf(" --resample <sfreq> sampling frequency of output file(kHz)- default=automatic\n"); - - fp.printf(" ID3 tag options:\n" - + " --tt <title> audio/song title (max 30 chars for version 1 tag)\n" - + " --ta <artist> audio/song artist (max 30 chars for version 1 tag)\n" - + " --tl <album> audio/song album (max 30 chars for version 1 tag)\n" - + " --ty <year> audio/song year of issue (1 to 9999)\n" - + " --tc <comment> user-defined text (max 30 chars for v1 tag, 28 for v1.1)\n" - + " --tn <track[/total]> audio/song track number and (optionally) the total\n" - + " number of tracks on the original recording. (track\n" - + " and total each 1 to 255. just the track number\n" - + " creates v1.1 tag, providing a total forces v2.0).\n" - + " --tg <genre> audio/song genre (name or number in list)\n" - + " --ti <file> audio/song albumArt (jpeg/png/gif file, 128KB max, v2.3)\n" - + " --tv <id=value> user-defined frame specified by id and value (v2.3 tag)\n"); - fp.printf(" --add-id3v2 force addition of version 2 tag\n" - + " --id3v1-only add only a version 1 tag\n" - + " --id3v2-only add only a version 2 tag\n" - + " --space-id3v1 pad version 1 tag with spaces instead of nulls\n" - + " --pad-id3v2 same as '--pad-id3v2-size 128'\n" - + " --pad-id3v2-size <value> adds version 2 tag, pad with extra <value> bytes\n" - + " --genre-list print alphabetically sorted ID3 genre list and exit\n" - + " --ignore-tag-errors ignore errors in values passed for tags\n" - + "\n"); - fp.printf(" Note: A version 2 tag will NOT be added unless one of the input fields\n" - + " won't fit in a version 1 tag (e.g. the title string is longer than 30\n" - + " characters), or the '--add-id3v2' or '--id3v2-only' options are used,\n" - + " or output is redirected to stdout.\n" - + "\nMisc:\n --license print License information\n\n"); - - display_bitrates(fp); - } - - public final void display_bitrates(final PrintStream fp) { - display_bitrate(fp, "1", 1, 1); - display_bitrate(fp, "2", 2, 0); - display_bitrate(fp, "2.5", 4, 0); - fp.println(); - } - - private void display_bitrate(final PrintStream fp, final String version, - final int d, final int indx) { - int nBitrates = 14; - if (d == 4) - nBitrates = 8; - - fp.printf( - "\nMPEG-%-3s layer III sample frequencies (kHz): %2d %2d %g\n" - + "bitrates (kbps):", version, 32 / d, 48 / d, 44.1 / d); - for (int i = 1; i <= nBitrates; i++) - fp.printf(" %2d", Tables.bitrate_table[indx][i]); - fp.println(); - } - - /** - * PURPOSE: Writes presetting info to #stdout# - */ - private void presets_longinfo_dm(final PrintStream msgfp) { - msgfp.printf("\n" - + "The --preset switches are aliases over LAME settings.\n" - + "\n" + "\n"); - msgfp.printf("To activate these presets:\n" + "\n" - + " For VBR modes (generally highest quality):\n" + "\n"); - msgfp.printf(" \"--preset medium\" This preset should provide near transparency\n" - + " to most people on most music.\n" - + "\n" - + " \"--preset standard\" This preset should generally be transparent\n" - + " to most people on most music and is already\n" - + " quite high in quality.\n" - + "\n"); - msgfp.printf(" \"--preset extreme\" If you have extremely good hearing and similar\n" - + " equipment, this preset will generally provide\n" - + " slightly higher quality than the \"standard\"\n" - + " mode.\n" + "\n"); - msgfp.printf(" For CBR 320kbps (highest quality possible from the --preset switches):\n" - + "\n" - + " \"--preset insane\" This preset will usually be overkill for most\n" - + " people and most situations, but if you must\n" - + " have the absolute highest quality with no\n" - + " regard to filesize, this is the way to go.\n" - + "\n"); - msgfp.printf(" For ABR modes (high quality per given bitrate but not as high as VBR):\n" - + "\n" - + " \"--preset <kbps>\" Using this preset will usually give you good\n" - + " quality at a specified bitrate. Depending on the\n" - + " bitrate entered, this preset will determine the\n"); - msgfp.printf(" optimal settings for that particular situation.\n" - + " While this approach works, it is not nearly as\n" - + " flexible as VBR, and usually will not attain the\n" - + " same level of quality as VBR at higher bitrates.\n" - + "\n"); - msgfp.printf("The following options are also available for the corresponding profiles:\n" - + "\n" - + " <fast> standard\n" - + " <fast> extreme\n" - + " insane\n" - + " <cbr> (ABR Mode) - The ABR Mode is implied. To use it,\n" - + " simply specify a bitrate. For example:\n" - + " \"--preset 185\" activates this\n" - + " preset and uses 185 as an average kbps.\n" - + "\n"); - msgfp.printf(" \"fast\" - Enables the fast VBR mode for a particular profile.\n" - + "\n"); - msgfp.printf(" \"cbr\" - If you use the ABR mode (read above) with a significant\n" - + " bitrate such as 80, 96, 112, 128, 160, 192, 224, 256, 320,\n" - + " you can use the \"cbr\" option to force CBR mode encoding\n" - + " instead of the standard abr mode. ABR does provide higher\n" - + " quality but CBR may be useful in situations such as when\n" - + " streaming an mp3 over the internet may be important.\n" - + "\n"); - msgfp.printf(" For example:\n" + "\n" - + " \"--preset fast standard <input file> <output file>\"\n" - + " or \"--preset cbr 192 <input file> <output file>\"\n" - + " or \"--preset 172 <input file> <output file>\"\n" - + " or \"--preset extreme <input file> <output file>\"\n" - + "\n" + "\n"); - msgfp.printf("A few aliases are also available for ABR mode:\n" - + "phone => 16kbps/mono phon+/lw/mw-eu/sw => 24kbps/mono\n" - + "mw-us => 40kbps/mono voice => 56kbps/mono\n" - + "fm/radio/tape => 112kbps hifi => 160kbps\n" - + "cd => 192kbps studio => 256kbps\n"); - } - - private int presets_set(final LameGlobalFlags gfp, final int fast, - final int cbr, String preset_name, final String ProgramName) { - int mono = 0; - - if ((preset_name.equals("help")) && (fast < 1) && (cbr < 1)) { - lame_version_print(System.out); - presets_longinfo_dm(System.out); - return -1; - } - - /* aliases for compatibility with old presets */ - - if (preset_name.equals("phone")) { - preset_name = "16"; - mono = 1; - } - if ((preset_name.equals("phon+")) || (preset_name.equals("lw")) - || (preset_name.equals("mw-eu")) || (preset_name.equals("sw"))) { - preset_name = "24"; - mono = 1; - } - if (preset_name.equals("mw-us")) { - preset_name = "40"; - mono = 1; - } - if (preset_name.equals("voice")) { - preset_name = "56"; - mono = 1; - } - if (preset_name.equals("fm")) { - preset_name = "112"; - } - if ((preset_name.equals("radio")) || (preset_name.equals("tape"))) { - preset_name = "112"; - } - if (preset_name.equals("hifi")) { - preset_name = "160"; - } - if (preset_name.equals("cd")) { - preset_name = "192"; - } - if (preset_name.equals("studio")) { - preset_name = "256"; - } - - if (preset_name.equals("medium")) { - pre.lame_set_VBR_q(gfp, 4); - if (fast > 0) { - gfp.VBR = VbrMode.vbr_mtrh; - } else { - gfp.VBR = VbrMode.vbr_rh; - } - return 0; - } - - if (preset_name.equals("standard")) { - pre.lame_set_VBR_q(gfp, 2); - if (fast > 0) { - gfp.VBR = VbrMode.vbr_mtrh; - } else { - gfp.VBR = VbrMode.vbr_rh; - } - return 0; - } - - else if (preset_name.equals("extreme")) { - pre.lame_set_VBR_q(gfp, 0); - if (fast > 0) { - gfp.VBR = VbrMode.vbr_mtrh; - } else { - gfp.VBR = VbrMode.vbr_rh; - } - return 0; - } - - else if ((preset_name.equals("insane")) && (fast < 1)) { - - gfp.preset = Lame.INSANE; - pre.apply_preset(gfp, Lame.INSANE, 1); - - return 0; - } - - /* Generic ABR Preset */ - if (((Integer.valueOf(preset_name)) > 0) && (fast < 1)) { - if ((Integer.valueOf(preset_name)) >= 8 - && (Integer.valueOf(preset_name)) <= 320) { - gfp.preset = Integer.valueOf(preset_name); - pre.apply_preset(gfp, Integer.valueOf(preset_name), 1); - - if (cbr == 1) - gfp.VBR = VbrMode.vbr_off; - - if (mono == 1) { - gfp.mode = MPEGMode.MONO; - } - - return 0; - - } else { - lame_version_print(System.err); - System.err - .printf("Error: The bitrate specified is out of the valid range for this preset\n" - + "\n" - + "When using this mode you must enter a value between \"32\" and \"320\"\n" - + "\n" - + "For further information try: \"%s --preset help\"\n", - ProgramName); - return -1; - } - } - - lame_version_print(System.err); - System.err - .printf("Error: You did not enter a valid profile and/or options with --preset\n" - + "\n" - + "Available profiles are:\n" - + "\n" - + " <fast> medium\n" - + " <fast> standard\n" - + " <fast> extreme\n" - + " insane\n" - + " <cbr> (ABR Mode) - The ABR Mode is implied. To use it,\n" - + " simply specify a bitrate. For example:\n" - + " \"--preset 185\" activates this\n" - + " preset and uses 185 as an average kbps.\n" - + "\n"); - System.err - .printf(" Some examples:\n" - + "\n" - + " or \"%s --preset fast standard <input file> <output file>\"\n" - + " or \"%s --preset cbr 192 <input file> <output file>\"\n" - + " or \"%s --preset 172 <input file> <output file>\"\n" - + " or \"%s --preset extreme <input file> <output file>\"\n" - + "\n" - + "For further information try: \"%s --preset help\"\n", - ProgramName, ProgramName, ProgramName, ProgramName, - ProgramName); - return -1; - } - - /** - * LAME is a simple frontend which just uses the file extension to determine - * the file type. Trying to analyze the file contents is well beyond the - * scope of LAME and should not be added. - */ - private sound_file_format filename_to_type(String FileName) { - int len = FileName.length(); - - if (len < 4) - return sound_file_format.sf_unknown; - - FileName = FileName.substring(len - 4); - if (FileName.equalsIgnoreCase(".mpg")) - return sound_file_format.sf_mp123; - if (FileName.equalsIgnoreCase(".mp1")) - return sound_file_format.sf_mp123; - if (FileName.equalsIgnoreCase(".mp2")) - return sound_file_format.sf_mp123; - if (FileName.equalsIgnoreCase(".mp3")) - return sound_file_format.sf_mp123; - if (FileName.equalsIgnoreCase(".wav")) - return sound_file_format.sf_wave; - if (FileName.equalsIgnoreCase(".aif")) - return sound_file_format.sf_aiff; - if (FileName.equalsIgnoreCase(".raw")) - return sound_file_format.sf_raw; - if (FileName.equalsIgnoreCase(".ogg")) - return sound_file_format.sf_ogg; - return GetAudio.sound_file_format.sf_unknown; - } - - private int resample_rate(double freq) { - if (freq >= 1.e3) - freq *= 1.e-3; - - switch ((int) freq) { - case 8: - return 8000; - case 11: - return 11025; - case 12: - return 12000; - case 16: - return 16000; - case 22: - return 22050; - case 24: - return 24000; - case 32: - return 32000; - case 44: - return 44100; - case 48: - return 48000; - default: - System.err.printf("Illegal resample frequency: %.3f kHz\n", freq); - return 0; - } - } - - private int set_id3_albumart(final LameGlobalFlags gfp, - final String file_name) { - int ret = -1; - RandomAccessFile fpi = null; - - if (file_name == null) { - return 0; - } - try { - fpi = new RandomAccessFile(file_name, "r"); - try { - int size = (int) (fpi.length() & Integer.MAX_VALUE); - byte[] albumart = new byte[size]; - fpi.readFully(albumart); - ret = id3.id3tag_set_albumart(gfp, albumart, size) ? 0 : 4; - } catch (IOException e) { - ret = 3; - } finally { - try { - fpi.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } catch (FileNotFoundException e1) { - ret = 1; - } - switch (ret) { - case 1: - System.err.printf("Could not find: '%s'.\n", file_name); - break; - case 2: - System.err - .printf("Insufficient memory for reading the albumart.\n"); - break; - case 3: - System.err.printf("Read error: '%s'.\n", file_name); - break; - case 4: - System.err - .printf("Unsupported image: '%s'.\nSpecify JPEG/PNG/GIF image (128KB maximum)\n", - file_name); - break; - default: - break; - } - return ret; - } - - private enum ID3TAG_MODE { - ID3TAG_MODE_DEFAULT, ID3TAG_MODE_V1_ONLY, ID3TAG_MODE_V2_ONLY - }; - - public static class NoGap { - int num_nogap; - } - - public int parse_args(final LameGlobalFlags gfp, - final ArrayList<String> argv, final StringBuilder inPath, - final StringBuilder outPath, final String[] nogap_inPath, - final NoGap ng) { - /* set to 1 if we parse an input file name */ - int input_file = 0; - int autoconvert = 0; - double val; - int nogap = 0; - /* set to 1 to use VBR tags in NOGAP mode */ - int nogap_tags = 0; - final String ProgramName = "lame"; - int count_nogap = 0; - /* is RG explicitly disabled by the user */ - int noreplaygain = 0; - ID3TAG_MODE id3tag_mode = ID3TAG_MODE.ID3TAG_MODE_DEFAULT; - - inPath.setLength(0); - outPath.setLength(0); - /* turn on display options. user settings may turn them off below */ - silent = 0; - ignore_tag_errors = false; - brhist = true; - mp3_delay = 0; - mp3_delay_set = false; - print_clipping_info = false; - disable_wav_header = false; - id3.id3tag_init(gfp); - - /* process args */ - for (int i = 0; i < argv.size(); i++) { - char c; - String token; - int tokenPos = 0; - String arg; - String nextArg; - int argUsed; - - token = argv.get(i); - if (token.charAt(tokenPos++) == '-') { - argUsed = 0; - nextArg = i + 1 < argv.size() ? argv.get(i + 1) : ""; - - if (token.length() - tokenPos == 0) { - /* The user wants to use stdin and/or stdout. */ - input_file = 1; - if (inPath.length() == 0) { - inPath.setLength(0); - inPath.append(argv.get(i)); - } else if (outPath.length() == 0) { - outPath.setLength(0); - outPath.append(argv.get(i)); - } - } - if (token.charAt(tokenPos) == '-') { /* GNU style */ - tokenPos++; - - if (token.substring(tokenPos).equalsIgnoreCase("resample")) { - argUsed = 1; - gfp.out_samplerate = resample_rate(Double - .parseDouble(nextArg)); - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "vbr-old")) { - gfp.VBR = VbrMode.vbr_rh; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "vbr-new")) { - gfp.VBR = VbrMode.vbr_mtrh; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "vbr-mtrh")) { - gfp.VBR = VbrMode.vbr_mtrh; - - } else if (token.substring(tokenPos) - .equalsIgnoreCase("cbr")) { - gfp.VBR = VbrMode.vbr_off; - - } else if (token.substring(tokenPos) - .equalsIgnoreCase("abr")) { - argUsed = 1; - gfp.VBR = VbrMode.vbr_abr; - gfp.VBR_mean_bitrate_kbps = Integer.valueOf(nextArg); - /* - * values larger than 8000 are bps (like Fraunhofer), so - * it's strange to get 320000 bps MP3 when specifying - * 8000 bps MP3 - */ - if (gfp.VBR_mean_bitrate_kbps >= 8000) - gfp.VBR_mean_bitrate_kbps = (gfp.VBR_mean_bitrate_kbps + 500) / 1000; - - gfp.VBR_mean_bitrate_kbps = Math.min( - gfp.VBR_mean_bitrate_kbps, 320); - gfp.VBR_mean_bitrate_kbps = Math.max( - gfp.VBR_mean_bitrate_kbps, 8); - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "r3mix")) { - gfp.preset = Lame.R3MIX; - pre.apply_preset(gfp, Lame.R3MIX, 1); - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "bitwidth")) { - argUsed = 1; - in_bitwidth = Integer.valueOf(nextArg); - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "signed")) { - in_signed = true; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "unsigned")) { - in_signed = false; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "little-endian")) { - in_endian = ByteOrder.LITTLE_ENDIAN; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "big-endian")) { - in_endian = ByteOrder.BIG_ENDIAN; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "mp1input")) { - input_format = GetAudio.sound_file_format.sf_mp1; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "mp2input")) { - input_format = GetAudio.sound_file_format.sf_mp2; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "mp3input")) { - input_format = GetAudio.sound_file_format.sf_mp3; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "ogginput")) { - System.err - .printf("sorry, vorbis support in LAME is deprecated.\n"); - return -1; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "phone")) { - if (presets_set(gfp, 0, 0, token, ProgramName) < 0) - return -1; - System.err - .printf("Warning: --phone is deprecated, use --preset phone instead!"); - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "voice")) { - if (presets_set(gfp, 0, 0, token, ProgramName) < 0) - return -1; - System.err - .printf("Warning: --voice is deprecated, use --preset voice instead!"); - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "noshort")) { - gfp.short_blocks = ShortBlock.short_block_dispensed; - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "short")) { - gfp.short_blocks = ShortBlock.short_block_allowed; - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "allshort")) { - gfp.short_blocks = ShortBlock.short_block_forced; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "decode")) { - gfp.decode_only = true; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "decode-mp3delay")) { - mp3_delay = Integer.valueOf(nextArg); - mp3_delay_set = true; - argUsed = 1; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "nores")) { - gfp.disable_reservoir = true; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "strictly-enforce-ISO")) { - gfp.strict_ISO = true; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "scale")) { - argUsed = 1; - gfp.scale = (float) Double.parseDouble(nextArg); - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "scale-l")) { - argUsed = 1; - gfp.scale_left = (float) Double.parseDouble(nextArg); - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "scale-r")) { - argUsed = 1; - gfp.scale_right = (float) Double.parseDouble(nextArg); - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "freeformat")) { - gfp.free_format = true; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "replaygain-fast")) { - gfp.findReplayGain = true; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "replaygain-accurate")) { - gfp.decode_on_the_fly = true; - gfp.findReplayGain = true; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "noreplaygain")) { - noreplaygain = 1; - gfp.findReplayGain = false; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "clipdetect")) { - print_clipping_info = true; - gfp.decode_on_the_fly = true; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "nohist")) { - brhist = false; - - /* options for ID3 tag */ - } else if (token.substring(tokenPos).equalsIgnoreCase("tt")) { - argUsed = 1; - id3_tag(gfp, 't', TextEncoding.TENC_RAW, nextArg); - - } else if (token.substring(tokenPos).equalsIgnoreCase("ta")) { - argUsed = 1; - id3_tag(gfp, 'a', TextEncoding.TENC_RAW, nextArg); - - } else if (token.substring(tokenPos).equalsIgnoreCase("tl")) { - argUsed = 1; - id3_tag(gfp, 'l', TextEncoding.TENC_RAW, nextArg); - - } else if (token.substring(tokenPos).equalsIgnoreCase("ty")) { - argUsed = 1; - id3_tag(gfp, 'y', TextEncoding.TENC_RAW, nextArg); - - } else if (token.substring(tokenPos).equalsIgnoreCase("tc")) { - argUsed = 1; - id3_tag(gfp, 'c', TextEncoding.TENC_RAW, nextArg); - - } else if (token.substring(tokenPos).equalsIgnoreCase("tn")) { - boolean ret = id3_tag(gfp, 'n', TextEncoding.TENC_RAW, - nextArg); - argUsed = 1; - if (ret) { - if (!ignore_tag_errors) { - if (id3tag_mode == ID3TAG_MODE.ID3TAG_MODE_V1_ONLY) { - System.err - .printf("The track number has to be between 1 and 255 for ID3v1.\n"); - return -1; - } else if (id3tag_mode == ID3TAG_MODE.ID3TAG_MODE_V2_ONLY) { - /* - * track will be stored as-is in ID3v2 case, - * so no problem here - */ - } else { - if (silent < 10) { - System.err - .printf("The track number has to be between 1 and 255 for ID3v1, ignored for ID3v1.\n"); - } - } - } - } - - } else if (token.substring(tokenPos).equalsIgnoreCase("tg")) { - id3_tag(gfp, 'g', TextEncoding.TENC_RAW, nextArg); - argUsed = 1; - - } else if (token.substring(tokenPos).equalsIgnoreCase("tv")) { - argUsed = 1; - if (id3_tag(gfp, 'v', TextEncoding.TENC_RAW, nextArg)) { - if (silent < 10) { - System.err.printf( - "Invalid field value: '%s'. Ignored\n", - nextArg); - } - } - - } else if (token.substring(tokenPos).equalsIgnoreCase("ti")) { - argUsed = 1; - if (set_id3_albumart(gfp, nextArg) != 0) { - if (!ignore_tag_errors) { - return -1; - } - } - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "ignore-tag-errors")) { - ignore_tag_errors = true; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "add-id3v2")) { - id3.id3tag_add_v2(gfp); - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "id3v1-only")) { - id3.id3tag_v1_only(gfp); - id3tag_mode = ID3TAG_MODE.ID3TAG_MODE_V1_ONLY; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "id3v2-only")) { - id3.id3tag_v2_only(gfp); - id3tag_mode = ID3TAG_MODE.ID3TAG_MODE_V2_ONLY; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "space-id3v1")) { - id3.id3tag_space_v1(gfp); - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "pad-id3v2")) { - id3.id3tag_pad_v2(gfp); - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "pad-id3v2-size")) { - int n = Integer.valueOf(nextArg); - n = n <= 128000 ? n : 128000; - n = n >= 0 ? n : 0; - id3.id3tag_set_pad(gfp, n); - argUsed = 1; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "genre-list")) { - id3.id3tag_genre_list(new GenreListHandler() { - - public void genre_list_handler(int num, String name) { - System.out.printf("%3d %s\n", num, name); - } - - }); - return -2; - - // XXX Unsupported: some experimental switches for - // setting ID3 tags - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "lowpass")) { - val = Double.parseDouble(nextArg); - argUsed = 1; - if (val < 0) { - gfp.lowpassfreq = -1; - } else { - /* useful are 0.001 kHz...50 kHz, 50 Hz...50000 Hz */ - if (val < 0.001 || val > 50000.) { - System.err - .printf("Must specify lowpass with --lowpass freq, freq >= 0.001 kHz\n"); - return -1; - } - gfp.lowpassfreq = (int) (val - * (val < 50. ? 1.e3 : 1.e0) + 0.5); - } - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "lowpass-width")) { - val = Double.parseDouble(nextArg); - argUsed = 1; - /* useful are 0.001 kHz...16 kHz, 16 Hz...50000 Hz */ - if (val < 0.001 || val > 50000.) { - System.err - .printf("Must specify lowpass width with --lowpass-width freq, freq >= 0.001 kHz\n"); - return -1; - } - gfp.lowpassfreq = (int) (val - * (val < 16. ? 1.e3 : 1.e0) + 0.5); - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "highpass")) { - val = Double.parseDouble(nextArg); - argUsed = 1; - if (val < 0.0) { - gfp.highpassfreq = -1; - } else { - /* useful are 0.001 kHz...16 kHz, 16 Hz...50000 Hz */ - if (val < 0.001 || val > 50000.) { - System.err - .printf("Must specify highpass with --highpass freq, freq >= 0.001 kHz\n"); - return -1; - } - gfp.highpassfreq = (int) (val - * (val < 16. ? 1.e3 : 1.e0) + 0.5); - } - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "highpass-width")) { - val = Double.parseDouble(nextArg); - argUsed = 1; - /* useful are 0.001 kHz...16 kHz, 16 Hz...50000 Hz */ - if (val < 0.001 || val > 50000.) { - System.err - .printf("Must specify highpass width with --highpass-width freq, freq >= 0.001 kHz\n"); - return -1; - } - gfp.highpasswidth = (int) val; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "comp")) { - argUsed = 1; - val = Double.parseDouble(nextArg); - if (val < 1.0) { - System.err - .printf("Must specify compression ratio >= 1.0\n"); - return -1; - } - gfp.compression_ratio = (float) val; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "notemp")) { - gfp.useTemporal = false; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "interch")) { - argUsed = 1; - gfp.interChRatio = (float) Double.parseDouble(nextArg); - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "temporal-masking")) { - argUsed = 1; - gfp.useTemporal = Integer.valueOf(nextArg) != 0; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "nssafejoint")) { - gfp.exp_nspsytune = gfp.exp_nspsytune | 2; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "nsmsfix")) { - argUsed = 1; - gfp.msfix = (float) Double.parseDouble(nextArg); - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "ns-bass")) { - argUsed = 1; - { - double d; - int k; - d = Double.parseDouble(nextArg); - k = (int) (d * 4); - if (k < -32) - k = -32; - if (k > 31) - k = 31; - if (k < 0) - k += 64; - gfp.exp_nspsytune = gfp.exp_nspsytune | (k << 2); - } - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "ns-alto")) { - argUsed = 1; - { - double d; - int k; - d = Double.parseDouble(nextArg); - k = (int) (d * 4); - if (k < -32) - k = -32; - if (k > 31) - k = 31; - if (k < 0) - k += 64; - gfp.exp_nspsytune = gfp.exp_nspsytune | (k << 8); - } - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "ns-treble")) { - argUsed = 1; - { - double d; - int k; - d = Double.parseDouble(nextArg); - k = (int) (d * 4); - if (k < -32) - k = -32; - if (k > 31) - k = 31; - if (k < 0) - k += 64; - gfp.exp_nspsytune = gfp.exp_nspsytune | (k << 14); - } - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "ns-sfb21")) { - /* - * to be compatible with Naoki's original code, ns-sfb21 - * specifies how to change ns-treble for sfb21 - */ - argUsed = 1; - { - double d; - int k; - d = Double.parseDouble(nextArg); - k = (int) (d * 4); - if (k < -32) - k = -32; - if (k > 31) - k = 31; - if (k < 0) - k += 64; - gfp.exp_nspsytune = gfp.exp_nspsytune | (k << 20); - } - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "nspsytune2")) { - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "quiet") - || token.substring(tokenPos).equalsIgnoreCase( - "silent")) { - silent = 10; /* on a scale from 1 to 10 be very silent */ - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "brief")) { - silent = -5; /* print few info on screen */ - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "verbose")) { - silent = -10; /* print a lot on screen */ - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "version") - || token.substring(tokenPos).equalsIgnoreCase( - "license")) { - print_license(System.out); - return -2; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "help") - || token.substring(tokenPos).equalsIgnoreCase( - "usage")) { - short_help(gfp, System.out, ProgramName); - return -2; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "longhelp")) { - long_help(gfp, System.out, ProgramName, 0 /* lessmode=NO */); - return -2; - - } else if (token.substring(tokenPos).equalsIgnoreCase("?")) { - long_help(gfp, System.out, ProgramName, 1 /* lessmode=YES */); - return -2; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "preset") - || token.substring(tokenPos).equalsIgnoreCase( - "alt-preset")) { - argUsed = 1; - { - int fast = 0, cbr = 0; - - while ((nextArg.equals("fast")) - || (nextArg.equals("cbr"))) { - - if ((nextArg.equals("fast")) && (fast < 1)) - fast = 1; - if ((nextArg.equals("cbr")) && (cbr < 1)) - cbr = 1; - - argUsed++; - nextArg = i + argUsed < argv.size() ? argv - .get(i + argUsed) : ""; - } - - if (presets_set(gfp, fast, cbr, nextArg, - ProgramName) < 0) - return -1; - } - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "disptime")) { - argUsed = 1; - update_interval = (float) Double.parseDouble(nextArg); - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "nogaptags")) { - nogap_tags = 1; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "nogapout")) { - outPath.setLength(0); - outPath.append(nextArg); - argUsed = 1; - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "nogap")) { - nogap = 1; - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "tune")) { /* without helptext */ - argUsed = 1; - { - gfp.tune_value_a = (float) Double - .parseDouble(nextArg); - gfp.tune = true; - } - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "shortthreshold")) { - { - float x, y; - Scanner sc = new Scanner(nextArg); - x = sc.nextFloat(); - if (!sc.hasNext()) { - y = x; - } else { - sc.nextByte(); - y = sc.nextFloat(); - } - argUsed = 1; - gfp.internal_flags.nsPsy.attackthre = x; - gfp.internal_flags.nsPsy.attackthre_s = y; - } - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "maskingadjust")) { /* without helptext */ - argUsed = 1; - gfp.maskingadjust = (float) Double.parseDouble(nextArg); - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "maskingadjustshort")) { /* without helptext */ - argUsed = 1; - gfp.maskingadjust_short = (float) Double - .parseDouble(nextArg); - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "athcurve")) { /* without helptext */ - argUsed = 1; - gfp.ATHcurve = (float) Double.parseDouble(nextArg); - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "no-preset-tune")) { /* without helptext */ - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "substep")) { - argUsed = 1; - gfp.internal_flags.substep_shaping = Integer - .valueOf(nextArg); - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "sbgain")) { /* without helptext */ - argUsed = 1; - gfp.internal_flags.subblock_gain = Integer - .valueOf(nextArg); - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "sfscale")) { /* without helptext */ - gfp.internal_flags.noise_shaping = 2; - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "noath")) { - gfp.noATH = true; - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "athonly")) { - gfp.ATHonly = true; - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "athshort")) { - gfp.ATHshort = true; - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "athlower")) { - argUsed = 1; - gfp.ATHlower = -(float) Double.parseDouble(nextArg) / 10.0f; - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "athtype")) { - argUsed = 1; - gfp.ATHtype = Integer.valueOf(nextArg); - - } else if (INTERNAL_OPTS - && token.substring(tokenPos).equalsIgnoreCase( - "athaa-type")) { - /* - * switch for developing, no DOCU - */ - argUsed = 1; - /* - * once was 1:Gaby, 2:Robert, 3:Jon, else:off - */ - gfp.athaa_type = Integer.valueOf(nextArg); - /* - * now: 0:off else:Jon - */ - - } else if (token.substring(tokenPos).equalsIgnoreCase( - "athaa-sensitivity")) { - argUsed = 1; - gfp.athaa_sensitivity = (float) Double - .parseDouble(nextArg); - - } else { - { - System.err.printf("%s: unrecognized option --%s\n", - ProgramName, token); - return -1; - } - } - i += argUsed; - - } else { - while (tokenPos < token.length()) { - c = token.charAt(tokenPos++); - - arg = tokenPos < token.length() ? token : nextArg; - switch (c) { - case 'm': - argUsed = 1; - - switch (arg.charAt(0)) { - case 's': - gfp.mode = MPEGMode.STEREO; - break; - case 'd': - gfp.mode = MPEGMode.DUAL_CHANNEL; - break; - case 'f': - gfp.force_ms = true; - /* FALLTHROUGH */ - case 'j': - gfp.mode = MPEGMode.JOINT_STEREO; - break; - case 'm': - gfp.mode = MPEGMode.MONO; - break; - case 'a': - gfp.mode = MPEGMode.JOINT_STEREO; - break; - default: - System.err - .printf("%s: -m mode must be s/d/j/f/m not %s\n", - ProgramName, arg); - return -1; - } - break; - - case 'V': - argUsed = 1; - /* to change VBR default look in lame.h */ - if (gfp.VBR == VbrMode.vbr_off) { - gfp.VBR_q = VbrMode.vbr_default.ordinal(); - gfp.VBR_q_frac = 0; - } - gfp.VBR_q = (int) (float) Double.parseDouble(arg); - gfp.VBR_q_frac = (float) Double.parseDouble(arg) - - gfp.VBR_q; - break; - case 'v': - /* to change VBR default look in lame.h */ - if (gfp.VBR == VbrMode.vbr_off) - gfp.VBR = VbrMode.vbr_mtrh; - break; - - case 'q': - argUsed = 1; - { - int tmp_quality = Integer.valueOf(arg); - - /* - * XXX should we move this into - * lame_set_quality()? - */ - if (tmp_quality < 0) - tmp_quality = 0; - if (tmp_quality > 9) - tmp_quality = 9; - - gfp.quality = tmp_quality; - } - break; - case 'f': - gfp.quality = 7; - break; - case 'h': - gfp.quality = 2; - break; - - case 's': - argUsed = 1; - val = Double.parseDouble(arg); - gfp.in_samplerate = (int) (val - * (val <= 192 ? 1.e3 : 1.e0) + 0.5); - break; - case 'b': - argUsed = 1; - gfp.brate = Integer.valueOf(arg); - - if (gfp.brate > 320) { - gfp.disable_reservoir = true; - } - gfp.VBR_min_bitrate_kbps = gfp.brate; - break; - case 'B': - argUsed = 1; - gfp.VBR_max_bitrate_kbps = Integer.valueOf(arg); - break; - case 'F': - gfp.VBR_hard_min = 1; - break; - case 't': /* dont write VBR tag */ - gfp.bWriteVbrTag = false; - disable_wav_header = true; - break; - case 'T': /* do write VBR tag */ - gfp.bWriteVbrTag = true; - nogap_tags = 1; - disable_wav_header = false; - break; - case 'r': /* force raw pcm input file */ - input_format = sound_file_format.sf_raw; - break; - case 'x': /* force byte swapping */ - swapbytes = true; - break; - case 'p': - /* - * (jo) error_protection: add crc16 information to - * stream - */ - gfp.error_protection = true; - break; - case 'a': - /* - * autoconvert input file from stereo to mono - for - * mono mp3 encoding - */ - autoconvert = 1; - gfp.mode = MPEGMode.MONO; - break; - case 'S': - silent = 10; - break; - case 'X': - /* - * experimental switch -X: the differnt types of - * quant compare are tough to communicate to - * endusers, so they shouldn't bother to toy around - * with them - */ - { - int x, y; - Scanner sc = new Scanner(arg); - x = sc.nextInt(); - if (!sc.hasNext()) { - y = x; - } else { - sc.nextByte(); - y = sc.nextInt(); - } - argUsed = 1; - if (INTERNAL_OPTS) { - gfp.quant_comp = x; - gfp.quant_comp_short = y; - } - } - break; - case 'Y': - gfp.experimentalY = true; - break; - case 'Z': - /* - * experimental switch -Z: this switch is obsolete - */ - { - int n = 1; - Scanner sc = new Scanner(arg); - n = sc.nextInt(); - if (INTERNAL_OPTS) { - gfp.experimentalZ = n; - } - } - break; - case 'e': - argUsed = 1; - - switch (arg.charAt(0)) { - case 'n': - gfp.emphasis = 0; - break; - case '5': - gfp.emphasis = 1; - break; - case 'c': - gfp.emphasis = 3; - break; - default: - System.err.printf( - "%s: -e emp must be n/5/c not %s\n", - ProgramName, arg); - return -1; - } - break; - case 'c': - gfp.copyright = 1; - break; - case 'o': - gfp.original = 0; - break; - - case '?': - long_help(gfp, System.out, ProgramName, 0 /* - * LESSMODE=NO - */); - return -1; - - default: - System.err.printf("%s: unrecognized option -%c\n", - ProgramName, c); - return -1; - } - if (argUsed != 0) { - if (arg == token) - token = ""; /* no more from token */ - else - ++i; /* skip arg we used */ - arg = ""; - argUsed = 0; - } - } - } - } else { - if (nogap != 0) { - if ((ng != null) && (count_nogap < ng.num_nogap)) { - nogap_inPath[count_nogap++] = argv.get(i); - input_file = 1; - } else { - /* sorry, calling program did not allocate enough space */ - System.err - .printf("Error: 'nogap option'. Calling program does not allow nogap option, or\n" - + "you have exceeded maximum number of input files for the nogap option\n"); - ng.num_nogap = -1; - return -1; - } - } else { - /* normal options: inputfile [outputfile] */ - if (inPath.length() == 0) { - inPath.setLength(0); - inPath.append(argv.get(i)); - input_file = 1; - } else { - if (outPath.length() == 0) { - outPath.setLength(0); - outPath.append(argv.get(i)); - } else { - System.err.printf("%s: excess arg %s\n", - ProgramName, argv.get(i)); - return -1; - } - } - } - } - } /* loop over args */ - - if (0 == input_file) { - usage(System.out, ProgramName); - return -1; - } - - if (inPath.toString().charAt(0) == '-') - silent = (silent <= 1 ? 1 : silent); - - if (outPath.length() == 0 && count_nogap == 0) { - outPath.setLength(0); - outPath.append(inPath.substring(0, inPath.length() - 4)); - if (gfp.decode_only) { - outPath.append(".mp3.wav"); - } else { - outPath.append(".mp3"); - } - } - - /* RG is enabled by default */ - if (0 == noreplaygain) - gfp.findReplayGain = true; - - /* disable VBR tags with nogap unless the VBR tags are forced */ - if (nogap != 0 && gfp.bWriteVbrTag && nogap_tags == 0) { - System.out - .println("Note: Disabling VBR Xing/Info tag since it interferes with --nogap\n"); - gfp.bWriteVbrTag = false; - } - - /* some file options not allowed with stdout */ - if (outPath.toString().charAt(0) == '-') { - gfp.bWriteVbrTag = false; /* turn off VBR tag */ - } - - /* if user did not explicitly specify input is mp3, check file name */ - if (input_format == sound_file_format.sf_unknown) - input_format = filename_to_type(inPath.toString()); - - if (input_format == sound_file_format.sf_ogg) { - System.err.printf("sorry, vorbis support in LAME is deprecated.\n"); - return -1; - } - /* default guess for number of channels */ - if (autoconvert != 0) - gfp.num_channels = 2; - else if (MPEGMode.MONO == gfp.mode) - gfp.num_channels = 1; - else - gfp.num_channels = 2; - - if (gfp.free_format) { - if (gfp.brate < 8 || gfp.brate > 640) { - System.err - .printf("For free format, specify a bitrate between 8 and 640 kbps\n"); - System.err.printf("with the -b <bitrate> option\n"); - return -1; - } - } - if (ng != null) - ng.num_nogap = count_nogap; - return 0; - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/PlottingData.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/PlottingData.java deleted file mode 100644 index 1d63692f4..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/PlottingData.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * GTK plotting routines source file - * - * Copyright (c) 1999 Mark Taylor - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -package mp3; - -/** - * used by the frame analyzer - */ -public class PlottingData { - /** - * current frame number - */ - int frameNum; - int frameNum123; - /** - * number of pcm samples read for this frame - */ - int num_samples; - /** - * starting time of frame, in seconds - */ - double frametime; - double pcmdata[][] = new double[2][1600]; - double pcmdata2[][] = new double[2][1152 + 1152 - Encoder.DECDELAY]; - double xr[][][] = new double[2][2][576]; - public double mpg123xr[][][] = new double[2][2][576]; - double ms_ratio[] = new double[2]; - double ms_ener_ratio[] = new double[2]; - - /* L,R, M and S values */ - - /** - * psymodel is one ahead - */ - double energy_save[][] = new double[4][Encoder.BLKSIZE]; - double energy[][][] = new double[2][4][Encoder.BLKSIZE]; - double pe[][] = new double[2][4]; - double thr[][][] = new double[2][4][Encoder.SBMAX_l]; - double en[][][] = new double[2][4][Encoder.SBMAX_l]; - double thr_s[][][] = new double[2][4][3 * Encoder.SBMAX_s]; - double en_s[][][] = new double[2][4][3 * Encoder.SBMAX_s]; - /** - * psymodel is one ahead - */ - double ers_save[] = new double[4]; - double ers[][] = new double[2][4]; - - public double sfb[][][] = new double[2][2][Encoder.SBMAX_l]; - public double sfb_s[][][] = new double[2][2][3 * Encoder.SBMAX_s]; - double LAMEsfb[][][] = new double[2][2][Encoder.SBMAX_l]; - double LAMEsfb_s[][][] = new double[2][2][3 * Encoder.SBMAX_s]; - - int LAMEqss[][] = new int[2][2]; - public int qss[][] = new int[2][2]; - public int big_values[][] = new int[2][2]; - public int sub_gain[][][] = new int[2][2][3]; - - double xfsf[][][] = new double[2][2][Encoder.SBMAX_l]; - double xfsf_s[][][] = new double[2][2][3 * Encoder.SBMAX_s]; - - int over[][] = new int[2][2]; - double tot_noise[][] = new double[2][2]; - double max_noise[][] = new double[2][2]; - double over_noise[][] = new double[2][2]; - int over_SSD[][] = new int[2][2]; - int blocktype[][] = new int[2][2]; - public int scalefac_scale[][] = new int[2][2]; - public int preflag[][] = new int[2][2]; - public int mpg123blocktype[][] = new int[2][2]; - public int mixed[][] = new int[2][2]; - public int mainbits[][] = new int[2][2]; - public int sfbits[][] = new int[2][2]; - int LAMEmainbits[][] = new int[2][2]; - int LAMEsfbits[][] = new int[2][2]; - public int framesize, stereo, js, ms_stereo, i_stereo, emph, bitrate, - sampfreq, maindata; - public int crc, padding; - public int scfsi[] = new int[2], mean_bits, resvsize; - int totbits; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Presets.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Presets.java deleted file mode 100644 index a27e69f3a..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Presets.java +++ /dev/null @@ -1,423 +0,0 @@ -package mp3; - -public class Presets { - Lame lame; - - public final void setModules(Lame lame) { - this.lame = lame; - } - - /** - * <PRE> - * Switch mappings for VBR mode VBR_RH - * vbr_q qcomp_l qcomp_s expY st_lrm st_s mask adj_l adj_s ath_lower ath_curve ath_sens interChR safejoint sfb21mod msfix - * </PRE> - */ - private static final VBRPresets vbr_old_switch_map[] = { - new VBRPresets(0, 9, 9, 0, 5.20f, 125.0f, -4.2f, -6.3f, 4.8f, 1f, 0f, 0f, 2, 21, 0.97f), - new VBRPresets(1, 9, 9, 0, 5.30f, 125.0f, -3.6f, -5.6f, 4.5f, 1.5f, 0f, 0f, 2, 21, 1.35f), - new VBRPresets(2, 9, 9, 0, 5.60f, 125.0f, -2.2f, -3.5f, 2.8f, 2f, 0f, 0f, 2, 21, 1.49f), - new VBRPresets(3, 9, 9, 1, 5.80f, 130.0f, -1.8f, -2.8f, 2.6f, 3f, -4f, 0f, 2, 20, 1.64f), - new VBRPresets(4, 9, 9, 1, 6.00f, 135.0f, -0.7f, -1.1f, 1.1f, 3.5f, -8f, 0f, 2, 0, 1.79f), - new VBRPresets(5, 9, 9, 1, 6.40f, 140.0f, 0.5f, 0.4f, -7.5f, 4f, -12f, 0.0002f, 0, 0, 1.95f), - new VBRPresets(6, 9, 9, 1, 6.60f, 145.0f, 0.67f, 0.65f, -14.7f, 6.5f, -19f, 0.0004f, 0, 0, 2.30f), - new VBRPresets(7, 9, 9, 1, 6.60f, 145.0f, 0.8f, 0.75f, -19.7f, 8f, -22f, 0.0006f, 0, 0, 2.70f), - new VBRPresets(8, 9, 9, 1, 6.60f, 145.0f, 1.2f, 1.15f, -27.5f, 10f, -23f, 0.0007f, 0, 0, 0f ), - new VBRPresets(9, 9, 9, 1, 6.60f, 145.0f, 1.6f, 1.6f, -36f, 11f, -25f, 0.0008f, 0, 0, 0f ), - new VBRPresets(10, 9, 9, 1, 6.60f, 145.0f, 2.0f, 2.0f, -36f, 12f, -25f, 0.0008f, 0, 0, 0f ) - }; - - /** - * <PRE> - * vbr_q qcomp_l qcomp_s expY st_lrm st_s mask adj_l adj_s ath_lower ath_curve ath_sens interChR safejoint sfb21mod msfix - * </PRE> - */ - private static final VBRPresets vbr_psy_switch_map[] = { - new VBRPresets(0, 9, 9, 0, 4.20f, 25.0f, -7.0f, -4.0f, 7.5f, 1f, 0f, 0f, 2, 26, 0.97f), - new VBRPresets(1, 9, 9, 0, 4.20f, 25.0f, -5.6f, -3.6f, 4.5f, 1.5f, 0f, 0f, 2, 21, 1.35f), - new VBRPresets(2, 9, 9, 0, 4.20f, 25.0f, -4.4f, -1.8f, 2f, 2f, 0f, 0f, 2, 18, 1.49f), - new VBRPresets(3, 9, 9, 1, 4.20f, 25.0f, -3.4f, -1.25f, 1.1f, 3f, -4f, 0f, 2, 15, 1.64f), - new VBRPresets(4, 9, 9, 1, 4.20f, 25.0f, -2.2f, 0.1f, 0f, 3.5f, -8f, 0f, 2, 0, 1.79f), - new VBRPresets(5, 9, 9, 1, 4.20f, 25.0f, -1.0f, 1.65f, -7.7f, 4f, -12f, 0.0002f, 0, 0, 1.95f), - new VBRPresets(6, 9, 9, 1, 4.20f, 25.0f, -0.0f, 2.47f, -7.7f, 6.5f, -19f, 0.0004f, 0, 0, 2f ), - new VBRPresets(7, 9, 9, 1, 4.20f, 25.0f, 0.5f, 2.0f, -14.5f, 8f, -22f, 0.0006f, 0, 0, 2f ), - new VBRPresets(8, 9, 9, 1, 4.20f, 25.0f, 1.0f, 2.4f, -22.0f, 10f, -23f, 0.0007f, 0, 0, 2f ), - new VBRPresets(9, 9, 9, 1, 4.20f, 25.0f, 1.5f, 2.95f, -30.0f, 11f, -25f, 0.0008f, 0, 0, 2f ), - new VBRPresets(10, 9, 9, 1, 4.20f, 25.0f, 2.0f, 2.95f, -36.0f, 12f, -30f, 0.0008f, 0, 0, 2f ) - }; - - private void apply_vbr_preset(final LameGlobalFlags gfp, final int a, - final int enforce) { - final VBRPresets[] vbr_preset = gfp.VBR == VbrMode.vbr_rh ? vbr_old_switch_map - : vbr_psy_switch_map; - - float x = gfp.VBR_q_frac; - VBRPresets p = vbr_preset[a]; - VBRPresets q = vbr_preset[a + 1]; - final VBRPresets set = p; - - // NOOP(vbr_q); - // NOOP(quant_comp); - // NOOP(quant_comp_s); - // NOOP(expY); - p.st_lrm = p.st_lrm + x * (q.st_lrm - p.st_lrm); - // LERP(st_lrm); - p.st_s = p.st_s + x * (q.st_s - p.st_s); - // LERP(st_s); - p.masking_adj = p.masking_adj + x * (q.masking_adj - p.masking_adj); - // LERP(masking_adj); - p.masking_adj_short = p.masking_adj_short + x - * (q.masking_adj_short - p.masking_adj_short); - // LERP(masking_adj_short); - p.ath_lower = p.ath_lower + x * (q.ath_lower - p.ath_lower); - // LERP(ath_lower); - p.ath_curve = p.ath_curve + x * (q.ath_curve - p.ath_curve); - // LERP(ath_curve); - p.ath_sensitivity = p.ath_sensitivity + x - * (q.ath_sensitivity - p.ath_sensitivity); - // LERP(ath_sensitivity); - p.interch = p.interch + x * (q.interch - p.interch); - // LERP(interch); - // NOOP(safejoint); - // NOOP(sfb21mod); - p.msfix = p.msfix + x * (q.msfix - p.msfix); - // LERP(msfix); - - lame_set_VBR_q(gfp, set.vbr_q); - - if (enforce != 0) - gfp.quant_comp = set.quant_comp; - else if (!(Math.abs(gfp.quant_comp - -1) > 0)) - gfp.quant_comp = set.quant_comp; - // SET_OPTION(quant_comp, set.quant_comp, -1); - if (enforce != 0) - gfp.quant_comp_short = set.quant_comp_s; - else if (!(Math.abs(gfp.quant_comp_short - -1) > 0)) - gfp.quant_comp_short = set.quant_comp_s; - // SET_OPTION(quant_comp_short, set.quant_comp_s, -1); - if (set.expY != 0) { - gfp.experimentalY = set.expY != 0; - } - if (enforce != 0) - gfp.internal_flags.nsPsy.attackthre = set.st_lrm; - else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre - -1) > 0)) - gfp.internal_flags.nsPsy.attackthre = set.st_lrm; - // SET_OPTION(short_threshold_lrm, set.st_lrm, -1); - if (enforce != 0) - gfp.internal_flags.nsPsy.attackthre_s = set.st_s; - else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre_s - -1) > 0)) - gfp.internal_flags.nsPsy.attackthre_s = set.st_s; - // SET_OPTION(short_threshold_s, set.st_s, -1); - if (enforce != 0) - gfp.maskingadjust = set.masking_adj; - else if (!(Math.abs(gfp.maskingadjust - 0) > 0)) - gfp.maskingadjust = set.masking_adj; - // SET_OPTION(maskingadjust, set.masking_adj, 0); - if (enforce != 0) - gfp.maskingadjust_short = set.masking_adj_short; - else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0)) - gfp.maskingadjust_short = set.masking_adj_short; - // SET_OPTION(maskingadjust_short, set.masking_adj_short, 0); - if (enforce != 0) - gfp.ATHlower = -set.ath_lower / 10.0f; - else if (!(Math.abs((-gfp.ATHlower * 10.0) - 0) > 0)) - gfp.ATHlower = -set.ath_lower / 10.0f; - // SET_OPTION(ATHlower, set.ath_lower, 0); - if (enforce != 0) - gfp.ATHcurve = set.ath_curve; - else if (!(Math.abs(gfp.ATHcurve - -1) > 0)) - gfp.ATHcurve = set.ath_curve; - // SET_OPTION(ATHcurve, set.ath_curve, -1); - if (enforce != 0) - gfp.athaa_sensitivity = set.ath_sensitivity; - else if (!(Math.abs(gfp.athaa_sensitivity - -1) > 0)) - gfp.athaa_sensitivity = set.ath_sensitivity; - // SET_OPTION(athaa_sensitivity, set.ath_sensitivity, 0); - if (set.interch > 0) { - if (enforce != 0) - gfp.interChRatio = set.interch; - else if (!(Math.abs(gfp.interChRatio - -1) > 0)) - gfp.interChRatio = set.interch; - // SET_OPTION(interChRatio, set.interch, -1); - } - - /* parameters for which there is no proper set/get interface */ - if (set.safejoint > 0) { - gfp.exp_nspsytune = gfp.exp_nspsytune | set.safejoint; - } - if (set.sfb21mod > 0) { - gfp.exp_nspsytune = gfp.exp_nspsytune | (set.sfb21mod << 20); - } - if (enforce != 0) - gfp.msfix = set.msfix; - else if (!(Math.abs(gfp.msfix - -1) > 0)) - gfp.msfix = set.msfix; - // SET_OPTION(msfix, set.msfix, -1); - - if (enforce == 0) { - gfp.VBR_q = a; - gfp.VBR_q_frac = x; - } - } - - /** - * <PRE> - * Switch mappings for ABR mode - * - * kbps quant q_s safejoint nsmsfix st_lrm st_s ns-bass scale msk ath_lwr ath_curve interch , sfscale - * </PRE> - */ - private static final ABRPresets abr_switch_map[] = { - new ABRPresets( 8, 9, 9, 0, 0f, 6.60f, 145f, 0f, 0.95f, 0f, -30.0f, 11f, 0.0012f, 1), /* 8, impossible to use in stereo */ - new ABRPresets( 16, 9, 9, 0, 0f, 6.60f, 145f, 0f, 0.95f, 0f, -25.0f, 11f, 0.0010f, 1), /* 16 */ - new ABRPresets( 24, 9, 9, 0, 0f, 6.60f, 145f, 0f, 0.95f, 0f, -20.0f, 11f, 0.0010f, 1), /* 24 */ - new ABRPresets( 32, 9, 9, 0, 0f, 6.60f, 145f, 0f, 0.95f, 0f, -15.0f, 11f, 0.0010f, 1), /* 32 */ - new ABRPresets( 40, 9, 9, 0, 0f, 6.60f, 145f, 0f, 0.95f, 0f, -10.0f, 11f, 0.0009f, 1), /* 40 */ - new ABRPresets( 48, 9, 9, 0, 0f, 6.60f, 145f, 0f, 0.95f, 0f, -10.0f, 11f, 0.0009f, 1), /* 48 */ - new ABRPresets( 56, 9, 9, 0, 0f, 6.60f, 145f, 0f, 0.95f, 0f, -6.0f, 11f, 0.0008f, 1), /* 56 */ - new ABRPresets( 64, 9, 9, 0, 0f, 6.60f, 145f, 0f, 0.95f, 0f, -2.0f, 11f, 0.0008f, 1), /* 64 */ - new ABRPresets( 80, 9, 9, 0, 0f, 6.60f, 145f, 0f, 0.95f, 0f, .0f, 8f, 0.0007f, 1), /* 80 */ - new ABRPresets( 96, 9, 9, 0, 2.50f, 6.60f, 145f, 0f, 0.95f, 0f, 1.0f, 5.5f, 0.0006f, 1), /* 96 */ - new ABRPresets(112, 9, 9, 0, 2.25f, 6.60f, 145f, 0f, 0.95f, 0f, 2.0f, 4.5f, 0.0005f, 1), /* 112 */ - new ABRPresets(128, 9, 9, 0, 1.95f, 6.40f, 140f, 0f, 0.95f, 0f, 3.0f, 4f, 0.0002f, 1), /* 128 */ - new ABRPresets(160, 9, 9, 1, 1.79f, 6.00f, 135f, 0f, 0.95f, -2f, 5.0f, 3.5f, 0f, 1), /* 160 */ - new ABRPresets(192, 9, 9, 1, 1.49f, 5.60f, 125f, 0f, 0.97f, -4f, 7.0f, 3f, 0f, 0), /* 192 */ - new ABRPresets(224, 9, 9, 1, 1.25f, 5.20f, 125f, 0f, 0.98f, -6f, 9.0f, 2f, 0f, 0), /* 224 */ - new ABRPresets(256, 9, 9, 1, 0.97f, 5.20f, 125f, 0f, 1.00f, -8f, 10.0f, 1f, 0f, 0), /* 256 */ - new ABRPresets(320, 9, 9, 1, 0.90f, 5.20f, 125f, 0f, 1.00f, -10f, 12.0f, 0f, 0f, 0) /* 320 */ - }; - - private int apply_abr_preset(final LameGlobalFlags gfp, final int preset, - final int enforce) { - /* Variables for the ABR stuff */ - int actual_bitrate = preset; - - int r = lame.nearestBitrateFullIndex(preset); - - gfp.VBR = VbrMode.vbr_abr; - gfp.VBR_mean_bitrate_kbps = actual_bitrate; - gfp.VBR_mean_bitrate_kbps = Math.min(gfp.VBR_mean_bitrate_kbps, 320); - gfp.VBR_mean_bitrate_kbps = Math.max(gfp.VBR_mean_bitrate_kbps, 8); - gfp.brate = gfp.VBR_mean_bitrate_kbps; - if (gfp.VBR_mean_bitrate_kbps > 320) { - gfp.disable_reservoir = true; - } - - /* parameters for which there is no proper set/get interface */ - if (abr_switch_map[r].safejoint > 0) - gfp.exp_nspsytune = gfp.exp_nspsytune | 2; /* safejoint */ - - if (abr_switch_map[r].sfscale > 0) { - gfp.internal_flags.noise_shaping = 2; - } - /* ns-bass tweaks */ - if (Math.abs(abr_switch_map[r].nsbass) > 0) { - int k = (int) (abr_switch_map[r].nsbass * 4); - if (k < 0) - k += 64; - gfp.exp_nspsytune = gfp.exp_nspsytune | (k << 2); - } - - if (enforce != 0) - gfp.quant_comp = abr_switch_map[r].quant_comp; - else if (!(Math.abs(gfp.quant_comp - -1) > 0)) - gfp.quant_comp = abr_switch_map[r].quant_comp; - // SET_OPTION(quant_comp, abr_switch_map[r].quant_comp, -1); - if (enforce != 0) - gfp.quant_comp_short = abr_switch_map[r].quant_comp_s; - else if (!(Math.abs(gfp.quant_comp_short - -1) > 0)) - gfp.quant_comp_short = abr_switch_map[r].quant_comp_s; - // SET_OPTION(quant_comp_short, abr_switch_map[r].quant_comp_s, -1); - - if (enforce != 0) - gfp.msfix = abr_switch_map[r].nsmsfix; - else if (!(Math.abs(gfp.msfix - -1) > 0)) - gfp.msfix = abr_switch_map[r].nsmsfix; - // SET_OPTION(msfix, abr_switch_map[r].nsmsfix, -1); - - if (enforce != 0) - gfp.internal_flags.nsPsy.attackthre = abr_switch_map[r].st_lrm; - else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre - -1) > 0)) - gfp.internal_flags.nsPsy.attackthre = abr_switch_map[r].st_lrm; - // SET_OPTION(short_threshold_lrm, abr_switch_map[r].st_lrm, -1); - if (enforce != 0) - gfp.internal_flags.nsPsy.attackthre_s = abr_switch_map[r].st_s; - else if (!(Math.abs(gfp.internal_flags.nsPsy.attackthre_s - -1) > 0)) - gfp.internal_flags.nsPsy.attackthre_s = abr_switch_map[r].st_s; - // SET_OPTION(short_threshold_s, abr_switch_map[r].st_s, -1); - - /* - * ABR seems to have big problems with clipping, especially at low - * bitrates - */ - /* - * so we compensate for that here by using a scale value depending on - * bitrate - */ - if (enforce != 0) - gfp.scale = abr_switch_map[r].scale; - else if (!(Math.abs(gfp.scale - -1) > 0)) - gfp.scale = abr_switch_map[r].scale; - // SET_OPTION(scale, abr_switch_map[r].scale, -1); - - if (enforce != 0) - gfp.maskingadjust = abr_switch_map[r].masking_adj; - else if (!(Math.abs(gfp.maskingadjust - 0) > 0)) - gfp.maskingadjust = abr_switch_map[r].masking_adj; - // SET_OPTION(maskingadjust, abr_switch_map[r].masking_adj, 0); - if (abr_switch_map[r].masking_adj > 0) { - if (enforce != 0) - gfp.maskingadjust_short = (float) (abr_switch_map[r].masking_adj * .9); - else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0)) - gfp.maskingadjust_short = (float) (abr_switch_map[r].masking_adj * .9); - // SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * - // .9, 0); - } else { - if (enforce != 0) - gfp.maskingadjust_short = (float) (abr_switch_map[r].masking_adj * 1.1); - else if (!(Math.abs(gfp.maskingadjust_short - 0) > 0)) - gfp.maskingadjust_short = (float) (abr_switch_map[r].masking_adj * 1.1); - // SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * - // 1.1, 0); - } - - if (enforce != 0) - gfp.ATHlower = -abr_switch_map[r].ath_lower / 10.f; - else if (!(Math.abs((-gfp.ATHlower * 10.f) - 0) > 0)) - gfp.ATHlower = -abr_switch_map[r].ath_lower / 10.f; - // SET_OPTION(ATHlower, abr_switch_map[r].ath_lower, 0); - if (enforce != 0) - gfp.ATHcurve = abr_switch_map[r].ath_curve; - else if (!(Math.abs(gfp.ATHcurve - -1) > 0)) - gfp.ATHcurve = abr_switch_map[r].ath_curve; - // SET_OPTION(ATHcurve, abr_switch_map[r].ath_curve, -1); - - if (enforce != 0) - gfp.interChRatio = abr_switch_map[r].interch; - else if (!(Math.abs(gfp.interChRatio - -1) > 0)) - gfp.interChRatio = abr_switch_map[r].interch; - // SET_OPTION(interChRatio, abr_switch_map[r].interch, -1); - - return preset; - } - - public final int apply_preset(final LameGlobalFlags gfp, int preset, - final int enforce) { - /* translate legacy presets */ - switch (preset) { - case Lame.R3MIX: { - preset = Lame.V3; - gfp.VBR = VbrMode.vbr_mtrh; - break; - } - case Lame.MEDIUM: { - preset = Lame.V4; - gfp.VBR = VbrMode.vbr_rh; - break; - } - case Lame.MEDIUM_FAST: { - preset = Lame.V4; - gfp.VBR = VbrMode.vbr_mtrh; - break; - } - case Lame.STANDARD: { - preset = Lame.V2; - gfp.VBR = VbrMode.vbr_rh; - break; - } - case Lame.STANDARD_FAST: { - preset = Lame.V2; - gfp.VBR = VbrMode.vbr_mtrh; - break; - } - case Lame.EXTREME: { - preset = Lame.V0; - gfp.VBR = VbrMode.vbr_rh; - break; - } - case Lame.EXTREME_FAST: { - preset = Lame.V0; - gfp.VBR = VbrMode.vbr_mtrh; - break; - } - case Lame.INSANE: { - preset = 320; - gfp.preset = preset; - apply_abr_preset(gfp, preset, enforce); - gfp.VBR = VbrMode.vbr_off; - return preset; - } - } - - gfp.preset = preset; - { - switch (preset) { - case Lame.V9: - apply_vbr_preset(gfp, 9, enforce); - return preset; - case Lame.V8: - apply_vbr_preset(gfp, 8, enforce); - return preset; - case Lame.V7: - apply_vbr_preset(gfp, 7, enforce); - return preset; - case Lame.V6: - apply_vbr_preset(gfp, 6, enforce); - return preset; - case Lame.V5: - apply_vbr_preset(gfp, 5, enforce); - return preset; - case Lame.V4: - apply_vbr_preset(gfp, 4, enforce); - return preset; - case Lame.V3: - apply_vbr_preset(gfp, 3, enforce); - return preset; - case Lame.V2: - apply_vbr_preset(gfp, 2, enforce); - return preset; - case Lame.V1: - apply_vbr_preset(gfp, 1, enforce); - return preset; - case Lame.V0: - apply_vbr_preset(gfp, 0, enforce); - return preset; - default: - break; - } - } - if (8 <= preset && preset <= 320) { - return apply_abr_preset(gfp, preset, enforce); - } - - /* no corresponding preset found */ - gfp.preset = 0; - return preset; - } - - // Rest from getset.c: - - /** - * VBR quality level.<BR> - * 0 = highest<BR> - * 9 = lowest - */ - public int lame_set_VBR_q(final LameGlobalFlags gfp, int VBR_q) { - int ret = 0; - - if (0 > VBR_q) { - /* Unknown VBR quality level! */ - ret = -1; - VBR_q = 0; - } - if (9 < VBR_q) { - ret = -1; - VBR_q = 9; - } - - gfp.VBR_q = VBR_q; - gfp.VBR_q_frac = 0; - return ret; - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/PsyModel.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/PsyModel.java deleted file mode 100644 index c394d39ea..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/PsyModel.java +++ /dev/null @@ -1,2942 +0,0 @@ -/* - * psymodel.c - * - * Copyright (c) 1999-2000 Mark Taylor - * Copyright (c) 2001-2002 Naoki Shibata - * Copyright (c) 2000-2003 Takehiro Tominaga - * Copyright (c) 2000-2008 Robert Hegemann - * Copyright (c) 2000-2005 Gabriel Bouvigne - * Copyright (c) 2000-2005 Alexander Leidinger - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: PsyModel.java,v 1.27 2011/05/24 20:48:06 kenchis Exp $ */ - - -/* -PSYCHO ACOUSTICS - - -This routine computes the psycho acoustics, delayed by one granule. - -Input: buffer of PCM data (1024 samples). - -This window should be centered over the 576 sample granule window. -The routine will compute the psycho acoustics for -this granule, but return the psycho acoustics computed -for the *previous* granule. This is because the block -type of the previous granule can only be determined -after we have computed the psycho acoustics for the following -granule. - -Output: maskings and energies for each scalefactor band. -block type, PE, and some correlation measures. -The PE is used by CBR modes to determine if extra bits -from the bit reservoir should be used. The correlation -measures are used to determine mid/side or regular stereo. -*/ -/* -Notation: - -barks: a non-linear frequency scale. Mapping from frequency to - barks is given by freq2bark() - -scalefactor bands: The spectrum (frequencies) are broken into - SBMAX "scalefactor bands". Thes bands - are determined by the MPEG ISO spec. In - the noise shaping/quantization code, we allocate - bits among the partition bands to achieve the - best possible quality - -partition bands: The spectrum is also broken into about - 64 "partition bands". Each partition - band is about .34 barks wide. There are about 2-5 - partition bands for each scalefactor band. - -LAME computes all psycho acoustic information for each partition -band. Then at the end of the computations, this information -is mapped to scalefactor bands. The energy in each scalefactor -band is taken as the sum of the energy in all partition bands -which overlap the scalefactor band. The maskings can be computed -in the same way (and thus represent the average masking in that band) -or by taking the minmum value multiplied by the number of -partition bands used (which represents a minimum masking in that band). -*/ -/* -The general outline is as follows: - -1. compute the energy in each partition band -2. compute the tonality in each partition band -3. compute the strength of each partion band "masker" -4. compute the masking (via the spreading function applied to each masker) -5. Modifications for mid/side masking. - -Each partition band is considiered a "masker". The strength -of the i'th masker in band j is given by: - - s3(bark(i)-bark(j))*strength(i) - -The strength of the masker is a function of the energy and tonality. -The more tonal, the less masking. LAME uses a simple linear formula -(controlled by NMT and TMN) which says the strength is given by the -energy divided by a linear function of the tonality. -*/ -/* -s3() is the "spreading function". It is given by a formula -determined via listening tests. - -The total masking in the j'th partition band is the sum over -all maskings i. It is thus given by the convolution of -the strength with s3(), the "spreading function." - -masking(j) = sum_over_i s3(i-j)*strength(i) = s3 o strength - -where "o" = convolution operator. s3 is given by a formula determined -via listening tests. It is normalized so that s3 o 1 = 1. - -Note: instead of a simple convolution, LAME also has the -option of using "additive masking" - -The most critical part is step 2, computing the tonality of each -partition band. LAME has two tonality estimators. The first -is based on the ISO spec, and measures how predictiable the -signal is over time. The more predictable, the more tonal. -The second measure is based on looking at the spectrum of -a single granule. The more peaky the spectrum, the more -tonal. By most indications, the latter approach is better. - -Finally, in step 5, the maskings for the mid and side -channel are possibly increased. Under certain circumstances, -noise in the mid & side channels is assumed to also -be masked by strong maskers in the L or R channels. - - -Other data computed by the psy-model: - -ms_ratio side-channel / mid-channel masking ratio (for previous granule) -ms_ratio_next side-channel / mid-channel masking ratio for this granule - -percep_entropy[2] L and R values (prev granule) of PE - A measure of how - much pre-echo is in the previous granule -percep_entropy_MS[2] mid and side channel values (prev granule) of percep_entropy -energy[4] L,R,M,S energy in each channel, prev granule -blocktype_d[2] block type to use for previous granule -*/ -package mp3; - -import java.util.Arrays; - -public class PsyModel { - - private FFT fft = new FFT(); - - private static final float LOG10 = 2.30258509299404568402f; - - private static final int rpelev = 2; - private static final int rpelev2 = 16; - private static final int rpelev_s = 2; - private static final int rpelev2_s = 16; - - /* size of each partition band, in barks: */ - private static final float DELBARK = .34f; - - /* tuned for output level (sensitive to energy scale) */ - private static final float VO_SCALE = (1.f / (14752 * 14752) / (Encoder.BLKSIZE / 2)); - - private static final float temporalmask_sustain_sec = 0.01f; - - private static final float NS_PREECHO_ATT0 = 0.8f; - private static final float NS_PREECHO_ATT1 = 0.6f; - private static final float NS_PREECHO_ATT2 = 0.3f; - - private static final float NS_MSFIX = 3.5f; - public static final float NSATTACKTHRE = 4.4f; - public static final int NSATTACKTHRE_S = 25; - - private static final int NSFIRLEN = 21; - - /* size of each partition band, in barks: */ - private static final float LN_TO_LOG10 = 0.2302585093f; - - private static final float NON_LINEAR_SCALE_ENERGY(float x) { - return x; - } - - /** - * <PRE> - * L3psycho_anal. Compute psycho acoustics. - * - * Data returned to the calling program must be delayed by one - * granule. - * - * This is done in two places. - * If we do not need to know the blocktype, the copying - * can be done here at the top of the program: we copy the data for - * the last granule (computed during the last call) before it is - * overwritten with the new data. It looks like this: - * - * 0. static psymodel_data - * 1. calling_program_data = psymodel_data - * 2. compute psymodel_data - * - * For data which needs to know the blocktype, the copying must be - * done at the end of this loop, and the old values must be saved: - * - * 0. static psymodel_data_old - * 1. compute psymodel_data - * 2. compute possible block type of this granule - * 3. compute final block type of previous granule based on #2. - * 4. calling_program_data = psymodel_data_old - * 5. psymodel_data_old = psymodel_data - * psycho_loudness_approx - * jd - 2001 mar 12 - * in: energy - BLKSIZE/2 elements of frequency magnitudes ^ 2 - * gfp - uses out_samplerate, ATHtype (also needed for ATHformula) - * returns: loudness^2 approximation, a positive value roughly tuned for a value - * of 1.0 for signals near clipping. - * notes: When calibrated, feeding this function binary white noise at sample - * values +32767 or -32768 should return values that approach 3. - * ATHformula is used to approximate an equal loudness curve. - * future: Data indicates that the shape of the equal loudness curve varies - * with intensity. This function might be improved by using an equal - * loudness curve shaped for typical playback levels (instead of the - * ATH, that is shaped for the threshold). A flexible realization might - * simply bend the existing ATH curve to achieve the desired shape. - * However, the potential gain may not be enough to justify an effort. - * </PRE> - */ - private float psycho_loudness_approx(final float[] energy, - final LameInternalFlags gfc) { - float loudness_power = 0.0f; - /* apply weights to power in freq. bands */ - for (int i = 0; i < Encoder.BLKSIZE / 2; ++i) - loudness_power += energy[i] * gfc.ATH.eql_w[i]; - loudness_power *= VO_SCALE; - - return loudness_power; - } - - private void compute_ffts(final LameGlobalFlags gfp, - final float fftenergy[], final float fftenergy_s[][], - final float wsamp_l[][], final int wsamp_lPos, - final float wsamp_s[][][], final int wsamp_sPos, final int gr_out, - final int chn, final float[] buffer[], final int bufPos) { - final LameInternalFlags gfc = gfp.internal_flags; - if (chn < 2) { - fft.fft_long(gfc, wsamp_l[wsamp_lPos], chn, buffer, bufPos); - fft.fft_short(gfc, wsamp_s[wsamp_sPos], chn, buffer, bufPos); - } - /* FFT data for mid and side channel is derived from L & R */ - else if (chn == 2) { - for (int j = Encoder.BLKSIZE - 1; j >= 0; --j) { - final float l = wsamp_l[wsamp_lPos + 0][j]; - final float r = wsamp_l[wsamp_lPos + 1][j]; - wsamp_l[wsamp_lPos + 0][j] = (l + r) * Util.SQRT2 * 0.5f; - wsamp_l[wsamp_lPos + 1][j] = (l - r) * Util.SQRT2 * 0.5f; - } - for (int b = 2; b >= 0; --b) { - for (int j = Encoder.BLKSIZE_s - 1; j >= 0; --j) { - final float l = wsamp_s[wsamp_sPos + 0][b][j]; - final float r = wsamp_s[wsamp_sPos + 1][b][j]; - wsamp_s[wsamp_sPos + 0][b][j] = (l + r) * Util.SQRT2 * 0.5f; - wsamp_s[wsamp_sPos + 1][b][j] = (l - r) * Util.SQRT2 * 0.5f; - } - } - } - - /********************************************************************* - * compute energies - *********************************************************************/ - fftenergy[0] = NON_LINEAR_SCALE_ENERGY(wsamp_l[wsamp_lPos + 0][0]); - fftenergy[0] *= fftenergy[0]; - - for (int j = Encoder.BLKSIZE / 2 - 1; j >= 0; --j) { - final float re = (wsamp_l[wsamp_lPos + 0])[Encoder.BLKSIZE / 2 - j]; - final float im = (wsamp_l[wsamp_lPos + 0])[Encoder.BLKSIZE / 2 + j]; - fftenergy[Encoder.BLKSIZE / 2 - j] = NON_LINEAR_SCALE_ENERGY((re - * re + im * im) * 0.5f); - } - for (int b = 2; b >= 0; --b) { - fftenergy_s[b][0] = (wsamp_s[wsamp_sPos + 0])[b][0]; - fftenergy_s[b][0] *= fftenergy_s[b][0]; - for (int j = Encoder.BLKSIZE_s / 2 - 1; j >= 0; --j) { - final float re = (wsamp_s[wsamp_sPos + 0])[b][Encoder.BLKSIZE_s - / 2 - j]; - final float im = (wsamp_s[wsamp_sPos + 0])[b][Encoder.BLKSIZE_s - / 2 + j]; - fftenergy_s[b][Encoder.BLKSIZE_s / 2 - j] = NON_LINEAR_SCALE_ENERGY((re - * re + im * im) * 0.5f); - } - } - /* total energy */ - { - float totalenergy = 0.0f; - for (int j = 11; j < Encoder.HBLKSIZE; j++) - totalenergy += fftenergy[j]; - - gfc.tot_ener[chn] = totalenergy; - } - - if (gfp.analysis) { - for (int j = 0; j < Encoder.HBLKSIZE; j++) { - gfc.pinfo.energy[gr_out][chn][j] = gfc.pinfo.energy_save[chn][j]; - gfc.pinfo.energy_save[chn][j] = fftenergy[j]; - } - gfc.pinfo.pe[gr_out][chn] = gfc.pe[chn]; - } - - /********************************************************************* - * compute loudness approximation (used for ATH auto-level adjustment) - *********************************************************************/ - if (gfp.athaa_loudapprox == 2 && chn < 2) { - // no loudness for mid/side ch - gfc.loudness_sq[gr_out][chn] = gfc.loudness_sq_save[chn]; - gfc.loudness_sq_save[chn] = psycho_loudness_approx(fftenergy, gfc); - } - } - - /* mask_add optimization */ - /* init the limit values used to avoid computing log in mask_add when it is not necessary */ - - /** - * <PRE> - * For example, with i = 10*log10(m2/m1)/10*16 (= log10(m2/m1)*16) - * - * abs(i)>8 is equivalent (as i is an integer) to - * abs(i)>=9 - * i>=9 || i<=-9 - * equivalent to (as i is the biggest integer smaller than log10(m2/m1)*16 - * or the smallest integer bigger than log10(m2/m1)*16 depending on the sign of log10(m2/m1)*16) - * log10(m2/m1)>=9/16 || log10(m2/m1)<=-9/16 - * exp10 is strictly increasing thus this is equivalent to - * m2/m1 >= 10^(9/16) || m2/m1<=10^(-9/16) which are comparisons to constants - * </PRE> - */ - - /** - * as in if(i>8) - */ - private static final int I1LIMIT = 8; - /** - * as in if(i>24) . changed 23 - */ - private static final int I2LIMIT = 23; - /** - * as in if(m<15) - */ - private static final int MLIMIT = 15; - - private float ma_max_i1; - private float ma_max_i2; - private float ma_max_m; - - /** - * This is the masking table:<BR> - * According to tonality, values are going from 0dB (TMN) to 9.3dB (NMT).<BR> - * After additive masking computation, 8dB are added, so final values are - * going from 8dB to 17.3dB - * - * pow(10, -0.0..-0.6) - */ - private static final float tab[] = { 1.0f, 0.79433f, 0.63096f, 0.63096f, - 0.63096f, 0.63096f, 0.63096f, 0.25119f, 0.11749f }; - - private void init_mask_add_max_values() { - ma_max_i1 = (float) Math.pow(10, (I1LIMIT + 1) / 16.0); - ma_max_i2 = (float) Math.pow(10, (I2LIMIT + 1) / 16.0); - ma_max_m = (float) Math.pow(10, (MLIMIT) / 10.0); - } - - private static final float table1[] = { 3.3246f * 3.3246f, - 3.23837f * 3.23837f, 3.15437f * 3.15437f, 3.00412f * 3.00412f, - 2.86103f * 2.86103f, 2.65407f * 2.65407f, 2.46209f * 2.46209f, - 2.284f * 2.284f, 2.11879f * 2.11879f, 1.96552f * 1.96552f, - 1.82335f * 1.82335f, 1.69146f * 1.69146f, 1.56911f * 1.56911f, - 1.46658f * 1.46658f, 1.37074f * 1.37074f, 1.31036f * 1.31036f, - 1.25264f * 1.25264f, 1.20648f * 1.20648f, 1.16203f * 1.16203f, - 1.12765f * 1.12765f, 1.09428f * 1.09428f, 1.0659f * 1.0659f, - 1.03826f * 1.03826f, 1.01895f * 1.01895f, 1 }; - - private static final float table2[] = { 1.33352f * 1.33352f, - 1.35879f * 1.35879f, 1.38454f * 1.38454f, 1.39497f * 1.39497f, - 1.40548f * 1.40548f, 1.3537f * 1.3537f, 1.30382f * 1.30382f, - 1.22321f * 1.22321f, 1.14758f * 1.14758f, 1 }; - - private static final float table3[] = { 2.35364f * 2.35364f, - 2.29259f * 2.29259f, 2.23313f * 2.23313f, 2.12675f * 2.12675f, - 2.02545f * 2.02545f, 1.87894f * 1.87894f, 1.74303f * 1.74303f, - 1.61695f * 1.61695f, 1.49999f * 1.49999f, 1.39148f * 1.39148f, - 1.29083f * 1.29083f, 1.19746f * 1.19746f, 1.11084f * 1.11084f, - 1.03826f * 1.03826f }; - - /** - * addition of simultaneous masking Naoki Shibata 2000/7 - */ - private float mask_add(float m1, float m2, final int kk, final int b, - final LameInternalFlags gfc, final int shortblock) { - float ratio; - - if (m2 > m1) { - if (m2 < (m1 * ma_max_i2)) - ratio = m2 / m1; - else - return (m1 + m2); - } else { - if (m1 >= (m2 * ma_max_i2)) - return (m1 + m2); - ratio = m1 / m2; - } - - /* Should always be true, just checking */ - assert (m1 >= 0); - assert (m2 >= 0); - - m1 += m2; - if (((long) (b + 3) & 0xffffffffL) <= 3 + 3) { - /* approximately, 1 bark = 3 partitions */ - /* 65% of the cases */ - /* originally 'if(i > 8)' */ - if (ratio >= ma_max_i1) { - /* 43% of the total */ - return m1; - } - - /* 22% of the total */ - int i = (int) (Util.FAST_LOG10_X(ratio, 16.0f)); - return m1 * table2[i]; - } - - /** - * <PRE> - * m<15 equ log10((m1+m2)/gfc.ATH.cb[k])<1.5 - * equ (m1+m2)/gfc.ATH.cb[k]<10^1.5 - * equ (m1+m2)<10^1.5 * gfc.ATH.cb[k] - * </PRE> - */ - - int i = (int) Util.FAST_LOG10_X(ratio, 16.0f); - if (shortblock != 0) { - m2 = gfc.ATH.cb_s[kk] * gfc.ATH.adjust; - } else { - m2 = gfc.ATH.cb_l[kk] * gfc.ATH.adjust; - } - assert (m2 >= 0); - if (m1 < ma_max_m * m2) { - /* 3% of the total */ - /* Originally if (m > 0) { */ - if (m1 > m2) { - float f, r; - - f = 1.0f; - if (i <= 13) - f = table3[i]; - - r = Util.FAST_LOG10_X(m1 / m2, 10.0f / 15.0f); - return m1 * ((table1[i] - f) * r + f); - } - - if (i > 13) - return m1; - - return m1 * table3[i]; - } - - /* 10% of total */ - return m1 * table1[i]; - } - - private static final float table2_[] = { 1.33352f * 1.33352f, - 1.35879f * 1.35879f, 1.38454f * 1.38454f, 1.39497f * 1.39497f, - 1.40548f * 1.40548f, 1.3537f * 1.3537f, 1.30382f * 1.30382f, - 1.22321f * 1.22321f, 1.14758f * 1.14758f, 1 }; - - /** - * addition of simultaneous masking Naoki Shibata 2000/7 - */ - private float vbrpsy_mask_add(float m1, float m2, final int b) { - float ratio; - - if (m1 < 0) { - m1 = 0; - } - if (m2 < 0) { - m2 = 0; - } - if (m1 <= 0) { - return m2; - } - if (m2 <= 0) { - return m1; - } - if (m2 > m1) { - ratio = m2 / m1; - } else { - ratio = m1 / m2; - } - if (-2 <= b && b <= 2) { - /* approximately, 1 bark = 3 partitions */ - /* originally 'if(i > 8)' */ - if (ratio >= ma_max_i1) { - return m1 + m2; - } else { - int i = (int) (Util.FAST_LOG10_X(ratio, 16.0f)); - return (m1 + m2) * table2_[i]; - } - } - if (ratio < ma_max_i2) { - return m1 + m2; - } - if (m1 < m2) { - m1 = m2; - } - return m1; - } - - /** - * compute interchannel masking effects - */ - private void calc_interchannel_masking(final LameGlobalFlags gfp, - final float ratio) { - final LameInternalFlags gfc = gfp.internal_flags; - if (gfc.channels_out > 1) { - for (int sb = 0; sb < Encoder.SBMAX_l; sb++) { - float l = gfc.thm[0].l[sb]; - float r = gfc.thm[1].l[sb]; - gfc.thm[0].l[sb] += r * ratio; - gfc.thm[1].l[sb] += l * ratio; - } - for (int sb = 0; sb < Encoder.SBMAX_s; sb++) { - for (int sblock = 0; sblock < 3; sblock++) { - float l = gfc.thm[0].s[sb][sblock]; - float r = gfc.thm[1].s[sb][sblock]; - gfc.thm[0].s[sb][sblock] += r * ratio; - gfc.thm[1].s[sb][sblock] += l * ratio; - } - } - } - } - - /** - * compute M/S thresholds from Johnston & Ferreira 1992 ICASSP paper - */ - private void msfix1(final LameInternalFlags gfc) { - for (int sb = 0; sb < Encoder.SBMAX_l; sb++) { - /* use this fix if L & R masking differs by 2db or less */ - /* if db = 10*log10(x2/x1) < 2 */ - /* if (x2 < 1.58*x1) { */ - if (gfc.thm[0].l[sb] > 1.58 * gfc.thm[1].l[sb] - || gfc.thm[1].l[sb] > 1.58 * gfc.thm[0].l[sb]) - continue; - - float mld = gfc.mld_l[sb] * gfc.en[3].l[sb]; - float rmid = Math.max(gfc.thm[2].l[sb], - Math.min(gfc.thm[3].l[sb], mld)); - - mld = gfc.mld_l[sb] * gfc.en[2].l[sb]; - float rside = Math.max(gfc.thm[3].l[sb], - Math.min(gfc.thm[2].l[sb], mld)); - gfc.thm[2].l[sb] = rmid; - gfc.thm[3].l[sb] = rside; - } - - for (int sb = 0; sb < Encoder.SBMAX_s; sb++) { - for (int sblock = 0; sblock < 3; sblock++) { - if (gfc.thm[0].s[sb][sblock] > 1.58 * gfc.thm[1].s[sb][sblock] - || gfc.thm[1].s[sb][sblock] > 1.58 * gfc.thm[0].s[sb][sblock]) - continue; - - float mld = gfc.mld_s[sb] * gfc.en[3].s[sb][sblock]; - float rmid = Math.max(gfc.thm[2].s[sb][sblock], - Math.min(gfc.thm[3].s[sb][sblock], mld)); - - mld = gfc.mld_s[sb] * gfc.en[2].s[sb][sblock]; - float rside = Math.max(gfc.thm[3].s[sb][sblock], - Math.min(gfc.thm[2].s[sb][sblock], mld)); - - gfc.thm[2].s[sb][sblock] = rmid; - gfc.thm[3].s[sb][sblock] = rside; - } - } - } - - /** - * Adjust M/S maskings if user set "msfix" - * - * Naoki Shibata 2000 - */ - private void ns_msfix(final LameInternalFlags gfc, float msfix, - final float athadjust) { - float msfix2 = msfix; - float athlower = (float) Math.pow(10, athadjust); - - msfix *= 2.0f; - msfix2 *= 2.0f; - for (int sb = 0; sb < Encoder.SBMAX_l; sb++) { - float thmLR, thmM, thmS, ath; - ath = (gfc.ATH.cb_l[gfc.bm_l[sb]]) * athlower; - thmLR = Math.min(Math.max(gfc.thm[0].l[sb], ath), - Math.max(gfc.thm[1].l[sb], ath)); - thmM = Math.max(gfc.thm[2].l[sb], ath); - thmS = Math.max(gfc.thm[3].l[sb], ath); - if (thmLR * msfix < thmM + thmS) { - float f = thmLR * msfix2 / (thmM + thmS); - thmM *= f; - thmS *= f; - assert (thmM + thmS > 0); - } - gfc.thm[2].l[sb] = Math.min(thmM, gfc.thm[2].l[sb]); - gfc.thm[3].l[sb] = Math.min(thmS, gfc.thm[3].l[sb]); - } - - athlower *= ((float) Encoder.BLKSIZE_s / Encoder.BLKSIZE); - for (int sb = 0; sb < Encoder.SBMAX_s; sb++) { - for (int sblock = 0; sblock < 3; sblock++) { - float thmLR, thmM, thmS, ath; - ath = (gfc.ATH.cb_s[gfc.bm_s[sb]]) * athlower; - thmLR = Math.min(Math.max(gfc.thm[0].s[sb][sblock], ath), - Math.max(gfc.thm[1].s[sb][sblock], ath)); - thmM = Math.max(gfc.thm[2].s[sb][sblock], ath); - thmS = Math.max(gfc.thm[3].s[sb][sblock], ath); - - if (thmLR * msfix < thmM + thmS) { - float f = thmLR * msfix / (thmM + thmS); - thmM *= f; - thmS *= f; - assert (thmM + thmS > 0); - } - gfc.thm[2].s[sb][sblock] = Math.min(gfc.thm[2].s[sb][sblock], - thmM); - gfc.thm[3].s[sb][sblock] = Math.min(gfc.thm[3].s[sb][sblock], - thmS); - } - } - } - - /** - * short block threshold calculation (part 2) - * - * partition band bo_s[sfb] is at the transition from scalefactor band sfb - * to the next one sfb+1; enn and thmm have to be split between them - */ - private void convert_partition2scalefac_s(final LameInternalFlags gfc, - final float[] eb, final float[] thr, final int chn, final int sblock) { - int sb, b; - float enn = 0.0f; - float thmm = 0.0f; - for (sb = b = 0; sb < Encoder.SBMAX_s; ++b, ++sb) { - int bo_s_sb = gfc.bo_s[sb]; - int npart_s = gfc.npart_s; - int b_lim = bo_s_sb < npart_s ? bo_s_sb : npart_s; - while (b < b_lim) { - assert (eb[b] >= 0); - // iff failed, it may indicate some index error elsewhere - assert (thr[b] >= 0); - enn += eb[b]; - thmm += thr[b]; - b++; - } - gfc.en[chn].s[sb][sblock] = enn; - gfc.thm[chn].s[sb][sblock] = thmm; - - if (b >= npart_s) { - ++sb; - break; - } - assert (eb[b] >= 0); - // iff failed, it may indicate some index error elsewhere - assert (thr[b] >= 0); - { - /* at transition sfb . sfb+1 */ - float w_curr = gfc.PSY.bo_s_weight[sb]; - float w_next = 1.0f - w_curr; - enn = w_curr * eb[b]; - thmm = w_curr * thr[b]; - gfc.en[chn].s[sb][sblock] += enn; - gfc.thm[chn].s[sb][sblock] += thmm; - enn = w_next * eb[b]; - thmm = w_next * thr[b]; - } - } - /* zero initialize the rest */ - for (; sb < Encoder.SBMAX_s; ++sb) { - gfc.en[chn].s[sb][sblock] = 0; - gfc.thm[chn].s[sb][sblock] = 0; - } - } - - /** - * longblock threshold calculation (part 2) - */ - private void convert_partition2scalefac_l(final LameInternalFlags gfc, - final float[] eb, final float[] thr, final int chn) { - int sb, b; - float enn = 0.0f; - float thmm = 0.0f; - for (sb = b = 0; sb < Encoder.SBMAX_l; ++b, ++sb) { - int bo_l_sb = gfc.bo_l[sb]; - int npart_l = gfc.npart_l; - int b_lim = bo_l_sb < npart_l ? bo_l_sb : npart_l; - while (b < b_lim) { - assert (eb[b] >= 0); - // iff failed, it may indicate some index error elsewhere - assert (thr[b] >= 0); - enn += eb[b]; - thmm += thr[b]; - b++; - } - gfc.en[chn].l[sb] = enn; - gfc.thm[chn].l[sb] = thmm; - - if (b >= npart_l) { - ++sb; - break; - } - assert (eb[b] >= 0); - assert (thr[b] >= 0); - { - /* at transition sfb . sfb+1 */ - float w_curr = gfc.PSY.bo_l_weight[sb]; - float w_next = 1.0f - w_curr; - enn = w_curr * eb[b]; - thmm = w_curr * thr[b]; - gfc.en[chn].l[sb] += enn; - gfc.thm[chn].l[sb] += thmm; - enn = w_next * eb[b]; - thmm = w_next * thr[b]; - } - } - /* zero initialize the rest */ - for (; sb < Encoder.SBMAX_l; ++sb) { - gfc.en[chn].l[sb] = 0; - gfc.thm[chn].l[sb] = 0; - } - } - - private void compute_masking_s(final LameGlobalFlags gfp, - final float fftenergy_s[][], final float[] eb, final float[] thr, - final int chn, final int sblock) { - final LameInternalFlags gfc = gfp.internal_flags; - int j, b; - - for (b = j = 0; b < gfc.npart_s; ++b) { - float ebb = 0, m = 0; - int n = gfc.numlines_s[b]; - for (int i = 0; i < n; ++i, ++j) { - float el = fftenergy_s[sblock][j]; - ebb += el; - if (m < el) - m = el; - } - eb[b] = ebb; - } - assert (b == gfc.npart_s); - assert (j == 129); - for (j = b = 0; b < gfc.npart_s; b++) { - int kk = gfc.s3ind_s[b][0]; - float ecb = gfc.s3_ss[j++] * eb[kk]; - ++kk; - while (kk <= gfc.s3ind_s[b][1]) { - ecb += gfc.s3_ss[j] * eb[kk]; - ++j; - ++kk; - } - - { /* limit calculated threshold by previous granule */ - float x = rpelev_s * gfc.nb_s1[chn][b]; - thr[b] = Math.min(ecb, x); - } - if (gfc.blocktype_old[chn & 1] == Encoder.SHORT_TYPE) { - /* limit calculated threshold by even older granule */ - float x = rpelev2_s * gfc.nb_s2[chn][b]; - float y = thr[b]; - thr[b] = Math.min(x, y); - } - - gfc.nb_s2[chn][b] = gfc.nb_s1[chn][b]; - gfc.nb_s1[chn][b] = ecb; - assert (thr[b] >= 0); - } - for (; b <= Encoder.CBANDS; ++b) { - eb[b] = 0; - thr[b] = 0; - } - } - - private void block_type_set(final LameGlobalFlags gfp, - final int[] uselongblock, final int[] blocktype_d, - final int[] blocktype) { - final LameInternalFlags gfc = gfp.internal_flags; - - if (gfp.short_blocks == ShortBlock.short_block_coupled - /* force both channels to use the same block type */ - /* this is necessary if the frame is to be encoded in ms_stereo. */ - /* But even without ms_stereo, FhG does this */ - && !(uselongblock[0] != 0 && uselongblock[1] != 0)) - uselongblock[0] = uselongblock[1] = 0; - - /* - * update the blocktype of the previous granule, since it depends on - * what happend in this granule - */ - for (int chn = 0; chn < gfc.channels_out; chn++) { - blocktype[chn] = Encoder.NORM_TYPE; - /* disable short blocks */ - if (gfp.short_blocks == ShortBlock.short_block_dispensed) - uselongblock[chn] = 1; - if (gfp.short_blocks == ShortBlock.short_block_forced) - uselongblock[chn] = 0; - - if (uselongblock[chn] != 0) { - /* no attack : use long blocks */ - assert (gfc.blocktype_old[chn] != Encoder.START_TYPE); - if (gfc.blocktype_old[chn] == Encoder.SHORT_TYPE) - blocktype[chn] = Encoder.STOP_TYPE; - } else { - /* attack : use short blocks */ - blocktype[chn] = Encoder.SHORT_TYPE; - if (gfc.blocktype_old[chn] == Encoder.NORM_TYPE) { - gfc.blocktype_old[chn] = Encoder.START_TYPE; - } - if (gfc.blocktype_old[chn] == Encoder.STOP_TYPE) - gfc.blocktype_old[chn] = Encoder.SHORT_TYPE; - } - - blocktype_d[chn] = gfc.blocktype_old[chn]; - // value returned to calling program - gfc.blocktype_old[chn] = blocktype[chn]; - // save for next call to l3psy_anal - } - } - - private float NS_INTERP(final float x, final float y, final float r) { - /* was pow((x),(r))*pow((y),1-(r)) */ - if (r >= 1.0) { - /* 99.7% of the time */ - return x; - } - if (r <= 0.0) - return y; - if (y > 0.0) { - /* rest of the time */ - return (float) (Math.pow(x / y, r) * y); - } - /* never happens */ - return 0.0f; - } - - /** - * these values are tuned only for 44.1kHz... - */ - private static final float regcoef_s[] = { 11.8f, 13.6f, 17.2f, 32f, 46.5f, - 51.3f, 57.5f, 67.1f, 71.5f, 84.6f, 97.6f, 130f, - /* 255.8 */ - }; - - private float pecalc_s(final III_psy_ratio mr, - final float masking_lower) { - float pe_s = 1236.28f / 4; - for (int sb = 0; sb < Encoder.SBMAX_s - 1; sb++) { - for (int sblock = 0; sblock < 3; sblock++) { - float thm = mr.thm.s[sb][sblock]; - assert (sb < regcoef_s.length); - if (thm > 0.0) { - float x = thm * masking_lower; - float en = mr.en.s[sb][sblock]; - if (en > x) { - if (en > x * 1e10) { - pe_s += regcoef_s[sb] * (10.0f * LOG10); - } else { - assert (x > 0); - pe_s += regcoef_s[sb] * Util.FAST_LOG10(en / x); - } - } - } - } - } - - return pe_s; - } - - /** - * these values are tuned only for 44.1kHz... - */ - private static final float regcoef_l[] = { 6.8f, 5.8f, 5.8f, 6.4f, 6.5f, 9.9f, - 12.1f, 14.4f, 15f, 18.9f, 21.6f, 26.9f, 34.2f, 40.2f, 46.8f, 56.5f, - 60.7f, 73.9f, 85.7f, 93.4f, 126.1f, - /* 241.3 */ - }; - - private float pecalc_l(final III_psy_ratio mr, - final float masking_lower) { - float pe_l = 1124.23f / 4; - for (int sb = 0; sb < Encoder.SBMAX_l - 1; sb++) { - float thm = mr.thm.l[sb]; - assert (sb < regcoef_l.length); - if (thm > 0.0) { - float x = thm * masking_lower; - float en = mr.en.l[sb]; - if (en > x) { - if (en > x * 1e10) { - pe_l += regcoef_l[sb] * (10.0f * LOG10); - } else { - assert (x > 0); - pe_l += regcoef_l[sb] * Util.FAST_LOG10(en / x); - } - } - } - } - return pe_l; - } - - private void calc_energy(final LameInternalFlags gfc, - final float[] fftenergy, final float[] eb, final float[] max, - final float[] avg) { - int b, j; - - for (b = j = 0; b < gfc.npart_l; ++b) { - float ebb = 0, m = 0; - int i; - for (i = 0; i < gfc.numlines_l[b]; ++i, ++j) { - float el = fftenergy[j]; - assert (el >= 0); - ebb += el; - if (m < el) - m = el; - } - eb[b] = ebb; - max[b] = m; - avg[b] = ebb * gfc.rnumlines_l[b]; - assert (gfc.rnumlines_l[b] >= 0); - assert (ebb >= 0); - assert (eb[b] >= 0); - assert (max[b] >= 0); - assert (avg[b] >= 0); - } - } - - private void calc_mask_index_l(final LameInternalFlags gfc, - final float[] max, final float[] avg, final int[] mask_idx) { - int last_tab_entry = tab.length - 1; - int b = 0; - float a = avg[b] + avg[b + 1]; - assert (a >= 0); - if (a > 0.0) { - float m = max[b]; - if (m < max[b + 1]) - m = max[b + 1]; - assert ((gfc.numlines_l[b] + gfc.numlines_l[b + 1] - 1) > 0); - a = 20.0f * (m * 2.0f - a) - / (a * (gfc.numlines_l[b] + gfc.numlines_l[b + 1] - 1)); - int k = (int) a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - - for (b = 1; b < gfc.npart_l - 1; b++) { - a = avg[b - 1] + avg[b] + avg[b + 1]; - assert (a >= 0); - if (a > 0.0) { - float m = max[b - 1]; - if (m < max[b]) - m = max[b]; - if (m < max[b + 1]) - m = max[b + 1]; - assert ((gfc.numlines_l[b - 1] + gfc.numlines_l[b] - + gfc.numlines_l[b + 1] - 1) > 0); - a = 20.0f - * (m * 3.0f - a) - / (a * (gfc.numlines_l[b - 1] + gfc.numlines_l[b] - + gfc.numlines_l[b + 1] - 1)); - int k = (int) a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - } - assert (b > 0); - assert (b == gfc.npart_l - 1); - - a = avg[b - 1] + avg[b]; - assert (a >= 0); - if (a > 0.0) { - float m = max[b - 1]; - if (m < max[b]) - m = max[b]; - assert ((gfc.numlines_l[b - 1] + gfc.numlines_l[b] - 1) > 0); - a = 20.0f * (m * 2.0f - a) - / (a * (gfc.numlines_l[b - 1] + gfc.numlines_l[b] - 1)); - int k = (int) a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - assert (b == (gfc.npart_l - 1)); - } - - private static final float fircoef[] = { - -8.65163e-18f * 2, -0.00851586f * 2, -6.74764e-18f * 2, 0.0209036f * 2, - -3.36639e-17f * 2, -0.0438162f * 2, -1.54175e-17f * 2, 0.0931738f * 2, - -5.52212e-17f * 2, -0.313819f * 2 - }; - - public final int L3psycho_anal_ns(final LameGlobalFlags gfp, - final float[] buffer[], final int bufPos, final int gr_out, - final III_psy_ratio masking_ratio[][], - final III_psy_ratio masking_MS_ratio[][], - final float percep_entropy[], final float percep_MS_entropy[], - final float energy[], final int blocktype_d[]) { - /* - * to get a good cache performance, one has to think about the sequence, - * in which the variables are used. - */ - final LameInternalFlags gfc = gfp.internal_flags; - - /* fft and energy calculation */ - float wsamp_L[][] = new float[2][Encoder.BLKSIZE]; - float wsamp_S[][][] = new float[2][3][Encoder.BLKSIZE_s]; - - /* convolution */ - float eb_l[] = new float[Encoder.CBANDS + 1], eb_s[] = new float[Encoder.CBANDS + 1]; - float thr[] = new float[Encoder.CBANDS + 2]; - - /* block type */ - int blocktype[] = new int[2], uselongblock[] = new int[2]; - - /* usual variables like loop indices, etc.. */ - int numchn, chn; - int b, i, j, k; - int sb, sblock; - - /* variables used for --nspsytune */ - float ns_hpfsmpl[][] = new float[2][576]; - float pcfact; - - int mask_idx_l[] = new int[Encoder.CBANDS + 2], mask_idx_s[] = new int[Encoder.CBANDS + 2]; - - Arrays.fill(mask_idx_s, 0); - - numchn = gfc.channels_out; - /* chn=2 and 3 = Mid and Side channels */ - if (gfp.mode == MPEGMode.JOINT_STEREO) - numchn = 4; - - if (gfp.VBR == VbrMode.vbr_off) - pcfact = gfc.ResvMax == 0 ? 0f : ((float) gfc.ResvSize) - / gfc.ResvMax * 0.5f; - else if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh - || gfp.VBR == VbrMode.vbr_mt) { - pcfact = 0.6f; - } else - pcfact = 1.0f; - - /********************************************************************** - * Apply HPF of fs/4 to the input signal. This is used for attack - * detection / handling. - **********************************************************************/ - /* Don't copy the input buffer into a temporary buffer */ - /* unroll the loop 2 times */ - for (chn = 0; chn < gfc.channels_out; chn++) { - /* apply high pass filter of fs/4 */ - final float[] firbuf = buffer[chn]; - int firbufPos = bufPos + 576 - 350 - NSFIRLEN + 192; - assert (fircoef.length == ((NSFIRLEN - 1) / 2)); - for (i = 0; i < 576; i++) { - float sum1, sum2; - sum1 = firbuf[firbufPos + i + 10]; - sum2 = 0.0f; - for (j = 0; j < ((NSFIRLEN - 1) / 2) - 1; j += 2) { - sum1 += fircoef[j] - * (firbuf[firbufPos + i + j] + firbuf[firbufPos + i - + NSFIRLEN - j]); - sum2 += fircoef[j + 1] - * (firbuf[firbufPos + i + j + 1] + firbuf[firbufPos - + i + NSFIRLEN - j - 1]); - } - ns_hpfsmpl[chn][i] = sum1 + sum2; - } - masking_ratio[gr_out][chn].en.assign(gfc.en[chn]); - masking_ratio[gr_out][chn].thm.assign(gfc.thm[chn]); - if (numchn > 2) { - /* MS maskings */ - /* percep_MS_entropy [chn-2] = gfc . pe [chn]; */ - masking_MS_ratio[gr_out][chn].en.assign(gfc.en[chn + 2]); - masking_MS_ratio[gr_out][chn].thm.assign(gfc.thm[chn + 2]); - } - } - - for (chn = 0; chn < numchn; chn++) { - float wsamp_l[][]; - float wsamp_s[][][]; - float en_subshort[] = new float[12]; - float en_short[] = { 0, 0, 0, 0 }; - float attack_intensity[] = new float[12]; - int ns_uselongblock = 1; - float attackThreshold; - float max[] = new float[Encoder.CBANDS], avg[] = new float[Encoder.CBANDS]; - int ns_attacks[] = { 0, 0, 0, 0 }; - float fftenergy[] = new float[Encoder.HBLKSIZE]; - float fftenergy_s[][] = new float[3][Encoder.HBLKSIZE_s]; - - /* - * rh 20040301: the following loops do access one off the limits so - * I increase the array dimensions by one and initialize the - * accessed values to zero - */ - assert (gfc.npart_s <= Encoder.CBANDS); - assert (gfc.npart_l <= Encoder.CBANDS); - - /*************************************************************** - * determine the block type (window type) - ***************************************************************/ - /* calculate energies of each sub-shortblocks */ - for (i = 0; i < 3; i++) { - en_subshort[i] = gfc.nsPsy.last_en_subshort[chn][i + 6]; - assert (gfc.nsPsy.last_en_subshort[chn][i + 4] > 0); - attack_intensity[i] = en_subshort[i] - / gfc.nsPsy.last_en_subshort[chn][i + 4]; - en_short[0] += en_subshort[i]; - } - - if (chn == 2) { - for (i = 0; i < 576; i++) { - float l, r; - l = ns_hpfsmpl[0][i]; - r = ns_hpfsmpl[1][i]; - ns_hpfsmpl[0][i] = l + r; - ns_hpfsmpl[1][i] = l - r; - } - } - { - float[] pf = ns_hpfsmpl[chn & 1]; - int pfPos = 0; - for (i = 0; i < 9; i++) { - int pfe = pfPos + 576 / 9; - float p = 1.f; - for (; pfPos < pfe; pfPos++) - if (p < Math.abs(pf[pfPos])) - p = Math.abs(pf[pfPos]); - - gfc.nsPsy.last_en_subshort[chn][i] = en_subshort[i + 3] = p; - en_short[1 + i / 3] += p; - if (p > en_subshort[i + 3 - 2]) { - assert (en_subshort[i + 3 - 2] > 0); - p = p / en_subshort[i + 3 - 2]; - } else if (en_subshort[i + 3 - 2] > p * 10.0f) { - assert (p > 0); - p = en_subshort[i + 3 - 2] / (p * 10.0f); - } else - p = 0.0f; - attack_intensity[i + 3] = p; - } - } - - if (gfp.analysis) { - float x = attack_intensity[0]; - for (i = 1; i < 12; i++) - if (x < attack_intensity[i]) - x = attack_intensity[i]; - gfc.pinfo.ers[gr_out][chn] = gfc.pinfo.ers_save[chn]; - gfc.pinfo.ers_save[chn] = x; - } - - /* compare energies between sub-shortblocks */ - attackThreshold = (chn == 3) ? gfc.nsPsy.attackthre_s - : gfc.nsPsy.attackthre; - for (i = 0; i < 12; i++) - if (0 == ns_attacks[i / 3] - && attack_intensity[i] > attackThreshold) - ns_attacks[i / 3] = (i % 3) + 1; - - /* - * should have energy change between short blocks, in order to avoid - * periodic signals - */ - for (i = 1; i < 4; i++) { - float ratio; - if (en_short[i - 1] > en_short[i]) { - assert (en_short[i] > 0); - ratio = en_short[i - 1] / en_short[i]; - } else { - assert (en_short[i - 1] > 0); - ratio = en_short[i] / en_short[i - 1]; - } - if (ratio < 1.7) { - ns_attacks[i] = 0; - if (i == 1) - ns_attacks[0] = 0; - } - } - - if (ns_attacks[0] != 0 && gfc.nsPsy.lastAttacks[chn] != 0) - ns_attacks[0] = 0; - - if (gfc.nsPsy.lastAttacks[chn] == 3 - || (ns_attacks[0] + ns_attacks[1] + ns_attacks[2] + ns_attacks[3]) != 0) { - ns_uselongblock = 0; - - if (ns_attacks[1] != 0 && ns_attacks[0] != 0) - ns_attacks[1] = 0; - if (ns_attacks[2] != 0 && ns_attacks[1] != 0) - ns_attacks[2] = 0; - if (ns_attacks[3] != 0 && ns_attacks[2] != 0) - ns_attacks[3] = 0; - } - - if (chn < 2) { - uselongblock[chn] = ns_uselongblock; - } else { - if (ns_uselongblock == 0) { - uselongblock[0] = uselongblock[1] = 0; - } - } - - /* - * there is a one granule delay. Copy maskings computed last call - * into masking_ratio to return to calling program. - */ - energy[chn] = gfc.tot_ener[chn]; - - /********************************************************************* - * compute FFTs - *********************************************************************/ - wsamp_s = wsamp_S; - wsamp_l = wsamp_L; - compute_ffts(gfp, fftenergy, fftenergy_s, wsamp_l, (chn & 1), - wsamp_s, (chn & 1), gr_out, chn, buffer, bufPos); - - /********************************************************************* - * Calculate the energy and the tonality of each partition. - *********************************************************************/ - calc_energy(gfc, fftenergy, eb_l, max, avg); - calc_mask_index_l(gfc, max, avg, mask_idx_l); - /* compute masking thresholds for short blocks */ - for (sblock = 0; sblock < 3; sblock++) { - float enn, thmm; - compute_masking_s(gfp, fftenergy_s, eb_s, thr, chn, sblock); - convert_partition2scalefac_s(gfc, eb_s, thr, chn, sblock); - /**** short block pre-echo control ****/ - for (sb = 0; sb < Encoder.SBMAX_s; sb++) { - thmm = gfc.thm[chn].s[sb][sblock]; - - thmm *= NS_PREECHO_ATT0; - if (ns_attacks[sblock] >= 2 || ns_attacks[sblock + 1] == 1) { - int idx = (sblock != 0) ? sblock - 1 : 2; - double p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT1 * pcfact); - thmm = (float) Math.min(thmm, p); - } - - if (ns_attacks[sblock] == 1) { - int idx = (sblock != 0) ? sblock - 1 : 2; - double p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT2 * pcfact); - thmm = (float) Math.min(thmm, p); - } else if ((sblock != 0 && ns_attacks[sblock - 1] == 3) - || (sblock == 0 && gfc.nsPsy.lastAttacks[chn] == 3)) { - int idx = (sblock != 2) ? sblock + 1 : 0; - double p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT2 * pcfact); - thmm = (float) Math.min(thmm, p); - } - - /* pulse like signal detection for fatboy.wav and so on */ - enn = en_subshort[sblock * 3 + 3] - + en_subshort[sblock * 3 + 4] - + en_subshort[sblock * 3 + 5]; - if (en_subshort[sblock * 3 + 5] * 6 < enn) { - thmm *= 0.5; - if (en_subshort[sblock * 3 + 4] * 6 < enn) - thmm *= 0.5; - } - - gfc.thm[chn].s[sb][sblock] = thmm; - } - } - gfc.nsPsy.lastAttacks[chn] = ns_attacks[2]; - - /********************************************************************* - * convolve the partitioned energy and unpredictability with the - * spreading function, s3_l[b][k] - ********************************************************************/ - k = 0; - { - for (b = 0; b < gfc.npart_l; b++) { - /* - * convolve the partitioned energy with the spreading - * function - */ - int kk = gfc.s3ind[b][0]; - float eb2 = eb_l[kk] * tab[mask_idx_l[kk]]; - float ecb = gfc.s3_ll[k++] * eb2; - while (++kk <= gfc.s3ind[b][1]) { - eb2 = eb_l[kk] * tab[mask_idx_l[kk]]; - ecb = mask_add(ecb, gfc.s3_ll[k++] * eb2, kk, kk - b, - gfc, 0); - } - ecb *= 0.158489319246111; /* pow(10,-0.8) */ - - /**** long block pre-echo control ****/ - /** - * <PRE> - * dont use long block pre-echo control if previous granule was - * a short block. This is to avoid the situation: - * frame0: quiet (very low masking) - * frame1: surge (triggers short blocks) - * frame2: regular frame. looks like pre-echo when compared to - * frame0, but all pre-echo was in frame1. - * </PRE> - */ - /* - * chn=0,1 L and R channels - * - * chn=2,3 S and M channels. - */ - - if (gfc.blocktype_old[chn & 1] == Encoder.SHORT_TYPE) - thr[b] = ecb; - else - thr[b] = NS_INTERP( - Math.min(ecb, Math.min(rpelev - * gfc.nb_1[chn][b], rpelev2 - * gfc.nb_2[chn][b])), ecb, pcfact); - - gfc.nb_2[chn][b] = gfc.nb_1[chn][b]; - gfc.nb_1[chn][b] = ecb; - } - } - for (; b <= Encoder.CBANDS; ++b) { - eb_l[b] = 0; - thr[b] = 0; - } - /* compute masking thresholds for long blocks */ - convert_partition2scalefac_l(gfc, eb_l, thr, chn); - } /* end loop over chn */ - - if (gfp.mode == MPEGMode.STEREO || gfp.mode == MPEGMode.JOINT_STEREO) { - if (gfp.interChRatio > 0.0) { - calc_interchannel_masking(gfp, gfp.interChRatio); - } - } - - if (gfp.mode == MPEGMode.JOINT_STEREO) { - float msfix; - msfix1(gfc); - msfix = gfp.msfix; - if (Math.abs(msfix) > 0.0) - ns_msfix(gfc, msfix, gfp.ATHlower * gfc.ATH.adjust); - } - - /*************************************************************** - * determine final block type - ***************************************************************/ - block_type_set(gfp, uselongblock, blocktype_d, blocktype); - - /********************************************************************* - * compute the value of PE to return ... no delay and advance - *********************************************************************/ - for (chn = 0; chn < numchn; chn++) { - float[] ppe; - int ppePos = 0; - int type; - III_psy_ratio mr; - - if (chn > 1) { - ppe = percep_MS_entropy; - ppePos = -2; - type = Encoder.NORM_TYPE; - if (blocktype_d[0] == Encoder.SHORT_TYPE - || blocktype_d[1] == Encoder.SHORT_TYPE) - type = Encoder.SHORT_TYPE; - mr = masking_MS_ratio[gr_out][chn - 2]; - } else { - ppe = percep_entropy; - ppePos = 0; - type = blocktype_d[chn]; - mr = masking_ratio[gr_out][chn]; - } - - if (type == Encoder.SHORT_TYPE) - ppe[ppePos + chn] = pecalc_s(mr, gfc.masking_lower); - else - ppe[ppePos + chn] = pecalc_l(mr, gfc.masking_lower); - - if (gfp.analysis) - gfc.pinfo.pe[gr_out][chn] = ppe[ppePos + chn]; - - } - return 0; - } - - private void vbrpsy_compute_fft_l(final LameGlobalFlags gfp, - final float[] buffer[], final int bufPos, final int chn, - final int gr_out, final float fftenergy[], final float wsamp_l[][], - final int wsamp_lPos) { - final LameInternalFlags gfc = gfp.internal_flags; - if (chn < 2) { - fft.fft_long(gfc, wsamp_l[wsamp_lPos], chn, buffer, bufPos); - } else if (chn == 2) { - /* FFT data for mid and side channel is derived from L & R */ - for (int j = Encoder.BLKSIZE - 1; j >= 0; --j) { - float l = wsamp_l[wsamp_lPos + 0][j]; - float r = wsamp_l[wsamp_lPos + 1][j]; - wsamp_l[wsamp_lPos + 0][j] = (l + r) * Util.SQRT2 * 0.5f; - wsamp_l[wsamp_lPos + 1][j] = (l - r) * Util.SQRT2 * 0.5f; - } - } - - /********************************************************************* - * compute energies - *********************************************************************/ - fftenergy[0] = NON_LINEAR_SCALE_ENERGY(wsamp_l[wsamp_lPos + 0][0]); - fftenergy[0] *= fftenergy[0]; - - for (int j = Encoder.BLKSIZE / 2 - 1; j >= 0; --j) { - float re = wsamp_l[wsamp_lPos + 0][Encoder.BLKSIZE / 2 - j]; - float im = wsamp_l[wsamp_lPos + 0][Encoder.BLKSIZE / 2 + j]; - fftenergy[Encoder.BLKSIZE / 2 - j] = NON_LINEAR_SCALE_ENERGY((re - * re + im * im) * 0.5f); - } - /* total energy */ - { - float totalenergy = 0.0f; - for (int j = 11; j < Encoder.HBLKSIZE; j++) - totalenergy += fftenergy[j]; - - gfc.tot_ener[chn] = totalenergy; - } - - if (gfp.analysis) { - for (int j = 0; j < Encoder.HBLKSIZE; j++) { - gfc.pinfo.energy[gr_out][chn][j] = gfc.pinfo.energy_save[chn][j]; - gfc.pinfo.energy_save[chn][j] = fftenergy[j]; - } - gfc.pinfo.pe[gr_out][chn] = gfc.pe[chn]; - } - } - - private void vbrpsy_compute_fft_s(final LameGlobalFlags gfp, - final float[] buffer[], final int bufPos, final int chn, - final int sblock, final float fftenergy_s[][], - final float wsamp_s[][][], int wsamp_sPos) { - final LameInternalFlags gfc = gfp.internal_flags; - - if (sblock == 0 && chn < 2) { - fft.fft_short(gfc, wsamp_s[wsamp_sPos], chn, buffer, bufPos); - } - if (chn == 2) { - /* FFT data for mid and side channel is derived from L & R */ - for (int j = Encoder.BLKSIZE_s - 1; j >= 0; --j) { - float l = wsamp_s[wsamp_sPos+0][sblock][j]; - float r = wsamp_s[wsamp_sPos+1][sblock][j]; - wsamp_s[wsamp_sPos+0][sblock][j] = (l + r) * Util.SQRT2 * 0.5f; - wsamp_s[wsamp_sPos+1][sblock][j] = (l - r) * Util.SQRT2 * 0.5f; - } - } - - /********************************************************************* - * compute energies - *********************************************************************/ - fftenergy_s[sblock][0] = wsamp_s[wsamp_sPos+0][sblock][0]; - fftenergy_s[sblock][0] *= fftenergy_s[sblock][0]; - for (int j = Encoder.BLKSIZE_s / 2 - 1; j >= 0; --j) { - float re = wsamp_s[wsamp_sPos+0][sblock][Encoder.BLKSIZE_s / 2 - j]; - float im = wsamp_s[wsamp_sPos+0][sblock][Encoder.BLKSIZE_s / 2 + j]; - fftenergy_s[sblock][Encoder.BLKSIZE_s / 2 - j] = NON_LINEAR_SCALE_ENERGY((re - * re + im * im) * 0.5f); - } - } - - /** - * compute loudness approximation (used for ATH auto-level adjustment) - */ - private void vbrpsy_compute_loudness_approximation_l(LameGlobalFlags gfp, - int gr_out, int chn, float fftenergy[]) { - final LameInternalFlags gfc = gfp.internal_flags; - if (gfp.athaa_loudapprox == 2 && chn < 2) { - // no loudness for mid/side ch - gfc.loudness_sq[gr_out][chn] = gfc.loudness_sq_save[chn]; - gfc.loudness_sq_save[chn] = psycho_loudness_approx(fftenergy, gfc); - } - } - - private static final float fircoef_[] = { -8.65163e-18f * 2, - -0.00851586f * 2, -6.74764e-18f * 2, 0.0209036f * 2, - -3.36639e-17f * 2, -0.0438162f * 2, -1.54175e-17f * 2, - 0.0931738f * 2, -5.52212e-17f * 2, -0.313819f * 2 }; - - /** - * Apply HPF of fs/4 to the input signal. This is used for attack detection - * / handling. - */ - private void vbrpsy_attack_detection(final LameGlobalFlags gfp, - final float[] buffer[], final int bufPos, final int gr_out, - final III_psy_ratio masking_ratio[][], - final III_psy_ratio masking_MS_ratio[][], - final float energy[], float sub_short_factor[][], - final int ns_attacks[][], final int uselongblock[]) { - float ns_hpfsmpl[][] = new float[2][576]; - final LameInternalFlags gfc = gfp.internal_flags; - int n_chn_out = gfc.channels_out; - /* chn=2 and 3 = Mid and Side channels */ - int n_chn_psy = (gfp.mode == MPEGMode.JOINT_STEREO) ? 4 : n_chn_out; - /* Don't copy the input buffer into a temporary buffer */ - /* unroll the loop 2 times */ - for (int chn = 0; chn < n_chn_out; chn++) { - /* apply high pass filter of fs/4 */ - final float[] firbuf = buffer[chn]; - int firbufPos = bufPos + 576 - 350 - NSFIRLEN + 192; - assert (fircoef_.length == ((NSFIRLEN - 1) / 2)); - for (int i = 0; i < 576; i++) { - float sum1, sum2; - sum1 = firbuf[firbufPos + i + 10]; - sum2 = 0.0f; - for (int j = 0; j < ((NSFIRLEN - 1) / 2) - 1; j += 2) { - sum1 += fircoef_[j] - * (firbuf[firbufPos + i + j] + firbuf[firbufPos + i - + NSFIRLEN - j]); - sum2 += fircoef_[j + 1] - * (firbuf[firbufPos + i + j + 1] + firbuf[firbufPos - + i + NSFIRLEN - j - 1]); - } - ns_hpfsmpl[chn][i] = sum1 + sum2; - } - masking_ratio[gr_out][chn].en.assign(gfc.en[chn]); - masking_ratio[gr_out][chn].thm.assign(gfc.thm[chn]); - if (n_chn_psy > 2) { - /* MS maskings */ - /* percep_MS_entropy [chn-2] = gfc . pe [chn]; */ - masking_MS_ratio[gr_out][chn].en.assign(gfc.en[chn + 2]); - masking_MS_ratio[gr_out][chn].thm.assign(gfc.thm[chn + 2]); - } - } - for (int chn = 0; chn < n_chn_psy; chn++) { - float attack_intensity[] = new float[12]; - float en_subshort[] = new float[12]; - float en_short[] = { 0, 0, 0, 0 }; - float[] pf = ns_hpfsmpl[chn & 1]; - int pfPos = 0; - final float attackThreshold = (chn == 3) ? gfc.nsPsy.attackthre_s - : gfc.nsPsy.attackthre; - int ns_uselongblock = 1; - - if (chn == 2) { - for (int i = 0, j = 576; j > 0; ++i, --j) { - final float l = ns_hpfsmpl[0][i]; - final float r = ns_hpfsmpl[1][i]; - ns_hpfsmpl[0][i] = l + r; - ns_hpfsmpl[1][i] = l - r; - } - } - /*************************************************************** - * determine the block type (window type) - ***************************************************************/ - /* calculate energies of each sub-shortblocks */ - for (int i = 0; i < 3; i++) { - en_subshort[i] = gfc.nsPsy.last_en_subshort[chn][i + 6]; - assert (gfc.nsPsy.last_en_subshort[chn][i + 4] > 0); - attack_intensity[i] = en_subshort[i] - / gfc.nsPsy.last_en_subshort[chn][i + 4]; - en_short[0] += en_subshort[i]; - } - - for (int i = 0; i < 9; i++) { - final int pfe = pfPos + 576 / 9; - float p = 1.f; - for (; pfPos < pfe; pfPos++) - if (p < Math.abs(pf[pfPos])) - p = Math.abs(pf[pfPos]); - - gfc.nsPsy.last_en_subshort[chn][i] = en_subshort[i + 3] = p; - en_short[1 + i / 3] += p; - if (p > en_subshort[i + 3 - 2]) { - assert (en_subshort[i + 3 - 2] > 0); - p = p / en_subshort[i + 3 - 2]; - } else if (en_subshort[i + 3 - 2] > p * 10.0) { - assert (p > 0); - p = en_subshort[i + 3 - 2] / (p * 10.0f); - } else { - p = 0.0f; - } - attack_intensity[i + 3] = p; - } - /* pulse like signal detection for fatboy.wav and so on */ - for (int i = 0; i < 3; ++i) { - final float enn = en_subshort[i * 3 + 3] - + en_subshort[i * 3 + 4] + en_subshort[i * 3 + 5]; - float factor = 1.f; - if (en_subshort[i * 3 + 5] * 6 < enn) { - factor *= 0.5f; - if (en_subshort[i * 3 + 4] * 6 < enn) { - factor *= 0.5f; - } - } - sub_short_factor[chn][i] = factor; - } - - if (gfp.analysis) { - float x = attack_intensity[0]; - for (int i = 1; i < 12; i++) { - if (x < attack_intensity[i]) { - x = attack_intensity[i]; - } - } - gfc.pinfo.ers[gr_out][chn] = gfc.pinfo.ers_save[chn]; - gfc.pinfo.ers_save[chn] = x; - } - - /* compare energies between sub-shortblocks */ - for (int i = 0; i < 12; i++) { - if (0 == ns_attacks[chn][i / 3] - && attack_intensity[i] > attackThreshold) { - ns_attacks[chn][i / 3] = (i % 3) + 1; - } - } - - /* - * should have energy change between short blocks, in order to avoid - * periodic signals - */ - /* Good samples to show the effect are Trumpet test songs */ - /* - * GB: tuned (1) to avoid too many short blocks for test sample - * TRUMPET - */ - /* - * RH: tuned (2) to let enough short blocks through for test sample - * FSOL and SNAPS - */ - for (int i = 1; i < 4; i++) { - final float u = en_short[i - 1]; - final float v = en_short[i]; - final float m = Math.max(u, v); - if (m < 40000) { /* (2) */ - if (u < 1.7 * v && v < 1.7 * u) { /* (1) */ - if (i == 1 && ns_attacks[chn][0] <= ns_attacks[chn][i]) { - ns_attacks[chn][0] = 0; - } - ns_attacks[chn][i] = 0; - } - } - } - - if (ns_attacks[chn][0] <= gfc.nsPsy.lastAttacks[chn]) { - ns_attacks[chn][0] = 0; - } - - if (gfc.nsPsy.lastAttacks[chn] == 3 - || (ns_attacks[chn][0] + ns_attacks[chn][1] - + ns_attacks[chn][2] + ns_attacks[chn][3]) != 0) { - ns_uselongblock = 0; - - if (ns_attacks[chn][1] != 0 && ns_attacks[chn][0] != 0) { - ns_attacks[chn][1] = 0; - } - if (ns_attacks[chn][2] != 0 && ns_attacks[chn][1] != 0) { - ns_attacks[chn][2] = 0; - } - if (ns_attacks[chn][3] != 0 && ns_attacks[chn][2] != 0) { - ns_attacks[chn][3] = 0; - } - } - if (chn < 2) { - uselongblock[chn] = ns_uselongblock; - } else { - if (ns_uselongblock == 0) { - uselongblock[0] = uselongblock[1] = 0; - } - } - - /* - * there is a one granule delay. Copy maskings computed last call - * into masking_ratio to return to calling program. - */ - energy[chn] = gfc.tot_ener[chn]; - } - } - - private void vbrpsy_skip_masking_s(final LameInternalFlags gfc, - final int chn, final int sblock) { - if (sblock == 0) { - for (int b = 0; b < gfc.npart_s; b++) { - gfc.nb_s2[chn][b] = gfc.nb_s1[chn][b]; - gfc.nb_s1[chn][b] = 0; - } - } - } - - private void vbrpsy_skip_masking_l(final LameInternalFlags gfc, - final int chn) { - for (int b = 0; b < gfc.npart_l; b++) { - gfc.nb_2[chn][b] = gfc.nb_1[chn][b]; - gfc.nb_1[chn][b] = 0; - } - } - - private void psyvbr_calc_mask_index_s(final LameInternalFlags gfc, - final float[] max, final float[] avg, final int[] mask_idx) { - int last_tab_entry = tab.length - 1; - int b = 0; - float a = avg[b] + avg[b + 1]; - assert (a >= 0); - if (a > 0.0) { - float m = max[b]; - if (m < max[b + 1]) - m = max[b + 1]; - assert ((gfc.numlines_s[b] + gfc.numlines_s[b + 1] - 1) > 0); - a = 20.0f * (m * 2.0f - a) - / (a * (gfc.numlines_s[b] + gfc.numlines_s[b + 1] - 1)); - int k = (int) a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - - for (b = 1; b < gfc.npart_s - 1; b++) { - a = avg[b - 1] + avg[b] + avg[b + 1]; - assert (b + 1 < gfc.npart_s); - assert (a >= 0); - if (a > 0.0) { - float m = max[b - 1]; - if (m < max[b]) - m = max[b]; - if (m < max[b + 1]) - m = max[b + 1]; - assert ((gfc.numlines_s[b - 1] + gfc.numlines_s[b] - + gfc.numlines_s[b + 1] - 1) > 0); - a = 20.0f - * (m * 3.0f - a) - / (a * (gfc.numlines_s[b - 1] + gfc.numlines_s[b] - + gfc.numlines_s[b + 1] - 1)); - int k = (int) a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - } - assert (b > 0); - assert (b == gfc.npart_s - 1); - - a = avg[b - 1] + avg[b]; - assert (a >= 0); - if (a > 0.0) { - float m = max[b - 1]; - if (m < max[b]) - m = max[b]; - assert ((gfc.numlines_s[b - 1] + gfc.numlines_s[b] - 1) > 0); - a = 20.0f * (m * 2.0f - a) - / (a * (gfc.numlines_s[b - 1] + gfc.numlines_s[b] - 1)); - int k = (int) a; - if (k > last_tab_entry) - k = last_tab_entry; - mask_idx[b] = k; - } else { - mask_idx[b] = 0; - } - assert (b == (gfc.npart_s - 1)); - } - - private void vbrpsy_compute_masking_s(final LameGlobalFlags gfp, - final float[] fftenergy_s[], final float[] eb, final float[] thr, - final int chn, final int sblock) { - final LameInternalFlags gfc = gfp.internal_flags; - float max[] = new float[Encoder.CBANDS], avg[] = new float[Encoder.CBANDS]; - int i, j, b; - int mask_idx_s[] = new int[Encoder.CBANDS]; - - for (b = j = 0; b < gfc.npart_s; ++b) { - float ebb = 0, m = 0; - int n = gfc.numlines_s[b]; - for (i = 0; i < n; ++i, ++j) { - float el = fftenergy_s[sblock][j]; - ebb += el; - if (m < el) - m = el; - } - eb[b] = ebb; - assert (ebb >= 0); - max[b] = m; - assert (n > 0); - avg[b] = ebb / n; - assert (avg[b] >= 0); - } - assert (b == gfc.npart_s); - assert (j == 129); - for (; b < Encoder.CBANDS; ++b) { - max[b] = 0; - avg[b] = 0; - } - psyvbr_calc_mask_index_s(gfc, max, avg, mask_idx_s); - for (j = b = 0; b < gfc.npart_s; b++) { - int kk = gfc.s3ind_s[b][0]; - int last = gfc.s3ind_s[b][1]; - int dd, dd_n; - float x, ecb, avg_mask; - dd = mask_idx_s[kk]; - dd_n = 1; - ecb = gfc.s3_ss[j] * eb[kk] * tab[mask_idx_s[kk]]; - ++j; - ++kk; - while (kk <= last) { - dd += mask_idx_s[kk]; - dd_n += 1; - x = gfc.s3_ss[j] * eb[kk] * tab[mask_idx_s[kk]]; - ecb = vbrpsy_mask_add(ecb, x, kk - b); - ++j; - ++kk; - } - dd = (1 + 2 * dd) / (2 * dd_n); - avg_mask = tab[dd] * 0.5f; - ecb *= avg_mask; - thr[b] = ecb; - gfc.nb_s2[chn][b] = gfc.nb_s1[chn][b]; - gfc.nb_s1[chn][b] = ecb; - { - /* - * if THR exceeds EB, the quantization routines will take the - * difference from other bands. in case of strong tonal samples - * (tonaltest.wav) this leads to heavy distortions. that's why - * we limit THR here. - */ - x = max[b]; - x *= gfc.minval_s[b]; - x *= avg_mask; - if (thr[b] > x) { - thr[b] = x; - } - } - if (gfc.masking_lower > 1) { - thr[b] *= gfc.masking_lower; - } - if (thr[b] > eb[b]) { - thr[b] = eb[b]; - } - if (gfc.masking_lower < 1) { - thr[b] *= gfc.masking_lower; - } - - assert (thr[b] >= 0); - } - for (; b < Encoder.CBANDS; ++b) { - eb[b] = 0; - thr[b] = 0; - } - } - - private void vbrpsy_compute_masking_l(final LameInternalFlags gfc, - final float fftenergy[], final float eb_l[], final float thr[], - final int chn) { - float max[] = new float[Encoder.CBANDS], avg[] = new float[Encoder.CBANDS]; - int mask_idx_l[] = new int[Encoder.CBANDS + 2]; - int b; - - /********************************************************************* - * Calculate the energy and the tonality of each partition. - *********************************************************************/ - calc_energy(gfc, fftenergy, eb_l, max, avg); - calc_mask_index_l(gfc, max, avg, mask_idx_l); - - /********************************************************************* - * convolve the partitioned energy and unpredictability with the - * spreading function, s3_l[b][k] - ********************************************************************/ - int k = 0; - for (b = 0; b < gfc.npart_l; b++) { - float x, ecb, avg_mask, t; - /* convolve the partitioned energy with the spreading function */ - int kk = gfc.s3ind[b][0]; - int last = gfc.s3ind[b][1]; - int dd = 0, dd_n = 0; - dd = mask_idx_l[kk]; - dd_n += 1; - ecb = gfc.s3_ll[k] * eb_l[kk] * tab[mask_idx_l[kk]]; - ++k; - ++kk; - while (kk <= last) { - dd += mask_idx_l[kk]; - dd_n += 1; - x = gfc.s3_ll[k] * eb_l[kk] * tab[mask_idx_l[kk]]; - t = vbrpsy_mask_add(ecb, x, kk - b); - ecb = t; - ++k; - ++kk; - } - dd = (1 + 2 * dd) / (2 * dd_n); - avg_mask = tab[dd] * 0.5f; - ecb *= avg_mask; - - /**** long block pre-echo control ****/ - /** - * <PRE> - * dont use long block pre-echo control if previous granule was - * a short block. This is to avoid the situation: - * frame0: quiet (very low masking) - * frame1: surge (triggers short blocks) - * frame2: regular frame. looks like pre-echo when compared to - * frame0, but all pre-echo was in frame1. - * </PRE> - */ - /* - * chn=0,1 L and R channels chn=2,3 S and M channels. - */ - if (gfc.blocktype_old[chn & 0x01] == Encoder.SHORT_TYPE) { - float ecb_limit = rpelev * gfc.nb_1[chn][b]; - if (ecb_limit > 0) { - thr[b] = Math.min(ecb, ecb_limit); - } else { - /** - * <PRE> - * Robert 071209: - * Because we don't calculate long block psy when we know a granule - * should be of short blocks, we don't have any clue how the granule - * before would have looked like as a long block. So we have to guess - * a little bit for this END_TYPE block. - * Most of the time we get away with this sloppyness. (fingers crossed :) - * The speed increase is worth it. - * </PRE> - */ - thr[b] = Math.min(ecb, eb_l[b] * NS_PREECHO_ATT2); - } - } else { - float ecb_limit_2 = rpelev2 * gfc.nb_2[chn][b]; - float ecb_limit_1 = rpelev * gfc.nb_1[chn][b]; - float ecb_limit; - if (ecb_limit_2 <= 0) { - ecb_limit_2 = ecb; - } - if (ecb_limit_1 <= 0) { - ecb_limit_1 = ecb; - } - if (gfc.blocktype_old[chn & 0x01] == Encoder.NORM_TYPE) { - ecb_limit = Math.min(ecb_limit_1, ecb_limit_2); - } else { - ecb_limit = ecb_limit_1; - } - thr[b] = Math.min(ecb, ecb_limit); - } - gfc.nb_2[chn][b] = gfc.nb_1[chn][b]; - gfc.nb_1[chn][b] = ecb; - { - /* - * if THR exceeds EB, the quantization routines will take the - * difference from other bands. in case of strong tonal samples - * (tonaltest.wav) this leads to heavy distortions. that's why - * we limit THR here. - */ - x = max[b]; - x *= gfc.minval_l[b]; - x *= avg_mask; - if (thr[b] > x) { - thr[b] = x; - } - } - if (gfc.masking_lower > 1) { - thr[b] *= gfc.masking_lower; - } - if (thr[b] > eb_l[b]) { - thr[b] = eb_l[b]; - } - if (gfc.masking_lower < 1) { - thr[b] *= gfc.masking_lower; - } - assert (thr[b] >= 0); - } - for (; b < Encoder.CBANDS; ++b) { - eb_l[b] = 0; - thr[b] = 0; - } - } - - private void vbrpsy_compute_block_type(final LameGlobalFlags gfp, - final int[] uselongblock) { - final LameInternalFlags gfc = gfp.internal_flags; - - if (gfp.short_blocks == ShortBlock.short_block_coupled - /* force both channels to use the same block type */ - /* this is necessary if the frame is to be encoded in ms_stereo. */ - /* But even without ms_stereo, FhG does this */ - && !(uselongblock[0] != 0 && uselongblock[1] != 0)) - uselongblock[0] = uselongblock[1] = 0; - - for (int chn = 0; chn < gfc.channels_out; chn++) { - /* disable short blocks */ - if (gfp.short_blocks == ShortBlock.short_block_dispensed) { - uselongblock[chn] = 1; - } - if (gfp.short_blocks == ShortBlock.short_block_forced) { - uselongblock[chn] = 0; - } - } - } - - private void vbrpsy_apply_block_type(final LameGlobalFlags gfp, - final int[] uselongblock, final int[] blocktype_d) { - final LameInternalFlags gfc = gfp.internal_flags; - - /* - * update the blocktype of the previous granule, since it depends on - * what happend in this granule - */ - for (int chn = 0; chn < gfc.channels_out; chn++) { - int blocktype = Encoder.NORM_TYPE; - /* disable short blocks */ - - if (uselongblock[chn] != 0) { - /* no attack : use long blocks */ - assert (gfc.blocktype_old[chn] != Encoder.START_TYPE); - if (gfc.blocktype_old[chn] == Encoder.SHORT_TYPE) - blocktype = Encoder.STOP_TYPE; - } else { - /* attack : use short blocks */ - blocktype = Encoder.SHORT_TYPE; - if (gfc.blocktype_old[chn] == Encoder.NORM_TYPE) { - gfc.blocktype_old[chn] = Encoder.START_TYPE; - } - if (gfc.blocktype_old[chn] == Encoder.STOP_TYPE) - gfc.blocktype_old[chn] = Encoder.SHORT_TYPE; - } - - blocktype_d[chn] = gfc.blocktype_old[chn]; - // value returned to calling program - gfc.blocktype_old[chn] = blocktype; - // save for next call to l3psy_anal - } - } - - /** - * compute M/S thresholds from Johnston & Ferreira 1992 ICASSP paper - */ - private void vbrpsy_compute_MS_thresholds(final float eb[][], - final float thr[][], final float cb_mld[], final float ath_cb[], - final float athadjust, final float msfix, final int n) { - float msfix2 = msfix * 2; - float athlower = msfix > 0 ? (float) Math.pow(10, athadjust) : 1f; - float rside, rmid; - for (int b = 0; b < n; ++b) { - float ebM = eb[2][b]; - float ebS = eb[3][b]; - float thmL = thr[0][b]; - float thmR = thr[1][b]; - float thmM = thr[2][b]; - float thmS = thr[3][b]; - - /* use this fix if L & R masking differs by 2db or less */ - if (thmL <= 1.58 * thmR && thmR <= 1.58 * thmL) { - float mld_m = cb_mld[b] * ebS; - float mld_s = cb_mld[b] * ebM; - rmid = Math.max(thmM, Math.min(thmS, mld_m)); - rside = Math.max(thmS, Math.min(thmM, mld_s)); - } else { - rmid = thmM; - rside = thmS; - } - if (msfix > 0) { - /***************************************************************/ - /* Adjust M/S maskings if user set "msfix" */ - /***************************************************************/ - /* Naoki Shibata 2000 */ - float thmLR, thmMS; - float ath = ath_cb[b] * athlower; - thmLR = Math.min(Math.max(thmL, ath), Math.max(thmR, ath)); - thmM = Math.max(rmid, ath); - thmS = Math.max(rside, ath); - thmMS = thmM + thmS; - if (thmMS > 0 && (thmLR * msfix2) < thmMS) { - float f = thmLR * msfix2 / thmMS; - thmM *= f; - thmS *= f; - assert (thmMS > 0); - } - rmid = Math.min(thmM, rmid); - rside = Math.min(thmS, rside); - } - if (rmid > ebM) { - rmid = ebM; - } - if (rside > ebS) { - rside = ebS; - } - thr[2][b] = rmid; - thr[3][b] = rside; - } - } - - public final int L3psycho_anal_vbr(final LameGlobalFlags gfp, - final float[] buffer[], final int bufPos, final int gr_out, - final III_psy_ratio masking_ratio[][], - final III_psy_ratio masking_MS_ratio[][], - final float percep_entropy[], final float percep_MS_entropy[], - final float energy[], final int blocktype_d[]) { - final LameInternalFlags gfc = gfp.internal_flags; - - /* fft and energy calculation */ - float wsamp_l[][]; - float wsamp_s[][][]; - float fftenergy[] = new float[Encoder.HBLKSIZE]; - float fftenergy_s[][] = new float[3][Encoder.HBLKSIZE_s]; - float wsamp_L[][] = new float[2][Encoder.BLKSIZE]; - float wsamp_S[][][] = new float[2][3][Encoder.BLKSIZE_s]; - float eb[][] = new float[4][Encoder.CBANDS], thr[][] = new float[4][Encoder.CBANDS]; - - float sub_short_factor[][] = new float[4][3]; - float pcfact = 0.6f; - - /* block type */ - int ns_attacks[][] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, - { 0, 0, 0, 0 } }; - int uselongblock[] = new int[2]; - - /* usual variables like loop indices, etc.. */ - - /* chn=2 and 3 = Mid and Side channels */ - int n_chn_psy = (gfp.mode == MPEGMode.JOINT_STEREO) ? 4 - : gfc.channels_out; - - vbrpsy_attack_detection(gfp, buffer, bufPos, gr_out, masking_ratio, - masking_MS_ratio, energy, sub_short_factor, ns_attacks, - uselongblock); - - vbrpsy_compute_block_type(gfp, uselongblock); - - /* LONG BLOCK CASE */ - { - for (int chn = 0; chn < n_chn_psy; chn++) { - int ch01 = chn & 0x01; - wsamp_l = wsamp_L; - vbrpsy_compute_fft_l(gfp, buffer, bufPos, chn, gr_out, - fftenergy, wsamp_l, ch01); - - vbrpsy_compute_loudness_approximation_l(gfp, gr_out, chn, - fftenergy); - - if (uselongblock[ch01] != 0) { - vbrpsy_compute_masking_l(gfc, fftenergy, eb[chn], thr[chn], - chn); - } else { - vbrpsy_skip_masking_l(gfc, chn); - } - } - if ((uselongblock[0] + uselongblock[1]) == 2) { - /* M/S channel */ - if (gfp.mode == MPEGMode.JOINT_STEREO) { - vbrpsy_compute_MS_thresholds(eb, thr, gfc.mld_cb_l, - gfc.ATH.cb_l, gfp.ATHlower * gfc.ATH.adjust, - gfp.msfix, gfc.npart_l); - } - } - /* TODO: apply adaptive ATH masking here ?? */ - for (int chn = 0; chn < n_chn_psy; chn++) { - int ch01 = chn & 0x01; - if (uselongblock[ch01] != 0) { - convert_partition2scalefac_l(gfc, eb[chn], thr[chn], chn); - } - } - } - - /* SHORT BLOCKS CASE */ - { - for (int sblock = 0; sblock < 3; sblock++) { - for (int chn = 0; chn < n_chn_psy; ++chn) { - int ch01 = chn & 0x01; - - if (uselongblock[ch01] != 0) { - vbrpsy_skip_masking_s(gfc, chn, sblock); - } else { - /* compute masking thresholds for short blocks */ - wsamp_s = wsamp_S; - vbrpsy_compute_fft_s(gfp, buffer, bufPos, chn, sblock, - fftenergy_s, wsamp_s, ch01); - vbrpsy_compute_masking_s(gfp, fftenergy_s, eb[chn], - thr[chn], chn, sblock); - } - } - if ((uselongblock[0] + uselongblock[1]) == 0) { - /* M/S channel */ - if (gfp.mode == MPEGMode.JOINT_STEREO) { - vbrpsy_compute_MS_thresholds(eb, thr, gfc.mld_cb_s, - gfc.ATH.cb_s, gfp.ATHlower * gfc.ATH.adjust, - gfp.msfix, gfc.npart_s); - } - /* L/R channel */ - } - /* TODO: apply adaptive ATH masking here ?? */ - for (int chn = 0; chn < n_chn_psy; ++chn) { - int ch01 = chn & 0x01; - if (0 == uselongblock[ch01]) { - convert_partition2scalefac_s(gfc, eb[chn], thr[chn], - chn, sblock); - } - } - } - - /**** short block pre-echo control ****/ - for (int chn = 0; chn < n_chn_psy; chn++) { - int ch01 = chn & 0x01; - - if (uselongblock[ch01] != 0) { - continue; - } - for (int sb = 0; sb < Encoder.SBMAX_s; sb++) { - float new_thmm[] = new float[3]; - for (int sblock = 0; sblock < 3; sblock++) { - float thmm = gfc.thm[chn].s[sb][sblock]; - thmm *= NS_PREECHO_ATT0; - - if (ns_attacks[chn][sblock] >= 2 - || ns_attacks[chn][sblock + 1] == 1) { - int idx = (sblock != 0) ? sblock - 1 : 2; - double p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT1 * pcfact); - thmm = (float) Math.min(thmm, p); - } else if (ns_attacks[chn][sblock] == 1) { - int idx = (sblock != 0) ? sblock - 1 : 2; - double p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT2 * pcfact); - thmm = (float) Math.min(thmm, p); - } else if ((sblock != 0 && ns_attacks[chn][sblock - 1] == 3) - || (sblock == 0 && gfc.nsPsy.lastAttacks[chn] == 3)) { - int idx = (sblock != 2) ? sblock + 1 : 0; - double p = NS_INTERP(gfc.thm[chn].s[sb][idx], thmm, - NS_PREECHO_ATT2 * pcfact); - thmm = (float) Math.min(thmm, p); - } - - /* pulse like signal detection for fatboy.wav and so on */ - thmm *= sub_short_factor[chn][sblock]; - - new_thmm[sblock] = thmm; - } - for (int sblock = 0; sblock < 3; sblock++) { - gfc.thm[chn].s[sb][sblock] = new_thmm[sblock]; - } - } - } - } - for (int chn = 0; chn < n_chn_psy; chn++) { - gfc.nsPsy.lastAttacks[chn] = ns_attacks[chn][2]; - } - - /*************************************************************** - * determine final block type - ***************************************************************/ - vbrpsy_apply_block_type(gfp, uselongblock, blocktype_d); - - /********************************************************************* - * compute the value of PE to return ... no delay and advance - *********************************************************************/ - for (int chn = 0; chn < n_chn_psy; chn++) { - float[] ppe; - int ppePos; - int type; - III_psy_ratio mr; - - if (chn > 1) { - ppe = percep_MS_entropy; - ppePos = -2; - type = Encoder.NORM_TYPE; - if (blocktype_d[0] == Encoder.SHORT_TYPE - || blocktype_d[1] == Encoder.SHORT_TYPE) - type = Encoder.SHORT_TYPE; - mr = masking_MS_ratio[gr_out][chn - 2]; - } else { - ppe = percep_entropy; - ppePos = 0; - type = blocktype_d[chn]; - mr = masking_ratio[gr_out][chn]; - } - - if (type == Encoder.SHORT_TYPE) { - ppe[ppePos + chn] = pecalc_s(mr, gfc.masking_lower); - } else { - ppe[ppePos + chn] = pecalc_l(mr, gfc.masking_lower); - } - - if (gfp.analysis) { - gfc.pinfo.pe[gr_out][chn] = ppe[ppePos + chn]; - } - } - return 0; - } - - private float s3_func_x(final float bark, final float hf_slope) { - float tempx = bark, tempy; - - if (tempx >= 0) { - tempy = -tempx * 27; - } else { - tempy = tempx * hf_slope; - } - if (tempy <= -72.0) { - return 0; - } - return (float) Math.exp(tempy * LN_TO_LOG10); - } - - private float norm_s3_func_x(final float hf_slope) { - double lim_a = 0, lim_b = 0; - { - double x = 0, l, h; - for (x = 0; s3_func_x((float) x, hf_slope) > 1e-20; x -= 1) - ; - l = x; - h = 0; - while (Math.abs(h - l) > 1e-12) { - x = (h + l) / 2; - if (s3_func_x((float) x, hf_slope) > 0) { - h = x; - } else { - l = x; - } - } - lim_a = l; - } - { - double x = 0, l, h; - for (x = 0; s3_func_x((float) x, hf_slope) > 1e-20; x += 1) - ; - l = 0; - h = x; - while (Math.abs(h - l) > 1e-12) { - x = (h + l) / 2; - if (s3_func_x((float) x, hf_slope) > 0) { - l = x; - } else { - h = x; - } - } - lim_b = h; - } - { - double sum = 0; - final int m = 1000; - int i; - for (i = 0; i <= m; ++i) { - double x = lim_a + i * (lim_b - lim_a) / m; - double y = s3_func_x((float) x, hf_slope); - sum += y; - } - { - double norm = (m + 1) / (sum * (lim_b - lim_a)); - /* printf( "norm = %lf\n",norm); */ - return (float) norm; - } - } - } - - /** - * The spreading function. Values returned in units of energy - */ - private float s3_func(final float bark) { - float tempx, x, tempy, temp; - tempx = bark; - if (tempx >= 0) - tempx *= 3; - else - tempx *= 1.5; - - if (tempx >= 0.5 && tempx <= 2.5) { - temp = tempx - 0.5f; - x = 8.0f * (temp * temp - 2.0f * temp); - } else - x = 0.0f; - tempx += 0.474; - tempy = 15.811389f + 7.5f * tempx - 17.5f - * (float) Math.sqrt(1.0 + tempx * tempx); - - if (tempy <= -60.0) - return 0.0f; - - tempx = (float) Math.exp((x + tempy) * LN_TO_LOG10); - - /** - * <PRE> - * Normalization. The spreading function should be normalized so that: - * +inf - * / - * | s3 [ bark ] d(bark) = 1 - * / - * -inf - * </PRE> - */ - tempx /= .6609193; - return tempx; - } - - /** - * see for example "Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 - */ - private float freq2bark(float freq) { - /* input: freq in hz output: barks */ - if (freq < 0) - freq = 0; - freq = freq * 0.001f; - return 13.0f * (float) Math.atan(.76 * freq) + 3.5f - * (float) Math.atan(freq * freq / (7.5 * 7.5)); - } - - private int init_numline(final int[] numlines, final int[] bo, - final int[] bm, final float[] bval, final float[] bval_width, - final float[] mld, final float[] bo_w, float sfreq, - final int blksize, final int[] scalepos, final float deltafreq, - final int sbmax) { - float b_frq[] = new float[Encoder.CBANDS + 1]; - float sample_freq_frac = sfreq / (sbmax > 15 ? 2 * 576 : 2 * 192); - int partition[] = new int[Encoder.HBLKSIZE]; - int i; - sfreq /= blksize; - int j = 0; - int ni = 0; - /* compute numlines, the number of spectral lines in each partition band */ - /* each partition band should be about DELBARK wide. */ - for (i = 0; i < Encoder.CBANDS; i++) { - float bark1; - int j2; - bark1 = freq2bark(sfreq * j); - - b_frq[i] = sfreq * j; - - for (j2 = j; freq2bark(sfreq * j2) - bark1 < DELBARK - && j2 <= blksize / 2; j2++) - ; - - numlines[i] = j2 - j; - ni = i + 1; - - while (j < j2) { - assert (j < Encoder.HBLKSIZE); - partition[j++] = i; - } - if (j > blksize / 2) { - j = blksize / 2; - ++i; - break; - } - } - assert (i < Encoder.CBANDS); - b_frq[i] = sfreq * j; - - for (int sfb = 0; sfb < sbmax; sfb++) { - int i1, i2, start, end; - float arg; - start = scalepos[sfb]; - end = scalepos[sfb + 1]; - - i1 = (int) Math.floor(.5 + deltafreq * (start - .5)); - if (i1 < 0) - i1 = 0; - i2 = (int) Math.floor(.5 + deltafreq * (end - .5)); - - if (i2 > blksize / 2) - i2 = blksize / 2; - - bm[sfb] = (partition[i1] + partition[i2]) / 2; - bo[sfb] = partition[i2]; - - float f_tmp = sample_freq_frac * end; - /* - * calculate how much of this band belongs to current scalefactor - * band - */ - bo_w[sfb] = (f_tmp - b_frq[bo[sfb]]) - / (b_frq[bo[sfb] + 1] - b_frq[bo[sfb]]); - if (bo_w[sfb] < 0) { - bo_w[sfb] = 0; - } else { - if (bo_w[sfb] > 1) { - bo_w[sfb] = 1; - } - } - /* setup stereo demasking thresholds */ - /* formula reverse enginerred from plot in paper */ - arg = freq2bark(sfreq * scalepos[sfb] * deltafreq); - arg = ((float) Math.min(arg, 15.5) / 15.5f); - - mld[sfb] = (float) Math.pow(10.0, - 1.25 * (1 - Math.cos(Math.PI * arg)) - 2.5); - } - - /* compute bark values of each critical band */ - j = 0; - for (int k = 0; k < ni; k++) { - final int w = numlines[k]; - float bark1, bark2; - - bark1 = freq2bark(sfreq * (j)); - bark2 = freq2bark(sfreq * (j + w - 1)); - bval[k] = .5f * (bark1 + bark2); - - bark1 = freq2bark(sfreq * (j - .5f)); - bark2 = freq2bark(sfreq * (j + w - .5f)); - bval_width[k] = bark2 - bark1; - j += w; - } - - return ni; - } - - private float[] init_s3_values(final int s3ind[][], final int npart, - final float[] bval, final float[] bval_width, final float[] norm, - final boolean use_old_s3) { - float s3[][] = new float[Encoder.CBANDS][Encoder.CBANDS]; - /* - * The s3 array is not linear in the bark scale. - * - * bval[x] should be used to get the bark value. - */ - int j; - int numberOfNoneZero = 0; - - /** - * <PRE> - * s[i][j], the value of the spreading function, - * centered at band j (masker), for band i (maskee) - * - * i.e.: sum over j to spread into signal barkval=i - * NOTE: i and j are used opposite as in the ISO docs - * </PRE> - */ - if (use_old_s3) { - for (int i = 0; i < npart; i++) { - for (j = 0; j < npart; j++) { - float v = s3_func(bval[i] - bval[j]) * bval_width[j]; - s3[i][j] = v * norm[i]; - } - } - } else { - for (j = 0; j < npart; j++) { - float hf_slope = 15 + Math.min(21 / bval[j], 12); - float s3_x_norm = norm_s3_func_x(hf_slope); - for (int i = 0; i < npart; i++) { - float v = s3_x_norm - * s3_func_x(bval[i] - bval[j], hf_slope) - * bval_width[j]; - s3[i][j] = v * norm[i]; - } - } - } - for (int i = 0; i < npart; i++) { - for (j = 0; j < npart; j++) { - if (s3[i][j] > 0.0f) - break; - } - s3ind[i][0] = j; - - for (j = npart - 1; j > 0; j--) { - if (s3[i][j] > 0.0f) - break; - } - s3ind[i][1] = j; - numberOfNoneZero += (s3ind[i][1] - s3ind[i][0] + 1); - } - - float[] p = new float[numberOfNoneZero]; - - int k = 0; - for (int i = 0; i < npart; i++) - for (j = s3ind[i][0]; j <= s3ind[i][1]; j++) - p[k++] = s3[i][j]; - - return p; - } - - private float stereo_demask(double f) { - /* setup stereo demasking thresholds */ - /* formula reverse enginerred from plot in paper */ - double arg = freq2bark((float) f); - arg = (Math.min(arg, 15.5) / 15.5); - - return (float) Math.pow(10.0, - 1.25 * (1 - Math.cos(Math.PI * arg)) - 2.5); - } - - /** - * NOTE: the bitrate reduction from the inter-channel masking effect is low - * compared to the chance of getting annyoing artefacts. L3psycho_anal_vbr - * does not use this feature. (Robert 071216) - */ - public final int psymodel_init(final LameGlobalFlags gfp) { - final LameInternalFlags gfc = gfp.internal_flags; - int i; - boolean useOldS3 = true; - float bvl_a = 13, bvl_b = 24; - float snr_l_a = 0, snr_l_b = 0; - float snr_s_a = -8.25f, snr_s_b = -4.5f; - - float bval[] = new float[Encoder.CBANDS]; - float bval_width[] = new float[Encoder.CBANDS]; - float norm[] = new float[Encoder.CBANDS]; - final float sfreq = gfp.out_samplerate; - - switch (gfp.experimentalZ) { - default: - case 0: - useOldS3 = true; - break; - case 1: - useOldS3 = (gfp.VBR == VbrMode.vbr_mtrh || gfp.VBR == VbrMode.vbr_mt) ? false - : true; - break; - case 2: - useOldS3 = false; - break; - case 3: - bvl_a = 8; - snr_l_a = -1.75f; - snr_l_b = -0.0125f; - snr_s_a = -8.25f; - snr_s_b = -2.25f; - break; - } - gfc.ms_ener_ratio_old = .25f; - gfc.blocktype_old[0] = gfc.blocktype_old[1] = Encoder.NORM_TYPE; - // the vbr header is long blocks - - for (i = 0; i < 4; ++i) { - for (int j = 0; j < Encoder.CBANDS; ++j) { - gfc.nb_1[i][j] = 1e20f; - gfc.nb_2[i][j] = 1e20f; - gfc.nb_s1[i][j] = gfc.nb_s2[i][j] = 1.0f; - } - for (int sb = 0; sb < Encoder.SBMAX_l; sb++) { - gfc.en[i].l[sb] = 1e20f; - gfc.thm[i].l[sb] = 1e20f; - } - for (int j = 0; j < 3; ++j) { - for (int sb = 0; sb < Encoder.SBMAX_s; sb++) { - gfc.en[i].s[sb][j] = 1e20f; - gfc.thm[i].s[sb][j] = 1e20f; - } - gfc.nsPsy.lastAttacks[i] = 0; - } - for (int j = 0; j < 9; j++) - gfc.nsPsy.last_en_subshort[i][j] = 10.f; - } - - /* init. for loudness approx. -jd 2001 mar 27 */ - gfc.loudness_sq_save[0] = gfc.loudness_sq_save[1] = 0.0f; - - /************************************************************************* - * now compute the psychoacoustic model specific constants - ************************************************************************/ - /* compute numlines, bo, bm, bval, bval_width, mld */ - - gfc.npart_l = init_numline(gfc.numlines_l, gfc.bo_l, gfc.bm_l, bval, - bval_width, gfc.mld_l, gfc.PSY.bo_l_weight, sfreq, - Encoder.BLKSIZE, gfc.scalefac_band.l, Encoder.BLKSIZE - / (2.0f * 576f), Encoder.SBMAX_l); - assert (gfc.npart_l < Encoder.CBANDS); - /* compute the spreading function */ - for (i = 0; i < gfc.npart_l; i++) { - double snr = snr_l_a; - if (bval[i] >= bvl_a) { - snr = snr_l_b * (bval[i] - bvl_a) / (bvl_b - bvl_a) + snr_l_a - * (bvl_b - bval[i]) / (bvl_b - bvl_a); - } - norm[i] = (float) Math.pow(10.0, snr / 10.0); - if (gfc.numlines_l[i] > 0) { - gfc.rnumlines_l[i] = 1.0f / gfc.numlines_l[i]; - } else { - gfc.rnumlines_l[i] = 0; - } - } - gfc.s3_ll = init_s3_values(gfc.s3ind, gfc.npart_l, bval, bval_width, - norm, useOldS3); - - /* compute long block specific values, ATH and MINVAL */ - int j = 0; - for (i = 0; i < gfc.npart_l; i++) { - double x; - - /* ATH */ - x = Float.MAX_VALUE; - for (int k = 0; k < gfc.numlines_l[i]; k++, j++) { - final float freq = sfreq * j / (1000.0f * Encoder.BLKSIZE); - float level; - /* - * ATH below 100 Hz constant, not further climbing - */ - level = ATHformula(freq * 1000, gfp) - 20; - // scale to FFT units; returned value is in dB - level = (float) Math.pow(10., 0.1 * level); - // convert from dB . energy - level *= gfc.numlines_l[i]; - if (x > level) - x = level; - } - gfc.ATH.cb_l[i] = (float) x; - - /* - * MINVAL. For low freq, the strength of the masking is limited by - * minval this is an ISO MPEG1 thing, dont know if it is really - * needed - */ - /* - * FIXME: it does work to reduce low-freq problems in S53-Wind-Sax - * and lead-voice samples, but introduces some 3 kbps bit bloat too. - * TODO: Further refinement of the shape of this hack. - */ - x = -20 + bval[i] * 20 / 10; - if (x > 6) { - x = 100; - } - if (x < -15) { - x = -15; - } - x -= 8.; - gfc.minval_l[i] = (float) (Math.pow(10.0, x / 10.) * gfc.numlines_l[i]); - } - - /************************************************************************ - * do the same things for short blocks - ************************************************************************/ - gfc.npart_s = init_numline(gfc.numlines_s, gfc.bo_s, gfc.bm_s, bval, - bval_width, gfc.mld_s, gfc.PSY.bo_s_weight, sfreq, - Encoder.BLKSIZE_s, gfc.scalefac_band.s, Encoder.BLKSIZE_s - / (2.0f * 192), Encoder.SBMAX_s); - assert (gfc.npart_s < Encoder.CBANDS); - - /* SNR formula. short block is normalized by SNR. is it still right ? */ - j = 0; - for (i = 0; i < gfc.npart_s; i++) { - double x; - double snr = snr_s_a; - if (bval[i] >= bvl_a) { - snr = snr_s_b * (bval[i] - bvl_a) / (bvl_b - bvl_a) + snr_s_a - * (bvl_b - bval[i]) / (bvl_b - bvl_a); - } - norm[i] = (float) Math.pow(10.0, snr / 10.0); - - /* ATH */ - x = Float.MAX_VALUE; - for (int k = 0; k < gfc.numlines_s[i]; k++, j++) { - final float freq = sfreq * j / (1000.0f * Encoder.BLKSIZE_s); - float level; - /* freq = Min(.1,freq); *//* - * ATH below 100 Hz constant, not - * further climbing - */ - level = ATHformula(freq * 1000, gfp) - 20; - // scale to FFT units; returned value is in dB - level = (float) Math.pow(10., 0.1 * level); - // convert from dB . energy - level *= gfc.numlines_s[i]; - if (x > level) - x = level; - } - gfc.ATH.cb_s[i] = (float) x; - - /* - * MINVAL. For low freq, the strength of the masking is limited by - * minval this is an ISO MPEG1 thing, dont know if it is really - * needed - */ - x = (-7.0 + bval[i] * 7.0 / 12.0); - if (bval[i] > 12) { - x *= 1 + Math.log(1 + x) * 3.1; - } - if (bval[i] < 12) { - x *= 1 + Math.log(1 - x) * 2.3; - } - if (x < -15) { - x = -15; - } - x -= 8; - gfc.minval_s[i] = (float) Math.pow(10.0, x / 10) - * gfc.numlines_s[i]; - } - - gfc.s3_ss = init_s3_values(gfc.s3ind_s, gfc.npart_s, bval, bval_width, - norm, useOldS3); - - init_mask_add_max_values(); - fft.init_fft(gfc); - - /* setup temporal masking */ - gfc.decay = (float) Math.exp(-1.0 * LOG10 - / (temporalmask_sustain_sec * sfreq / 192.0)); - - { - float msfix; - msfix = NS_MSFIX; - if ((gfp.exp_nspsytune & 2) != 0) - msfix = 1.0f; - if (Math.abs(gfp.msfix) > 0.0) - msfix = gfp.msfix; - gfp.msfix = msfix; - - /* - * spread only from npart_l bands. Normally, we use the spreading - * function to convolve from npart_l down to npart_l bands - */ - for (int b = 0; b < gfc.npart_l; b++) - if (gfc.s3ind[b][1] > gfc.npart_l - 1) - gfc.s3ind[b][1] = gfc.npart_l - 1; - } - - /* - * prepare for ATH auto adjustment: we want to decrease the ATH by 12 dB - * per second - */ - float frame_duration = (576.f * gfc.mode_gr / sfreq); - gfc.ATH.decay = (float) Math.pow(10., -12. / 10. * frame_duration); - gfc.ATH.adjust = 0.01f; /* minimum, for leading low loudness */ - gfc.ATH.adjustLimit = 1.0f; /* on lead, allow adjust up to maximum */ - - assert (gfc.bo_l[Encoder.SBMAX_l - 1] <= gfc.npart_l); - assert (gfc.bo_s[Encoder.SBMAX_s - 1] <= gfc.npart_s); - - if (gfp.ATHtype != -1) { - /* compute equal loudness weights (eql_w) */ - float freq; - final float freq_inc = (float) gfp.out_samplerate - / (float) (Encoder.BLKSIZE); - float eql_balance = 0.0f; - freq = 0.0f; - for (i = 0; i < Encoder.BLKSIZE / 2; ++i) { - /* convert ATH dB to relative power (not dB) */ - /* to determine eql_w */ - freq += freq_inc; - gfc.ATH.eql_w[i] = 1.f / (float) Math.pow(10, - ATHformula(freq, gfp) / 10); - eql_balance += gfc.ATH.eql_w[i]; - } - eql_balance = 1.0f / eql_balance; - for (i = Encoder.BLKSIZE / 2; --i >= 0;) { /* scale weights */ - gfc.ATH.eql_w[i] *= eql_balance; - } - } - { - for (int b = j = 0; b < gfc.npart_s; ++b) { - for (i = 0; i < gfc.numlines_s[b]; ++i) { - ++j; - } - } - assert (j == 129); - for (int b = j = 0; b < gfc.npart_l; ++b) { - for (i = 0; i < gfc.numlines_l[b]; ++i) { - ++j; - } - } - assert (j == 513); - } - j = 0; - for (i = 0; i < gfc.npart_l; i++) { - final float freq = sfreq * (j + gfc.numlines_l[i] / 2) - / (1.0f * Encoder.BLKSIZE); - gfc.mld_cb_l[i] = stereo_demask(freq); - j += gfc.numlines_l[i]; - } - for (; i < Encoder.CBANDS; ++i) { - gfc.mld_cb_l[i] = 1; - } - j = 0; - for (i = 0; i < gfc.npart_s; i++) { - final float freq = sfreq * (j + gfc.numlines_s[i] / 2) - / (1.0f * Encoder.BLKSIZE_s); - gfc.mld_cb_s[i] = stereo_demask(freq); - j += gfc.numlines_s[i]; - } - for (; i < Encoder.CBANDS; ++i) { - gfc.mld_cb_s[i] = 1; - } - return 0; - } - - /** - * Those ATH formulas are returning their minimum value for input = -1 - */ - private float ATHformula_GB(float f, final float value) { - /** - * <PRE> - * from Painter & Spanias - * modified by Gabriel Bouvigne to better fit the reality - * ath = 3.640 * pow(f,-0.8) - * - 6.800 * exp(-0.6*pow(f-3.4,2.0)) - * + 6.000 * exp(-0.15*pow(f-8.7,2.0)) - * + 0.6* 0.001 * pow(f,4.0); - * - * - * In the past LAME was using the Painter &Spanias formula. - * But we had some recurrent problems with HF content. - * We measured real ATH values, and found the older formula - * to be inaccurate in the higher part. So we made this new - * formula and this solved most of HF problematic test cases. - * The tradeoff is that in VBR mode it increases a lot the - * bitrate. - * </PRE> - */ - - /* - * This curve can be adjusted according to the VBR scale: it adjusts - * from something close to Painter & Spanias on V9 up to Bouvigne's - * formula for V0. This way the VBR bitrate is more balanced according - * to the -V value. - */ - - // the following Hack allows to ask for the lowest value - if (f < -.3) - f = 3410; - - // convert to khz - f /= 1000; - f = (float) Math.max(0.1, f); - - float ath = 3.640f * (float) Math.pow(f, -0.8) - 6.800f - * (float) Math.exp(-0.6 * Math.pow(f - 3.4, 2.0)) + 6.000f - * (float) Math.exp(-0.15 * Math.pow(f - 8.7, 2.0)) - + (0.6f + 0.04f * value) * 0.001f * (float) Math.pow(f, 4.0); - return ath; - } - - public final float ATHformula(final float f, final LameGlobalFlags gfp) { - float ath; - switch (gfp.ATHtype) { - case 0: - ath = ATHformula_GB(f, 9); - break; - case 1: - // over sensitive, should probably be removed - ath = ATHformula_GB(f, -1); - break; - case 2: - ath = ATHformula_GB(f, 0); - break; - case 3: - // modification of GB formula by Roel - ath = ATHformula_GB(f, 1) + 6; - break; - case 4: - ath = ATHformula_GB(f, gfp.ATHcurve); - break; - default: - ath = ATHformula_GB(f, 0); - break; - } - return ath; - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Quantize.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Quantize.java deleted file mode 100644 index a9928832f..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Quantize.java +++ /dev/null @@ -1,1478 +0,0 @@ -/* - * MP3 quantization - * - * Copyright (c) 1999-2000 Mark Taylor - * Copyright (c) 1999-2003 Takehiro Tominaga - * Copyright (c) 2000-2007 Robert Hegemann - * Copyright (c) 2001-2005 Gabriel Bouvigne - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: Quantize.java,v 1.24 2011/05/24 20:48:06 kenchis Exp $ */ - -package mp3; - -import java.util.Arrays; - -public class Quantize { - BitStream bs; - Reservoir rv; - QuantizePVT qupvt; - VBRQuantize vbr = new VBRQuantize(); - Takehiro tk; - - public final void setModules(BitStream bs, Reservoir rv, QuantizePVT qupvt, - Takehiro tk) { - this.bs = bs; - this.rv = rv; - this.qupvt = qupvt; - this.tk = tk; - this.vbr.setModules(qupvt, tk); - } - - /** - * convert from L/R <. Mid/Side - */ - public final void ms_convert(final IIISideInfo l3_side, final int gr) { - for (int i = 0; i < 576; ++i) { - float l = l3_side.tt[gr][0].xr[i]; - float r = l3_side.tt[gr][1].xr[i]; - l3_side.tt[gr][0].xr[i] = (l + r) * (float) (Util.SQRT2 * 0.5); - l3_side.tt[gr][1].xr[i] = (l - r) * (float) (Util.SQRT2 * 0.5); - } - } - - /** - * mt 6/99 - * - * initializes cod_info, scalefac and xrpow - * - * returns 0 if all energies in xr are zero, else 1 - */ - private float init_xrpow_core(final GrInfo cod_info, float xrpow[], - int upper, float sum) { - sum = 0; - for (int i = 0; i <= upper; ++i) { - float tmp = Math.abs(cod_info.xr[i]); - sum += tmp; - xrpow[i] = (float) Math.sqrt(tmp * Math.sqrt(tmp)); - - if (xrpow[i] > cod_info.xrpow_max) - cod_info.xrpow_max = xrpow[i]; - } - return sum; - } - - public final boolean init_xrpow(final LameInternalFlags gfc, - final GrInfo cod_info, float xrpow[]) { - float sum = 0; - final int upper = cod_info.max_nonzero_coeff; - - assert (xrpow != null); - cod_info.xrpow_max = 0; - - /* - * check if there is some energy we have to quantize and calculate xrpow - * matching our fresh scalefactors - */ - assert (0 <= upper && upper <= 575); - - Arrays.fill(xrpow, upper, 576, 0); - - sum = init_xrpow_core(cod_info, xrpow, upper, sum); - - /* - * return 1 if we have something to quantize, else 0 - */ - if (sum > 1E-20f) { - int j = 0; - if ((gfc.substep_shaping & 2) != 0) - j = 1; - - for (int i = 0; i < cod_info.psymax; i++) - gfc.pseudohalf[i] = j; - - return true; - } - - Arrays.fill(cod_info.l3_enc, 0, 576, 0); - return false; - } - - /** - * Gabriel Bouvigne feb/apr 2003<BR> - * Analog silence detection in partitionned sfb21 or sfb12 for short blocks - * - * From top to bottom of sfb, changes to 0 coeffs which are below ath. It - * stops on the first coeff higher than ath. - */ - private void psfb21_analogsilence(final LameInternalFlags gfc, - final GrInfo cod_info) { - final ATH ath = gfc.ATH; - final float[] xr = cod_info.xr; - - if (cod_info.block_type != Encoder.SHORT_TYPE) { - /* NORM, START or STOP type, but not SHORT blocks */ - boolean stop = false; - for (int gsfb = Encoder.PSFB21 - 1; gsfb >= 0 && !stop; gsfb--) { - final int start = gfc.scalefac_band.psfb21[gsfb]; - final int end = gfc.scalefac_band.psfb21[gsfb + 1]; - float ath21 = qupvt.athAdjust(ath.adjust, ath.psfb21[gsfb], - ath.floor); - - if (gfc.nsPsy.longfact[21] > 1e-12f) - ath21 *= gfc.nsPsy.longfact[21]; - - for (int j = end - 1; j >= start; j--) { - if (Math.abs(xr[j]) < ath21) - xr[j] = 0; - else { - stop = true; - break; - } - } - } - } else { - /* note: short blocks coeffs are reordered */ - for (int block = 0; block < 3; block++) { - boolean stop = false; - for (int gsfb = Encoder.PSFB12 - 1; gsfb >= 0 && !stop; gsfb--) { - final int start = gfc.scalefac_band.s[12] - * 3 - + (gfc.scalefac_band.s[13] - gfc.scalefac_band.s[12]) - * block - + (gfc.scalefac_band.psfb12[gsfb] - gfc.scalefac_band.psfb12[0]); - final int end = start - + (gfc.scalefac_band.psfb12[gsfb + 1] - gfc.scalefac_band.psfb12[gsfb]); - float ath12 = qupvt.athAdjust(ath.adjust, ath.psfb12[gsfb], - ath.floor); - - if (gfc.nsPsy.shortfact[12] > 1e-12f) - ath12 *= gfc.nsPsy.shortfact[12]; - - for (int j = end - 1; j >= start; j--) { - if (Math.abs(xr[j]) < ath12) - xr[j] = 0; - else { - stop = true; - break; - } - } - } - } - } - - } - - public final void init_outer_loop(final LameInternalFlags gfc, - final GrInfo cod_info) { - /* - * initialize fresh cod_info - */ - cod_info.part2_3_length = 0; - cod_info.big_values = 0; - cod_info.count1 = 0; - cod_info.global_gain = 210; - cod_info.scalefac_compress = 0; - /* mixed_block_flag, block_type was set in psymodel.c */ - cod_info.table_select[0] = 0; - cod_info.table_select[1] = 0; - cod_info.table_select[2] = 0; - cod_info.subblock_gain[0] = 0; - cod_info.subblock_gain[1] = 0; - cod_info.subblock_gain[2] = 0; - cod_info.subblock_gain[3] = 0; /* this one is always 0 */ - cod_info.region0_count = 0; - cod_info.region1_count = 0; - cod_info.preflag = 0; - cod_info.scalefac_scale = 0; - cod_info.count1table_select = 0; - cod_info.part2_length = 0; - cod_info.sfb_lmax = Encoder.SBPSY_l; - cod_info.sfb_smin = Encoder.SBPSY_s; - cod_info.psy_lmax = gfc.sfb21_extra ? Encoder.SBMAX_l : Encoder.SBPSY_l; - cod_info.psymax = cod_info.psy_lmax; - cod_info.sfbmax = cod_info.sfb_lmax; - cod_info.sfbdivide = 11; - for (int sfb = 0; sfb < Encoder.SBMAX_l; sfb++) { - cod_info.width[sfb] = gfc.scalefac_band.l[sfb + 1] - - gfc.scalefac_band.l[sfb]; - /* which is always 0. */ - cod_info.window[sfb] = 3; - } - if (cod_info.block_type == Encoder.SHORT_TYPE) { - float ixwork[] = new float[576]; - - cod_info.sfb_smin = 0; - cod_info.sfb_lmax = 0; - if (cod_info.mixed_block_flag != 0) { - /* - * MPEG-1: sfbs 0-7 long block, 3-12 short blocks MPEG-2(.5): - * sfbs 0-5 long block, 3-12 short blocks - */ - cod_info.sfb_smin = 3; - cod_info.sfb_lmax = gfc.mode_gr * 2 + 4; - } - cod_info.psymax = cod_info.sfb_lmax - + 3 - * ((gfc.sfb21_extra ? Encoder.SBMAX_s : Encoder.SBPSY_s) - cod_info.sfb_smin); - cod_info.sfbmax = cod_info.sfb_lmax + 3 - * (Encoder.SBPSY_s - cod_info.sfb_smin); - cod_info.sfbdivide = cod_info.sfbmax - 18; - cod_info.psy_lmax = cod_info.sfb_lmax; - /* re-order the short blocks, for more efficient encoding below */ - /* By Takehiro TOMINAGA */ - /* - * Within each scalefactor band, data is given for successive time - * windows, beginning with window 0 and ending with window 2. Within - * each window, the quantized values are then arranged in order of - * increasing frequency... - */ - int ix = gfc.scalefac_band.l[cod_info.sfb_lmax]; - System.arraycopy(cod_info.xr, 0, ixwork, 0, 576); - for (int sfb = cod_info.sfb_smin; sfb < Encoder.SBMAX_s; sfb++) { - final int start = gfc.scalefac_band.s[sfb]; - final int end = gfc.scalefac_band.s[sfb + 1]; - for (int window = 0; window < 3; window++) { - for (int l = start; l < end; l++) { - cod_info.xr[ix++] = ixwork[3 * l + window]; - } - } - } - - int j = cod_info.sfb_lmax; - for (int sfb = cod_info.sfb_smin; sfb < Encoder.SBMAX_s; sfb++) { - cod_info.width[j] = cod_info.width[j + 1] = cod_info.width[j + 2] = gfc.scalefac_band.s[sfb + 1] - - gfc.scalefac_band.s[sfb]; - cod_info.window[j] = 0; - cod_info.window[j + 1] = 1; - cod_info.window[j + 2] = 2; - j += 3; - } - } - - cod_info.count1bits = 0; - cod_info.sfb_partition_table = qupvt.nr_of_sfb_block[0][0]; - cod_info.slen[0] = 0; - cod_info.slen[1] = 0; - cod_info.slen[2] = 0; - cod_info.slen[3] = 0; - - cod_info.max_nonzero_coeff = 575; - - /* - * fresh scalefactors are all zero - */ - Arrays.fill(cod_info.scalefac, 0); - - psfb21_analogsilence(gfc, cod_info); - } - - private enum BinSearchDirection { - BINSEARCH_NONE, BINSEARCH_UP, BINSEARCH_DOWN - } - - /** - * author/date?? - * - * binary step size search used by outer_loop to get a quantizer step size - * to start with - */ - private int bin_search_StepSize(final LameInternalFlags gfc, - final GrInfo cod_info, int desired_rate, final int ch, - final float xrpow[]) { - int nBits; - int CurrentStep = gfc.CurrentStep[ch]; - boolean flagGoneOver = false; - final int start = gfc.OldValue[ch]; - BinSearchDirection Direction = BinSearchDirection.BINSEARCH_NONE; - cod_info.global_gain = start; - desired_rate -= cod_info.part2_length; - - assert (CurrentStep != 0); - for (;;) { - int step; - nBits = tk.count_bits(gfc, xrpow, cod_info, null); - - if (CurrentStep == 1 || nBits == desired_rate) - break; /* nothing to adjust anymore */ - - if (nBits > desired_rate) { - /* increase Quantize_StepSize */ - if (Direction == BinSearchDirection.BINSEARCH_DOWN) - flagGoneOver = true; - - if (flagGoneOver) - CurrentStep /= 2; - Direction = BinSearchDirection.BINSEARCH_UP; - step = CurrentStep; - } else { - /* decrease Quantize_StepSize */ - if (Direction == BinSearchDirection.BINSEARCH_UP) - flagGoneOver = true; - - if (flagGoneOver) - CurrentStep /= 2; - Direction = BinSearchDirection.BINSEARCH_DOWN; - step = -CurrentStep; - } - cod_info.global_gain += step; - if (cod_info.global_gain < 0) { - cod_info.global_gain = 0; - flagGoneOver = true; - } - if (cod_info.global_gain > 255) { - cod_info.global_gain = 255; - flagGoneOver = true; - } - } - - assert (cod_info.global_gain >= 0); - assert (cod_info.global_gain < 256); - - while (nBits > desired_rate && cod_info.global_gain < 255) { - cod_info.global_gain++; - nBits = tk.count_bits(gfc, xrpow, cod_info, null); - } - gfc.CurrentStep[ch] = (start - cod_info.global_gain >= 4) ? 4 : 2; - gfc.OldValue[ch] = cod_info.global_gain; - cod_info.part2_3_length = nBits; - return nBits; - } - - public final void trancate_smallspectrums(final LameInternalFlags gfc, - final GrInfo gi, final float[] l3_xmin, final float[] work) { - float distort[] = new float[L3Side.SFBMAX]; - - if ((0 == (gfc.substep_shaping & 4) && gi.block_type == Encoder.SHORT_TYPE) - || (gfc.substep_shaping & 0x80) != 0) - return; - qupvt.calc_noise(gi, l3_xmin, distort, new CalcNoiseResult(), null); - for (int j = 0; j < 576; j++) { - float xr = 0.0f; - if (gi.l3_enc[j] != 0) - xr = Math.abs(gi.xr[j]); - work[j] = xr; - } - - int j = 0; - int sfb = 8; - if (gi.block_type == Encoder.SHORT_TYPE) - sfb = 6; - do { - float allowedNoise, trancateThreshold; - int nsame, start; - - int width = gi.width[sfb]; - j += width; - if (distort[sfb] >= 1.0) - continue; - - Arrays.sort(work, j - width, width); - if (BitStream.EQ(work[j - 1], 0.0f)) - continue; /* all zero sfb */ - - allowedNoise = (1.0f - distort[sfb]) * l3_xmin[sfb]; - trancateThreshold = 0.0f; - start = 0; - do { - float noise; - for (nsame = 1; start + nsame < width; nsame++) - if (BitStream.NEQ(work[start + j - width], work[start + j - + nsame - width])) - break; - - noise = work[start + j - width] * work[start + j - width] - * nsame; - if (allowedNoise < noise) { - if (start != 0) - trancateThreshold = work[start + j - width - 1]; - break; - } - allowedNoise -= noise; - start += nsame; - } while (start < width); - if (BitStream.EQ(trancateThreshold, 0.0f)) - continue; - - do { - if (Math.abs(gi.xr[j - width]) <= trancateThreshold) - gi.l3_enc[j - width] = 0; - } while (--width > 0); - } while (++sfb < gi.psymax); - - gi.part2_3_length = tk.noquant_count_bits(gfc, gi, null); - } - - /** - * author/date?? - * - * Function: Returns zero if there is a scalefac which has not been - * amplified. Otherwise it returns one. - */ - private boolean loop_break(final GrInfo cod_info) { - for (int sfb = 0; sfb < cod_info.sfbmax; sfb++) - if (cod_info.scalefac[sfb] - + cod_info.subblock_gain[cod_info.window[sfb]] == 0) - return false; - - return true; - } - - /* mt 5/99: Function: Improved calc_noise for a single channel */ - - private double penalties(final double noise) { - return Util.FAST_LOG10((float) (0.368 + 0.632 * noise * noise * noise)); - } - - /** - * author/date?? - * - * several different codes to decide which quantization is better - */ - private double get_klemm_noise(final float[] distort, final GrInfo gi) { - double klemm_noise = 1E-37; - for (int sfb = 0; sfb < gi.psymax; sfb++) - klemm_noise += penalties(distort[sfb]); - - return Math.max(1e-20, klemm_noise); - } - - private boolean quant_compare(final int quant_comp, - final CalcNoiseResult best, final CalcNoiseResult calc, - final GrInfo gi, final float[] distort) { - /** - * noise is given in decibels (dB) relative to masking thesholds.<BR> - * - * over_noise: ??? (the previous comment is fully wrong)<BR> - * tot_noise: ??? (the previous comment is fully wrong)<BR> - * max_noise: max quantization noise - */ - boolean better; - - switch (quant_comp) { - default: - case 9: { - if (best.over_count > 0) { - /* there are distorted sfb */ - better = calc.over_SSD <= best.over_SSD; - if (calc.over_SSD == best.over_SSD) - better = calc.bits < best.bits; - } else { - /* no distorted sfb */ - better = ((calc.max_noise < 0) && ((calc.max_noise * 10 + calc.bits) <= (best.max_noise * 10 + best.bits))); - } - break; - } - - case 0: - better = calc.over_count < best.over_count - || (calc.over_count == best.over_count && calc.over_noise < best.over_noise) - || (calc.over_count == best.over_count - && BitStream.EQ(calc.over_noise, best.over_noise) && calc.tot_noise < best.tot_noise); - break; - - case 8: - calc.max_noise = (float) get_klemm_noise(distort, gi); - //$FALL-THROUGH$ - case 1: - better = calc.max_noise < best.max_noise; - break; - case 2: - better = calc.tot_noise < best.tot_noise; - break; - case 3: - better = (calc.tot_noise < best.tot_noise) - && (calc.max_noise < best.max_noise); - break; - case 4: - better = (calc.max_noise <= 0.0 && best.max_noise > 0.2) - || (calc.max_noise <= 0.0 && best.max_noise < 0.0 - && best.max_noise > calc.max_noise - 0.2 && calc.tot_noise < best.tot_noise) - || (calc.max_noise <= 0.0 && best.max_noise > 0.0 - && best.max_noise > calc.max_noise - 0.2 && calc.tot_noise < best.tot_noise - + best.over_noise) - || (calc.max_noise > 0.0 && best.max_noise > -0.05 - && best.max_noise > calc.max_noise - 0.1 && calc.tot_noise - + calc.over_noise < best.tot_noise - + best.over_noise) - || (calc.max_noise > 0.0 && best.max_noise > -0.1 - && best.max_noise > calc.max_noise - 0.15 && calc.tot_noise - + calc.over_noise + calc.over_noise < best.tot_noise - + best.over_noise + best.over_noise); - break; - case 5: - better = calc.over_noise < best.over_noise - || (BitStream.EQ(calc.over_noise, best.over_noise) && calc.tot_noise < best.tot_noise); - break; - case 6: - better = calc.over_noise < best.over_noise - || (BitStream.EQ(calc.over_noise, best.over_noise) && (calc.max_noise < best.max_noise || (BitStream - .EQ(calc.max_noise, best.max_noise) && calc.tot_noise <= best.tot_noise))); - break; - case 7: - better = calc.over_count < best.over_count - || calc.over_noise < best.over_noise; - break; - } - - if (best.over_count == 0) { - /* - * If no distorted bands, only use this quantization if it is - * better, and if it uses less bits. Unfortunately, part2_3_length - * is sometimes a poor estimator of the final size at low bitrates. - */ - better = better && calc.bits < best.bits; - } - - return better; - } - - /** - * author/date?? - * - * <PRE> - * Amplify the scalefactor bands that violate the masking threshold. - * See ISO 11172-3 Section C.1.5.4.3.5 - * - * distort[] = noise/masking - * distort[] > 1 ==> noise is not masked - * distort[] < 1 ==> noise is masked - * max_dist = maximum value of distort[] - * - * Three algorithms: - * noise_shaping_amp - * 0 Amplify all bands with distort[]>1. - * - * 1 Amplify all bands with distort[] >= max_dist^(.5); - * ( 50% in the db scale) - * - * 2 Amplify first band with distort[] >= max_dist; - * - * - * For algorithms 0 and 1, if max_dist < 1, then amplify all bands - * with distort[] >= .95*max_dist. This is to make sure we always - * amplify at least one band. - * </PRE> - */ - private void amp_scalefac_bands(final LameGlobalFlags gfp, - final GrInfo cod_info, final float[] distort, - final float xrpow[], final boolean bRefine) { - final LameInternalFlags gfc = gfp.internal_flags; - float ifqstep34; - - if (cod_info.scalefac_scale == 0) { - ifqstep34 = 1.29683955465100964055f; /* 2**(.75*.5) */ - } else { - ifqstep34 = 1.68179283050742922612f; /* 2**(.75*1) */ - } - - /* compute maximum value of distort[] */ - float trigger = 0; - for (int sfb = 0; sfb < cod_info.sfbmax; sfb++) { - if (trigger < distort[sfb]) - trigger = distort[sfb]; - } - - int noise_shaping_amp = gfc.noise_shaping_amp; - if (noise_shaping_amp == 3) { - if (bRefine) - noise_shaping_amp = 2; - else - noise_shaping_amp = 1; - } - switch (noise_shaping_amp) { - case 2: - /* amplify exactly 1 band */ - break; - - case 1: - /* amplify bands within 50% of max (on db scale) */ - if (trigger > 1.0) - trigger = (float) Math.pow(trigger, .5); - else - trigger *= .95; - break; - - case 0: - default: - /* ISO algorithm. amplify all bands with distort>1 */ - if (trigger > 1.0) - trigger = 1.0f; - else - trigger *= .95; - break; - } - - int j = 0; - for (int sfb = 0; sfb < cod_info.sfbmax; sfb++) { - final int width = cod_info.width[sfb]; - int l; - j += width; - if (distort[sfb] < trigger) - continue; - - if ((gfc.substep_shaping & 2) != 0) { - gfc.pseudohalf[sfb] = (0 == gfc.pseudohalf[sfb]) ? 1 : 0; - if (0 == gfc.pseudohalf[sfb] && gfc.noise_shaping_amp == 2) - return; - } - cod_info.scalefac[sfb]++; - for (l = -width; l < 0; l++) { - xrpow[j + l] *= ifqstep34; - if (xrpow[j + l] > cod_info.xrpow_max) - cod_info.xrpow_max = xrpow[j + l]; - } - - if (gfc.noise_shaping_amp == 2) - return; - } - } - - /** - * Takehiro Tominaga 2000-xx-xx - * - * turns on scalefac scale and adjusts scalefactors - */ - private void inc_scalefac_scale(final GrInfo cod_info, float xrpow[]) { - final float ifqstep34 = 1.29683955465100964055f; - - int j = 0; - for (int sfb = 0; sfb < cod_info.sfbmax; sfb++) { - final int width = cod_info.width[sfb]; - int s = cod_info.scalefac[sfb]; - if (cod_info.preflag != 0) - s += qupvt.pretab[sfb]; - j += width; - if ((s & 1) != 0) { - s++; - for (int l = -width; l < 0; l++) { - xrpow[j + l] *= ifqstep34; - if (xrpow[j + l] > cod_info.xrpow_max) - cod_info.xrpow_max = xrpow[j + l]; - } - } - cod_info.scalefac[sfb] = s >> 1; - } - cod_info.preflag = 0; - cod_info.scalefac_scale = 1; - } - - /** - * Takehiro Tominaga 2000-xx-xx - * - * increases the subblock gain and adjusts scalefactors - */ - private boolean inc_subblock_gain(final LameInternalFlags gfc, - final GrInfo cod_info, float xrpow[]) { - int sfb; - final int[] scalefac = cod_info.scalefac; - - /* subbloc_gain can't do anything in the long block region */ - for (sfb = 0; sfb < cod_info.sfb_lmax; sfb++) { - if (scalefac[sfb] >= 16) - return true; - } - - for (int window = 0; window < 3; window++) { - int s1 = 0; - int s2 = 0; - - for (sfb = cod_info.sfb_lmax + window; sfb < cod_info.sfbdivide; sfb += 3) { - if (s1 < scalefac[sfb]) - s1 = scalefac[sfb]; - } - for (; sfb < cod_info.sfbmax; sfb += 3) { - if (s2 < scalefac[sfb]) - s2 = scalefac[sfb]; - } - - if (s1 < 16 && s2 < 8) - continue; - - if (cod_info.subblock_gain[window] >= 7) - return true; - - /* - * even though there is no scalefactor for sfb12 subblock gain - * affects upper frequencies too, that's why we have to go up to - * SBMAX_s - */ - cod_info.subblock_gain[window]++; - int j = gfc.scalefac_band.l[cod_info.sfb_lmax]; - for (sfb = cod_info.sfb_lmax + window; sfb < cod_info.sfbmax; sfb += 3) { - float amp; - final int width = cod_info.width[sfb]; - int s = scalefac[sfb]; - assert (s >= 0); - s = s - (4 >> cod_info.scalefac_scale); - if (s >= 0) { - scalefac[sfb] = s; - j += width * 3; - continue; - } - - scalefac[sfb] = 0; - { - final int gain = 210 + (s << (cod_info.scalefac_scale + 1)); - amp = qupvt.IPOW20(gain); - } - j += width * (window + 1); - for (int l = -width; l < 0; l++) { - xrpow[j + l] *= amp; - if (xrpow[j + l] > cod_info.xrpow_max) - cod_info.xrpow_max = xrpow[j + l]; - } - j += width * (3 - window - 1); - } - - { - final float amp = qupvt.IPOW20(202); - j += cod_info.width[sfb] * (window + 1); - for (int l = -cod_info.width[sfb]; l < 0; l++) { - xrpow[j + l] *= amp; - if (xrpow[j + l] > cod_info.xrpow_max) - cod_info.xrpow_max = xrpow[j + l]; - } - } - } - return false; - } - - /** - * <PRE> - * Takehiro Tominaga /date?? - * Robert Hegemann 2000-09-06: made a function of it - * - * amplifies scalefactor bands, - * - if all are already amplified returns 0 - * - if some bands are amplified too much: - * * try to increase scalefac_scale - * * if already scalefac_scale was set - * try on short blocks to increase subblock gain - * </PRE> - */ - private boolean balance_noise(final LameGlobalFlags gfp, - final GrInfo cod_info, final float[] distort, float xrpow[], - final boolean bRefine) { - final LameInternalFlags gfc = gfp.internal_flags; - - amp_scalefac_bands(gfp, cod_info, distort, xrpow, bRefine); - - /* - * check to make sure we have not amplified too much loop_break returns - * 0 if there is an unamplified scalefac scale_bitcount returns 0 if no - * scalefactors are too large - */ - - boolean status = loop_break(cod_info); - - if (status) - return false; /* all bands amplified */ - - /* - * not all scalefactors have been amplified. so these scalefacs are - * possibly valid. encode them: - */ - if (gfc.mode_gr == 2) - status = tk.scale_bitcount(cod_info); - else - status = tk.scale_bitcount_lsf(gfc, cod_info); - - if (!status) - return true; /* amplified some bands not exceeding limits */ - - /* - * some scalefactors are too large. lets try setting scalefac_scale=1 - */ - if (gfc.noise_shaping > 1) { - Arrays.fill(gfc.pseudohalf, 0); - if (0 == cod_info.scalefac_scale) { - inc_scalefac_scale(cod_info, xrpow); - status = false; - } else { - if (cod_info.block_type == Encoder.SHORT_TYPE - && gfc.subblock_gain > 0) { - status = (inc_subblock_gain(gfc, cod_info, xrpow) || loop_break(cod_info)); - } - } - } - - if (!status) { - if (gfc.mode_gr == 2) - status = tk.scale_bitcount(cod_info); - else - status = tk.scale_bitcount_lsf(gfc, cod_info); - } - return !status; - } - - /** - * <PRE> - * Function: The outer iteration loop controls the masking conditions - * of all scalefactorbands. It computes the best scalefac and - * global gain. This module calls the inner iteration loop - * - * mt 5/99 completely rewritten to allow for bit reservoir control, - * mid/side channels with L/R or mid/side masking thresholds, - * and chooses best quantization instead of last quantization when - * no distortion free quantization can be found. - * - * added VBR support mt 5/99 - * - * some code shuffle rh 9/00 - * </PRE> - * - * @param l3_xmin - * allowed distortion - * @param xrpow - * coloured magnitudes of spectral - * @param targ_bits - * maximum allowed bits - */ - public final int outer_loop(final LameGlobalFlags gfp, - final GrInfo cod_info, final float[] l3_xmin, float xrpow[], - final int ch, final int targ_bits) { - final LameInternalFlags gfc = gfp.internal_flags; - GrInfo cod_info_w = new GrInfo(); - float save_xrpow[] = new float[576]; - float distort[] = new float[L3Side.SFBMAX]; - CalcNoiseResult best_noise_info = new CalcNoiseResult(); - int better; - CalcNoiseData prev_noise = new CalcNoiseData(); - int best_part2_3_length = 9999999; - boolean bEndOfSearch = false; - boolean bRefine = false; - int best_ggain_pass1 = 0; - - bin_search_StepSize(gfc, cod_info, targ_bits, ch, xrpow); - - if (0 == gfc.noise_shaping) - /* fast mode, no noise shaping, we are ready */ - return 100; /* default noise_info.over_count */ - - /* compute the distortion in this quantization */ - /* coefficients and thresholds both l/r (or both mid/side) */ - qupvt.calc_noise(cod_info, l3_xmin, distort, best_noise_info, - prev_noise); - best_noise_info.bits = cod_info.part2_3_length; - - cod_info_w.assign(cod_info); - int age = 0; - System.arraycopy(xrpow, 0, save_xrpow, 0, 576); - - while (!bEndOfSearch) { - /* BEGIN MAIN LOOP */ - do { - CalcNoiseResult noise_info = new CalcNoiseResult(); - int search_limit; - int maxggain = 255; - - /* - * When quantization with no distorted bands is found, allow up - * to X new unsuccesful tries in serial. This gives us more - * possibilities for different quant_compare modes. Much more - * than 3 makes not a big difference, it is only slower. - */ - - if ((gfc.substep_shaping & 2) != 0) { - search_limit = 20; - } else { - search_limit = 3; - } - - /* - * Check if the last scalefactor band is distorted. in VBR mode - * we can't get rid of the distortion, so quit now and VBR mode - * will try again with more bits. (makes a 10% speed increase, - * the files I tested were binary identical, 2000/05/20 Robert - * Hegemann) distort[] > 1 means noise > allowed noise - */ - if (gfc.sfb21_extra) { - if (distort[cod_info_w.sfbmax] > 1.0) - break; - if (cod_info_w.block_type == Encoder.SHORT_TYPE - && (distort[cod_info_w.sfbmax + 1] > 1.0 || distort[cod_info_w.sfbmax + 2] > 1.0)) - break; - } - - /* try a new scalefactor conbination on cod_info_w */ - if (!balance_noise(gfp, cod_info_w, distort, xrpow, bRefine)) - break; - if (cod_info_w.scalefac_scale != 0) - maxggain = 254; - - /* - * inner_loop starts with the initial quantization step computed - * above and slowly increases until the bits < huff_bits. Thus - * it is important not to start with too large of an inital - * quantization step. Too small is ok, but inner_loop will take - * longer - */ - int huff_bits = targ_bits - cod_info_w.part2_length; - if (huff_bits <= 0) - break; - - /* - * increase quantizer stepsize until needed bits are below - * maximum - */ - while ((cod_info_w.part2_3_length = tk.count_bits(gfc, xrpow, - cod_info_w, prev_noise)) > huff_bits - && cod_info_w.global_gain <= maxggain) - cod_info_w.global_gain++; - - if (cod_info_w.global_gain > maxggain) - break; - - if (best_noise_info.over_count == 0) { - - while ((cod_info_w.part2_3_length = tk.count_bits(gfc, - xrpow, cod_info_w, prev_noise)) > best_part2_3_length - && cod_info_w.global_gain <= maxggain) - cod_info_w.global_gain++; - - if (cod_info_w.global_gain > maxggain) - break; - } - - /* compute the distortion in this quantization */ - qupvt.calc_noise(cod_info_w, l3_xmin, distort, noise_info, - prev_noise); - noise_info.bits = cod_info_w.part2_3_length; - - /* - * check if this quantization is better than our saved - * quantization - */ - if (cod_info.block_type != Encoder.SHORT_TYPE) { - // NORM, START or STOP type - better = gfp.quant_comp; - } else - better = gfp.quant_comp_short; - - better = quant_compare(better, best_noise_info, noise_info, - cod_info_w, distort) ? 1 : 0; - - /* save data so we can restore this quantization later */ - if (better != 0) { - best_part2_3_length = cod_info.part2_3_length; - best_noise_info = noise_info; - cod_info.assign(cod_info_w); - age = 0; - /* save data so we can restore this quantization later */ - /* store for later reuse */ - System.arraycopy(xrpow, 0, save_xrpow, 0, 576); - } else { - /* early stop? */ - if (gfc.full_outer_loop == 0) { - if (++age > search_limit - && best_noise_info.over_count == 0) - break; - if ((gfc.noise_shaping_amp == 3) && bRefine && age > 30) - break; - if ((gfc.noise_shaping_amp == 3) - && bRefine - && (cod_info_w.global_gain - best_ggain_pass1) > 15) - break; - } - } - } while ((cod_info_w.global_gain + cod_info_w.scalefac_scale) < 255); - - if (gfc.noise_shaping_amp == 3) { - if (!bRefine) { - /* refine search */ - cod_info_w.assign(cod_info); - System.arraycopy(save_xrpow, 0, xrpow, 0, 576); - age = 0; - best_ggain_pass1 = cod_info_w.global_gain; - - bRefine = true; - } else { - /* search already refined, stop */ - bEndOfSearch = true; - } - - } else { - bEndOfSearch = true; - } - } - - assert ((cod_info.global_gain + cod_info.scalefac_scale) <= 255); - /* - * finish up - */ - if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh) - /* restore for reuse on next try */ - System.arraycopy(save_xrpow, 0, xrpow, 0, 576); - /* - * do the 'substep shaping' - */ - else if ((gfc.substep_shaping & 1) != 0) - trancate_smallspectrums(gfc, cod_info, l3_xmin, xrpow); - - return best_noise_info.over_count; - } - - /** - * Robert Hegemann 2000-09-06 - * - * update reservoir status after FINAL quantization/bitrate - */ - public final void iteration_finish_one(final LameInternalFlags gfc, - final int gr, final int ch) { - final IIISideInfo l3_side = gfc.l3_side; - final GrInfo cod_info = l3_side.tt[gr][ch]; - - /* - * try some better scalefac storage - */ - tk.best_scalefac_store(gfc, gr, ch, l3_side); - - /* - * best huffman_divide may save some bits too - */ - if (gfc.use_best_huffman == 1) - tk.best_huffman_divide(gfc, cod_info); - - /* - * update reservoir status after FINAL quantization/bitrate - */ - rv.ResvAdjust(gfc, cod_info); - } - - /** - * - * 2000-09-04 Robert Hegemann - * - * @param l3_xmin - * allowed distortion of the scalefactor - * @param xrpow - * coloured magnitudes of spectral values - */ - public final void VBR_encode_granule(final LameGlobalFlags gfp, - GrInfo cod_info, final float[] l3_xmin, float xrpow[], - final int ch, int min_bits, int max_bits) { - final LameInternalFlags gfc = gfp.internal_flags; - GrInfo bst_cod_info = new GrInfo(); - float bst_xrpow[] = new float[576]; - final int Max_bits = max_bits; - int real_bits = max_bits + 1; - int this_bits = (max_bits + min_bits) / 2; - int dbits, over, found = 0; - final boolean sfb21_extra = gfc.sfb21_extra; - - assert (Max_bits <= LameInternalFlags.MAX_BITS_PER_CHANNEL); - Arrays.fill(bst_cod_info.l3_enc, 0); - - /* - * search within round about 40 bits of optimal - */ - do { - assert (this_bits >= min_bits); - assert (this_bits <= max_bits); - assert (min_bits <= max_bits); - - if (this_bits > Max_bits - 42) - gfc.sfb21_extra = false; - else - gfc.sfb21_extra = sfb21_extra; - - over = outer_loop(gfp, cod_info, l3_xmin, xrpow, ch, this_bits); - - /* - * is quantization as good as we are looking for ? in this case: is - * no scalefactor band distorted? - */ - if (over <= 0) { - found = 1; - /* - * now we know it can be done with "real_bits" and maybe we can - * skip some iterations - */ - real_bits = cod_info.part2_3_length; - - /* - * store best quantization so far - */ - bst_cod_info.assign(cod_info); - System.arraycopy(xrpow, 0, bst_xrpow, 0, 576); - - /* - * try with fewer bits - */ - max_bits = real_bits - 32; - dbits = max_bits - min_bits; - this_bits = (max_bits + min_bits) / 2; - } else { - /* - * try with more bits - */ - min_bits = this_bits + 32; - dbits = max_bits - min_bits; - this_bits = (max_bits + min_bits) / 2; - - if (found != 0) { - found = 2; - /* - * start again with best quantization so far - */ - cod_info.assign(bst_cod_info); - System.arraycopy(bst_xrpow, 0, xrpow, 0, 576); - } - } - } while (dbits > 12); - - gfc.sfb21_extra = sfb21_extra; - - /* - * found=0 => nothing found, use last one found=1 => we just found the - * best and left the loop found=2 => we restored a good one and have now - * l3_enc to restore too - */ - if (found == 2) { - System.arraycopy(bst_cod_info.l3_enc, 0, cod_info.l3_enc, 0, 576); - } - assert (cod_info.part2_3_length <= Max_bits); - } - - /** - * Robert Hegemann 2000-09-05 - * - * calculates * how many bits are available for analog silent granules * how - * many bits to use for the lowest allowed bitrate * how many bits each - * bitrate would provide - */ - public final void get_framebits(final LameGlobalFlags gfp, - final int frameBits[]) { - final LameInternalFlags gfc = gfp.internal_flags; - - /* - * always use at least this many bits per granule per channel unless we - * detect analog silence, see below - */ - gfc.bitrate_index = gfc.VBR_min_bitrate; - int bitsPerFrame = bs.getframebits(gfp); - - /* - * bits for analog silence - */ - gfc.bitrate_index = 1; - bitsPerFrame = bs.getframebits(gfp); - - for (int i = 1; i <= gfc.VBR_max_bitrate; i++) { - gfc.bitrate_index = i; - MeanBits mb = new MeanBits(bitsPerFrame); - frameBits[i] = rv.ResvFrameBegin(gfp, mb); - bitsPerFrame = mb.bits; - } - } - - /* RH: this one needs to be overhauled sometime */ - - /** - * <PRE> - * 2000-09-04 Robert Hegemann - * - * * converts LR to MS coding when necessary - * * calculates allowed/adjusted quantization noise amounts - * * detects analog silent frames - * - * some remarks: - * - lower masking depending on Quality setting - * - quality control together with adjusted ATH MDCT scaling - * on lower quality setting allocate more noise from - * ATH masking, and on higher quality setting allocate - * less noise from ATH masking. - * - experiments show that going more than 2dB over GPSYCHO's - * limits ends up in very annoying artefacts - * </PRE> - */ - public final int VBR_old_prepare(final LameGlobalFlags gfp, float pe[][], - final float ms_ener_ratio[], final III_psy_ratio ratio[][], - float l3_xmin[][][], final int frameBits[], final int min_bits[][], - final int max_bits[][], final int bands[][]) { - final LameInternalFlags gfc = gfp.internal_flags; - - float masking_lower_db, adjust = 0.0f; - int analog_silence = 1; - int bits = 0; - - gfc.bitrate_index = gfc.VBR_max_bitrate; - int avg = rv.ResvFrameBegin(gfp, new MeanBits(0)) / gfc.mode_gr; - - get_framebits(gfp, frameBits); - - for (int gr = 0; gr < gfc.mode_gr; gr++) { - int mxb = qupvt.on_pe(gfp, pe, max_bits[gr], avg, gr, 0); - if (gfc.mode_ext == Encoder.MPG_MD_MS_LR) { - ms_convert(gfc.l3_side, gr); - qupvt.reduce_side(max_bits[gr], ms_ener_ratio[gr], avg, mxb); - } - for (int ch = 0; ch < gfc.channels_out; ++ch) { - final GrInfo cod_info = gfc.l3_side.tt[gr][ch]; - - if (cod_info.block_type != Encoder.SHORT_TYPE) { - // NORM, START or STOP type - adjust = 1.28f / (1 + (float) Math - .exp(3.5 - pe[gr][ch] / 300.)) - 0.05f; - masking_lower_db = gfc.PSY.mask_adjust - adjust; - } else { - adjust = 2.56f / (1 + (float) Math - .exp(3.5 - pe[gr][ch] / 300.)) - 0.14f; - masking_lower_db = gfc.PSY.mask_adjust_short - adjust; - } - gfc.masking_lower = (float) Math.pow(10.0, - masking_lower_db * 0.1); - - init_outer_loop(gfc, cod_info); - bands[gr][ch] = qupvt.calc_xmin(gfp, ratio[gr][ch], cod_info, - l3_xmin[gr][ch]); - if (bands[gr][ch] != 0) - analog_silence = 0; - - min_bits[gr][ch] = 126; - - bits += max_bits[gr][ch]; - } - } - for (int gr = 0; gr < gfc.mode_gr; gr++) { - for (int ch = 0; ch < gfc.channels_out; ch++) { - if (bits > frameBits[gfc.VBR_max_bitrate]) { - max_bits[gr][ch] *= frameBits[gfc.VBR_max_bitrate]; - max_bits[gr][ch] /= bits; - } - if (min_bits[gr][ch] > max_bits[gr][ch]) - min_bits[gr][ch] = max_bits[gr][ch]; - - } /* for ch */ - } /* for gr */ - - return analog_silence; - } - - public final void bitpressure_strategy(final LameInternalFlags gfc, - float l3_xmin[][][], final int min_bits[][], final int max_bits[][]) { - for (int gr = 0; gr < gfc.mode_gr; gr++) { - for (int ch = 0; ch < gfc.channels_out; ch++) { - final GrInfo gi = gfc.l3_side.tt[gr][ch]; - float[] pxmin = l3_xmin[gr][ch]; - int pxminPos = 0; - for (int sfb = 0; sfb < gi.psy_lmax; sfb++) - pxmin[pxminPos++] *= 1. + .029 * sfb * sfb - / Encoder.SBMAX_l / Encoder.SBMAX_l; - - if (gi.block_type == Encoder.SHORT_TYPE) { - for (int sfb = gi.sfb_smin; sfb < Encoder.SBMAX_s; sfb++) { - pxmin[pxminPos++] *= 1. + .029 * sfb * sfb - / Encoder.SBMAX_s / Encoder.SBMAX_s; - pxmin[pxminPos++] *= 1. + .029 * sfb * sfb - / Encoder.SBMAX_s / Encoder.SBMAX_s; - pxmin[pxminPos++] *= 1. + .029 * sfb * sfb - / Encoder.SBMAX_s / Encoder.SBMAX_s; - } - } - max_bits[gr][ch] = (int) Math.max(min_bits[gr][ch], - 0.9 * max_bits[gr][ch]); - } - } - } - - public final int VBR_new_prepare(final LameGlobalFlags gfp, float pe[][], - III_psy_ratio ratio[][], float l3_xmin[][][], - final int frameBits[], final int max_bits[][]) { - final LameInternalFlags gfc = gfp.internal_flags; - - int analog_silence = 1; - int avg = 0, bits = 0; - int maximum_framebits; - - if (!gfp.free_format) { - gfc.bitrate_index = gfc.VBR_max_bitrate; - - MeanBits mb = new MeanBits(avg); - rv.ResvFrameBegin(gfp, mb); - avg = mb.bits; - - get_framebits(gfp, frameBits); - maximum_framebits = frameBits[gfc.VBR_max_bitrate]; - } else { - gfc.bitrate_index = 0; - MeanBits mb = new MeanBits(avg); - maximum_framebits = rv.ResvFrameBegin(gfp, mb); - avg = mb.bits; - frameBits[0] = maximum_framebits; - } - - for (int gr = 0; gr < gfc.mode_gr; gr++) { - qupvt.on_pe(gfp, pe, max_bits[gr], avg, gr, 0); - if (gfc.mode_ext == Encoder.MPG_MD_MS_LR) { - ms_convert(gfc.l3_side, gr); - } - for (int ch = 0; ch < gfc.channels_out; ++ch) { - final GrInfo cod_info = gfc.l3_side.tt[gr][ch]; - - gfc.masking_lower = (float) Math.pow(10.0, - gfc.PSY.mask_adjust * 0.1); - - init_outer_loop(gfc, cod_info); - if (0 != qupvt.calc_xmin(gfp, ratio[gr][ch], cod_info, - l3_xmin[gr][ch])) - analog_silence = 0; - - bits += max_bits[gr][ch]; - } - } - for (int gr = 0; gr < gfc.mode_gr; gr++) { - for (int ch = 0; ch < gfc.channels_out; ch++) { - if (bits > maximum_framebits) { - max_bits[gr][ch] *= maximum_framebits; - max_bits[gr][ch] /= bits; - } - - } /* for ch */ - } /* for gr */ - - return analog_silence; - } - - /** - * calculates target bits for ABR encoding - * - * mt 2000/05/31 - */ - public final void calc_target_bits(final LameGlobalFlags gfp, float pe[][], - final float ms_ener_ratio[], final int targ_bits[][], - final int[] analog_silence_bits, final int[] max_frame_bits) { - final LameInternalFlags gfc = gfp.internal_flags; - final IIISideInfo l3_side = gfc.l3_side; - float res_factor; - int gr, ch, totbits, mean_bits = 0; - - gfc.bitrate_index = gfc.VBR_max_bitrate; - MeanBits mb = new MeanBits(mean_bits); - max_frame_bits[0] = rv.ResvFrameBegin(gfp, mb); - mean_bits = mb.bits; - - gfc.bitrate_index = 1; - mean_bits = bs.getframebits(gfp) - gfc.sideinfo_len * 8; - analog_silence_bits[0] = mean_bits / (gfc.mode_gr * gfc.channels_out); - - mean_bits = gfp.VBR_mean_bitrate_kbps * gfp.framesize * 1000; - if ((gfc.substep_shaping & 1) != 0) - mean_bits *= 1.09; - mean_bits /= gfp.out_samplerate; - mean_bits -= gfc.sideinfo_len * 8; - mean_bits /= (gfc.mode_gr * gfc.channels_out); - - /** - * <PRE> - * res_factor is the percentage of the target bitrate that should - * be used on average. the remaining bits are added to the - * bitreservoir and used for difficult to encode frames. - * - * Since we are tracking the average bitrate, we should adjust - * res_factor "on the fly", increasing it if the average bitrate - * is greater than the requested bitrate, and decreasing it - * otherwise. Reasonable ranges are from .9 to 1.0 - * - * Until we get the above suggestion working, we use the following - * tuning: - * compression ratio res_factor - * 5.5 (256kbps) 1.0 no need for bitreservoir - * 11 (128kbps) .93 7% held for reservoir - * - * with linear interpolation for other values. - * </PRE> - */ - res_factor = .93f + .07f * (11.0f - gfp.compression_ratio) - / (11.0f - 5.5f); - if (res_factor < .90) - res_factor = .90f; - if (res_factor > 1.00) - res_factor = 1.00f; - - for (gr = 0; gr < gfc.mode_gr; gr++) { - int sum = 0; - for (ch = 0; ch < gfc.channels_out; ch++) { - targ_bits[gr][ch] = (int) (res_factor * mean_bits); - - if (pe[gr][ch] > 700) { - int add_bits = (int) ((pe[gr][ch] - 700) / 1.4); - - final GrInfo cod_info = l3_side.tt[gr][ch]; - targ_bits[gr][ch] = (int) (res_factor * mean_bits); - - /* short blocks use a little extra, no matter what the pe */ - if (cod_info.block_type == Encoder.SHORT_TYPE) { - if (add_bits < mean_bits / 2) - add_bits = mean_bits / 2; - } - /* at most increase bits by 1.5*average */ - if (add_bits > mean_bits * 3 / 2) - add_bits = mean_bits * 3 / 2; - else if (add_bits < 0) - add_bits = 0; - - targ_bits[gr][ch] += add_bits; - } - if (targ_bits[gr][ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL) { - targ_bits[gr][ch] = LameInternalFlags.MAX_BITS_PER_CHANNEL; - } - sum += targ_bits[gr][ch]; - } /* for ch */ - if (sum > LameInternalFlags.MAX_BITS_PER_GRANULE) { - for (ch = 0; ch < gfc.channels_out; ++ch) { - targ_bits[gr][ch] *= LameInternalFlags.MAX_BITS_PER_GRANULE; - targ_bits[gr][ch] /= sum; - } - } - } /* for gr */ - - if (gfc.mode_ext == Encoder.MPG_MD_MS_LR) - for (gr = 0; gr < gfc.mode_gr; gr++) { - qupvt.reduce_side(targ_bits[gr], ms_ener_ratio[gr], mean_bits - * gfc.channels_out, - LameInternalFlags.MAX_BITS_PER_GRANULE); - } - - /* - * sum target bits - */ - totbits = 0; - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - if (targ_bits[gr][ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL) - targ_bits[gr][ch] = LameInternalFlags.MAX_BITS_PER_CHANNEL; - totbits += targ_bits[gr][ch]; - } - } - - /* - * repartion target bits if needed - */ - if (totbits > max_frame_bits[0]) { - for (gr = 0; gr < gfc.mode_gr; gr++) { - for (ch = 0; ch < gfc.channels_out; ch++) { - targ_bits[gr][ch] *= max_frame_bits[0]; - targ_bits[gr][ch] /= totbits; - } - } - } - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/QuantizePVT.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/QuantizePVT.java deleted file mode 100644 index 582def417..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/QuantizePVT.java +++ /dev/null @@ -1,1009 +0,0 @@ -/* - * quantize_pvt source file - * - * Copyright (c) 1999-2002 Takehiro Tominaga - * Copyright (c) 2000-2002 Robert Hegemann - * Copyright (c) 2001 Naoki Shibata - * Copyright (c) 2002-2005 Gabriel Bouvigne - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: QuantizePVT.js,v 1.24 2011/05/24 20:48:06 kenchis Exp $ */ -package mp3; - - - -public class QuantizePVT { - - Takehiro tak; - Reservoir rv; - PsyModel psy; - - public final void setModules(Takehiro tk, Reservoir rv, PsyModel psy) { - this.tak = tk; - this.rv = rv; - this.psy = psy; - } - - public final float POW20(final int x) { - assert (0 <= (x + QuantizePVT.Q_MAX2) && x < QuantizePVT.Q_MAX); - return pow20[x + QuantizePVT.Q_MAX2]; - } - - public final float IPOW20(final int x) { - assert (0 <= x && x < QuantizePVT.Q_MAX); - return ipow20[x]; - } - - /** - * smallest such that 1.0+DBL_EPSILON != 1.0 - */ - private static final float DBL_EPSILON = 2.2204460492503131e-016f; - - /** - * ix always <= 8191+15. see count_bits() - */ - public static final int IXMAX_VAL = 8206; - - private static final int PRECALC_SIZE = (IXMAX_VAL + 2); - - private static final int Q_MAX =(256+1); - - /** - * <CODE> - * minimum possible number of - * -cod_info.global_gain + ((scalefac[] + (cod_info.preflag ? pretab[sfb] : 0)) - * << (cod_info.scalefac_scale + 1)) + cod_info.subblock_gain[cod_info.window[sfb]] * 8; - * - * for long block, 0+((15+3)<<2) = 18*4 = 72 - * for short block, 0+(15<<2)+7*8 = 15*4+56 = 116 - * </CODE> - */ - public static final int Q_MAX2 = 116; - - public static final int LARGE_BITS =100000; - - /** - * Assuming dynamic range=96dB, this value should be 92 - */ - private static final int NSATHSCALE = 100; - - /** - * The following table is used to implement the scalefactor partitioning for - * MPEG2 as described in section 2.4.3.2 of the IS. The indexing corresponds - * to the way the tables are presented in the IS: - * - * [table_number][row_in_table][column of nr_of_sfb] - */ - public final int nr_of_sfb_block[][][] = new int[][][] { - { { 6, 5, 5, 5 }, { 9, 9, 9, 9 }, { 6, 9, 9, 9 } }, - { { 6, 5, 7, 3 }, { 9, 9, 12, 6 }, { 6, 9, 12, 6 } }, - { { 11, 10, 0, 0 }, { 18, 18, 0, 0 }, { 15, 18, 0, 0 } }, - { { 7, 7, 7, 0 }, { 12, 12, 12, 0 }, { 6, 15, 12, 0 } }, - { { 6, 6, 6, 3 }, { 12, 9, 9, 6 }, { 6, 12, 9, 6 } }, - { { 8, 8, 5, 0 }, { 15, 12, 9, 0 }, { 6, 18, 9, 0 } } }; - - /** - * Table B.6: layer3 preemphasis - */ - public final int pretab[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, - 2, 2, 3, 3, 3, 2, 0 }; - - /** - * Here are MPEG1 Table B.8 and MPEG2 Table B.1 -- Layer III scalefactor - * bands. <BR> - * Index into this using a method such as:<BR> - * idx = fr_ps.header.sampling_frequency + (fr_ps.header.version * 3) - */ - public final ScaleFac sfBandIndex[] = { - // Table B.2.b: 22.05 kHz - new ScaleFac(new int[]{0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, - 522, 576}, - new int[]{0, 4, 8, 12, 18, 24, 32, 42, 56, 74, 100, 132, 174, 192} - , new int[]{0, 0, 0, 0, 0, 0, 0} // sfb21 pseudo sub bands - , new int[]{0, 0, 0, 0, 0, 0, 0} // sfb12 pseudo sub bands - ), - /* Table B.2.c: 24 kHz */ /* docs: 332. mpg123(broken): 330 */ - new ScaleFac(new int[]{0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 114, 136, 162, 194, 232, 278, 332, 394, 464, - 540, 576}, - new int[]{0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 136, 180, 192} - , new int[]{0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ - , new int[]{0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ - ), - /* Table B.2.a: 16 kHz */ - new ScaleFac(new int[]{0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, - 522, 576}, - new int[]{0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192} - , new int[]{0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ - , new int[]{0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ - ), - /* Table B.8.b: 44.1 kHz */ - new ScaleFac(new int[]{0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418, - 576}, - new int[]{0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84, 106, 136, 192} - , new int[]{0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ - , new int[]{0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ - ), - /* Table B.8.c: 48 kHz */ - new ScaleFac(new int[]{0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330, 384, - 576}, - new int[]{0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80, 100, 126, 192} - , new int[]{0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ - , new int[]{0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ - ), - /* Table B.8.a: 32 kHz */ - new ScaleFac(new int[]{0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448, 550, - 576}, - new int[]{0, 4, 8, 12, 16, 22, 30, 42, 58, 78, 104, 138, 180, 192} - , new int[]{0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ - , new int[]{0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ - ), - /* MPEG-2.5 11.025 kHz */ - new ScaleFac(new int[]{0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, - 522, 576}, - new int[]{0 / 3, 12 / 3, 24 / 3, 36 / 3, 54 / 3, 78 / 3, 108 / 3, 144 / 3, 186 / 3, 240 / 3, 312 / 3, - 402 / 3, 522 / 3, 576 / 3} - , new int[]{0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ - , new int[]{0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ - ), - /* MPEG-2.5 12 kHz */ - new ScaleFac(new int[]{0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, - 522, 576}, - new int[]{0 / 3, 12 / 3, 24 / 3, 36 / 3, 54 / 3, 78 / 3, 108 / 3, 144 / 3, 186 / 3, 240 / 3, 312 / 3, - 402 / 3, 522 / 3, 576 / 3} - , new int[]{0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ - , new int[]{0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ - ), - /* MPEG-2.5 8 kHz */ - new ScaleFac(new int[]{0, 12, 24, 36, 48, 60, 72, 88, 108, 132, 160, 192, 232, 280, 336, 400, 476, 566, 568, 570, - 572, 574, 576}, - new int[]{0 / 3, 24 / 3, 48 / 3, 72 / 3, 108 / 3, 156 / 3, 216 / 3, 288 / 3, 372 / 3, 480 / 3, 486 / 3, - 492 / 3, 498 / 3, 576 / 3} - , new int[]{0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ - , new int[]{0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ - ) - }; - - public float pow20[] = new float[Q_MAX + Q_MAX2 + 1]; - public float ipow20[] = new float[Q_MAX]; - public float pow43[] = new float[PRECALC_SIZE]; - - public float adj43[] = new float[PRECALC_SIZE]; - - /** - * <PRE> - * compute the ATH for each scalefactor band cd range: 0..96db - * - * Input: 3.3kHz signal 32767 amplitude (3.3kHz is where ATH is smallest = - * -5db) longblocks: sfb=12 en0/bw=-11db max_en0 = 1.3db shortblocks: sfb=5 - * -9db 0db - * - * Input: 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated) longblocks: amp=1 - * sfb=12 en0/bw=-103 db max_en0 = -92db amp=32767 sfb=12 -12 db -1.4db - * - * Input: 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated) shortblocks: amp=1 - * sfb=5 en0/bw= -99 -86 amp=32767 sfb=5 -9 db 4db - * - * - * MAX energy of largest wave at 3.3kHz = 1db AVE energy of largest wave at - * 3.3kHz = -11db Let's take AVE: -11db = maximum signal in sfb=12. Dynamic - * range of CD: 96db. Therefor energy of smallest audible wave in sfb=12 = - * -11 - 96 = -107db = ATH at 3.3kHz. - * - * ATH formula for this wave: -5db. To adjust to LAME scaling, we need ATH = - * ATH_formula - 103 (db) ATH = ATH * 2.5e-10 (ener) - * </PRE> - */ - private float ATHmdct(final LameGlobalFlags gfp, final float f) { - float ath = psy.ATHformula(f, gfp); - - ath -= NSATHSCALE; - - /* modify the MDCT scaling for the ATH and convert to energy */ - ath = (float) Math.pow(10.0, ath / 10.0 + gfp.ATHlower); - return ath; - } - - private void compute_ath(final LameGlobalFlags gfp) { - final float[] ATH_l = gfp.internal_flags.ATH.l; - final float[] ATH_psfb21 = gfp.internal_flags.ATH.psfb21; - final float[] ATH_s = gfp.internal_flags.ATH.s; - final float[] ATH_psfb12 = gfp.internal_flags.ATH.psfb12; - final LameInternalFlags gfc = gfp.internal_flags; - final float samp_freq = gfp.out_samplerate; - - for (int sfb = 0; sfb < Encoder.SBMAX_l; sfb++) { - int start = gfc.scalefac_band.l[sfb]; - int end = gfc.scalefac_band.l[sfb + 1]; - ATH_l[sfb] = Float.MAX_VALUE; - for (int i = start; i < end; i++) { - final float freq = i * samp_freq / (2 * 576); - float ATH_f = ATHmdct(gfp, freq); /* freq in kHz */ - ATH_l[sfb] = Math.min(ATH_l[sfb], ATH_f); - } - } - - for (int sfb = 0; sfb < Encoder.PSFB21; sfb++) { - int start = gfc.scalefac_band.psfb21[sfb]; - int end = gfc.scalefac_band.psfb21[sfb + 1]; - ATH_psfb21[sfb] = Float.MAX_VALUE; - for (int i = start; i < end; i++) { - final float freq = i * samp_freq / (2 * 576); - float ATH_f = ATHmdct(gfp, freq); /* freq in kHz */ - ATH_psfb21[sfb] = Math.min(ATH_psfb21[sfb], ATH_f); - } - } - - for (int sfb = 0; sfb < Encoder.SBMAX_s; sfb++) { - int start = gfc.scalefac_band.s[sfb]; - int end = gfc.scalefac_band.s[sfb + 1]; - ATH_s[sfb] = Float.MAX_VALUE; - for (int i = start; i < end; i++) { - final float freq = i * samp_freq / (2 * 192); - float ATH_f = ATHmdct(gfp, freq); /* freq in kHz */ - ATH_s[sfb] = Math.min(ATH_s[sfb], ATH_f); - } - ATH_s[sfb] *= (gfc.scalefac_band.s[sfb + 1] - gfc.scalefac_band.s[sfb]); - } - - for (int sfb = 0; sfb < Encoder.PSFB12; sfb++) { - int start = gfc.scalefac_band.psfb12[sfb]; - int end = gfc.scalefac_band.psfb12[sfb + 1]; - ATH_psfb12[sfb] = Float.MAX_VALUE; - for (int i = start; i < end; i++) { - final float freq = i * samp_freq / (2 * 192); - float ATH_f = ATHmdct(gfp, freq); /* freq in kHz */ - ATH_psfb12[sfb] = Math.min(ATH_psfb12[sfb], ATH_f); - } - /* not sure about the following */ - ATH_psfb12[sfb] *= (gfc.scalefac_band.s[13] - gfc.scalefac_band.s[12]); - } - - /* - * no-ATH mode: reduce ATH to -200 dB - */ - if (gfp.noATH) { - for (int sfb = 0; sfb < Encoder.SBMAX_l; sfb++) { - ATH_l[sfb] = 1E-20f; - } - for (int sfb = 0; sfb < Encoder.PSFB21; sfb++) { - ATH_psfb21[sfb] = 1E-20f; - } - for (int sfb = 0; sfb < Encoder.SBMAX_s; sfb++) { - ATH_s[sfb] = 1E-20f; - } - for (int sfb = 0; sfb < Encoder.PSFB12; sfb++) { - ATH_psfb12[sfb] = 1E-20f; - } - } - - /* - * work in progress, don't rely on it too much - */ - gfc.ATH.floor = 10.f * (float) Math.log10(ATHmdct(gfp, -1.f)); - } - - /** - * initialization for iteration_loop - */ - public final void iteration_init(final LameGlobalFlags gfp) { - final LameInternalFlags gfc = gfp.internal_flags; - final IIISideInfo l3_side = gfc.l3_side; - int i; - - if (gfc.iteration_init_init == 0) { - gfc.iteration_init_init = 1; - - l3_side.main_data_begin = 0; - compute_ath(gfp); - - pow43[0] = 0.0f; - for (i = 1; i < PRECALC_SIZE; i++) - pow43[i] = (float) Math.pow((float) i, 4.0 / 3.0); - - for (i = 0; i < PRECALC_SIZE - 1; i++) - adj43[i] = (float) ((i + 1) - Math.pow( - 0.5 * (pow43[i] + pow43[i + 1]), 0.75)); - adj43[i] = 0.5f; - - for (i = 0; i < Q_MAX; i++) - ipow20[i] = (float) Math.pow(2.0, (i - 210) * -0.1875); - for (i = 0; i <= Q_MAX + Q_MAX2; i++) - pow20[i] = (float) Math.pow(2.0, (i - 210 - Q_MAX2) * 0.25); - - tak.huffman_init(gfc); - - { - float bass, alto, treble, sfb21; - - i = (gfp.exp_nspsytune >> 2) & 63; - if (i >= 32) - i -= 64; - bass = (float) Math.pow(10, i / 4.0 / 10.0); - - i = (gfp.exp_nspsytune >> 8) & 63; - if (i >= 32) - i -= 64; - alto = (float) Math.pow(10, i / 4.0 / 10.0); - - i = (gfp.exp_nspsytune >> 14) & 63; - if (i >= 32) - i -= 64; - treble = (float) Math.pow(10, i / 4.0 / 10.0); - - /* - * to be compatible with Naoki's original code, the next 6 bits - * define only the amount of changing treble for sfb21 - */ - i = (gfp.exp_nspsytune >> 20) & 63; - if (i >= 32) - i -= 64; - sfb21 = treble * (float) Math.pow(10, i / 4.0 / 10.0); - for (i = 0; i < Encoder.SBMAX_l; i++) { - float f; - if (i <= 6) - f = bass; - else if (i <= 13) - f = alto; - else if (i <= 20) - f = treble; - else - f = sfb21; - - gfc.nsPsy.longfact[i] = f; - } - for (i = 0; i < Encoder.SBMAX_s; i++) { - float f; - if (i <= 5) - f = bass; - else if (i <= 10) - f = alto; - else if (i <= 11) - f = treble; - else - f = sfb21; - - gfc.nsPsy.shortfact[i] = f; - } - } - } - } - - /** - * allocate bits among 2 channels based on PE<BR> - * mt 6/99<BR> - * bugfixes rh 8/01: often allocated more than the allowed 4095 bits - */ - public final int on_pe(final LameGlobalFlags gfp, float pe[][], - int targ_bits[], int mean_bits, int gr, int cbr) { - final LameInternalFlags gfc = gfp.internal_flags; - int tbits = 0, bits; - int add_bits[] = new int[2]; - int ch; - - /* allocate targ_bits for granule */ - MeanBits mb = new MeanBits(tbits); - int extra_bits = rv.ResvMaxBits(gfp, mean_bits, mb, cbr); - tbits = mb.bits; - /* maximum allowed bits for this granule */ - int max_bits = tbits + extra_bits; - if (max_bits > LameInternalFlags.MAX_BITS_PER_GRANULE) { - // hard limit per granule - max_bits = LameInternalFlags.MAX_BITS_PER_GRANULE; - } - for (bits = 0, ch = 0; ch < gfc.channels_out; ++ch) { - /****************************************************************** - * allocate bits for each channel - ******************************************************************/ - targ_bits[ch] = Math.min(LameInternalFlags.MAX_BITS_PER_CHANNEL, - tbits / gfc.channels_out); - - add_bits[ch] = (int) (targ_bits[ch] * pe[gr][ch] / 700.0 - targ_bits[ch]); - - /* at most increase bits by 1.5*average */ - if (add_bits[ch] > mean_bits * 3 / 4) - add_bits[ch] = mean_bits * 3 / 4; - if (add_bits[ch] < 0) - add_bits[ch] = 0; - - if (add_bits[ch] + targ_bits[ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL) - add_bits[ch] = Math.max(0, - LameInternalFlags.MAX_BITS_PER_CHANNEL - targ_bits[ch]); - - bits += add_bits[ch]; - } - if (bits > extra_bits) { - for (ch = 0; ch < gfc.channels_out; ++ch) { - add_bits[ch] = extra_bits * add_bits[ch] / bits; - } - } - - for (ch = 0; ch < gfc.channels_out; ++ch) { - targ_bits[ch] += add_bits[ch]; - extra_bits -= add_bits[ch]; - } - - for (bits = 0, ch = 0; ch < gfc.channels_out; ++ch) { - bits += targ_bits[ch]; - } - if (bits > LameInternalFlags.MAX_BITS_PER_GRANULE) { - int sum = 0; - for (ch = 0; ch < gfc.channels_out; ++ch) { - targ_bits[ch] *= LameInternalFlags.MAX_BITS_PER_GRANULE; - targ_bits[ch] /= bits; - sum += targ_bits[ch]; - } - assert (sum <= LameInternalFlags.MAX_BITS_PER_GRANULE); - } - - return max_bits; - } - - public final void reduce_side(final int targ_bits[], - final float ms_ener_ratio, final int mean_bits, final int max_bits) { - assert (max_bits <= LameInternalFlags.MAX_BITS_PER_GRANULE); - assert (targ_bits[0] + targ_bits[1] <= LameInternalFlags.MAX_BITS_PER_GRANULE); - - /* - * ms_ener_ratio = 0: allocate 66/33 mid/side fac=.33 ms_ener_ratio =.5: - * allocate 50/50 mid/side fac= 0 - */ - /* 75/25 split is fac=.5 */ - float fac = .33f * (.5f - ms_ener_ratio) / .5f; - if (fac < 0) - fac = 0; - if (fac > .5) - fac = .5f; - - /* number of bits to move from side channel to mid channel */ - /* move_bits = fac*targ_bits[1]; */ - int move_bits = (int) (fac * .5 * (targ_bits[0] + targ_bits[1])); - - if (move_bits > LameInternalFlags.MAX_BITS_PER_CHANNEL - targ_bits[0]) { - move_bits = LameInternalFlags.MAX_BITS_PER_CHANNEL - targ_bits[0]; - } - if (move_bits < 0) - move_bits = 0; - - if (targ_bits[1] >= 125) { - /* dont reduce side channel below 125 bits */ - if (targ_bits[1] - move_bits > 125) { - - /* if mid channel already has 2x more than average, dont bother */ - /* mean_bits = bits per granule (for both channels) */ - if (targ_bits[0] < mean_bits) - targ_bits[0] += move_bits; - targ_bits[1] -= move_bits; - } else { - targ_bits[0] += targ_bits[1] - 125; - targ_bits[1] = 125; - } - } - - move_bits = targ_bits[0] + targ_bits[1]; - if (move_bits > max_bits) { - targ_bits[0] = (max_bits * targ_bits[0]) / move_bits; - targ_bits[1] = (max_bits * targ_bits[1]) / move_bits; - } - assert (targ_bits[0] <= LameInternalFlags.MAX_BITS_PER_CHANNEL); - assert (targ_bits[1] <= LameInternalFlags.MAX_BITS_PER_CHANNEL); - assert (targ_bits[0] + targ_bits[1] <= LameInternalFlags.MAX_BITS_PER_GRANULE); - } - - /** - * Robert Hegemann 2001-04-27: - * this adjusts the ATH, keeping the original noise floor - * affects the higher frequencies more than the lower ones - */ - public final float athAdjust(final float a, final float x, - final float athFloor) { - /* - * work in progress - */ - final float o = 90.30873362f; - final float p = 94.82444863f; - float u = Util.FAST_LOG10_X(x, 10.0f); - final float v = a * a; - float w = 0.0f; - u -= athFloor; /* undo scaling */ - if (v > 1E-20) - w = 1.f + Util.FAST_LOG10_X(v, 10.0f / o); - if (w < 0) - w = 0.f; - u *= w; - u += athFloor + o - p; /* redo scaling */ - - return (float) Math.pow(10., 0.1 * u); - } - - /** - * Calculate the allowed distortion for each scalefactor band, as determined - * by the psychoacoustic model. xmin(sb) = ratio(sb) * en(sb) / bw(sb) - * - * returns number of sfb's with energy > ATH - */ - public final int calc_xmin(final LameGlobalFlags gfp, - final III_psy_ratio ratio, final GrInfo cod_info, - final float[] pxmin) { - int pxminPos = 0; - final LameInternalFlags gfc = gfp.internal_flags; - int gsfb, j = 0, ath_over = 0; - final ATH ATH = gfc.ATH; - final float[] xr = cod_info.xr; - final int enable_athaa_fix = (gfp.VBR == VbrMode.vbr_mtrh) ? 1 : 0; - float masking_lower = gfc.masking_lower; - - if (gfp.VBR == VbrMode.vbr_mtrh || gfp.VBR == VbrMode.vbr_mt) { - /* was already done in PSY-Model */ - masking_lower = 1.0f; - } - - for (gsfb = 0; gsfb < cod_info.psy_lmax; gsfb++) { - float en0, xmin; - float rh1, rh2; - int width, l; - - if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh) - xmin = athAdjust(ATH.adjust, ATH.l[gsfb], ATH.floor); - else - xmin = ATH.adjust * ATH.l[gsfb]; - - width = cod_info.width[gsfb]; - rh1 = xmin / width; - rh2 = DBL_EPSILON; - l = width >> 1; - en0 = 0.0f; - do { - float xa, xb; - xa = xr[j] * xr[j]; - en0 += xa; - rh2 += (xa < rh1) ? xa : rh1; - j++; - xb = xr[j] * xr[j]; - en0 += xb; - rh2 += (xb < rh1) ? xb : rh1; - j++; - } while (--l > 0); - if (en0 > xmin) - ath_over++; - - if (gsfb == Encoder.SBPSY_l) { - float x = xmin * gfc.nsPsy.longfact[gsfb]; - if (rh2 < x) { - rh2 = x; - } - } - if (enable_athaa_fix != 0) { - xmin = rh2; - } - if (!gfp.ATHonly) { - final float e = ratio.en.l[gsfb]; - if (e > 0.0f) { - float x; - x = en0 * ratio.thm.l[gsfb] * masking_lower / e; - if (enable_athaa_fix != 0) - x *= gfc.nsPsy.longfact[gsfb]; - if (xmin < x) - xmin = x; - } - } - if (enable_athaa_fix != 0) - pxmin[pxminPos++] = xmin; - else - pxmin[pxminPos++] = xmin * gfc.nsPsy.longfact[gsfb]; - } /* end of long block loop */ - - /* use this function to determine the highest non-zero coeff */ - int max_nonzero = 575; - if (cod_info.block_type != Encoder.SHORT_TYPE) { - // NORM, START or STOP type, but not SHORT - int k = 576; - while (k-- != 0 && BitStream.EQ(xr[k], 0)) { - max_nonzero = k; - } - } - cod_info.max_nonzero_coeff = max_nonzero; - - for (int sfb = cod_info.sfb_smin; gsfb < cod_info.psymax; sfb++, gsfb += 3) { - int width, b; - float tmpATH; - if (gfp.VBR == VbrMode.vbr_rh || gfp.VBR == VbrMode.vbr_mtrh) - tmpATH = athAdjust(ATH.adjust, ATH.s[sfb], ATH.floor); - else - tmpATH = ATH.adjust * ATH.s[sfb]; - - width = cod_info.width[gsfb]; - for (b = 0; b < 3; b++) { - float en0 = 0.0f, xmin; - float rh1, rh2; - int l = width >> 1; - - rh1 = tmpATH / width; - rh2 = DBL_EPSILON; - do { - float xa, xb; - xa = xr[j] * xr[j]; - en0 += xa; - rh2 += (xa < rh1) ? xa : rh1; - j++; - xb = xr[j] * xr[j]; - en0 += xb; - rh2 += (xb < rh1) ? xb : rh1; - j++; - } while (--l > 0); - if (en0 > tmpATH) - ath_over++; - if (sfb == Encoder.SBPSY_s) { - float x = tmpATH * gfc.nsPsy.shortfact[sfb]; - if (rh2 < x) { - rh2 = x; - } - } - if (enable_athaa_fix != 0) - xmin = rh2; - else - xmin = tmpATH; - - if (!gfp.ATHonly && !gfp.ATHshort) { - final float e = ratio.en.s[sfb][b]; - if (e > 0.0f) { - float x; - x = en0 * ratio.thm.s[sfb][b] * masking_lower / e; - if (enable_athaa_fix != 0) - x *= gfc.nsPsy.shortfact[sfb]; - if (xmin < x) - xmin = x; - } - } - if (enable_athaa_fix != 0) - pxmin[pxminPos++] = xmin; - else - pxmin[pxminPos++] = xmin * gfc.nsPsy.shortfact[sfb]; - } /* b */ - if (gfp.useTemporal) { - if (pxmin[pxminPos - 3] > pxmin[pxminPos - 3 + 1]) - pxmin[pxminPos - 3 + 1] += (pxmin[pxminPos - 3] - pxmin[pxminPos - 3 + 1]) - * gfc.decay; - if (pxmin[pxminPos - 3 + 1] > pxmin[pxminPos - 3 + 2]) - pxmin[pxminPos - 3 + 2] += (pxmin[pxminPos - 3 + 1] - pxmin[pxminPos - 3 + 2]) - * gfc.decay; - } - } /* end of short block sfb loop */ - - return ath_over; - } - - private static class StartLine { - public StartLine(final int j) { - s = j; - } - - int s; - } - - private float calc_noise_core(final GrInfo cod_info, - final StartLine startline, int l, final float step) { - float noise = 0; - int j = startline.s; - final int[] ix = cod_info.l3_enc; - - if (j > cod_info.count1) { - while ((l--) != 0) { - float temp; - temp = cod_info.xr[j]; - j++; - noise += temp * temp; - temp = cod_info.xr[j]; - j++; - noise += temp * temp; - } - } else if (j > cod_info.big_values) { - float ix01[] = new float[2]; - ix01[0] = 0; - ix01[1] = step; - while ((l--) != 0) { - float temp; - temp = Math.abs(cod_info.xr[j]) - ix01[ix[j]]; - j++; - noise += temp * temp; - temp = Math.abs(cod_info.xr[j]) - ix01[ix[j]]; - j++; - noise += temp * temp; - } - } else { - while ((l--) != 0) { - float temp; - temp = Math.abs(cod_info.xr[j]) - pow43[ix[j]] * step; - j++; - noise += temp * temp; - temp = Math.abs(cod_info.xr[j]) - pow43[ix[j]] * step; - j++; - noise += temp * temp; - } - } - - startline.s = j; - return noise; - } - - /** - * <PRE> - * -oo dB => -1.00 - * - 6 dB => -0.97 - * - 3 dB => -0.80 - * - 2 dB => -0.64 - * - 1 dB => -0.38 - * 0 dB => 0.00 - * + 1 dB => +0.49 - * + 2 dB => +1.06 - * + 3 dB => +1.68 - * + 6 dB => +3.69 - * +10 dB => +6.45 - * </PRE> - */ - public final int calc_noise(final GrInfo cod_info, - final float[] l3_xmin, final float[] distort, - final CalcNoiseResult res, final CalcNoiseData prev_noise) { - int distortPos = 0; - int l3_xminPos = 0; - int sfb, l, over = 0; - float over_noise_db = 0; - /* 0 dB relative to masking */ - float tot_noise_db = 0; - /* -200 dB relative to masking */ - float max_noise = -20.0f; - int j = 0; - final int[] scalefac = cod_info.scalefac; - int scalefacPos = 0; - - res.over_SSD = 0; - - for (sfb = 0; sfb < cod_info.psymax; sfb++) { - final int s = cod_info.global_gain - - (((scalefac[scalefacPos++]) + (cod_info.preflag != 0 ? pretab[sfb] - : 0)) << (cod_info.scalefac_scale + 1)) - - cod_info.subblock_gain[cod_info.window[sfb]] * 8; - float noise = 0.0f; - - if (prev_noise != null && (prev_noise.step[sfb] == s)) { - - /* use previously computed values */ - noise = prev_noise.noise[sfb]; - j += cod_info.width[sfb]; - distort[distortPos++] = noise / l3_xmin[l3_xminPos++]; - - noise = prev_noise.noise_log[sfb]; - - } else { - final float step = POW20(s); - l = cod_info.width[sfb] >> 1; - - if ((j + cod_info.width[sfb]) > cod_info.max_nonzero_coeff) { - int usefullsize; - usefullsize = cod_info.max_nonzero_coeff - j + 1; - - if (usefullsize > 0) - l = usefullsize >> 1; - else - l = 0; - } - - StartLine sl = new StartLine(j); - noise = calc_noise_core(cod_info, sl, l, step); - j = sl.s; - - if (prev_noise != null) { - /* save noise values */ - prev_noise.step[sfb] = s; - prev_noise.noise[sfb] = noise; - } - - noise = distort[distortPos++] = noise / l3_xmin[l3_xminPos++]; - - /* multiplying here is adding in dB, but can overflow */ - noise = Util.FAST_LOG10((float) Math.max(noise, 1E-20)); - - if (prev_noise != null) { - /* save noise values */ - prev_noise.noise_log[sfb] = noise; - } - } - - if (prev_noise != null) { - /* save noise values */ - prev_noise.global_gain = cod_info.global_gain; - } - - tot_noise_db += noise; - - if (noise > 0.0) { - int tmp; - - tmp = Math.max((int) (noise * 10 + .5), 1); - res.over_SSD += tmp * tmp; - - over++; - /* multiplying here is adding in dB -but can overflow */ - /* over_noise *= noise; */ - over_noise_db += noise; - } - max_noise = Math.max(max_noise, noise); - - } - - res.over_count = over; - res.tot_noise = tot_noise_db; - res.over_noise = over_noise_db; - res.max_noise = max_noise; - - return over; - } - - /** - * updates plotting data - * - * Mark Taylor 2000-??-?? - * - * Robert Hegemann: moved noise/distortion calc into it - */ - private void set_pinfo(final LameGlobalFlags gfp, - final GrInfo cod_info, final III_psy_ratio ratio, - final int gr, final int ch) { - final LameInternalFlags gfc = gfp.internal_flags; - int sfb, sfb2; - int l; - float en0, en1; - float ifqstep = (cod_info.scalefac_scale == 0) ? .5f : 1.0f; - int[] scalefac = cod_info.scalefac; - - float l3_xmin[] = new float[L3Side.SFBMAX], xfsf[] = new float[L3Side.SFBMAX]; - CalcNoiseResult noise = new CalcNoiseResult(); - - calc_xmin(gfp, ratio, cod_info, l3_xmin); - calc_noise(cod_info, l3_xmin, xfsf, noise, null); - - int j = 0; - sfb2 = cod_info.sfb_lmax; - if (cod_info.block_type != Encoder.SHORT_TYPE - && 0 == cod_info.mixed_block_flag) - sfb2 = 22; - for (sfb = 0; sfb < sfb2; sfb++) { - int start = gfc.scalefac_band.l[sfb]; - int end = gfc.scalefac_band.l[sfb + 1]; - int bw = end - start; - for (en0 = 0.0f; j < end; j++) - en0 += cod_info.xr[j] * cod_info.xr[j]; - en0 /= bw; - /* convert to MDCT units */ - /* scaling so it shows up on FFT plot */ - en1 = 1e15f; - gfc.pinfo.en[gr][ch][sfb] = en1 * en0; - gfc.pinfo.xfsf[gr][ch][sfb] = en1 * l3_xmin[sfb] * xfsf[sfb] / bw; - - if (ratio.en.l[sfb] > 0 && !gfp.ATHonly) - en0 = en0 / ratio.en.l[sfb]; - else - en0 = 0.0f; - - gfc.pinfo.thr[gr][ch][sfb] = en1 - * Math.max(en0 * ratio.thm.l[sfb], gfc.ATH.l[sfb]); - - /* there is no scalefactor bands >= SBPSY_l */ - gfc.pinfo.LAMEsfb[gr][ch][sfb] = 0; - if (cod_info.preflag != 0 && sfb >= 11) - gfc.pinfo.LAMEsfb[gr][ch][sfb] = -ifqstep * pretab[sfb]; - - if (sfb < Encoder.SBPSY_l) { - /* scfsi should be decoded by caller side */ - assert (scalefac[sfb] >= 0); - gfc.pinfo.LAMEsfb[gr][ch][sfb] -= ifqstep * scalefac[sfb]; - } - } /* for sfb */ - - if (cod_info.block_type == Encoder.SHORT_TYPE) { - sfb2 = sfb; - for (sfb = cod_info.sfb_smin; sfb < Encoder.SBMAX_s; sfb++) { - int start = gfc.scalefac_band.s[sfb]; - int end = gfc.scalefac_band.s[sfb + 1]; - int bw = end - start; - for (int i = 0; i < 3; i++) { - for (en0 = 0.0f, l = start; l < end; l++) { - en0 += cod_info.xr[j] * cod_info.xr[j]; - j++; - } - en0 = (float) Math.max(en0 / bw, 1e-20); - /* convert to MDCT units */ - /* scaling so it shows up on FFT plot */ - en1 = 1e15f; - - gfc.pinfo.en_s[gr][ch][3 * sfb + i] = en1 * en0; - gfc.pinfo.xfsf_s[gr][ch][3 * sfb + i] = en1 * l3_xmin[sfb2] - * xfsf[sfb2] / bw; - if (ratio.en.s[sfb][i] > 0) - en0 = en0 / ratio.en.s[sfb][i]; - else - en0 = 0.0f; - if (gfp.ATHonly || gfp.ATHshort) - en0 = 0; - - gfc.pinfo.thr_s[gr][ch][3 * sfb + i] = en1 - * Math.max(en0 * ratio.thm.s[sfb][i], - gfc.ATH.s[sfb]); - - /* there is no scalefactor bands >= SBPSY_s */ - gfc.pinfo.LAMEsfb_s[gr][ch][3 * sfb + i] = -2.0 - * cod_info.subblock_gain[i]; - if (sfb < Encoder.SBPSY_s) { - gfc.pinfo.LAMEsfb_s[gr][ch][3 * sfb + i] -= ifqstep - * scalefac[sfb2]; - } - sfb2++; - } - } - } /* block type short */ - gfc.pinfo.LAMEqss[gr][ch] = cod_info.global_gain; - gfc.pinfo.LAMEmainbits[gr][ch] = cod_info.part2_3_length - + cod_info.part2_length; - gfc.pinfo.LAMEsfbits[gr][ch] = cod_info.part2_length; - - gfc.pinfo.over[gr][ch] = noise.over_count; - gfc.pinfo.max_noise[gr][ch] = noise.max_noise * 10.0; - gfc.pinfo.over_noise[gr][ch] = noise.over_noise * 10.0; - gfc.pinfo.tot_noise[gr][ch] = noise.tot_noise * 10.0; - gfc.pinfo.over_SSD[gr][ch] = noise.over_SSD; - } - - /** - * updates plotting data for a whole frame - * - * Robert Hegemann 2000-10-21 - */ - public final void set_frame_pinfo(final LameGlobalFlags gfp, - final III_psy_ratio ratio[][]) { - final LameInternalFlags gfc = gfp.internal_flags; - - gfc.masking_lower = 1.0f; - - /* - * for every granule and channel patch l3_enc and set info - */ - for (int gr = 0; gr < gfc.mode_gr; gr++) { - for (int ch = 0; ch < gfc.channels_out; ch++) { - GrInfo cod_info = gfc.l3_side.tt[gr][ch]; - int scalefac_sav[] = new int[L3Side.SFBMAX]; - System.arraycopy(cod_info.scalefac, 0, scalefac_sav, 0, - scalefac_sav.length); - - /* - * reconstruct the scalefactors in case SCFSI was used - */ - if (gr == 1) { - int sfb; - for (sfb = 0; sfb < cod_info.sfb_lmax; sfb++) { - if (cod_info.scalefac[sfb] < 0) /* scfsi */ - cod_info.scalefac[sfb] = gfc.l3_side.tt[0][ch].scalefac[sfb]; - } - } - - set_pinfo(gfp, cod_info, ratio[gr][ch], gr, ch); - System.arraycopy(scalefac_sav, 0, cod_info.scalefac, 0, - scalefac_sav.length); - } /* for ch */ - } /* for gr */ - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ReplayGain.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ReplayGain.java deleted file mode 100644 index 30dcdc456..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ReplayGain.java +++ /dev/null @@ -1,41 +0,0 @@ -package mp3; - -public final class ReplayGain { - float linprebuf[] = new float[GainAnalysis.MAX_ORDER * 2]; - /** - * left input samples, with pre-buffer - */ - int linpre; - float lstepbuf[] = new float[GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER]; - /** - * left "first step" (i.e. post first filter) samples - */ - int lstep; - float loutbuf[] = new float[GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER]; - /** - * left "out" (i.e. post second filter) samples - */ - int lout; - float rinprebuf[] = new float[GainAnalysis.MAX_ORDER * 2]; - /** - * right input samples ... - */ - int rinpre; - float rstepbuf[] = new float[GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER]; - int rstep; - float routbuf[] = new float[GainAnalysis.MAX_SAMPLES_PER_WINDOW + GainAnalysis.MAX_ORDER]; - int rout; - /** - * number of samples required to reach number of milliseconds required - * for RMS window - */ - int sampleWindow; - int totsamp; - double lsum; - double rsum; - int freqindex; - int first; - int A[] = new int[(int) (GainAnalysis.STEPS_per_dB * GainAnalysis.MAX_dB)]; - int B[] = new int[(int) (GainAnalysis.STEPS_per_dB * GainAnalysis.MAX_dB)]; - -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Reservoir.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Reservoir.java deleted file mode 100644 index 19362414e..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Reservoir.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * bit reservoir source file - * - * Copyright (c) 1999-2000 Mark Taylor - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: Reservoir.java,v 1.9 2011/05/24 20:48:06 kenchis Exp $ */ - -package mp3; - -/** - * ResvFrameBegin:<BR> - * Called (repeatedly) at the beginning of a frame. Updates the maximum size of - * the reservoir, and checks to make sure main_data_begin was set properly by - * the formatter<BR> - * Background information: - * - * This is the original text from the ISO standard. Because of sooo many bugs - * and irritations correcting comments are added in brackets []. A '^W' means - * you should remove the last word. - * - * <PRE> - * 1. The following rule can be used to calculate the maximum - * number of bits used for one granule [^W frame]:<BR> - * At the highest possible bitrate of Layer III (320 kbps - * per stereo signal [^W^W^W], 48 kHz) the frames must be of - * [^W^W^W are designed to have] constant length, i.e. - * one buffer [^W^W the frame] length is:<BR> - * - * 320 kbps * 1152/48 kHz = 7680 bit = 960 byte - * - * This value is used as the maximum buffer per channel [^W^W] at - * lower bitrates [than 320 kbps]. At 64 kbps mono or 128 kbps - * stereo the main granule length is 64 kbps * 576/48 kHz = 768 bit - * [per granule and channel] at 48 kHz sampling frequency. - * This means that there is a maximum deviation (short time buffer - * [= reservoir]) of 7680 - 2*2*768 = 4608 bits is allowed at 64 kbps. - * The actual deviation is equal to the number of bytes [with the - * meaning of octets] denoted by the main_data_end offset pointer. - * The actual maximum deviation is (2^9-1)*8 bit = 4088 bits - * [for MPEG-1 and (2^8-1)*8 bit for MPEG-2, both are hard limits]. - * ... The xchange of buffer bits between the left and right channel - * is allowed without restrictions [exception: dual channel]. - * Because of the [constructed] constraint on the buffer size - * main_data_end is always set to 0 in the case of bit_rate_index==14, - * i.e. data rate 320 kbps per stereo signal [^W^W^W]. In this case - * all data are allocated between adjacent header [^W sync] words - * [, i.e. there is no buffering at all]. - * </PRE> - */ -public class Reservoir { - BitStream bs; - - public final void setModules(BitStream bs) { - this.bs = bs; - } - - public final int ResvFrameBegin(final LameGlobalFlags gfp, - final MeanBits mean_bits) { - final LameInternalFlags gfc = gfp.internal_flags; - int maxmp3buf; - final IIISideInfo l3_side = gfc.l3_side; - - int frameLength = bs.getframebits(gfp); - mean_bits.bits = (frameLength - gfc.sideinfo_len * 8) / gfc.mode_gr; - - /** - * <PRE> - * Meaning of the variables: - * resvLimit: (0, 8, ..., 8*255 (MPEG-2), 8*511 (MPEG-1)) - * Number of bits can be stored in previous frame(s) due to - * counter size constaints - * maxmp3buf: ( ??? ... 8*1951 (MPEG-1 and 2), 8*2047 (MPEG-2.5)) - * Number of bits allowed to encode one frame (you can take 8*511 bit - * from the bit reservoir and at most 8*1440 bit from the current - * frame (320 kbps, 32 kHz), so 8*1951 bit is the largest possible - * value for MPEG-1 and -2) - * - * maximum allowed granule/channel size times 4 = 8*2047 bits., - * so this is the absolute maximum supported by the format. - * - * - * fullFrameBits: maximum number of bits available for encoding - * the current frame. - * - * mean_bits: target number of bits per granule. - * - * frameLength: - * - * gfc.ResvMax: maximum allowed reservoir - * - * gfc.ResvSize: current reservoir size - * - * l3_side.resvDrain_pre: - * ancillary data to be added to previous frame: - * (only usefull in VBR modes if it is possible to have - * maxmp3buf < fullFrameBits)). Currently disabled, - * see #define NEW_DRAIN - * 2010-02-13: RH now enabled, it seems to be needed for CBR too, - * as there exists one example, where the FhG decoder - * can't decode a -b320 CBR file anymore. - * - * l3_side.resvDrain_post: - * ancillary data to be added to this frame: - * - * </PRE> - */ - - /* main_data_begin has 9 bits in MPEG-1, 8 bits MPEG-2 */ - int resvLimit = (8 * 256) * gfc.mode_gr - 8; - - /* - * maximum allowed frame size. dont use more than this number of bits, - * even if the frame has the space for them: - */ - if (gfp.brate > 320) { - /* in freeformat the buffer is constant */ - maxmp3buf = 8 * ((int) ((gfp.brate * 1000) - / (gfp.out_samplerate / 1152f) / 8 + .5)); - } else { - /* - * all mp3 decoders should have enough buffer to handle this value: - * size of a 320kbps 32kHz frame - */ - maxmp3buf = 8 * 1440; - - /* - * Bouvigne suggests this more lax interpretation of the ISO doc - * instead of using 8*960. - */ - - if (gfp.strict_ISO) { - maxmp3buf = 8 * ((int) (320000 / (gfp.out_samplerate / 1152f) / 8 + .5)); - } - } - - gfc.ResvMax = maxmp3buf - frameLength; - if (gfc.ResvMax > resvLimit) - gfc.ResvMax = resvLimit; - if (gfc.ResvMax < 0 || gfp.disable_reservoir) - gfc.ResvMax = 0; - - int fullFrameBits = mean_bits.bits * gfc.mode_gr - + Math.min(gfc.ResvSize, gfc.ResvMax); - - if (fullFrameBits > maxmp3buf) - fullFrameBits = maxmp3buf; - - assert (0 == gfc.ResvMax % 8); - assert (gfc.ResvMax >= 0); - - l3_side.resvDrain_pre = 0; - - // frame analyzer code - if (gfc.pinfo != null) { - /* - * expected bits per channel per granule [is this also right for - * mono/stereo, MPEG-1/2 ?] - */ - gfc.pinfo.mean_bits = mean_bits.bits / 2; - gfc.pinfo.resvsize = gfc.ResvSize; - } - - return fullFrameBits; - } - - /** - * returns targ_bits: target number of bits to use for 1 granule<BR> - * extra_bits: amount extra available from reservoir<BR> - * Mark Taylor 4/99 - */ - public final int ResvMaxBits(final LameGlobalFlags gfp, - final int mean_bits, final MeanBits targ_bits, final int cbr) { - final LameInternalFlags gfc = gfp.internal_flags; - int add_bits; - int ResvSize = gfc.ResvSize, ResvMax = gfc.ResvMax; - - /* compensate the saved bits used in the 1st granule */ - if (cbr != 0) - ResvSize += mean_bits; - - if ((gfc.substep_shaping & 1) != 0) - ResvMax *= 0.9; - - targ_bits.bits = mean_bits; - - /* extra bits if the reservoir is almost full */ - if (ResvSize * 10 > ResvMax * 9) { - add_bits = ResvSize - (ResvMax * 9) / 10; - targ_bits.bits += add_bits; - gfc.substep_shaping |= 0x80; - } else { - add_bits = 0; - gfc.substep_shaping &= 0x7f; - /* - * build up reservoir. this builds the reservoir a little slower - * than FhG. It could simple be mean_bits/15, but this was rigged to - * always produce 100 (the old value) at 128kbs - */ - if (!gfp.disable_reservoir && 0 == (gfc.substep_shaping & 1)) - targ_bits.bits -= .1 * mean_bits; - } - - /* amount from the reservoir we are allowed to use. ISO says 6/10 */ - int extra_bits = (ResvSize < (gfc.ResvMax * 6) / 10 ? ResvSize - : (gfc.ResvMax * 6) / 10); - extra_bits -= add_bits; - - if (extra_bits < 0) - extra_bits = 0; - return extra_bits; - } - - /** - * Called after a granule's bit allocation. Readjusts the size of the - * reservoir to reflect the granule's usage. - */ - public final void ResvAdjust(final LameInternalFlags gfc, - final GrInfo gi) { - gfc.ResvSize -= gi.part2_3_length + gi.part2_length; - } - - /** - * Called after all granules in a frame have been allocated. Makes sure that - * the reservoir size is within limits, possibly by adding stuffing bits. - */ - public final void ResvFrameEnd(final LameInternalFlags gfc, - final int mean_bits) { - int over_bits; - final IIISideInfo l3_side = gfc.l3_side; - - gfc.ResvSize += mean_bits * gfc.mode_gr; - int stuffingBits = 0; - l3_side.resvDrain_post = 0; - l3_side.resvDrain_pre = 0; - - /* we must be byte aligned */ - if ((over_bits = gfc.ResvSize % 8) != 0) - stuffingBits += over_bits; - - over_bits = (gfc.ResvSize - stuffingBits) - gfc.ResvMax; - if (over_bits > 0) { - assert (0 == over_bits % 8); - assert (over_bits >= 0); - stuffingBits += over_bits; - } - - /* - * NOTE: enabling the NEW_DRAIN code fixes some problems with FhG - * decoder shipped with MS Windows operating systems. Using this, it is - * even possible to use Gabriel's lax buffer consideration again, which - * assumes, any decoder should have a buffer large enough for a 320 kbps - * frame at 32 kHz sample rate. - * - * old drain code: lame -b320 BlackBird.wav --. does not play with - * GraphEdit.exe using FhG decoder V1.5 Build 50 - * - * new drain code: lame -b320 BlackBird.wav --. plays fine with - * GraphEdit.exe using FhG decoder V1.5 Build 50 - * - * Robert Hegemann, 2010-02-13. - */ - /* - * drain as many bits as possible into previous frame ancillary data In - * particular, in VBR mode ResvMax may have changed, and we have to make - * sure main_data_begin does not create a reservoir bigger than ResvMax - * mt 4/00 - */ - { - int mdb_bytes = Math.min(l3_side.main_data_begin * 8, stuffingBits) / 8; - l3_side.resvDrain_pre += 8 * mdb_bytes; - stuffingBits -= 8 * mdb_bytes; - gfc.ResvSize -= 8 * mdb_bytes; - l3_side.main_data_begin -= mdb_bytes; - } - /* drain the rest into this frames ancillary data */ - l3_side.resvDrain_post += stuffingBits; - gfc.ResvSize -= stuffingBits; - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ScaleFac.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ScaleFac.java deleted file mode 100644 index 65109a47d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ScaleFac.java +++ /dev/null @@ -1,27 +0,0 @@ -package mp3; - -/** - * Layer III side information. - * - * @author Ken - * - */ -public final class ScaleFac { - public ScaleFac() { - } - - public ScaleFac(final int[] arrL, final int[] arrS, final int[] arr21, - final int[] arr12) { - System.arraycopy(arrL, 0, l, 0, Math.min(arrL.length, l.length)); - System.arraycopy(arrS, 0, s, 0, Math.min(arrS.length, s.length)); - System.arraycopy(arr21, 0, psfb21, 0, - Math.min(arr21.length, psfb21.length)); - System.arraycopy(arr12, 0, psfb12, 0, - Math.min(arr12.length, psfb12.length)); - } - - int[] l = new int[1 + Encoder.SBMAX_l]; - int[] s = new int[1 + Encoder.SBMAX_s]; - int[] psfb21 = new int[1 + Encoder.PSFB21]; - int[] psfb12 = new int[1 + Encoder.PSFB12]; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ShortBlock.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ShortBlock.java deleted file mode 100644 index ad46ceb0a..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ShortBlock.java +++ /dev/null @@ -1,20 +0,0 @@ -package mp3; - -public enum ShortBlock { - /** - * LAME may use them, even different block types for L/R. - */ - short_block_allowed, - /** - * LAME may use them, but always same block types in L/R. - */ - short_block_coupled, - /** - * LAME will not use short blocks, long blocks only. - */ - short_block_dispensed, - /** - * LAME will not use long blocks, short blocks only. - */ - short_block_forced -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ShortBlockConstrain.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ShortBlockConstrain.java deleted file mode 100644 index 8dde4d55a..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/ShortBlockConstrain.java +++ /dev/null @@ -1,89 +0,0 @@ -package mp3; - -import mp3.VBRQuantize.algo_t; - -final class ShortBlockConstrain implements VBRQuantize.alloc_sf_f { - /** - * - */ - private final VBRQuantize vbrQuantize; - - /** - * @param vbrQuantize - */ - ShortBlockConstrain(VBRQuantize vbrQuantize) { - this.vbrQuantize = vbrQuantize; - } - - /****************************************************************** - * - * short block scalefacs - * - ******************************************************************/ - - public void alloc(algo_t that, int[] vbrsf, int[] vbrsfmin, int vbrmax) { - final GrInfo cod_info = that.cod_info; - final LameInternalFlags gfc = that.gfc; - final int maxminsfb = that.mingain_l; - int mover, maxover0 = 0, maxover1 = 0, delta = 0; - int v, v0, v1; - int sfb; - final int psymax = cod_info.psymax; - - for (sfb = 0; sfb < psymax; ++sfb) { - assert (vbrsf[sfb] >= vbrsfmin[sfb]); - v = vbrmax - vbrsf[sfb]; - if (delta < v) { - delta = v; - } - v0 = v - (4 * 14 + 2 * VBRQuantize.max_range_short[sfb]); - v1 = v - (4 * 14 + 4 * VBRQuantize.max_range_short[sfb]); - if (maxover0 < v0) { - maxover0 = v0; - } - if (maxover1 < v1) { - maxover1 = v1; - } - } - if (gfc.noise_shaping == 2) { - /* allow scalefac_scale=1 */ - mover = Math.min(maxover0, maxover1); - } else { - mover = maxover0; - } - if (delta > mover) { - delta = mover; - } - vbrmax -= delta; - maxover0 -= mover; - maxover1 -= mover; - - if (maxover0 == 0) { - cod_info.scalefac_scale = 0; - } else if (maxover1 == 0) { - cod_info.scalefac_scale = 1; - } - if (vbrmax < maxminsfb) { - vbrmax = maxminsfb; - } - cod_info.global_gain = vbrmax; - - if (cod_info.global_gain < 0) { - cod_info.global_gain = 0; - } else if (cod_info.global_gain > 255) { - cod_info.global_gain = 255; - } - { - int sf_temp[] = new int[L3Side.SFBMAX]; - for (sfb = 0; sfb < L3Side.SFBMAX; ++sfb) { - sf_temp[sfb] = vbrsf[sfb] - vbrmax; - } - this.vbrQuantize.set_subblock_gain(cod_info, that.mingain_s, - sf_temp); - this.vbrQuantize.set_scalefacs(cod_info, vbrsfmin, sf_temp, - VBRQuantize.max_range_short); - } - assert (this.vbrQuantize.checkScalefactor(cod_info, vbrsfmin)); - - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Tables.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Tables.java deleted file mode 100644 index f16b52462..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Tables.java +++ /dev/null @@ -1,507 +0,0 @@ -package mp3; - -public interface Tables { - - static final int t1HB[] = { - 1, 1, - 1, 0 - }; - - static final int t2HB[] = { - 1, 2, 1, - 3, 1, 1, - 3, 2, 0 - }; - - static final int t3HB[] = { - 3, 2, 1, - 1, 1, 1, - 3, 2, 0 - }; - - static final int t5HB[] = { - 1, 2, 6, 5, - 3, 1, 4, 4, - 7, 5, 7, 1, - 6, 1, 1, 0 - }; - - static final int t6HB[] = { - 7, 3, 5, 1, - 6, 2, 3, 2, - 5, 4, 4, 1, - 3, 3, 2, 0 - }; - - static final int t7HB[] = { - 1, 2, 10, 19, 16, 10, - 3, 3, 7, 10, 5, 3, - 11, 4, 13, 17, 8, 4, - 12, 11, 18, 15, 11, 2, - 7, 6, 9, 14, 3, 1, - 6, 4, 5, 3, 2, 0 - }; - - static final int t8HB[] = { - 3, 4, 6, 18, 12, 5, - 5, 1, 2, 16, 9, 3, - 7, 3, 5, 14, 7, 3, - 19, 17, 15, 13, 10, 4, - 13, 5, 8, 11, 5, 1, - 12, 4, 4, 1, 1, 0 - }; - - static final int t9HB[] = { - 7, 5, 9, 14, 15, 7, - 6, 4, 5, 5, 6, 7, - 7, 6, 8, 8, 8, 5, - 15, 6, 9, 10, 5, 1, - 11, 7, 9, 6, 4, 1, - 14, 4, 6, 2, 6, 0 - }; - - static final int t10HB[] = { - 1, 2, 10, 23, 35, 30, 12, 17, - 3, 3, 8, 12, 18, 21, 12, 7, - 11, 9, 15, 21, 32, 40, 19, 6, - 14, 13, 22, 34, 46, 23, 18, 7, - 20, 19, 33, 47, 27, 22, 9, 3, - 31, 22, 41, 26, 21, 20, 5, 3, - 14, 13, 10, 11, 16, 6, 5, 1, - 9, 8, 7, 8, 4, 4, 2, 0 - }; - - static final int t11HB[] = { - 3, 4, 10, 24, 34, 33, 21, 15, - 5, 3, 4, 10, 32, 17, 11, 10, - 11, 7, 13, 18, 30, 31, 20, 5, - 25, 11, 19, 59, 27, 18, 12, 5, - 35, 33, 31, 58, 30, 16, 7, 5, - 28, 26, 32, 19, 17, 15, 8, 14, - 14, 12, 9, 13, 14, 9, 4, 1, - 11, 4, 6, 6, 6, 3, 2, 0 - }; - - static final int t12HB[] = { - 9, 6, 16, 33, 41, 39, 38, 26, - 7, 5, 6, 9, 23, 16, 26, 11, - 17, 7, 11, 14, 21, 30, 10, 7, - 17, 10, 15, 12, 18, 28, 14, 5, - 32, 13, 22, 19, 18, 16, 9, 5, - 40, 17, 31, 29, 17, 13, 4, 2, - 27, 12, 11, 15, 10, 7, 4, 1, - 27, 12, 8, 12, 6, 3, 1, 0 - }; - - static final int t13HB[] = { - 1, 5, 14, 21, 34, 51, 46, 71, 42, 52, 68, 52, 67, 44, 43, 19, - 3, 4, 12, 19, 31, 26, 44, 33, 31, 24, 32, 24, 31, 35, 22, 14, - 15, 13, 23, 36, 59, 49, 77, 65, 29, 40, 30, 40, 27, 33, 42, 16, - 22, 20, 37, 61, 56, 79, 73, 64, 43, 76, 56, 37, 26, 31, 25, 14, - 35, 16, 60, 57, 97, 75, 114, 91, 54, 73, 55, 41, 48, 53, 23, 24, - 58, 27, 50, 96, 76, 70, 93, 84, 77, 58, 79, 29, 74, 49, 41, 17, - 47, 45, 78, 74, 115, 94, 90, 79, 69, 83, 71, 50, 59, 38, 36, 15, - 72, 34, 56, 95, 92, 85, 91, 90, 86, 73, 77, 65, 51, 44, 43, 42, - 43, 20, 30, 44, 55, 78, 72, 87, 78, 61, 46, 54, 37, 30, 20, 16, - 53, 25, 41, 37, 44, 59, 54, 81, 66, 76, 57, 54, 37, 18, 39, 11, - 35, 33, 31, 57, 42, 82, 72, 80, 47, 58, 55, 21, 22, 26, 38, 22, - 53, 25, 23, 38, 70, 60, 51, 36, 55, 26, 34, 23, 27, 14, 9, 7, - 34, 32, 28, 39, 49, 75, 30, 52, 48, 40, 52, 28, 18, 17, 9, 5, - 45, 21, 34, 64, 56, 50, 49, 45, 31, 19, 12, 15, 10, 7, 6, 3, - 48, 23, 20, 39, 36, 35, 53, 21, 16, 23, 13, 10, 6, 1, 4, 2, - 16, 15, 17, 27, 25, 20, 29, 11, 17, 12, 16, 8, 1, 1, 0, 1 - }; - - static final int t15HB[] = { - 7, 12, 18, 53, 47, 76, 124, 108, 89, 123, 108, 119, 107, 81, 122, 63, - 13, 5, 16, 27, 46, 36, 61, 51, 42, 70, 52, 83, 65, 41, 59, 36, - 19, 17, 15, 24, 41, 34, 59, 48, 40, 64, 50, 78, 62, 80, 56, 33, - 29, 28, 25, 43, 39, 63, 55, 93, 76, 59, 93, 72, 54, 75, 50, 29, - 52, 22, 42, 40, 67, 57, 95, 79, 72, 57, 89, 69, 49, 66, 46, 27, - 77, 37, 35, 66, 58, 52, 91, 74, 62, 48, 79, 63, 90, 62, 40, 38, - 125, 32, 60, 56, 50, 92, 78, 65, 55, 87, 71, 51, 73, 51, 70, 30, - 109, 53, 49, 94, 88, 75, 66, 122, 91, 73, 56, 42, 64, 44, 21, 25, - 90, 43, 41, 77, 73, 63, 56, 92, 77, 66, 47, 67, 48, 53, 36, 20, - 71, 34, 67, 60, 58, 49, 88, 76, 67, 106, 71, 54, 38, 39, 23, 15, - 109, 53, 51, 47, 90, 82, 58, 57, 48, 72, 57, 41, 23, 27, 62, 9, - 86, 42, 40, 37, 70, 64, 52, 43, 70, 55, 42, 25, 29, 18, 11, 11, - 118, 68, 30, 55, 50, 46, 74, 65, 49, 39, 24, 16, 22, 13, 14, 7, - 91, 44, 39, 38, 34, 63, 52, 45, 31, 52, 28, 19, 14, 8, 9, 3, - 123, 60, 58, 53, 47, 43, 32, 22, 37, 24, 17, 12, 15, 10, 2, 1, - 71, 37, 34, 30, 28, 20, 17, 26, 21, 16, 10, 6, 8, 6, 2, 0 - }; - - static final int t16HB[] = { - 1, 5, 14, 44, 74, 63, 110, 93, 172, 149, 138, 242, 225, 195, 376, 17, - 3, 4, 12, 20, 35, 62, 53, 47, 83, 75, 68, 119, 201, 107, 207, 9, - 15, 13, 23, 38, 67, 58, 103, 90, 161, 72, 127, 117, 110, 209, 206, 16, - 45, 21, 39, 69, 64, 114, 99, 87, 158, 140, 252, 212, 199, 387, 365, 26, - 75, 36, 68, 65, 115, 101, 179, 164, 155, 264, 246, 226, 395, 382, 362, 9, - 66, 30, 59, 56, 102, 185, 173, 265, 142, 253, 232, 400, 388, 378, 445, 16, - 111, 54, 52, 100, 184, 178, 160, 133, 257, 244, 228, 217, 385, 366, 715, 10, - 98, 48, 91, 88, 165, 157, 148, 261, 248, 407, 397, 372, 380, 889, 884, 8, - 85, 84, 81, 159, 156, 143, 260, 249, 427, 401, 392, 383, 727, 713, 708, 7, - 154, 76, 73, 141, 131, 256, 245, 426, 406, 394, 384, 735, 359, 710, 352, 11, - 139, 129, 67, 125, 247, 233, 229, 219, 393, 743, 737, 720, 885, 882, 439, 4, - 243, 120, 118, 115, 227, 223, 396, 746, 742, 736, 721, 712, 706, 223, 436, 6, - 202, 224, 222, 218, 216, 389, 386, 381, 364, 888, 443, 707, 440, 437, 1728, 4, - 747, 211, 210, 208, 370, 379, 734, 723, 714, 1735, 883, 877, 876, 3459, 865, 2, - 377, 369, 102, 187, 726, 722, 358, 711, 709, 866, 1734, 871, 3458, 870, 434, 0, - 12, 10, 7, 11, 10, 17, 11, 9, 13, 12, 10, 7, 5, 3, 1, 3 - }; - - static final int t24HB[] = { - 15, 13, 46, 80, 146, 262, 248, 434, 426, 669, 653, 649, 621, 517, 1032, 88, - 14, 12, 21, 38, 71, 130, 122, 216, 209, 198, 327, 345, 319, 297, 279, 42, - 47, 22, 41, 74, 68, 128, 120, 221, 207, 194, 182, 340, 315, 295, 541, 18, - 81, 39, 75, 70, 134, 125, 116, 220, 204, 190, 178, 325, 311, 293, 271, 16, - 147, 72, 69, 135, 127, 118, 112, 210, 200, 188, 352, 323, 306, 285, 540, 14, - 263, 66, 129, 126, 119, 114, 214, 202, 192, 180, 341, 317, 301, 281, 262, 12, - 249, 123, 121, 117, 113, 215, 206, 195, 185, 347, 330, 308, 291, 272, 520, 10, - 435, 115, 111, 109, 211, 203, 196, 187, 353, 332, 313, 298, 283, 531, 381, 17, - 427, 212, 208, 205, 201, 193, 186, 177, 169, 320, 303, 286, 268, 514, 377, 16, - 335, 199, 197, 191, 189, 181, 174, 333, 321, 305, 289, 275, 521, 379, 371, 11, - 668, 184, 183, 179, 175, 344, 331, 314, 304, 290, 277, 530, 383, 373, 366, 10, - 652, 346, 171, 168, 164, 318, 309, 299, 287, 276, 263, 513, 375, 368, 362, 6, - 648, 322, 316, 312, 307, 302, 292, 284, 269, 261, 512, 376, 370, 364, 359, 4, - 620, 300, 296, 294, 288, 282, 273, 266, 515, 380, 374, 369, 365, 361, 357, 2, - 1033, 280, 278, 274, 267, 264, 259, 382, 378, 372, 367, 363, 360, 358, 356, 0, - 43, 20, 19, 17, 15, 13, 11, 9, 7, 6, 4, 7, 5, 3, 1, 3 - }; - - static final int t32HB[] = { - 1 << 0, 5 << 1, 4 << 1, 5 << 2, 6 << 1, 5 << 2, 4 << 2, 4 << 3, - 7 << 1, 3 << 2, 6 << 2, 0 << 3, 7 << 2, 2 << 3, 3 << 3, 1 << 4 - }; - - static final int t33HB[] = { - 15 << 0, 14 << 1, 13 << 1, 12 << 2, 11 << 1, 10 << 2, 9 << 2, 8 << 3, - 7 << 1, 6 << 2, 5 << 2, 4 << 3, 3 << 2, 2 << 3, 1 << 3, 0 << 4 - }; - - static final int t1l[] = { - 1, 4, - 3, 5 - }; - - static final int t2l[] = { - 1, 4, 7, - 4, 5, 7, - 6, 7, 8 - }; - - static final int t3l[] = { - 2, 3, 7, - 4, 4, 7, - 6, 7, 8 - }; - - static final int t5l[] = { - 1, 4, 7, 8, - 4, 5, 8, 9, - 7, 8, 9, 10, - 8, 8, 9, 10 - }; - - static final int t6l[] = { - 3, 4, 6, 8, - 4, 4, 6, 7, - 5, 6, 7, 8, - 7, 7, 8, 9 - }; - - static final int t7l[] = { - 1, 4, 7, 9, 9, 10, - 4, 6, 8, 9, 9, 10, - 7, 7, 9, 10, 10, 11, - 8, 9, 10, 11, 11, 11, - 8, 9, 10, 11, 11, 12, - 9, 10, 11, 12, 12, 12 - }; - - static final int t8l[] = { - 2, 4, 7, 9, 9, 10, - 4, 4, 6, 10, 10, 10, - 7, 6, 8, 10, 10, 11, - 9, 10, 10, 11, 11, 12, - 9, 9, 10, 11, 12, 12, - 10, 10, 11, 11, 13, 13 - }; - - static final int t9l[] = { - 3, 4, 6, 7, 9, 10, - 4, 5, 6, 7, 8, 10, - 5, 6, 7, 8, 9, 10, - 7, 7, 8, 9, 9, 10, - 8, 8, 9, 9, 10, 11, - 9, 9, 10, 10, 11, 11 - }; - - static final int t10l[] = { - 1, 4, 7, 9, 10, 10, 10, 11, - 4, 6, 8, 9, 10, 11, 10, 10, - 7, 8, 9, 10, 11, 12, 11, 11, - 8, 9, 10, 11, 12, 12, 11, 12, - 9, 10, 11, 12, 12, 12, 12, 12, - 10, 11, 12, 12, 13, 13, 12, 13, - 9, 10, 11, 12, 12, 12, 13, 13, - 10, 10, 11, 12, 12, 13, 13, 13 - }; - - static final int t11l[] = { - 2, 4, 6, 8, 9, 10, 9, 10, - 4, 5, 6, 8, 10, 10, 9, 10, - 6, 7, 8, 9, 10, 11, 10, 10, - 8, 8, 9, 11, 10, 12, 10, 11, - 9, 10, 10, 11, 11, 12, 11, 12, - 9, 10, 11, 12, 12, 13, 12, 13, - 9, 9, 9, 10, 11, 12, 12, 12, - 9, 9, 10, 11, 12, 12, 12, 12 - }; - - static final int t12l[] = { - 4, 4, 6, 8, 9, 10, 10, 10, - 4, 5, 6, 7, 9, 9, 10, 10, - 6, 6, 7, 8, 9, 10, 9, 10, - 7, 7, 8, 8, 9, 10, 10, 10, - 8, 8, 9, 9, 10, 10, 10, 11, - 9, 9, 10, 10, 10, 11, 10, 11, - 9, 9, 9, 10, 10, 11, 11, 12, - 10, 10, 10, 11, 11, 11, 11, 12 - }; - - static final int t13l[] = { - 1, 5, 7, 8, 9, 10, 10, 11, 10, 11, 12, 12, 13, 13, 14, 14, - 4, 6, 8, 9, 10, 10, 11, 11, 11, 11, 12, 12, 13, 14, 14, 14, - 7, 8, 9, 10, 11, 11, 12, 12, 11, 12, 12, 13, 13, 14, 15, 15, - 8, 9, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 15, 15, - 9, 9, 11, 11, 12, 12, 13, 13, 12, 13, 13, 14, 14, 15, 15, 16, - 10, 10, 11, 12, 12, 12, 13, 13, 13, 13, 14, 13, 15, 15, 16, 16, - 10, 11, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16, - 11, 11, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 16, 18, 18, - 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 15, 15, 16, 17, 17, - 11, 11, 12, 12, 13, 13, 13, 15, 14, 15, 15, 16, 16, 16, 18, 17, - 11, 12, 12, 13, 13, 14, 14, 15, 14, 15, 16, 15, 16, 17, 18, 19, - 12, 12, 12, 13, 14, 14, 14, 14, 15, 15, 15, 16, 17, 17, 17, 18, - 12, 13, 13, 14, 14, 15, 14, 15, 16, 16, 17, 17, 17, 18, 18, 18, - 13, 13, 14, 15, 15, 15, 16, 16, 16, 16, 16, 17, 18, 17, 18, 18, - 14, 14, 14, 15, 15, 15, 17, 16, 16, 19, 17, 17, 17, 19, 18, 18, - 13, 14, 15, 16, 16, 16, 17, 16, 17, 17, 18, 18, 21, 20, 21, 18 - }; - - static final int t15l[] = { - 3, 5, 6, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 14, - 5, 5, 7, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, - 6, 7, 7, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 13, - 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, - 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, - 9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 13, 13, 13, 14, - 10, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14, - 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 14, - 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 14, 14, - 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, - 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 15, 14, - 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, - 12, 12, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 14, 14, 15, 15, - 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, - 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 14, 15, - 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15 - }; - - static final int t16_5l[] = { - 1, 5, 7, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 11, - 4, 6, 8, 9, 10, 11, 11, 11, 12, 12, 12, 13, 14, 13, 14, 11, - 7, 8, 9, 10, 11, 11, 12, 12, 13, 12, 13, 13, 13, 14, 14, 12, - 9, 9, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 13, - 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 12, - 10, 10, 11, 11, 12, 13, 13, 14, 13, 14, 14, 15, 15, 15, 16, 13, - 11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 13, - 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 17, 17, 13, - 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 13, - 12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 16, 15, 14, - 12, 13, 12, 13, 14, 14, 14, 14, 15, 16, 16, 16, 17, 17, 16, 13, - 13, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 14, - 13, 14, 14, 14, 14, 15, 15, 15, 15, 17, 16, 16, 16, 16, 18, 14, - 15, 14, 14, 14, 15, 15, 16, 16, 16, 18, 17, 17, 17, 19, 17, 14, - 14, 15, 13, 14, 16, 16, 15, 16, 16, 17, 18, 17, 19, 17, 16, 14, - 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 12 - }; - - static final int t16l[] = { - 1, 5, 7, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 10, - 4, 6, 8, 9, 10, 11, 11, 11, 12, 12, 12, 13, 14, 13, 14, 10, - 7, 8, 9, 10, 11, 11, 12, 12, 13, 12, 13, 13, 13, 14, 14, 11, - 9, 9, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 12, - 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 11, - 10, 10, 11, 11, 12, 13, 13, 14, 13, 14, 14, 15, 15, 15, 16, 12, - 11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 12, - 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 17, 17, 12, - 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 12, - 12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 16, 15, 13, - 12, 13, 12, 13, 14, 14, 14, 14, 15, 16, 16, 16, 17, 17, 16, 12, - 13, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 13, - 13, 14, 14, 14, 14, 15, 15, 15, 15, 17, 16, 16, 16, 16, 18, 13, - 15, 14, 14, 14, 15, 15, 16, 16, 16, 18, 17, 17, 17, 19, 17, 13, - 14, 15, 13, 14, 16, 16, 15, 16, 16, 17, 18, 17, 19, 17, 16, 13, - 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 10 - }; - - static final int t24l[] = { - 4, 5, 7, 8, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 13, 10, - 5, 6, 7, 8, 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 10, - 7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 9, - 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 9, - 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, 9, - 10, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 9, - 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 9, - 11, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 10, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 10, - 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 10, - 12, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 10, - 12, 12, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 10, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 10, - 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 10, - 13, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 10, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 6 - }; - - static final int t32l[] = { - 1 + 0, 4 + 1, 4 + 1, 5 + 2, 4 + 1, 6 + 2, 5 + 2, 6 + 3, - 4 + 1, 5 + 2, 5 + 2, 6 + 3, 5 + 2, 6 + 3, 6 + 3, 6 + 4 - }; - - static final int t33l[] = { - 4 + 0, 4 + 1, 4 + 1, 4 + 2, 4 + 1, 4 + 2, 4 + 2, 4 + 3, - 4 + 1, 4 + 2, 4 + 2, 4 + 3, 4 + 2, 4 + 3, 4 + 3, 4 + 4 - }; - - final HuffCodeTab ht[] = { - /* xlen, linmax, table, hlen */ - new HuffCodeTab(0, 0, null, null), - new HuffCodeTab(2, 0, t1HB, t1l), - new HuffCodeTab(3, 0, t2HB, t2l), - new HuffCodeTab(3, 0, t3HB, t3l), - new HuffCodeTab(0, 0, null, null), /* Apparently not used */ - new HuffCodeTab(4, 0, t5HB, t5l), - new HuffCodeTab(4, 0, t6HB, t6l), - new HuffCodeTab(6, 0, t7HB, t7l), - new HuffCodeTab(6, 0, t8HB, t8l), - new HuffCodeTab(6, 0, t9HB, t9l), - new HuffCodeTab(8, 0, t10HB, t10l), - new HuffCodeTab(8, 0, t11HB, t11l), - new HuffCodeTab(8, 0, t12HB, t12l), - new HuffCodeTab(16, 0, t13HB, t13l), - new HuffCodeTab(0, 0, null, t16_5l), /* Apparently not used */ - new HuffCodeTab(16, 0, t15HB, t15l), - - new HuffCodeTab(1, 1, t16HB, t16l), - new HuffCodeTab(2, 3, t16HB, t16l), - new HuffCodeTab(3, 7, t16HB, t16l), - new HuffCodeTab(4, 15, t16HB, t16l), - new HuffCodeTab(6, 63, t16HB, t16l), - new HuffCodeTab(8, 255, t16HB, t16l), - new HuffCodeTab(10, 1023, t16HB, t16l), - new HuffCodeTab(13, 8191, t16HB, t16l), - - new HuffCodeTab(4, 15, t24HB, t24l), - new HuffCodeTab(5, 31, t24HB, t24l), - new HuffCodeTab(6, 63, t24HB, t24l), - new HuffCodeTab(7, 127, t24HB, t24l), - new HuffCodeTab(8, 255, t24HB, t24l), - new HuffCodeTab(9, 511, t24HB, t24l), - new HuffCodeTab(11, 2047, t24HB, t24l), - new HuffCodeTab(13, 8191, t24HB, t24l), - - new HuffCodeTab(0, 0, t32HB, t32l), - new HuffCodeTab(0, 0, t33HB, t33l), - }; - - /** - * <CODE> - * for (i = 0; i < 16*16; i++) { - * largetbl[i] = ((ht[16].hlen[i]) << 16) + ht[24].hlen[i]; - * } - * </CODE> - * - */ - static final int largetbl[] = { - 0x010004, 0x050005, 0x070007, 0x090008, 0x0a0009, 0x0a000a, 0x0b000a, 0x0b000b, - 0x0c000b, 0x0c000c, 0x0c000c, 0x0d000c, 0x0d000c, 0x0d000c, 0x0e000d, 0x0a000a, - 0x040005, 0x060006, 0x080007, 0x090008, 0x0a0009, 0x0b000a, 0x0b000a, 0x0b000b, - 0x0c000b, 0x0c000b, 0x0c000c, 0x0d000c, 0x0e000c, 0x0d000c, 0x0e000c, 0x0a000a, - 0x070007, 0x080007, 0x090008, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000b, - 0x0d000b, 0x0c000b, 0x0d000b, 0x0d000c, 0x0d000c, 0x0e000c, 0x0e000d, 0x0b0009, - 0x090008, 0x090008, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000a, 0x0c000b, - 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0c0009, - 0x0a0009, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000a, 0x0d000a, 0x0d000b, - 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000d, 0x0b0009, - 0x0a000a, 0x0a0009, 0x0b000a, 0x0b000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0e000b, - 0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x0c0009, - 0x0b000a, 0x0b000a, 0x0b000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0d000b, 0x0d000b, - 0x0e000b, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x10000d, 0x0c0009, - 0x0b000b, 0x0b000a, 0x0c000a, 0x0c000a, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b, - 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x11000d, 0x11000d, 0x0c000a, - 0x0b000b, 0x0c000b, 0x0c000b, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000b, - 0x0f000b, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x10000d, 0x10000d, 0x0c000a, - 0x0c000b, 0x0c000b, 0x0c000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000b, 0x0f000c, - 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x0f000d, 0x10000d, 0x0f000d, 0x0d000a, - 0x0c000c, 0x0d000b, 0x0c000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0e000c, - 0x0f000c, 0x10000c, 0x10000c, 0x10000d, 0x11000d, 0x11000d, 0x10000d, 0x0c000a, - 0x0d000c, 0x0d000c, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x10000c, - 0x10000c, 0x10000c, 0x10000c, 0x10000d, 0x10000d, 0x0f000d, 0x10000d, 0x0d000a, - 0x0d000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, - 0x0f000c, 0x11000c, 0x10000d, 0x10000d, 0x10000d, 0x10000d, 0x12000d, 0x0d000a, - 0x0f000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x10000c, 0x10000c, - 0x10000d, 0x12000d, 0x11000d, 0x11000d, 0x11000d, 0x13000d, 0x11000d, 0x0d000a, - 0x0e000d, 0x0f000c, 0x0d000c, 0x0e000c, 0x10000c, 0x10000c, 0x0f000c, 0x10000d, - 0x10000d, 0x11000d, 0x12000d, 0x11000d, 0x13000d, 0x11000d, 0x10000d, 0x0d000a, - 0x0a0009, 0x0a0009, 0x0a0009, 0x0b0009, 0x0b0009, 0x0c0009, 0x0c0009, 0x0c0009, - 0x0d0009, 0x0d0009, 0x0d0009, 0x0d000a, 0x0d000a, 0x0d000a, 0x0d000a, 0x0a0006 - }; - /** - * <CODE> - * for (i = 0; i < 3*3; i++) { - * table23[i] = ((ht[2].hlen[i]) << 16) + ht[3].hlen[i]; - * } - * </CODE> - * - */ - static final int table23[] = { - 0x010002, 0x040003, 0x070007, - 0x040004, 0x050004, 0x070007, - 0x060006, 0x070007, 0x080008 - }; - - /** - * <CODE> - * for (i = 0; i < 4*4; i++) { - * table56[i] = ((ht[5].hlen[i]) << 16) + ht[6].hlen[i]; - * } - * </CODE> - * - */ - static final int table56[] = { - 0x010003, 0x040004, 0x070006, 0x080008, 0x040004, 0x050004, 0x080006, 0x090007, - 0x070005, 0x080006, 0x090007, 0x0a0008, 0x080007, 0x080007, 0x090008, 0x0a0009 - }; - - public static final int bitrate_table[][] = { - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}, /* MPEG 2 */ - {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1}, /* MPEG 1 */ - {0, 8, 16, 24, 32, 40, 48, 56, 64, -1, -1, -1, -1, -1, -1, -1}, /* MPEG 2.5 */ - }; - - /** - * MPEG 2, MPEG 1, MPEG 2.5. - */ - public static final int samplerate_table[][] = { - {22050, 24000, 16000, -1}, - {44100, 48000, 32000, -1}, - {11025, 12000, 8000, -1}, - }; - - /** - * This is the scfsi_band table from 2.4.2.7 of the IS. - */ - static final int scfsi_band[] = { 0, 6, 11, 16, 21 }; -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Takehiro.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Takehiro.java deleted file mode 100644 index dbf70cf3e..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Takehiro.java +++ /dev/null @@ -1,1179 +0,0 @@ -/* - * MP3 huffman table selecting and bit counting - * - * Copyright (c) 1999-2005 Takehiro TOMINAGA - * Copyright (c) 2002-2005 Gabriel Bouvigne - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: Takehiro.java,v 1.26 2011/05/24 20:48:06 kenchis Exp $ */ - -package mp3; - -import java.util.Arrays; - - -public class Takehiro { - - QuantizePVT qupvt; - - public final void setModules(QuantizePVT qupvt) { - this.qupvt = qupvt; - } - - static class Bits { - public Bits(int b) { - bits = b; - } - - int bits; - } - - private int subdv_table[][] = { { 0, 0 }, /* 0 bands */ - { 0, 0 }, /* 1 bands */ - { 0, 0 }, /* 2 bands */ - { 0, 0 }, /* 3 bands */ - { 0, 0 }, /* 4 bands */ - { 0, 1 }, /* 5 bands */ - { 1, 1 }, /* 6 bands */ - { 1, 1 }, /* 7 bands */ - { 1, 2 }, /* 8 bands */ - { 2, 2 }, /* 9 bands */ - { 2, 3 }, /* 10 bands */ - { 2, 3 }, /* 11 bands */ - { 3, 4 }, /* 12 bands */ - { 3, 4 }, /* 13 bands */ - { 3, 4 }, /* 14 bands */ - { 4, 5 }, /* 15 bands */ - { 4, 5 }, /* 16 bands */ - { 4, 6 }, /* 17 bands */ - { 5, 6 }, /* 18 bands */ - { 5, 6 }, /* 19 bands */ - { 5, 7 }, /* 20 bands */ - { 6, 7 }, /* 21 bands */ - { 6, 7 }, /* 22 bands */ - }; - - /** - * nonlinear quantization of xr More accurate formula than the ISO formula. - * Takes into account the fact that we are quantizing xr . ix, but we want - * ix^4/3 to be as close as possible to x^4/3. (taking the nearest int would - * mean ix is as close as possible to xr, which is different.) - * - * From Segher Boessenkool <segher@eastsite.nl> 11/1999 - * - * 09/2000: ASM code removed in favor of IEEE754 hack by Takehiro Tominaga. - * If you need the ASM code, check CVS circa Aug 2000. - * - * 01/2004: Optimizations by Gabriel Bouvigne - */ - private void quantize_lines_xrpow_01(int l, float istep, final float[] xr, - int xrPos, int[] ix, int ixPos) { - final float compareval0 = (1.0f - 0.4054f) / istep; - - assert (l > 0); - l = l >> 1; - while ((l--) != 0) { - ix[ixPos++] = (compareval0 > xr[xrPos++]) ? 0 : 1; - ix[ixPos++] = (compareval0 > xr[xrPos++]) ? 0 : 1; - } - } - - /** - * XRPOW_FTOI is a macro to convert floats to ints.<BR> - * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x]<BR> - * ROUNDFAC= -0.0946<BR> - * - * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x]<BR> - * ROUNDFAC=0.4054<BR> - * - * Note: using floor() or (int) is extremely slow. On machines where the - * TAKEHIRO_IEEE754_HACK code above does not work, it is worthwile to write - * some ASM for XRPOW_FTOI(). - */ - private void quantize_lines_xrpow(int l, float istep, final float[] xr, - int xrPos, int[] ix, int ixPos) { - assert (l > 0); - - l = l >> 1; - int remaining = l % 2; - l = l >> 1; - while (l-- != 0) { - float x0, x1, x2, x3; - int rx0, rx1, rx2, rx3; - - x0 = xr[xrPos++] * istep; - x1 = xr[xrPos++] * istep; - rx0 = (int) x0; - x2 = xr[xrPos++] * istep; - rx1 = (int) x1; - x3 = xr[xrPos++] * istep; - rx2 = (int) x2; - x0 += qupvt.adj43[rx0]; - rx3 = (int) x3; - x1 += qupvt.adj43[rx1]; - ix[ixPos++] = (int) x0; - x2 += qupvt.adj43[rx2]; - ix[ixPos++] = (int) x1; - x3 += qupvt.adj43[rx3]; - ix[ixPos++] = (int) x2; - ix[ixPos++] = (int) x3; - } - if (remaining != 0) { - float x0, x1; - int rx0, rx1; - - x0 = xr[xrPos++] * istep; - x1 = xr[xrPos++] * istep; - rx0 = (int) x0; - rx1 = (int) x1; - x0 += qupvt.adj43[rx0]; - x1 += qupvt.adj43[rx1]; - ix[ixPos++] = (int) x0; - ix[ixPos++] = (int) x1; - } - } - - /** - * Quantization function This function will select which lines to quantize - * and call the proper quantization function - */ - private void quantize_xrpow(final float[] xp, int[] pi, float istep, - final GrInfo codInfo, final CalcNoiseData prevNoise) { - /* quantize on xr^(3/4) instead of xr */ - int sfb; - int sfbmax; - int j = 0; - boolean prev_data_use; - int accumulate = 0; - int accumulate01 = 0; - - int xpPos = 0; - - int[] iData = pi; - int iDataPos = 0; - int[] acc_iData = iData; - int acc_iDataPos = 0; - float[] acc_xp = xp; - int acc_xpPos = 0; - - /* - * Reusing previously computed data does not seems to work if global - * gain is changed. Finding why it behaves this way would allow to use a - * cache of previously computed values (let's 10 cached values per sfb) - * that would probably provide a noticeable speedup - */ - prev_data_use = (prevNoise != null && (codInfo.global_gain == prevNoise.global_gain)); - - if (codInfo.block_type == Encoder.SHORT_TYPE) - sfbmax = 38; - else - sfbmax = 21; - - for (sfb = 0; sfb <= sfbmax; sfb++) { - int step = -1; - - if (prev_data_use || codInfo.block_type == Encoder.NORM_TYPE) { - step = codInfo.global_gain - - ((codInfo.scalefac[sfb] + (codInfo.preflag != 0 ? qupvt.pretab[sfb] - : 0)) << (codInfo.scalefac_scale + 1)) - - codInfo.subblock_gain[codInfo.window[sfb]] * 8; - } - assert (codInfo.width[sfb] >= 0); - if (prev_data_use && (prevNoise.step[sfb] == step)) { - /* - * do not recompute this part, but compute accumulated lines - */ - if (accumulate != 0) { - quantize_lines_xrpow(accumulate, istep, acc_xp, acc_xpPos, - acc_iData, acc_iDataPos); - accumulate = 0; - } - if (accumulate01 != 0) { - quantize_lines_xrpow_01(accumulate01, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate01 = 0; - } - } else { /* should compute this part */ - int l = codInfo.width[sfb]; - - if ((j + codInfo.width[sfb]) > codInfo.max_nonzero_coeff) { - /* do not compute upper zero part */ - int usefullsize; - usefullsize = codInfo.max_nonzero_coeff - j + 1; - Arrays.fill(pi, codInfo.max_nonzero_coeff, 576, 0); - l = usefullsize; - - if (l < 0) { - l = 0; - } - - /* no need to compute higher sfb values */ - sfb = sfbmax + 1; - } - - /* accumulate lines to quantize */ - if (0 == accumulate && 0 == accumulate01) { - acc_iData = iData; - acc_iDataPos = iDataPos; - acc_xp = xp; - acc_xpPos = xpPos; - } - if (prevNoise != null && prevNoise.sfb_count1 > 0 - && sfb >= prevNoise.sfb_count1 - && prevNoise.step[sfb] > 0 - && step >= prevNoise.step[sfb]) { - - if (accumulate != 0) { - quantize_lines_xrpow(accumulate, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate = 0; - acc_iData = iData; - acc_iDataPos = iDataPos; - acc_xp = xp; - acc_xpPos = xpPos; - } - accumulate01 += l; - } else { - if (accumulate01 != 0) { - quantize_lines_xrpow_01(accumulate01, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate01 = 0; - acc_iData = iData; - acc_iDataPos = iDataPos; - acc_xp = xp; - acc_xpPos = xpPos; - } - accumulate += l; - } - - if (l <= 0) { - /* - * rh: 20040215 may happen due to "prev_data_use" - * optimization - */ - if (accumulate01 != 0) { - quantize_lines_xrpow_01(accumulate01, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate01 = 0; - } - if (accumulate != 0) { - quantize_lines_xrpow(accumulate, istep, acc_xp, - acc_xpPos, acc_iData, acc_iDataPos); - accumulate = 0; - } - - break; /* ends for-loop */ - } - } - if (sfb <= sfbmax) { - iDataPos += codInfo.width[sfb]; - xpPos += codInfo.width[sfb]; - j += codInfo.width[sfb]; - } - } - if (accumulate != 0) { /* last data part */ - quantize_lines_xrpow(accumulate, istep, acc_xp, acc_xpPos, - acc_iData, acc_iDataPos); - accumulate = 0; - } - if (accumulate01 != 0) { /* last data part */ - quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_xpPos, - acc_iData, acc_iDataPos); - accumulate01 = 0; - } - - } - - /** - * ix_max - */ - private int ix_max(final int[] ix, int ixPos, final int endPos) { - int max1 = 0, max2 = 0; - - do { - final int x1 = ix[ixPos++]; - final int x2 = ix[ixPos++]; - if (max1 < x1) - max1 = x1; - - if (max2 < x2) - max2 = x2; - } while (ixPos < endPos); - if (max1 < max2) - max1 = max2; - return max1; - } - - private int count_bit_ESC(final int[] ix, int ixPos, final int end, int t1, - final int t2, Bits s) { - /* ESC-table is used */ - final int linbits = Tables.ht[t1].xlen * 65536 + Tables.ht[t2].xlen; - int sum = 0, sum2; - - do { - int x = ix[ixPos++]; - int y = ix[ixPos++]; - - if (x != 0) { - if (x > 14) { - x = 15; - sum += linbits; - } - x *= 16; - } - - if (y != 0) { - if (y > 14) { - y = 15; - sum += linbits; - } - x += y; - } - - sum += Tables.largetbl[x]; - } while (ixPos < end); - - sum2 = sum & 0xffff; - sum >>= 16; - - if (sum > sum2) { - sum = sum2; - t1 = t2; - } - - s.bits += sum; - return t1; - } - - private int count_bit_noESC(final int[] ix, int ixPos, final int end, Bits s) { - /* No ESC-words */ - int sum1 = 0; - final int[] hlen1 = Tables.ht[1].hlen; - - do { - final int x = ix[ixPos + 0] * 2 + ix[ixPos + 1]; - ixPos += 2; - sum1 += hlen1[x]; - } while (ixPos < end); - - s.bits += sum1; - return 1; - } - - private int count_bit_noESC_from2(final int[] ix, int ixPos, final int end, - int t1, Bits s) { - /* No ESC-words */ - int sum = 0, sum2; - final int xlen = Tables.ht[t1].xlen; - final int[] hlen; - if (t1 == 2) - hlen = Tables.table23; - else - hlen = Tables.table56; - - do { - final int x = ix[ixPos + 0] * xlen + ix[ixPos + 1]; - ixPos += 2; - sum += hlen[x]; - } while (ixPos < end); - - sum2 = sum & 0xffff; - sum >>= 16; - - if (sum > sum2) { - sum = sum2; - t1++; - } - - s.bits += sum; - return t1; - } - - private int count_bit_noESC_from3(final int[] ix, int ixPos, final int end, - int t1, Bits s) { - /* No ESC-words */ - int sum1 = 0; - int sum2 = 0; - int sum3 = 0; - final int xlen = Tables.ht[t1].xlen; - final int[] hlen1 = Tables.ht[t1].hlen; - final int[] hlen2 = Tables.ht[t1 + 1].hlen; - final int[] hlen3 = Tables.ht[t1 + 2].hlen; - - do { - final int x = ix[ixPos + 0] * xlen + ix[ixPos + 1]; - ixPos += 2; - sum1 += hlen1[x]; - sum2 += hlen2[x]; - sum3 += hlen3[x]; - } while (ixPos < end); - - int t = t1; - if (sum1 > sum2) { - sum1 = sum2; - t++; - } - if (sum1 > sum3) { - sum1 = sum3; - t = t1 + 2; - } - s.bits += sum1; - - return t; - } - - /*************************************************************************/ - /* choose table */ - /*************************************************************************/ - - private final static int huf_tbl_noESC[] = { 1, 2, 5, 7, 7, 10, 10, 13, 13, - 13, 13, 13, 13, 13, 13 }; - - /** - * Choose the Huffman table that will encode ix[begin..end] with the fewest - * bits. - * - * Note: This code contains knowledge about the sizes and characteristics of - * the Huffman tables as defined in the IS (Table B.7), and will not work - * with any arbitrary tables. - */ - private int choose_table(final int[] ix, final int ixPos, final int endPos, - final Bits s) { - int max = ix_max(ix, ixPos, endPos); - - switch (max) { - case 0: - return max; - - case 1: - return count_bit_noESC(ix, ixPos, endPos, s); - - case 2: - case 3: - return count_bit_noESC_from2(ix, ixPos, endPos, - huf_tbl_noESC[max - 1], s); - - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - return count_bit_noESC_from3(ix, ixPos, endPos, - huf_tbl_noESC[max - 1], s); - - default: - /* try tables with linbits */ - if (max > QuantizePVT.IXMAX_VAL) { - s.bits = QuantizePVT.LARGE_BITS; - return -1; - } - max -= 15; - int choice2; - for (choice2 = 24; choice2 < 32; choice2++) { - if (Tables.ht[choice2].linmax >= max) { - break; - } - } - int choice; - for (choice = choice2 - 8; choice < 24; choice++) { - if (Tables.ht[choice].linmax >= max) { - break; - } - } - return count_bit_ESC(ix, ixPos, endPos, choice, choice2, s); - } - } - - /** - * count_bit - */ - public int noquant_count_bits(final LameInternalFlags gfc, - final GrInfo gi, CalcNoiseData prev_noise) { - final int[] ix = gi.l3_enc; - - int i = Math.min(576, ((gi.max_nonzero_coeff + 2) >> 1) << 1); - - if (prev_noise != null) - prev_noise.sfb_count1 = 0; - - /* Determine count1 region */ - for (; i > 1; i -= 2) - if ((ix[i - 1] | ix[i - 2]) != 0) - break; - gi.count1 = i; - - /* Determines the number of bits to encode the quadruples. */ - int a1 = 0; - int a2 = 0; - for (; i > 3; i -= 4) { - int p; - /* hack to check if all values <= 1 */ - if ((((long) ix[i - 1] | (long) ix[i - 2] | (long) ix[i - 3] | (long) ix[i - 4]) & 0xffffffffL) > 1L) - break; - - p = ((ix[i - 4] * 2 + ix[i - 3]) * 2 + ix[i - 2]) * 2 + ix[i - 1]; - a1 += Tables.t32l[p]; - a2 += Tables.t33l[p]; - } - - int bits = a1; - gi.count1table_select = 0; - if (a1 > a2) { - bits = a2; - gi.count1table_select = 1; - } - - gi.count1bits = bits; - gi.big_values = i; - if (i == 0) - return bits; - - if (gi.block_type == Encoder.SHORT_TYPE) { - a1 = 3 * gfc.scalefac_band.s[3]; - if (a1 > gi.big_values) - a1 = gi.big_values; - a2 = gi.big_values; - - } else if (gi.block_type == Encoder.NORM_TYPE) { - assert (i <= 576); /* bv_scf has 576 entries (0..575) */ - a1 = gi.region0_count = gfc.bv_scf[i - 2]; - a2 = gi.region1_count = gfc.bv_scf[i - 1]; - - assert (a1 + a2 + 2 < Encoder.SBPSY_l); - a2 = gfc.scalefac_band.l[a1 + a2 + 2]; - a1 = gfc.scalefac_band.l[a1 + 1]; - if (a2 < i) { - Bits bi = new Bits(bits); - gi.table_select[2] = choose_table(ix, a2, i, bi); - bits = bi.bits; - } - } else { - gi.region0_count = 7; - /* gi.region1_count = SBPSY_l - 7 - 1; */ - gi.region1_count = Encoder.SBMAX_l - 1 - 7 - 1; - a1 = gfc.scalefac_band.l[7 + 1]; - a2 = i; - if (a1 > a2) { - a1 = a2; - } - } - - /* have to allow for the case when bigvalues < region0 < region1 */ - /* (and region0, region1 are ignored) */ - a1 = Math.min(a1, i); - a2 = Math.min(a2, i); - - assert (a1 >= 0); - assert (a2 >= 0); - - /* Count the number of bits necessary to code the bigvalues region. */ - if (0 < a1) { - Bits bi = new Bits(bits); - gi.table_select[0] = choose_table(ix, 0, a1, bi); - bits = bi.bits; - } - if (a1 < a2) { - Bits bi = new Bits(bits); - gi.table_select[1] = choose_table(ix, a1, a2, bi); - bits = bi.bits; - } - if (gfc.use_best_huffman == 2) { - gi.part2_3_length = bits; - best_huffman_divide(gfc, gi); - bits = gi.part2_3_length; - } - - if (prev_noise != null) { - if (gi.block_type == Encoder.NORM_TYPE) { - int sfb = 0; - while (gfc.scalefac_band.l[sfb] < gi.big_values) { - sfb++; - } - prev_noise.sfb_count1 = sfb; - } - } - - return bits; - } - - public int count_bits(final LameInternalFlags gfc, final float[] xr, - final GrInfo gi, CalcNoiseData prev_noise) { - final int[] ix = gi.l3_enc; - - /* since quantize_xrpow uses table lookup, we need to check this first: */ - final float w = (QuantizePVT.IXMAX_VAL) / qupvt.IPOW20(gi.global_gain); - - if (gi.xrpow_max > w) - return QuantizePVT.LARGE_BITS; - - quantize_xrpow(xr, ix, qupvt.IPOW20(gi.global_gain), gi, prev_noise); - - if ((gfc.substep_shaping & 2) != 0) { - int j = 0; - /* 0.634521682242439 = 0.5946*2**(.5*0.1875) */ - final int gain = gi.global_gain + gi.scalefac_scale; - final float roundfac = 0.634521682242439f / qupvt.IPOW20(gain); - for (int sfb = 0; sfb < gi.sfbmax; sfb++) { - final int width = gi.width[sfb]; - assert (width >= 0); - if (0 == gfc.pseudohalf[sfb]) { - j += width; - } else { - int k; - for (k = j, j += width; k < j; ++k) { - ix[k] = (xr[k] >= roundfac) ? ix[k] : 0; - } - } - } - } - return noquant_count_bits(gfc, gi, prev_noise); - } - - /** - * re-calculate the best scalefac_compress using scfsi the saved bits are - * kept in the bit reservoir. - */ - private void recalc_divide_init(final LameInternalFlags gfc, - final GrInfo cod_info, final int[] ix, int r01_bits[], - int r01_div[], int r0_tbl[], int r1_tbl[]) { - int bigv = cod_info.big_values; - - for (int r0 = 0; r0 <= 7 + 15; r0++) { - r01_bits[r0] = QuantizePVT.LARGE_BITS; - } - - for (int r0 = 0; r0 < 16; r0++) { - final int a1 = gfc.scalefac_band.l[r0 + 1]; - if (a1 >= bigv) - break; - int r0bits = 0; - Bits bi = new Bits(r0bits); - int r0t = choose_table(ix, 0, a1, bi); - r0bits = bi.bits; - - for (int r1 = 0; r1 < 8; r1++) { - final int a2 = gfc.scalefac_band.l[r0 + r1 + 2]; - if (a2 >= bigv) - break; - - int bits = r0bits; - bi = new Bits(bits); - int r1t = choose_table(ix, a1, a2, bi); - bits = bi.bits; - if (r01_bits[r0 + r1] > bits) { - r01_bits[r0 + r1] = bits; - r01_div[r0 + r1] = r0; - r0_tbl[r0 + r1] = r0t; - r1_tbl[r0 + r1] = r1t; - } - } - } - } - - private void recalc_divide_sub(final LameInternalFlags gfc, - final GrInfo cod_info2, GrInfo gi, final int[] ix, - final int r01_bits[], final int r01_div[], final int r0_tbl[], - final int r1_tbl[]) { - int bigv = cod_info2.big_values; - - for (int r2 = 2; r2 < Encoder.SBMAX_l + 1; r2++) { - int a2 = gfc.scalefac_band.l[r2]; - if (a2 >= bigv) - break; - - int bits = r01_bits[r2 - 2] + cod_info2.count1bits; - if (gi.part2_3_length <= bits) - break; - - Bits bi = new Bits(bits); - int r2t = choose_table(ix, a2, bigv, bi); - bits = bi.bits; - if (gi.part2_3_length <= bits) - continue; - - gi.assign(cod_info2); - gi.part2_3_length = bits; - gi.region0_count = r01_div[r2 - 2]; - gi.region1_count = r2 - 2 - r01_div[r2 - 2]; - gi.table_select[0] = r0_tbl[r2 - 2]; - gi.table_select[1] = r1_tbl[r2 - 2]; - gi.table_select[2] = r2t; - } - } - - public void best_huffman_divide(final LameInternalFlags gfc, - GrInfo gi) { - GrInfo cod_info2 = new GrInfo(); - final int[] ix = gi.l3_enc; - - int r01_bits[] = new int[7 + 15 + 1]; - int r01_div[] = new int[7 + 15 + 1]; - int r0_tbl[] = new int[7 + 15 + 1]; - int r1_tbl[] = new int[7 + 15 + 1]; - - /* SHORT BLOCK stuff fails for MPEG2 */ - if (gi.block_type == Encoder.SHORT_TYPE && gfc.mode_gr == 1) - return; - - cod_info2.assign(gi); - if (gi.block_type == Encoder.NORM_TYPE) { - recalc_divide_init(gfc, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl); - recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div, - r0_tbl, r1_tbl); - } - - int i = cod_info2.big_values; - if (i == 0 || (ix[i - 2] | ix[i - 1]) > 1) - return; - - i = gi.count1 + 2; - if (i > 576) - return; - - /* Determines the number of bits to encode the quadruples. */ - cod_info2.assign(gi); - cod_info2.count1 = i; - int a1 = 0; - int a2 = 0; - - assert (i <= 576); - - for (; i > cod_info2.big_values; i -= 4) { - final int p = ((ix[i - 4] * 2 + ix[i - 3]) * 2 + ix[i - 2]) * 2 - + ix[i - 1]; - a1 += Tables.t32l[p]; - a2 += Tables.t33l[p]; - } - cod_info2.big_values = i; - - cod_info2.count1table_select = 0; - if (a1 > a2) { - a1 = a2; - cod_info2.count1table_select = 1; - } - - cod_info2.count1bits = a1; - - if (cod_info2.block_type == Encoder.NORM_TYPE) - recalc_divide_sub(gfc, cod_info2, gi, ix, r01_bits, r01_div, - r0_tbl, r1_tbl); - else { - /* Count the number of bits necessary to code the bigvalues region. */ - cod_info2.part2_3_length = a1; - a1 = gfc.scalefac_band.l[7 + 1]; - if (a1 > i) { - a1 = i; - } - if (a1 > 0) { - Bits bi = new Bits(cod_info2.part2_3_length); - cod_info2.table_select[0] = choose_table(ix, 0, a1, bi); - cod_info2.part2_3_length = bi.bits; - } - if (i > a1) { - Bits bi = new Bits(cod_info2.part2_3_length); - cod_info2.table_select[1] = choose_table(ix, a1, i, bi); - cod_info2.part2_3_length = bi.bits; - } - if (gi.part2_3_length > cod_info2.part2_3_length) - gi.assign(cod_info2); - } - } - - private static final int slen1_n[] = { 1, 1, 1, 1, 8, 2, 2, 2, 4, 4, 4, 8, - 8, 8, 16, 16 }; - private static final int slen2_n[] = { 1, 2, 4, 8, 1, 2, 4, 8, 2, 4, 8, 2, - 4, 8, 4, 8 }; - public static final int slen1_tab[] = { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, - 3, 3, 4, 4 }; - public static final int slen2_tab[] = { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, - 2, 3, 2, 3 }; - - private void scfsi_calc(int ch, final IIISideInfo l3_side) { - int sfb; - final GrInfo gi = l3_side.tt[1][ch]; - final GrInfo g0 = l3_side.tt[0][ch]; - - for (int i = 0; i < Tables.scfsi_band.length - 1; i++) { - for (sfb = Tables.scfsi_band[i]; sfb < Tables.scfsi_band[i + 1]; sfb++) { - if (g0.scalefac[sfb] != gi.scalefac[sfb] - && gi.scalefac[sfb] >= 0) - break; - } - if (sfb == Tables.scfsi_band[i + 1]) { - for (sfb = Tables.scfsi_band[i]; sfb < Tables.scfsi_band[i + 1]; sfb++) { - gi.scalefac[sfb] = -1; - } - l3_side.scfsi[ch][i] = 1; - } - } - - int s1 = 0; - int c1 = 0; - for (sfb = 0; sfb < 11; sfb++) { - if (gi.scalefac[sfb] == -1) - continue; - c1++; - if (s1 < gi.scalefac[sfb]) - s1 = gi.scalefac[sfb]; - } - - int s2 = 0; - int c2 = 0; - for (; sfb < Encoder.SBPSY_l; sfb++) { - if (gi.scalefac[sfb] == -1) - continue; - c2++; - if (s2 < gi.scalefac[sfb]) - s2 = gi.scalefac[sfb]; - } - - for (int i = 0; i < 16; i++) { - if (s1 < slen1_n[i] && s2 < slen2_n[i]) { - final int c = slen1_tab[i] * c1 + slen2_tab[i] * c2; - if (gi.part2_length > c) { - gi.part2_length = c; - gi.scalefac_compress = i; - } - } - } - } - - /** - * Find the optimal way to store the scalefactors. Only call this routine - * after final scalefactors have been chosen and the channel/granule will - * not be re-encoded. - */ - public void best_scalefac_store(final LameInternalFlags gfc, final int gr, - final int ch, final IIISideInfo l3_side) { - /* use scalefac_scale if we can */ - final GrInfo gi = l3_side.tt[gr][ch]; - int sfb, i, j, l; - int recalc = 0; - - /* - * remove scalefacs from bands with ix=0. This idea comes from the AAC - * ISO docs. added mt 3/00 - */ - /* check if l3_enc=0 */ - j = 0; - for (sfb = 0; sfb < gi.sfbmax; sfb++) { - final int width = gi.width[sfb]; - assert (width >= 0); - j += width; - for (l = -width; l < 0; l++) { - if (gi.l3_enc[l + j] != 0) - break; - } - if (l == 0) - gi.scalefac[sfb] = recalc = -2; /* anything goes. */ - /* - * only best_scalefac_store and calc_scfsi know--and only they - * should know--about the magic number -2. - */ - } - - if (0 == gi.scalefac_scale && 0 == gi.preflag) { - int s = 0; - for (sfb = 0; sfb < gi.sfbmax; sfb++) - if (gi.scalefac[sfb] > 0) - s |= gi.scalefac[sfb]; - - if (0 == (s & 1) && s != 0) { - for (sfb = 0; sfb < gi.sfbmax; sfb++) - if (gi.scalefac[sfb] > 0) - gi.scalefac[sfb] >>= 1; - - gi.scalefac_scale = recalc = 1; - } - } - - if (0 == gi.preflag && gi.block_type != Encoder.SHORT_TYPE - && gfc.mode_gr == 2) { - for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) - if (gi.scalefac[sfb] < qupvt.pretab[sfb] - && gi.scalefac[sfb] != -2) - break; - if (sfb == Encoder.SBPSY_l) { - for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) - if (gi.scalefac[sfb] > 0) - gi.scalefac[sfb] -= qupvt.pretab[sfb]; - - gi.preflag = recalc = 1; - } - } - - for (i = 0; i < 4; i++) - l3_side.scfsi[ch][i] = 0; - - if (gfc.mode_gr == 2 && gr == 1 - && l3_side.tt[0][ch].block_type != Encoder.SHORT_TYPE - && l3_side.tt[1][ch].block_type != Encoder.SHORT_TYPE) { - scfsi_calc(ch, l3_side); - recalc = 0; - } - for (sfb = 0; sfb < gi.sfbmax; sfb++) { - if (gi.scalefac[sfb] == -2) { - gi.scalefac[sfb] = 0; /* if anything goes, then 0 is a good choice */ - } - } - if (recalc != 0) { - if (gfc.mode_gr == 2) { - scale_bitcount(gi); - } else { - scale_bitcount_lsf(gfc, gi); - } - } - } - - private boolean all_scalefactors_not_negative(final int[] scalefac, int n) { - for (int i = 0; i < n; ++i) { - if (scalefac[i] < 0) - return false; - } - return true; - } - - /** - * number of bits used to encode scalefacs. - * - * 18*slen1_tab[i] + 18*slen2_tab[i] - */ - private static final int scale_short[] = { 0, 18, 36, 54, 54, 36, 54, 72, - 54, 72, 90, 72, 90, 108, 108, 126 }; - - /** - * number of bits used to encode scalefacs. - * - * 17*slen1_tab[i] + 18*slen2_tab[i] - */ - private static final int scale_mixed[] = { 0, 18, 36, 54, 51, 35, 53, 71, - 52, 70, 88, 69, 87, 105, 104, 122 }; - - /** - * number of bits used to encode scalefacs. - * - * 11*slen1_tab[i] + 10*slen2_tab[i] - */ - private static final int scale_long[] = { 0, 10, 20, 30, 33, 21, 31, 41, 32, 42, - 52, 43, 53, 63, 64, 74 }; - - /** - * Also calculates the number of bits necessary to code the scalefactors. - */ - public boolean scale_bitcount(final GrInfo cod_info) { - int k, sfb, max_slen1 = 0, max_slen2 = 0; - - /* maximum values */ - int[] tab; - final int[] scalefac = cod_info.scalefac; - - assert (all_scalefactors_not_negative(scalefac, cod_info.sfbmax)); - - if (cod_info.block_type == Encoder.SHORT_TYPE) { - tab = scale_short; - if (cod_info.mixed_block_flag != 0) - tab = scale_mixed; - } else { /* block_type == 1,2,or 3 */ - tab = scale_long; - if (0 == cod_info.preflag) { - for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) - if (scalefac[sfb] < qupvt.pretab[sfb]) - break; - - if (sfb == Encoder.SBPSY_l) { - cod_info.preflag = 1; - for (sfb = 11; sfb < Encoder.SBPSY_l; sfb++) - scalefac[sfb] -= qupvt.pretab[sfb]; - } - } - } - - for (sfb = 0; sfb < cod_info.sfbdivide; sfb++) - if (max_slen1 < scalefac[sfb]) - max_slen1 = scalefac[sfb]; - - for (; sfb < cod_info.sfbmax; sfb++) - if (max_slen2 < scalefac[sfb]) - max_slen2 = scalefac[sfb]; - - /* - * from Takehiro TOMINAGA <tominaga@isoternet.org> 10/99 loop over *all* - * posible values of scalefac_compress to find the one which uses the - * smallest number of bits. ISO would stop at first valid index - */ - cod_info.part2_length = QuantizePVT.LARGE_BITS; - for (k = 0; k < 16; k++) { - if (max_slen1 < slen1_n[k] && max_slen2 < slen2_n[k] - && cod_info.part2_length > tab[k]) { - cod_info.part2_length = tab[k]; - cod_info.scalefac_compress = k; - } - } - return cod_info.part2_length == QuantizePVT.LARGE_BITS; - } - - /** - * table of largest scalefactor values for MPEG2 - */ - private static final int max_range_sfac_tab[][] = { { 15, 15, 7, 7 }, - { 15, 15, 7, 0 }, { 7, 3, 0, 0 }, { 15, 31, 31, 0 }, - { 7, 7, 7, 0 }, { 3, 3, 0, 0 } }; - - /** - * Also counts the number of bits to encode the scalefacs but for MPEG 2 - * Lower sampling frequencies (24, 22.05 and 16 kHz.) - * - * This is reverse-engineered from section 2.4.3.2 of the MPEG2 IS, - * "Audio Decoding Layer III" - */ - public boolean scale_bitcount_lsf(final LameInternalFlags gfc, - final GrInfo cod_info) { - int table_number, row_in_table, partition, nr_sfb, window; - boolean over; - int i, sfb, max_sfac[] = new int[4]; - final int[] partition_table; - final int[] scalefac = cod_info.scalefac; - - /* - * Set partition table. Note that should try to use table one, but do - * not yet... - */ - if (cod_info.preflag != 0) - table_number = 2; - else - table_number = 0; - - for (i = 0; i < 4; i++) - max_sfac[i] = 0; - - if (cod_info.block_type == Encoder.SHORT_TYPE) { - row_in_table = 1; - partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table]; - for (sfb = 0, partition = 0; partition < 4; partition++) { - nr_sfb = partition_table[partition] / 3; - for (i = 0; i < nr_sfb; i++, sfb++) - for (window = 0; window < 3; window++) - if (scalefac[sfb * 3 + window] > max_sfac[partition]) - max_sfac[partition] = scalefac[sfb * 3 + window]; - } - } else { - row_in_table = 0; - partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table]; - for (sfb = 0, partition = 0; partition < 4; partition++) { - nr_sfb = partition_table[partition]; - for (i = 0; i < nr_sfb; i++, sfb++) - if (scalefac[sfb] > max_sfac[partition]) - max_sfac[partition] = scalefac[sfb]; - } - } - - for (over = false, partition = 0; partition < 4; partition++) { - if (max_sfac[partition] > max_range_sfac_tab[table_number][partition]) - over = true; - } - if (!over) { - - int slen1, slen2, slen3, slen4; - - cod_info.sfb_partition_table = qupvt.nr_of_sfb_block[table_number][row_in_table]; - for (partition = 0; partition < 4; partition++) - cod_info.slen[partition] = log2tab[max_sfac[partition]]; - - /* set scalefac_compress */ - slen1 = cod_info.slen[0]; - slen2 = cod_info.slen[1]; - slen3 = cod_info.slen[2]; - slen4 = cod_info.slen[3]; - - switch (table_number) { - case 0: - cod_info.scalefac_compress = (((slen1 * 5) + slen2) << 4) - + (slen3 << 2) + slen4; - break; - - case 1: - cod_info.scalefac_compress = 400 + (((slen1 * 5) + slen2) << 2) - + slen3; - break; - - case 2: - cod_info.scalefac_compress = 500 + (slen1 * 3) + slen2; - break; - - default: - System.err.printf("intensity stereo not implemented yet\n"); - break; - } - } - if (!over) { - assert (cod_info.sfb_partition_table != null); - cod_info.part2_length = 0; - for (partition = 0; partition < 4; partition++) - cod_info.part2_length += cod_info.slen[partition] - * cod_info.sfb_partition_table[partition]; - } - return over; - } - - /* - * Since no bands have been over-amplified, we can set scalefac_compress and - * slen[] for the formatter - */ - private static final int log2tab[] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, - 4, 4, 4, 4 }; - - public void huffman_init(final LameInternalFlags gfc) { - for (int i = 2; i <= 576; i += 2) { - int scfb_anz = 0, bv_index; - while (gfc.scalefac_band.l[++scfb_anz] < i) - ; - - bv_index = subdv_table[scfb_anz][0]; // .region0_count - while (gfc.scalefac_band.l[bv_index + 1] > i) - bv_index--; - - if (bv_index < 0) { - /* - * this is an indication that everything is going to be encoded - * as region0: bigvalues < region0 < region1 so lets set - * region0, region1 to some value larger than bigvalues - */ - bv_index = subdv_table[scfb_anz][0]; // .region0_count - } - - gfc.bv_scf[i - 2] = bv_index; - - bv_index = subdv_table[scfb_anz][1]; // .region1_count - while (gfc.scalefac_band.l[bv_index + gfc.bv_scf[i - 2] + 2] > i) - bv_index--; - - if (bv_index < 0) { - bv_index = subdv_table[scfb_anz][1]; // .region1_count - } - - gfc.bv_scf[i - 1] = bv_index; - } - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Util.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Util.java deleted file mode 100644 index 86c6d1d7e..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Util.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * lame utility library include file - * - * Copyright (c) 1999 Albert L Faber - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: Util.java,v 1.16 2011/05/24 21:27:00 kenchis Exp $ */ - -package mp3; - - -public class Util { - - public static final float SQRT2 = 1.41421356237309504880f; - - public static float FAST_LOG10(float x) { - return (float) Math.log10(x); - } - public static float FAST_LOG10_X(float x,float y) { - return (float) Math.log10(x)*y; - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRNewIterationLoop.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRNewIterationLoop.java deleted file mode 100644 index 4d1518c64..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRNewIterationLoop.java +++ /dev/null @@ -1,97 +0,0 @@ -package mp3; - -public final class VBRNewIterationLoop implements IIterationLoop { - - /** - * - */ - private final Quantize quantize; - - /** - * @param quantize - */ - VBRNewIterationLoop(Quantize quantize) { - this.quantize = quantize; - } - - public final void iteration_loop(final LameGlobalFlags gfp, - final float[][] pe, final float[] ms_ener_ratio, - final III_psy_ratio[][] ratio) { - LameInternalFlags gfc = gfp.internal_flags; - float l3_xmin[][][] = new float[2][2][L3Side.SFBMAX]; - - float xrpow[][][] = new float[2][2][576]; - int frameBits[] = new int[15]; - int max_bits[][] = new int[2][2]; - final IIISideInfo l3_side = gfc.l3_side; - - int analog_silence = this.quantize.VBR_new_prepare(gfp, pe, ratio, l3_xmin, - frameBits, max_bits); - - for (int gr = 0; gr < gfc.mode_gr; gr++) { - for (int ch = 0; ch < gfc.channels_out; ch++) { - final GrInfo cod_info = l3_side.tt[gr][ch]; - - /* - * init_outer_loop sets up cod_info, scalefac and xrpow - */ - if (!this.quantize.init_xrpow(gfc, cod_info, xrpow[gr][ch])) { - /* silent granule needs no bits */ - max_bits[gr][ch] = 0; - } - } /* for ch */ - } /* for gr */ - - /* - * quantize granules with lowest possible number of bits - */ - - int used_bits = this.quantize.vbr.VBR_encode_frame(gfc, xrpow, l3_xmin, max_bits); - - if (!gfp.free_format) { - /* - * find lowest bitrate able to hold used bits - */ - if (analog_silence != 0 && 0 == gfp.VBR_hard_min) { - /* - * we detected analog silence and the user did not specify - * any hard framesize limit, so start with smallest possible - * frame - */ - gfc.bitrate_index = 1; - } else { - gfc.bitrate_index = gfc.VBR_min_bitrate; - } - - for (; gfc.bitrate_index < gfc.VBR_max_bitrate; gfc.bitrate_index++) { - if (used_bits <= frameBits[gfc.bitrate_index]) - break; - } - if (gfc.bitrate_index > gfc.VBR_max_bitrate) { - gfc.bitrate_index = gfc.VBR_max_bitrate; - } - } else { - gfc.bitrate_index = 0; - } - if (used_bits <= frameBits[gfc.bitrate_index]) { - /* update Reservoire status */ - int mean_bits = 0, fullframebits; - MeanBits mb = new MeanBits(mean_bits); - fullframebits = this.quantize.rv.ResvFrameBegin(gfp, mb); - mean_bits = mb.bits; - assert (used_bits <= fullframebits); - for (int gr = 0; gr < gfc.mode_gr; gr++) { - for (int ch = 0; ch < gfc.channels_out; ch++) { - final GrInfo cod_info = l3_side.tt[gr][ch]; - this.quantize.rv.ResvAdjust(gfc, cod_info); - } - } - this.quantize.rv.ResvFrameEnd(gfc, mean_bits); - } else { - /* - * SHOULD NOT HAPPEN INTERNAL ERROR - */ - throw new RuntimeException("INTERNAL ERROR IN VBR NEW CODE, please send bug report"); - } - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBROldIterationLoop.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBROldIterationLoop.java deleted file mode 100644 index 2346adab7..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBROldIterationLoop.java +++ /dev/null @@ -1,119 +0,0 @@ -package mp3; - -/** - * tries to find out how many bits are needed for each granule and channel - * to get an acceptable quantization. An appropriate bitrate will then be - * choosed for quantization. rh 8/99 - * - * Robert Hegemann 2000-09-06 rewrite - * - * @author Ken - * - */ -public final class VBROldIterationLoop implements IIterationLoop { - - /** - * - */ - private final Quantize quantize; - - /** - * @param quantize - */ - VBROldIterationLoop(Quantize quantize) { - this.quantize = quantize; - } - - public void iteration_loop(LameGlobalFlags gfp, float[][] pe, - float[] ms_ener_ratio, III_psy_ratio[][] ratio) { - final LameInternalFlags gfc = gfp.internal_flags; - float l3_xmin[][][] = new float[2][2][L3Side.SFBMAX]; - - float xrpow[] = new float[576]; - int bands[][] = new int[2][2]; - int frameBits[] = new int[15]; - int min_bits[][] = new int[2][2], max_bits[][] = new int[2][2]; - int mean_bits = 0; - final IIISideInfo l3_side = gfc.l3_side; - - int analog_silence = this.quantize.VBR_old_prepare(gfp, pe, ms_ener_ratio, ratio, - l3_xmin, frameBits, min_bits, max_bits, bands); - - /*---------------------------------*/ - for (;;) { - /* - * quantize granules with lowest possible number of bits - */ - int used_bits = 0; - - for (int gr = 0; gr < gfc.mode_gr; gr++) { - for (int ch = 0; ch < gfc.channels_out; ch++) { - final GrInfo cod_info = l3_side.tt[gr][ch]; - - /* - * init_outer_loop sets up cod_info, scalefac and xrpow - */ - boolean ret = this.quantize.init_xrpow(gfc, cod_info, xrpow); - if (!ret || max_bits[gr][ch] == 0) { - /* - * xr contains no energy l3_enc, our encoding data, - * will be quantized to zero - */ - continue; /* with next channel */ - } - - this.quantize.VBR_encode_granule(gfp, cod_info, l3_xmin[gr][ch], - xrpow, ch, min_bits[gr][ch], max_bits[gr][ch]); - - /* - * do the 'substep shaping' - */ - if ((gfc.substep_shaping & 1) != 0) { - this.quantize.trancate_smallspectrums(gfc, l3_side.tt[gr][ch], - l3_xmin[gr][ch], xrpow); - } - - int usedB = cod_info.part2_3_length - + cod_info.part2_length; - used_bits += usedB; - } /* for ch */ - } /* for gr */ - - /* - * find lowest bitrate able to hold used bits - */ - if (analog_silence != 0 && 0 == gfp.VBR_hard_min) - /* - * we detected analog silence and the user did not specify - * any hard framesize limit, so start with smallest possible - * frame - */ - gfc.bitrate_index = 1; - else - gfc.bitrate_index = gfc.VBR_min_bitrate; - - for (; gfc.bitrate_index < gfc.VBR_max_bitrate; gfc.bitrate_index++) { - if (used_bits <= frameBits[gfc.bitrate_index]) - break; - } - MeanBits mb = new MeanBits(mean_bits); - int bits = this.quantize.rv.ResvFrameBegin(gfp, mb); - mean_bits = mb.bits; - - if (used_bits <= bits) - break; - - this.quantize.bitpressure_strategy(gfc, l3_xmin, min_bits, max_bits); - - } - /* breaks adjusted */ - /*--------------------------------------*/ - - for (int gr = 0; gr < gfc.mode_gr; gr++) { - for (int ch = 0; ch < gfc.channels_out; ch++) { - this.quantize.iteration_finish_one(gfc, gr, ch); - } /* for ch */ - } /* for gr */ - this.quantize.rv.ResvFrameEnd(gfc, mean_bits); - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRPresets.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRPresets.java deleted file mode 100644 index 63656e4f4..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRPresets.java +++ /dev/null @@ -1,44 +0,0 @@ -package mp3; - -class VBRPresets { - public VBRPresets(final int qual, final int comp, final int compS, - final int y, final float shThreshold, final float shThresholdS, - final float adj, final float adjShort, final float lower, - final float curve, final float sens, final float inter, - final int joint, final int mod, final float fix) { - vbr_q = qual; - quant_comp = comp; - quant_comp_s = compS; - expY = y; - st_lrm = shThreshold; - st_s = shThresholdS; - masking_adj = adj; - masking_adj_short = adjShort; - ath_lower = lower; - ath_curve = curve; - ath_sensitivity = sens; - interch = inter; - safejoint = joint; - sfb21mod = mod; - msfix = fix; - } - - int vbr_q; - int quant_comp; - int quant_comp_s; - int expY; - /** - * short threshold - */ - float st_lrm; - float st_s; - float masking_adj; - float masking_adj_short; - float ath_lower; - float ath_curve; - float ath_sensitivity; - float interch; - int safejoint; - int sfb21mod; - float msfix; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRQuantize.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRQuantize.java deleted file mode 100644 index eada4eaa7..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRQuantize.java +++ /dev/null @@ -1,1126 +0,0 @@ -/* - * MP3 quantization - * - * Copyright (c) 1999-2000 Mark Taylor - * Copyright (c) 2000-2007 Robert Hegemann - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: VBRQuantize.java,v 1.18 2011/08/27 18:57:12 kenchis Exp $ */ - -package mp3; - -import java.util.Arrays; - -public class VBRQuantize { - - QuantizePVT qupvt; - Takehiro tak; - - public final void setModules(QuantizePVT qupvt, Takehiro tk) { - this.qupvt = qupvt; - this.tak = tk; - } - - protected static class algo_t { - alloc_sf_f alloc; - float[] xr34orig; - LameInternalFlags gfc; - GrInfo cod_info; - int mingain_l; - int mingain_s[] = new int[3]; - } - - interface alloc_sf_f { - void alloc(final algo_t al, final int[] x, final int[] y, final int z); - } - - private float max_x34(final float[] xr34, int x34Pos, final int bw) { - float xfsf = 0; - int j = bw >> 1; - final int remaining = (j & 0x01); - - for (j >>= 1; j > 0; --j) { - if (xfsf < xr34[x34Pos + 0]) { - xfsf = xr34[x34Pos + 0]; - } - if (xfsf < xr34[x34Pos + 1]) { - xfsf = xr34[x34Pos + 1]; - } - if (xfsf < xr34[x34Pos + 2]) { - xfsf = xr34[x34Pos + 2]; - } - if (xfsf < xr34[x34Pos + 3]) { - xfsf = xr34[x34Pos + 3]; - } - x34Pos += 4; - } - if (remaining != 0) { - if (xfsf < xr34[x34Pos + 0]) { - xfsf = xr34[x34Pos + 0]; - } - if (xfsf < xr34[x34Pos + 1]) { - xfsf = xr34[x34Pos + 1]; - } - } - return xfsf; - } - - private int findLowestScalefac(final float xr34) { - int sfOk = 255; - int sf = 128, delsf = 64; - for (int i = 0; i < 8; ++i) { - final float xfsf = qupvt.ipow20[sf] * xr34; - if (xfsf <= QuantizePVT.IXMAX_VAL) { - sfOk = sf; - sf -= delsf; - } else { - sf += delsf; - } - delsf >>= 1; - } - return sfOk; - } - - private int belowNoiseFloor(final float[] xr, int xrPos, float l3xmin, - final int bw) { - float sum = 0.0f; - for (int i = 0, j = bw; j > 0; ++i, --j) { - final float x = xr[xrPos + i]; - sum += x * x; - } - return (l3xmin - sum) >= -1E-20 ? 1 : 0; - } - - private void k_34_4(final double x[], final int l3[], final int l3Pos) { - assert (x[0] <= QuantizePVT.IXMAX_VAL && x[1] <= QuantizePVT.IXMAX_VAL - && x[2] <= QuantizePVT.IXMAX_VAL && x[3] <= QuantizePVT.IXMAX_VAL); - l3[l3Pos + 0] = (int) x[0]; - l3[l3Pos + 1] = (int) x[1]; - l3[l3Pos + 2] = (int) x[2]; - l3[l3Pos + 3] = (int) x[3]; - x[0] += qupvt.adj43[l3[l3Pos + 0]]; - x[1] += qupvt.adj43[l3[l3Pos + 1]]; - x[2] += qupvt.adj43[l3[l3Pos + 2]]; - x[3] += qupvt.adj43[l3[l3Pos + 3]]; - l3[l3Pos + 0] = (int) x[0]; - l3[l3Pos + 1] = (int) x[1]; - l3[l3Pos + 2] = (int) x[2]; - l3[l3Pos + 3] = (int) x[3]; - } - - private void k_34_2(final double x[], final int l3[], final int l3Pos) { - assert (x[0] <= QuantizePVT.IXMAX_VAL && x[1] <= QuantizePVT.IXMAX_VAL); - l3[l3Pos + 0] = (int) x[0]; - l3[l3Pos + 1] = (int) x[1]; - x[0] += qupvt.adj43[l3[l3Pos + 0]]; - x[1] += qupvt.adj43[l3[l3Pos + 1]]; - l3[l3Pos + 0] = (int) x[0]; - l3[l3Pos + 1] = (int) x[1]; - } - - private float calc_sfb_noise_x34(final float[] xr, final float[] xr34, - int xrPos, int bw, int sf) { - double x[] = new double[4]; - int l3[] = new int[4]; - final float sfpow = qupvt.pow20[sf + QuantizePVT.Q_MAX2]; - final float sfpow34 = qupvt.ipow20[sf]; - - float xfsf = 0; - int j = bw >> 1; - final int remaining = (j & 0x01); - - for (j >>= 1; j > 0; --j) { - x[0] = sfpow34 * xr34[xrPos + 0]; - x[1] = sfpow34 * xr34[xrPos + 1]; - x[2] = sfpow34 * xr34[xrPos + 2]; - x[3] = sfpow34 * xr34[xrPos + 3]; - - k_34_4(x, l3, 0); - - x[0] = Math.abs(xr[xrPos + 0]) - sfpow * qupvt.pow43[l3[0]]; - x[1] = Math.abs(xr[xrPos + 1]) - sfpow * qupvt.pow43[l3[1]]; - x[2] = Math.abs(xr[xrPos + 2]) - sfpow * qupvt.pow43[l3[2]]; - x[3] = Math.abs(xr[xrPos + 3]) - sfpow * qupvt.pow43[l3[3]]; - xfsf += (x[0] * x[0] + x[1] * x[1]) + (x[2] * x[2] + x[3] * x[3]); - - xrPos += 4; - } - if (remaining != 0) { - x[0] = sfpow34 * xr34[xrPos + 0]; - x[1] = sfpow34 * xr34[xrPos + 1]; - - k_34_2(x, l3, 0); - - x[0] = Math.abs(xr[xrPos + 0]) - sfpow * qupvt.pow43[l3[0]]; - x[1] = Math.abs(xr[xrPos + 1]) - sfpow * qupvt.pow43[l3[1]]; - xfsf += x[0] * x[0] + x[1] * x[1]; - } - return xfsf; - } - - protected static class CalcNoiseCache { - int valid; - float value; - }; - - private boolean tri_calc_sfb_noise_x34(final float[] xr, - final float[] xr34, final int xrPos, final float l3_xmin, - final int bw, final int sf, final CalcNoiseCache[] did_it) { - if (did_it[sf].valid == 0) { - did_it[sf].valid = 1; - did_it[sf].value = calc_sfb_noise_x34(xr, xr34, xrPos, bw, sf); - } - if (l3_xmin < did_it[sf].value) { - return true; - } - if (sf < 255) { - final int sf_x = sf + 1; - if (did_it[sf_x].valid == 0) { - did_it[sf_x].valid = 1; - did_it[sf_x].value = calc_sfb_noise_x34(xr, xr34, xrPos, bw, - sf_x); - } - if (l3_xmin < did_it[sf_x].value) { - return true; - } - } - if (sf > 0) { - final int sf_x = sf - 1; - if (did_it[sf_x].valid == 0) { - did_it[sf_x].valid = 1; - did_it[sf_x].value = calc_sfb_noise_x34(xr, xr34, xrPos, bw, - sf_x); - } - if (l3_xmin < did_it[sf_x].value) { - return true; - } - } - return false; - } - - /** - * the find_scalefac* routines calculate a quantization step size which - * would introduce as much noise as is allowed. The larger the step size the - * more quantization noise we'll get. The scalefactors are there to lower - * the global step size, allowing limited differences in quantization step - * sizes per band (shaping the noise). - */ - private int find_scalefac_x34(final float[] xr, final float[] xr34, - final int xrPos, final float l3_xmin, final int bw, final int sf_min) { - CalcNoiseCache did_it[] = new CalcNoiseCache[256]; - int sf = 128, sf_ok = 255, delsf = 128, seen_good_one = 0, i; - for (int j = 0; j < did_it.length; j++) { - did_it[j] = new CalcNoiseCache(); - } - for (i = 0; i < 8; ++i) { - delsf >>= 1; - if (sf <= sf_min) { - sf += delsf; - } else { - final boolean bad = tri_calc_sfb_noise_x34(xr, xr34, xrPos, - l3_xmin, bw, sf, did_it); - if (bad) { - /* distortion. try a smaller scalefactor */ - sf -= delsf; - } else { - sf_ok = sf; - sf += delsf; - seen_good_one = 1; - } - } - } - // returning a scalefac without distortion, if possible - if (seen_good_one > 0) { - return sf_ok; - } - if (sf <= sf_min) { - return sf_min; - } - return sf; - } - - /** - * - * calc_short_block_vbr_sf(), calc_long_block_vbr_sf() - * - * a variation for vbr-mtrh - * - * @author Mark Taylor 2000-??-?? - * @author Robert Hegemann 2000-10-25 made functions of it - */ - private int block_sf(final algo_t that, final float l3_xmin[], - final int vbrsf[], final int vbrsfmin[]) { - float max_xr34; - final float[] xr = that.cod_info.xr; - final float[] xr34_orig = that.xr34orig; - final int[] width = that.cod_info.width; - final int max_nonzero_coeff = that.cod_info.max_nonzero_coeff; - int maxsf = 0; - int sfb = 0; - int j = 0, i = 0; - final int psymax = that.cod_info.psymax; - - assert (that.cod_info.max_nonzero_coeff >= 0); - - that.mingain_l = 0; - that.mingain_s[0] = 0; - that.mingain_s[1] = 0; - that.mingain_s[2] = 0; - while (j <= max_nonzero_coeff) { - final int w = width[sfb]; - final int m = (max_nonzero_coeff - j + 1); - int l = w; - int m1, m2; - if (l > m) { - l = m; - } - max_xr34 = max_x34(xr34_orig, j, l); - - m1 = findLowestScalefac(max_xr34); - vbrsfmin[sfb] = m1; - if (that.mingain_l < m1) { - that.mingain_l = m1; - } - if (that.mingain_s[i] < m1) { - that.mingain_s[i] = m1; - } - if (++i > 2) { - i = 0; - } - if (sfb < psymax) { - if (belowNoiseFloor(xr, j, l3_xmin[sfb], l) == 0) { - m2 = find_scalefac_x34(xr, xr34_orig, j, l3_xmin[sfb], l, - m1); - if (maxsf < m2) { - maxsf = m2; - } - } else { - m2 = 255; - maxsf = 255; - } - } else { - if (maxsf < m1) { - maxsf = m1; - } - m2 = maxsf; - } - vbrsf[sfb] = m2; - ++sfb; - j += w; - } - for (; sfb < L3Side.SFBMAX; ++sfb) { - vbrsf[sfb] = maxsf; - vbrsfmin[sfb] = 0; - } - return maxsf; - } - - /** - * quantize xr34 based on scalefactors - * - * block_xr34 - * - * @author Mark Taylor 2000-??-?? - * @author Robert Hegemann 2000-10-20 made functions of them - */ - private final void quantize_x34(final algo_t that) { - double x[] = new double[4]; - int xr34_orig = 0; - final GrInfo cod_info = that.cod_info; - final int ifqstep = (cod_info.scalefac_scale == 0) ? 2 : 4; - int l3 = 0; - int j = 0, sfb = 0; - final int max_nonzero_coeff = cod_info.max_nonzero_coeff; - - assert (cod_info.max_nonzero_coeff >= 0); - assert (cod_info.max_nonzero_coeff < 576); - - while (j <= max_nonzero_coeff) { - final int s = (cod_info.scalefac[sfb] + (cod_info.preflag != 0 ? qupvt.pretab[sfb] - : 0)) - * ifqstep - + cod_info.subblock_gain[cod_info.window[sfb]] - * 8; - final int sfac = (cod_info.global_gain - s); - final float sfpow34 = qupvt.ipow20[sfac]; - final int w = cod_info.width[sfb]; - final int m = (max_nonzero_coeff - j + 1); - int l = w; - int remaining; - - assert ((cod_info.global_gain - s) >= 0); - assert (cod_info.width[sfb] >= 0); - - if (l > m) { - l = m; - } - j += w; - ++sfb; - l >>= 1; - remaining = (l & 1); - - for (l >>= 1; l > 0; --l) { - x[0] = sfpow34 * that.xr34orig[xr34_orig + 0]; - x[1] = sfpow34 * that.xr34orig[xr34_orig + 1]; - x[2] = sfpow34 * that.xr34orig[xr34_orig + 2]; - x[3] = sfpow34 * that.xr34orig[xr34_orig + 3]; - - k_34_4(x, cod_info.l3_enc, l3); - - l3 += 4; - xr34_orig += 4; - } - if (remaining != 0) { - x[0] = sfpow34 * that.xr34orig[xr34_orig + 0]; - x[1] = sfpow34 * that.xr34orig[xr34_orig + 1]; - - k_34_2(x, cod_info.l3_enc, l3); - - l3 += 2; - xr34_orig += 2; - } - } - } - - protected static final int max_range_short[] = { 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0 }; - - protected static final int max_range_long[] = { 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0 }; - - protected static final int max_range_long_lsf_pretab[] = { 7, 7, 7, 7, 7, - 7, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - protected void set_subblock_gain(final GrInfo cod_info, - final int mingain_s[], final int sf[]) { - final int maxrange1 = 15, maxrange2 = 7; - final int ifqstepShift = (cod_info.scalefac_scale == 0) ? 1 : 2; - int[] sbg = cod_info.subblock_gain; - final int psymax = (int) cod_info.psymax; - int psydiv = 18; - int sbg0, sbg1, sbg2; - int sfb; - int min_sbg = 7; - - if (psydiv > psymax) { - psydiv = psymax; - } - for (int i = 0; i < 3; ++i) { - int maxsf1 = 0, maxsf2 = 0, minsf = 1000; - /* see if we should use subblock gain */ - for (sfb = i; sfb < psydiv; sfb += 3) { - /* part 1 */ - final int v = -sf[sfb]; - if (maxsf1 < v) { - maxsf1 = v; - } - if (minsf > v) { - minsf = v; - } - } - for (; sfb < L3Side.SFBMAX; sfb += 3) { - /* part 2 */ - final int v = -sf[sfb]; - if (maxsf2 < v) { - maxsf2 = v; - } - if (minsf > v) { - minsf = v; - } - } - - /* - * boost subblock gain as little as possible so we can reach maxsf1 - * with scalefactors 8*sbg >= maxsf1 - */ - { - final int m1 = maxsf1 - (maxrange1 << ifqstepShift); - final int m2 = maxsf2 - (maxrange2 << ifqstepShift); - - maxsf1 = Math.max(m1, m2); - } - if (minsf > 0) { - sbg[i] = minsf >> 3; - } else { - sbg[i] = 0; - } - if (maxsf1 > 0) { - final int m1 = sbg[i]; - final int m2 = (maxsf1 + 7) >> 3; - sbg[i] = Math.max(m1, m2); - } - if (sbg[i] > 0 - && mingain_s[i] > (cod_info.global_gain - sbg[i] * 8)) { - sbg[i] = (cod_info.global_gain - mingain_s[i]) >> 3; - } - if (sbg[i] > 7) { - sbg[i] = 7; - } - if (min_sbg > sbg[i]) { - min_sbg = sbg[i]; - } - } - sbg0 = sbg[0] * 8; - sbg1 = sbg[1] * 8; - sbg2 = sbg[2] * 8; - for (sfb = 0; sfb < L3Side.SFBMAX; sfb += 3) { - sf[sfb + 0] += sbg0; - sf[sfb + 1] += sbg1; - sf[sfb + 2] += sbg2; - } - if (min_sbg > 0) { - for (int i = 0; i < 3; ++i) { - sbg[i] -= min_sbg; - } - cod_info.global_gain -= min_sbg * 8; - } - } - - protected void set_scalefacs(final GrInfo cod_info, - final int[] vbrsfmin, final int sf[], final int[] max_range) { - final int ifqstep = (cod_info.scalefac_scale == 0) ? 2 : 4; - final int ifqstepShift = (cod_info.scalefac_scale == 0) ? 1 : 2; - final int[] scalefac = cod_info.scalefac; - final int sfbmax = cod_info.sfbmax; - final int[] sbg = cod_info.subblock_gain; - final int[] window = cod_info.window; - final int preflag = cod_info.preflag; - - if (preflag != 0) { - for (int sfb = 11; sfb < sfbmax; ++sfb) { - sf[sfb] += qupvt.pretab[sfb] * ifqstep; - } - } - for (int sfb = 0; sfb < sfbmax; ++sfb) { - final int gain = cod_info.global_gain - (sbg[window[sfb]] * 8) - - ((preflag != 0 ? qupvt.pretab[sfb] : 0) * ifqstep); - - if (sf[sfb] < 0) { - final int m = gain - vbrsfmin[sfb]; - /* ifqstep*scalefac >= -sf[sfb], so round UP */ - scalefac[sfb] = (ifqstep - 1 - sf[sfb]) >> ifqstepShift; - - if (scalefac[sfb] > max_range[sfb]) { - scalefac[sfb] = max_range[sfb]; - } - if (scalefac[sfb] > 0 && (scalefac[sfb] << ifqstepShift) > m) { - scalefac[sfb] = m >> ifqstepShift; - } - } else { - scalefac[sfb] = 0; - } - } - for (int sfb = sfbmax; sfb < L3Side.SFBMAX; ++sfb) { - scalefac[sfb] = 0; /* sfb21 */ - } - } - - protected boolean checkScalefactor(final GrInfo cod_info, - final int vbrsfmin[]) { - final int ifqstep = cod_info.scalefac_scale == 0 ? 2 : 4; - for (int sfb = 0; sfb < cod_info.psymax; ++sfb) { - final int s = ((cod_info.scalefac[sfb] + (cod_info.preflag != 0 ? qupvt.pretab[sfb] - : 0)) * ifqstep) - + cod_info.subblock_gain[cod_info.window[sfb]] * 8; - - if ((cod_info.global_gain - s) < vbrsfmin[sfb]) { - /** - * <CODE> - * fprintf( stdout, "sf %d\n", sfb ); - * fprintf( stdout, "min %d\n", vbrsfmin[sfb] ); - * fprintf( stdout, "ggain %d\n", cod_info.global_gain ); - * fprintf( stdout, "scalefac %d\n", cod_info.scalefac[sfb] ); - * fprintf( stdout, "pretab %d\n", (cod_info.preflag ? pretab[sfb] : 0) ); - * fprintf( stdout, "scale %d\n", (cod_info.scalefac_scale + 1) ); - * fprintf( stdout, "subgain %d\n", cod_info.subblock_gain[cod_info.window[sfb]] * 8 ); - * fflush( stdout ); - * exit(-1); - * </CODE> - */ - return false; - } - } - return true; - } - - private void bitcount(final algo_t that) { - boolean rc; - - if (that.gfc.mode_gr == 2) { - rc = tak.scale_bitcount(that.cod_info); - } else { - rc = tak.scale_bitcount_lsf(that.gfc, that.cod_info); - } - if (!rc) { - return; - } - /* this should not happen due to the way the scalefactors are selected */ - throw new RuntimeException("INTERNAL ERROR IN VBR NEW CODE (986), please send bug report"); - } - - private int quantizeAndCountBits(final algo_t that) { - quantize_x34(that); - that.cod_info.part2_3_length = tak.noquant_count_bits(that.gfc, - that.cod_info, null); - return that.cod_info.part2_3_length; - } - - private int tryGlobalStepsize(final algo_t that, final int sfwork[], - final int vbrsfmin[], int delta) { - final float xrpow_max = that.cod_info.xrpow_max; - int sftemp[] = new int[L3Side.SFBMAX], nbits; - int vbrmax = 0; - for (int i = 0; i < L3Side.SFBMAX; ++i) { - int gain = sfwork[i] + delta; - if (gain < vbrsfmin[i]) { - gain = vbrsfmin[i]; - } - if (gain > 255) { - gain = 255; - } - if (vbrmax < gain) { - vbrmax = gain; - } - sftemp[i] = gain; - } - that.alloc.alloc(that, sftemp, vbrsfmin, vbrmax); - bitcount(that); - nbits = quantizeAndCountBits(that); - that.cod_info.xrpow_max = xrpow_max; - return nbits; - } - - private void searchGlobalStepsizeMax(final algo_t that, final int sfwork[], - final int vbrsfmin[], final int target) { - final GrInfo cod_info = that.cod_info; - final int gain = cod_info.global_gain; - int curr = gain; - int gain_ok = 1024; - int nbits = QuantizePVT.LARGE_BITS; - int l = gain, r = 512; - - assert (gain >= 0); - while (l <= r) { - curr = (l + r) >> 1; - nbits = tryGlobalStepsize(that, sfwork, vbrsfmin, curr - gain); - if (nbits == 0 || (nbits + cod_info.part2_length) < target) { - r = curr - 1; - gain_ok = curr; - } else { - l = curr + 1; - if (gain_ok == 1024) { - gain_ok = curr; - } - } - } - if (gain_ok != curr) { - curr = gain_ok; - nbits = tryGlobalStepsize(that, sfwork, vbrsfmin, curr - gain); - } - } - - private int sfDepth(final int sfwork[]) { - int m = 0; - for (int j = L3Side.SFBMAX, i = 0; j > 0; --j, ++i) { - final int di = 255 - sfwork[i]; - if (m < di) { - m = di; - } - assert (sfwork[i] >= 0); - assert (sfwork[i] <= 255); - } - assert (m >= 0); - assert (m <= 255); - return m; - } - - private void cutDistribution(final int sfwork[], final int sf_out[], - final int cut) { - for (int j = L3Side.SFBMAX, i = 0; j > 0; --j, ++i) { - final int x = sfwork[i]; - sf_out[i] = x < cut ? x : cut; - } - } - - private int flattenDistribution(final int sfwork[], final int sf_out[], - final int dm, final int k, final int p) { - int sfmax = 0; - if (dm > 0) { - for (int j = L3Side.SFBMAX, i = 0; j > 0; --j, ++i) { - final int di = p - sfwork[i]; - int x = sfwork[i] + (k * di) / dm; - if (x < 0) { - x = 0; - } else { - if (x > 255) { - x = 255; - } - } - sf_out[i] = x; - if (sfmax < x) { - sfmax = x; - } - } - } else { - for (int j = L3Side.SFBMAX, i = 0; j > 0; --j, ++i) { - int x = sfwork[i]; - sf_out[i] = x; - if (sfmax < x) { - sfmax = x; - } - } - } - return sfmax; - } - - private int tryThatOne(final algo_t that, final int sftemp[], - final int vbrsfmin[], final int vbrmax) { - final float xrpow_max = that.cod_info.xrpow_max; - int nbits = QuantizePVT.LARGE_BITS; - that.alloc.alloc(that, sftemp, vbrsfmin, vbrmax); - bitcount(that); - nbits = quantizeAndCountBits(that); - nbits += that.cod_info.part2_length; - that.cod_info.xrpow_max = xrpow_max; - return nbits; - } - - private void outOfBitsStrategy(final algo_t that, final int sfwork[], - final int vbrsfmin[], final int target) { - int wrk[] = new int[L3Side.SFBMAX]; - final int dm = sfDepth(sfwork); - final int p = that.cod_info.global_gain; - - /* PART 1 */ - { - int bi = dm / 2; - int bi_ok = -1; - int bu = 0; - int bo = dm; - for (;;) { - final int sfmax = flattenDistribution(sfwork, wrk, dm, bi, p); - int nbits = tryThatOne(that, wrk, vbrsfmin, sfmax); - if (nbits <= target) { - bi_ok = bi; - bo = bi - 1; - } else { - bu = bi + 1; - } - if (bu <= bo) { - bi = (bu + bo) / 2; - } else { - break; - } - } - if (bi_ok >= 0) { - if (bi != bi_ok) { - final int sfmax = flattenDistribution(sfwork, wrk, dm, - bi_ok, p); - tryThatOne(that, wrk, vbrsfmin, sfmax); - } - return; - } - } - - /* PART 2: */ - { - int bi = (255 + p) / 2; - int bi_ok = -1; - int bu = p; - int bo = 255; - for (;;) { - final int sfmax = flattenDistribution(sfwork, wrk, dm, dm, bi); - int nbits = tryThatOne(that, wrk, vbrsfmin, sfmax); - if (nbits <= target) { - bi_ok = bi; - bo = bi - 1; - } else { - bu = bi + 1; - } - if (bu <= bo) { - bi = (bu + bo) / 2; - } else { - break; - } - } - if (bi_ok >= 0) { - if (bi != bi_ok) { - final int sfmax = flattenDistribution(sfwork, wrk, dm, dm, - bi_ok); - tryThatOne(that, wrk, vbrsfmin, sfmax); - } - return; - } - } - - /* fall back to old code, likely to be never called */ - searchGlobalStepsizeMax(that, wrk, vbrsfmin, target); - } - - private int reduce_bit_usage(final LameInternalFlags gfc, final int gr, - final int ch) { - final GrInfo cod_info = gfc.l3_side.tt[gr][ch]; - // try some better scalefac storage - tak.best_scalefac_store(gfc, gr, ch, gfc.l3_side); - - // best huffman_divide may save some bits too - if (gfc.use_best_huffman == 1) - tak.best_huffman_divide(gfc, cod_info); - return cod_info.part2_3_length + cod_info.part2_length; - } - - public int VBR_encode_frame(final LameInternalFlags gfc, - final float xr34orig[][][], final float l3_xmin[][][], - final int max_bits[][]) { - int sfwork_[][][] = new int[2][2][L3Side.SFBMAX]; - int vbrsfmin_[][][] = new int[2][2][L3Side.SFBMAX]; - algo_t that_[][] = new algo_t[2][2]; - final int ngr = gfc.mode_gr; - final int nch = gfc.channels_out; - int max_nbits_ch[][] = new int[2][2]; - int max_nbits_gr[] = new int[2]; - int max_nbits_fr = 0; - int use_nbits_ch[][] = new int[2][2]; - int use_nbits_gr[] = new int[2]; - int use_nbits_fr = 0; - - /* - * set up some encoding parameters - */ - for (int gr = 0; gr < ngr; ++gr) { - max_nbits_gr[gr] = 0; - for (int ch = 0; ch < nch; ++ch) { - max_nbits_ch[gr][ch] = max_bits[gr][ch]; - use_nbits_ch[gr][ch] = 0; - max_nbits_gr[gr] += max_bits[gr][ch]; - max_nbits_fr += max_bits[gr][ch]; - that_[gr][ch] = new algo_t(); - that_[gr][ch].gfc = gfc; - that_[gr][ch].cod_info = gfc.l3_side.tt[gr][ch]; - that_[gr][ch].xr34orig = xr34orig[gr][ch]; - if (that_[gr][ch].cod_info.block_type == Encoder.SHORT_TYPE) { - that_[gr][ch].alloc = new ShortBlockConstrain(this); - } else { - that_[gr][ch].alloc = new LongBlockConstrain(this); - } - } /* for ch */ - } - - /* - * searches scalefactors - */ - for (int gr = 0; gr < ngr; ++gr) { - for (int ch = 0; ch < nch; ++ch) { - if (max_bits[gr][ch] > 0) { - algo_t that = that_[gr][ch]; - int[] sfwork = sfwork_[gr][ch]; - int[] vbrsfmin = vbrsfmin_[gr][ch]; - int vbrmax; - - vbrmax = block_sf(that, l3_xmin[gr][ch], sfwork, vbrsfmin); - that.alloc.alloc(that, sfwork, vbrsfmin, vbrmax); - bitcount(that); - } else { - /* - * xr contains no energy l3_enc, our encoding data, will be - * quantized to zero continue with next channel - */ - } - } /* for ch */ - } - - /* - * encode 'as is' - */ - use_nbits_fr = 0; - for (int gr = 0; gr < ngr; ++gr) { - use_nbits_gr[gr] = 0; - for (int ch = 0; ch < nch; ++ch) { - algo_t that = that_[gr][ch]; - if (max_bits[gr][ch] > 0) { - final int max_nonzero_coeff = that.cod_info.max_nonzero_coeff; - - assert (max_nonzero_coeff < 576); - Arrays.fill(that.cod_info.l3_enc, max_nonzero_coeff, 576, 0); - - quantizeAndCountBits(that); - } else { - /* - * xr contains no energy l3_enc, our encoding data, will be - * quantized to zero continue with next channel - */ - } - use_nbits_ch[gr][ch] = reduce_bit_usage(gfc, gr, ch); - use_nbits_gr[gr] += use_nbits_ch[gr][ch]; - } /* for ch */ - use_nbits_fr += use_nbits_gr[gr]; - } - - /* - * check bit constrains - */ - if (use_nbits_fr <= max_nbits_fr) { - boolean ok = true; - for (int gr = 0; gr < ngr; ++gr) { - if (use_nbits_gr[gr] > LameInternalFlags.MAX_BITS_PER_GRANULE) { - /* - * violates the rule that every granule has to use no more - * bits than MAX_BITS_PER_GRANULE - */ - ok = false; - } - for (int ch = 0; ch < nch; ++ch) { - if (use_nbits_ch[gr][ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL) { - /* - * violates the rule that every gr_ch has to use no more - * bits than MAX_BITS_PER_CHANNEL - * - * This isn't explicitly stated in the ISO docs, but the - * part2_3_length field has only 12 bits, that makes it - * up to a maximum size of 4095 bits!!! - */ - ok = false; - } - } - } - if (ok) { - return use_nbits_fr; - } - } - - /* - * OK, we are in trouble and have to define how many bits are to be used - * for each granule - */ - { - boolean ok = true; - int sum_fr = 0; - - for (int gr = 0; gr < ngr; ++gr) { - max_nbits_gr[gr] = 0; - for (int ch = 0; ch < nch; ++ch) { - if (use_nbits_ch[gr][ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL) { - max_nbits_ch[gr][ch] = LameInternalFlags.MAX_BITS_PER_CHANNEL; - } else { - max_nbits_ch[gr][ch] = use_nbits_ch[gr][ch]; - } - max_nbits_gr[gr] += max_nbits_ch[gr][ch]; - } - if (max_nbits_gr[gr] > LameInternalFlags.MAX_BITS_PER_GRANULE) { - float f[] = new float[2], s = 0; - for (int ch = 0; ch < nch; ++ch) { - if (max_nbits_ch[gr][ch] > 0) { - f[ch] = (float) Math.sqrt(Math - .sqrt(max_nbits_ch[gr][ch])); - s += f[ch]; - } else { - f[ch] = 0; - } - } - for (int ch = 0; ch < nch; ++ch) { - if (s > 0) { - max_nbits_ch[gr][ch] = (int) (LameInternalFlags.MAX_BITS_PER_GRANULE - * f[ch] / s); - } else { - max_nbits_ch[gr][ch] = 0; - } - } - if (nch > 1) { - if (max_nbits_ch[gr][0] > use_nbits_ch[gr][0] + 32) { - max_nbits_ch[gr][1] += max_nbits_ch[gr][0]; - max_nbits_ch[gr][1] -= use_nbits_ch[gr][0] + 32; - max_nbits_ch[gr][0] = use_nbits_ch[gr][0] + 32; - } - if (max_nbits_ch[gr][1] > use_nbits_ch[gr][1] + 32) { - max_nbits_ch[gr][0] += max_nbits_ch[gr][1]; - max_nbits_ch[gr][0] -= use_nbits_ch[gr][1] + 32; - max_nbits_ch[gr][1] = use_nbits_ch[gr][1] + 32; - } - if (max_nbits_ch[gr][0] > LameInternalFlags.MAX_BITS_PER_CHANNEL) { - max_nbits_ch[gr][0] = LameInternalFlags.MAX_BITS_PER_CHANNEL; - } - if (max_nbits_ch[gr][1] > LameInternalFlags.MAX_BITS_PER_CHANNEL) { - max_nbits_ch[gr][1] = LameInternalFlags.MAX_BITS_PER_CHANNEL; - } - } - max_nbits_gr[gr] = 0; - for (int ch = 0; ch < nch; ++ch) { - max_nbits_gr[gr] += max_nbits_ch[gr][ch]; - } - } - sum_fr += max_nbits_gr[gr]; - } - if (sum_fr > max_nbits_fr) { - { - float f[] = new float[2], s = 0; - for (int gr = 0; gr < ngr; ++gr) { - if (max_nbits_gr[gr] > 0) { - f[gr] = (float) Math.sqrt(max_nbits_gr[gr]); - s += f[gr]; - } else { - f[gr] = 0; - } - } - for (int gr = 0; gr < ngr; ++gr) { - if (s > 0) { - max_nbits_gr[gr] = (int) (max_nbits_fr * f[gr] / s); - } else { - max_nbits_gr[gr] = 0; - } - } - } - if (ngr > 1) { - if (max_nbits_gr[0] > use_nbits_gr[0] + 125) { - max_nbits_gr[1] += max_nbits_gr[0]; - max_nbits_gr[1] -= use_nbits_gr[0] + 125; - max_nbits_gr[0] = use_nbits_gr[0] + 125; - } - if (max_nbits_gr[1] > use_nbits_gr[1] + 125) { - max_nbits_gr[0] += max_nbits_gr[1]; - max_nbits_gr[0] -= use_nbits_gr[1] + 125; - max_nbits_gr[1] = use_nbits_gr[1] + 125; - } - for (int gr = 0; gr < ngr; ++gr) { - if (max_nbits_gr[gr] > LameInternalFlags.MAX_BITS_PER_GRANULE) { - max_nbits_gr[gr] = LameInternalFlags.MAX_BITS_PER_GRANULE; - } - } - } - for (int gr = 0; gr < ngr; ++gr) { - float f[] = new float[2], s = 0; - for (int ch = 0; ch < nch; ++ch) { - if (max_nbits_ch[gr][ch] > 0) { - f[ch] = (float) Math.sqrt(max_nbits_ch[gr][ch]); - s += f[ch]; - } else { - f[ch] = 0; - } - } - for (int ch = 0; ch < nch; ++ch) { - if (s > 0) { - max_nbits_ch[gr][ch] = (int) (max_nbits_gr[gr] - * f[ch] / s); - } else { - max_nbits_ch[gr][ch] = 0; - } - } - if (nch > 1) { - if (max_nbits_ch[gr][0] > use_nbits_ch[gr][0] + 32) { - max_nbits_ch[gr][1] += max_nbits_ch[gr][0]; - max_nbits_ch[gr][1] -= use_nbits_ch[gr][0] + 32; - max_nbits_ch[gr][0] = use_nbits_ch[gr][0] + 32; - } - if (max_nbits_ch[gr][1] > use_nbits_ch[gr][1] + 32) { - max_nbits_ch[gr][0] += max_nbits_ch[gr][1]; - max_nbits_ch[gr][0] -= use_nbits_ch[gr][1] + 32; - max_nbits_ch[gr][1] = use_nbits_ch[gr][1] + 32; - } - for (int ch = 0; ch < nch; ++ch) { - if (max_nbits_ch[gr][ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL) { - max_nbits_ch[gr][ch] = LameInternalFlags.MAX_BITS_PER_CHANNEL; - } - } - } - } - } - /* sanity check */ - sum_fr = 0; - for (int gr = 0; gr < ngr; ++gr) { - int sum_gr = 0; - for (int ch = 0; ch < nch; ++ch) { - sum_gr += max_nbits_ch[gr][ch]; - if (max_nbits_ch[gr][ch] > LameInternalFlags.MAX_BITS_PER_CHANNEL) { - ok = false; - } - } - sum_fr += sum_gr; - if (sum_gr > LameInternalFlags.MAX_BITS_PER_GRANULE) { - ok = false; - } - } - if (sum_fr > max_nbits_fr) { - ok = false; - } - if (!ok) { - /* - * we must have done something wrong, fallback to 'on_pe' based - * constrain - */ - for (int gr = 0; gr < ngr; ++gr) { - for (int ch = 0; ch < nch; ++ch) { - max_nbits_ch[gr][ch] = max_bits[gr][ch]; - } - } - } - } - - /* - * we already called the 'best_scalefac_store' function, so we need to - * reset some variables before we can do it again. - */ - for (int ch = 0; ch < nch; ++ch) { - gfc.l3_side.scfsi[ch][0] = 0; - gfc.l3_side.scfsi[ch][1] = 0; - gfc.l3_side.scfsi[ch][2] = 0; - gfc.l3_side.scfsi[ch][3] = 0; - } - for (int gr = 0; gr < ngr; ++gr) { - for (int ch = 0; ch < nch; ++ch) { - gfc.l3_side.tt[gr][ch].scalefac_compress = 0; - } - } - - /* - * alter our encoded data, until it fits into the target bitrate - */ - use_nbits_fr = 0; - for (int gr = 0; gr < ngr; ++gr) { - use_nbits_gr[gr] = 0; - for (int ch = 0; ch < nch; ++ch) { - algo_t that = that_[gr][ch]; - use_nbits_ch[gr][ch] = 0; - if (max_bits[gr][ch] > 0) { - int[] sfwork = sfwork_[gr][ch]; - int[] vbrsfmin = vbrsfmin_[gr][ch]; - cutDistribution(sfwork, sfwork, that.cod_info.global_gain); - outOfBitsStrategy(that, sfwork, vbrsfmin, - max_nbits_ch[gr][ch]); - } - use_nbits_ch[gr][ch] = reduce_bit_usage(gfc, gr, ch); - assert (use_nbits_ch[gr][ch] <= max_nbits_ch[gr][ch]); - use_nbits_gr[gr] += use_nbits_ch[gr][ch]; - } /* for ch */ - use_nbits_fr += use_nbits_gr[gr]; - } - - /* - * check bit constrains, but it should always be ok, if there are no - * bugs ;-) - */ - if (use_nbits_fr <= max_nbits_fr) { - return use_nbits_fr; - } - - throw new RuntimeException(String.format( - "INTERNAL ERROR IN VBR NEW CODE (1313), please send bug report\n" - + "maxbits=%d usedbits=%d\n", max_nbits_fr, - use_nbits_fr)); - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRSeekInfo.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRSeekInfo.java deleted file mode 100644 index 690ba95db..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRSeekInfo.java +++ /dev/null @@ -1,32 +0,0 @@ -package mp3; - -public class VBRSeekInfo { - /** - * What we have seen so far. - */ - int sum; - /** - * How many frames we have seen in this chunk. - */ - int seen; - /** - * How many frames we want to collect into one chunk. - */ - int want; - /** - * Actual position in our bag. - */ - int pos; - /** - * Size of our bag. - */ - int size; - /** - * Pointer to our bag. - */ - int[] bag; - int nVbrNumFrames; - int nBytesWritten; - /* VBR tag data */ - int TotalFrameSize; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRTag.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRTag.java deleted file mode 100644 index 1b184fe76..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRTag.java +++ /dev/null @@ -1,989 +0,0 @@ -/* - * Xing VBR tagging for LAME. - * - * Copyright (c) 1999 A.L. Faber - * Copyright (c) 2001 Jonathan Dee - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -package mp3; - -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.charset.Charset; -import java.util.Arrays; - -/** - * A Vbr header may be present in the ancillary data field of the first frame of - * an mp3 bitstream<BR> - * The Vbr header (optionally) contains - * <UL> - * <LI>frames total number of audio frames in the bitstream - * <LI>bytes total number of bytes in the bitstream - * <LI>toc table of contents - * </UL> - * - * toc (table of contents) gives seek points for random access.<BR> - * The ith entry determines the seek point for i-percent duration.<BR> - * seek point in bytes = (toc[i]/256.0) * total_bitstream_bytes<BR> - * e.g. half duration seek point = (toc[50]/256.0) * total_bitstream_bytes - */ -public class VBRTag { - - Lame lame; - BitStream bs; - Version v; - - public final void setModules(Lame lame, BitStream bs, Version v) { - this.lame = lame; - this.bs = bs; - this.v = v; - } - - private static final int FRAMES_FLAG = 0x0001; - private static final int BYTES_FLAG = 0x0002; - private static final int TOC_FLAG = 0x0004; - private static final int VBR_SCALE_FLAG = 0x0008; - - public static final int NUMTOCENTRIES = 100; - - /** - * (0xB40) the max freeformat 640 32kHz framesize. - */ - public static final int MAXFRAMESIZE = 2880; - - /** - * <PRE> - * 4 bytes for Header Tag - * 4 bytes for Header Flags - * 100 bytes for entry (toc) - * 4 bytes for frame size - * 4 bytes for stream size - * 4 bytes for VBR scale. a VBR quality indicator: 0=best 100=worst - * 20 bytes for LAME tag. for example, "LAME3.12 (beta 6)" - * ___________ - * 140 bytes - * </PRE> - */ - private static final int VBRHEADERSIZE = (NUMTOCENTRIES + 4 + 4 + 4 + 4 + 4); - - private static final int LAMEHEADERSIZE = (VBRHEADERSIZE + 9 + 1 + 1 + 8 - + 1 + 1 + 3 + 1 + 1 + 2 + 4 + 2 + 2); - - /** - * The size of the Xing header MPEG-1, bit rate in kbps. - */ - private static final int XING_BITRATE1 = 128; - /** - * The size of the Xing header MPEG-2, bit rate in kbps. - */ - private static final int XING_BITRATE2 = 64; - /** - * The size of the Xing header MPEG-2.5, bit rate in kbps. - */ - private static final int XING_BITRATE25 = 32; - - /** - * ISO-8859-1 charset for byte to string operations. - */ - private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); - - /** - * VBR header magic string. - */ - private static final String VBRTag0 = "Xing"; - /** - * VBR header magic string (VBR == VBRMode.vbr_off). - */ - private static final String VBRTag1 = "Info"; - - /** - * Lookup table for fast CRC-16 computation. Uses the polynomial - * x^16+x^15+x^2+1 - */ - private static int crc16Lookup[] = { 0x0000, 0xC0C1, 0xC181, 0x0140, - 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, - 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, - 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, - 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, - 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, - 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, - 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, - 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, - 0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, - 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, - 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, - 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, - 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, - 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, - 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, - 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, - 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, - 0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, - 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, - 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, - 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, - 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, - 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, - 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, - 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, - 0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, - 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, - 0x9901, 0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, - 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, - 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, - 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, - 0x4100, 0x81C1, 0x8081, 0x4040 }; - - /*********************************************************************** - * Robert Hegemann 2001-01-17 - ***********************************************************************/ - - private void addVbr(final VBRSeekInfo v, final int bitrate) { - v.nVbrNumFrames++; - v.sum += bitrate; - v.seen++; - - if (v.seen < v.want) { - return; - } - - if (v.pos < v.size) { - v.bag[v.pos] = v.sum; - v.pos++; - v.seen = 0; - } - if (v.pos == v.size) { - for (int i = 1; i < v.size; i += 2) { - v.bag[i / 2] = v.bag[i]; - } - v.want *= 2; - v.pos /= 2; - } - } - - private void xingSeekTable(VBRSeekInfo v, byte[] t) { - if (v.pos <= 0) - return; - - for (int i = 1; i < NUMTOCENTRIES; ++i) { - float j = i / (float) NUMTOCENTRIES, act, sum; - int indx = (int) (Math.floor(j * v.pos)); - if (indx > v.pos - 1) - indx = v.pos - 1; - act = v.bag[indx]; - sum = v.sum; - int seek_point = (int) (256. * act / sum); - if (seek_point > 255) - seek_point = 255; - t[i] = (byte) seek_point; - } - } - - /** - * Add VBR entry, used to fill the VBR TOC entries. - * - * @param gfp - * global flags - */ - public final void addVbrFrame(final LameGlobalFlags gfp) { - final LameInternalFlags gfc = gfp.internal_flags; - - int kbps = Tables.bitrate_table[gfp.version][gfc.bitrate_index]; - assert (gfc.VBR_seek_table.bag != null); - addVbr(gfc.VBR_seek_table, kbps); - } - - /** - * Read big endian integer (4-bytes) from header. - * - * @param buf - * header containing the integer - * @param bufPos - * offset into the header - * @return extracted integer - */ - private int extractInteger(final byte[] buf, final int bufPos) { - int x = buf[bufPos + 0] & 0xff; - x <<= 8; - x |= buf[bufPos + 1] & 0xff; - x <<= 8; - x |= buf[bufPos + 2] & 0xff; - x <<= 8; - x |= buf[bufPos + 3] & 0xff; - return x; - } - - /** - * Write big endian integer (4-bytes) in the header. - * - * @param buf - * header to write the integer into - * @param bufPos - * offset into the header - * @param value - * integer value to write - */ - private void createInteger(final byte[] buf, final int bufPos, - final int value) { - buf[bufPos + 0] = (byte) ((value >> 24) & 0xff); - buf[bufPos + 1] = (byte) ((value >> 16) & 0xff); - buf[bufPos + 2] = (byte) ((value >> 8) & 0xff); - buf[bufPos + 3] = (byte) (value & 0xff); - } - - /** - * Write big endian short (2-bytes) in the header. - * - * @param buf - * header to write the integer into - * @param bufPos - * offset into the header - * @param value - * integer value to write - */ - private void createShort(final byte[] buf, final int bufPos, final int value) { - buf[bufPos + 0] = (byte) ((value >> 8) & 0xff); - buf[bufPos + 1] = (byte) (value & 0xff); - } - - /** - * Check for magic strings (Xing/Info). - * - * @param buf - * header to check - * @param bufPos - * header offset to check - * @return magic string found - */ - private boolean isVbrTag(final byte[] buf, final int bufPos) { - return new String(buf, bufPos, VBRTag0.length(), ISO_8859_1) - .equals(VBRTag0) - || new String(buf, bufPos, VBRTag1.length(), ISO_8859_1) - .equals(VBRTag1); - } - - private byte shiftInBitsValue(final byte x, final int n, final int v) { - return (byte) ((x << n) | (v & ~(-1 << n))); - } - - /** - * Construct the MP3 header using the settings of the global flags. - * - * <img src="1000px-Mp3filestructure.svg.png"> - * - * @param gfp - * global flags - * @param buffer - * header - */ - private void setLameTagFrameHeader(final LameGlobalFlags gfp, - final byte[] buffer) { - final LameInternalFlags gfc = gfp.internal_flags; - - // MP3 Sync Word - buffer[0] = shiftInBitsValue(buffer[0], 8, 0xff); - - buffer[1] = shiftInBitsValue(buffer[1], 3, 7); - buffer[1] = shiftInBitsValue(buffer[1], 1, - (gfp.out_samplerate < 16000) ? 0 : 1); - // Version - buffer[1] = shiftInBitsValue(buffer[1], 1, gfp.version); - // 01 == Layer 3 - buffer[1] = shiftInBitsValue(buffer[1], 2, 4 - 3); - // Error protection - buffer[1] = shiftInBitsValue(buffer[1], 1, (!gfp.error_protection) ? 1 - : 0); - - // Bit rate - buffer[2] = shiftInBitsValue(buffer[2], 4, gfc.bitrate_index); - // Frequency - buffer[2] = shiftInBitsValue(buffer[2], 2, gfc.samplerate_index); - // Pad. Bit - buffer[2] = shiftInBitsValue(buffer[2], 1, 0); - // Priv. Bit - buffer[2] = shiftInBitsValue(buffer[2], 1, gfp.extension); - - // Mode - buffer[3] = shiftInBitsValue(buffer[3], 2, gfp.mode.ordinal()); - // Mode extension (Used with Joint Stereo) - buffer[3] = shiftInBitsValue(buffer[3], 2, gfc.mode_ext); - // Copy - buffer[3] = shiftInBitsValue(buffer[3], 1, gfp.copyright); - // Original - buffer[3] = shiftInBitsValue(buffer[3], 1, gfp.original); - // Emphasis - buffer[3] = shiftInBitsValue(buffer[3], 2, gfp.emphasis); - - /* the default VBR header. 48 kbps layer III, no padding, no crc */ - /* but sampling freq, mode and copyright/copy protection taken */ - /* from first valid frame */ - buffer[0] = (byte) 0xff; - byte abyte = (byte) (buffer[1] & 0xf1); - - int bitrate; - if (1 == gfp.version) { - bitrate = XING_BITRATE1; - } else { - if (gfp.out_samplerate < 16000) - bitrate = XING_BITRATE25; - else - bitrate = XING_BITRATE2; - } - - if (gfp.VBR == VbrMode.vbr_off) - bitrate = gfp.brate; - - byte bbyte; - if (gfp.free_format) - bbyte = 0x00; - else - bbyte = (byte) (16 * lame.BitrateIndex(bitrate, gfp.version, - gfp.out_samplerate)); - - /* - * Use as much of the info from the real frames in the Xing header: - * samplerate, channels, crc, etc... - */ - if (gfp.version == 1) { - /* MPEG1 */ - buffer[1] = (byte) (abyte | 0x0a); /* was 0x0b; */ - abyte = (byte) (buffer[2] & 0x0d); /* AF keep also private bit */ - buffer[2] = (byte) (bbyte | abyte); /* 64kbs MPEG1 frame */ - } else { - /* MPEG2 */ - buffer[1] = (byte) (abyte | 0x02); /* was 0x03; */ - abyte = (byte) (buffer[2] & 0x0d); /* AF keep also private bit */ - buffer[2] = (byte) (bbyte | abyte); /* 64kbs MPEG2 frame */ - } - } - - /** - * Get VBR tag information - * - * @param buf - * header to analyze - * @param bufPos - * offset into the header - * @return VBR tag data - */ - public final VBRTagData getVbrTag(final byte[] buf) { - final VBRTagData pTagData = new VBRTagData(); - int bufPos = 0; - - /* get Vbr header data */ - pTagData.flags = 0; - - /* get selected MPEG header data */ - int hId = (buf[bufPos + 1] >> 3) & 1; - int hSrIndex = (buf[bufPos + 2] >> 2) & 3; - int hMode = (buf[bufPos + 3] >> 6) & 3; - int hBitrate = ((buf[bufPos + 2] >> 4) & 0xf); - hBitrate = Tables.bitrate_table[hId][hBitrate]; - - /* check for FFE syncword */ - if ((buf[bufPos + 1] >> 4) == 0xE) - pTagData.samprate = Tables.samplerate_table[2][hSrIndex]; - else - pTagData.samprate = Tables.samplerate_table[hId][hSrIndex]; - - /* determine offset of header */ - if (hId != 0) { - /* mpeg1 */ - if (hMode != 3) - bufPos += (32 + 4); - else - bufPos += (17 + 4); - } else { - /* mpeg2 */ - if (hMode != 3) - bufPos += (17 + 4); - else - bufPos += (9 + 4); - } - - if (!isVbrTag(buf, bufPos)) - return null; - - bufPos += 4; - - pTagData.hId = hId; - - /* get flags */ - int head_flags = pTagData.flags = extractInteger(buf, bufPos); - bufPos += 4; - - if ((head_flags & FRAMES_FLAG) != 0) { - pTagData.frames = extractInteger(buf, bufPos); - bufPos += 4; - } - - if ((head_flags & BYTES_FLAG) != 0) { - pTagData.bytes = extractInteger(buf, bufPos); - bufPos += 4; - } - - if ((head_flags & TOC_FLAG) != 0) { - if (pTagData.toc != null) { - for (int i = 0; i < NUMTOCENTRIES; i++) - pTagData.toc[i] = buf[bufPos + i]; - } - bufPos += NUMTOCENTRIES; - } - - pTagData.vbrScale = -1; - - if ((head_flags & VBR_SCALE_FLAG) != 0) { - pTagData.vbrScale = extractInteger(buf, bufPos); - bufPos += 4; - } - - pTagData.headersize = ((hId + 1) * 72000 * hBitrate) - / pTagData.samprate; - - bufPos += 21; - int encDelay = buf[bufPos + 0] << 4; - encDelay += buf[bufPos + 1] >> 4; - int encPadding = (buf[bufPos + 1] & 0x0F) << 8; - encPadding += buf[bufPos + 2] & 0xff; - /* check for reasonable values (this may be an old Xing header, */ - /* not a INFO tag) */ - if (encDelay < 0 || encDelay > 3000) - encDelay = -1; - if (encPadding < 0 || encPadding > 3000) - encPadding = -1; - - pTagData.encDelay = encDelay; - pTagData.encPadding = encPadding; - - /* success */ - return pTagData; - } - - /** - * Initializes the header - * - * @param gfp - * global flags - */ - public final void InitVbrTag(final LameGlobalFlags gfp) { - final LameInternalFlags gfc = gfp.internal_flags; - - /** - * <PRE> - * Xing VBR pretends to be a 48kbs layer III frame. (at 44.1kHz). - * (at 48kHz they use 56kbs since 48kbs frame not big enough for - * table of contents) - * let's always embed Xing header inside a 64kbs layer III frame. - * this gives us enough room for a LAME version string too. - * size determined by sampling frequency (MPEG1) - * 32kHz: 216 bytes@48kbs 288bytes@ 64kbs - * 44.1kHz: 156 bytes 208bytes@64kbs (+1 if padding = 1) - * 48kHz: 144 bytes 192 - * - * MPEG 2 values are the same since the framesize and samplerate - * are each reduced by a factor of 2. - * </PRE> - */ - int kbps_header; - if (1 == gfp.version) { - kbps_header = XING_BITRATE1; - } else { - if (gfp.out_samplerate < 16000) - kbps_header = XING_BITRATE25; - else - kbps_header = XING_BITRATE2; - } - - if (gfp.VBR == VbrMode.vbr_off) - kbps_header = gfp.brate; - - // make sure LAME Header fits into Frame - int totalFrameSize = ((gfp.version + 1) * 72000 * kbps_header) - / gfp.out_samplerate; - int headerSize = (gfc.sideinfo_len + LAMEHEADERSIZE); - gfc.VBR_seek_table.TotalFrameSize = totalFrameSize; - if (totalFrameSize < headerSize || totalFrameSize > MAXFRAMESIZE) { - /* disable tag, it wont fit */ - gfp.bWriteVbrTag = false; - return; - } - - gfc.VBR_seek_table.nVbrNumFrames = 0; - gfc.VBR_seek_table.nBytesWritten = 0; - gfc.VBR_seek_table.sum = 0; - - gfc.VBR_seek_table.seen = 0; - gfc.VBR_seek_table.want = 1; - gfc.VBR_seek_table.pos = 0; - - if (gfc.VBR_seek_table.bag == null) { - gfc.VBR_seek_table.bag = new int[400]; - gfc.VBR_seek_table.size = 400; - } - - // write dummy VBR tag of all 0's into bitstream - byte buffer[] = new byte[MAXFRAMESIZE]; - - setLameTagFrameHeader(gfp, buffer); - int n = gfc.VBR_seek_table.TotalFrameSize; - for (int i = 0; i < n; ++i) { - bs.add_dummy_byte(gfp, buffer[i] & 0xff, 1); - } - } - - /** - * Fast CRC-16 computation (uses table crc16Lookup). - * - * @param value - * @param crc - * @return - */ - private int crcUpdateLookup(final int value, int crc) { - int tmp = crc ^ value; - crc = (crc >> 8) ^ crc16Lookup[tmp & 0xff]; - return crc; - } - - public final void updateMusicCRC(final int[] crc, final byte[] buffer, - final int bufferPos, final int size) { - for (int i = 0; i < size; ++i) - crc[0] = crcUpdateLookup(buffer[bufferPos + i], crc[0]); - } - - /** - * Write LAME info: mini version + info on various switches used (Jonathan - * Dee 2001/08/31). - * - * @param gfp - * global flags - * @param musicLength - * music length - * @param streamBuffer - * pointer to output buffer - * @param streamBufferPos - * offset into the output buffer - * @param crc - * computation of CRC-16 of Lame Tag so far (starting at frame - * sync) - * @return number of bytes written to the stream - */ - private int putLameVBR(final LameGlobalFlags gfp, final int musicLength, - final byte[] streamBuffer, final int streamBufferPos, int crc) { - final LameInternalFlags gfc = gfp.internal_flags; - - int bytesWritten = 0; - - /* encoder delay */ - int encDelay = gfp.encoder_delay; - /* encoder padding */ - int encPadding = gfp.encoder_padding; - - /* recall: gfp.VBR_q is for example set by the switch -V */ - /* gfp.quality by -q, -h, -f, etc */ - int quality = (100 - 10 * gfp.VBR_q - gfp.quality); - - final String version = v.getLameVeryShortVersion(); - int vbr; - int revision = 0x00; - int revMethod; - // numbering different in vbr_mode vs. Lame tag - int vbrTypeTranslator[] = { 1, 5, 3, 2, 4, 0, 3 }; - - int lowpass = (int) (((gfp.lowpassfreq / 100.0) + .5) > 255 ? 255 - : (gfp.lowpassfreq / 100.0) + .5); - - int peakSignalAmplitude = 0; - - int radioReplayGain = 0; - int audiophileReplayGain = 0; - - int noiseShaping = gfp.internal_flags.noise_shaping; - int stereoMode = 0; - int nonOptimal = 0; - int sourceFreq = 0; - int misc = 0; - int musicCRC = 0; - - // psy model type: Gpsycho or NsPsytune - boolean expNPsyTune = (gfp.exp_nspsytune & 1) != 0; - boolean safeJoint = (gfp.exp_nspsytune & 2) != 0; - - boolean noGapMore = false; - boolean noGapPrevious = false; - - int noGapCount = gfp.internal_flags.nogap_total; - int noGapCurr = gfp.internal_flags.nogap_current; - - // 4 bits - int athType = gfp.ATHtype; - - int flags = 0; - - // vbr modes - int abrBitrate; - switch (gfp.VBR) { - case vbr_abr: - abrBitrate = gfp.VBR_mean_bitrate_kbps; - break; - case vbr_off: - abrBitrate = gfp.brate; - break; - default: - abrBitrate = gfp.VBR_min_bitrate_kbps; - } - - // revision and vbr method - if (gfp.VBR.ordinal() < vbrTypeTranslator.length) - vbr = vbrTypeTranslator[gfp.VBR.ordinal()]; - else - vbr = 0x00; // unknown - - revMethod = 0x10 * revision + vbr; - - // ReplayGain - if (gfc.findReplayGain) { - if (gfc.RadioGain > 0x1FE) - gfc.RadioGain = 0x1FE; - if (gfc.RadioGain < -0x1FE) - gfc.RadioGain = -0x1FE; - - // set name code - radioReplayGain = 0x2000; - // set originator code to `determined automatically' - radioReplayGain |= 0xC00; - - if (gfc.RadioGain >= 0) { - // set gain adjustment - radioReplayGain |= gfc.RadioGain; - } else { - // set the sign bit - radioReplayGain |= 0x200; - // set gain adjustment - radioReplayGain |= -gfc.RadioGain; - } - } - - // peak sample - if (gfc.findPeakSample) - peakSignalAmplitude = Math - .abs((int) ((((float) gfc.PeakSample) / 32767.0) - * Math.pow(2, 23) + .5)); - - // nogap - if (noGapCount != -1) { - if (noGapCurr > 0) - noGapPrevious = true; - - if (noGapCurr < noGapCount - 1) - noGapMore = true; - } - - // flags - flags = athType + ((expNPsyTune ? 1 : 0) << 4) - + ((safeJoint ? 1 : 0) << 5) + ((noGapMore ? 1 : 0) << 6) - + ((noGapPrevious ? 1 : 0) << 7); - - if (quality < 0) - quality = 0; - - // stereo mode field (Intensity stereo is not implemented) - switch (gfp.mode) { - case MONO: - stereoMode = 0; - break; - case STEREO: - stereoMode = 1; - break; - case DUAL_CHANNEL: - stereoMode = 2; - break; - case JOINT_STEREO: - if (gfp.force_ms) - stereoMode = 4; - else - stereoMode = 3; - break; - case NOT_SET: - //$FALL-THROUGH$ - default: - stereoMode = 7; - break; - } - - if (gfp.in_samplerate <= 32000) - sourceFreq = 0x00; - else if (gfp.in_samplerate == 48000) - sourceFreq = 0x02; - else if (gfp.in_samplerate > 48000) - sourceFreq = 0x03; - else { - // default is 44100Hz - sourceFreq = 0x01; - } - - // Check if the user overrided the default LAME behavior with some - // nasty options - if (gfp.short_blocks == ShortBlock.short_block_forced - || gfp.short_blocks == ShortBlock.short_block_dispensed - || ((gfp.lowpassfreq == -1) && (gfp.highpassfreq == -1)) || /* "-k" */ - (gfp.scale_left < gfp.scale_right) - || (gfp.scale_left > gfp.scale_right) - || (gfp.disable_reservoir && gfp.brate < 320) || gfp.noATH - || gfp.ATHonly || (athType == 0) || gfp.in_samplerate <= 32000) - nonOptimal = 1; - - misc = noiseShaping + (stereoMode << 2) + (nonOptimal << 5) - + (sourceFreq << 6); - - musicCRC = gfc.nMusicCRC; - - // Write all this information into the stream - - createInteger(streamBuffer, streamBufferPos + bytesWritten, quality); - bytesWritten += 4; - - for (int j = 0; j < 9; j++) { - streamBuffer[streamBufferPos + bytesWritten + j] = (byte) version - .charAt(j); - } - bytesWritten += 9; - - streamBuffer[streamBufferPos + bytesWritten] = (byte) revMethod; - bytesWritten++; - - streamBuffer[streamBufferPos + bytesWritten] = (byte) lowpass; - bytesWritten++; - - createInteger(streamBuffer, streamBufferPos + bytesWritten, - peakSignalAmplitude); - bytesWritten += 4; - - createShort(streamBuffer, streamBufferPos + bytesWritten, - radioReplayGain); - bytesWritten += 2; - - createShort(streamBuffer, streamBufferPos + bytesWritten, - audiophileReplayGain); - bytesWritten += 2; - - streamBuffer[streamBufferPos + bytesWritten] = (byte) flags; - bytesWritten++; - - if (abrBitrate >= 255) - streamBuffer[streamBufferPos + bytesWritten] = (byte) 0xFF; - else - streamBuffer[streamBufferPos + bytesWritten] = (byte) abrBitrate; - bytesWritten++; - - streamBuffer[streamBufferPos + bytesWritten] = (byte) (encDelay >> 4); - streamBuffer[streamBufferPos + bytesWritten + 1] = (byte) ((encDelay << 4) + (encPadding >> 8)); - streamBuffer[streamBufferPos + bytesWritten + 2] = (byte) encPadding; - - bytesWritten += 3; - - streamBuffer[streamBufferPos + bytesWritten] = (byte) misc; - bytesWritten++; - - // unused in rev0 - streamBuffer[streamBufferPos + bytesWritten++] = 0; - - createShort(streamBuffer, streamBufferPos + bytesWritten, gfp.preset); - bytesWritten += 2; - - createInteger(streamBuffer, streamBufferPos + bytesWritten, musicLength); - bytesWritten += 4; - - createShort(streamBuffer, streamBufferPos + bytesWritten, musicCRC); - bytesWritten += 2; - - // Calculate tag CRC.... must be done here, since it includes previous - // information - - for (int i = 0; i < bytesWritten; i++) - crc = crcUpdateLookup(streamBuffer[streamBufferPos + i], crc); - - createShort(streamBuffer, streamBufferPos + bytesWritten, crc); - bytesWritten += 2; - - return bytesWritten; - } - - private int skipId3v2(final RandomAccessFile fpStream) throws IOException { - // seek to the beginning of the stream - fpStream.seek(0); - // read 10 bytes in case there's an ID3 version 2 header here - byte[] id3v2Header = new byte[10]; - fpStream.readFully(id3v2Header); - /* does the stream begin with the ID3 version 2 file identifier? */ - int id3v2TagSize; - if (!new String(id3v2Header, "ISO-8859-1").startsWith("ID3")) { - /* - * the tag size (minus the 10-byte header) is encoded into four - * bytes where the most significant bit is clear in each byte - */ - id3v2TagSize = (((id3v2Header[6] & 0x7f) << 21) - | ((id3v2Header[7] & 0x7f) << 14) - | ((id3v2Header[8] & 0x7f) << 7) | (id3v2Header[9] & 0x7f)) - + id3v2Header.length; - } else { - /* no ID3 version 2 tag in this stream */ - id3v2TagSize = 0; - } - return id3v2TagSize; - } - - public final int getLameTagFrame(final LameGlobalFlags gfp, - final byte[] buffer) { - final LameInternalFlags gfc = gfp.internal_flags; - - if (!gfp.bWriteVbrTag) { - return 0; - } - if (gfc.Class_ID != Lame.LAME_ID) { - return 0; - } - if (gfc.VBR_seek_table.pos <= 0) { - return 0; - } - if (buffer.length < gfc.VBR_seek_table.TotalFrameSize) { - return gfc.VBR_seek_table.TotalFrameSize; - } - - Arrays.fill(buffer, 0, gfc.VBR_seek_table.TotalFrameSize, (byte) 0); - - // 4 bytes frame header - setLameTagFrameHeader(gfp, buffer); - - // Create TOC entries - byte toc[] = new byte[NUMTOCENTRIES]; - - if (gfp.free_format) { - for (int i = 1; i < NUMTOCENTRIES; ++i) - toc[i] = (byte) (255 * i / 100); - } else { - xingSeekTable(gfc.VBR_seek_table, toc); - } - - // Start writing the tag after the zero frame - int streamIndex = gfc.sideinfo_len; - /** - * Note: Xing header specifies that Xing data goes in the ancillary data - * with NO ERROR PROTECTION. If error protecton in enabled, the Xing - * data still starts at the same offset, and now it is in sideinfo data - * block, and thus will not decode correctly by non-Xing tag aware - * players - */ - if (gfp.error_protection) - streamIndex -= 2; - - // Put Vbr tag - if (gfp.VBR == VbrMode.vbr_off) { - buffer[streamIndex++] = (byte) VBRTag1.charAt(0); - buffer[streamIndex++] = (byte) VBRTag1.charAt(1); - buffer[streamIndex++] = (byte) VBRTag1.charAt(2); - buffer[streamIndex++] = (byte) VBRTag1.charAt(3); - - } else { - buffer[streamIndex++] = (byte) VBRTag0.charAt(0); - buffer[streamIndex++] = (byte) VBRTag0.charAt(1); - buffer[streamIndex++] = (byte) VBRTag0.charAt(2); - buffer[streamIndex++] = (byte) VBRTag0.charAt(3); - } - - // Put header flags - createInteger(buffer, streamIndex, FRAMES_FLAG + BYTES_FLAG + TOC_FLAG - + VBR_SCALE_FLAG); - streamIndex += 4; - - // Put Total Number of frames - createInteger(buffer, streamIndex, gfc.VBR_seek_table.nVbrNumFrames); - streamIndex += 4; - - // Put total audio stream size, including Xing/LAME Header - int streamSize = (gfc.VBR_seek_table.nBytesWritten + gfc.VBR_seek_table.TotalFrameSize); - createInteger(buffer, streamIndex, (int) streamSize); - streamIndex += 4; - - /* Put TOC */ - System.arraycopy(toc, 0, buffer, streamIndex, toc.length); - streamIndex += toc.length; - - if (gfp.error_protection) { - // (jo) error_protection: add crc16 information to header - bs.CRC_writeheader(gfc, buffer); - } - - // work out CRC so far: initially crc = 0 - int crc = 0x00; - for (int i = 0; i < streamIndex; i++) - crc = crcUpdateLookup(buffer[i], crc); - // Put LAME VBR info - streamIndex += putLameVBR(gfp, streamSize, buffer, streamIndex, crc); - - return gfc.VBR_seek_table.TotalFrameSize; - } - - /** - * Write final VBR tag to the file. - * - * @param gfp - * global flags - * @param stream - * stream to add the VBR tag to - * @return 0 (OK), -1 else - * @throws IOException - * I/O error - */ - public final int putVbrTag(final LameGlobalFlags gfp, - final RandomAccessFile stream) throws IOException { - final LameInternalFlags gfc = gfp.internal_flags; - - if (gfc.VBR_seek_table.pos <= 0) - return -1; - - // Seek to end of file - stream.seek(stream.length()); - - // Get file size, abort if file has zero length. - if (stream.length() == 0) - return -1; - - // The VBR tag may NOT be located at the beginning of the stream. If an - // ID3 version 2 tag was added, then it must be skipped to write the VBR - // tag data. - int id3v2TagSize = skipId3v2(stream); - - // Seek to the beginning of the stream - stream.seek(id3v2TagSize); - - byte[] buffer = new byte[MAXFRAMESIZE]; - int bytes = getLameTagFrame(gfp, buffer); - if (bytes > buffer.length) { - return -1; - } - - if (bytes < 1) { - return 0; - } - - // Put it all to disk again - stream.write(buffer, 0, bytes); - // success - return 0; - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRTagData.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRTagData.java deleted file mode 100644 index 7ae4acb5b..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VBRTagData.java +++ /dev/null @@ -1,50 +0,0 @@ -package mp3; - -/** - * Structure to receive extracted header (toc may be null). - * - * @author Ken - * - */ -public class VBRTagData { - /** - * From MPEG header 0=MPEG2, 1=MPEG1. - */ - protected int hId; - /** - * Sample rate determined from MPEG header. - */ - protected int samprate; - /** - * From Vbr header data. - */ - protected int flags; - /** - * Total bit stream frames from Vbr header data. - */ - public int frames; - /** - * Total bit stream bytes from Vbr header data. - */ - protected int bytes; - /** - * Encoded vbr scale from Vbr header data. - */ - protected int vbrScale; - /** - * May be null if toc not desired. - */ - protected byte[] toc = new byte[VBRTag.NUMTOCENTRIES]; - /** - * Size of VBR header, in bytes. - */ - public int headersize; - /** - * Encoder delay. - */ - public int encDelay; - /** - * Encoder padding added at end of stream. - */ - public int encPadding; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VbrMode.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VbrMode.java deleted file mode 100644 index e01aba003..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/VbrMode.java +++ /dev/null @@ -1,6 +0,0 @@ -package mp3; - -public enum VbrMode { - vbr_off, vbr_mt, vbr_rh, vbr_abr, vbr_mtrh; - public static final VbrMode vbr_default = vbr_mtrh; -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Version.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Version.java deleted file mode 100644 index 68db5b0ed..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mp3/Version.java +++ /dev/null @@ -1,90 +0,0 @@ -package mp3; - -public class Version { - - /** - * URL for the LAME website. - */ - private static final String LAME_URL = "http://www.mp3dev.org/"; - - /** - * Major version number. - */ - private static final int LAME_MAJOR_VERSION = 3; - /** - * Minor version number. - */ - private static final int LAME_MINOR_VERSION = 98; - /** - * Patch level. - */ - private static final int LAME_PATCH_VERSION = 4; - - /** - * Major version number. - */ - private static final int PSY_MAJOR_VERSION = 0; - /** - * Minor version number. - */ - private static final int PSY_MINOR_VERSION = 93; - - /** - * A string which describes the version of LAME. - * - * @return string which describes the version of LAME - */ - public final String getLameVersion() { - // primary to write screen reports - return (LAME_MAJOR_VERSION + "." + LAME_MINOR_VERSION + "." + LAME_PATCH_VERSION); - } - - /** - * The short version of the LAME version string. - * - * @return short version of the LAME version string - */ - public final String getLameShortVersion() { - // Adding date and time to version string makes it harder for output - // validation - return (LAME_MAJOR_VERSION + "." + LAME_MINOR_VERSION + "." + LAME_PATCH_VERSION); - } - - /** - * The shortest version of the LAME version string. - * - * @return shortest version of the LAME version string - */ - public final String getLameVeryShortVersion() { - // Adding date and time to version string makes it harder for output - return ("LAME" + LAME_MAJOR_VERSION + "." + LAME_MINOR_VERSION + "r"); - } - - /** - * String which describes the version of GPSYCHO - * - * @return string which describes the version of GPSYCHO - */ - public final String getPsyVersion() { - return (PSY_MAJOR_VERSION + "." + PSY_MINOR_VERSION); - } - - /** - * String which is a URL for the LAME website. - * - * @return string which is a URL for the LAME website - */ - public final String getLameUrl() { - return LAME_URL; - } - - /** - * Quite useless for a java version, however we are compatible ;-) - * - * @return "32bits" - */ - public final String getLameOsBitness() { - return "32bits"; - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Common.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Common.java deleted file mode 100644 index ba71f1f00..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Common.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * common.c: some common bitstream operations - * - * Copyright (C) 1999-2010 The L.A.M.E. project - * - * Initially written by Michael Hipp, see also AUTHORS and README. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: Common.java,v 1.6 2011/08/27 18:57:09 kenchis Exp $ */ - -package mpg; - -import mpg.MPGLib.mpstr_tag; - -public class Common { - - public static final int tabsel_123[][][] = { - { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,}, - {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,}, - {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} }, - - { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,}, - {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,}, - {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} } - }; - - public static final int freqs[] = { 44100, 48000, 32000, 22050, 24000, - 16000, 11025, 12000, 8000 }; - - public float muls[][] = new float[27][64]; - - private static final int MAX_INPUT_FRAMESIZE = 4096; - - public final boolean head_check(final long head, final int check_layer) { - /** - * <PRE> - * look for a valid header. - * if check_layer > 0, then require that - * nLayer = check_layer. - * </PRE> - */ - - /* bits 13-14 = layer 3 */ - int nLayer = (int) (4 - ((head >> 17) & 3)); - - if ((head & 0xffe00000L) != 0xffe00000L) { - /* syncword */ - return false; - } - - if (nLayer == 4) - return false; - - if (check_layer > 0 && nLayer != check_layer) - return false; - - if (((head >> 12) & 0xf) == 0xf) { - /* bits 16,17,18,19 = 1111 invalid bitrate */ - return false; - } - if (((head >> 10) & 0x3) == 0x3) { - /* bits 20,21 = 11 invalid sampling freq */ - return false; - } - if ((head & 0x3) == 0x2) - /* invalid emphasis */ - return false; - return true; - } - - /** - * decode a header and write the information into the frame structure - */ - public final int decode_header(final Frame fr, final long newhead) { - - if ((newhead & (1 << 20)) != 0) { - fr.lsf = (newhead & (1 << 19)) != 0 ? 0x0 : 0x1; - fr.mpeg25 = false; - } else { - fr.lsf = 1; - fr.mpeg25 = true; - } - - fr.lay = (int) (4 - ((newhead >> 17) & 3)); - if (((newhead >> 10) & 0x3) == 0x3) { - throw new RuntimeException("Stream error"); - } - if (fr.mpeg25) { - fr.sampling_frequency = (int) (6 + ((newhead >> 10) & 0x3)); - } else - fr.sampling_frequency = (int) (((newhead >> 10) & 0x3) + (fr.lsf * 3)); - - fr.error_protection = ((newhead >> 16) & 0x1) == 0; - - if (fr.mpeg25) /* allow Bitrate change for 2.5 ... */ - fr.bitrate_index = (int) ((newhead >> 12) & 0xf); - - fr.bitrate_index = (int) ((newhead >> 12) & 0xf); - fr.padding = (int) ((newhead >> 9) & 0x1); - fr.extension = (int) ((newhead >> 8) & 0x1); - fr.mode = (int) ((newhead >> 6) & 0x3); - fr.mode_ext = (int) ((newhead >> 4) & 0x3); - fr.copyright = (int) ((newhead >> 3) & 0x1); - fr.original = (int) ((newhead >> 2) & 0x1); - fr.emphasis = (int) (newhead & 0x3); - - fr.stereo = (fr.mode == MPG123.MPG_MD_MONO) ? 1 : 2; - - switch (fr.lay) { - case 1: - fr.framesize = tabsel_123[fr.lsf][0][fr.bitrate_index] * 12000; - fr.framesize /= freqs[fr.sampling_frequency]; - fr.framesize = ((fr.framesize + fr.padding) << 2) - 4; - fr.down_sample = 0; - fr.down_sample_sblimit = MPG123.SBLIMIT >> (fr.down_sample); - break; - - case 2: - fr.framesize = tabsel_123[fr.lsf][1][fr.bitrate_index] * 144000; - fr.framesize /= freqs[fr.sampling_frequency]; - fr.framesize += fr.padding - 4; - fr.down_sample = 0; - fr.down_sample_sblimit = MPG123.SBLIMIT >> (fr.down_sample); - break; - - case 3: - if (fr.framesize > MAX_INPUT_FRAMESIZE) { - System.err.printf("Frame size too big.\n"); - fr.framesize = MAX_INPUT_FRAMESIZE; - return (0); - } - - if (fr.bitrate_index == 0) - fr.framesize = 0; - else { - fr.framesize = tabsel_123[fr.lsf][2][fr.bitrate_index] * 144000; - fr.framesize /= freqs[fr.sampling_frequency] << (fr.lsf); - fr.framesize = fr.framesize + fr.padding - 4; - } - break; - default: - System.err.printf("Sorry, layer %d not supported\n", fr.lay); - return (0); - } - /* print_header(fr); */ - - return 1; - } - - private static final String modes[] = { "Stereo", "Joint-Stereo", - "Dual-Channel", "Single-Channel" }; - private static final String layers[] = { "Unknown", "I", "II", "III" }; - - public final void print_header(final Frame fr) { - - System.err - .printf("MPEG %s, Layer: %s, Freq: %d, mode: %s, modext: %d, BPF : %d\n", - fr.mpeg25 ? "2.5" : (fr.lsf != 0 ? "2.0" : "1.0"), - layers[fr.lay], freqs[fr.sampling_frequency], - modes[fr.mode], fr.mode_ext, fr.framesize + 4); - System.err - .printf("Channels: %d, copyright: %s, original: %s, CRC: %s, emphasis: %d.\n", - fr.stereo, fr.copyright != 0 ? "Yes" : "No", - fr.original != 0 ? "Yes" : "No", - fr.error_protection ? "Yes" : "No", fr.emphasis); - System.err.printf("Bitrate: %d Kbits/s, Extension value: %d\n", - tabsel_123[fr.lsf][fr.lay - 1][fr.bitrate_index], fr.extension); - } - - public final void print_header_compact(final Frame fr) { - System.err.printf("MPEG %s layer %s, %d kbit/s, %d Hz %s\n", - fr.mpeg25 ? "2.5" : (fr.lsf != 0 ? "2.0" : "1.0"), - layers[fr.lay], - tabsel_123[fr.lsf][fr.lay - 1][fr.bitrate_index], - freqs[fr.sampling_frequency], modes[fr.mode]); - } - - public final int getbits(final mpstr_tag mp, final int number_of_bits) { - long rval; - - if (number_of_bits <= 0 || null == mp.wordpointer) - return 0; - - { - rval = mp.wordpointer[mp.wordpointerPos + 0] & 0xff; - rval <<= 8; - rval |= mp.wordpointer[mp.wordpointerPos + 1] & 0xff; - rval <<= 8; - rval |= mp.wordpointer[mp.wordpointerPos + 2] & 0xff; - rval <<= mp.bitindex; - rval &= 0xffffffL; - - mp.bitindex += number_of_bits; - - rval >>= (24 - number_of_bits); - - mp.wordpointerPos += (mp.bitindex >> 3); - mp.bitindex &= 7; - } - return (int) rval; - } - - public final int getbits_fast(final mpstr_tag mp, final int number_of_bits) { - long rval; - - { - rval = mp.wordpointer[mp.wordpointerPos + 0] & 0xff; - rval <<= 8; - rval |= mp.wordpointer[mp.wordpointerPos + 1] & 0xff; - rval <<= mp.bitindex; - rval &= 0xffffL; - mp.bitindex += number_of_bits; - - rval >>= (16 - number_of_bits); - - mp.wordpointerPos += (mp.bitindex >> 3); - mp.bitindex &= 7; - } - return (int) rval; - } - - public final int set_pointer(final mpstr_tag mp, final int backstep) { - if (mp.fsizeold < 0 && backstep > 0) { - System.err.printf("hip: Can't step back %d bytes!\n", backstep); - return MPGLib.MP3_ERR; - } - byte[] bsbufold = mp.bsspace[1 - mp.bsnum]; - int bsbufoldPos = 512; - mp.wordpointerPos -= backstep; - if (backstep != 0) - System.arraycopy(bsbufold, bsbufoldPos + mp.fsizeold - backstep, - mp.wordpointer, mp.wordpointerPos, backstep); - mp.bitindex = 0; - return MPGLib.MP3_OK; - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/DCT64.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/DCT64.java deleted file mode 100644 index a5ae530f3..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/DCT64.java +++ /dev/null @@ -1,346 +0,0 @@ -/* - * dct64_i368.c - * - * Copyright (C) 1999-2010 The L.A.M.E. project - * - * Initially written by Michael Hipp, see also AUTHORS and README. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * - * Discrete Cosine Tansform (DCT) for subband synthesis - * optimized for machines with no auto-increment. - * The performance is highly compiler dependend. Maybe - * the dct64.c version for 'normal' processor may be faster - * even for Intel processors. - */ - -/* $Id: DCT64.java,v 1.7 2011/05/31 03:33:59 kenchis Exp $ */ - -package mpg; - -public class DCT64 { - - private TabInit tabInit; - - public void setModules(final TabInit ti) { - tabInit = ti; - } - - private void dct64_1(float[] out0, int out0Pos, float[] out1, int out1Pos, - float[] b1, int b2, float[] samples, int samplesPos) { - - { - float[]costab = tabInit.pnts[0]; - - b1[0x00] = samples[samplesPos+0x00] + samples[samplesPos+0x1F]; - b1[0x1F] = (samples[samplesPos+0x00] - samples[samplesPos+0x1F]) * costab[0x0]; - - b1[0x01] = samples[samplesPos+0x01] + samples[samplesPos+0x1E]; - b1[0x1E] = (samples[samplesPos+0x01] - samples[samplesPos+0x1E]) * costab[0x1]; - - b1[0x02] = samples[samplesPos+0x02] + samples[samplesPos+0x1D]; - b1[0x1D] = (samples[samplesPos+0x02] - samples[samplesPos+0x1D]) * costab[0x2]; - - b1[0x03] = samples[samplesPos+0x03] + samples[samplesPos+0x1C]; - b1[0x1C] = (samples[samplesPos+0x03] - samples[samplesPos+0x1C]) * costab[0x3]; - - b1[0x04] = samples[samplesPos+0x04] + samples[samplesPos+0x1B]; - b1[0x1B] = (samples[samplesPos+0x04] - samples[samplesPos+0x1B]) * costab[0x4]; - - b1[0x05] = samples[samplesPos+0x05] + samples[samplesPos+0x1A]; - b1[0x1A] = (samples[samplesPos+0x05] - samples[samplesPos+0x1A]) * costab[0x5]; - - b1[0x06] = samples[samplesPos+0x06] + samples[samplesPos+0x19]; - b1[0x19] = (samples[samplesPos+0x06] - samples[samplesPos+0x19]) * costab[0x6]; - - b1[0x07] = samples[samplesPos+0x07] + samples[samplesPos+0x18]; - b1[0x18] = (samples[samplesPos+0x07] - samples[samplesPos+0x18]) * costab[0x7]; - - b1[0x08] = samples[samplesPos+0x08] + samples[samplesPos+0x17]; - b1[0x17] = (samples[samplesPos+0x08] - samples[samplesPos+0x17]) * costab[0x8]; - - b1[0x09] = samples[samplesPos+0x09] + samples[samplesPos+0x16]; - b1[0x16] = (samples[samplesPos+0x09] - samples[samplesPos+0x16]) * costab[0x9]; - - b1[0x0A] = samples[samplesPos+0x0A] + samples[samplesPos+0x15]; - b1[0x15] = (samples[samplesPos+0x0A] - samples[samplesPos+0x15]) * costab[0xA]; - - b1[0x0B] = samples[samplesPos+0x0B] + samples[samplesPos+0x14]; - b1[0x14] = (samples[samplesPos+0x0B] - samples[samplesPos+0x14]) * costab[0xB]; - - b1[0x0C] = samples[samplesPos+0x0C] + samples[samplesPos+0x13]; - b1[0x13] = (samples[samplesPos+0x0C] - samples[samplesPos+0x13]) * costab[0xC]; - - b1[0x0D] = samples[samplesPos+0x0D] + samples[samplesPos+0x12]; - b1[0x12] = (samples[samplesPos+0x0D] - samples[samplesPos+0x12]) * costab[0xD]; - - b1[0x0E] = samples[samplesPos+0x0E] + samples[samplesPos+0x11]; - b1[0x11] = (samples[samplesPos+0x0E] - samples[samplesPos+0x11]) * costab[0xE]; - - b1[0x0F] = samples[samplesPos+0x0F] + samples[samplesPos+0x10]; - b1[0x10] = (samples[samplesPos+0x0F] - samples[samplesPos+0x10]) * costab[0xF]; - } - - - { - float[] costab = tabInit.pnts[1]; - - b1[b2 + 0x00] = b1[0x00] + b1[0x0F]; - b1[b2 + 0x0F] = (b1[0x00] - b1[0x0F]) * costab[0]; - b1[b2 + 0x01] = b1[0x01] + b1[0x0E]; - b1[b2 + 0x0E] = (b1[0x01] - b1[0x0E]) * costab[1]; - b1[b2 + 0x02] = b1[0x02] + b1[0x0D]; - b1[b2 + 0x0D] = (b1[0x02] - b1[0x0D]) * costab[2]; - b1[b2 + 0x03] = b1[0x03] + b1[0x0C]; - b1[b2 + 0x0C] = (b1[0x03] - b1[0x0C]) * costab[3]; - b1[b2 + 0x04] = b1[0x04] + b1[0x0B]; - b1[b2 + 0x0B] = (b1[0x04] - b1[0x0B]) * costab[4]; - b1[b2 + 0x05] = b1[0x05] + b1[0x0A]; - b1[b2 + 0x0A] = (b1[0x05] - b1[0x0A]) * costab[5]; - b1[b2 + 0x06] = b1[0x06] + b1[0x09]; - b1[b2 + 0x09] = (b1[0x06] - b1[0x09]) * costab[6]; - b1[b2 + 0x07] = b1[0x07] + b1[0x08]; - b1[b2 + 0x08] = (b1[0x07] - b1[0x08]) * costab[7]; - - b1[b2 + 0x10] = b1[0x10] + b1[0x1F]; - b1[b2 + 0x1F] = (b1[0x1F] - b1[0x10]) * costab[0]; - b1[b2 + 0x11] = b1[0x11] + b1[0x1E]; - b1[b2 + 0x1E] = (b1[0x1E] - b1[0x11]) * costab[1]; - b1[b2 + 0x12] = b1[0x12] + b1[0x1D]; - b1[b2 + 0x1D] = (b1[0x1D] - b1[0x12]) * costab[2]; - b1[b2 + 0x13] = b1[0x13] + b1[0x1C]; - b1[b2 + 0x1C] = (b1[0x1C] - b1[0x13]) * costab[3]; - b1[b2 + 0x14] = b1[0x14] + b1[0x1B]; - b1[b2 + 0x1B] = (b1[0x1B] - b1[0x14]) * costab[4]; - b1[b2 + 0x15] = b1[0x15] + b1[0x1A]; - b1[b2 + 0x1A] = (b1[0x1A] - b1[0x15]) * costab[5]; - b1[b2 + 0x16] = b1[0x16] + b1[0x19]; - b1[b2 + 0x19] = (b1[0x19] - b1[0x16]) * costab[6]; - b1[b2 + 0x17] = b1[0x17] + b1[0x18]; - b1[b2 + 0x18] = (b1[0x18] - b1[0x17]) * costab[7]; - } - - { - float[] costab = tabInit.pnts[2]; - - b1[0x00] = b1[b2 + 0x00] + b1[b2 + 0x07]; - b1[0x07] = (b1[b2 + 0x00] - b1[b2 + 0x07]) * costab[0]; - b1[0x01] = b1[b2 + 0x01] + b1[b2 + 0x06]; - b1[0x06] = (b1[b2 + 0x01] - b1[b2 + 0x06]) * costab[1]; - b1[0x02] = b1[b2 + 0x02] + b1[b2 + 0x05]; - b1[0x05] = (b1[b2 + 0x02] - b1[b2 + 0x05]) * costab[2]; - b1[0x03] = b1[b2 + 0x03] + b1[b2 + 0x04]; - b1[0x04] = (b1[b2 + 0x03] - b1[b2 + 0x04]) * costab[3]; - - b1[0x08] = b1[b2 + 0x08] + b1[b2 + 0x0F]; - b1[0x0F] = (b1[b2 + 0x0F] - b1[b2 + 0x08]) * costab[0]; - b1[0x09] = b1[b2 + 0x09] + b1[b2 + 0x0E]; - b1[0x0E] = (b1[b2 + 0x0E] - b1[b2 + 0x09]) * costab[1]; - b1[0x0A] = b1[b2 + 0x0A] + b1[b2 + 0x0D]; - b1[0x0D] = (b1[b2 + 0x0D] - b1[b2 + 0x0A]) * costab[2]; - b1[0x0B] = b1[b2 + 0x0B] + b1[b2 + 0x0C]; - b1[0x0C] = (b1[b2 + 0x0C] - b1[b2 + 0x0B]) * costab[3]; - - b1[0x10] = b1[b2 + 0x10] + b1[b2 + 0x17]; - b1[0x17] = (b1[b2 + 0x10] - b1[b2 + 0x17]) * costab[0]; - b1[0x11] = b1[b2 + 0x11] + b1[b2 + 0x16]; - b1[0x16] = (b1[b2 + 0x11] - b1[b2 + 0x16]) * costab[1]; - b1[0x12] = b1[b2 + 0x12] + b1[b2 + 0x15]; - b1[0x15] = (b1[b2 + 0x12] - b1[b2 + 0x15]) * costab[2]; - b1[0x13] = b1[b2 + 0x13] + b1[b2 + 0x14]; - b1[0x14] = (b1[b2 + 0x13] - b1[b2 + 0x14]) * costab[3]; - - b1[0x18] = b1[b2 + 0x18] + b1[b2 + 0x1F]; - b1[0x1F] = (b1[b2 + 0x1F] - b1[b2 + 0x18]) * costab[0]; - b1[0x19] = b1[b2 + 0x19] + b1[b2 + 0x1E]; - b1[0x1E] = (b1[b2 + 0x1E] - b1[b2 + 0x19]) * costab[1]; - b1[0x1A] = b1[b2 + 0x1A] + b1[b2 + 0x1D]; - b1[0x1D] = (b1[b2 + 0x1D] - b1[b2 + 0x1A]) * costab[2]; - b1[0x1B] = b1[b2 + 0x1B] + b1[b2 + 0x1C]; - b1[0x1C] = (b1[b2 + 0x1C] - b1[b2 + 0x1B]) * costab[3]; - } - - { - final float cos0 = tabInit.pnts[3][0]; - final float cos1 = tabInit.pnts[3][1]; - - b1[b2 + 0x00] = b1[0x00] + b1[0x03]; - b1[b2 + 0x03] = (b1[0x00] - b1[0x03]) * cos0; - b1[b2 + 0x01] = b1[0x01] + b1[0x02]; - b1[b2 + 0x02] = (b1[0x01] - b1[0x02]) * cos1; - - b1[b2 + 0x04] = b1[0x04] + b1[0x07]; - b1[b2 + 0x07] = (b1[0x07] - b1[0x04]) * cos0; - b1[b2 + 0x05] = b1[0x05] + b1[0x06]; - b1[b2 + 0x06] = (b1[0x06] - b1[0x05]) * cos1; - - b1[b2 + 0x08] = b1[0x08] + b1[0x0B]; - b1[b2 + 0x0B] = (b1[0x08] - b1[0x0B]) * cos0; - b1[b2 + 0x09] = b1[0x09] + b1[0x0A]; - b1[b2 + 0x0A] = (b1[0x09] - b1[0x0A]) * cos1; - - b1[b2 + 0x0C] = b1[0x0C] + b1[0x0F]; - b1[b2 + 0x0F] = (b1[0x0F] - b1[0x0C]) * cos0; - b1[b2 + 0x0D] = b1[0x0D] + b1[0x0E]; - b1[b2 + 0x0E] = (b1[0x0E] - b1[0x0D]) * cos1; - - b1[b2 + 0x10] = b1[0x10] + b1[0x13]; - b1[b2 + 0x13] = (b1[0x10] - b1[0x13]) * cos0; - b1[b2 + 0x11] = b1[0x11] + b1[0x12]; - b1[b2 + 0x12] = (b1[0x11] - b1[0x12]) * cos1; - - b1[b2 + 0x14] = b1[0x14] + b1[0x17]; - b1[b2 + 0x17] = (b1[0x17] - b1[0x14]) * cos0; - b1[b2 + 0x15] = b1[0x15] + b1[0x16]; - b1[b2 + 0x16] = (b1[0x16] - b1[0x15]) * cos1; - - b1[b2 + 0x18] = b1[0x18] + b1[0x1B]; - b1[b2 + 0x1B] = (b1[0x18] - b1[0x1B]) * cos0; - b1[b2 + 0x19] = b1[0x19] + b1[0x1A]; - b1[b2 + 0x1A] = (b1[0x19] - b1[0x1A]) * cos1; - - b1[b2 + 0x1C] = b1[0x1C] + b1[0x1F]; - b1[b2 + 0x1F] = (b1[0x1F] - b1[0x1C]) * cos0; - b1[b2 + 0x1D] = b1[0x1D] + b1[0x1E]; - b1[b2 + 0x1E] = (b1[0x1E] - b1[0x1D]) * cos1; - } - - { - final float cos0 = tabInit.pnts[4][0]; - - b1[0x00] = b1[b2 + 0x00] + b1[b2 + 0x01]; - b1[0x01] = (b1[b2 + 0x00] - b1[b2 + 0x01]) * cos0; - b1[0x02] = b1[b2 + 0x02] + b1[b2 + 0x03]; - b1[0x03] = (b1[b2 + 0x03] - b1[b2 + 0x02]) * cos0; - b1[0x02] += b1[0x03]; - - b1[0x04] = b1[b2 + 0x04] + b1[b2 + 0x05]; - b1[0x05] = (b1[b2 + 0x04] - b1[b2 + 0x05]) * cos0; - b1[0x06] = b1[b2 + 0x06] + b1[b2 + 0x07]; - b1[0x07] = (b1[b2 + 0x07] - b1[b2 + 0x06]) * cos0; - b1[0x06] += b1[0x07]; - b1[0x04] += b1[0x06]; - b1[0x06] += b1[0x05]; - b1[0x05] += b1[0x07]; - - b1[0x08] = b1[b2 + 0x08] + b1[b2 + 0x09]; - b1[0x09] = (b1[b2 + 0x08] - b1[b2 + 0x09]) * cos0; - b1[0x0A] = b1[b2 + 0x0A] + b1[b2 + 0x0B]; - b1[0x0B] = (b1[b2 + 0x0B] - b1[b2 + 0x0A]) * cos0; - b1[0x0A] += b1[0x0B]; - - b1[0x0C] = b1[b2 + 0x0C] + b1[b2 + 0x0D]; - b1[0x0D] = (b1[b2 + 0x0C] - b1[b2 + 0x0D]) * cos0; - b1[0x0E] = b1[b2 + 0x0E] + b1[b2 + 0x0F]; - b1[0x0F] = (b1[b2 + 0x0F] - b1[b2 + 0x0E]) * cos0; - b1[0x0E] += b1[0x0F]; - b1[0x0C] += b1[0x0E]; - b1[0x0E] += b1[0x0D]; - b1[0x0D] += b1[0x0F]; - - b1[0x10] = b1[b2 + 0x10] + b1[b2 + 0x11]; - b1[0x11] = (b1[b2 + 0x10] - b1[b2 + 0x11]) * cos0; - b1[0x12] = b1[b2 + 0x12] + b1[b2 + 0x13]; - b1[0x13] = (b1[b2 + 0x13] - b1[b2 + 0x12]) * cos0; - b1[0x12] += b1[0x13]; - - b1[0x14] = b1[b2 + 0x14] + b1[b2 + 0x15]; - b1[0x15] = (b1[b2 + 0x14] - b1[b2 + 0x15]) * cos0; - b1[0x16] = b1[b2 + 0x16] + b1[b2 + 0x17]; - b1[0x17] = (b1[b2 + 0x17] - b1[b2 + 0x16]) * cos0; - b1[0x16] += b1[0x17]; - b1[0x14] += b1[0x16]; - b1[0x16] += b1[0x15]; - b1[0x15] += b1[0x17]; - - b1[0x18] = b1[b2 + 0x18] + b1[b2 + 0x19]; - b1[0x19] = (b1[b2 + 0x18] - b1[b2 + 0x19]) * cos0; - b1[0x1A] = b1[b2 + 0x1A] + b1[b2 + 0x1B]; - b1[0x1B] = (b1[b2 + 0x1B] - b1[b2 + 0x1A]) * cos0; - b1[0x1A] += b1[0x1B]; - - b1[0x1C] = b1[b2 + 0x1C] + b1[b2 + 0x1D]; - b1[0x1D] = (b1[b2 + 0x1C] - b1[b2 + 0x1D]) * cos0; - b1[0x1E] = b1[b2 + 0x1E] + b1[b2 + 0x1F]; - b1[0x1F] = (b1[b2 + 0x1F] - b1[b2 + 0x1E]) * cos0; - b1[0x1E] += b1[0x1F]; - b1[0x1C] += b1[0x1E]; - b1[0x1E] += b1[0x1D]; - b1[0x1D] += b1[0x1F]; - } - - out0[out0Pos+(0x10 * 16)] = b1[0x00]; - out0[out0Pos+(0x10 * 12)] = b1[0x04]; - out0[out0Pos+(0x10 * 8)] = b1[0x02]; - out0[out0Pos+(0x10 * 4)] = b1[0x06]; - out0[out0Pos+(0x10 * 0)] = b1[0x01]; - out1[out1Pos+(0x10 * 0)] = b1[0x01]; - out1[out1Pos+(0x10 * 4)] = b1[0x05]; - out1[out1Pos+(0x10 * 8)] = b1[0x03]; - out1[out1Pos+(0x10 * 12)] = b1[0x07]; - - b1[0x08] += b1[0x0C]; - out0[out0Pos+(0x10 * 14)] = b1[0x08]; - b1[0x0C] += b1[0x0a]; - out0[out0Pos+(0x10 * 10)] = b1[0x0C]; - b1[0x0A] += b1[0x0E]; - out0[out0Pos+(0x10 * 6)] = b1[0x0A]; - b1[0x0E] += b1[0x09]; - out0[out0Pos+(0x10 * 2)] = b1[0x0E]; - b1[0x09] += b1[0x0D]; - out1[out1Pos+(0x10 * 2)] = b1[0x09]; - b1[0x0D] += b1[0x0B]; - out1[out1Pos+(0x10 * 6)] = b1[0x0D]; - b1[0x0B] += b1[0x0F]; - out1[out1Pos+(0x10 * 10)] = b1[0x0B]; - out1[out1Pos+(0x10 * 14)] = b1[0x0F]; - - b1[0x18] += b1[0x1C]; - out0[out0Pos+(0x10 * 15)] = b1[0x10] + b1[0x18]; - out0[out0Pos+(0x10 * 13)] = b1[0x18] + b1[0x14]; - b1[0x1C] += b1[0x1a]; - out0[out0Pos+(0x10 * 11)] = b1[0x14] + b1[0x1C]; - out0[out0Pos+(0x10 * 9)] = b1[0x1C] + b1[0x12]; - b1[0x1A] += b1[0x1E]; - out0[out0Pos+(0x10 * 7)] = b1[0x12] + b1[0x1A]; - out0[out0Pos+(0x10 * 5)] = b1[0x1A] + b1[0x16]; - b1[0x1E] += b1[0x19]; - out0[out0Pos+(0x10 * 3)] = b1[0x16] + b1[0x1E]; - out0[out0Pos+(0x10 * 1)] = b1[0x1E] + b1[0x11]; - b1[0x19] += b1[0x1D]; - out1[out1Pos+(0x10 * 1)] = b1[0x11] + b1[0x19]; - out1[out1Pos+(0x10 * 3)] = b1[0x19] + b1[0x15]; - b1[0x1D] += b1[0x1B]; - out1[out1Pos+(0x10 * 5)] = b1[0x15] + b1[0x1D]; - out1[out1Pos+(0x10 * 7)] = b1[0x1D] + b1[0x13]; - b1[0x1B] += b1[0x1F]; - out1[out1Pos+(0x10 * 9)] = b1[0x13] + b1[0x1B]; - out1[out1Pos+(0x10 * 11)] = b1[0x1B] + b1[0x17]; - out1[out1Pos+(0x10 * 13)] = b1[0x17] + b1[0x1F]; - out1[out1Pos+(0x10 * 15)] = b1[0x1F]; - } - - /* - * the call via dct64 is a trick to force GCC to use - * (new) registers for the b1,b2 pointer to the bufs[xx] field - */ - public void dct64(float[] a, int aPos, float[] b, int bPos, float[] c, - int cPos) { - float bufs[] = new float[0x40]; - dct64_1(a, aPos, b, bPos, bufs, 0x20, c, cPos); - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Decode.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Decode.java deleted file mode 100644 index 673105890..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Decode.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * decode_i396.c: Mpeg Layer-1,2,3 audio decoder - * - * Copyright (C) 1999-2010 The L.A.M.E. project - * - * Initially written by Michael Hipp, see also AUTHORS and README. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * - * Slighlty optimized for machines without autoincrement/decrement. - * The performance is highly compiler dependend. Maybe - * the decode.c version for 'normal' processor may be faster - * even for Intel processors. - */ - -/* $Id: Decode.java,v 1.10 2011/05/31 03:33:59 kenchis Exp $ */ - -package mpg; - -import mpg.MPGLib.ProcessedBytes; -import mpg.MPGLib.mpstr_tag; - -public class Decode { - - private TabInit tab; - private DCT64 dct64; - - public void setModules(TabInit t, DCT64 d) { - tab = t; - dct64 = d; - } - - interface Factory<T> { - public T create(float x); - } - - /* old WRITE_SAMPLE_CLIPPED */ - private <T> int WRITE_SAMPLE_CLIPPED(int samples, float sum, int clip, - T[] out, Factory<T> tFactory) { - /* old WRITE_SAMPLE_CLIPPED */ - if ((sum) > 32767.0) { - out[samples] = tFactory.create(32767); - (clip)++; - } else if ((sum) < -32768.0) { - out[samples] = tFactory.create(-32768); - (clip)++; - } else { - out[samples] = tFactory.create((int) ((sum) > 0 ? (sum) + 0.5 - : (sum) - 0.5)); - } - return clip; - } - - private <T> void WRITE_SAMPLE_UNCLIPPED(int samples, float sum, int clip, - T[] out, Factory<T> tFactory) { - out[samples] = tFactory.create(sum); - } - - <T>int synth_1to1_mono(mpstr_tag mp, float[] bandPtr, int bandPos, T[] out, - ProcessedBytes pnt, Factory<T> tFactory) { - @SuppressWarnings("unchecked") - T[] samples_tmp = (T[]) (new Object[64]); - int tmp1 = 0; - int i, ret; - ProcessedBytes pnt1 = new ProcessedBytes(); - - ret = synth_1to1(mp, bandPtr, bandPos, 0, samples_tmp, pnt1, tFactory); - int outPos = pnt.pb; - - for (i = 0; i < 32; i++) { - out[outPos++] = samples_tmp[tmp1]; - tmp1 += 2; - } - pnt.pb += 32; - - return ret; - } - - <T> int synth_1to1_mono_unclipped(mpstr_tag mp, float[] bandPtr, - int bandPos, T[] out, ProcessedBytes pnt, - Factory<T> tFactory) { - @SuppressWarnings("unchecked") - T[] samples_tmp = (T[]) (new Object[64]); - int tmp1 = 0; - int i, ret; - ProcessedBytes pnt1 = new ProcessedBytes(); - - ret = synth_1to1_unclipped(mp, bandPtr, bandPos, 0, samples_tmp, - pnt1, tFactory); - int outPos = pnt.pb; - - for (i = 0; i < 32; i++) { - out[outPos++] = samples_tmp[tmp1]; - tmp1 += 2; - } - pnt.pb += 32; - - return ret; - } - - private static final int step = 2; - - <T>int synth_1to1(mpstr_tag mp, float[] bandPtr, int bandPos, int channel, - T[] out, ProcessedBytes pnt, Factory<T> tFactory) { - int bo; - int samples = pnt.pb; - float[] b0; - int b0Pos; - float buf[][]; - int clip = 0; - int bo1; - - bo = mp.synth_bo; - - if (0 == channel) { - bo--; - bo &= 0xf; - buf = mp.synth_buffs[0]; - } else { - samples ++; - buf = mp.synth_buffs[1]; - } - - if ((bo & 0x1) != 0) { - b0 = buf[0]; - b0Pos = 0; - bo1 = bo; - dct64.dct64(buf[1], ((bo + 1) & 0xf), buf[0], bo, bandPtr, bandPos); - } else { - b0 = buf[1]; - b0Pos = 0; - bo1 = bo + 1; - dct64.dct64(buf[0], bo, buf[1], bo + 1, bandPtr, bandPos); - } - - mp.synth_bo = bo; - - { - int j; - int window = 16 - bo1; - - for (j = 16; j != 0; j--, b0Pos += 0x10, window += 0x20, samples += step) { - float sum; - sum = tab.decwin[window + 0x0] * b0[b0Pos + 0x0]; - sum -= tab.decwin[window + 0x1] * b0[b0Pos + 0x1]; - sum += tab.decwin[window + 0x2] * b0[b0Pos + 0x2]; - sum -= tab.decwin[window + 0x3] * b0[b0Pos + 0x3]; - sum += tab.decwin[window + 0x4] * b0[b0Pos + 0x4]; - sum -= tab.decwin[window + 0x5] * b0[b0Pos + 0x5]; - sum += tab.decwin[window + 0x6] * b0[b0Pos + 0x6]; - sum -= tab.decwin[window + 0x7] * b0[b0Pos + 0x7]; - sum += tab.decwin[window + 0x8] * b0[b0Pos + 0x8]; - sum -= tab.decwin[window + 0x9] * b0[b0Pos + 0x9]; - sum += tab.decwin[window + 0xA] * b0[b0Pos + 0xA]; - sum -= tab.decwin[window + 0xB] * b0[b0Pos + 0xB]; - sum += tab.decwin[window + 0xC] * b0[b0Pos + 0xC]; - sum -= tab.decwin[window + 0xD] * b0[b0Pos + 0xD]; - sum += tab.decwin[window + 0xE] * b0[b0Pos + 0xE]; - sum -= tab.decwin[window + 0xF] * b0[b0Pos + 0xF]; - clip = WRITE_SAMPLE_CLIPPED(samples, sum, clip, out, tFactory); - } - - { - float sum; - sum = tab.decwin[window + 0x0] * b0[b0Pos + 0x0]; - sum += tab.decwin[window + 0x2] * b0[b0Pos + 0x2]; - sum += tab.decwin[window + 0x4] * b0[b0Pos + 0x4]; - sum += tab.decwin[window + 0x6] * b0[b0Pos + 0x6]; - sum += tab.decwin[window + 0x8] * b0[b0Pos + 0x8]; - sum += tab.decwin[window + 0xA] * b0[b0Pos + 0xA]; - sum += tab.decwin[window + 0xC] * b0[b0Pos + 0xC]; - sum += tab.decwin[window + 0xE] * b0[b0Pos + 0xE]; - clip = WRITE_SAMPLE_CLIPPED(samples, sum, clip, out, tFactory); - b0Pos -= 0x10; - window -= 0x20; - samples += step; - } - window += bo1 << 1; - - for (j = 15; j != 0; j--, b0Pos -= 0x10, window -= 0x20, samples += step) { - float sum; - sum = -tab.decwin[window + -0x1] * b0[b0Pos + 0x0]; - sum -= tab.decwin[window + -0x2] * b0[b0Pos + 0x1]; - sum -= tab.decwin[window + -0x3] * b0[b0Pos + 0x2]; - sum -= tab.decwin[window + -0x4] * b0[b0Pos + 0x3]; - sum -= tab.decwin[window + -0x5] * b0[b0Pos + 0x4]; - sum -= tab.decwin[window + -0x6] * b0[b0Pos + 0x5]; - sum -= tab.decwin[window + -0x7] * b0[b0Pos + 0x6]; - sum -= tab.decwin[window + -0x8] * b0[b0Pos + 0x7]; - sum -= tab.decwin[window + -0x9] * b0[b0Pos + 0x8]; - sum -= tab.decwin[window + -0xA] * b0[b0Pos + 0x9]; - sum -= tab.decwin[window + -0xB] * b0[b0Pos + 0xA]; - sum -= tab.decwin[window + -0xC] * b0[b0Pos + 0xB]; - sum -= tab.decwin[window + -0xD] * b0[b0Pos + 0xC]; - sum -= tab.decwin[window + -0xE] * b0[b0Pos + 0xD]; - sum -= tab.decwin[window + -0xF] * b0[b0Pos + 0xE]; - sum -= tab.decwin[window + -0x0] * b0[b0Pos + 0xF]; - - clip = WRITE_SAMPLE_CLIPPED(samples, sum, clip, out, tFactory); - } - } - pnt.pb += 64; - - return clip; - } - - <T>int - synth_1to1_unclipped(mpstr_tag mp, float[] bandPtr, int bandPos, int channel, T[] out, ProcessedBytes pnt, Factory<T> tFactory) - { - int bo; - int samples = pnt.pb; - float[] b0; - int b0Pos; - float buf[][]; - int clip = 0; - int bo1; - - bo = mp.synth_bo; - - if (0 == channel) { - bo--; - bo &= 0xf; - buf = mp.synth_buffs[0]; - } else { - samples ++; - buf = mp.synth_buffs[1]; - } - - if ((bo & 0x1) != 0) { - b0 = buf[0]; - b0Pos = 0; - bo1 = bo; - dct64.dct64(buf[1], ((bo + 1) & 0xf), buf[0], bo, bandPtr, bandPos); - } else { - b0 = buf[1]; - b0Pos = 0; - bo1 = bo + 1; - dct64.dct64(buf[0], bo, buf[1], bo + 1, bandPtr, bandPos); - } - - mp.synth_bo = bo; - - { - int j; - int window = 16 - bo1; - - for (j = 16; j != 0; j--, b0Pos += 0x10, window += 0x20, samples += step) { - float sum; - sum = tab.decwin[window + 0x0] * b0[b0Pos + 0x0]; - sum -= tab.decwin[window + 0x1] * b0[b0Pos + 0x1]; - sum += tab.decwin[window + 0x2] * b0[b0Pos + 0x2]; - sum -= tab.decwin[window + 0x3] * b0[b0Pos + 0x3]; - sum += tab.decwin[window + 0x4] * b0[b0Pos + 0x4]; - sum -= tab.decwin[window + 0x5] * b0[b0Pos + 0x5]; - sum += tab.decwin[window + 0x6] * b0[b0Pos + 0x6]; - sum -= tab.decwin[window + 0x7] * b0[b0Pos + 0x7]; - sum += tab.decwin[window + 0x8] * b0[b0Pos + 0x8]; - sum -= tab.decwin[window + 0x9] * b0[b0Pos + 0x9]; - sum += tab.decwin[window + 0xA] * b0[b0Pos + 0xA]; - sum -= tab.decwin[window + 0xB] * b0[b0Pos + 0xB]; - sum += tab.decwin[window + 0xC] * b0[b0Pos + 0xC]; - sum -= tab.decwin[window + 0xD] * b0[b0Pos + 0xD]; - sum += tab.decwin[window + 0xE] * b0[b0Pos + 0xE]; - sum -= tab.decwin[window + 0xF] * b0[b0Pos + 0xF]; - WRITE_SAMPLE_UNCLIPPED(samples, sum, clip, out, tFactory); - } - - { - float sum; - sum = tab.decwin[window + 0x0] * b0[b0Pos + 0x0]; - sum += tab.decwin[window + 0x2] * b0[b0Pos + 0x2]; - sum += tab.decwin[window + 0x4] * b0[b0Pos + 0x4]; - sum += tab.decwin[window + 0x6] * b0[b0Pos + 0x6]; - sum += tab.decwin[window + 0x8] * b0[b0Pos + 0x8]; - sum += tab.decwin[window + 0xA] * b0[b0Pos + 0xA]; - sum += tab.decwin[window + 0xC] * b0[b0Pos + 0xC]; - sum += tab.decwin[window + 0xE] * b0[b0Pos + 0xE]; - WRITE_SAMPLE_UNCLIPPED(samples, sum, clip, out, tFactory); - b0Pos -= 0x10; - window -= 0x20; - samples += step; - } - window += bo1 << 1; - - for (j = 15; j != 0; j--, b0Pos -= 0x10, window -= 0x20, samples += step) { - float sum; - sum = -tab.decwin[window + -0x1] * b0[b0Pos + 0x0]; - sum -= tab.decwin[window + -0x2] * b0[b0Pos + 0x1]; - sum -= tab.decwin[window + -0x3] * b0[b0Pos + 0x2]; - sum -= tab.decwin[window + -0x4] * b0[b0Pos + 0x3]; - sum -= tab.decwin[window + -0x5] * b0[b0Pos + 0x4]; - sum -= tab.decwin[window + -0x6] * b0[b0Pos + 0x5]; - sum -= tab.decwin[window + -0x7] * b0[b0Pos + 0x6]; - sum -= tab.decwin[window + -0x8] * b0[b0Pos + 0x7]; - sum -= tab.decwin[window + -0x9] * b0[b0Pos + 0x8]; - sum -= tab.decwin[window + -0xA] * b0[b0Pos + 0x9]; - sum -= tab.decwin[window + -0xB] * b0[b0Pos + 0xA]; - sum -= tab.decwin[window + -0xC] * b0[b0Pos + 0xB]; - sum -= tab.decwin[window + -0xD] * b0[b0Pos + 0xC]; - sum -= tab.decwin[window + -0xE] * b0[b0Pos + 0xD]; - sum -= tab.decwin[window + -0xF] * b0[b0Pos + 0xE]; - sum -= tab.decwin[window + -0x0] * b0[b0Pos + 0xF]; - - WRITE_SAMPLE_UNCLIPPED(samples, sum, clip, out, tFactory); - } - } - pnt.pb += 64; - - return clip; - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Frame.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Frame.java deleted file mode 100644 index bddbf6fd0..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Frame.java +++ /dev/null @@ -1,31 +0,0 @@ -package mpg; - -import mpg.L2Tables.al_table2; - -public class Frame { - - int stereo; - int jsbound; - int single; /* single channel (monophonic) */ - int lsf; /* 0 = MPEG-1, 1 = MPEG-2/2.5 */ - boolean mpeg25; /* 1 = MPEG-2.5, 0 = MPEG-1/2 */ - int lay; /* Layer */ - boolean error_protection; /* 1 = CRC-16 code following header */ - int bitrate_index; - int sampling_frequency; /* sample rate of decompressed audio in Hz */ - int padding; - int extension; - int mode; - int mode_ext; - int copyright; - int original; - int emphasis; - int framesize; /* computed framesize */ - - /* AF: ADDED FOR LAYER1/LAYER2 */ - int II_sblimit; - al_table2 []alloc; - int down_sample_sblimit; - int down_sample; - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Huffman.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Huffman.java deleted file mode 100644 index f8b6a75fc..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Huffman.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (C) 1999-2010 The L.A.M.E. project - * - * Initially written by Michael Hipp, see also AUTHORS and README. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * huffman tables ... recalcualted to work with my optimzed - * decoder scheme (MH) - * - * probably we could save a few bytes of memory, because the - * smaller tables are often the part of a bigger table - */ - -package mpg; - -public class Huffman { - - public static class newhuff { - public newhuff(int bits, short[] t) { - linbits = bits; - table = t; - } - - public final int linbits; - public final short[] table; - }; - - private static final short tab0[] = { 0 }; - - private static final short tab1[] = { -5, -3, -1, 17, 1, 16, 0 }; - - private static final short tab2[] = { -15, -11, -9, -5, -3, -1, 34, 2, 18, - -1, 33, 32, 17, -1, 1, 16, 0 }; - - private static final short tab3[] = { -13, -11, -9, -5, -3, -1, 34, 2, 18, - -1, 33, 32, 16, 17, -1, 1, 0 }; - - private static final short tab5[] = { -29, -25, -23, -15, -7, -5, -3, -1, - 51, 35, 50, 49, -3, -1, 19, 3, -1, 48, 34, -3, -1, 18, 33, -1, 2, - 32, 17, -1, 1, 16, 0 }; - - private static final short tab6[] = { -25, -19, -13, -9, -5, -3, -1, 51, 3, - 35, -1, 50, 48, -1, 19, 49, -3, -1, 34, 2, 18, -3, -1, 33, 32, 1, - -1, 17, -1, 16, 0 }; - - private static final short tab7[] = { -69, -65, -57, -39, -29, -17, -11, - -7, -3, -1, 85, 69, -1, 84, 83, -1, 53, 68, -3, -1, 37, 82, 21, -5, - -1, 81, -1, 5, 52, -1, 80, -1, 67, 51, -5, -3, -1, 36, 66, 20, -1, - 65, 64, -11, -7, -3, -1, 4, 35, -1, 50, 3, -1, 19, 49, -3, -1, 48, - 34, 18, -5, -1, 33, -1, 2, 32, 17, -1, 1, 16, 0 }; - - private static final short tab8[] = { -65, -63, -59, -45, -31, -19, -13, - -7, -5, -3, -1, 85, 84, 69, 83, -3, -1, 53, 68, 37, -3, -1, 82, 5, - 21, -5, -1, 81, -1, 52, 67, -3, -1, 80, 51, 36, -5, -3, -1, 66, 20, - 65, -3, -1, 4, 64, -1, 35, 50, -9, -7, -3, -1, 19, 49, -1, 3, 48, - 34, -1, 2, 32, -1, 18, 33, 17, -3, -1, 1, 16, 0 }; - - private static final short tab9[] = { -63, -53, -41, -29, -19, -11, -5, -3, - -1, 85, 69, 53, -1, 83, -1, 84, 5, -3, -1, 68, 37, -1, 82, 21, -3, - -1, 81, 52, -1, 67, -1, 80, 4, -7, -3, -1, 36, 66, -1, 51, 64, -1, - 20, 65, -5, -3, -1, 35, 50, 19, -1, 49, -1, 3, 48, -5, -3, -1, 34, - 2, 18, -1, 33, 32, -3, -1, 17, 1, -1, 16, 0 }; - - private static final short tab10[] = { -125, -121, -111, -83, -55, -35, - -21, -13, -7, -3, -1, 119, 103, -1, 118, 87, -3, -1, 117, 102, 71, - -3, -1, 116, 86, -1, 101, 55, -9, -3, -1, 115, 70, -3, -1, 85, 84, - 99, -1, 39, 114, -11, -5, -3, -1, 100, 7, 112, -1, 98, -1, 69, 53, - -5, -1, 6, -1, 83, 68, 23, -17, -5, -1, 113, -1, 54, 38, -5, -3, - -1, 37, 82, 21, -1, 81, -1, 52, 67, -3, -1, 22, 97, -1, 96, -1, 5, - 80, -19, -11, -7, -3, -1, 36, 66, -1, 51, 4, -1, 20, 65, -3, -1, - 64, 35, -1, 50, 3, -3, -1, 19, 49, -1, 48, 34, -7, -3, -1, 18, 33, - -1, 2, 32, 17, -1, 1, 16, 0 }; - - private static final short tab11[] = { -121, -113, -89, -59, -43, -27, -17, - -7, -3, -1, 119, 103, -1, 118, 117, -3, -1, 102, 71, -1, 116, -1, - 87, 85, -5, -3, -1, 86, 101, 55, -1, 115, 70, -9, -7, -3, -1, 69, - 84, -1, 53, 83, 39, -1, 114, -1, 100, 7, -5, -1, 113, -1, 23, 112, - -3, -1, 54, 99, -1, 96, -1, 68, 37, -13, -7, -5, -3, -1, 82, 5, 21, - 98, -3, -1, 38, 6, 22, -5, -1, 97, -1, 81, 52, -5, -1, 80, -1, 67, - 51, -1, 36, 66, -15, -11, -7, -3, -1, 20, 65, -1, 4, 64, -1, 35, - 50, -1, 19, 49, -5, -3, -1, 3, 48, 34, 33, -5, -1, 18, -1, 2, 32, - 17, -3, -1, 1, 16, 0 }; - - private static final short tab12[] = { -115, -99, -73, -45, -27, -17, -9, - -5, -3, -1, 119, 103, 118, -1, 87, 117, -3, -1, 102, 71, -1, 116, - 101, -3, -1, 86, 55, -3, -1, 115, 85, 39, -7, -3, -1, 114, 70, -1, - 100, 23, -5, -1, 113, -1, 7, 112, -1, 54, 99, -13, -9, -3, -1, 69, - 84, -1, 68, -1, 6, 5, -1, 38, 98, -5, -1, 97, -1, 22, 96, -3, -1, - 53, 83, -1, 37, 82, -17, -7, -3, -1, 21, 81, -1, 52, 67, -5, -3, - -1, 80, 4, 36, -1, 66, 20, -3, -1, 51, 65, -1, 35, 50, -11, -7, -5, - -3, -1, 64, 3, 48, 19, -1, 49, 34, -1, 18, 33, -7, -5, -3, -1, 2, - 32, 0, 17, -1, 1, 16 }; - - private static final short tab13[] = { -509, -503, -475, -405, -333, -265, - -205, -153, -115, -83, -53, -35, -21, -13, -9, -7, -5, -3, -1, 254, - 252, 253, 237, 255, -1, 239, 223, -3, -1, 238, 207, -1, 222, 191, - -9, -3, -1, 251, 206, -1, 220, -1, 175, 233, -1, 236, 221, -9, -5, - -3, -1, 250, 205, 190, -1, 235, 159, -3, -1, 249, 234, -1, 189, - 219, -17, -9, -3, -1, 143, 248, -1, 204, -1, 174, 158, -5, -1, 142, - -1, 127, 126, 247, -5, -1, 218, -1, 173, 188, -3, -1, 203, 246, - 111, -15, -7, -3, -1, 232, 95, -1, 157, 217, -3, -1, 245, 231, -1, - 172, 187, -9, -3, -1, 79, 244, -3, -1, 202, 230, 243, -1, 63, -1, - 141, 216, -21, -9, -3, -1, 47, 242, -3, -1, 110, 156, 15, -5, -3, - -1, 201, 94, 171, -3, -1, 125, 215, 78, -11, -5, -3, -1, 200, 214, - 62, -1, 185, -1, 155, 170, -1, 31, 241, -23, -13, -5, -1, 240, -1, - 186, 229, -3, -1, 228, 140, -1, 109, 227, -5, -1, 226, -1, 46, 14, - -1, 30, 225, -15, -7, -3, -1, 224, 93, -1, 213, 124, -3, -1, 199, - 77, -1, 139, 184, -7, -3, -1, 212, 154, -1, 169, 108, -1, 198, 61, - -37, -21, -9, -5, -3, -1, 211, 123, 45, -1, 210, 29, -5, -1, 183, - -1, 92, 197, -3, -1, 153, 122, 195, -7, -5, -3, -1, 167, 151, 75, - 209, -3, -1, 13, 208, -1, 138, 168, -11, -7, -3, -1, 76, 196, -1, - 107, 182, -1, 60, 44, -3, -1, 194, 91, -3, -1, 181, 137, 28, -43, - -23, -11, -5, -1, 193, -1, 152, 12, -1, 192, -1, 180, 106, -5, -3, - -1, 166, 121, 59, -1, 179, -1, 136, 90, -11, -5, -1, 43, -1, 165, - 105, -1, 164, -1, 120, 135, -5, -1, 148, -1, 119, 118, 178, -11, - -3, -1, 27, 177, -3, -1, 11, 176, -1, 150, 74, -7, -3, -1, 58, 163, - -1, 89, 149, -1, 42, 162, -47, -23, -9, -3, -1, 26, 161, -3, -1, - 10, 104, 160, -5, -3, -1, 134, 73, 147, -3, -1, 57, 88, -1, 133, - 103, -9, -3, -1, 41, 146, -3, -1, 87, 117, 56, -5, -1, 131, -1, - 102, 71, -3, -1, 116, 86, -1, 101, 115, -11, -3, -1, 25, 145, -3, - -1, 9, 144, -1, 72, 132, -7, -5, -1, 114, -1, 70, 100, 40, -1, 130, - 24, -41, -27, -11, -5, -3, -1, 55, 39, 23, -1, 113, -1, 85, 7, -7, - -3, -1, 112, 54, -1, 99, 69, -3, -1, 84, 38, -1, 98, 53, -5, -1, - 129, -1, 8, 128, -3, -1, 22, 97, -1, 6, 96, -13, -9, -5, -3, -1, - 83, 68, 37, -1, 82, 5, -1, 21, 81, -7, -3, -1, 52, 67, -1, 80, 36, - -3, -1, 66, 51, 20, -19, -11, -5, -1, 65, -1, 4, 64, -3, -1, 35, - 50, 19, -3, -1, 49, 3, -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, - -1, 17, 1, 16, 0 }; - - private static final short tab15[] = { -495, -445, -355, -263, -183, -115, - -77, -43, -27, -13, -7, -3, -1, 255, 239, -1, 254, 223, -1, 238, - -1, 253, 207, -7, -3, -1, 252, 222, -1, 237, 191, -1, 251, -1, 206, - 236, -7, -3, -1, 221, 175, -1, 250, 190, -3, -1, 235, 205, -1, 220, - 159, -15, -7, -3, -1, 249, 234, -1, 189, 219, -3, -1, 143, 248, -1, - 204, 158, -7, -3, -1, 233, 127, -1, 247, 173, -3, -1, 218, 188, -1, - 111, -1, 174, 15, -19, -11, -3, -1, 203, 246, -3, -1, 142, 232, -1, - 95, 157, -3, -1, 245, 126, -1, 231, 172, -9, -3, -1, 202, 187, -3, - -1, 217, 141, 79, -3, -1, 244, 63, -1, 243, 216, -33, -17, -9, -3, - -1, 230, 47, -1, 242, -1, 110, 240, -3, -1, 31, 241, -1, 156, 201, - -7, -3, -1, 94, 171, -1, 186, 229, -3, -1, 125, 215, -1, 78, 228, - -15, -7, -3, -1, 140, 200, -1, 62, 109, -3, -1, 214, 227, -1, 155, - 185, -7, -3, -1, 46, 170, -1, 226, 30, -5, -1, 225, -1, 14, 224, - -1, 93, 213, -45, -25, -13, -7, -3, -1, 124, 199, -1, 77, 139, -1, - 212, -1, 184, 154, -7, -3, -1, 169, 108, -1, 198, 61, -1, 211, 210, - -9, -5, -3, -1, 45, 13, 29, -1, 123, 183, -5, -1, 209, -1, 92, 208, - -1, 197, 138, -17, -7, -3, -1, 168, 76, -1, 196, 107, -5, -1, 182, - -1, 153, 12, -1, 60, 195, -9, -3, -1, 122, 167, -1, 166, -1, 192, - 11, -1, 194, -1, 44, 91, -55, -29, -15, -7, -3, -1, 181, 28, -1, - 137, 152, -3, -1, 193, 75, -1, 180, 106, -5, -3, -1, 59, 121, 179, - -3, -1, 151, 136, -1, 43, 90, -11, -5, -1, 178, -1, 165, 27, -1, - 177, -1, 176, 105, -7, -3, -1, 150, 74, -1, 164, 120, -3, -1, 135, - 58, 163, -17, -7, -3, -1, 89, 149, -1, 42, 162, -3, -1, 26, 161, - -3, -1, 10, 160, 104, -7, -3, -1, 134, 73, -1, 148, 57, -5, -1, - 147, -1, 119, 9, -1, 88, 133, -53, -29, -13, -7, -3, -1, 41, 103, - -1, 118, 146, -1, 145, -1, 25, 144, -7, -3, -1, 72, 132, -1, 87, - 117, -3, -1, 56, 131, -1, 102, 71, -7, -3, -1, 40, 130, -1, 24, - 129, -7, -3, -1, 116, 8, -1, 128, 86, -3, -1, 101, 55, -1, 115, 70, - -17, -7, -3, -1, 39, 114, -1, 100, 23, -3, -1, 85, 113, -3, -1, 7, - 112, 54, -7, -3, -1, 99, 69, -1, 84, 38, -3, -1, 98, 22, -3, -1, 6, - 96, 53, -33, -19, -9, -5, -1, 97, -1, 83, 68, -1, 37, 82, -3, -1, - 21, 81, -3, -1, 5, 80, 52, -7, -3, -1, 67, 36, -1, 66, 51, -1, 65, - -1, 20, 4, -9, -3, -1, 35, 50, -3, -1, 64, 3, 19, -3, -1, 49, 48, - 34, -9, -7, -3, -1, 18, 33, -1, 2, 32, 17, -3, -1, 1, 16, 0 }; - - private static final short tab16[] = { -509, -503, -461, -323, -103, -37, - -27, -15, -7, -3, -1, 239, 254, -1, 223, 253, -3, -1, 207, 252, -1, - 191, 251, -5, -1, 175, -1, 250, 159, -3, -1, 249, 248, 143, -7, -3, - -1, 127, 247, -1, 111, 246, 255, -9, -5, -3, -1, 95, 245, 79, -1, - 244, 243, -53, -1, 240, -1, 63, -29, -19, -13, -7, -5, -1, 206, -1, - 236, 221, 222, -1, 233, -1, 234, 217, -1, 238, -1, 237, 235, -3, - -1, 190, 205, -3, -1, 220, 219, 174, -11, -5, -1, 204, -1, 173, - 218, -3, -1, 126, 172, 202, -5, -3, -1, 201, 125, 94, 189, 242, - -93, -5, -3, -1, 47, 15, 31, -1, 241, -49, -25, -13, -5, -1, 158, - -1, 188, 203, -3, -1, 142, 232, -1, 157, 231, -7, -3, -1, 187, 141, - -1, 216, 110, -1, 230, 156, -13, -7, -3, -1, 171, 186, -1, 229, - 215, -1, 78, -1, 228, 140, -3, -1, 200, 62, -1, 109, -1, 214, 155, - -19, -11, -5, -3, -1, 185, 170, 225, -1, 212, -1, 184, 169, -5, -1, - 123, -1, 183, 208, 227, -7, -3, -1, 14, 224, -1, 93, 213, -3, -1, - 124, 199, -1, 77, 139, -75, -45, -27, -13, -7, -3, -1, 154, 108, - -1, 198, 61, -3, -1, 92, 197, 13, -7, -3, -1, 138, 168, -1, 153, - 76, -3, -1, 182, 122, 60, -11, -5, -3, -1, 91, 137, 28, -1, 192, - -1, 152, 121, -1, 226, -1, 46, 30, -15, -7, -3, -1, 211, 45, -1, - 210, 209, -5, -1, 59, -1, 151, 136, 29, -7, -3, -1, 196, 107, -1, - 195, 167, -1, 44, -1, 194, 181, -23, -13, -7, -3, -1, 193, 12, -1, - 75, 180, -3, -1, 106, 166, 179, -5, -3, -1, 90, 165, 43, -1, 178, - 27, -13, -5, -1, 177, -1, 11, 176, -3, -1, 105, 150, -1, 74, 164, - -5, -3, -1, 120, 135, 163, -3, -1, 58, 89, 42, -97, -57, -33, -19, - -11, -5, -3, -1, 149, 104, 161, -3, -1, 134, 119, 148, -5, -3, -1, - 73, 87, 103, 162, -5, -1, 26, -1, 10, 160, -3, -1, 57, 147, -1, 88, - 133, -9, -3, -1, 41, 146, -3, -1, 118, 9, 25, -5, -1, 145, -1, 144, - 72, -3, -1, 132, 117, -1, 56, 131, -21, -11, -5, -3, -1, 102, 40, - 130, -3, -1, 71, 116, 24, -3, -1, 129, 128, -3, -1, 8, 86, 55, -9, - -5, -1, 115, -1, 101, 70, -1, 39, 114, -5, -3, -1, 100, 85, 7, 23, - -23, -13, -5, -1, 113, -1, 112, 54, -3, -1, 99, 69, -1, 84, 38, -3, - -1, 98, 22, -1, 97, -1, 6, 96, -9, -5, -1, 83, -1, 53, 68, -1, 37, - 82, -1, 81, -1, 21, 5, -33, -23, -13, -7, -3, -1, 52, 67, -1, 80, - 36, -3, -1, 66, 51, 20, -5, -1, 65, -1, 4, 64, -1, 35, 50, -3, -1, - 19, 49, -3, -1, 3, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, - 1, 16, 0 }; - - private static final short tab24[] = { -451, -117, -43, -25, -15, -7, -3, - -1, 239, 254, -1, 223, 253, -3, -1, 207, 252, -1, 191, 251, -5, -1, - 250, -1, 175, 159, -1, 249, 248, -9, -5, -3, -1, 143, 127, 247, -1, - 111, 246, -3, -1, 95, 245, -1, 79, 244, -71, -7, -3, -1, 63, 243, - -1, 47, 242, -5, -1, 241, -1, 31, 240, -25, -9, -1, 15, -3, -1, - 238, 222, -1, 237, 206, -7, -3, -1, 236, 221, -1, 190, 235, -3, -1, - 205, 220, -1, 174, 234, -15, -7, -3, -1, 189, 219, -1, 204, 158, - -3, -1, 233, 173, -1, 218, 188, -7, -3, -1, 203, 142, -1, 232, 157, - -3, -1, 217, 126, -1, 231, 172, 255, -235, -143, -77, -45, -25, - -15, -7, -3, -1, 202, 187, -1, 141, 216, -5, -3, -1, 14, 224, 13, - 230, -5, -3, -1, 110, 156, 201, -1, 94, 186, -9, -5, -1, 229, -1, - 171, 125, -1, 215, 228, -3, -1, 140, 200, -3, -1, 78, 46, 62, -15, - -7, -3, -1, 109, 214, -1, 227, 155, -3, -1, 185, 170, -1, 226, 30, - -7, -3, -1, 225, 93, -1, 213, 124, -3, -1, 199, 77, -1, 139, 184, - -31, -15, -7, -3, -1, 212, 154, -1, 169, 108, -3, -1, 198, 61, -1, - 211, 45, -7, -3, -1, 210, 29, -1, 123, 183, -3, -1, 209, 92, -1, - 197, 138, -17, -7, -3, -1, 168, 153, -1, 76, 196, -3, -1, 107, 182, - -3, -1, 208, 12, 60, -7, -3, -1, 195, 122, -1, 167, 44, -3, -1, - 194, 91, -1, 181, 28, -57, -35, -19, -7, -3, -1, 137, 152, -1, 193, - 75, -5, -3, -1, 192, 11, 59, -3, -1, 176, 10, 26, -5, -1, 180, -1, - 106, 166, -3, -1, 121, 151, -3, -1, 160, 9, 144, -9, -3, -1, 179, - 136, -3, -1, 43, 90, 178, -7, -3, -1, 165, 27, -1, 177, 105, -1, - 150, 164, -17, -9, -5, -3, -1, 74, 120, 135, -1, 58, 163, -3, -1, - 89, 149, -1, 42, 162, -7, -3, -1, 161, 104, -1, 134, 119, -3, -1, - 73, 148, -1, 57, 147, -63, -31, -15, -7, -3, -1, 88, 133, -1, 41, - 103, -3, -1, 118, 146, -1, 25, 145, -7, -3, -1, 72, 132, -1, 87, - 117, -3, -1, 56, 131, -1, 102, 40, -17, -7, -3, -1, 130, 24, -1, - 71, 116, -5, -1, 129, -1, 8, 128, -1, 86, 101, -7, -5, -1, 23, -1, - 7, 112, 115, -3, -1, 55, 39, 114, -15, -7, -3, -1, 70, 100, -1, 85, - 113, -3, -1, 54, 99, -1, 69, 84, -7, -3, -1, 38, 98, -1, 22, 97, - -5, -3, -1, 6, 96, 53, -1, 83, 68, -51, -37, -23, -15, -9, -3, -1, - 37, 82, -1, 21, -1, 5, 80, -1, 81, -1, 52, 67, -3, -1, 36, 66, -1, - 51, 20, -9, -5, -1, 65, -1, 4, 64, -1, 35, 50, -1, 19, 49, -7, -5, - -3, -1, 3, 48, 34, 18, -1, 33, -1, 2, 32, -3, -1, 17, 1, -1, 16, 0 }; - - private static final short tab_c0[] = { -29, -21, -13, -7, -3, -1, 11, 15, - -1, 13, 14, -3, -1, 7, 5, 9, -3, -1, 6, 3, -1, 10, 12, -3, -1, 2, - 1, -1, 4, 8, 0 }; - - private static final short tab_c1[] = { -15, -7, -3, -1, 15, 14, -1, 13, - 12, -3, -1, 11, 10, -1, 9, 8, -7, -3, -1, 7, 6, -1, 5, 4, -3, -1, - 3, 2, -1, 1, 0 }; - - public static final newhuff ht[] = { new newhuff( /* 0 */0, tab0), - new newhuff( /* 2 */0, tab1), new newhuff( /* 3 */0, tab2), - new newhuff( /* 3 */0, tab3), new newhuff( /* 0 */0, tab0), - new newhuff( /* 4 */0, tab5), new newhuff( /* 4 */0, tab6), - new newhuff( /* 6 */0, tab7), new newhuff( /* 6 */0, tab8), - new newhuff( /* 6 */0, tab9), new newhuff( /* 8 */0, tab10), - new newhuff( /* 8 */0, tab11), new newhuff( /* 8 */0, tab12), - new newhuff( /* 16 */0, tab13), new newhuff( /* 0 */0, tab0), - new newhuff( /* 16 */0, tab15), - - new newhuff( /* 16 */1, tab16), new newhuff( /* 16 */2, tab16), - new newhuff( /* 16 */3, tab16), new newhuff( /* 16 */4, tab16), - new newhuff( /* 16 */6, tab16), new newhuff( /* 16 */8, tab16), - new newhuff( /* 16 */10, tab16), new newhuff( /* 16 */13, tab16), - new newhuff( /* 16 */4, tab24), new newhuff( /* 16 */5, tab24), - new newhuff( /* 16 */6, tab24), new newhuff( /* 16 */7, tab24), - new newhuff( /* 16 */8, tab24), new newhuff( /* 16 */9, tab24), - new newhuff( /* 16 */11, tab24), new newhuff( /* 16 */13, tab24) }; - - public static final newhuff htc[] = { - new newhuff( /* 1 , 1 , */0, tab_c0), - new newhuff( /* 1 , 1 , */0, tab_c1) }; -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Interface.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Interface.java deleted file mode 100644 index 85b95ca6d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Interface.java +++ /dev/null @@ -1,700 +0,0 @@ -/* - * interface.c - * - * Copyright (C) 1999-2010 The L.A.M.E. project - * - * Initially written by Michael Hipp, see also AUTHORS and README. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -/* $Id: Interface.java,v 1.12 2011/08/27 18:57:09 kenchis Exp $ */ - -package mpg; - -import mp3.VBRTag; -import mp3.VBRTagData; -import mpg.Decode.Factory; -import mpg.MPGLib.ProcessedBytes; -import mpg.MPGLib.buf; -import mpg.MPGLib.mpstr_tag; - -public class Interface { - - private VBRTag vbr; - private Common common; - - public void setModules(VBRTag v, Common c) { - vbr = v; - common = c; - layer1.setModules(common, decode); - layer2.setModules(common); - layer3.setModules(common); - decode.setModules(tab, dct); - dct.setModules(tab); - } - - protected Decode decode = new Decode(); - private Layer1 layer1 = new Layer1() ; - private Layer2 layer2 = new Layer2(); - private Layer3 layer3 = new Layer3(); - private DCT64 dct = new DCT64(); - private TabInit tab = new TabInit(); - - mpstr_tag - InitMP3() - { - mpstr_tag mp = new mpstr_tag(); - - mp.framesize = 0; - mp.num_frames = 0; - mp.enc_delay = -1; - mp.enc_padding = -1; - mp.vbr_header = false; - mp.header_parsed = false; - mp.side_parsed = false; - mp.data_parsed = false; - mp.free_format = false; - mp.old_free_format = false; - mp.ssize = 0; - mp.dsize = 0; - mp.fsizeold = -1; - mp.bsize = 0; - mp.head = mp.tail = null; - mp.fr.single = -1; - mp.bsnum = 0; - mp.wordpointer = mp.bsspace[mp.bsnum]; - mp.wordpointerPos = 512; - mp.bitindex = 0; - mp.synth_bo = 1; - mp.sync_bitstream = 1; - - tab.make_decode_tables(32767); - - layer3.init_layer3(MPG123.SBLIMIT); - - layer2.init_layer2(); - - return mp; - } - - void - ExitMP3(mpstr_tag mp) - { - buf b, bn; - - b = mp.tail; - while (b!=null) { - b.pnt=null; - bn = b.next; - b = bn; - } - } - - buf - addbuf(mpstr_tag mp, byte []buf, int bufPos, int size) - { - buf nbuf; - - nbuf = new buf(); - nbuf.pnt = new byte[size]; - nbuf.size = size; - System.arraycopy(buf, bufPos, nbuf.pnt, 0, size); - nbuf.next = null; - nbuf.prev = mp.head; - nbuf.pos = 0; - - if (null==mp.tail) { - mp.tail = nbuf; - } - else { - mp.head.next = nbuf; - } - - mp.head = nbuf; - mp.bsize += size; - - return nbuf; - } - - void - remove_buf(mpstr_tag mp) - { - buf buf = mp.tail; - - mp.tail = buf.next; - if (mp.tail!=null) - mp.tail.prev = null; - else { - mp.tail = mp.head = null; - } - - buf.pnt=null; - buf=null; - - } - - int - read_buf_byte(mpstr_tag mp) - { - int b; - - int pos; - - - pos = mp.tail.pos; - while (pos >= mp.tail.size) { - remove_buf(mp); - if (null==mp.tail) { - throw new RuntimeException("hip: Fatal error! tried to read past mp buffer"); - } - pos = mp.tail.pos; - } - - b = mp.tail.pnt[pos] & 0xff; - mp.bsize--; - mp.tail.pos++; - - - return b; - } - - void - read_head(mpstr_tag mp) - { - long head; - - head = read_buf_byte(mp); - head <<= 8; - head |= read_buf_byte(mp); - head <<= 8; - head |= read_buf_byte(mp); - head <<= 8; - head |= read_buf_byte(mp); - - mp.header = head; - } - - void - copy_mp(mpstr_tag mp, int size, byte[]ptr, int ptrPos) - { - int len = 0; - - while (len < size && mp.tail!=null) { - int nlen; - int blen = mp.tail.size - mp.tail.pos; - if ((size - len) <= blen) { - nlen = size - len; - } - else { - nlen = blen; - } - System.arraycopy(mp.tail.pnt, mp.tail.pos, ptr, ptrPos+len, nlen); - len += nlen; - mp.tail.pos += nlen; - mp.bsize -= nlen; - if (mp.tail.pos == mp.tail.size) { - remove_buf(mp); - } - } - } - - /* number of bytes needed by GetVbrTag to parse header */ - public static final int XING_HEADER_SIZE =194; - - /* - traverse mp data structure without changing it - (just like sync_buffer) - pull out Xing bytes - call vbr header check code from LAME - if we find a header, parse it and also compute the VBR header size - if no header, do nothing. - - bytes = number of bytes before MPEG header. skip this many bytes - before starting to read - return value: number of bytes in VBR header, including syncword - */ - int - check_vbr_header(mpstr_tag mp, int bytes) - { - int i, pos; - buf buf = mp.tail; - byte xing[]=new byte[XING_HEADER_SIZE]; - - pos = buf.pos; - /* skip to valid header */ - for (i = 0; i < bytes; ++i) { - while (pos >= buf.size) { - buf = buf.next; - if (null==buf) - return -1; /* fatal error */ - pos = buf.pos; - } - ++pos; - } - /* now read header */ - for (i = 0; i < XING_HEADER_SIZE; ++i) { - while (pos >= buf.size) { - buf = buf.next; - if (null==buf) - return -1; /* fatal error */ - pos = buf.pos; - } - xing[i] = buf.pnt[pos]; - ++pos; - } - - /* check first bytes for Xing header */ - VBRTagData pTagData = vbr.getVbrTag(xing); - mp.vbr_header = pTagData != null; - if (mp.vbr_header) { - mp.num_frames = pTagData.frames; - mp.enc_delay = pTagData.encDelay; - mp.enc_padding = pTagData.encPadding; - - /* fprintf(stderr,"hip: delays: %i %i \n",mp.enc_delay,mp.enc_padding); */ - /* fprintf(stderr,"hip: Xing VBR header dectected. MP3 file has %i frames\n", pTagData.frames); */ - if (pTagData.headersize < 1) - return 1; - return pTagData.headersize; - } - return 0; - } - - int - sync_buffer(mpstr_tag mp, boolean free_match) - { - /* traverse mp structure without modifying pointers, looking - * for a frame valid header. - * if free_format, valid header must also have the same - * samplerate. - * return number of bytes in mp, before the header - * return -1 if header is not found - */ - int b[] = { 0, 0, 0, 0 }; - int i, pos; - boolean h; - buf buf = mp.tail; - if (null==buf) - return -1; - - pos = buf.pos; - for (i = 0; i < mp.bsize; i++) { - /* get 4 bytes */ - - b[0] = b[1]; - b[1] = b[2]; - b[2] = b[3]; - while (pos >= buf.size) { - buf = buf.next; - pos = buf.pos; - } - b[3] = buf.pnt[pos] & 0xff; - ++pos; - - if (i >= 3) { - Frame fr = mp.fr; - long head; - - head = b[0]; - head <<= 8; - head |= b[1]; - head <<= 8; - head |= b[2]; - head <<= 8; - head |= b[3]; - h = common.head_check(head, fr.lay); - - if (h && free_match) { - /* just to be even more thorough, match the sample rate */ - int mode, stereo, sampling_frequency, lsf; - boolean mpeg25; - - if ((head & (1 << 20))!=0) { - lsf = (head & (1 << 19)) !=0 ? 0x0 : 0x1; - mpeg25 = false; - } - else { - lsf = 1; - mpeg25 = true; - } - - mode = (int) ((head >> 6) & 0x3); - stereo = (mode == MPG123.MPG_MD_MONO) ? 1 : 2; - - if (mpeg25) - sampling_frequency = (int) (6 + ((head >> 10) & 0x3)); - else - sampling_frequency = (int) (((head >> 10) & 0x3) + (lsf * 3)); - h = ((stereo == fr.stereo) && (lsf == fr.lsf) && (mpeg25 == fr.mpeg25) && - (sampling_frequency == fr.sampling_frequency)); - } - - if (h) { - return i - 3; - } - } - } - return -1; - } - - mpstr_tag - decode_reset() - { - return InitMP3(); /* Less error prone to just to reinitialise. */ - } - - int - audiodata_precedesframes(mpstr_tag mp) - { - if (mp.fr.lay == 3) - return layer3.layer3_audiodata_precedesframes(mp); - else - return 0; /* For Layer 1 & 2 the audio data starts at the frame that describes it, so no audio data precedes. */ - } - - interface ISynth { - <T>int synth_1to1_mono_ptr (mpstr_tag mp, float[] in, int inPos, T[] out, ProcessedBytes p, Factory<T> tFactory); - <T>int synth_1to1_ptr (mpstr_tag mp, float[] in, int inPos, int i, T[] out, ProcessedBytes p, Factory<T> tFactory); - } - - <T>int - decodeMP3_clipchoice(mpstr_tag mp, byte[] in, int inPos, int isize, T[] out, ProcessedBytes done, - ISynth synth, Factory<T> tFactory) - { - int i, iret, bits, bytes; - - if (in!=null && isize!=0 && addbuf(mp, in, inPos, isize) == null) - return MPGLib.MP3_ERR; - - /* First decode header */ - if (!mp.header_parsed) { - - if (mp.fsizeold == -1 || mp.sync_bitstream!=0) { - int vbrbytes; - mp.sync_bitstream = 0; - - /* This is the very first call. sync with anything */ - /* bytes= number of bytes before header */ - bytes = sync_buffer(mp, false); - - /* now look for Xing VBR header */ - if (mp.bsize >= bytes + XING_HEADER_SIZE) { - /* vbrbytes = number of bytes in entire vbr header */ - vbrbytes = check_vbr_header(mp, bytes); - } - else { - /* not enough data to look for Xing header */ -// #ifdef HIP_DEBUG -// fprintf(stderr, "hip: not enough data to look for Xing header\n"); -// #endif - return MPGLib.MP3_NEED_MORE; - } - - if (mp.vbr_header) { - /* do we have enough data to parse entire Xing header? */ - if (bytes + vbrbytes > mp.bsize) { - /* fprintf(stderr,"hip: not enough data to parse entire Xing header\n"); */ - return MPGLib.MP3_NEED_MORE; - } - - /* read in Xing header. Buffer data in case it - * is used by a non zero main_data_begin for the next - * frame, but otherwise dont decode Xing header */ -// #ifdef HIP_DEBUG -// fprintf(stderr, "hip: found xing header, skipping %i bytes\n", vbrbytes + bytes); -// #endif - for (i = 0; i < vbrbytes + bytes; ++i) - read_buf_byte(mp); - /* now we need to find another syncword */ - /* just return and make user send in more data */ - - return MPGLib.MP3_NEED_MORE; - } - } - else { - /* match channels, samplerate, etc, when syncing */ - bytes = sync_buffer(mp, true); - } - - /* buffer now synchronized */ - if (bytes < 0) { - /* fprintf(stderr,"hip: need more bytes %d\n", bytes); */ - return MPGLib.MP3_NEED_MORE; - } - if (bytes > 0) { - /* there were some extra bytes in front of header. - * bitstream problem, but we are now resynced - * should try to buffer previous data in case new - * frame has nonzero main_data_begin, but we need - * to make sure we do not overflow buffer - */ - int size; - System.err.printf("hip: bitstream problem, resyncing skipping %d bytes...\n", bytes); - mp.old_free_format = false; - - /* FIXME: correct ??? */ - mp.sync_bitstream = 1; - - /* skip some bytes, buffer the rest */ - size = mp.wordpointerPos - 512; - - if (size > MPG123.MAXFRAMESIZE) { - /* wordpointer buffer is trashed. probably cant recover, but try anyway */ - System.err.printf("hip: wordpointer trashed. size=%i (%i) bytes=%i \n", - size, MPG123.MAXFRAMESIZE, bytes); - size = 0; - mp.wordpointer = mp.bsspace[mp.bsnum]; - mp.wordpointerPos = 512; - } - - /* buffer contains 'size' data right now - we want to add 'bytes' worth of data, but do not - exceed MAXFRAMESIZE, so we through away 'i' bytes */ - i = (size + bytes) - MPG123.MAXFRAMESIZE; - for (; i > 0; --i) { - --bytes; - read_buf_byte(mp); - } - - copy_mp(mp, bytes, mp.wordpointer, mp.wordpointerPos); - mp.fsizeold += bytes; - } - - read_head(mp); - common.decode_header(mp.fr, mp.header); - mp.header_parsed = true; - mp.framesize = mp.fr.framesize; - mp.free_format = (mp.framesize == 0); - - if (mp.fr.lsf!=0) - mp.ssize = (mp.fr.stereo == 1) ? 9 : 17; - else - mp.ssize = (mp.fr.stereo == 1) ? 17 : 32; - if (mp.fr.error_protection) - mp.ssize += 2; - - mp.bsnum = 1 - mp.bsnum; /* toggle buffer */ - mp.wordpointer = mp.bsspace[mp.bsnum]; - mp.wordpointerPos = 512; - mp.bitindex = 0; - - /* for very first header, never parse rest of data */ - if (mp.fsizeold == -1) { -// #ifdef HIP_DEBUG -// fprintf(stderr, "hip: not parsing the rest of the data of the first header\n"); -// #endif - return MPGLib.MP3_NEED_MORE; - } - } /* end of header parsing block */ - - /* now decode side information */ - if (!mp.side_parsed) { - - /* Layer 3 only */ - if (mp.fr.lay == 3) { - if (mp.bsize < mp.ssize) - return MPGLib.MP3_NEED_MORE; - - copy_mp(mp, mp.ssize, mp.wordpointer, mp.wordpointerPos); - - if (mp.fr.error_protection) - common.getbits(mp, 16); - bits = layer3.do_layer3_sideinfo(mp); - /* bits = actual number of bits needed to parse this frame */ - /* can be negative, if all bits needed are in the reservoir */ - if (bits < 0) - bits = 0; - - /* read just as many bytes as necessary before decoding */ - mp.dsize = (bits + 7) / 8; - -// #ifdef HIP_DEBUG -// fprintf(stderr, -// "hip: %d bits needed to parse layer III frame, number of bytes to read before decoding dsize = %d\n", -// bits, mp.dsize); -// #endif - - /* this will force mpglib to read entire frame before decoding */ - /* mp.dsize= mp.framesize - mp.ssize; */ - - } - else { - /* Layers 1 and 2 */ - - /* check if there is enough input data */ - if (mp.fr.framesize > mp.bsize) - return MPGLib.MP3_NEED_MORE; - - /* takes care that the right amount of data is copied into wordpointer */ - mp.dsize = mp.fr.framesize; - mp.ssize = 0; - } - - mp.side_parsed = true; - } - - /* now decode main data */ - iret = MPGLib.MP3_NEED_MORE; - if (!mp.data_parsed) { - if (mp.dsize > mp.bsize) { - return MPGLib.MP3_NEED_MORE; - } - - copy_mp(mp, mp.dsize, mp.wordpointer, mp.wordpointerPos); - - done.pb = 0; - - /*do_layer3(&mp.fr,(unsigned char *) out,done); */ - switch (mp.fr.lay) { - case 1: - if (mp.fr.error_protection) - common.getbits(mp, 16); - - layer1.do_layer1(mp, out, done, tFactory); - break; - - case 2: - if (mp.fr.error_protection) - common.getbits(mp, 16); - - layer2.do_layer2(mp, out, done, synth, tFactory); - break; - - case 3: - layer3.do_layer3(mp, out, done, synth, tFactory); - break; - default: - System.err.printf("hip: invalid layer %d\n", mp.fr.lay); - } - - mp.wordpointer = mp.bsspace[mp.bsnum]; - mp.wordpointerPos = 512 + mp.ssize + mp.dsize; - - mp.data_parsed = true; - iret = MPGLib.MP3_OK; - } - - - /* remaining bits are ancillary data, or reservoir for next frame - * If free format, scan stream looking for next frame to determine - * mp.framesize */ - if (mp.free_format) { - if (mp.old_free_format) { - /* free format. bitrate must not vary */ - mp.framesize = mp.fsizeold_nopadding + (mp.fr.padding); - } - else { - bytes = sync_buffer(mp, true); - if (bytes < 0) - return iret; - mp.framesize = bytes + mp.ssize + mp.dsize; - mp.fsizeold_nopadding = mp.framesize - mp.fr.padding; - /* - fprintf(stderr,"hip: freeformat bitstream: estimated bitrate=%ikbs \n", - 8*(4+mp.framesize)*freqs[mp.fr.sampling_frequency]/ - (1000*576*(2-mp.fr.lsf))); - */ - } - } - - /* buffer the ancillary data and reservoir for next frame */ - bytes = mp.framesize - (mp.ssize + mp.dsize); - if (bytes > mp.bsize) { - return iret; - } - - if (bytes > 0) { - int size; - copy_mp(mp, bytes, mp.wordpointer, mp.wordpointerPos); - mp.wordpointerPos += bytes; - - size = mp.wordpointerPos - 512; - if (size > MPG123.MAXFRAMESIZE) { - System.err.printf("hip: fatal error. MAXFRAMESIZE not large enough.\n"); - } - - } - - /* the above frame is completely parsed. start looking for next frame */ - mp.fsizeold = mp.framesize; - mp.old_free_format = mp.free_format; - mp.framesize = 0; - mp.header_parsed = false; - mp.side_parsed = false; - mp.data_parsed = false; - - return iret; - } - - <T>int - decodeMP3(MPGLib.mpstr_tag mp, byte []in, int bufferPos, int isize, T []out, int osize, ProcessedBytes done, Factory<T> tFactory) - { - if (osize < 2304) { - System.err.printf("hip: Insufficient memory for decoding buffer %d\n", osize); - return MPGLib.MP3_ERR; - } - - /* passing pointers to the functions which clip the samples */ - ISynth synth = new ISynth() { - - @Override - public <X> int synth_1to1_mono_ptr(mpstr_tag mp, float[] in, - int inPos, X[] out, ProcessedBytes p, - Factory<X> tFactory) { - return decode.synth_1to1_mono(mp, in, inPos, out, p, tFactory); - } - - @Override - public <X> int synth_1to1_ptr(mpstr_tag mp, float[] in, int inPos, - int i, X[] out, ProcessedBytes p, - Factory<X> tFactory) { - return decode.synth_1to1(mp, in, inPos, i, out, p, tFactory); - } - - }; - return decodeMP3_clipchoice(mp, in, bufferPos, isize, out, done, synth, tFactory); - } - - <T>int - decodeMP3_unclipped(MPGLib.mpstr_tag mp, byte []in, int bufferPos, int isize, T []out, int osize, ProcessedBytes done, Factory<T> tFactory) - { - /* we forbid input with more than 1152 samples per channel for output in unclipped mode */ - if (osize < 1152 * 2) { - System.err.printf("hip: out space too small for unclipped mode\n"); - return MPGLib.MP3_ERR; - } - - ISynth synth = new ISynth() { - - @Override - public <X>int synth_1to1_mono_ptr(mpstr_tag mp, float[] in, - int inPos, X[] out, ProcessedBytes p, - Factory<X> tFactory) { - return decode.synth_1to1_mono_unclipped(mp, in, inPos, out, p, tFactory); - } - - @Override - public <X>int synth_1to1_ptr(mpstr_tag mp, float[] in, int inPos, - int i, X[] out, ProcessedBytes p, - Factory<X> tFactory) { - return decode.synth_1to1_unclipped(mp, in, inPos, i, out, p, tFactory); - } - - }; - /* passing pointers to the functions which don't clip the samples */ - return decodeMP3_clipchoice(mp, in, bufferPos, isize, out, done, synth, tFactory); - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/L2Tables.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/L2Tables.java deleted file mode 100644 index d04099b8d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/L2Tables.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 1999-2010 The L.A.M.E. project - * - * Initially written by Michael Hipp, see also AUTHORS and README. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Layer 2 Alloc tables .. - * most other tables are calculated on program start (which is (of course) - * not ISO-conform) .. - * Layer-3 huffman table is in huffman.h - */ -package mpg; - - -public class L2Tables { - - public static final class al_table2 { - public al_table2(final int b, final int d) { - this.bits = (short) b; - this.d = (short) d; - } - - short bits; - short d; - }; - - public static final al_table2 alloc_0[] = { - new al_table2(4, 0), new al_table2(5, 3), new al_table2(3, -3), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), new al_table2(9, -255), new al_table2(10, - -511), - new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(14, -8191), new al_table2(15, -16383), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(3, -3), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), new al_table2(9, -255), new al_table2(10, - -511), - new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(14, -8191), new al_table2(15, -16383), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(3, -3), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), new al_table2(9, -255), new al_table2(10, - -511), - new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(14, -8191), new al_table2(15, -16383), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(16, -32767), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(16, -32767), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(16, -32767), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(16, -32767) - }; - - public static final al_table2 alloc_1[] = { - new al_table2(4, 0), new al_table2(5, 3), new al_table2(3, -3), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), new al_table2(9, -255), new al_table2(10, - -511), - new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(14, -8191), new al_table2(15, -16383), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(3, -3), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), new al_table2(9, -255), new al_table2(10, - -511), - new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(14, -8191), new al_table2(15, -16383), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(3, -3), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), new al_table2(9, -255), new al_table2(10, - -511), - new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(14, -8191), new al_table2(15, -16383), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(16, -32767), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(16, -32767), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(16, -32767), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(16, -32767), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(16, -32767), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(16, -32767), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(16, -32767), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(16, -32767), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(16, -32767) - }; - - public static final al_table2 alloc_2[] = { - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), new al_table2(9, -255), - new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(14, -8191), new al_table2(15, -16383), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), new al_table2(9, -255), - new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(14, -8191), new al_table2(15, -16383), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63) - }; - - public static final al_table2 alloc_3[] = { - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), new al_table2(9, -255), - new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(14, -8191), new al_table2(15, -16383), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), new al_table2(9, -255), - new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(14, -8191), new al_table2(15, -16383), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63) - }; - - public static final al_table2 alloc_4[] = { - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(14, -8191), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(14, -8191), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(14, -8191), - new al_table2(4, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(3, -3), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), new al_table2(8, -127), - new al_table2(9, -255), new al_table2(10, -511), new al_table2(11, -1023), new al_table2(12, -2047), new al_table2(13, -4095), new al_table2(14, -8191), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(3, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), new al_table2(4, -7), new al_table2(5, -15), new al_table2(6, -31), new al_table2(7, -63), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9), - new al_table2(2, 0), new al_table2(5, 3), new al_table2(7, 5), new al_table2(10, 9) - }; -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Layer1.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Layer1.java deleted file mode 100644 index 6d2e13e02..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Layer1.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * layer1.c: Mpeg Layer-1 audio decoder - * - * Copyright (C) 1999-2010 The L.A.M.E. project - * - * Initially written by Michael Hipp, see also AUTHORS and README. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* $Id: Layer1.java,v 1.5 2011/05/31 19:42:01 kenchis Exp $ */ - -package mpg; - -import mpg.Decode.Factory; -import mpg.MPGLib.ProcessedBytes; -import mpg.MPGLib.mpstr_tag; - -public class Layer1 { - private Common common; - private Decode decode; - - public void setModules(Common c, Decode d) { - common = c; - decode = d; - } - - private void I_step_one(final mpstr_tag mp, final int balloc[], - final int scale_index[], final Frame fr) { - int ba = 0; - int sca = 0; - - assert(fr.stereo == 1 || fr.stereo == 2); - if (fr.stereo == 2) { - int i; - int jsbound = fr.jsbound; - for (i = 0; i < jsbound; i++) { - balloc[ba++] = common.getbits(mp, 4); - balloc[ba++] = common.getbits(mp, 4); - } - for (i = jsbound; i < MPG123.SBLIMIT; i++) - balloc[ba++] = common.getbits(mp, 4); - - ba = 0; - - for (i = 0; i < jsbound; i++) { - if ((balloc[ba]++)!=0) - scale_index[sca++] = common.getbits(mp, 6); - if ((balloc[ba++])!=0) - scale_index[sca++] = common.getbits(mp, 6); - } - for (i = jsbound; i < MPG123.SBLIMIT; i++) - if ((balloc[ba++])!=0) { - scale_index[sca++] = common.getbits(mp, 6); - scale_index[sca++] = common.getbits(mp, 6); - } - } - else { - int i; - for (i = 0; i < MPG123.SBLIMIT; i++) - balloc[ba++] = common.getbits(mp, 4); - ba = 0; - for (i = 0; i < MPG123.SBLIMIT; i++) - if ((balloc[ba++])!=0) - scale_index[sca++] = common.getbits(mp, 6); - } - } - - private void I_step_two(final mpstr_tag mp, final float fraction[][], - final int balloc[], final int scale_index[], final Frame fr) { - int i, n; - int smpb[]=new int[2 * MPG123.SBLIMIT]; /* values: 0-65535 */ - int sample; - int ba = 0; - int sca = 0; - - assert(fr.stereo == 1 || fr.stereo == 2); - if (fr.stereo == 2) { - int jsbound = fr.jsbound; - int f0 = 0; - int f1 = 0; - ba = 0; - for (sample = 0, i = 0; i < jsbound; i++) { - n = balloc[ba++]; - if (n!=0) - smpb[sample++] = common.getbits(mp, n + 1); - n = balloc[ba++]; - if (n!=0) - smpb[sample++] = common.getbits(mp, n + 1); - } - for (i = jsbound; i < MPG123.SBLIMIT; i++) { - n = balloc[ba++]; - if (n!=0) - smpb[sample++] = common.getbits(mp, n + 1); - } - ba = 0; - for (sample = 0, i = 0; i < jsbound; i++) { - n = balloc[ba++]; - if (n!=0) - fraction[0][f0++] = (float) (((-1) << n) + (smpb[sample++]) + 1) * common.muls[n + 1][scale_index[sca++]]; - else - fraction[0][f0++] = 0.0f; - n = balloc[ba++]; - if (n!=0) - fraction[1][f1++] = (float) (((-1) << n) + (smpb[sample++]) + 1) * common.muls[n + 1][scale_index[sca++]]; - else - fraction[1][f1++] = 0.0f; - } - for (i = jsbound; i < MPG123.SBLIMIT; i++) { - n = balloc[ba++]; - if (n!=0) { - float samp = (float) (((-1) << n) + (smpb[sample++]) + 1); - fraction[0][f0++] = samp * common.muls[n + 1][scale_index[sca++]]; - fraction[1][f1++] = samp * common.muls[n + 1][scale_index[sca++]]; - } - else - fraction[0][f0++] = fraction[1][f1++] = 0.0f; - } - for (i = fr.down_sample_sblimit; i < 32; i++) - fraction[0][i] = fraction[1][i] = 0.0f; - } - else { - int f0 = 0; - ba = 0; - for (sample = 0, i = 0; i < MPG123.SBLIMIT; i++) { - n = balloc[ba++]; - if (n!=0) - smpb[sample++] = common.getbits(mp, n + 1); - } - ba = 0; - for (sample = 0, i = 0; i < MPG123.SBLIMIT; i++) { - n = balloc[ba++]; - if (n!=0) - fraction[0][f0++] = (float) (((-1) << n) + (smpb[sample++]) + 1) * common.muls[n + 1][scale_index[sca++]]; - else - fraction[0][f0++] = 0.0f; - } - for (i = fr.down_sample_sblimit; i < 32; i++) - fraction[0][i] = 0.0f; - } - } - - public <T> int do_layer1(final mpstr_tag mp, final T[] pcm_sample, - final ProcessedBytes pcm_point, final Factory<T> tFactory) { - int clip = 0; - int balloc[]=new int[2 * MPG123.SBLIMIT]; - int scale_index[]=new int[2 * MPG123.SBLIMIT]; - float fraction[][]=new float[2][MPG123.SBLIMIT]; - Frame fr = mp.fr; - int i, stereo = fr.stereo; - int single = fr.single; - - fr.jsbound = (fr.mode == MPG123.MPG_MD_JOINT_STEREO) ? (fr.mode_ext << 2) + 4 : 32; - - if (stereo == 1 || single == 3) - single = 0; - - I_step_one(mp, balloc, scale_index, fr); - - for (i = 0; i < MPG123.SCALE_BLOCK; i++) { - I_step_two(mp, fraction, balloc, scale_index, fr); - - if (single >= 0) { - clip += decode.synth_1to1_mono(mp, fraction[single], 0, pcm_sample, pcm_point, tFactory); - } - else { - ProcessedBytes p1 = new ProcessedBytes(); - p1.pb = pcm_point.pb; - clip += decode.synth_1to1(mp, fraction[0], 0, 0, pcm_sample, p1, tFactory); - clip += decode.synth_1to1(mp, fraction[1], 0, 1, pcm_sample, pcm_point, tFactory); - } - } - - return clip; - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Layer2.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Layer2.java deleted file mode 100644 index c7f49b969..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Layer2.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * layer2.c: Mpeg Layer-2 audio decoder - * - * Copyright (C) 1999-2010 The L.A.M.E. project - * - * Initially written by Michael Hipp, see also AUTHORS and README. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -/* $Id: Layer2.java,v 1.4 2011/05/31 19:42:01 kenchis Exp $ */ - -package mpg; - -import mpg.Decode.Factory; -import mpg.Interface.ISynth; -import mpg.MPGLib.ProcessedBytes; -import mpg.MPGLib.mpstr_tag; - -public class Layer2 { - - private Common common; - - public void setModules(final Common c) { - common = c; - } - - private final int grp_3tab[]=new int[32 * 3]; /* used: 27 */ - private final int grp_5tab[]=new int[128 * 3]; /* used: 125 */ - private final int grp_9tab[]=new int[1024 * 3]; /* used: 729 */ - - private static final double mulmul[] = { - 0.0, -2.0 / 3.0, 2.0 / 3.0, - 2.0 / 7.0, 2.0 / 15.0, 2.0 / 31.0, 2.0 / 63.0, 2.0 / 127.0, 2.0 / 255.0, - 2.0 / 511.0, 2.0 / 1023.0, 2.0 / 2047.0, 2.0 / 4095.0, 2.0 / 8191.0, - 2.0 / 16383.0, 2.0 / 32767.0, 2.0 / 65535.0, - -4.0 / 5.0, -2.0 / 5.0, 2.0 / 5.0, 4.0 / 5.0, - -8.0 / 9.0, -4.0 / 9.0, -2.0 / 9.0, 2.0 / 9.0, 4.0 / 9.0, 8.0 / 9.0 - }; - private final int base[][] = { - {1, 0, 2,}, - {17, 18, 0, 19, 20,}, - {21, 1, 22, 23, 0, 24, 25, 2, 26} - }; - - private final int tablen[] = { 3, 5, 9 }; - private final int tables[][] = { grp_3tab, grp_5tab, grp_9tab }; - private int itable; - - public void init_layer2() { - int i, j, k, l, len; - float[] table; - - for (i = 0; i < 3; i++) { - itable = 0; - len = tablen[i]; - for (j = 0; j < len; j++) - for (k = 0; k < len; k++) - for (l = 0; l < len; l++) { - tables[i][itable++] = base[i][l]; - tables[i][itable++] = base[i][k]; - tables[i][itable++] = base[i][j]; - } - } - - for (k = 0; k < 27; k++) { - double m = mulmul[k]; - table = common.muls[k]; - int tablePos = 0; - for (j = 3, i = 0; i < 63; i++, j--) - table[tablePos++] = (float) (m * Math.pow(2.0, (double) j / 3.0)); - table[tablePos++] = 0.0f; - } - } - - private int scfsi_buf[]=new int[64]; - - private void II_step_one(final mpstr_tag mp, final int[] bit_alloc, - final int[] scale, final Frame fr) { - int scalePos = 0; - int stereo = fr.stereo - 1; - int sblimit = fr.II_sblimit; - int jsbound = fr.jsbound; - int sblimit2 = fr.II_sblimit << stereo; - int alloc1 = 0; - int i; - int scfsi, bita; - int sc, step; - - bita = 0; - if (stereo!=0) { - for (i = jsbound; i!=0; i--, alloc1 += (1 << step)) { - bit_alloc[bita++] = (char) common.getbits(mp, step = fr.alloc[alloc1].bits); - bit_alloc[bita++] = (char) common.getbits(mp, step); - } - for (i = sblimit - jsbound; i!=0; i--, alloc1 += (1 << step)) { - bit_alloc[bita+0] = (char) common.getbits(mp, step = fr.alloc[alloc1].bits); - bit_alloc[bita+1] = bit_alloc[bita+0]; - bita += 2; - } - bita = 0; - scfsi = 0; - for (i = sblimit2; i!=0; i--) - if (bit_alloc[bita++]!=0) - scfsi_buf[scfsi++] = (char) common.getbits_fast(mp, 2); - } - else { /* mono */ - - for (i = sblimit; i!=0; i--, alloc1 += (1 << step)) - bit_alloc[bita++] = (char) common.getbits(mp, step = fr.alloc[alloc1].bits); - bita = 0; - scfsi = 0; - for (i = sblimit; i!=0; i--) - if (bit_alloc[bita++]!=0) - scfsi_buf[scfsi++] = (char) common.getbits_fast(mp, 2); - } - - bita = 0; - scfsi = 0; - for (i = sblimit2; i!=0; i--) - if (bit_alloc[bita++]!=0) - switch (scfsi_buf[scfsi++]) { - case 0: - scale[scalePos++] = common.getbits_fast(mp, 6); - scale[scalePos++] = common.getbits_fast(mp, 6); - scale[scalePos++] = common.getbits_fast(mp, 6); - break; - case 1: - scale[scalePos++] = sc = common.getbits_fast(mp, 6); - scale[scalePos++] = sc; - scale[scalePos++] = common.getbits_fast(mp, 6); - break; - case 2: - scale[scalePos++] = sc = common.getbits_fast(mp, 6); - scale[scalePos++] = sc; - scale[scalePos++] = sc; - break; - default: /* case 3 */ - scale[scalePos++] = common.getbits_fast(mp, 6); - scale[scalePos++] = sc = common.getbits_fast(mp, 6); - scale[scalePos++] = sc; - break; - } - - } - - private final int []table[] = { null, null, null, grp_3tab, null, grp_5tab, null, null, null, grp_9tab }; - - private void II_step_two(final mpstr_tag mp, final int[] bit_alloc, - final float fraction[][][], final int[] scale, final Frame fr, - final int x1) { - int scalePos = 0; - int i, j, k, ba; - int stereo = fr.stereo; - int sblimit = fr.II_sblimit; - int jsbound = fr.jsbound; - int alloc2, alloc1 = 0; - int bita = 0; - int d1, step; - - for (i = 0; i < jsbound; i++, alloc1 += (1 << step)) { - step = fr.alloc[alloc1].bits; - for (j = 0; j < stereo; j++) { - ba = bit_alloc[bita++]; - if (ba!=0) { - k = fr.alloc[(alloc2 = alloc1 + ba)].bits; - if ((d1 = fr.alloc[alloc2].d) < 0) { - float cm = common.muls[k][scale[scalePos+x1]]; - fraction[j][0][i] = ((float) ((int) common.getbits(mp, k) + d1)) * cm; - fraction[j][1][i] = ((float) ((int) common.getbits(mp, k) + d1)) * cm; - fraction[j][2][i] = ((float) ((int) common.getbits(mp, k) + d1)) * cm; - } - else { - int idx, tab, m = scale[scalePos+x1]; - idx = (int) common.getbits(mp, k); - tab = (idx + idx + idx); - fraction[j][0][i] = common.muls[table[d1][tab++]][m]; - fraction[j][1][i] = common.muls[table[d1][tab++]][m]; - fraction[j][2][i] = common.muls[table[d1][tab]][m]; - } - scalePos += 3; - } - else - fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0f; - } - } - - for (i = jsbound; i < sblimit; i++, alloc1 += (1 << step)) { - step = fr.alloc[alloc1].bits; - bita++; /* channel 1 and channel 2 bitalloc are the same */ - ba = bit_alloc[bita++]; - if (ba!=0) { - k = fr.alloc[(alloc2 = alloc1 + ba)].bits; - if ((d1 = fr.alloc[alloc2].d) < 0) { - float cm; - cm = common.muls[k][scale[scalePos+x1 + 3]]; - fraction[1][0][i] = (fraction[0][0][i] = (float) ((int) common.getbits(mp, k) + d1)) * cm; - fraction[1][1][i] = (fraction[0][1][i] = (float) ((int) common.getbits(mp, k) + d1)) * cm; - fraction[1][2][i] = (fraction[0][2][i] = (float) ((int) common.getbits(mp, k) + d1)) * cm; - cm = common.muls[k][scale[scalePos+x1]]; - fraction[0][0][i] *= cm; - fraction[0][1][i] *= cm; - fraction[0][2][i] *= cm; - } - else { - int idx, tab, m1, m2; - m1 = scale[scalePos+x1]; - m2 = scale[scalePos+x1 + 3]; - idx = (int) common.getbits(mp, k); - tab = (idx + idx + idx); - fraction[0][0][i] = common.muls[table[d1][tab]][m1]; - fraction[1][0][i] = common.muls[table[d1][tab++]][m2]; - fraction[0][1][i] = common.muls[table[d1][tab]][m1]; - fraction[1][1][i] = common.muls[table[d1][tab++]][m2]; - fraction[0][2][i] = common.muls[table[d1][tab]][m1]; - fraction[1][2][i] = common.muls[table[d1][tab]][m2]; - } - scalePos += 6; - } - else { - fraction[0][0][i] = fraction[0][1][i] = fraction[0][2][i] = - fraction[1][0][i] = fraction[1][1][i] = fraction[1][2][i] = 0.0f; - } - /* - should we use individual scalefac for channel 2 or - is the current way the right one , where we just copy channel 1 to - channel 2 ?? - The current 'strange' thing is, that we throw away the scalefac - values for the second channel ...!! - . changed .. now we use the scalefac values of channel one !! - */ - } - /* if(sblimit > (fr.down_sample_sblimit) ) */ - /* sblimit = fr.down_sample_sblimit; */ - - for (i = sblimit; i < MPG123.SBLIMIT; i++) - for (j = 0; j < stereo; j++) - fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0f; - - } - - private static final int translate[][][] = - { { { 0,2,2,2,2,2,2,0,0,0,1,1,1,1,1,0 } , - { 0,2,2,0,0,0,1,1,1,1,1,1,1,1,1,0 } } , - { { 0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0 } , - { 0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0 } } , - { { 0,3,3,3,3,3,3,0,0,0,1,1,1,1,1,0 } , - { 0,3,3,0,0,0,1,1,1,1,1,1,1,1,1,0 } } }; - - private final L2Tables.al_table2 []tables2[] = { L2Tables.alloc_0, L2Tables.alloc_1, L2Tables.alloc_2, L2Tables.alloc_3, L2Tables.alloc_4 }; - private final int sblims[] = { 27, 30, 8, 12, 30 }; - - private void II_select_table(final Frame fr) { - int table, sblim; - - if (fr.lsf!=0) - table = 4; - else - table = translate[fr.sampling_frequency][2 - fr.stereo][fr.bitrate_index]; - sblim = sblims[table]; - - fr.alloc = tables2[table]; - fr.II_sblimit = sblim; - } - - public <T> int do_layer2(final mpstr_tag mp, final T[] pcm_sample, - final ProcessedBytes pcm_point, final ISynth synth, - final Factory<T> tFactory) { - int clip = 0; - int i, j; - float fraction[][][]=new float[2][4][MPG123.SBLIMIT]; /* pick_table clears unused subbands */ - int bit_alloc[]=new int[64]; - int scale[]=new int[192]; - Frame fr = mp.fr; - int stereo = fr.stereo; - int single = fr.single; - - II_select_table(fr); - fr.jsbound = (fr.mode == MPG123.MPG_MD_JOINT_STEREO) ? (fr.mode_ext << 2) + 4 : fr.II_sblimit; - - if (stereo == 1 || single == 3) - single = 0; - - II_step_one(mp, bit_alloc, scale, fr); - - for (i = 0; i < MPG123.SCALE_BLOCK; i++) { - II_step_two(mp, bit_alloc, fraction, scale, fr, i >> 2); - for (j = 0; j < 3; j++) { - if (single >= 0) { - clip += synth.synth_1to1_mono_ptr(mp, fraction[single][j], 0, pcm_sample, pcm_point, tFactory); - } - else { - ProcessedBytes p1 = new ProcessedBytes(); - p1.pb = pcm_point.pb; - clip += synth.synth_1to1_ptr(mp, fraction[0][j], 0, 0, pcm_sample, p1, tFactory); - clip += synth.synth_1to1_ptr(mp, fraction[1][j], 0, 1, pcm_sample, pcm_point, tFactory); - } - } - } - - return clip; - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Layer3.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Layer3.java deleted file mode 100644 index 04f2246ee..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/Layer3.java +++ /dev/null @@ -1,2019 +0,0 @@ -/* - * layer3.c: Mpeg Layer-3 audio decoder - * - * Copyright (C) 1999-2010 The L.A.M.E. project - * - * Initially written by Michael Hipp, see also AUTHORS and README. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -/* $Id: Layer3.java,v 1.19 2011/06/17 05:26:42 kenchis Exp $ */ -package mpg; - -import mpg.Decode.Factory; -import mpg.Huffman.newhuff; -import mpg.Interface.ISynth; -import mpg.MPG123.III_sideinfo; -import mpg.MPG123.gr_info_s; -import mpg.MPGLib.ProcessedBytes; -import mpg.MPGLib.mpstr_tag; - -public class Layer3 { - private Common common; - - public void setModules(final Common c) { - common = c; - } - - private float ispow[] = new float[8207]; - private float aa_ca[] = new float[8], aa_cs[] = new float[8]; - private float COS1[][] = new float[12][6]; - private float win[][] = new float[4][36]; - private float win1[][] = new float[4][36]; - private float gainpow2[] = new float[256 + 118 + 4]; - private float COS9[] = new float[9]; - private float COS6_1, COS6_2; - private float tfcos36[] = new float[9]; - private float tfcos12[] = new float[3]; - - private static class bandInfoStruct { - public bandInfoStruct(final short[] lIdx, final short[] lDiff, - final short[] sIdx, final short[] sDiff) { - longIdx = lIdx; - longDiff = lDiff; - shortIdx = sIdx; - shortDiff = sDiff; - } - - short longIdx[] = new short[23]; - short longDiff[] = new short[22]; - short shortIdx[] = new short[14]; - short shortDiff[] = new short[13]; - }; - - private int longLimit[][] = new int[9][23]; - private int shortLimit[][] = new int[9][14]; - - private static bandInfoStruct bandInfo[] = { - - /* MPEG 1.0 */ - new bandInfoStruct( - new short[]{0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576}, - new short[]{4,4,4,4,4,4,6,6,8, 8,10,12,16,20,24,28,34,42,50,54, 76,158}, - new short[]{0,4*3,8*3,12*3,16*3,22*3,30*3,40*3,52*3,66*3, 84*3,106*3,136*3,192*3}, - new short[]{4,4,4,4,6,8,10,12,14,18,22,30,56}) , - - new bandInfoStruct( - new short[]{0,4,8,12,16,20,24,30,36,42,50,60,72, 88,106,128,156,190,230,276,330,384,576}, - new short[]{4,4,4,4,4,4,6,6,6, 8,10,12,16,18,22,28,34,40,46,54, 54,192}, - new short[]{0,4*3,8*3,12*3,16*3,22*3,28*3,38*3,50*3,64*3, 80*3,100*3,126*3,192*3}, - new short[]{4,4,4,4,6,6,10,12,14,16,20,26,66}) , - - new bandInfoStruct( - new short[]{0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576} , - new short[]{4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102, 26} , - new short[]{0,4*3,8*3,12*3,16*3,22*3,30*3,42*3,58*3,78*3,104*3,138*3,180*3,192*3} , - new short[]{4,4,4,4,6,8,12,16,20,26,34,42,12}) , - - /* MPEG 2.0 */ - new bandInfoStruct( - new short[]{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, - new short[]{6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } , - new short[]{0,4*3,8*3,12*3,18*3,24*3,32*3,42*3,56*3,74*3,100*3,132*3,174*3,192*3} , - new short[]{4,4,4,6,6,8,10,14,18,26,32,42,18 }) , - /* docs: 332. mpg123: 330 */ - new bandInfoStruct( - new short[]{0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,332,394,464,540,576}, - new short[]{6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,54,62,70,76,36 } , - new short[]{0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,136*3,180*3,192*3} , - new short[]{4,4,4,6,8,10,12,14,18,24,32,44,12 } ) , - - new bandInfoStruct( - new short[]{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, - new short[]{6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 }, - new short[]{0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,134*3,174*3,192*3}, - new short[]{4,4,4,6,8,10,12,14,18,24,30,40,18 } ) , - /* MPEG 2.5 */ - new bandInfoStruct( - new short[]{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} , - new short[]{6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54}, - new short[]{0,12,24,36,54,78,108,144,186,240,312,402,522,576}, - new short[]{4,4,4,6,8,10,12,14,18,24,30,40,18} ), - new bandInfoStruct( - new short[]{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} , - new short[]{6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54}, - new short[]{0,12,24,36,54,78,108,144,186,240,312,402,522,576}, - new short[]{4,4,4,6,8,10,12,14,18,24,30,40,18} ), - new bandInfoStruct( - new short[]{0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576}, - new short[]{12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2}, - new short[]{0, 24, 48, 72,108,156,216,288,372,480,486,492,498,576}, - new short[]{8,8,8,12,16,20,24,28,36,2,2,2,26} ) , - }; - - private int mapbuf0[][] = new int[9][152]; - private int mapbuf1[][] = new int[9][156]; - private int mapbuf2[][] = new int[9][44]; - private int map[][][] = new int[9][3][]; - private int mapend[][] = new int[9][3]; - - /** - * MPEG 2.0 slen for 'normal' mode. - */ - private int n_slen2[] = new int[512]; - /** - * MPEG 2.0 slen for intensity stereo. - */ - private int i_slen2[] = new int[256]; - - private float tan1_1[] = new float[16], tan2_1[] = new float[16], - tan1_2[] = new float[16], tan2_2[] = new float[16]; - private float pow1_1[][] = new float[2][16], pow2_1[][] = new float[2][16], - pow1_2[][] = new float[2][16], pow2_2[][] = new float[2][16]; - - private int get1bit(final mpstr_tag mp) { - int rval = (mp.wordpointer[mp.wordpointerPos] & 0xff) << mp.bitindex; - rval &= 0xff; - mp.bitindex++; - mp.wordpointerPos += (mp.bitindex >> 3); - mp.bitindex &= 7; - - return rval >> 7; - } - - private static double Ci[] = { -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, - -0.0142, -0.0037 }; - private static int len[] = { 36, 36, 12, 36 }; - - /* - * init tables for layer-3 - */ - public void init_layer3(final int down_sample_sblimit) { - for (int i = -256; i < 118 + 4; i++) - gainpow2[i + 256] = (float) Math.pow((double) 2.0, -0.25 - * (double) (i + 210)); - - for (int i = 0; i < 8207; i++) - ispow[i] = (float) Math.pow((double) i, (double) 4.0 / 3.0); - - for (int i = 0; i < 8; i++) { - double sq = Math.sqrt(1.0 + Ci[i] * Ci[i]); - aa_cs[i] = (float) (1.0 / sq); - aa_ca[i] = (float) (Ci[i] / sq); - } - - for (int i = 0; i < 18; i++) { - win[0][i] = win[1][i] = (float) (0.5 * Math.sin(MPG123.M_PI / 72.0 - * (double) (2 * (i + 0) + 1)) / Math.cos(MPG123.M_PI - * (double) (2 * (i + 0) + 19) / 72.0)); - win[0][i + 18] = win[3][i + 18] = (float) (0.5 * Math - .sin(MPG123.M_PI / 72.0 * (double) (2 * (i + 18) + 1)) / Math - .cos(MPG123.M_PI * (double) (2 * (i + 18) + 19) / 72.0)); - } - for (int i = 0; i < 6; i++) { - win[1][i + 18] = (float) (0.5 / Math.cos(MPG123.M_PI - * (double) (2 * (i + 18) + 19) / 72.0)); - win[3][i + 12] = (float) (0.5 / Math.cos(MPG123.M_PI - * (double) (2 * (i + 12) + 19) / 72.0)); - win[1][i + 24] = (float) (0.5 * Math.sin(MPG123.M_PI / 24.0 - * (double) (2 * i + 13)) / Math.cos(MPG123.M_PI - * (double) (2 * (i + 24) + 19) / 72.0)); - win[1][i + 30] = win[3][i] = 0.0f; - win[3][i + 6] = (float) (0.5 * Math.sin(MPG123.M_PI / 24.0 - * (double) (2 * i + 1)) / Math.cos(MPG123.M_PI - * (double) (2 * (i + 6) + 19) / 72.0)); - } - - for (int i = 0; i < 9; i++) - COS9[i] = (float) Math.cos(MPG123.M_PI / 18.0 * (double) i); - - for (int i = 0; i < 9; i++) - tfcos36[i] = (float) (0.5 / Math.cos(MPG123.M_PI - * (double) (i * 2 + 1) / 36.0)); - for (int i = 0; i < 3; i++) - tfcos12[i] = (float) (0.5 / Math.cos(MPG123.M_PI - * (double) (i * 2 + 1) / 12.0)); - - COS6_1 = (float) Math.cos(MPG123.M_PI / 6.0 * (double) 1); - COS6_2 = (float) Math.cos(MPG123.M_PI / 6.0 * (double) 2); - - for (int i = 0; i < 12; i++) { - win[2][i] = (float) (0.5 * Math.sin(MPG123.M_PI / 24.0 - * (double) (2 * i + 1)) / Math.cos(MPG123.M_PI - * (double) (2 * i + 7) / 24.0)); - for (int j = 0; j < 6; j++) - COS1[i][j] = (float) Math.cos(MPG123.M_PI / 24.0 - * (double) ((2 * i + 7) * (2 * j + 1))); - } - - for (int j = 0; j < 4; j++) { - for (int i = 0; i < len[j]; i += 2) - win1[j][i] = +win[j][i]; - for (int i = 1; i < len[j]; i += 2) - win1[j][i] = -win[j][i]; - } - - for (int i = 0; i < 16; i++) { - double t = Math.tan((double) i * MPG123.M_PI / 12.0); - tan1_1[i] = (float) (t / (1.0 + t)); - tan2_1[i] = (float) (1.0 / (1.0 + t)); - tan1_2[i] = (float) (MPG123.M_SQRT2 * t / (1.0 + t)); - tan2_2[i] = (float) (MPG123.M_SQRT2 / (1.0 + t)); - - for (int j = 0; j < 2; j++) { - double base = Math.pow(2.0, -0.25 * (j + 1.0)); - double p1 = 1.0, p2 = 1.0; - if (i > 0) { - if ((i & 1) != 0) - p1 = Math.pow(base, (i + 1.0) * 0.5); - else - p2 = Math.pow(base, i * 0.5); - } - pow1_1[j][i] = (float) p1; - pow2_1[j][i] = (float) p2; - pow1_2[j][i] = (float) (MPG123.M_SQRT2 * p1); - pow2_2[j][i] = (float) (MPG123.M_SQRT2 * p2); - } - } - - for (int j = 0; j < 9; j++) { - final bandInfoStruct bi = bandInfo[j]; - int mp; - int cb, lwin; - int bdf; - - map[j][0] = mapbuf0[j]; - mp = 0; - bdf = 0; - int i; - for (i = 0, cb = 0; cb < 8; cb++, i += bi.longDiff[bdf++]) { - map[j][0][mp++] = (bi.longDiff[bdf]) >> 1; - map[j][0][mp++] = i; - map[j][0][mp++] = 3; - map[j][0][mp++] = cb; - } - bdf = +3; - for (cb = 3; cb < 13; cb++) { - int l = (bi.shortDiff[bdf++]) >> 1; - for (lwin = 0; lwin < 3; lwin++) { - map[j][0][mp++] = l; - map[j][0][mp++] = i + lwin; - map[j][0][mp++] = lwin; - map[j][0][mp++] = cb; - } - i += 6 * l; - } - mapend[j][0] = mp; - - map[j][1] = mapbuf1[j]; - mp = 0; - bdf = 0; - for (i = 0, cb = 0; cb < 13; cb++) { - int l = (bi.shortDiff[bdf++]) >> 1; - for (lwin = 0; lwin < 3; lwin++) { - map[j][1][mp++] = l; - map[j][1][mp++] = i + lwin; - map[j][1][mp++] = lwin; - map[j][1][mp++] = cb; - } - i += 6 * l; - } - mapend[j][1] = mp; - - map[j][2] = mapbuf2[j]; - mp = 0; - bdf = 0; - for (cb = 0; cb < 22; cb++) { - map[j][2][mp++] = (bi.longDiff[bdf++]) >> 1; - map[j][2][mp++] = cb; - } - mapend[j][2] = mp; - - } - - for (int j = 0; j < 9; j++) { - for (int i = 0; i < 23; i++) { - longLimit[j][i] = (bandInfo[j].longIdx[i] - 1 + 8) / 18 + 1; - if (longLimit[j][i] > (down_sample_sblimit)) - longLimit[j][i] = down_sample_sblimit; - } - for (int i = 0; i < 14; i++) { - shortLimit[j][i] = (bandInfo[j].shortIdx[i] - 1) / 18 + 1; - if (shortLimit[j][i] > (down_sample_sblimit)) - shortLimit[j][i] = down_sample_sblimit; - } - } - - for (int i = 0; i < 5; i++) { - for (int j = 0; j < 6; j++) { - for (int k = 0; k < 6; k++) { - int n = k + j * 6 + i * 36; - i_slen2[n] = i | (j << 3) | (k << 6) | (3 << 12); - } - } - } - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - for (int k = 0; k < 4; k++) { - int n = k + j * 4 + i * 16; - i_slen2[n + 180] = i | (j << 3) | (k << 6) | (4 << 12); - } - } - } - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 3; j++) { - int n = j + i * 3; - i_slen2[n + 244] = i | (j << 3) | (5 << 12); - n_slen2[n + 500] = i | (j << 3) | (2 << 12) | (1 << 15); - } - } - - for (int i = 0; i < 5; i++) { - for (int j = 0; j < 5; j++) { - for (int k = 0; k < 4; k++) { - int l; - for (l = 0; l < 4; l++) { - int n = l + k * 4 + j * 16 + i * 80; - n_slen2[n] = i | (j << 3) | (k << 6) | (l << 9) - | (0 << 12); - } - } - } - } - for (int i = 0; i < 5; i++) { - for (int j = 0; j < 5; j++) { - for (int k = 0; k < 4; k++) { - int n = k + j * 4 + i * 20; - n_slen2[n + 400] = i | (j << 3) | (k << 6) | (1 << 12); - } - } - } - } - - /* - * read additional side information - */ - - private void III_get_side_info_1(final mpstr_tag mp, final III_sideinfo si, - final int stereo, final int ms_stereo, final int sfreq, - final int single) { - int ch, gr; - int powdiff = (single == 3) ? 4 : 0; - - si.main_data_begin = common.getbits(mp, 9); - if (stereo == 1) - si.private_bits = common.getbits_fast(mp, 5); - else - si.private_bits = common.getbits_fast(mp, 3); - - for (ch = 0; ch < stereo; ch++) { - si.ch[ch].gr[0].scfsi = -1; - si.ch[ch].gr[1].scfsi = common.getbits_fast(mp, 4); - } - - for (gr = 0; gr < 2; gr++) { - for (ch = 0; ch < stereo; ch++) { - gr_info_s gr_infos = si.ch[ch].gr[gr]; - - gr_infos.part2_3_length = common.getbits(mp, 12); - gr_infos.big_values = common.getbits_fast(mp, 9); - if (gr_infos.big_values > 288) { - System.err.printf("big_values too large! %d\n", gr_infos.big_values); - gr_infos.big_values = 288; - } - { - int qss = common.getbits_fast(mp, 8); - gr_infos.pow2gain = gainpow2; - gr_infos.pow2gainPos = 256 - qss + powdiff; - if (mp.pinfo != null) { - mp.pinfo.qss[gr][ch] = qss; - } - } - if (ms_stereo!=0) - gr_infos.pow2gainPos += 2; - gr_infos.scalefac_compress = common.getbits_fast(mp, 4); - /* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 . win-sw-flag = 0 */ - if (get1bit(mp)!=0) { - int i; - gr_infos.block_type = common.getbits_fast(mp, 2); - gr_infos.mixed_block_flag = get1bit(mp); - gr_infos.table_select[0] = common.getbits_fast(mp, 5); - gr_infos.table_select[1] = common.getbits_fast(mp, 5); - - - /* - * table_select[2] not needed, because there is no region2, - * but to satisfy some verifications tools we set it either. - */ - gr_infos.table_select[2] = 0; - for (i = 0; i < 3; i++) { - int sbg = (common.getbits_fast(mp, 3) << 3); - gr_infos.full_gain[i] = gr_infos.pow2gain; - gr_infos.full_gainPos[i] = gr_infos.pow2gainPos + sbg; - if (mp.pinfo != null) - mp.pinfo.sub_gain[gr][ch][i] = sbg / 8; - } - - if (gr_infos.block_type == 0) { - System.err.printf("Blocktype == 0 and window-switching == 1 not allowed.\n"); - /* error seems to be very good recoverable, so don't exit */ - /* exit(1); */ - } - /* region_count/start parameters are implicit in this case. */ - gr_infos.region1start = 36 >> 1; - gr_infos.region2start = 576 >> 1; - } - else { - int i, r0c, r1c; - for (i = 0; i < 3; i++) - gr_infos.table_select[i] = common.getbits_fast(mp, 5); - r0c = common.getbits_fast(mp, 4); - r1c = common.getbits_fast(mp, 3); - gr_infos.region1start = bandInfo[sfreq].longIdx[r0c + 1] >> 1; - gr_infos.region2start = bandInfo[sfreq].longIdx[r0c + 1 + r1c + 1] >> 1; - gr_infos.block_type = 0; - gr_infos.mixed_block_flag = 0; - } - gr_infos.preflag = get1bit(mp); - gr_infos.scalefac_scale = get1bit(mp); - gr_infos.count1table_select = get1bit(mp); - } - } - } - - /* - * Side Info for MPEG 2.0 / LSF - */ - private void III_get_side_info_2(final mpstr_tag mp, final III_sideinfo si, - final int stereo, final int ms_stereo, final int sfreq, - final int single) { - int ch; - int powdiff = (single == 3) ? 4 : 0; - - si.main_data_begin = common.getbits(mp, 8); - - if (stereo == 1) - si.private_bits = get1bit(mp); - else - si.private_bits = common.getbits_fast(mp, 2); - - for (ch = 0; ch < stereo; ch++) { - gr_info_s gr_infos = si.ch[ch].gr[0]; - int qss; - - gr_infos.part2_3_length = common.getbits(mp, 12); - gr_infos.big_values = common.getbits_fast(mp, 9); - if (gr_infos.big_values > 288) { - System.err.printf("big_values too large! %d\n", gr_infos.big_values); - gr_infos.big_values = 288; - } - qss = common.getbits_fast(mp, 8); - gr_infos.pow2gain = gainpow2; - gr_infos.pow2gainPos = 256 - qss + powdiff; - if (mp.pinfo != null) { - mp.pinfo.qss[0][ch] = qss; - } - - if (ms_stereo!=0) - gr_infos.pow2gainPos += 2; - gr_infos.scalefac_compress = common.getbits(mp, 9); - /* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 . win-sw-flag = 0 */ - if (get1bit(mp)!=0) { - int i; - gr_infos.block_type = common.getbits_fast(mp, 2); - gr_infos.mixed_block_flag = get1bit(mp); - gr_infos.table_select[0] = common.getbits_fast(mp, 5); - gr_infos.table_select[1] = common.getbits_fast(mp, 5); - /* - * table_select[2] not needed, because there is no region2, - * but to satisfy some verifications tools we set it either. - */ - gr_infos.table_select[2] = 0; - for (i = 0; i < 3; i++) { - int sbg = (common.getbits_fast(mp, 3) << 3); - gr_infos.full_gain[i] = gr_infos.pow2gain; - gr_infos.full_gainPos[i] = gr_infos.pow2gainPos+sbg; - if (mp.pinfo != null) - mp.pinfo.sub_gain[0][ch][i] = sbg / 8; - - } - - if (gr_infos.block_type == 0) { - System.err.printf("Blocktype == 0 and window-switching == 1 not allowed.\n"); - /* error seems to be very good recoverable, so don't exit */ - /* exit(1); */ - } - /* region_count/start parameters are implicit in this case. */ - /* check this again! */ - if (gr_infos.block_type == 2) { - if (sfreq == 8) - gr_infos.region1start = 36; - else - gr_infos.region1start = 36 >> 1; - } - else if (sfreq == 8) - /* check this for 2.5 and sfreq=8 */ - gr_infos.region1start = 108 >> 1; - else - gr_infos.region1start = 54 >> 1; - gr_infos.region2start = 576 >> 1; - } - else { - int i, r0c, r1c; - for (i = 0; i < 3; i++) - gr_infos.table_select[i] = common.getbits_fast(mp, 5); - r0c = common.getbits_fast(mp, 4); - r1c = common.getbits_fast(mp, 3); - gr_infos.region1start = bandInfo[sfreq].longIdx[r0c + 1] >> 1; - gr_infos.region2start = bandInfo[sfreq].longIdx[r0c + 1 + r1c + 1] >> 1; - gr_infos.block_type = 0; - gr_infos.mixed_block_flag = 0; - } - gr_infos.scalefac_scale = get1bit(mp); - gr_infos.count1table_select = get1bit(mp); - } - } - - private static final int slen[][] = { - {0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4}, - {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3} - }; - /* - * read scalefactors - */ - - private int - III_get_scale_factors_1(mpstr_tag mp, int []scf, gr_info_s gr_infos) - { - int scfPos=0; - int numbits; - int num0 = slen[0][gr_infos.scalefac_compress]; - int num1 = slen[1][gr_infos.scalefac_compress]; - - if (gr_infos.block_type == 2) { - int i = 18; - numbits = (num0 + num1) * 18; - - if (gr_infos.mixed_block_flag!=0) { - for (i = 8; i!=0; i--) - scf[scfPos++] = common.getbits_fast(mp, num0); - i = 9; - numbits -= num0; /* num0 * 17 + num1 * 18 */ - } - - for (; i!=0; i--) - scf[scfPos++] = common.getbits_fast(mp, num0); - for (i = 18; i!=0; i--) - scf[scfPos++] = common.getbits_fast(mp, num1); - scf[scfPos++] = 0; - scf[scfPos++] = 0; - scf[scfPos++] = 0; /* short[13][0..2] = 0 */ - } - else { - int i; - int scfsi = gr_infos.scfsi; - - if (scfsi < 0) { /* scfsi < 0 => granule == 0 */ - for (i = 11; i!=0; i--) - scf[scfPos++] = common.getbits_fast(mp, num0); - for (i = 10; i!=0; i--) - scf[scfPos++] = common.getbits_fast(mp, num1); - numbits = (num0 + num1) * 10 + num0; - } - else { - numbits = 0; - if (0==(scfsi & 0x8)) { - for (i = 6; i!=0; i--) - scf[scfPos++] = common.getbits_fast(mp, num0); - numbits += num0 * 6; - } - else { - scfPos += 6; - } - - if (0==(scfsi & 0x4)) { - for (i = 5; i!=0; i--) - scf[scfPos++] = common.getbits_fast(mp, num0); - numbits += num0 * 5; - } - else { - scfPos += 5; - } - - if (0==(scfsi & 0x2)) { - for (i = 5; i!=0; i--) - scf[scfPos++] = common.getbits_fast(mp, num1); - numbits += num1 * 5; - } - else { - scfPos += 5; - } - - if (0==(scfsi & 0x1)) { - for (i = 5; i!=0; i--) - scf[scfPos++] = common.getbits_fast(mp, num1); - numbits += num1 * 5; - } - else { - scfPos += 5; - } - } - - scf[scfPos++] = 0; /* no l[21] in original sources */ - } - return numbits; - } - - private static final int stab[][][] = { - { { 6, 5, 5,5 } , { 6, 5, 7,3 } , { 11,10,0,0} , - { 7, 7, 7,0 } , { 6, 6, 6,3 } , { 8, 8,5,0} } , - { { 9, 9, 9,9 } , { 9, 9,12,6 } , { 18,18,0,0} , - {12,12,12,0 } , {12, 9, 9,6 } , { 15,12,9,0} } , - { { 6, 9, 9,9 } , { 6, 9,12,6 } , { 15,18,0,0} , - { 6,15,12,0 } , { 6,12, 9,6 } , { 6,18,9,0} } }; - - private int - III_get_scale_factors_2(mpstr_tag mp, int []scf, gr_info_s gr_infos, int i_stereo) - { - int scfPos=0; - int[] pnt; - int i, j; - int slen; - int n = 0; - int numbits = 0; - - if (i_stereo!=0) /* i_stereo AND second channel . do_layer3() checks this */ - slen = i_slen2[gr_infos.scalefac_compress >> 1]; - else - slen = n_slen2[gr_infos.scalefac_compress]; - - gr_infos.preflag = (slen >> 15) & 0x1; - - n = 0; - if (gr_infos.block_type == 2) { - n++; - if (gr_infos.mixed_block_flag!=0) - n++; - } - - pnt = stab[n][(slen >> 12) & 0x7]; - - for (i = 0; i < 4; i++) { - int num = slen & 0x7; - slen >>= 3; - if (num!=0) { - for (j = 0; j < (int) (pnt[i]); j++) - scf[scfPos++] = common.getbits_fast(mp, num); - numbits += pnt[i] * num; - } - else { - for (j = 0; j < (int) (pnt[i]); j++) - scf[scfPos++] = 0; - } - } - - n = (n << 1) + 1; - for (i = 0; i < n; i++) - scf[scfPos++] = 0; - - return numbits; - } - - private static final int pretab1 [] = {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0}; /* char enough ? */ - private static final int pretab2 [] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - - private int - III_dequantize_sample(mpstr_tag mp, float xr[], int []scf, - gr_info_s gr_infos, int sfreq, int part2bits) - { - int scfPos = 0; - int shift = 1 + gr_infos.scalefac_scale; - float []xrpnt = (float []) xr; - int xrpntPos=0; - int l[]=new int[3], l3; - int part2remain = gr_infos.part2_3_length - part2bits; - int me; - - /* fprintf(stderr,"part2remain = %d, gr_infos.part2_3_length = %d, part2bits = %d\n", - part2remain, gr_infos.part2_3_length, part2bits); */ - - { - int i; - - for (i = ((MPG123.SBLIMIT*MPG123.SSLIMIT) - xrpntPos) >> 1; i > 0; i--) { - xrpnt[xrpntPos++] = 0.0f; - xrpnt[xrpntPos++] = 0.0f; - } - - xrpnt = (float [])xr; - xrpntPos = 0; - } - - { - int bv = gr_infos.big_values; - int region1 = gr_infos.region1start; - int region2 = gr_infos.region2start; - - l3 = ((576 >> 1) - bv) >> 1; - /* - * we may lose the 'odd' bit here !! - * check this later again - */ - if (bv <= region1) { - l[0] = bv; - l[1] = 0; - l[2] = 0; - } - else { - l[0] = region1; - if (bv <= region2) { - l[1] = bv - l[0]; - l[2] = 0; - } - else { - l[1] = region2 - l[0]; - l[2] = bv - region2; - } - } - } - /* MDH crash fix */ - { - int i; - for (i = 0; i < 3; i++) { - if (l[i] < 0) { - System.err.printf("hip: Bogus region length (%d)\n", l[i]); - l[i] = 0; - } - } - } - /* end MDH crash fix */ - - if (gr_infos.block_type == 2) { - /* - * decoding with short or mixed mode BandIndex table - */ - int i, max[]=new int[4]; - int step = 0, lwin = 0, cb = 0; - float v = 0.0f; - int []m; - int mc; - int mPos=0; - if (gr_infos.mixed_block_flag!=0) { - max[3] = -1; - max[0] = max[1] = max[2] = 2; - m = map[sfreq][0]; - mPos = 0; - me = mapend[sfreq][0]; - } - else { - max[0] = max[1] = max[2] = max[3] = -1; - /* max[3] not really needed in this case */ - m = map[sfreq][1]; - mPos = 0; - me = mapend[sfreq][1]; - } - - mc = 0; - for (i = 0; i < 2; i++) { - int lp = l[i]; - newhuff []h = Huffman.ht; - int hPos = (gr_infos.table_select[i]); - - for (; lp!=0; lp--, mc--) { - int x, y; - if ((0==mc)) { - mc = m[mPos++]; - xrpnt = (float[]) xr; - xrpntPos = (m[mPos++]); - lwin = m[mPos++]; - cb = m[mPos++]; - if (lwin == 3) { - v = gr_infos.pow2gain[gr_infos.pow2gainPos+(((scf[scfPos++]) << shift))]; - step = 1; - } - else { - v = gr_infos.full_gain[lwin][gr_infos.full_gainPos[lwin]+((scf[scfPos++]) << shift)]; - step = 3; - } - } - { - short []val = h[hPos].table; - int valPos=0; - while ((y = val[valPos++]) < 0) { - if (get1bit(mp)!=0) - valPos -= y; - part2remain--; - } - x = y >> 4; - y &= 0xf; - } - if (x == 15) { - max[lwin] = cb; - part2remain -= h[hPos].linbits + 1; - x += common.getbits(mp, (int) h[hPos].linbits); - if (get1bit(mp)!=0) - xrpnt[xrpntPos] = -ispow[x] * v; - else - xrpnt[xrpntPos] = ispow[x] * v; - } - else if (x!=0) { - max[lwin] = cb; - if (get1bit(mp)!=0) - xrpnt[xrpntPos] = -ispow[x] * v; - else - xrpnt[xrpntPos] = ispow[x] * v; - part2remain--; - } - else - xrpnt[xrpntPos] = 0.0f; - xrpntPos += step; - if (y == 15) { - max[lwin] = cb; - part2remain -= h[hPos].linbits + 1; - y += common.getbits(mp, (int) h[hPos].linbits); - if (get1bit(mp)!=0) - xrpnt[xrpntPos] = -ispow[y] * v; - else - xrpnt[xrpntPos] = ispow[y] * v; - } - else if (y!=0) { - max[lwin] = cb; - if (get1bit(mp)!=0) - xrpnt[xrpntPos] = -ispow[y] * v; - else - xrpnt[xrpntPos] = ispow[y] * v; - part2remain--; - } - else - xrpnt[xrpntPos] = 0.0f; - xrpntPos += step; - } - } - for (; l3!=0 && (part2remain > 0); l3--) { - newhuff []h = Huffman.htc; - int hPos = (gr_infos.count1table_select); - short []val = h[hPos].table; - int valPos = 0; - short a; - - while ((a = val[valPos++]) < 0) { - part2remain--; - if (part2remain < 0) { - part2remain++; - a = 0; - break; - } - if (get1bit(mp)!=0) - valPos -= a; - } - for (i = 0; i < 4; i++) { - if (0==(i & 1)) { - if (0==mc) { - mc = m[mPos++]; - xrpnt = ((float []) xr); - xrpntPos = (m[mPos++]); - lwin = m[mPos++]; - cb = m[mPos++]; - if (lwin == 3) { - v = gr_infos.pow2gain[gr_infos.pow2gainPos+((scf[scfPos++]) << shift)]; - step = 1; - } - else { - v = gr_infos.full_gain[lwin][gr_infos.full_gainPos[lwin]+((scf[scfPos++]) << shift)]; - step = 3; - } - } - mc--; - } - if ((a & (0x8 >> i))!=0) { - max[lwin] = cb; - part2remain--; - if (part2remain < 0) { - part2remain++; - break; - } - if (get1bit(mp)!=0) - xrpnt[xrpntPos] = -v; - else - xrpnt[xrpntPos] = v; - } - else - xrpnt[xrpntPos] = 0.0f; - xrpntPos += step; - } - } - - while (mPos < me) { - if (0==mc) { - mc = m[mPos++]; - xrpnt = ((float []) xr); - xrpntPos = m[mPos++]; - if ((m[mPos++]) == 3) - step = 1; - else - step = 3; - mPos++; /* cb */ - } - mc--; - xrpnt[xrpntPos] = 0.0f; - xrpntPos += step; - xrpnt[xrpntPos] = 0.0f; - xrpntPos += step; - /* we could add a little opt. here: - * if we finished a band for window 3 or a long band - * further bands could copied in a simple loop without a - * special 'map' decoding - */ - } - - gr_infos.maxband[0] = max[0] + 1; - gr_infos.maxband[1] = max[1] + 1; - gr_infos.maxband[2] = max[2] + 1; - gr_infos.maxbandl = max[3] + 1; - - { - int rmax = max[0] > max[1] ? max[0] : max[1]; - rmax = (rmax > max[2] ? rmax : max[2]) + 1; - gr_infos.maxb = rmax!=0 ? shortLimit[sfreq][rmax] : longLimit[sfreq][max[3] + 1]; - } - - } - else { - /* - * decoding with 'long' BandIndex table (block_type != 2) - */ - int []pretab = (int []) (gr_infos.preflag!=0 ? pretab1 : pretab2); - int pretabPos = 0; - int i, max = -1; - int cb = 0; - int []m = map[sfreq][2]; - int mPos=0; - float v = 0.0f; - int mc = 0; - - /* - * long hash table values - */ - for (i = 0; i < 3; i++) { - int lp = l[i]; - newhuff []h = Huffman.ht; - int hPos = (gr_infos.table_select[i]); - - for (; lp!=0; lp--, mc--) { - int x, y; - - if (0==mc) { - mc = m[mPos++]; - v = gr_infos.pow2gain[gr_infos.pow2gainPos+(((scf[scfPos++]) + (pretab[pretabPos++])) << shift)]; - cb = m[mPos++]; - } - { - short []val = h[hPos].table; - int valPos = 0; - while ((y = val[valPos++]) < 0) { - if (get1bit(mp)!=0) - valPos -= y; - part2remain--; - } - x = y >> 4; - y &= 0xf; - } - if (x == 15) { - max = cb; - part2remain -= h[hPos].linbits + 1; - x += common.getbits(mp, (int) h[hPos].linbits); - if (get1bit(mp)!=0) - xrpnt[xrpntPos++] = -ispow[x] * v; - else - xrpnt[xrpntPos++] = ispow[x] * v; - } - else if (x!=0) { - max = cb; - if (get1bit(mp)!=0) - xrpnt[xrpntPos++] = -ispow[x] * v; - else - xrpnt[xrpntPos++] = ispow[x] * v; - part2remain--; - } - else - xrpnt[xrpntPos++] = 0.0f; - - if (y == 15) { - max = cb; - part2remain -= h[hPos].linbits + 1; - y += common.getbits(mp, (int) h[hPos].linbits); - if (get1bit(mp)!=0) - xrpnt[xrpntPos++] = -ispow[y] * v; - else - xrpnt[xrpntPos++] = ispow[y] * v; - } - else if (y!=0) { - max = cb; - if (get1bit(mp)!=0) - xrpnt[xrpntPos++] = -ispow[y] * v; - else - xrpnt[xrpntPos++] = ispow[y] * v; - part2remain--; - } - else - xrpnt[xrpntPos++] = 0.0f; - } - } - - /* - * short (count1table) values - */ - for (; l3!=0 && (part2remain > 0); l3--) { - newhuff []h = Huffman.htc; - int hPos = (gr_infos.count1table_select); - short []val = h[hPos].table; - int valPos = 0; - short a; - - while ((a = val[valPos++]) < 0) { - part2remain--; - if (part2remain < 0) { - part2remain++; - a = 0; - break; - } - if (get1bit(mp)!=0) - valPos -= a; - } - for (i = 0; i < 4; i++) { - if (0==(i & 1)) { - if (0==mc) { - mc = m[mPos++]; - cb = m[mPos++]; - v = gr_infos.pow2gain[gr_infos.pow2gainPos+(((scf[scfPos++]) + (pretab[pretabPos++])) << shift)]; - } - mc--; - } - if ((a & (0x8 >> i))!=0) { - max = cb; - part2remain--; - if (part2remain < 0) { - part2remain++; - break; - } - if (get1bit(mp)!=0) - xrpnt[xrpntPos++] = -v; - else - xrpnt[xrpntPos++] = v; - } - else - xrpnt[xrpntPos++] = 0.0f; - } - } - - /* - * zero part - */ - for (i = ((MPG123.SBLIMIT*MPG123.SSLIMIT) - xrpntPos) >> 1; i!=0; i--) { - xrpnt[xrpntPos++] = 0.0f; - xrpnt[xrpntPos++] = 0.0f; - } - - gr_infos.maxbandl = max + 1; - gr_infos.maxb = longLimit[sfreq][gr_infos.maxbandl]; - } - - while (part2remain > 16) { - common.getbits(mp, 16); /* Dismiss stuffing Bits */ - part2remain -= 16; - } - if (part2remain > 0) - common.getbits(mp, part2remain); - else if (part2remain < 0) { - System.err.printf("hip: Can't rewind stream by %d bits!\n", -part2remain); - return 1; /* . error */ - } - return 0; - } - - /* - * III_stereo: calculate real channel values for Joint-I-Stereo-mode - */ - private void - III_i_stereo(float xr_buf[][], int []scalefac, - gr_info_s gr_infos, int sfreq, int ms_stereo, int lsf) - { - float[][] xr = xr_buf ; - final bandInfoStruct bi = bandInfo[sfreq]; - float tabl1[], tabl2[]; - - if (lsf!=0) { - int p = gr_infos.scalefac_compress & 0x1; - if (ms_stereo!=0) { - tabl1 = pow1_2[p]; - tabl2 = pow2_2[p]; - } - else { - tabl1 = pow1_1[p]; - tabl2 = pow2_1[p]; - } - } - else { - if (ms_stereo!=0) { - tabl1 = tan1_2; - tabl2 = tan2_2; - } - else { - tabl1 = tan1_1; - tabl2 = tan2_1; - } - } - - if (gr_infos.block_type == 2) { - int lwin, do_l = 0; - if (gr_infos.mixed_block_flag!=0) - do_l = 1; - - for (lwin = 0; lwin < 3; lwin++) { /* process each window */ - /* get first band with zero values */ - int is_p, sb, idx, sfb = gr_infos.maxband[lwin]; /* sfb is minimal 3 for mixed mode */ - if (sfb > 3) - do_l = 0; - - for (; sfb < 12; sfb++) { - is_p = scalefac[sfb * 3 + lwin - gr_infos.mixed_block_flag]; /* scale: 0-15 */ - if (is_p != 7) { - float t1, t2; - sb = bi.shortDiff[sfb]; - idx = bi.shortIdx[sfb] + lwin; - t1 = tabl1[is_p]; - t2 = tabl2[is_p]; - for (; sb > 0; sb--, idx += 3) { - float v = xr[0][idx]; - xr[0][idx] = v * t1; - xr[1][idx] = v * t2; - } - } - } - - /* in the original: copy 10 to 11 , here: copy 11 to 12 - maybe still wrong??? (copy 12 to 13?) */ - is_p = scalefac[11 * 3 + lwin - gr_infos.mixed_block_flag]; /* scale: 0-15 */ - sb = bi.shortDiff[12]; - idx = bi.shortIdx[12] + lwin; - if (is_p != 7) { - float t1, t2; - t1 = tabl1[is_p]; - t2 = tabl2[is_p]; - for (; sb > 0; sb--, idx += 3) { - float v = xr[0][idx]; - xr[0][idx] = v * t1; - xr[1][idx] = v * t2; - } - } - } /* end for(lwin; .. ; . ) */ - - if (do_l!=0) { - /* also check l-part, if ALL bands in the three windows are 'empty' - * and mode = mixed_mode - */ - int sfb = gr_infos.maxbandl; - int idx = bi.longIdx[sfb]; - - for (; sfb < 8; sfb++) { - int sb = bi.longDiff[sfb]; - int is_p = scalefac[sfb]; /* scale: 0-15 */ - if (is_p != 7) { - float t1, t2; - t1 = tabl1[is_p]; - t2 = tabl2[is_p]; - for (; sb > 0; sb--, idx++) { - float v = xr[0][idx]; - xr[0][idx] = v * t1; - xr[1][idx] = v * t2; - } - } - else - idx += sb; - } - } - } - else { /* ((gr_infos.block_type != 2)) */ - - int sfb = gr_infos.maxbandl; - int is_p, idx = bi.longIdx[sfb]; - for (; sfb < 21; sfb++) { - int sb = bi.longDiff[sfb]; - is_p = scalefac[sfb]; /* scale: 0-15 */ - if (is_p != 7) { - float t1, t2; - t1 = tabl1[is_p]; - t2 = tabl2[is_p]; - for (; sb > 0; sb--, idx++) { - float v = xr[0][idx]; - xr[0][idx] = v * t1; - xr[1][idx] = v * t2; - } - } - else - idx += sb; - } - - is_p = scalefac[20]; /* copy l-band 20 to l-band 21 */ - if (is_p != 7) { - int sb; - float t1 = tabl1[is_p], t2 = tabl2[is_p]; - - for (sb = bi.longDiff[21]; sb > 0; sb--, idx++) { - float v = xr[0][idx]; - xr[0][idx] = v * t1; - xr[1][idx] = v * t2; - } - } - } /* ... */ - } - - private void - III_antialias(float xr[], gr_info_s gr_infos) - { - int sblim; - - if (gr_infos.block_type == 2) { - if (0==gr_infos.mixed_block_flag) - return; - sblim = 1; - } - else { - sblim = gr_infos.maxb - 1; - } - - /* 31 alias-reduction operations between each pair of sub-bands */ - /* with 8 butterflies between each pair */ - - { - int sb; - float []xr1 = (float []) xr; - int xr1Pos=MPG123.SSLIMIT; - - for (sb = sblim; sb!=0; sb--, xr1Pos += 10) { - int ss; - float cs[] = aa_cs, ca[] = aa_ca; - int caPos=0; int csPos=0; - float []xr2 = xr1; - int xr2Pos = xr1Pos; - - for (ss = 7; ss >= 0; ss--) { /* upper and lower butterfly inputs */ - float bu = xr2[--xr2Pos], bd = xr1[xr1Pos]; - xr2[xr2Pos] = (bu * (cs[csPos])) - (bd * (ca[caPos])); - xr1[xr1Pos++] = (bd * (cs[csPos++])) + (bu * (ca[caPos++])); - } - } - } - } - - /* - DCT insipired by Jeff Tsay's DCT from the maplay package - this is an optimized version with manual unroll. - - References: - [1] S. Winograd: "On Computing the Discrete Fourier Transform", - Mathematics of Computation, Volume 32, Number 141, January 1978, - Pages 175-199 - */ - - private void dct36(float[] inbuf, int inbufPos,float[] o1, int o1Pos,float[] o2, int o2Pos,float[] wintab,float[] tsbuf, int tsPos) - { - { - float []in = inbuf; - int inPos = inbufPos; - - in[inPos+17]+=in[inPos+16]; in[inPos+16]+=in[inPos+15]; in[inPos+15]+=in[inPos+14]; - in[inPos+14]+=in[inPos+13]; in[inPos+13]+=in[inPos+12]; in[inPos+12]+=in[inPos+11]; - in[inPos+11]+=in[inPos+10]; in[inPos+10]+=in[inPos+9]; in[inPos+9] +=in[inPos+8]; - in[inPos+8] +=in[inPos+7]; in[inPos+7] +=in[inPos+6]; in[inPos+6] +=in[inPos+5]; - in[inPos+5] +=in[inPos+4]; in[inPos+4] +=in[inPos+3]; in[inPos+3] +=in[inPos+2]; - in[inPos+2] +=in[inPos+1]; in[inPos+1] +=in[inPos+0]; - - in[inPos+17]+=in[inPos+15]; in[inPos+15]+=in[inPos+13]; in[inPos+13]+=in[inPos+11]; in[inPos+11]+=in[inPos+9]; - in[inPos+9] +=in[inPos+7]; in[inPos+7] +=in[inPos+5]; in[inPos+5] +=in[inPos+3]; in[inPos+3] +=in[inPos+1]; - - { - - final float []c = COS9; - float []out2 = o2; - int out2Pos = o2Pos; - float []w = wintab; - float []out1 = o1; - int out1Pos = o1Pos; - float []ts = tsbuf; - - float ta33,ta66,tb33,tb66; - - ta33 = in[inPos+2*3+0] * c[3]; - ta66 = in[inPos+2*6+0] * c[6]; - tb33 = in[inPos+2*3+1] * c[3]; - tb66 = in[inPos+2*6+1] * c[6]; - - { - float tmp1a,tmp2a,tmp1b,tmp2b; - tmp1a = in[inPos+2*1+0] * c[1] + ta33 + in[inPos+2*5+0] * c[5] + in[inPos+2*7+0] * c[7]; - tmp1b = in[inPos+2*1+1] * c[1] + tb33 + in[inPos+2*5+1] * c[5] + in[inPos+2*7+1] * c[7]; - tmp2a = in[inPos+2*0+0] + in[inPos+2*2+0] * c[2] + in[inPos+2*4+0] * c[4] + ta66 + in[inPos+2*8+0] * c[8]; - tmp2b = in[inPos+2*0+1] + in[inPos+2*2+1] * c[2] + in[inPos+2*4+1] * c[4] + tb66 + in[inPos+2*8+1] * c[8]; - -// MACRO1(0); - { - float sum0 = tmp1a + tmp2a; - float sum1 = (tmp1b + tmp2b) * tfcos36[(0)]; - float tmp; - out2[out2Pos+9 + (0)] = (tmp = sum0 + sum1) * w[27 + (0)]; - out2[out2Pos+8 - (0)] = tmp * w[26 - (0)]; - sum0 -= sum1; - ts[tsPos + MPG123.SBLIMIT*(8-(0))] = out1[out1Pos+8-(0)] + sum0 * w[8-(0)]; - ts[tsPos + MPG123.SBLIMIT*(9+(0))] = out1[out1Pos+9+(0)] + sum0 * w[9+(0)]; - } -// MACRO2(8); - { - float sum0, sum1; - sum0 = tmp2a - tmp1a; - sum1 = (tmp2b - tmp1b) * tfcos36[(8)]; - float tmp; - out2[out2Pos+9 + (8)] = (tmp = sum0 + sum1) * w[27 + (8)]; - out2[out2Pos+8 - (8)] = tmp * w[26 - (8)]; - sum0 -= sum1; - ts[tsPos + MPG123.SBLIMIT*(8-(8))] = out1[out1Pos+8-(8)] + sum0 * w[8-(8)]; - ts[tsPos + MPG123.SBLIMIT*(9+(8))] = out1[out1Pos+9+(8)] + sum0 * w[9+(8)]; - } - } - - { - float tmp1a,tmp2a,tmp1b,tmp2b; - tmp1a = ( in[inPos+2*1+0] - in[inPos+2*5+0] - in[inPos+2*7+0] ) * c[3]; - tmp1b = ( in[inPos+2*1+1] - in[inPos+2*5+1] - in[inPos+2*7+1] ) * c[3]; - tmp2a = ( in[inPos+2*2+0] - in[inPos+2*4+0] - in[inPos+2*8+0] ) * c[6] - in[inPos+2*6+0] + in[inPos+2*0+0]; - tmp2b = ( in[inPos+2*2+1] - in[inPos+2*4+1] - in[inPos+2*8+1] ) * c[6] - in[inPos+2*6+1] + in[inPos+2*0+1]; - -// MACRO1(1); - { - float sum0 = tmp1a + tmp2a; - float sum1 = (tmp1b + tmp2b) * tfcos36[(1)]; - float tmp; - out2[out2Pos+9 + (1)] = (tmp = sum0 + sum1) * w[27 + (1)]; - out2[out2Pos+8 - (1)] = tmp * w[26 - (1)]; - sum0 -= sum1; - ts[tsPos + MPG123.SBLIMIT*(8-(1))] = out1[out1Pos+8-(1)] + sum0 * w[8-(1)]; - ts[tsPos + MPG123.SBLIMIT*(9+(1))] = out1[out1Pos+9+(1)] + sum0 * w[9+(1)]; - } -// MACRO2(7); - { - float sum0, sum1; - sum0 = tmp2a - tmp1a; - sum1 = (tmp2b - tmp1b) * tfcos36[(7)]; - float tmp; - out2[out2Pos+9 + (7)] = (tmp = sum0 + sum1) * w[27 + (7)]; - out2[out2Pos+8 - (7)] = tmp * w[26 - (7)]; - sum0 -= sum1; - ts[tsPos + MPG123.SBLIMIT*(8-(7))] = out1[out1Pos+8-(7)] + sum0 * w[8-(7)]; - ts[tsPos + MPG123.SBLIMIT*(9+(7))] = out1[out1Pos+9+(7)] + sum0 * w[9+(7)]; - } - } - - { - float tmp1a,tmp2a,tmp1b,tmp2b; - tmp1a = in[inPos+2*1+0] * c[5] - ta33 - in[inPos+2*5+0] * c[7] + in[inPos+2*7+0] * c[1]; - tmp1b = in[inPos+2*1+1] * c[5] - tb33 - in[inPos+2*5+1] * c[7] + in[inPos+2*7+1] * c[1]; - tmp2a = in[inPos+2*0+0] - in[inPos+2*2+0] * c[8] - in[inPos+2*4+0] * c[2] + ta66 + in[inPos+2*8+0] * c[4]; - tmp2b = in[inPos+2*0+1] - in[inPos+2*2+1] * c[8] - in[inPos+2*4+1] * c[2] + tb66 + in[inPos+2*8+1] * c[4]; - -// MACRO1(2); - { - float sum0 = tmp1a + tmp2a; - float sum1 = (tmp1b + tmp2b) * tfcos36[(2)]; - float tmp; - out2[out2Pos+9 + (2)] = (tmp = sum0 + sum1) * w[27 + (2)]; - out2[out2Pos+8 - (2)] = tmp * w[26 - (2)]; - sum0 -= sum1; - ts[tsPos + MPG123.SBLIMIT*(8-(2))] = out1[out1Pos+8-(2)] + sum0 * w[8-(2)]; - ts[tsPos + MPG123.SBLIMIT*(9+(2))] = out1[out1Pos+9+(2)] + sum0 * w[9+(2)]; - } -// MACRO2(6); - { - float sum0, sum1; - sum0 = tmp2a - tmp1a; - sum1 = (tmp2b - tmp1b) * tfcos36[(6)]; - float tmp; - out2[out2Pos+9 + (6)] = (tmp = sum0 + sum1) * w[27 + (6)]; - out2[out2Pos+8 - (6)] = tmp * w[26 - (6)]; - sum0 -= sum1; - ts[tsPos + MPG123.SBLIMIT*(8-(6))] = out1[out1Pos+8-(6)] + sum0 * w[8-(6)]; - ts[tsPos + MPG123.SBLIMIT*(9+(6))] = out1[out1Pos+9+(6)] + sum0 * w[9+(6)]; - } - } - - { - float tmp1a,tmp2a,tmp1b,tmp2b; - tmp1a = in[inPos+2*1+0] * c[7] - ta33 + in[inPos+2*5+0] * c[1] - in[inPos+2*7+0] * c[5]; - tmp1b = in[inPos+2*1+1] * c[7] - tb33 + in[inPos+2*5+1] * c[1] - in[inPos+2*7+1] * c[5]; - tmp2a = in[inPos+2*0+0] - in[inPos+2*2+0] * c[4] + in[inPos+2*4+0] * c[8] + ta66 - in[inPos+2*8+0] * c[2]; - tmp2b = in[inPos+2*0+1] - in[inPos+2*2+1] * c[4] + in[inPos+2*4+1] * c[8] + tb66 - in[inPos+2*8+1] * c[2]; - -// MACRO1(3); - { - float sum0 = tmp1a + tmp2a; - float sum1 = (tmp1b + tmp2b) * tfcos36[(3)]; - float tmp; - out2[out2Pos+9 + (3)] = (tmp = sum0 + sum1) * w[27 + (3)]; - out2[out2Pos+8 - (3)] = tmp * w[26 - (3)]; - sum0 -= sum1; - ts[tsPos + MPG123.SBLIMIT*(8-(3))] = out1[out1Pos+8-(3)] + sum0 * w[8-(3)]; - ts[tsPos + MPG123.SBLIMIT*(9+(3))] = out1[out1Pos+9+(3)] + sum0 * w[9+(3)]; - } -// MACRO2(5); - { - float sum0, sum1; - sum0 = tmp2a - tmp1a; - sum1 = (tmp2b - tmp1b) * tfcos36[(5)]; - float tmp; - out2[out2Pos+9 + (5)] = (tmp = sum0 + sum1) * w[27 + (5)]; - out2[out2Pos+8 - (5)] = tmp * w[26 - (5)]; - sum0 -= sum1; - ts[tsPos + MPG123.SBLIMIT*(8-(5))] = out1[out1Pos+8-(5)] + sum0 * w[8-(5)]; - ts[tsPos + MPG123.SBLIMIT*(9+(5))] = out1[out1Pos+9+(5)] + sum0 * w[9+(5)]; - } - } - - { - float sum0,sum1; - sum0 = in[inPos+2*0+0] - in[inPos+2*2+0] + in[inPos+2*4+0] - in[inPos+2*6+0] + in[inPos+2*8+0]; - sum1 = (in[inPos+2*0+1] - in[inPos+2*2+1] + in[inPos+2*4+1] - in[inPos+2*6+1] + in[inPos+2*8+1] ) * tfcos36[4]; -// MACRO0(4) - { - float tmp; - out2[out2Pos+9 + (4)] = (tmp = sum0 + sum1) * w[27 + (4)]; - out2[out2Pos+8 - (4)] = tmp * w[26 - (4)]; - sum0 -= sum1; - ts[tsPos + MPG123.SBLIMIT*(8-(4))] = out1[out1Pos + 8-(4)] + sum0 * w[8-(4)]; - ts[tsPos + MPG123.SBLIMIT*(9+(4))] = out1[out1Pos + 9+(4)] + sum0 * w[9+(4)]; - } - } - } - - } - } - - /* - * new DCT12 - */ - private void dct12(float[]in,int inbufPos,float[]rawout1, int rawout1Pos,float[]rawout2, int rawout2Pos,float[]wi,float[]ts, int tsPos) - { - { - float in0,in1,in2,in3,in4,in5; - float []out1 = rawout1; - int out1Pos = rawout1Pos; - ts[tsPos+MPG123.SBLIMIT*0] = out1[out1Pos+0]; ts[tsPos+MPG123.SBLIMIT*1] = out1[out1Pos+1]; ts[tsPos+MPG123.SBLIMIT*2] = out1[out1Pos+2]; - ts[tsPos+MPG123.SBLIMIT*3] = out1[out1Pos+3]; ts[tsPos+MPG123.SBLIMIT*4] = out1[out1Pos+4]; ts[tsPos+MPG123.SBLIMIT*5] = out1[out1Pos+5]; - -// DCT12_PART1 - { - in5 = in[inbufPos+5 * 3]; - in5 += (in4 = in[inbufPos+4 * 3]); - in4 += (in3 = in[inbufPos+3 * 3]); - in3 += (in2 = in[inbufPos+2 * 3]); - in2 += (in1 = in[inbufPos+1 * 3]); - in1 += (in0 = in[inbufPos+0 * 3]); - - in5 += in3; - in3 += in1; - - in2 *= COS6_1; - in3 *= COS6_1; - } - { - float tmp0,tmp1 = (in0 - in4); - { - float tmp2 = (in1 - in5) * tfcos12[1]; - tmp0 = tmp1 + tmp2; - tmp1 -= tmp2; - } - ts[tsPos+(17-1)*MPG123.SBLIMIT] = out1[out1Pos+17-1] + tmp0 * wi[11-1]; - ts[tsPos+(12+1)*MPG123.SBLIMIT] = out1[out1Pos+12+1] + tmp0 * wi[6+1]; - ts[tsPos+(6 +1)*MPG123.SBLIMIT] = out1[out1Pos+6 +1] + tmp1 * wi[1]; - ts[tsPos+(11-1)*MPG123.SBLIMIT] = out1[out1Pos+11-1] + tmp1 * wi[5-1]; - } - -// DCT12_PART2 - { - in0 += in4 * COS6_2; - - in4 = in0 + in2; - in0 -= in2; - - in1 += in5 * COS6_2; - - in5 = (in1 + in3) * tfcos12[0]; - in1 = (in1 - in3) * tfcos12[2]; - - in3 = in4 + in5; - in4 -= in5; - - in2 = in0 + in1; - in0 -= in1; - } - ts[tsPos+(17-0)*MPG123.SBLIMIT] = out1[out1Pos+17-0] + in2 * wi[11-0]; - ts[tsPos+(12+0)*MPG123.SBLIMIT] = out1[out1Pos+12+0] + in2 * wi[6+0]; - ts[tsPos+(12+2)*MPG123.SBLIMIT] = out1[out1Pos+12+2] + in3 * wi[6+2]; - ts[tsPos+(17-2)*MPG123.SBLIMIT] = out1[out1Pos+17-2] + in3 * wi[11-2]; - - ts[tsPos+(6+0)*MPG123.SBLIMIT] = out1[out1Pos+6+0] + in0 * wi[0]; - ts[tsPos+(11-0)*MPG123.SBLIMIT] = out1[out1Pos+11-0] + in0 * wi[5-0]; - ts[tsPos+(6+2)*MPG123.SBLIMIT] = out1[out1Pos+6+2] + in4 * wi[2]; - ts[tsPos+(11-2)*MPG123.SBLIMIT] = out1[out1Pos+11-2] + in4 * wi[5-2]; - } - - inbufPos++; - - { - float in0,in1,in2,in3,in4,in5; - float []out2 = rawout2; - int out2Pos = rawout2Pos; - -// DCT12_PART1 - { - in5 = in[inbufPos+5 * 3]; - in5 += (in4 = in[inbufPos+4 * 3]); - in4 += (in3 = in[inbufPos+3 * 3]); - in3 += (in2 = in[inbufPos+2 * 3]); - in2 += (in1 = in[inbufPos+1 * 3]); - in1 += (in0 = in[inbufPos+0 * 3]); - - in5 += in3; - in3 += in1; - - in2 *= COS6_1; - in3 *= COS6_1; - } - - { - float tmp0,tmp1 = (in0 - in4); - { - float tmp2 = (in1 - in5) * tfcos12[1]; - tmp0 = tmp1 + tmp2; - tmp1 -= tmp2; - } - out2[out2Pos+5-1] = tmp0 * wi[11-1]; - out2[out2Pos+0+1] = tmp0 * wi[6+1]; - ts[tsPos+(12+1)*MPG123.SBLIMIT] += tmp1 * wi[1]; - ts[tsPos+(17-1)*MPG123.SBLIMIT] += tmp1 * wi[5-1]; - } - -// DCT12_PART2 - { - in0 += in4 * COS6_2; - - in4 = in0 + in2; - in0 -= in2; - - in1 += in5 * COS6_2; - - in5 = (in1 + in3) * tfcos12[0]; - in1 = (in1 - in3) * tfcos12[2]; - - in3 = in4 + in5; - in4 -= in5; - - in2 = in0 + in1; - in0 -= in1; - } - - out2[out2Pos+5-0] = in2 * wi[11-0]; - out2[out2Pos+0+0] = in2 * wi[6+0]; - out2[out2Pos+0+2] = in3 * wi[6+2]; - out2[out2Pos+5-2] = in3 * wi[11-2]; - - ts[tsPos+(12+0)*MPG123.SBLIMIT] += in0 * wi[0]; - ts[tsPos+(17-0)*MPG123.SBLIMIT] += in0 * wi[5-0]; - ts[tsPos+(12+2)*MPG123.SBLIMIT] += in4 * wi[2]; - ts[tsPos+(17-2)*MPG123.SBLIMIT] += in4 * wi[5-2]; - } - - inbufPos++; - - { - float in0,in1,in2,in3,in4,in5; - float []out2 = rawout2; - int out2Pos = rawout2Pos; - out2[out2Pos+12]=out2[out2Pos+13]=out2[out2Pos+14]=out2[out2Pos+15]=out2[out2Pos+16]=out2[out2Pos+17]=0.0f; - -// DCT12_PART1 - { - in5 = in[inbufPos+5 * 3]; - in5 += (in4 = in[inbufPos+4 * 3]); - in4 += (in3 = in[inbufPos+3 * 3]); - in3 += (in2 = in[inbufPos+2 * 3]); - in2 += (in1 = in[inbufPos+1 * 3]); - in1 += (in0 = in[inbufPos+0 * 3]); - - in5 += in3; - in3 += in1; - - in2 *= COS6_1; - in3 *= COS6_1; - } - - { - float tmp0,tmp1 = (in0 - in4); - { - float tmp2 = (in1 - in5) * tfcos12[1]; - tmp0 = tmp1 + tmp2; - tmp1 -= tmp2; - } - out2[out2Pos+11-1] = tmp0 * wi[11-1]; - out2[out2Pos+6 +1] = tmp0 * wi[6+1]; - out2[out2Pos+0+1] += tmp1 * wi[1]; - out2[out2Pos+5-1] += tmp1 * wi[5-1]; - } - -// DCT12_PART2 - { - in0 += in4 * COS6_2; - - in4 = in0 + in2; - in0 -= in2; - - in1 += in5 * COS6_2; - - in5 = (in1 + in3) * tfcos12[0]; - in1 = (in1 - in3) * tfcos12[2]; - - in3 = in4 + in5; - in4 -= in5; - - in2 = in0 + in1; - in0 -= in1; - } - - out2[out2Pos+11-0] = in2 * wi[11-0]; - out2[out2Pos+6 +0] = in2 * wi[6+0]; - out2[out2Pos+6 +2] = in3 * wi[6+2]; - out2[out2Pos+11-2] = in3 * wi[11-2]; - - out2[out2Pos+0+0] += in0 * wi[0]; - out2[out2Pos+5-0] += in0 * wi[5-0]; - out2[out2Pos+0+2] += in4 * wi[2]; - out2[out2Pos+5-2] += in4 * wi[5-2]; - } - } - - /* - * III_hybrid - */ - private void - III_hybrid(mpstr_tag mp, float fsIn[], float tsOut[], - int ch, gr_info_s gr_infos) - { - float []tspnt = (float []) tsOut; - int tspntPos = 0; - float block[][][] = mp.hybrid_block; - int []blc = mp.hybrid_blc; - float rawout1[], rawout2[]; - int rawout1Pos, rawout2Pos; - int bt; - int sb = 0; - - { - int b = blc[ch]; - rawout1 = block[b][ch]; - rawout1Pos = 0; - b = -b + 1; - rawout2 = block[b][ch]; - rawout2Pos = 0; - blc[ch] = b; - } - - - if (gr_infos.mixed_block_flag!=0) { - sb = 2; - dct36(fsIn, 0 * MPG123.SSLIMIT, rawout1, rawout1Pos, rawout2, rawout2Pos, win[0], tspnt, tspntPos+0); - dct36(fsIn, 1 * MPG123.SSLIMIT, rawout1, rawout1Pos+18, rawout2, rawout2Pos+18, win1[0], tspnt, tspntPos+1); - rawout1Pos += 36; - rawout2Pos += 36; - tspntPos += 2; - } - - bt = gr_infos.block_type; - if (bt == 2) { - for (; sb < (int) gr_infos.maxb; sb += 2, tspntPos += 2, rawout1Pos += 36, rawout2Pos += 36) { - dct12(fsIn, sb * MPG123.SSLIMIT, rawout1, rawout1Pos, rawout2, rawout2Pos, win[2], tspnt, tspntPos+0); - dct12(fsIn, (sb + 1) * MPG123.SSLIMIT, rawout1, rawout1Pos+18, rawout2, rawout2Pos+18, win1[2], tspnt, tspntPos+1); - } - } - else { - for (; sb < (int) gr_infos.maxb; sb += 2, tspntPos += 2, rawout1Pos += 36, rawout2Pos += 36) { - dct36(fsIn, sb * MPG123.SSLIMIT, rawout1, rawout1Pos, rawout2, rawout2Pos, win[bt], tspnt, tspntPos+0); - dct36(fsIn, (sb + 1) * MPG123.SSLIMIT, rawout1, rawout1Pos+18, rawout2, rawout2Pos+18, win1[bt], tspnt, tspntPos+1); - } - } - - for (; sb < MPG123.SBLIMIT; sb++, tspntPos++) { - int i; - for (i = 0; i < MPG123.SSLIMIT; i++) { - tspnt[tspntPos+i * MPG123.SBLIMIT] = rawout1[rawout1Pos++]; - rawout2[rawout2Pos++] = 0.0f; - } - } - } - - /* - * main layer3 handler - */ - private III_sideinfo sideinfo = new III_sideinfo(); - - public int - layer3_audiodata_precedesframes(mpstr_tag mp) - { - int audioDataInFrame; - int framesToBacktrack; - - /* specific to Layer 3, since Layer 1 & 2 the audio data starts at the frame that describes it. */ - /* determine how many bytes and therefore bitstream frames the audio data precedes it's matching frame */ - /* fprintf(stderr, "hip: main_data_begin = %d, mp.bsize %d, mp.fsizeold %d, mp.ssize %d\n", - sideinfo.main_data_begin, mp.bsize, mp.fsizeold, mp.ssize); */ - /* compute the number of frames to backtrack, 4 for the header, ssize already holds the CRC */ - /* TODO Erroneously assumes current frame is same as previous frame. */ - audioDataInFrame = mp.bsize - 4 - mp.ssize; - framesToBacktrack = (sideinfo.main_data_begin + audioDataInFrame - 1) / audioDataInFrame; - /* fprintf(stderr, "hip: audioDataInFrame %d framesToBacktrack %d\n", audioDataInFrame, framesToBacktrack); */ - return framesToBacktrack; - } - - public int - do_layer3_sideinfo(mpstr_tag mp) - { - Frame fr = mp.fr; - int stereo = fr.stereo; - int single = fr.single; - int ms_stereo; - int sfreq = fr.sampling_frequency; - int granules; - int ch, gr, databits; - - if (stereo == 1) { /* stream is mono */ - single = 0; - } - - if (fr.mode == MPG123.MPG_MD_JOINT_STEREO) { - ms_stereo = fr.mode_ext & 0x2; - } - else - ms_stereo = 0; - - - if (fr.lsf!=0) { - granules = 1; - III_get_side_info_2(mp, sideinfo, stereo, ms_stereo, sfreq, single); - } - else { - granules = 2; - III_get_side_info_1(mp, sideinfo, stereo, ms_stereo, sfreq, single); - } - - databits = 0; - for (gr = 0; gr < granules; ++gr) { - for (ch = 0; ch < stereo; ++ch) { - gr_info_s gr_infos = (sideinfo.ch[ch].gr[gr]); - databits += gr_infos.part2_3_length; - } - } - return databits - 8 * sideinfo.main_data_begin; - } - - private float hybridIn[][]=new float[2][MPG123.SBLIMIT*MPG123.SSLIMIT]; - private float hybridOut[][]=new float[2][MPG123.SSLIMIT*MPG123.SBLIMIT]; - - public <T>int - do_layer3(mpstr_tag mp, T[] pcm_sample, ProcessedBytes pcm_point, - ISynth synth, Factory<T> tFactory) - { - int gr, ch, ss, clip = 0; - int scalefacs[][]=new int[2][39]; /* max 39 for short[13][3] mode, mixed: 38, long: 22 */ - /* struct III_sideinfo sideinfo; */ - Frame fr = (mp.fr); - int stereo = fr.stereo; - int single = fr.single; - int ms_stereo, i_stereo; - int sfreq = fr.sampling_frequency; - int stereo1, granules; - - if (common.set_pointer(mp, (int) sideinfo.main_data_begin) == MPGLib.MP3_ERR) - return 0; - - if (stereo == 1) { /* stream is mono */ - stereo1 = 1; - single = 0; - } - else if (single >= 0) /* stream is stereo, but force to mono */ - stereo1 = 1; - else - stereo1 = 2; - - if (fr.mode == MPG123.MPG_MD_JOINT_STEREO) { - ms_stereo = fr.mode_ext & 0x2; - i_stereo = fr.mode_ext & 0x1; - } - else - ms_stereo = i_stereo = 0; - - - if (fr.lsf!=0) { - granules = 1; - } - else { - granules = 2; - } - - for (gr = 0; gr < granules; gr++) { - - { - gr_info_s gr_infos = (sideinfo.ch[0].gr[gr]); - int part2bits; - - if (fr.lsf!=0) - part2bits = III_get_scale_factors_2(mp, scalefacs[0], gr_infos, 0); - else { - part2bits = III_get_scale_factors_1(mp, scalefacs[0], gr_infos); - } - - if (mp.pinfo != null) { - int i; - mp.pinfo.sfbits[gr][0] = part2bits; - for (i = 0; i < 39; i++) - mp.pinfo.sfb_s[gr][0][i] = scalefacs[0][i]; - } - - /* fprintf(stderr, "calling III dequantize sample 1 gr_infos.part2_3_length %d\n", gr_infos.part2_3_length); */ - if (III_dequantize_sample(mp, hybridIn[0], scalefacs[0], gr_infos, sfreq, part2bits)!=0) - return clip; - } - if (stereo == 2) { - gr_info_s gr_infos = (sideinfo.ch[1].gr[gr]); - int part2bits; - if (fr.lsf!=0) - part2bits = III_get_scale_factors_2(mp, scalefacs[1], gr_infos, i_stereo); - else { - part2bits = III_get_scale_factors_1(mp, scalefacs[1], gr_infos); - } - if (mp.pinfo != null) { - int i; - mp.pinfo.sfbits[gr][1] = part2bits; - for (i = 0; i < 39; i++) - mp.pinfo.sfb_s[gr][1][i] = scalefacs[1][i]; - } - - /* fprintf(stderr, "calling III dequantize sample 2 gr_infos.part2_3_length %d\n", gr_infos.part2_3_length); */ - if (III_dequantize_sample(mp, hybridIn[1], scalefacs[1], gr_infos, sfreq, part2bits)!=0) - return clip; - - if (ms_stereo!=0) { - int i; - for (i = 0; i < MPG123.SBLIMIT * MPG123.SSLIMIT; i++) { - float tmp0, tmp1; - tmp0 = ((float []) hybridIn[0])[i]; - tmp1 = ((float []) hybridIn[1])[i]; - ((float []) hybridIn[1])[i] = tmp0 - tmp1; - ((float []) hybridIn[0])[i] = tmp0 + tmp1; - } - } - - if (i_stereo!=0) - III_i_stereo(hybridIn, scalefacs[1], gr_infos, sfreq, ms_stereo, fr.lsf); - - if (ms_stereo!=0 || i_stereo!=0 || (single == 3)) { - if (gr_infos.maxb > sideinfo.ch[0].gr[gr].maxb) - sideinfo.ch[0].gr[gr].maxb = gr_infos.maxb; - else - gr_infos.maxb = sideinfo.ch[0].gr[gr].maxb; - } - - switch (single) { - case 3: - { - int i; - float in0[] = (float []) hybridIn[0], in1[] = (float []) hybridIn[1]; - int in0Pos = 0, in1Pos = 0; - for (i = 0; i < (int) (MPG123.SSLIMIT * gr_infos.maxb); i++, in0Pos++) - in0[in0Pos] = (in0[in0Pos] + in1[in1Pos++]); /* *0.5 done by pow-scale */ - } - break; - case 1: - { - int i; - float in0[] = (float []) hybridIn[0], in1[] = (float []) hybridIn[1]; - int in0Pos = 0, in1Pos = 0; - for (i = 0; i < (int) (MPG123.SSLIMIT * gr_infos.maxb); i++) - in0[in0Pos++] = in1[in1Pos++]; - } - break; - } - } - - if (mp.pinfo != null) { - int i, sb; - float ifqstep; - - mp.pinfo.bitrate = Common.tabsel_123[fr.lsf][fr.lay - 1][fr.bitrate_index]; - mp.pinfo.sampfreq = Common.freqs[sfreq]; - mp.pinfo.emph = fr.emphasis; - mp.pinfo.crc = fr.error_protection?1:0; - mp.pinfo.padding = fr.padding; - mp.pinfo.stereo = fr.stereo; - mp.pinfo.js = (fr.mode == MPG123.MPG_MD_JOINT_STEREO)?1:0; - mp.pinfo.ms_stereo = ms_stereo; - mp.pinfo.i_stereo = i_stereo; - mp.pinfo.maindata = sideinfo.main_data_begin; - - for (ch = 0; ch < stereo1; ch++) { - gr_info_s gr_infos = (sideinfo.ch[ch].gr[gr]); - mp.pinfo.big_values[gr][ch] = gr_infos.big_values; - mp.pinfo.scalefac_scale[gr][ch] = gr_infos.scalefac_scale; - mp.pinfo.mixed[gr][ch] = gr_infos.mixed_block_flag; - mp.pinfo.mpg123blocktype[gr][ch] = gr_infos.block_type; - mp.pinfo.mainbits[gr][ch] = gr_infos.part2_3_length; - mp.pinfo.preflag[gr][ch] = gr_infos.preflag; - if (gr == 1) - mp.pinfo.scfsi[ch] = gr_infos.scfsi; - } - - - for (ch = 0; ch < stereo1; ch++) { - gr_info_s gr_infos = (sideinfo.ch[ch].gr[gr]); - ifqstep = (mp.pinfo.scalefac_scale[gr][ch] == 0) ? .5f : 1.0f; - if (2 == gr_infos.block_type) { - for (i = 0; i < 3; i++) { - for (sb = 0; sb < 12; sb++) { - int j = 3 * sb + i; - /* - is_p = scalefac[sfb*3+lwin-gr_infos.mixed_block_flag]; - */ - /* scalefac was copied into pinfo.sfb_s[] above */ - mp.pinfo.sfb_s[gr][ch][j] = - -ifqstep * mp.pinfo.sfb_s[gr][ch][j - gr_infos.mixed_block_flag]; - mp.pinfo.sfb_s[gr][ch][j] -= 2 * (mp.pinfo.sub_gain[gr][ch][i]); - } - mp.pinfo.sfb_s[gr][ch][3 * sb + i] = - -2 * (mp.pinfo.sub_gain[gr][ch][i]); - } - } - else { - for (sb = 0; sb < 21; sb++) { - /* scalefac was copied into pinfo.sfb[] above */ - mp.pinfo.sfb[gr][ch][sb] = mp.pinfo.sfb_s[gr][ch][sb]; - if (gr_infos.preflag!=0) - mp.pinfo.sfb[gr][ch][sb] += pretab1[sb]; - mp.pinfo.sfb[gr][ch][sb] *= -ifqstep; - } - mp.pinfo.sfb[gr][ch][21] = 0; - } - } - - - - for (ch = 0; ch < stereo1; ch++) { - int j = 0; - for (sb = 0; sb < MPG123.SBLIMIT; sb++) - for (ss = 0; ss < MPG123.SSLIMIT; ss++, j++) - mp.pinfo.mpg123xr[gr][ch][j] = hybridIn[ch][sb*MPG123.SSLIMIT+ss]; - } - } - - - for (ch = 0; ch < stereo1; ch++) { - gr_info_s gr_infos = (sideinfo.ch[ch].gr[gr]); - III_antialias(hybridIn[ch], gr_infos); - III_hybrid(mp, hybridIn[ch], hybridOut[ch], ch, gr_infos); - } - - for (ss = 0; ss < MPG123.SSLIMIT; ss++) { - if (single >= 0) { - clip += synth.synth_1to1_mono_ptr(mp, hybridOut[0], ss*MPG123.SBLIMIT, pcm_sample, pcm_point, tFactory); - } - else { - ProcessedBytes p1 = new ProcessedBytes(); - p1.pb = pcm_point.pb; - clip += synth.synth_1to1_ptr(mp, hybridOut[0], ss*MPG123.SBLIMIT, 0, pcm_sample, p1, tFactory); - clip += synth.synth_1to1_ptr(mp, hybridOut[1], ss*MPG123.SBLIMIT, 1, pcm_sample, pcm_point, tFactory); - } - } - } - - return clip; - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/MPG123.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/MPG123.java deleted file mode 100644 index bc8a24844..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/MPG123.java +++ /dev/null @@ -1,63 +0,0 @@ -package mpg; - -public class MPG123 { - public static final double M_SQRT2 = 1.41421356237309504880; - public static final double M_PI = 3.14159265358979323846; - - public static final int SBLIMIT =32; - public static final int SSLIMIT =18; - - public static final int MPG_MD_STEREO =0; - public static final int MPG_MD_JOINT_STEREO =1; - public static final int MPG_MD_DUAL_CHANNEL =2; - public static final int MPG_MD_MONO =3; - - public static final int MAXFRAMESIZE =2880; - - /* AF: ADDED FOR LAYER1/LAYER2 */ - public static final int SCALE_BLOCK =12; - - - static class gr_info_s { - int scfsi; - int part2_3_length; - int big_values; - int scalefac_compress; - int block_type; - int mixed_block_flag; - int table_select[]=new int[3]; - int subblock_gain[]=new int[3]; - int maxband[]=new int[3]; - int maxbandl; - int maxb; - int region1start; - int region2start; - int preflag; - int scalefac_scale; - int count1table_select; - float full_gain[][]=new float[3][]; - int full_gainPos[]=new int[3]; - float []pow2gain; - int pow2gainPos; - }; - - static class grT { - public grT() { - gr[0] = new gr_info_s(); - gr[1] = new gr_info_s(); - } - gr_info_s gr[]=new gr_info_s[2]; - } - static class III_sideinfo { - public III_sideinfo() { - ch[0]= new grT(); - ch[1]= new grT(); - } - int main_data_begin; - int private_bits; - grT ch[]=new grT[2]; - }; - - - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/MPGLib.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/MPGLib.java deleted file mode 100644 index 76b172e9d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/MPGLib.java +++ /dev/null @@ -1,373 +0,0 @@ -/* - * LAME MP3 encoding engine - * - * Copyright (c) 1999-2000 Mark Taylor - * Copyright (c) 2003 Olcios - * Copyright (c) 2008 Robert Hegemann - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -package mpg; - -import mp3.Enc; -import mp3.MP3Data; -import mp3.PlottingData; -import mpg.MPG123; -import mpg.Decode.Factory; - -public class MPGLib { - - Interface interf; - Common common; - - public void setModules(Interface i, Common c) { - interf = i; - common = c; - } - - public static class buf { - byte[] pnt; - int size; - int pos; - buf next; - buf prev; - }; - - public static class framebuf { - buf buf; - long pos; - Frame next; - Frame prev; - }; - - - public static class mpstr_tag { - buf head, tail; /* buffer linked list pointers, tail points to oldest buffer */ - boolean vbr_header; /* 1 if valid Xing vbr header detected */ - int num_frames; /* set if vbr header present */ - int enc_delay; /* set if vbr header present */ - int enc_padding; /* set if vbr header present */ - /* header_parsed, side_parsed and data_parsed must be all set 1 - before the full frame has been parsed */ - boolean header_parsed; /* 1 = header of current frame has been parsed */ - boolean side_parsed; /* 1 = header of sideinfo of current frame has been parsed */ - boolean data_parsed; - boolean free_format; /* 1 = free format frame */ - boolean old_free_format; /* 1 = last frame was free format */ - int bsize; - int framesize; - int ssize; /* number of bytes used for side information, including 2 bytes for CRC-16 if present */ - int dsize; - int fsizeold; /* size of previous frame, -1 for first */ - int fsizeold_nopadding; - Frame fr = new Frame(); /* holds the parameters decoded from the header */ - byte bsspace[][]=new byte[2][MPG123.MAXFRAMESIZE + 1024]; /* bit stream space used ???? */ /* MAXFRAMESIZE */ - float hybrid_block[][][]=new float[2][2][MPG123.SBLIMIT * MPG123.SSLIMIT]; - int hybrid_blc[]=new int[2]; - long header; - int bsnum; - float synth_buffs[][][]= new float[2][2][0x110]; - int synth_bo; - int sync_bitstream; /* 1 = bitstream is yet to be synchronized */ - - int bitindex; - byte[] wordpointer; - int wordpointerPos; - PlottingData pinfo; - } - - public final static int MP3_ERR =-1; - public final static int MP3_OK =0; - final static int MP3_NEED_MORE =1; - - /* copy mono samples */ - @SuppressWarnings("unchecked") - protected <DST_TYPE, SRC_TYPE> void COPY_MONO(DST_TYPE[] pcm_l, - int pcm_lPos, int processed_samples, SRC_TYPE[] p) { - int p_samples = 0; - for (int i = 0; i < processed_samples; i++) - pcm_l[pcm_lPos++] = (DST_TYPE) (p[p_samples++]); - } - - /* copy stereo samples */ - @SuppressWarnings("unchecked") - protected <DST_TYPE, SRC_TYPE> void COPY_STEREO(DST_TYPE[] pcm_l, - int pcm_lPos, DST_TYPE[] pcm_r, int pcm_rPos, - int processed_samples, SRC_TYPE[] p) { - int p_samples = 0; - for (int i = 0; i < processed_samples; i++) { - pcm_l[pcm_lPos++] = (DST_TYPE) (p[p_samples++]); - pcm_r[pcm_rPos++] = (DST_TYPE) (p[p_samples++]); - } - } - - static class ProcessedBytes { - int pb; - } - - interface IDecoder { - <T>int decode(mpstr_tag mp, byte []in, int bufferPos, int isize, T []out, int osize, ProcessedBytes done, Factory<T> tFactory); - } - - private static final int smpls[][] = { - /* Layer I II III */ - {0, 384, 1152, 1152}, /* MPEG-1 */ - {0, 384, 1152, 576} /* MPEG-2(.5) */ - }; - - /* - * For lame_decode: return code - * -1 error - * 0 ok, but need more data before outputing any samples - * n number of samples output. either 576 or 1152 depending on MP3 file. - */ - - private <S,T>int decode1_headersB_clipchoice(mpstr_tag pmp, byte[] buffer, - int bufferPos, int len, S pcm_l[], int pcm_lPos, S pcm_r[], int pcm_rPos, MP3Data mp3data, - Enc enc, T[] p, int psize, - IDecoder decodeMP3_ptr, Factory<T> tFactory) { - - int processed_samples; /* processed samples per channel */ - int ret; - - mp3data.header_parsed = false; - - ProcessedBytes pb = new ProcessedBytes(); - ret = decodeMP3_ptr.decode(pmp, buffer, bufferPos, len, p, psize, pb, tFactory); - processed_samples = pb.pb; - /* three cases: - * 1. headers parsed, but data not complete - * pmp.header_parsed==1 - * pmp.framesize=0 - * pmp.fsizeold=size of last frame, or 0 if this is first frame - * - * 2. headers, data parsed, but ancillary data not complete - * pmp.header_parsed==1 - * pmp.framesize=size of frame - * pmp.fsizeold=size of last frame, or 0 if this is first frame - * - * 3. frame fully decoded: - * pmp.header_parsed==0 - * pmp.framesize=0 - * pmp.fsizeold=size of frame (which is now the last frame) - * - */ - if (pmp.header_parsed || pmp.fsizeold > 0 || pmp.framesize > 0) { - mp3data.header_parsed = true; - mp3data.stereo = pmp.fr.stereo; - mp3data.samplerate = Common.freqs[pmp.fr.sampling_frequency]; - mp3data.mode = pmp.fr.mode; - mp3data.mode_ext = pmp.fr.mode_ext; - mp3data.framesize = smpls[pmp.fr.lsf][pmp.fr.lay]; - - /* free format, we need the entire frame before we can determine - * the bitrate. If we haven't gotten the entire frame, bitrate=0 */ - if (pmp.fsizeold > 0) /* works for free format and fixed, no overrun, temporal results are < 400.e6 */ - mp3data.bitrate = (int) (8 * (4 + pmp.fsizeold) * mp3data.samplerate / - (1.e3 * mp3data.framesize) + 0.5); - else if (pmp.framesize > 0) - mp3data.bitrate = (int) (8 * (4 + pmp.framesize) * mp3data.samplerate / - (1.e3 * mp3data.framesize) + 0.5); - else - mp3data.bitrate = Common.tabsel_123[pmp.fr.lsf][pmp.fr.lay - 1][pmp.fr.bitrate_index]; - - - - if (pmp.num_frames > 0) { - /* Xing VBR header found and num_frames was set */ - mp3data.totalframes = pmp.num_frames; - mp3data.nsamp = mp3data.framesize * pmp.num_frames; - enc.enc_delay = pmp.enc_delay; - enc.enc_padding = pmp.enc_padding; - } - } - - switch (ret) { - case MP3_OK: - switch (pmp.fr.stereo) { - case 1: - COPY_MONO(pcm_l, pcm_lPos, processed_samples, p); - break; - case 2: - processed_samples = (processed_samples) >> 1; - COPY_STEREO(pcm_l, pcm_lPos, pcm_r, pcm_rPos,processed_samples, p); - break; - default: - processed_samples = -1; - assert(false); - break; - } - break; - - case MP3_NEED_MORE: - processed_samples = 0; - break; - - case MP3_ERR: - processed_samples = -1; - break; - - default: - processed_samples = -1; - assert(false); - break; - } - - /*fprintf(stderr,"ok, more, err: %i %i %i\n", MP3_OK, MP3_NEED_MORE, MP3_ERR ); */ - /*fprintf(stderr,"ret = %i out=%i\n", ret, processed_samples ); */ - return processed_samples; - } - - private static final int OUTSIZE_CLIPPED = 4096; - - public mpstr_tag hip_decode_init() - { - return interf.InitMP3(); - } - - - public int hip_decode_exit(mpstr_tag hip) - { - if (hip!=null) { - interf.ExitMP3(hip); - hip = null; - } - return 0; - } - - /* we forbid input with more than 1152 samples per channel for output in the unclipped mode */ - private final static int OUTSIZE_UNCLIPPED = 1152*2; - - /* - * same as hip_decode1 (look in lame.h), but returns unclipped raw - * floating-point samples. It is declared here, not in lame.h, because it - * returns LAME's internal type sample_t. No more than 1152 samples per - * channel are allowed. - */ - public int hip_decode1_unclipped(mpstr_tag hip, byte[] buffer, int bufferPos, - int len, final float pcm_l[], final float pcm_r[]) { - - MP3Data mp3data = new MP3Data(); - Enc enc = new Enc(); - - if (hip != null) { - IDecoder dec = new IDecoder() { - - @Override - public <X>int decode(mpstr_tag mp, byte[] in, int bufferPos, int isize, - X[] out, int osize, ProcessedBytes done, Factory<X> tFactory) { - return interf.decodeMP3_unclipped(mp, in, bufferPos, isize, out, osize, done, tFactory); - } - }; - Float[] out = new Float[OUTSIZE_UNCLIPPED]; - Factory<Float> tFactory = new Factory<Float>() { - - @Override - public Float create(float x) { - return Float.valueOf(x); - } - }; - // XXX should we avoid the primitive type version? - Float[] pcmL = new Float[pcm_l.length]; - for (int i = 0; i < pcmL.length; i++) { - pcmL[i] = Float.valueOf(pcm_l[i]); - } - Float[] pcmR = new Float[pcm_r.length]; - for (int i = 0; i < pcmR.length; i++) { - pcmR[i] = Float.valueOf(pcm_r[i]); - } - int decode1_headersB_clipchoice = decode1_headersB_clipchoice(hip, buffer, bufferPos, len, - pcmL, 0, pcmR, 0, mp3data, enc, out, OUTSIZE_UNCLIPPED, dec, tFactory ); - for (int i = 0; i < pcmL.length; i++) { - pcm_l[i] = pcmL[i]; - } - for (int i = 0; i < pcmR.length; i++) { - pcm_r[i] = pcmR[i]; - } - return decode1_headersB_clipchoice; - } - return 0; - } - - /* - * For lame_decode: return code - * -1 error - * 0 ok, but need more data before outputing any samples - * n number of samples output. Will be at most one frame of - * MPEG data. - */ - public int - hip_decode1_headers(mpstr_tag hip, byte[]buffer, - int len, short pcm_l[], short pcm_r[], MP3Data mp3data) - { - Enc enc = new Enc(); - return hip_decode1_headersB(hip, buffer, len, pcm_l, pcm_r, mp3data, enc); - } - - public int - hip_decode1_headersB(mpstr_tag hip, byte[] buffer, - int len, - final short pcm_l[], final short pcm_r[], MP3Data mp3data, - Enc enc) - { - if (hip!=null) { - IDecoder dec = new IDecoder() { - - @Override - public <X>int decode(mpstr_tag mp, byte[] in, int bufferPos, int isize, - X[] out, int osize, ProcessedBytes done, Factory<X> tFactory) { - return interf.decodeMP3(mp, in, bufferPos, isize, out, osize, done, tFactory); - } - }; - Short[] out = new Short[OUTSIZE_CLIPPED]; - Factory<Short> tFactory = new Factory<Short>() { - - @Override - public Short create(float x) { - return Short.valueOf((short)x); - } - }; - // XXX should we avoid the primitive type version? - Short[] pcmL = new Short[pcm_l.length]; - for (int i = 0; i < pcmL.length; i++) { - pcmL[i] = Short.valueOf(pcm_l[i]); - } - Short[] pcmR = new Short[pcm_r.length]; - for (int i = 0; i < pcmR.length; i++) { - pcmR[i] = Short.valueOf(pcm_r[i]); - } - int decode1_headersB_clipchoice = decode1_headersB_clipchoice(hip, buffer, 0, len, pcmL, 0, pcmR, 0, mp3data, - enc, out, OUTSIZE_CLIPPED, - dec, tFactory ); - for (int i = 0; i < pcmL.length; i++) { - pcm_l[i] = pcmL[i]; - } - for (int i = 0; i < pcmR.length; i++) { - pcm_r[i] = pcmR[i]; - } - return decode1_headersB_clipchoice; - } - return -1; - } - - void hip_set_pinfo(mpstr_tag hip, PlottingData pinfo) - { - if (hip!=null) { - hip.pinfo = pinfo; - } - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/TabInit.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/TabInit.java deleted file mode 100644 index 65565484d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/mpg/TabInit.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * tabinit.c - * - * Copyright (C) 1999-2010 The L.A.M.E. project - * - * Initially written by Michael Hipp, see also AUTHORS and README. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -/* $Id: TabInit.java,v 1.3 2011/06/08 00:39:06 kenchis Exp $ */ - -package mpg; - -public class TabInit { - - public float decwin[]=new float[512 + 32]; - private static float cos64[]=new float[16], cos32[]=new float[8], cos16[]=new float[4], cos8[]=new float[2], cos4[]=new float[1]; - public float[] pnts[] = { cos64, cos32, cos16, cos8, cos4 }; - - private static final double dewin[] = { - 0.000000000,-0.000015259,-0.000015259,-0.000015259, - -0.000015259,-0.000015259,-0.000015259,-0.000030518, - -0.000030518,-0.000030518,-0.000030518,-0.000045776, - -0.000045776,-0.000061035,-0.000061035,-0.000076294, - -0.000076294,-0.000091553,-0.000106812,-0.000106812, - -0.000122070,-0.000137329,-0.000152588,-0.000167847, - -0.000198364,-0.000213623,-0.000244141,-0.000259399, - -0.000289917,-0.000320435,-0.000366211,-0.000396729, - -0.000442505,-0.000473022,-0.000534058,-0.000579834, - -0.000625610,-0.000686646,-0.000747681,-0.000808716, - -0.000885010,-0.000961304,-0.001037598,-0.001113892, - -0.001205444,-0.001296997,-0.001388550,-0.001480103, - -0.001586914,-0.001693726,-0.001785278,-0.001907349, - -0.002014160,-0.002120972,-0.002243042,-0.002349854, - -0.002456665,-0.002578735,-0.002685547,-0.002792358, - -0.002899170,-0.002990723,-0.003082275,-0.003173828, - -0.003250122,-0.003326416,-0.003387451,-0.003433228, - -0.003463745,-0.003479004,-0.003479004,-0.003463745, - -0.003417969,-0.003372192,-0.003280640,-0.003173828, - -0.003051758,-0.002883911,-0.002700806,-0.002487183, - -0.002227783,-0.001937866,-0.001617432,-0.001266479, - -0.000869751,-0.000442505, 0.000030518, 0.000549316, - 0.001098633, 0.001693726, 0.002334595, 0.003005981, - 0.003723145, 0.004486084, 0.005294800, 0.006118774, - 0.007003784, 0.007919312, 0.008865356, 0.009841919, - 0.010848999, 0.011886597, 0.012939453, 0.014022827, - 0.015121460, 0.016235352, 0.017349243, 0.018463135, - 0.019577026, 0.020690918, 0.021789551, 0.022857666, - 0.023910522, 0.024932861, 0.025909424, 0.026840210, - 0.027725220, 0.028533936, 0.029281616, 0.029937744, - 0.030532837, 0.031005859, 0.031387329, 0.031661987, - 0.031814575, 0.031845093, 0.031738281, 0.031478882, - 0.031082153, 0.030517578, 0.029785156, 0.028884888, - 0.027801514, 0.026535034, 0.025085449, 0.023422241, - 0.021575928, 0.019531250, 0.017257690, 0.014801025, - 0.012115479, 0.009231567, 0.006134033, 0.002822876, - -0.000686646,-0.004394531,-0.008316040,-0.012420654, - -0.016708374,-0.021179199,-0.025817871,-0.030609131, - -0.035552979,-0.040634155,-0.045837402,-0.051132202, - -0.056533813,-0.061996460,-0.067520142,-0.073059082, - -0.078628540,-0.084182739,-0.089706421,-0.095169067, - -0.100540161,-0.105819702,-0.110946655,-0.115921021, - -0.120697021,-0.125259399,-0.129562378,-0.133590698, - -0.137298584,-0.140670776,-0.143676758,-0.146255493, - -0.148422241,-0.150115967,-0.151306152,-0.151962280, - -0.152069092,-0.151596069,-0.150497437,-0.148773193, - -0.146362305,-0.143264771,-0.139450073,-0.134887695, - -0.129577637,-0.123474121,-0.116577148,-0.108856201, - -0.100311279,-0.090927124,-0.080688477,-0.069595337, - -0.057617187,-0.044784546,-0.031082153,-0.016510010, - -0.001068115, 0.015228271, 0.032379150, 0.050354004, - 0.069168091, 0.088775635, 0.109161377, 0.130310059, - 0.152206421, 0.174789429, 0.198059082, 0.221984863, - 0.246505737, 0.271591187, 0.297210693, 0.323318481, - 0.349868774, 0.376800537, 0.404083252, 0.431655884, - 0.459472656, 0.487472534, 0.515609741, 0.543823242, - 0.572036743, 0.600219727, 0.628295898, 0.656219482, - 0.683914185, 0.711318970, 0.738372803, 0.765029907, - 0.791213989, 0.816864014, 0.841949463, 0.866363525, - 0.890090942, 0.913055420, 0.935195923, 0.956481934, - 0.976852417, 0.996246338, 1.014617920, 1.031936646, - 1.048156738, 1.063217163, 1.077117920, 1.089782715, - 1.101211548, 1.111373901, 1.120223999, 1.127746582, - 1.133926392, 1.138763428, 1.142211914, 1.144287109, - 1.144989014 - }; - /* *INDENT-ON* */ - - void - make_decode_tables(long scaleval) - { - int i, j, k, kr, divv; - int table; float[] costab; - - - for (i = 0; i < 5; i++) { - kr = 0x10 >> i; - divv = 0x40 >> i; - costab = pnts[i]; - for (k = 0; k < kr; k++) - costab[k] = (float) (1.0 / (2.0 * Math.cos(MPG123.M_PI * ((double) k * 2.0 + 1.0) / (double) divv))); - } - - table = 0; - scaleval = -scaleval; - for (i = 0, j = 0; i < 256; i++, j++, table += 32) { - if (table < 512 + 16) - decwin[table+16] = decwin[table+0] = (float) (dewin[j] * scaleval); - if (i % 32 == 31) - table -= 1023; - if (i % 64 == 63) - scaleval = -scaleval; - } - - for ( /* i=256 */ ; i < 512; i++, j--, table += 32) { - if (table < 512 + 16) - decwin[table+16] = decwin[table+0] = (float) (dewin[j] * scaleval); - if (i % 32 == 31) - table -= 1023; - if (i % 64 == 63) - scaleval = -scaleval; - } - } - -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/ui/InputTableModel.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/ui/InputTableModel.java deleted file mode 100644 index 10267458e..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/ui/InputTableModel.java +++ /dev/null @@ -1,60 +0,0 @@ -package ui; - -import java.util.ArrayList; - -import javax.swing.JProgressBar; -import javax.swing.table.DefaultTableModel; - -public class InputTableModel extends DefaultTableModel { - - private static final long serialVersionUID = 1L; - private String[] COLUMN_NAMES = { "No", "Type", "File", "Progress" }; - private Class<?>[] COLUMN_CLASSES = { Integer.class, String.class, - String.class, JProgressBar.class }; - private ArrayList<JProgressBar> progresses = new ArrayList<JProgressBar>(); - - @Override - public int getColumnCount() { - return 4; - } - - @Override - public String getColumnName(int column) { - return COLUMN_NAMES[column]; - } - - @Override - public Object getValueAt(int row, int column) { - if (column == 0) { - return row + 1; - } - if (column==3) { - if (row >= progresses.size()) { - progresses.add(new JProgressBar()); - } - JProgressBar bar = progresses.get(row); - bar.setMinimum(0); - bar.setMaximum(100); - return bar; - } - return super.getValueAt(row, column); - } - - @Override - public Class<?> getColumnClass(int column) { - return COLUMN_CLASSES[column]; - } - - @Override - public void fireTableRowsDeleted(int firstRow, int lastRow) { - for (int row = firstRow; row <= lastRow; row++) { - progresses.remove(row); - } - super.fireTableRowsDeleted(firstRow, lastRow); - } - - @Override - public boolean isCellEditable(int row, int column) { - return false; - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/ui/LameUI.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/ui/LameUI.java deleted file mode 100644 index 2f255b664..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/ui/LameUI.java +++ /dev/null @@ -1,418 +0,0 @@ -package ui; - -import java.awt.Component; -import java.awt.Frame; -import java.awt.event.ActionEvent; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Locale; - -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JComponent; -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JOptionPane; -import javax.swing.JProgressBar; -import javax.swing.JRadioButton; -import javax.swing.JTable; -import javax.swing.JTextField; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; -import javax.swing.filechooser.FileFilter; -import javax.swing.table.DefaultTableModel; -import javax.swing.table.TableCellRenderer; - -import mp3.Main; - -import org.swixml.SwingEngine; - -public class LameUI extends JFrame { - private static final long serialVersionUID = 1L; - - public static class JComponentCellRenderer implements TableCellRenderer { - - public Component getTableCellRendererComponent(JTable table, - Object value, boolean isSelected, boolean hasFocus, int row, - int column) { - return (JComponent) value; - } - - } - - public static void main(String[] args) { - new LameUI(); - } - - protected Picture picture; - protected JButton doRemove, doEncodeDecode; - protected JTable files; - protected JComboBox presets, cbr, abr, vbr, algorithm; - protected JRadioButton setCBR, setABR, setVBR; - protected JRadioButton setStereo, setJointStereo, setForcedJointStereo, - setDualChannels, setMono, setAuto; - protected JRadioButton outputIsInput, customOutputDir; - protected JTextField outputDir; - protected JCheckBox overwrite; - - protected int inUse; - - protected File lastDir; - protected FileFilter musicFilter = new FileFilter() { - - @Override - public String getDescription() { - return "MUSIC (WAV, MP3)"; - } - - @Override - public boolean accept(File f) { - return f.isDirectory() - || (f.getName().toLowerCase().endsWith(".wav") || f - .getName().toLowerCase().endsWith(".mp3")); - } - }; - - public Action add = new AbstractAction() { - - private static final long serialVersionUID = 1L; - - public void actionPerformed(ActionEvent e) { - JFileChooser fileDialog = new JFileChooser(lastDir); - fileDialog.setMultiSelectionEnabled(true); - fileDialog.setFileFilter(musicFilter); - final Frame containerFrame = JOptionPane - .getFrameForComponent(LameUI.this); - int rc = fileDialog.showOpenDialog(containerFrame); - if (rc == JFileChooser.APPROVE_OPTION - && fileDialog.getSelectedFile() != null) { - lastDir = fileDialog.getSelectedFile().getParentFile(); - File[] selectedFiles = fileDialog.getSelectedFiles(); - DefaultTableModel model = (DefaultTableModel) files.getModel(); - for (int i = 0; i < selectedFiles.length; i++) { - File file = selectedFiles[i]; - String ext = file.getName().substring( - file.getName().lastIndexOf('.') + 1); - model.addRow(new Object[] { 0, ext, file.getAbsolutePath() }); - } - } - } - }; - - public Action remove = new AbstractAction() { - - private static final long serialVersionUID = 1L; - - public void actionPerformed(ActionEvent e) { - DefaultTableModel model = (DefaultTableModel) files.getModel(); - while (files.getSelectedRows().length > 0) { - model.removeRow(files.getSelectedRows()[0]); - } - } - }; - - public Action setPresets = new AbstractAction() { - - private static final long serialVersionUID = 1L; - - public void actionPerformed(ActionEvent e) { - setPresetsOrCustom(true); - } - }; - - public Action setCustom = new AbstractAction() { - - private static final long serialVersionUID = 1L; - - public void actionPerformed(ActionEvent e) { - setPresetsOrCustom(false); - } - }; - - public Action encodeDecode = new AbstractAction() { - - private static final long serialVersionUID = 1L; - - public void actionPerformed(ActionEvent e) { - DefaultTableModel model = (DefaultTableModel) files.getModel(); - for (int row = 0; row < model.getRowCount(); row++) { - final String filename = String - .valueOf(model.getValueAt(row, 2)); - final JProgressBar bar = (JProgressBar) model - .getValueAt(row, 3); - if (bar.getValue()==100) { - continue; - } - try { - final ArrayList<String> cmd = getCommand(filename); - for (int i = 0; i < cmd.size(); i++) { - System.out.print(cmd.get(i) + " "); - } - System.out.println(); - final Main main = new Main(); - main.getSupport().addPropertyChangeListener(new PropertyChangeListener() { - - public void propertyChange(final PropertyChangeEvent evt) { - if ("progress".equals(evt.getPropertyName())) { - bar.setValue(Integer.valueOf(evt.getNewValue().toString())); - SwingUtilities.invokeLater(new Runnable() { - - @Override - public void run() { - repaint(); - } - }); - } - } - }); - new Thread(new Runnable() { - - public void run() { - synchronized (LameUI.this) { - inUse++; - doRemove.setEnabled(false); - doEncodeDecode.setEnabled(false); - } - try { - System.out.println(cmd); - main.run(cmd.toArray(new String[cmd.size()])); - } catch (IOException e) { - e.printStackTrace(); - } finally { - synchronized (LameUI.this) { - inUse--; - if (inUse == 0) { - doRemove.setEnabled(true); - doEncodeDecode.setEnabled(true); - } - } - bar.setValue(100); - } - } - }).start(); - } catch (IOException e1) { - System.err.println(e1.getMessage()); - } - } - } - - }; - - public Action chooseOutputDir = new AbstractAction() { - - private static final long serialVersionUID = 1L; - - public void actionPerformed(ActionEvent e) { - JFileChooser fileDialog = new JFileChooser(lastDir); - fileDialog.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - final Frame containerFrame = JOptionPane - .getFrameForComponent(LameUI.this); - int rc = fileDialog.showOpenDialog(containerFrame); - if (rc == JFileChooser.APPROVE_OPTION - && fileDialog.getSelectedFile() != null) { - lastDir = fileDialog.getSelectedFile(); - File file = fileDialog.getSelectedFile(); - outputDir.setText(file.getAbsolutePath()); - - customOutputDir.setSelected(true); - } - } - }; - - public LameUI() { - try { - // use system L&F - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - - SwingEngine swix = new SwingEngine(this); - swix.getTaglib().registerTag("picture", Picture.class); - swix.insert(new URL("file:../conf/LameUI.xml"), this); - - presets.addItem("Medium (~160 kbps)"); - presets.addItem("Standard (~192 kbps)"); - presets.addItem("Extreme (~224 kbps)"); - presets.addItem("Insane (320 kbps)"); - presets.setSelectedItem("Standard (~192 kbps)"); - - cbr.addItem(320); - cbr.addItem(256); - cbr.addItem(224); - cbr.addItem(192); - cbr.addItem(160); - cbr.addItem(128); - cbr.addItem(112); - cbr.addItem(96); - cbr.addItem(80); - cbr.addItem(64); - cbr.addItem(56); - cbr.addItem(48); - cbr.addItem(40); - cbr.addItem(32); - cbr.setSelectedItem(192); - - vbr.addItem("0 - highest"); - vbr.addItem("1"); - vbr.addItem("2 - recommended"); - vbr.addItem("3"); - vbr.addItem("4 - default"); - vbr.addItem("5"); - vbr.addItem("6"); - vbr.addItem("7"); - vbr.addItem("8"); - vbr.addItem("9"); - vbr.setSelectedItem("2 - recommended"); - - for (int i = 310; i >= 8; i--) { - abr.addItem(i); - } - abr.setSelectedItem(192); - - algorithm.addItem("0 - highest quality, very slow"); - algorithm.addItem("1"); - algorithm.addItem("2 - recommended"); - algorithm.addItem("3"); - algorithm.addItem("4"); - algorithm.addItem("5 - LAME default"); - algorithm.addItem("6"); - algorithm.addItem("7 - Fast, ok quality"); - algorithm.addItem("8"); - algorithm.addItem("9 - Poor quality, but fast"); - algorithm.addItem("Auto"); - - files.getColumnModel().getColumn(0).setMaxWidth(50); - files.getColumnModel().getColumn(1).setMaxWidth(100); - files.getColumnModel().getColumn(3).setMaxWidth(100); - files.setDefaultRenderer(JComponent.class, new JComponentCellRenderer()); - - final URL resource =new URL("file:../images/picture.png"); - picture.setComposerImage(new ImageIcon(resource).getImage()); - - pack(); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setVisible(true); - } catch (Exception e) { - e.printStackTrace(); - } - - } - - protected void setPresetsOrCustom(boolean isPresets) { - presets.setEnabled(isPresets); - setCBR.setEnabled(!isPresets); - setABR.setEnabled(!isPresets); - setVBR.setEnabled(!isPresets); - cbr.setEnabled(!isPresets); - abr.setEnabled(!isPresets); - vbr.setEnabled(!isPresets); - } - - protected ArrayList<String> getCommand(String filename) throws IOException { - ArrayList<String> cmd = new ArrayList<String>(); - if (new File(filename).getName().toLowerCase(Locale.US) - .endsWith(".mp3")) { - cmd.add("--decode"); - } - if (presets.isEnabled()) { - // preset - String pr = String.valueOf(presets.getSelectedItem()); - cmd.add("--preset"); - cmd.add(pr.substring(0, pr.indexOf(' ')).toLowerCase(Locale.US)); - } else { - // custom - if (setVBR.isSelected()) { - // vbr - String v = String.valueOf(vbr.getSelectedItem()); - if (v.indexOf(' ') != -1) { - v = v.substring(0, v.indexOf(' ')); - } - cmd.add("-v"); - cmd.add("-V"); - cmd.add(v); - } else if (setABR.isSelected()) { - // abr - String a = String.valueOf(abr.getSelectedItem()); - cmd.add("--abr"); - cmd.add(a); - } else { - // cbr - String a = String.valueOf(cbr.getSelectedItem()); - cmd.add("--cbr"); - cmd.add("-b"); - cmd.add(a); - } - } - String eaq = String.valueOf(algorithm.getSelectedItem()); - if (!"Auto".equals(eaq)) { - if (eaq.indexOf(' ') != -1) { - eaq = eaq.substring(0, eaq.indexOf(' ')); - } - cmd.add("-q"); - cmd.add(eaq); - } - - if (setStereo.isSelected()) { - cmd.add("-m"); - cmd.add("s"); - } else if (setJointStereo.isSelected()) { - cmd.add("-m"); - cmd.add("j"); - } else if (setForcedJointStereo.isSelected()) { - cmd.add("-m"); - cmd.add("f"); - } else if (setDualChannels.isSelected()) { - cmd.add("-m"); - cmd.add("d"); - } else if (setMono.isSelected()) { - cmd.add("-m"); - cmd.add("m"); - } - - cmd.add(filename); - if (!outputIsInput.isSelected()) { - String outDir = outputDir.getText(); - if (outDir.length() == 0) { - outDir = System.getProperty("user.dir"); - } - String outName = new File(filename).getName(); - if (outName.toLowerCase(Locale.US).endsWith(".mp3")) { - outName = outName.substring(0, outName.lastIndexOf('.')) - + ".wav"; - } else { - // outName.toLowerCase(Locale.US).endsWith(".wav") - outName = outName.substring(0, outName.lastIndexOf('.')) - + ".mp3"; - } - cmd.add(new File(outDir, outName).getAbsolutePath()); - if (!overwrite.isSelected() && new File(outDir, outName).exists()) { - throw new IOException("Output file " - + new File(outDir, outName) + " already exists!"); - } - } else { - // Custom output dir - String outName = new File(filename).getName(); - if (outName.toLowerCase(Locale.US).endsWith(".mp3")) { - outName = outName.substring(0, outName.lastIndexOf('.')) - + ".wav"; - } else { - // outName.toLowerCase(Locale.US).endsWith(".wav") - outName = outName.substring(0, outName.lastIndexOf('.')) - + ".mp3"; - } - String outDir = new File(filename).getParent(); - cmd.add(new File(outDir, outName).getAbsolutePath()); - if (!overwrite.isSelected() && new File(outDir, outName).exists()) { - throw new IOException("Output file " - + new File(outDir, outName) + " already exists!"); - } - } - return cmd; - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/ui/Picture.java b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/ui/Picture.java deleted file mode 100644 index a9f70c6ff..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/java/ui/Picture.java +++ /dev/null @@ -1,63 +0,0 @@ -package ui; - -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.RenderingHints; - -import javax.swing.JComponent; - -public final class Picture extends JComponent { - - private static final long serialVersionUID = 1L; - - private Image composerImage; - - /** - * @param collection - */ - public Picture() { - } - - { - setOpaque(true); - setPreferredSize(new Dimension(200, 200)); - } - - public final void setComposerImage(Image image) { - composerImage = image; - } - - @Override - public void paint(Graphics g) { - g.setColor(getBackground()); - g.fillRect(0, 0, getWidth(), getHeight()); - if (composerImage != null) { - int picWidth = composerImage.getWidth(null); - int picHeight = composerImage.getHeight(null); - - int availableWidth = getWidth(); - int availableHeight = getHeight(); - - /* figure out which dimension limits scaling first */ - float scaleW = (float) availableWidth / picWidth; - float scaleH = (float) availableHeight / picHeight; - - float safeScale = scaleW > scaleH ? scaleH : scaleW; - picWidth *= safeScale; - picHeight *= safeScale; - - ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_INTERPOLATION, - RenderingHints.VALUE_INTERPOLATION_BICUBIC); - g.drawImage(composerImage, (availableWidth - picWidth) / 2, - (availableHeight - picHeight) / 2, picWidth, picHeight, - null); - } - } - - @Override - public void update(Graphics g) { - paint(g); - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/resources/LameUI.xml b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/resources/LameUI.xml deleted file mode 100644 index 7a55daeae..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/resources/LameUI.xml +++ /dev/null @@ -1,150 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<panel layout="BorderLayout"> - <vbox constraints="BorderLayout.CENTER"> - <panel layout="BorderLayout"> - <hbox constraints="BorderLayout.NORTH"> - <button text="Add..." action="add" /> - <button text="Remove" action="remove" id="doRemove" /> - <button text="Encode/Decode" action="encodeDecode" id="doEncodeDecode" /> - </hbox> - <tabbedpane titles="Input / Output,LAME Settings" - constraints="BorderLayout.CENTER"> - <vbox border="TitledBorder(Input files:)"> - <scrollpane> - <table initclass="ui.InputTableModel" CellSelectionEnabled="false" - ColumnSelectionAllowed="false" RowSelectionAllowed="true" id="files"></table> - </scrollpane> - <panel border="TitledBorder(Output directory:)" layout="GridLayout(3,1)"> - <buttongroup> - <radiobutton label="Output directory = Input directory" - Selected="true" id="outputIsInput"></radiobutton> - <radiobutton label="Use below:" id="customOutputDir"></radiobutton> - </buttongroup> - <panel> - <textfield columns="30" Editable="false" id="outputDir"></textfield> - <button text="Browse..." action="chooseOutputDir"></button> - </panel> - </panel> - <panel layout="GridLayout(3,1)"> - <checkbox text="Overwrite existing files" id="overwrite"></checkbox> - </panel> - </vbox> - <vbox> - <panel layout="GridLayout(4,3)"> - <buttongroup> - <radiobutton text="Presets" selected="true" action="setPresets"> - </radiobutton> - <label text="Preset:"> - </label> - <combobox id="presets"> - </combobox> - - <radiobutton text="Custom" action="setCustom"> - </radiobutton> - </buttongroup> - <buttongroup> - <radiobutton text="VBR - variable bitrate:" Selected="true" - Enabled="false" id="setVBR"> - </radiobutton> - <combobox id="vbr" Enabled="false"> - </combobox> - <label></label> - <radiobutton text="ABR - average bitrate:" Enabled="false" - id="setABR"> - </radiobutton> - <combobox MaximumRowCount="1" Enabled="false" id="abr"> - </combobox> - <label></label> - <radiobutton text="CBR - constant bitrate:" Enabled="false" - id="setCBR"> - </radiobutton> - <combobox Enabled="false" id="cbr"> - </combobox> - </buttongroup> - </panel> - <panel border="TitledBorder(Channel Mode)"> - <buttongroup> - <radiobutton text="Stereo" Selected="true" id="setStereo"></radiobutton> - <radiobutton text="Joint stereo" id="setJointStereo"></radiobutton> - <radiobutton text="Forced joint stereo" id="setForcedJointStereo"></radiobutton> - <radiobutton text="Dual channels" id="setDualChannels"></radiobutton> - <radiobutton text="Mono" id="setMono"></radiobutton> - <radiobutton text="Auto" Selected="true" id="setAuto"></radiobutton> - </buttongroup> - </panel> - <panel border="TitledBorder(Encoding algorithm quality)"> - <combobox id="algorithm"> - </combobox> - </panel> - </vbox> - </tabbedpane> - </panel> - </vbox> - <hbox constraints="BorderLayout.WEST"> - <panel border="TitledBorder(Tag Settings)"> - <vbox> - <panel layout="BorderLayout(10,10)"> - <label text="Title:" /> - </panel> - <panel layout="BorderLayout(10,10)"> - <combobox Editable="true" /> - </panel> - <panel layout="BorderLayout(10,10)"> - <label text="Interpret:"/> - </panel> - <panel layout="BorderLayout(10,10)"> - <combobox Editable="true" /> - </panel> - <panel layout="BorderLayout(10,10)"> - <label text="Album:"/> - </panel> - <panel layout="BorderLayout(10,10)"> - <combobox Editable="true" /> - </panel> - <panel layout="BorderLayout(10,10)"> - <label text="Year:"/> - </panel> - <panel layout="BorderLayout(10,10)"> - <combobox Editable="true" /> - </panel> - <panel layout="BorderLayout(10,10)"> - <label text="Track:"/> - </panel> - <panel layout="BorderLayout(10,10)"> - <combobox Editable="true" /> - </panel> - <panel layout="BorderLayout(10,10)"> - <label text="Genre:"/> - </panel> - <panel layout="BorderLayout(10,10)"> - <combobox Editable="true" /> - </panel> - <panel layout="BorderLayout(10,10)"> - <label text="Comment:"/> - </panel> - <panel layout="BorderLayout(10,10)"> - <combobox Editable="true" /> - </panel> - <panel layout="BorderLayout(10,10)"> - <label text="Album Interpret:"/> - </panel> - <panel layout="BorderLayout(10,10)"> - <combobox Editable="true" /> - </panel> - <panel layout="BorderLayout(10,10)"> - <label text="Komponist:"/> - </panel> - <panel layout="BorderLayout(10,10)"> - <combobox Editable="true" /> - </panel> - <panel layout="BorderLayout(10,10)"> - <label text="CD Number:"/> - </panel> - <panel layout="BorderLayout(10,10)"> - <combobox Editable="true" /> - </panel> - <picture id="picture" /> - </vbox> - </panel> - </hbox> -</panel> \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/resources/picture.png b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/resources/picture.png deleted file mode 100644 index ba98f66ab..000000000 Binary files a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/resources/picture.png and /dev/null differ diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/resources/run.bat b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/resources/run.bat deleted file mode 100644 index 20678e612..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/resources/run.bat +++ /dev/null @@ -1 +0,0 @@ -java -jar ../lib/jump3r-1.0.3.jar \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/resources/run.sh b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/resources/run.sh deleted file mode 100644 index d418cbf5d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/src/main/resources/run.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -java -jar ../lib/jump3r-1.0.3.jar \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/testdata/Left.wav b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/testdata/Left.wav deleted file mode 100644 index 67f9d3518..000000000 Binary files a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/testdata/Left.wav and /dev/null differ diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/testdata/Left44100.wav b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/testdata/Left44100.wav deleted file mode 100644 index e7dfc6f26..000000000 Binary files a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/testdata/Left44100.wav and /dev/null differ diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/testdata/Right.wav b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/testdata/Right.wav deleted file mode 100644 index 0fa355d33..000000000 Binary files a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/testdata/Right.wav and /dev/null differ diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/testdata/Right44100.wav b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/testdata/Right44100.wav deleted file mode 100644 index 1366b7485..000000000 Binary files a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/testdata/Right44100.wav and /dev/null differ diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/testdata/Stereo44100.wav b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/testdata/Stereo44100.wav deleted file mode 100644 index 3e158689e..000000000 Binary files a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/testdata/Stereo44100.wav and /dev/null differ diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/index.html b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/index.html deleted file mode 100644 index 076c2025a..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/index.html +++ /dev/null @@ -1,123 +0,0 @@ -<html> -<head> - <title>Lame.js Upload Example - - - - - -
-
-
-
-
- - -
- -
- -
-
- - kbit/s -
-
- -
- -
-
- -
- -
-
-
- -
-
    - -
    -
    -
    - - - - - - diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/index.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/index.js deleted file mode 100644 index f27eef2c7..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/index.js +++ /dev/null @@ -1,86 +0,0 @@ -(function (exports) { - 'use strict'; - - var MP3Converter = function (config) { - config = config || {}; - var busy = false; - var mp3Worker = new Worker('worker.js'); - - this.isBusy = function () { - return busy - }; - - this.convert = function (blob) { - var conversionId = 'conversion_' + Date.now(), - tag = conversionId + ":" - ; - var opts = []; - for(var i=1; i < arguments.length;i++){ - opts.push(arguments[i]); - } - console.log(tag, 'Starting conversion'); - var preferredConfig = {}, onSuccess, onProgress, onError; - if (typeof opts[0] == 'object') { - preferredConfig = opts.shift(); - } - - - onSuccess = opts.shift(); - onProgress = opts.shift(); - onError = opts.shift(); - - if (busy) { - throw ("Another conversion is in progress"); - } - - var initialSize = blob.size, - fileReader = new FileReader(), - startTime = Date.now(); - - fileReader.onload = function (e) { - console.log(tag, "Passed to BG process"); - mp3Worker.postMessage({ - cmd: 'init', - config: preferredConfig - }); - - mp3Worker.postMessage({cmd: 'encode', rawInput: e.target.result}); - mp3Worker.postMessage({cmd: 'finish'}); - - mp3Worker.onmessage = function (e) { - if (e.data.cmd == 'end') { - console.log(tag, "Done converting to Mp3"); - var mp3Blob = new Blob(e.data.buf, {type: 'audio/mp3'}); - console.log(tag, "Conversion completed in: " + ((Date.now() - startTime) / 1000) + 's'); - var finalSize = mp3Blob.size; - console.log(tag + - "Initial size: = " + initialSize + ", " + - "Final size = " + finalSize - + ", Reduction: " + Number((100 * (initialSize - finalSize) / initialSize)).toPrecision(4) + "%"); - - busy = false; - - if(onProgress && typeof onProgress=='function'){ - onProgress(1); - } - - if (onSuccess && typeof onSuccess === 'function') { - onSuccess(mp3Blob); - } - } else if(e.data.cmd == 'progress'){ - //post progress - if(onProgress && typeof onProgress=='function'){ - onProgress(e.data.progress); - } - } else if(e.data.cmd == 'error'){ - - } - }; - }; - busy = true; - fileReader.readAsArrayBuffer(blob); - } - }; - - exports.MP3Converter = MP3Converter; -})(window); diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/mic.html b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/mic.html deleted file mode 100644 index 836aa973b..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/mic.html +++ /dev/null @@ -1,95 +0,0 @@ - - - Lame.js Upload Example - - - - - -
    -
    -
    -
    -

    -
    - - - - -
      - -
      -
      -
      - - - - - - diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/mic.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/mic.js deleted file mode 100644 index b8679739e..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/mic.js +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Created by intelWorx on 27/10/2015. - */ -(function (exports) { - - navigator.getUserMedia = navigator.getUserMedia || - navigator.webkitGetUserMedia || - navigator.mozGetUserMedia || - navigator.msGetUserMedia; - - var MP3Recorder = function (config) { - - var recorder = this, startTime = 0, context = new AudioContext(); - config = config || {}; - var realTimeWorker = new Worker('worker-realtime.js'); - - // Initializes LAME so that we can record. - this.initialize = function () { - config.sampleRate = context.sampleRate; - realTimeWorker.postMessage({cmd: 'init', config: config}); - }; - - - // This function finalizes LAME output and saves the MP3 data to a file. - var microphone, processor; - // Function that handles getting audio out of the browser's media API. - function beginRecording(stream) { - // Set up Web Audio API to process data from the media stream (microphone). - microphone = context.createMediaStreamSource(stream); - // Settings a bufferSize of 0 instructs the browser to choose the best bufferSize - processor = context.createScriptProcessor(0, 1, 1); - // Add all buffers from LAME into an array. - processor.onaudioprocess = function (event) { - // Send microphone data to LAME for MP3 encoding while recording. - var array = event.inputBuffer.getChannelData(0); - //console.log('Buffer Received', array); - realTimeWorker.postMessage({cmd: 'encode', buf: array}) - }; - // Begin retrieving microphone data. - microphone.connect(processor); - processor.connect(context.destination); - // Return a function which will stop recording and return all MP3 data. - } - - this.stop = function () { - if (processor && microphone) { - // Clean up the Web Audio API resources. - microphone.disconnect(); - processor.disconnect(); - processor.onaudioprocess = null; - // Return the buffers array. Note that there may be more buffers pending here. - } - }; - - - // Function for kicking off recording once the button is pressed. - this.start = function (onSuccess, onError) { - // Request access to the microphone. - navigator.getUserMedia({audio: true}, function (stream) { - // Begin recording and get a function that stops the recording. - var stopRecording = beginRecording(stream); - recorder.startTime = Date.now(); - if (onSuccess && typeof onSuccess === 'function') { - onSuccess(); - } - // Run a function every 100 ms to update the UI and dispose it after 5 seconds. - }, function (error) { - if (onError && typeof onError === 'function') { - onError(error); - } - }); - }; - - - var mp3ReceiveSuccess, currentErrorCallback; - this.getMp3Blob = function (onSuccess, onError) { - currentErrorCallback = onError; - mp3ReceiveSuccess = onSuccess; - realTimeWorker.postMessage({cmd: 'finish'}); - }; - - realTimeWorker.onmessage = function (e) { - switch (e.data.cmd) { - case 'end': - if (mp3ReceiveSuccess) { - mp3ReceiveSuccess(new Blob(e.data.buf, {type: 'audio/mp3'})); - } - console.log('MP3 data size', e.data.buf.length); - break; - case 'error': - if (currentErrorCallback) { - currentErrorCallback(e.data.error); - } - break; - default : - console.log('I just received a message I know not how to handle.', e.data); - } - }; - this.initialize(); - }; - - exports.MP3Recorder = MP3Recorder; -})(window); \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/worker-realtime.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/worker-realtime.js deleted file mode 100644 index 7c754c862..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/worker-realtime.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Created by intelWorx on 27/10/2015. - */ -(function () { - 'use strict'; - - console.log('MP3 conversion worker started.'); - importScripts('../lame.min.js'); - - var mp3Encoder, maxSamples = 1152, samplesMono, config, dataBuffer; - var clearBuffer = function () { - dataBuffer = []; - }; - - var appendToBuffer = function (mp3Buf) { - dataBuffer.push(new Int8Array(mp3Buf)); - }; - - - var init = function (prefConfig) { - config = prefConfig || {debug: true}; - mp3Encoder = new lamejs.Mp3Encoder(1, config.sampleRate || 44100, config.bitRate || 123); - clearBuffer(); - }; - - var floatTo16BitPCM = function floatTo16BitPCM(input, output) { - //var offset = 0; - for (var i = 0; i < input.length; i++) { - var s = Math.max(-1, Math.min(1, input[i])); - output[i] = (s < 0 ? s * 0x8000 : s * 0x7FFF); - } - }; - - var convertBuffer = function(arrayBuffer){ - var data = new Float32Array(arrayBuffer); - var out = new Int16Array(arrayBuffer.length); - floatTo16BitPCM(data, out) - return out; - }; - - var encode = function (arrayBuffer) { - samplesMono = convertBuffer(arrayBuffer); - var remaining = samplesMono.length; - for (var i = 0; remaining >= 0; i += maxSamples) { - var left = samplesMono.subarray(i, i + maxSamples); - var mp3buf = mp3Encoder.encodeBuffer(left); - appendToBuffer(mp3buf); - remaining -= maxSamples; - } - - }; - - var finish = function () { - appendToBuffer(mp3Encoder.flush()); - self.postMessage({ - cmd: 'end', - buf: dataBuffer - }); - if (config.debug) { - console.log('Sending finished command'); - } - clearBuffer(); //free up memory - }; - - self.onmessage = function (e) { - switch (e.data.cmd) { - case 'init': - init(e.data.config); - break; - - case 'encode': - encode(e.data.buf); - break; - - case 'finish': - finish(); - break; - } - }; - -})(); diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/worker.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/worker.js deleted file mode 100644 index bdbe861ac..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs/worker-example/worker.js +++ /dev/null @@ -1,90 +0,0 @@ -(function () { - 'use strict'; - - console.log('MP3 conversion worker started.'); - importScripts('../lame.min.js'); - - var mp3Encoder, maxSamples = 1152, - wav, samplesLeft, config, dataBuffer, samplesRight; - var clearBuffer = function () { - dataBuffer = []; - }; - - var appendToBuffer = function (mp3Buf) { - dataBuffer.push(new Int8Array(mp3Buf)); - }; - - - var init = function (prefConfig) { - config = prefConfig || {}; - clearBuffer(); - }; - - var encode = function (arrayBuffer) { - wav = lamejs.WavHeader.readHeader(new DataView(arrayBuffer)); - console.log('wave:', wav); - if (!wav) { - self.postMessage({cmd: 'error', msg: 'Specified file is not a Wave file'}); - return; - } - - var dataView = new Int16Array(arrayBuffer, wav.dataOffset, wav.dataLen / 2); - samplesLeft = wav.channels === 1 ? dataView : new Int16Array(wav.dataLen / (2 * wav.channels)); - samplesRight = wav.channels === 2 ? new Int16Array(wav.dataLen / (2 * wav.channels)) : undefined; - if (wav.channels > 1) { - for (var i = 0; i < samplesLeft.length; i++) { - samplesLeft[i] = dataView[i * 2]; - samplesRight[i] = dataView[i * 2 + 1]; - } - } - - mp3Encoder = new lamejs.Mp3Encoder(wav.channels, wav.sampleRate, config.bitRate || 96); - - var remaining = samplesLeft.length; - for (var i = 0; remaining >= maxSamples; i += maxSamples) { - var left = samplesLeft.subarray(i, i + maxSamples); - var right; - if (samplesRight) { - right = samplesRight.subarray(i, i + maxSamples); - } - var mp3buf = mp3Encoder.encodeBuffer(left, right); - appendToBuffer(mp3buf); - remaining -= maxSamples; - self.postMessage({ - cmd: 'progress', - progress: (1 - remaining / samplesLeft.length) - }); - } - }; - - var finish = function () { - if (!wav) { - return; - } - var mp3buf = mp3Encoder.flush(); - appendToBuffer(mp3buf); - self.postMessage({ - cmd: 'end', - buf: dataBuffer - }); - console.log('done encoding'); - clearBuffer(); //free up memory - }; - - self.onmessage = function (e) { - switch (e.data.cmd) { - case 'init': - init(e.data.config); - break; - - case 'encode': - encode(e.data.rawInput); - break; - - case 'finish': - finish(); - break; - } - }; - -})(); \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs/libopus.wasm b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs/libopus.wasm deleted file mode 100644 index f8dbe5943..000000000 Binary files a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs/libopus.wasm and /dev/null differ diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs/libopus.wasm.fetch.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs/libopus.wasm.fetch.js deleted file mode 100644 index 01f626a77..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs/libopus.wasm.fetch.js +++ /dev/null @@ -1,3732 +0,0 @@ -import wasmUrl from './libopus.wasm'; - -const location = new URL('http://localhost'); - -let libopus; -var Module = typeof Module !== "undefined" ? Module : {}; -Module.onRuntimeInitialized = function() { - if (Module.onload) Module.onload(); - Module.loaded = true -}; -Module.locateFile = function(url) { - if (url == "libopusjs/libopus.wasm" && typeof LIBOPUS_WASM_URL !== "undefined") return LIBOPUS_WASM_URL; - else return url -}; -var moduleOverrides = {}; -var key; -for (key in Module) { - if (Module.hasOwnProperty(key)) { - moduleOverrides[key] = Module[key] - } -} -var arguments_ = []; -var thisProgram = "./this.program"; -var quit_ = function(status, toThrow) { - throw toThrow -}; -var ENVIRONMENT_IS_WEB = true; -var ENVIRONMENT_IS_WORKER = false; -var ENVIRONMENT_IS_NODE = false; -var ENVIRONMENT_IS_SHELL = false; -// ENVIRONMENT_IS_WEB = typeof window === "object"; -// ENVIRONMENT_IS_WORKER = typeof importScripts === "function"; -// ENVIRONMENT_IS_NODE = typeof process === "object" && typeof process.versions === "object" && typeof process.versions.node === "string"; -// ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; -var scriptDirectory = ""; - -function locateFile(path) { - if (Module.locateFile) { - return Module.locateFile(path, scriptDirectory) - } - return scriptDirectory + path -} -var read_, readAsync, readBinary, setWindowTitle; -var nodeFS; -var nodePath; -if (ENVIRONMENT_IS_NODE) { - if (ENVIRONMENT_IS_WORKER) { - scriptDirectory = require("path").dirname(scriptDirectory) + "/" - } else { - scriptDirectory = __dirname + "/" - } - read_ = function shell_read(filename, binary) { - throw new Error("no fs"); - // if (!nodeFS) nodeFS = require("fs"); - if (!nodePath) nodePath = require("path"); - filename = nodePath.normalize(filename); - return nodeFS.readFileSync(filename, binary ? null : "utf8") - }; - readBinary = function readBinary(filename) { - var ret = read_(filename, true); - if (!ret.buffer) { - ret = new Uint8Array(ret) - } - assert(ret.buffer); - return ret - }; - if (process.argv.length > 1) { - thisProgram = process.argv[1].replace(/\\/g, "/") - } - arguments_ = process.argv.slice(2); - // if (typeof module !== "undefined") { - // module.exports = Module - // } - process.on("uncaughtException", function(ex) { - if (!(ex instanceof ExitStatus)) { - throw ex - } - }); - process.on("unhandledRejection", abort); - quit_ = function(status) { - process.exit(status) - }; - Module.inspect = function() { - return "[Emscripten Module object]" - } -} else if (ENVIRONMENT_IS_SHELL) { - if (typeof read !== "undefined") { - read_ = function shell_read(f) { - return read(f) - } - } - readBinary = function readBinary(f) { - var data; - if (typeof readbuffer === "function") { - return new Uint8Array(readbuffer(f)) - } - data = read(f, "binary"); - assert(typeof data === "object"); - return data - }; - if (typeof scriptArgs !== "undefined") { - arguments_ = scriptArgs - } else if (typeof arguments !== "undefined") { - arguments_ = arguments - } - if (typeof quit === "function") { - quit_ = function(status) { - quit(status) - } - } - if (typeof print !== "undefined") { - if (typeof console === "undefined") console = {}; - console.log = print; - console.warn = console.error = typeof printErr !== "undefined" ? printErr : print - } -} else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { - if (ENVIRONMENT_IS_WORKER) { - scriptDirectory = location.href - } else if (globalThis.document?.currentScript) { - scriptDirectory = globalThis.document?.currentScript.src - } - if (scriptDirectory.indexOf("blob:") !== 0) { - scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf("/") + 1) - } else { - scriptDirectory = "" - } { - read_ = function shell_read(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - xhr.send(null); - return xhr.responseText - }; - if (ENVIRONMENT_IS_WORKER) { - readBinary = function readBinary(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - xhr.responseType = "arraybuffer"; - xhr.send(null); - return new Uint8Array(xhr.response) - } - } - readAsync = function readAsync(url, onload, onerror) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, true); - xhr.responseType = "arraybuffer"; - xhr.onload = function xhr_onload() { - if (xhr.status == 200 || xhr.status == 0 && xhr.response) { - onload(xhr.response); - return - } - onerror() - }; - xhr.onerror = onerror; - xhr.send(null) - } - } - setWindowTitle = function(title) { - globalThis.document && (globalThis.document.title = title); - } -} else {} -var out = Module.print || console.log.bind(console); -var err = Module.printErr || console.warn.bind(console); -for (key in moduleOverrides) { - if (moduleOverrides.hasOwnProperty(key)) { - Module[key] = moduleOverrides[key] - } -} -moduleOverrides = null; -if (Module.arguments) arguments_ = Module.arguments; -if (Module.thisProgram) thisProgram = Module.thisProgram; -if (Module.quit) quit_ = Module.quit; -var STACK_ALIGN = 16; - -function alignMemory(size, factor) { - if (!factor) factor = STACK_ALIGN; - return Math.ceil(size / factor) * factor -} -var wasmBinary; -if (Module.wasmBinary) wasmBinary = Module.wasmBinary; -var noExitRuntime; -if (Module.noExitRuntime) noExitRuntime = Module.noExitRuntime; -if (typeof WebAssembly !== "object") { - abort("no native wasm support detected") -} -var wasmMemory; -var wasmTable; -var ABORT = false; -var EXITSTATUS = 0; - -function assert(condition, text) { - if (!condition) { - abort("Assertion failed: " + text) - } -} -var UTF8Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf8") : undefined; - -function UTF8ArrayToString(heap, idx, maxBytesToRead) { - var endIdx = idx + maxBytesToRead; - var endPtr = idx; - while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr; - if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) { - return UTF8Decoder.decode(heap.subarray(idx, endPtr)) - } else { - var str = ""; - while (idx < endPtr) { - var u0 = heap[idx++]; - if (!(u0 & 128)) { - str += String.fromCharCode(u0); - continue - } - var u1 = heap[idx++] & 63; - if ((u0 & 224) == 192) { - str += String.fromCharCode((u0 & 31) << 6 | u1); - continue - } - var u2 = heap[idx++] & 63; - if ((u0 & 240) == 224) { - u0 = (u0 & 15) << 12 | u1 << 6 | u2 - } else { - u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heap[idx++] & 63 - } - if (u0 < 65536) { - str += String.fromCharCode(u0) - } else { - var ch = u0 - 65536; - str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023) - } - } - } - return str -} - -function UTF8ToString(ptr, maxBytesToRead) { - return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : "" -} - -function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) { - if (!(maxBytesToWrite > 0)) return 0; - var startIdx = outIdx; - var endIdx = outIdx + maxBytesToWrite - 1; - for (var i = 0; i < str.length; ++i) { - var u = str.charCodeAt(i); - if (u >= 55296 && u <= 57343) { - var u1 = str.charCodeAt(++i); - u = 65536 + ((u & 1023) << 10) | u1 & 1023 - } - if (u <= 127) { - if (outIdx >= endIdx) break; - heap[outIdx++] = u - } else if (u <= 2047) { - if (outIdx + 1 >= endIdx) break; - heap[outIdx++] = 192 | u >> 6; - heap[outIdx++] = 128 | u & 63 - } else if (u <= 65535) { - if (outIdx + 2 >= endIdx) break; - heap[outIdx++] = 224 | u >> 12; - heap[outIdx++] = 128 | u >> 6 & 63; - heap[outIdx++] = 128 | u & 63 - } else { - if (outIdx + 3 >= endIdx) break; - heap[outIdx++] = 240 | u >> 18; - heap[outIdx++] = 128 | u >> 12 & 63; - heap[outIdx++] = 128 | u >> 6 & 63; - heap[outIdx++] = 128 | u & 63 - } - } - heap[outIdx] = 0; - return outIdx - startIdx -} - -function stringToUTF8(str, outPtr, maxBytesToWrite) { - return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite) -} - -function lengthBytesUTF8(str) { - var len = 0; - for (var i = 0; i < str.length; ++i) { - var u = str.charCodeAt(i); - if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023; - if (u <= 127) ++len; - else if (u <= 2047) len += 2; - else if (u <= 65535) len += 3; - else len += 4 - } - return len -} - -function writeArrayToMemory(array, buffer) { - HEAP8.set(array, buffer) -} - -function writeAsciiToMemory(str, buffer, dontAddNull) { - for (var i = 0; i < str.length; ++i) { - HEAP8[buffer++ >> 0] = str.charCodeAt(i) - } - if (!dontAddNull) HEAP8[buffer >> 0] = 0 -} -var WASM_PAGE_SIZE = 65536; -var buffer, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64; - -function updateGlobalBufferAndViews(buf) { - buffer = buf; - Module.HEAP8 = HEAP8 = new Int8Array(buf); - Module.HEAP16 = HEAP16 = new Int16Array(buf); - Module.HEAP32 = HEAP32 = new Int32Array(buf); - Module.HEAPU8 = HEAPU8 = new Uint8Array(buf); - Module.HEAPU16 = HEAPU16 = new Uint16Array(buf); - Module.HEAPU32 = HEAPU32 = new Uint32Array(buf); - Module.HEAPF32 = HEAPF32 = new Float32Array(buf); - Module.HEAPF64 = HEAPF64 = new Float64Array(buf) -} -var INITIAL_INITIAL_MEMORY = Module.INITIAL_MEMORY || 16777216; -if (Module.wasmMemory) { - wasmMemory = Module.wasmMemory -} else { - wasmMemory = new WebAssembly.Memory({ - "initial": INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE, - "maximum": INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE - }) -} -if (wasmMemory) { - buffer = wasmMemory.buffer -} -INITIAL_INITIAL_MEMORY = buffer.byteLength; -updateGlobalBufferAndViews(buffer); -var __ATPRERUN__ = []; -var __ATINIT__ = []; -var __ATMAIN__ = []; -var __ATPOSTRUN__ = []; -var runtimeInitialized = false; - -function preRun() { - if (Module.preRun) { - if (typeof Module.preRun === "function") Module.preRun = [Module.preRun]; - while (Module.preRun.length) { - addOnPreRun(Module.preRun.shift()) - } - } - callRuntimeCallbacks(__ATPRERUN__) -} - -function initRuntime() { - runtimeInitialized = true; - if (!Module.noFSInit && !FS.init.initialized) FS.init(); - TTY.init(); - callRuntimeCallbacks(__ATINIT__) -} - -function preMain() { - FS.ignorePermissions = false; - callRuntimeCallbacks(__ATMAIN__) -} - -function postRun() { - if (Module.postRun) { - if (typeof Module.postRun === "function") Module.postRun = [Module.postRun]; - while (Module.postRun.length) { - addOnPostRun(Module.postRun.shift()) - } - } - callRuntimeCallbacks(__ATPOSTRUN__) -} - -function addOnPreRun(cb) { - __ATPRERUN__.unshift(cb) -} - -function addOnPostRun(cb) { - __ATPOSTRUN__.unshift(cb) -} -var runDependencies = 0; -var runDependencyWatcher = null; -var dependenciesFulfilled = null; - -function getUniqueRunDependency(id) { - return id -} - -function addRunDependency(id) { - runDependencies++; - if (Module.monitorRunDependencies) { - Module.monitorRunDependencies(runDependencies) - } -} - -function removeRunDependency(id) { - runDependencies--; - if (Module.monitorRunDependencies) { - Module.monitorRunDependencies(runDependencies) - } - if (runDependencies == 0) { - if (runDependencyWatcher !== null) { - clearInterval(runDependencyWatcher); - runDependencyWatcher = null - } - if (dependenciesFulfilled) { - var callback = dependenciesFulfilled; - dependenciesFulfilled = null; - callback() - } - } -} -Module.preloadedImages = {}; -Module.preloadedAudios = {}; - -function abort(what) { - if (Module.onAbort) { - Module.onAbort(what) - } - what += ""; - err(what); - ABORT = true; - EXITSTATUS = 1; - what = "abort(" + what + "). Build with -s ASSERTIONS=1 for more info."; - var e = new WebAssembly.RuntimeError(what); - throw e -} - -function hasPrefix(str, prefix) { - return String.prototype.startsWith ? str.startsWith(prefix) : str.indexOf(prefix) === 0 -} -var dataURIPrefix = "data:application/octet-stream;base64,"; - -function isDataURI(filename) { - return hasPrefix(filename, dataURIPrefix) -} -var fileURIPrefix = "file://"; - -function isFileURI(filename) { - return hasPrefix(filename, fileURIPrefix) -} -var wasmBinaryFile = "libopusjs/libopus.wasm"; -if (!isDataURI(wasmBinaryFile)) { - wasmBinaryFile = locateFile(wasmBinaryFile) -} - -function getBinary() { - try { - if (wasmBinary) { - return new Uint8Array(wasmBinary) - } - if (readBinary) { - return readBinary(wasmBinaryFile) - } else { - throw "both async and sync fetching of the wasm failed" - } - } catch (err) { - abort(err) - } -} - -async function getBinaryPromise() { - const res = await fetch(wasmUrl); - return WebAssembly.compileStreaming(res) - /* if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && typeof fetch === "function" && !isFileURI(wasmBinaryFile)) { - console.log('binary promise', { - wasmBinaryFile, - }); - const s = new URL(wasmBinaryFile, 'http://localhost'); - return fetch(s, { - // credentials: "same-origin" - }).then(function(response) { - if (!response.ok) { - throw "failed to load wasm binary file at '" + wasmBinaryFile + "'" - } - return response.arrayBuffer() - }).catch(function() { - return getBinary() - }) - } - return Promise.resolve().then(getBinary) */ -} - -function createWasm() { - var info = { - "a": asmLibraryArg - }; - - function receiveInstance(instance, module) { - var exports = instance.exports; - Module.asm = exports; - wasmTable = Module.asm.n; - removeRunDependency("wasm-instantiate") - } - addRunDependency("wasm-instantiate"); - - function receiveInstantiatedSource(output) { - receiveInstance(output.instance) - } - - function instantiateArrayBuffer(receiver) { - return getBinaryPromise().then(function(binary) { - return WebAssembly.instantiate(binary, info) - }).then(receiver, function(reason) { - err("failed to asynchronously prepare wasm: " + reason); - abort(reason) - }) - } - - async function instantiateAsync() { - const instance = await WebAssembly.instantiate(wasm, info); - receiveInstance(instance); - } - if (Module.instantiateWasm) { - try { - var exports = Module.instantiateWasm(info, receiveInstance); - return exports - } catch (e) { - err("Module.instantiateWasm callback failed with error: " + e); - return false - } - } - instantiateAsync(); - return {} -} -var tempDouble; -var tempI64; - -function callRuntimeCallbacks(callbacks) { - while (callbacks.length > 0) { - var callback = callbacks.shift(); - if (typeof callback === "function") { - callback(Module); - continue - } - var func = callback.func; - if (typeof func === "number") { - if (callback.arg === undefined) { - wasmTable.get(func)() - } else { - wasmTable.get(func)(callback.arg) - } - } else { - func(callback.arg === undefined ? null : callback.arg) - } - } -} - -function demangle(func) { - return func -} - -function demangleAll(text) { - var regex = /\b_Z[\w\d_]+/g; - return text.replace(regex, function(x) { - var y = demangle(x); - return x === y ? x : y + " [" + x + "]" - }) -} - -function jsStackTrace() { - var error = new Error; - if (!error.stack) { - try { - throw new Error - } catch (e) { - error = e - } - if (!error.stack) { - return "(no stack trace available)" - } - } - return error.stack.toString() -} - -function stackTrace() { - var js = jsStackTrace(); - if (Module.extraStackTrace) js += "\n" + Module.extraStackTrace(); - return demangleAll(js) -} -var ExceptionInfoAttrs = { - DESTRUCTOR_OFFSET: 0, - REFCOUNT_OFFSET: 4, - TYPE_OFFSET: 8, - CAUGHT_OFFSET: 12, - RETHROWN_OFFSET: 13, - SIZE: 16 -}; - -function ___cxa_allocate_exception(size) { - return _malloc(size + ExceptionInfoAttrs.SIZE) + ExceptionInfoAttrs.SIZE -} - -function ExceptionInfo(excPtr) { - this.excPtr = excPtr; - this.ptr = excPtr - ExceptionInfoAttrs.SIZE; - this.set_type = function(type) { - HEAP32[this.ptr + ExceptionInfoAttrs.TYPE_OFFSET >> 2] = type - }; - this.get_type = function() { - return HEAP32[this.ptr + ExceptionInfoAttrs.TYPE_OFFSET >> 2] - }; - this.set_destructor = function(destructor) { - HEAP32[this.ptr + ExceptionInfoAttrs.DESTRUCTOR_OFFSET >> 2] = destructor - }; - this.get_destructor = function() { - return HEAP32[this.ptr + ExceptionInfoAttrs.DESTRUCTOR_OFFSET >> 2] - }; - this.set_refcount = function(refcount) { - HEAP32[this.ptr + ExceptionInfoAttrs.REFCOUNT_OFFSET >> 2] = refcount - }; - this.set_caught = function(caught) { - caught = caught ? 1 : 0; - HEAP8[this.ptr + ExceptionInfoAttrs.CAUGHT_OFFSET >> 0] = caught - }; - this.get_caught = function() { - return HEAP8[this.ptr + ExceptionInfoAttrs.CAUGHT_OFFSET >> 0] != 0 - }; - this.set_rethrown = function(rethrown) { - rethrown = rethrown ? 1 : 0; - HEAP8[this.ptr + ExceptionInfoAttrs.RETHROWN_OFFSET >> 0] = rethrown - }; - this.get_rethrown = function() { - return HEAP8[this.ptr + ExceptionInfoAttrs.RETHROWN_OFFSET >> 0] != 0 - }; - this.init = function(type, destructor) { - this.set_type(type); - this.set_destructor(destructor); - this.set_refcount(0); - this.set_caught(false); - this.set_rethrown(false) - }; - this.add_ref = function() { - var value = HEAP32[this.ptr + ExceptionInfoAttrs.REFCOUNT_OFFSET >> 2]; - HEAP32[this.ptr + ExceptionInfoAttrs.REFCOUNT_OFFSET >> 2] = value + 1 - }; - this.release_ref = function() { - var prev = HEAP32[this.ptr + ExceptionInfoAttrs.REFCOUNT_OFFSET >> 2]; - HEAP32[this.ptr + ExceptionInfoAttrs.REFCOUNT_OFFSET >> 2] = prev - 1; - return prev === 1 - } -} -var exceptionLast = 0; - -function __ZSt18uncaught_exceptionv() { - return __ZSt18uncaught_exceptionv.uncaught_exceptions > 0 -} - -function ___cxa_throw(ptr, type, destructor) { - var info = new ExceptionInfo(ptr); - info.init(type, destructor); - exceptionLast = ptr; - if (!("uncaught_exception" in __ZSt18uncaught_exceptionv)) { - __ZSt18uncaught_exceptionv.uncaught_exceptions = 1 - } else { - __ZSt18uncaught_exceptionv.uncaught_exceptions++ - } - throw ptr -} - -function _abort() { - abort() -} - -function _emscripten_memcpy_big(dest, src, num) { - HEAPU8.copyWithin(dest, src, src + num) -} - -function abortOnCannotGrowMemory(requestedSize) { - abort("OOM") -} - -function _emscripten_resize_heap(requestedSize) { - requestedSize = requestedSize >>> 0; - abortOnCannotGrowMemory(requestedSize) -} -var ENV = {}; - -function getExecutableName() { - return thisProgram || "./this.program" -} - -function getEnvStrings() { - if (!getEnvStrings.strings) { - var lang = (typeof navigator === "object" && navigator.languages && navigator.languages[0] || "C").replace("-", "_") + ".UTF-8"; - var env = { - "USER": "web_user", - "LOGNAME": "web_user", - "PATH": "/", - "PWD": "/", - "HOME": "/home/web_user", - "LANG": lang, - "_": getExecutableName() - }; - for (var x in ENV) { - env[x] = ENV[x] - } - var strings = []; - for (var x in env) { - strings.push(x + "=" + env[x]) - } - getEnvStrings.strings = strings - } - return getEnvStrings.strings -} - -function _environ_get(__environ, environ_buf) { - var bufSize = 0; - getEnvStrings().forEach(function(string, i) { - var ptr = environ_buf + bufSize; - HEAP32[__environ + i * 4 >> 2] = ptr; - writeAsciiToMemory(string, ptr); - bufSize += string.length + 1 - }); - return 0 -} - -function _environ_sizes_get(penviron_count, penviron_buf_size) { - var strings = getEnvStrings(); - HEAP32[penviron_count >> 2] = strings.length; - var bufSize = 0; - strings.forEach(function(string) { - bufSize += string.length + 1 - }); - HEAP32[penviron_buf_size >> 2] = bufSize; - return 0 -} -var PATH = { - splitPath: function(filename) { - var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; - return splitPathRe.exec(filename).slice(1) - }, - normalizeArray: function(parts, allowAboveRoot) { - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === ".") { - parts.splice(i, 1) - } else if (last === "..") { - parts.splice(i, 1); - up++ - } else if (up) { - parts.splice(i, 1); - up-- - } - } - if (allowAboveRoot) { - for (; up; up--) { - parts.unshift("..") - } - } - return parts - }, - normalize: function(path) { - var isAbsolute = path.charAt(0) === "/"; - var trailingSlash = path.substr(-1) === "/"; - path = PATH.normalizeArray(path.split("/").filter(function(p) { - return !!p - }), !isAbsolute).join("/"); - if (!path && !isAbsolute) { - path = "." - } - if (path && trailingSlash) { - path += "/" - } - return (isAbsolute ? "/" : "") + path - }, - dirname: function(path) { - var result = PATH.splitPath(path); - var root = result[0]; - var dir = result[1]; - if (!root && !dir) { - return "." - } - if (dir) { - dir = dir.substr(0, dir.length - 1) - } - return root + dir - }, - basename: function(path) { - if (path === "/") return "/"; - path = PATH.normalize(path); - path = path.replace(/\/$/, ""); - var lastSlash = path.lastIndexOf("/"); - if (lastSlash === -1) return path; - return path.substr(lastSlash + 1) - }, - extname: function(path) { - return PATH.splitPath(path)[3] - }, - join: function() { - var paths = Array.prototype.slice.call(arguments, 0); - return PATH.normalize(paths.join("/")) - }, - join2: function(l, r) { - return PATH.normalize(l + "/" + r) - } -}; - -function setErrNo(value) { - HEAP32[___errno_location() >> 2] = value; - return value -} - -function getRandomDevice() { - if (typeof crypto === "object" && typeof crypto.getRandomValues === "function") { - var randomBuffer = new Uint8Array(1); - return function() { - crypto.getRandomValues(randomBuffer); - return randomBuffer[0] - } - } else if (ENVIRONMENT_IS_NODE) { - try { - var crypto_module = require("crypto"); - return function() { - return crypto_module.randomBytes(1)[0] - } - } catch (e) {} - } - return function() { - abort("randomDevice") - } -} -var PATH_FS = { - resolve: function() { - var resolvedPath = ""; - var resolvedAbsolute = false; - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = i >= 0 ? arguments[i] : FS.cwd(); - if (typeof path !== "string") { - throw new TypeError("Arguments to path.resolve must be strings") - } else if (!path) { - return "" - } - resolvedPath = path + "/" + resolvedPath; - resolvedAbsolute = path.charAt(0) === "/" - } - resolvedPath = PATH.normalizeArray(resolvedPath.split("/").filter(function(p) { - return !!p - }), !resolvedAbsolute).join("/"); - return (resolvedAbsolute ? "/" : "") + resolvedPath || "." - }, - relative: function(from, to) { - from = PATH_FS.resolve(from).substr(1); - to = PATH_FS.resolve(to).substr(1); - - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== "") break - } - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== "") break - } - if (start > end) return []; - return arr.slice(start, end - start + 1) - } - var fromParts = trim(from.split("/")); - var toParts = trim(to.split("/")); - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break - } - } - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push("..") - } - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - return outputParts.join("/") - } -}; -var TTY = { - ttys: [], - init: function() {}, - shutdown: function() {}, - register: function(dev, ops) { - TTY.ttys[dev] = { - input: [], - output: [], - ops: ops - }; - FS.registerDevice(dev, TTY.stream_ops) - }, - stream_ops: { - open: function(stream) { - var tty = TTY.ttys[stream.node.rdev]; - if (!tty) { - throw new FS.ErrnoError(43) - } - stream.tty = tty; - stream.seekable = false - }, - close: function(stream) { - stream.tty.ops.flush(stream.tty) - }, - flush: function(stream) { - stream.tty.ops.flush(stream.tty) - }, - read: function(stream, buffer, offset, length, pos) { - if (!stream.tty || !stream.tty.ops.get_char) { - throw new FS.ErrnoError(60) - } - var bytesRead = 0; - for (var i = 0; i < length; i++) { - var result; - try { - result = stream.tty.ops.get_char(stream.tty) - } catch (e) { - throw new FS.ErrnoError(29) - } - if (result === undefined && bytesRead === 0) { - throw new FS.ErrnoError(6) - } - if (result === null || result === undefined) break; - bytesRead++; - buffer[offset + i] = result - } - if (bytesRead) { - stream.node.timestamp = Date.now() - } - return bytesRead - }, - write: function(stream, buffer, offset, length, pos) { - if (!stream.tty || !stream.tty.ops.put_char) { - throw new FS.ErrnoError(60) - } - try { - for (var i = 0; i < length; i++) { - stream.tty.ops.put_char(stream.tty, buffer[offset + i]) - } - } catch (e) { - throw new FS.ErrnoError(29) - } - if (length) { - stream.node.timestamp = Date.now() - } - return i - } - }, - default_tty_ops: { - get_char: function(tty) { - if (!tty.input.length) { - var result = null; - if (ENVIRONMENT_IS_NODE) { - var BUFSIZE = 256; - var buf = Buffer.alloc ? Buffer.alloc(BUFSIZE) : new Buffer(BUFSIZE); - var bytesRead = 0; - try { - bytesRead = nodeFS.readSync(process.stdin.fd, buf, 0, BUFSIZE, null) - } catch (e) { - if (e.toString().indexOf("EOF") != -1) bytesRead = 0; - else throw e - } - if (bytesRead > 0) { - result = buf.slice(0, bytesRead).toString("utf-8") - } else { - result = null - } - } else if (typeof window !== "undefined" && typeof window.prompt === "function") { - result = window.prompt("Input: "); - if (result !== null) { - result += "\n" - } - } else if (typeof readline === "function") { - result = readline(); - if (result !== null) { - result += "\n" - } - } - if (!result) { - return null - } - tty.input = intArrayFromString(result, true) - } - return tty.input.shift() - }, - put_char: function(tty, val) { - if (val === null || val === 10) { - out(UTF8ArrayToString(tty.output, 0)); - tty.output = [] - } else { - if (val != 0) tty.output.push(val) - } - }, - flush: function(tty) { - if (tty.output && tty.output.length > 0) { - out(UTF8ArrayToString(tty.output, 0)); - tty.output = [] - } - } - }, - default_tty1_ops: { - put_char: function(tty, val) { - if (val === null || val === 10) { - err(UTF8ArrayToString(tty.output, 0)); - tty.output = [] - } else { - if (val != 0) tty.output.push(val) - } - }, - flush: function(tty) { - if (tty.output && tty.output.length > 0) { - err(UTF8ArrayToString(tty.output, 0)); - tty.output = [] - } - } - } -}; - -function mmapAlloc(size) { - var alignedSize = alignMemory(size, 16384); - var ptr = _malloc(alignedSize); - while (size < alignedSize) HEAP8[ptr + size++] = 0; - return ptr -} -var MEMFS = { - ops_table: null, - mount: function(mount) { - return MEMFS.createNode(null, "/", 16384 | 511, 0) - }, - createNode: function(parent, name, mode, dev) { - if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { - throw new FS.ErrnoError(63) - } - if (!MEMFS.ops_table) { - MEMFS.ops_table = { - dir: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr, - lookup: MEMFS.node_ops.lookup, - mknod: MEMFS.node_ops.mknod, - rename: MEMFS.node_ops.rename, - unlink: MEMFS.node_ops.unlink, - rmdir: MEMFS.node_ops.rmdir, - readdir: MEMFS.node_ops.readdir, - symlink: MEMFS.node_ops.symlink - }, - stream: { - llseek: MEMFS.stream_ops.llseek - } - }, - file: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr - }, - stream: { - llseek: MEMFS.stream_ops.llseek, - read: MEMFS.stream_ops.read, - write: MEMFS.stream_ops.write, - allocate: MEMFS.stream_ops.allocate, - mmap: MEMFS.stream_ops.mmap, - msync: MEMFS.stream_ops.msync - } - }, - link: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr, - readlink: MEMFS.node_ops.readlink - }, - stream: {} - }, - chrdev: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr - }, - stream: FS.chrdev_stream_ops - } - } - } - var node = FS.createNode(parent, name, mode, dev); - if (FS.isDir(node.mode)) { - node.node_ops = MEMFS.ops_table.dir.node; - node.stream_ops = MEMFS.ops_table.dir.stream; - node.contents = {} - } else if (FS.isFile(node.mode)) { - node.node_ops = MEMFS.ops_table.file.node; - node.stream_ops = MEMFS.ops_table.file.stream; - node.usedBytes = 0; - node.contents = null - } else if (FS.isLink(node.mode)) { - node.node_ops = MEMFS.ops_table.link.node; - node.stream_ops = MEMFS.ops_table.link.stream - } else if (FS.isChrdev(node.mode)) { - node.node_ops = MEMFS.ops_table.chrdev.node; - node.stream_ops = MEMFS.ops_table.chrdev.stream - } - node.timestamp = Date.now(); - if (parent) { - parent.contents[name] = node - } - return node - }, - getFileDataAsRegularArray: function(node) { - if (node.contents && node.contents.subarray) { - var arr = []; - for (var i = 0; i < node.usedBytes; ++i) arr.push(node.contents[i]); - return arr - } - return node.contents - }, - getFileDataAsTypedArray: function(node) { - if (!node.contents) return new Uint8Array(0); - if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); - return new Uint8Array(node.contents) - }, - expandFileStorage: function(node, newCapacity) { - var prevCapacity = node.contents ? node.contents.length : 0; - if (prevCapacity >= newCapacity) return; - var CAPACITY_DOUBLING_MAX = 1024 * 1024; - newCapacity = Math.max(newCapacity, prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125) >>> 0); - if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); - var oldContents = node.contents; - node.contents = new Uint8Array(newCapacity); - if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); - }, - resizeFileStorage: function(node, newSize) { - if (node.usedBytes == newSize) return; - if (newSize == 0) { - node.contents = null; - node.usedBytes = 0; - return - } - if (!node.contents || node.contents.subarray) { - var oldContents = node.contents; - node.contents = new Uint8Array(newSize); - if (oldContents) { - node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))) - } - node.usedBytes = newSize; - return - } - if (!node.contents) node.contents = []; - if (node.contents.length > newSize) node.contents.length = newSize; - else - while (node.contents.length < newSize) node.contents.push(0); - node.usedBytes = newSize - }, - node_ops: { - getattr: function(node) { - var attr = {}; - attr.dev = FS.isChrdev(node.mode) ? node.id : 1; - attr.ino = node.id; - attr.mode = node.mode; - attr.nlink = 1; - attr.uid = 0; - attr.gid = 0; - attr.rdev = node.rdev; - if (FS.isDir(node.mode)) { - attr.size = 4096 - } else if (FS.isFile(node.mode)) { - attr.size = node.usedBytes - } else if (FS.isLink(node.mode)) { - attr.size = node.link.length - } else { - attr.size = 0 - } - attr.atime = new Date(node.timestamp); - attr.mtime = new Date(node.timestamp); - attr.ctime = new Date(node.timestamp); - attr.blksize = 4096; - attr.blocks = Math.ceil(attr.size / attr.blksize); - return attr - }, - setattr: function(node, attr) { - if (attr.mode !== undefined) { - node.mode = attr.mode - } - if (attr.timestamp !== undefined) { - node.timestamp = attr.timestamp - } - if (attr.size !== undefined) { - MEMFS.resizeFileStorage(node, attr.size) - } - }, - lookup: function(parent, name) { - throw FS.genericErrors[44] - }, - mknod: function(parent, name, mode, dev) { - return MEMFS.createNode(parent, name, mode, dev) - }, - rename: function(old_node, new_dir, new_name) { - if (FS.isDir(old_node.mode)) { - var new_node; - try { - new_node = FS.lookupNode(new_dir, new_name) - } catch (e) {} - if (new_node) { - for (var i in new_node.contents) { - throw new FS.ErrnoError(55) - } - } - } - delete old_node.parent.contents[old_node.name]; - old_node.name = new_name; - new_dir.contents[new_name] = old_node; - old_node.parent = new_dir - }, - unlink: function(parent, name) { - delete parent.contents[name] - }, - rmdir: function(parent, name) { - var node = FS.lookupNode(parent, name); - for (var i in node.contents) { - throw new FS.ErrnoError(55) - } - delete parent.contents[name] - }, - readdir: function(node) { - var entries = [".", ".."]; - for (var key in node.contents) { - if (!node.contents.hasOwnProperty(key)) { - continue - } - entries.push(key) - } - return entries - }, - symlink: function(parent, newname, oldpath) { - var node = MEMFS.createNode(parent, newname, 511 | 40960, 0); - node.link = oldpath; - return node - }, - readlink: function(node) { - if (!FS.isLink(node.mode)) { - throw new FS.ErrnoError(28) - } - return node.link - } - }, - stream_ops: { - read: function(stream, buffer, offset, length, position) { - var contents = stream.node.contents; - if (position >= stream.node.usedBytes) return 0; - var size = Math.min(stream.node.usedBytes - position, length); - if (size > 8 && contents.subarray) { - buffer.set(contents.subarray(position, position + size), offset) - } else { - for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i] - } - return size - }, - write: function(stream, buffer, offset, length, position, canOwn) { - if (!length) return 0; - var node = stream.node; - node.timestamp = Date.now(); - if (buffer.subarray && (!node.contents || node.contents.subarray)) { - if (canOwn) { - node.contents = buffer.subarray(offset, offset + length); - node.usedBytes = length; - return length - } else if (node.usedBytes === 0 && position === 0) { - node.contents = buffer.slice(offset, offset + length); - node.usedBytes = length; - return length - } else if (position + length <= node.usedBytes) { - node.contents.set(buffer.subarray(offset, offset + length), position); - return length - } - } - MEMFS.expandFileStorage(node, position + length); - if (node.contents.subarray && buffer.subarray) { - node.contents.set(buffer.subarray(offset, offset + length), position) - } else { - for (var i = 0; i < length; i++) { - node.contents[position + i] = buffer[offset + i] - } - } - node.usedBytes = Math.max(node.usedBytes, position + length); - return length - }, - llseek: function(stream, offset, whence) { - var position = offset; - if (whence === 1) { - position += stream.position - } else if (whence === 2) { - if (FS.isFile(stream.node.mode)) { - position += stream.node.usedBytes - } - } - if (position < 0) { - throw new FS.ErrnoError(28) - } - return position - }, - allocate: function(stream, offset, length) { - MEMFS.expandFileStorage(stream.node, offset + length); - stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length) - }, - mmap: function(stream, address, length, position, prot, flags) { - assert(address === 0); - if (!FS.isFile(stream.node.mode)) { - throw new FS.ErrnoError(43) - } - var ptr; - var allocated; - var contents = stream.node.contents; - if (!(flags & 2) && contents.buffer === buffer) { - allocated = false; - ptr = contents.byteOffset - } else { - if (position > 0 || position + length < contents.length) { - if (contents.subarray) { - contents = contents.subarray(position, position + length) - } else { - contents = Array.prototype.slice.call(contents, position, position + length) - } - } - allocated = true; - ptr = mmapAlloc(length); - if (!ptr) { - throw new FS.ErrnoError(48) - } - HEAP8.set(contents, ptr) - } - return { - ptr: ptr, - allocated: allocated - } - }, - msync: function(stream, buffer, offset, length, mmapFlags) { - if (!FS.isFile(stream.node.mode)) { - throw new FS.ErrnoError(43) - } - if (mmapFlags & 2) { - return 0 - } - var bytesWritten = MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false); - return 0 - } - } -}; -var FS = { - root: null, - mounts: [], - devices: {}, - streams: [], - nextInode: 1, - nameTable: null, - currentPath: "/", - initialized: false, - ignorePermissions: true, - trackingDelegate: {}, - tracking: { - openFlags: { - READ: 1, - WRITE: 2 - } - }, - ErrnoError: null, - genericErrors: {}, - filesystems: null, - syncFSRequests: 0, - handleFSError: function(e) { - if (!(e instanceof FS.ErrnoError)) throw e + " : " + stackTrace(); - return setErrNo(e.errno) - }, - lookupPath: function(path, opts) { - path = PATH_FS.resolve(FS.cwd(), path); - opts = opts || {}; - if (!path) return { - path: "", - node: null - }; - var defaults = { - follow_mount: true, - recurse_count: 0 - }; - for (var key in defaults) { - if (opts[key] === undefined) { - opts[key] = defaults[key] - } - } - if (opts.recurse_count > 8) { - throw new FS.ErrnoError(32) - } - var parts = PATH.normalizeArray(path.split("/").filter(function(p) { - return !!p - }), false); - var current = FS.root; - var current_path = "/"; - for (var i = 0; i < parts.length; i++) { - var islast = i === parts.length - 1; - if (islast && opts.parent) { - break - } - current = FS.lookupNode(current, parts[i]); - current_path = PATH.join2(current_path, parts[i]); - if (FS.isMountpoint(current)) { - if (!islast || islast && opts.follow_mount) { - current = current.mounted.root - } - } - if (!islast || opts.follow) { - var count = 0; - while (FS.isLink(current.mode)) { - var link = FS.readlink(current_path); - current_path = PATH_FS.resolve(PATH.dirname(current_path), link); - var lookup = FS.lookupPath(current_path, { - recurse_count: opts.recurse_count - }); - current = lookup.node; - if (count++ > 40) { - throw new FS.ErrnoError(32) - } - } - } - } - return { - path: current_path, - node: current - } - }, - getPath: function(node) { - var path; - while (true) { - if (FS.isRoot(node)) { - var mount = node.mount.mountpoint; - if (!path) return mount; - return mount[mount.length - 1] !== "/" ? mount + "/" + path : mount + path - } - path = path ? node.name + "/" + path : node.name; - node = node.parent - } - }, - hashName: function(parentid, name) { - var hash = 0; - for (var i = 0; i < name.length; i++) { - hash = (hash << 5) - hash + name.charCodeAt(i) | 0 - } - return (parentid + hash >>> 0) % FS.nameTable.length - }, - hashAddNode: function(node) { - var hash = FS.hashName(node.parent.id, node.name); - node.name_next = FS.nameTable[hash]; - FS.nameTable[hash] = node - }, - hashRemoveNode: function(node) { - var hash = FS.hashName(node.parent.id, node.name); - if (FS.nameTable[hash] === node) { - FS.nameTable[hash] = node.name_next - } else { - var current = FS.nameTable[hash]; - while (current) { - if (current.name_next === node) { - current.name_next = node.name_next; - break - } - current = current.name_next - } - } - }, - lookupNode: function(parent, name) { - var errCode = FS.mayLookup(parent); - if (errCode) { - throw new FS.ErrnoError(errCode, parent) - } - var hash = FS.hashName(parent.id, name); - for (var node = FS.nameTable[hash]; node; node = node.name_next) { - var nodeName = node.name; - if (node.parent.id === parent.id && nodeName === name) { - return node - } - } - return FS.lookup(parent, name) - }, - createNode: function(parent, name, mode, rdev) { - var node = new FS.FSNode(parent, name, mode, rdev); - FS.hashAddNode(node); - return node - }, - destroyNode: function(node) { - FS.hashRemoveNode(node) - }, - isRoot: function(node) { - return node === node.parent - }, - isMountpoint: function(node) { - return !!node.mounted - }, - isFile: function(mode) { - return (mode & 61440) === 32768 - }, - isDir: function(mode) { - return (mode & 61440) === 16384 - }, - isLink: function(mode) { - return (mode & 61440) === 40960 - }, - isChrdev: function(mode) { - return (mode & 61440) === 8192 - }, - isBlkdev: function(mode) { - return (mode & 61440) === 24576 - }, - isFIFO: function(mode) { - return (mode & 61440) === 4096 - }, - isSocket: function(mode) { - return (mode & 49152) === 49152 - }, - flagModes: { - "r": 0, - "rs": 1052672, - "r+": 2, - "w": 577, - "wx": 705, - "xw": 705, - "w+": 578, - "wx+": 706, - "xw+": 706, - "a": 1089, - "ax": 1217, - "xa": 1217, - "a+": 1090, - "ax+": 1218, - "xa+": 1218 - }, - modeStringToFlags: function(str) { - var flags = FS.flagModes[str]; - if (typeof flags === "undefined") { - throw new Error("Unknown file open mode: " + str) - } - return flags - }, - flagsToPermissionString: function(flag) { - var perms = ["r", "w", "rw"][flag & 3]; - if (flag & 512) { - perms += "w" - } - return perms - }, - nodePermissions: function(node, perms) { - if (FS.ignorePermissions) { - return 0 - } - if (perms.indexOf("r") !== -1 && !(node.mode & 292)) { - return 2 - } else if (perms.indexOf("w") !== -1 && !(node.mode & 146)) { - return 2 - } else if (perms.indexOf("x") !== -1 && !(node.mode & 73)) { - return 2 - } - return 0 - }, - mayLookup: function(dir) { - var errCode = FS.nodePermissions(dir, "x"); - if (errCode) return errCode; - if (!dir.node_ops.lookup) return 2; - return 0 - }, - mayCreate: function(dir, name) { - try { - var node = FS.lookupNode(dir, name); - return 20 - } catch (e) {} - return FS.nodePermissions(dir, "wx") - }, - mayDelete: function(dir, name, isdir) { - var node; - try { - node = FS.lookupNode(dir, name) - } catch (e) { - return e.errno - } - var errCode = FS.nodePermissions(dir, "wx"); - if (errCode) { - return errCode - } - if (isdir) { - if (!FS.isDir(node.mode)) { - return 54 - } - if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) { - return 10 - } - } else { - if (FS.isDir(node.mode)) { - return 31 - } - } - return 0 - }, - mayOpen: function(node, flags) { - if (!node) { - return 44 - } - if (FS.isLink(node.mode)) { - return 32 - } else if (FS.isDir(node.mode)) { - if (FS.flagsToPermissionString(flags) !== "r" || flags & 512) { - return 31 - } - } - return FS.nodePermissions(node, FS.flagsToPermissionString(flags)) - }, - MAX_OPEN_FDS: 4096, - nextfd: function(fd_start, fd_end) { - fd_start = fd_start || 0; - fd_end = fd_end || FS.MAX_OPEN_FDS; - for (var fd = fd_start; fd <= fd_end; fd++) { - if (!FS.streams[fd]) { - return fd - } - } - throw new FS.ErrnoError(33) - }, - getStream: function(fd) { - return FS.streams[fd] - }, - createStream: function(stream, fd_start, fd_end) { - if (!FS.FSStream) { - FS.FSStream = function() {}; - FS.FSStream.prototype = { - object: { - get: function() { - return this.node - }, - set: function(val) { - this.node = val - } - }, - isRead: { - get: function() { - return (this.flags & 2097155) !== 1 - } - }, - isWrite: { - get: function() { - return (this.flags & 2097155) !== 0 - } - }, - isAppend: { - get: function() { - return this.flags & 1024 - } - } - } - } - var newStream = new FS.FSStream; - for (var p in stream) { - newStream[p] = stream[p] - } - stream = newStream; - var fd = FS.nextfd(fd_start, fd_end); - stream.fd = fd; - FS.streams[fd] = stream; - return stream - }, - closeStream: function(fd) { - FS.streams[fd] = null - }, - chrdev_stream_ops: { - open: function(stream) { - var device = FS.getDevice(stream.node.rdev); - stream.stream_ops = device.stream_ops; - if (stream.stream_ops.open) { - stream.stream_ops.open(stream) - } - }, - llseek: function() { - throw new FS.ErrnoError(70) - } - }, - major: function(dev) { - return dev >> 8 - }, - minor: function(dev) { - return dev & 255 - }, - makedev: function(ma, mi) { - return ma << 8 | mi - }, - registerDevice: function(dev, ops) { - FS.devices[dev] = { - stream_ops: ops - } - }, - getDevice: function(dev) { - return FS.devices[dev] - }, - getMounts: function(mount) { - var mounts = []; - var check = [mount]; - while (check.length) { - var m = check.pop(); - mounts.push(m); - check.push.apply(check, m.mounts) - } - return mounts - }, - syncfs: function(populate, callback) { - if (typeof populate === "function") { - callback = populate; - populate = false - } - FS.syncFSRequests++; - if (FS.syncFSRequests > 1) { - err("warning: " + FS.syncFSRequests + " FS.syncfs operations in flight at once, probably just doing extra work") - } - var mounts = FS.getMounts(FS.root.mount); - var completed = 0; - - function doCallback(errCode) { - FS.syncFSRequests--; - return callback(errCode) - } - - function done(errCode) { - if (errCode) { - if (!done.errored) { - done.errored = true; - return doCallback(errCode) - } - return - } - if (++completed >= mounts.length) { - doCallback(null) - } - } - mounts.forEach(function(mount) { - if (!mount.type.syncfs) { - return done(null) - } - mount.type.syncfs(mount, populate, done) - }) - }, - mount: function(type, opts, mountpoint) { - var root = mountpoint === "/"; - var pseudo = !mountpoint; - var node; - if (root && FS.root) { - throw new FS.ErrnoError(10) - } else if (!root && !pseudo) { - var lookup = FS.lookupPath(mountpoint, { - follow_mount: false - }); - mountpoint = lookup.path; - node = lookup.node; - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10) - } - if (!FS.isDir(node.mode)) { - throw new FS.ErrnoError(54) - } - } - var mount = { - type: type, - opts: opts, - mountpoint: mountpoint, - mounts: [] - }; - var mountRoot = type.mount(mount); - mountRoot.mount = mount; - mount.root = mountRoot; - if (root) { - FS.root = mountRoot - } else if (node) { - node.mounted = mount; - if (node.mount) { - node.mount.mounts.push(mount) - } - } - return mountRoot - }, - unmount: function(mountpoint) { - var lookup = FS.lookupPath(mountpoint, { - follow_mount: false - }); - if (!FS.isMountpoint(lookup.node)) { - throw new FS.ErrnoError(28) - } - var node = lookup.node; - var mount = node.mounted; - var mounts = FS.getMounts(mount); - Object.keys(FS.nameTable).forEach(function(hash) { - var current = FS.nameTable[hash]; - while (current) { - var next = current.name_next; - if (mounts.indexOf(current.mount) !== -1) { - FS.destroyNode(current) - } - current = next - } - }); - node.mounted = null; - var idx = node.mount.mounts.indexOf(mount); - node.mount.mounts.splice(idx, 1) - }, - lookup: function(parent, name) { - return parent.node_ops.lookup(parent, name) - }, - mknod: function(path, mode, dev) { - var lookup = FS.lookupPath(path, { - parent: true - }); - var parent = lookup.node; - var name = PATH.basename(path); - if (!name || name === "." || name === "..") { - throw new FS.ErrnoError(28) - } - var errCode = FS.mayCreate(parent, name); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - if (!parent.node_ops.mknod) { - throw new FS.ErrnoError(63) - } - return parent.node_ops.mknod(parent, name, mode, dev) - }, - create: function(path, mode) { - mode = mode !== undefined ? mode : 438; - mode &= 4095; - mode |= 32768; - return FS.mknod(path, mode, 0) - }, - mkdir: function(path, mode) { - mode = mode !== undefined ? mode : 511; - mode &= 511 | 512; - mode |= 16384; - return FS.mknod(path, mode, 0) - }, - mkdirTree: function(path, mode) { - var dirs = path.split("/"); - var d = ""; - for (var i = 0; i < dirs.length; ++i) { - if (!dirs[i]) continue; - d += "/" + dirs[i]; - try { - FS.mkdir(d, mode) - } catch (e) { - if (e.errno != 20) throw e - } - } - }, - mkdev: function(path, mode, dev) { - if (typeof dev === "undefined") { - dev = mode; - mode = 438 - } - mode |= 8192; - return FS.mknod(path, mode, dev) - }, - symlink: function(oldpath, newpath) { - if (!PATH_FS.resolve(oldpath)) { - throw new FS.ErrnoError(44) - } - var lookup = FS.lookupPath(newpath, { - parent: true - }); - var parent = lookup.node; - if (!parent) { - throw new FS.ErrnoError(44) - } - var newname = PATH.basename(newpath); - var errCode = FS.mayCreate(parent, newname); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - if (!parent.node_ops.symlink) { - throw new FS.ErrnoError(63) - } - return parent.node_ops.symlink(parent, newname, oldpath) - }, - rename: function(old_path, new_path) { - var old_dirname = PATH.dirname(old_path); - var new_dirname = PATH.dirname(new_path); - var old_name = PATH.basename(old_path); - var new_name = PATH.basename(new_path); - var lookup, old_dir, new_dir; - lookup = FS.lookupPath(old_path, { - parent: true - }); - old_dir = lookup.node; - lookup = FS.lookupPath(new_path, { - parent: true - }); - new_dir = lookup.node; - if (!old_dir || !new_dir) throw new FS.ErrnoError(44); - if (old_dir.mount !== new_dir.mount) { - throw new FS.ErrnoError(75) - } - var old_node = FS.lookupNode(old_dir, old_name); - var relative = PATH_FS.relative(old_path, new_dirname); - if (relative.charAt(0) !== ".") { - throw new FS.ErrnoError(28) - } - relative = PATH_FS.relative(new_path, old_dirname); - if (relative.charAt(0) !== ".") { - throw new FS.ErrnoError(55) - } - var new_node; - try { - new_node = FS.lookupNode(new_dir, new_name) - } catch (e) {} - if (old_node === new_node) { - return - } - var isdir = FS.isDir(old_node.mode); - var errCode = FS.mayDelete(old_dir, old_name, isdir); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - errCode = new_node ? FS.mayDelete(new_dir, new_name, isdir) : FS.mayCreate(new_dir, new_name); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - if (!old_dir.node_ops.rename) { - throw new FS.ErrnoError(63) - } - if (FS.isMountpoint(old_node) || new_node && FS.isMountpoint(new_node)) { - throw new FS.ErrnoError(10) - } - if (new_dir !== old_dir) { - errCode = FS.nodePermissions(old_dir, "w"); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - } - try { - if (FS.trackingDelegate.willMovePath) { - FS.trackingDelegate.willMovePath(old_path, new_path) - } - } catch (e) { - err("FS.trackingDelegate['willMovePath']('" + old_path + "', '" + new_path + "') threw an exception: " + e.message) - } - FS.hashRemoveNode(old_node); - try { - old_dir.node_ops.rename(old_node, new_dir, new_name) - } catch (e) { - throw e - } finally { - FS.hashAddNode(old_node) - } - try { - if (FS.trackingDelegate.onMovePath) FS.trackingDelegate.onMovePath(old_path, new_path) - } catch (e) { - err("FS.trackingDelegate['onMovePath']('" + old_path + "', '" + new_path + "') threw an exception: " + e.message) - } - }, - rmdir: function(path) { - var lookup = FS.lookupPath(path, { - parent: true - }); - var parent = lookup.node; - var name = PATH.basename(path); - var node = FS.lookupNode(parent, name); - var errCode = FS.mayDelete(parent, name, true); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - if (!parent.node_ops.rmdir) { - throw new FS.ErrnoError(63) - } - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10) - } - try { - if (FS.trackingDelegate.willDeletePath) { - FS.trackingDelegate.willDeletePath(path) - } - } catch (e) { - err("FS.trackingDelegate['willDeletePath']('" + path + "') threw an exception: " + e.message) - } - parent.node_ops.rmdir(parent, name); - FS.destroyNode(node); - try { - if (FS.trackingDelegate.onDeletePath) FS.trackingDelegate.onDeletePath(path) - } catch (e) { - err("FS.trackingDelegate['onDeletePath']('" + path + "') threw an exception: " + e.message) - } - }, - readdir: function(path) { - var lookup = FS.lookupPath(path, { - follow: true - }); - var node = lookup.node; - if (!node.node_ops.readdir) { - throw new FS.ErrnoError(54) - } - return node.node_ops.readdir(node) - }, - unlink: function(path) { - var lookup = FS.lookupPath(path, { - parent: true - }); - var parent = lookup.node; - var name = PATH.basename(path); - var node = FS.lookupNode(parent, name); - var errCode = FS.mayDelete(parent, name, false); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - if (!parent.node_ops.unlink) { - throw new FS.ErrnoError(63) - } - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10) - } - try { - if (FS.trackingDelegate.willDeletePath) { - FS.trackingDelegate.willDeletePath(path) - } - } catch (e) { - err("FS.trackingDelegate['willDeletePath']('" + path + "') threw an exception: " + e.message) - } - parent.node_ops.unlink(parent, name); - FS.destroyNode(node); - try { - if (FS.trackingDelegate.onDeletePath) FS.trackingDelegate.onDeletePath(path) - } catch (e) { - err("FS.trackingDelegate['onDeletePath']('" + path + "') threw an exception: " + e.message) - } - }, - readlink: function(path) { - var lookup = FS.lookupPath(path); - var link = lookup.node; - if (!link) { - throw new FS.ErrnoError(44) - } - if (!link.node_ops.readlink) { - throw new FS.ErrnoError(28) - } - return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link)) - }, - stat: function(path, dontFollow) { - var lookup = FS.lookupPath(path, { - follow: !dontFollow - }); - var node = lookup.node; - if (!node) { - throw new FS.ErrnoError(44) - } - if (!node.node_ops.getattr) { - throw new FS.ErrnoError(63) - } - return node.node_ops.getattr(node) - }, - lstat: function(path) { - return FS.stat(path, true) - }, - chmod: function(path, mode, dontFollow) { - var node; - if (typeof path === "string") { - var lookup = FS.lookupPath(path, { - follow: !dontFollow - }); - node = lookup.node - } else { - node = path - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63) - } - node.node_ops.setattr(node, { - mode: mode & 4095 | node.mode & ~4095, - timestamp: Date.now() - }) - }, - lchmod: function(path, mode) { - FS.chmod(path, mode, true) - }, - fchmod: function(fd, mode) { - var stream = FS.getStream(fd); - if (!stream) { - throw new FS.ErrnoError(8) - } - FS.chmod(stream.node, mode) - }, - chown: function(path, uid, gid, dontFollow) { - var node; - if (typeof path === "string") { - var lookup = FS.lookupPath(path, { - follow: !dontFollow - }); - node = lookup.node - } else { - node = path - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63) - } - node.node_ops.setattr(node, { - timestamp: Date.now() - }) - }, - lchown: function(path, uid, gid) { - FS.chown(path, uid, gid, true) - }, - fchown: function(fd, uid, gid) { - var stream = FS.getStream(fd); - if (!stream) { - throw new FS.ErrnoError(8) - } - FS.chown(stream.node, uid, gid) - }, - truncate: function(path, len) { - if (len < 0) { - throw new FS.ErrnoError(28) - } - var node; - if (typeof path === "string") { - var lookup = FS.lookupPath(path, { - follow: true - }); - node = lookup.node - } else { - node = path - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63) - } - if (FS.isDir(node.mode)) { - throw new FS.ErrnoError(31) - } - if (!FS.isFile(node.mode)) { - throw new FS.ErrnoError(28) - } - var errCode = FS.nodePermissions(node, "w"); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - node.node_ops.setattr(node, { - size: len, - timestamp: Date.now() - }) - }, - ftruncate: function(fd, len) { - var stream = FS.getStream(fd); - if (!stream) { - throw new FS.ErrnoError(8) - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(28) - } - FS.truncate(stream.node, len) - }, - utime: function(path, atime, mtime) { - var lookup = FS.lookupPath(path, { - follow: true - }); - var node = lookup.node; - node.node_ops.setattr(node, { - timestamp: Math.max(atime, mtime) - }) - }, - open: function(path, flags, mode, fd_start, fd_end) { - if (path === "") { - throw new FS.ErrnoError(44) - } - flags = typeof flags === "string" ? FS.modeStringToFlags(flags) : flags; - mode = typeof mode === "undefined" ? 438 : mode; - if (flags & 64) { - mode = mode & 4095 | 32768 - } else { - mode = 0 - } - var node; - if (typeof path === "object") { - node = path - } else { - path = PATH.normalize(path); - try { - var lookup = FS.lookupPath(path, { - follow: !(flags & 131072) - }); - node = lookup.node - } catch (e) {} - } - var created = false; - if (flags & 64) { - if (node) { - if (flags & 128) { - throw new FS.ErrnoError(20) - } - } else { - node = FS.mknod(path, mode, 0); - created = true - } - } - if (!node) { - throw new FS.ErrnoError(44) - } - if (FS.isChrdev(node.mode)) { - flags &= ~512 - } - if (flags & 65536 && !FS.isDir(node.mode)) { - throw new FS.ErrnoError(54) - } - if (!created) { - var errCode = FS.mayOpen(node, flags); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - } - if (flags & 512) { - FS.truncate(node, 0) - } - flags &= ~(128 | 512 | 131072); - var stream = FS.createStream({ - node: node, - path: FS.getPath(node), - flags: flags, - seekable: true, - position: 0, - stream_ops: node.stream_ops, - ungotten: [], - error: false - }, fd_start, fd_end); - if (stream.stream_ops.open) { - stream.stream_ops.open(stream) - } - if (Module.logReadFiles && !(flags & 1)) { - if (!FS.readFiles) FS.readFiles = {}; - if (!(path in FS.readFiles)) { - FS.readFiles[path] = 1; - err("FS.trackingDelegate error on read file: " + path) - } - } - try { - if (FS.trackingDelegate.onOpenFile) { - var trackingFlags = 0; - if ((flags & 2097155) !== 1) { - trackingFlags |= FS.tracking.openFlags.READ - } - if ((flags & 2097155) !== 0) { - trackingFlags |= FS.tracking.openFlags.WRITE - } - FS.trackingDelegate.onOpenFile(path, trackingFlags) - } - } catch (e) { - err("FS.trackingDelegate['onOpenFile']('" + path + "', flags) threw an exception: " + e.message) - } - return stream - }, - close: function(stream) { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8) - } - if (stream.getdents) stream.getdents = null; - try { - if (stream.stream_ops.close) { - stream.stream_ops.close(stream) - } - } catch (e) { - throw e - } finally { - FS.closeStream(stream.fd) - } - stream.fd = null - }, - isClosed: function(stream) { - return stream.fd === null - }, - llseek: function(stream, offset, whence) { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8) - } - if (!stream.seekable || !stream.stream_ops.llseek) { - throw new FS.ErrnoError(70) - } - if (whence != 0 && whence != 1 && whence != 2) { - throw new FS.ErrnoError(28) - } - stream.position = stream.stream_ops.llseek(stream, offset, whence); - stream.ungotten = []; - return stream.position - }, - read: function(stream, buffer, offset, length, position) { - if (length < 0 || position < 0) { - throw new FS.ErrnoError(28) - } - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8) - } - if ((stream.flags & 2097155) === 1) { - throw new FS.ErrnoError(8) - } - if (FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(31) - } - if (!stream.stream_ops.read) { - throw new FS.ErrnoError(28) - } - var seeking = typeof position !== "undefined"; - if (!seeking) { - position = stream.position - } else if (!stream.seekable) { - throw new FS.ErrnoError(70) - } - var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position); - if (!seeking) stream.position += bytesRead; - return bytesRead - }, - write: function(stream, buffer, offset, length, position, canOwn) { - if (length < 0 || position < 0) { - throw new FS.ErrnoError(28) - } - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8) - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(8) - } - if (FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(31) - } - if (!stream.stream_ops.write) { - throw new FS.ErrnoError(28) - } - if (stream.seekable && stream.flags & 1024) { - FS.llseek(stream, 0, 2) - } - var seeking = typeof position !== "undefined"; - if (!seeking) { - position = stream.position - } else if (!stream.seekable) { - throw new FS.ErrnoError(70) - } - var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn); - if (!seeking) stream.position += bytesWritten; - try { - if (stream.path && FS.trackingDelegate.onWriteToFile) FS.trackingDelegate.onWriteToFile(stream.path) - } catch (e) { - err("FS.trackingDelegate['onWriteToFile']('" + stream.path + "') threw an exception: " + e.message) - } - return bytesWritten - }, - allocate: function(stream, offset, length) { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8) - } - if (offset < 0 || length <= 0) { - throw new FS.ErrnoError(28) - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(8) - } - if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(43) - } - if (!stream.stream_ops.allocate) { - throw new FS.ErrnoError(138) - } - stream.stream_ops.allocate(stream, offset, length) - }, - mmap: function(stream, address, length, position, prot, flags) { - if ((prot & 2) !== 0 && (flags & 2) === 0 && (stream.flags & 2097155) !== 2) { - throw new FS.ErrnoError(2) - } - if ((stream.flags & 2097155) === 1) { - throw new FS.ErrnoError(2) - } - if (!stream.stream_ops.mmap) { - throw new FS.ErrnoError(43) - } - return stream.stream_ops.mmap(stream, address, length, position, prot, flags) - }, - msync: function(stream, buffer, offset, length, mmapFlags) { - if (!stream || !stream.stream_ops.msync) { - return 0 - } - return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags) - }, - munmap: function(stream) { - return 0 - }, - ioctl: function(stream, cmd, arg) { - if (!stream.stream_ops.ioctl) { - throw new FS.ErrnoError(59) - } - return stream.stream_ops.ioctl(stream, cmd, arg) - }, - readFile: function(path, opts) { - opts = opts || {}; - opts.flags = opts.flags || "r"; - opts.encoding = opts.encoding || "binary"; - if (opts.encoding !== "utf8" && opts.encoding !== "binary") { - throw new Error('Invalid encoding type "' + opts.encoding + '"') - } - var ret; - var stream = FS.open(path, opts.flags); - var stat = FS.stat(path); - var length = stat.size; - var buf = new Uint8Array(length); - FS.read(stream, buf, 0, length, 0); - if (opts.encoding === "utf8") { - ret = UTF8ArrayToString(buf, 0) - } else if (opts.encoding === "binary") { - ret = buf - } - FS.close(stream); - return ret - }, - writeFile: function(path, data, opts) { - opts = opts || {}; - opts.flags = opts.flags || "w"; - var stream = FS.open(path, opts.flags, opts.mode); - if (typeof data === "string") { - var buf = new Uint8Array(lengthBytesUTF8(data) + 1); - var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length); - FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn) - } else if (ArrayBuffer.isView(data)) { - FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn) - } else { - throw new Error("Unsupported data type") - } - FS.close(stream) - }, - cwd: function() { - return FS.currentPath - }, - chdir: function(path) { - var lookup = FS.lookupPath(path, { - follow: true - }); - if (lookup.node === null) { - throw new FS.ErrnoError(44) - } - if (!FS.isDir(lookup.node.mode)) { - throw new FS.ErrnoError(54) - } - var errCode = FS.nodePermissions(lookup.node, "x"); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - FS.currentPath = lookup.path - }, - createDefaultDirectories: function() { - FS.mkdir("/tmp"); - FS.mkdir("/home"); - FS.mkdir("/home/web_user") - }, - createDefaultDevices: function() { - FS.mkdir("/dev"); - FS.registerDevice(FS.makedev(1, 3), { - read: function() { - return 0 - }, - write: function(stream, buffer, offset, length, pos) { - return length - } - }); - FS.mkdev("/dev/null", FS.makedev(1, 3)); - TTY.register(FS.makedev(5, 0), TTY.default_tty_ops); - TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops); - FS.mkdev("/dev/tty", FS.makedev(5, 0)); - FS.mkdev("/dev/tty1", FS.makedev(6, 0)); - var random_device = getRandomDevice(); - FS.createDevice("/dev", "random", random_device); - FS.createDevice("/dev", "urandom", random_device); - FS.mkdir("/dev/shm"); - FS.mkdir("/dev/shm/tmp") - }, - createSpecialDirectories: function() { - FS.mkdir("/proc"); - FS.mkdir("/proc/self"); - FS.mkdir("/proc/self/fd"); - FS.mount({ - mount: function() { - var node = FS.createNode("/proc/self", "fd", 16384 | 511, 73); - node.node_ops = { - lookup: function(parent, name) { - var fd = +name; - var stream = FS.getStream(fd); - if (!stream) throw new FS.ErrnoError(8); - var ret = { - parent: null, - mount: { - mountpoint: "fake" - }, - node_ops: { - readlink: function() { - return stream.path - } - } - }; - ret.parent = ret; - return ret - } - }; - return node - } - }, {}, "/proc/self/fd") - }, - createStandardStreams: function() { - if (Module.stdin) { - FS.createDevice("/dev", "stdin", Module.stdin) - } else { - FS.symlink("/dev/tty", "/dev/stdin") - } - if (Module.stdout) { - FS.createDevice("/dev", "stdout", null, Module.stdout) - } else { - FS.symlink("/dev/tty", "/dev/stdout") - } - if (Module.stderr) { - FS.createDevice("/dev", "stderr", null, Module.stderr) - } else { - FS.symlink("/dev/tty1", "/dev/stderr") - } - var stdin = FS.open("/dev/stdin", "r"); - var stdout = FS.open("/dev/stdout", "w"); - var stderr = FS.open("/dev/stderr", "w") - }, - ensureErrnoError: function() { - if (FS.ErrnoError) return; - FS.ErrnoError = function ErrnoError(errno, node) { - this.node = node; - this.setErrno = function(errno) { - this.errno = errno - }; - this.setErrno(errno); - this.message = "FS error" - }; - FS.ErrnoError.prototype = new Error; - FS.ErrnoError.prototype.constructor = FS.ErrnoError; - [44].forEach(function(code) { - FS.genericErrors[code] = new FS.ErrnoError(code); - FS.genericErrors[code].stack = "" - }) - }, - staticInit: function() { - FS.ensureErrnoError(); - FS.nameTable = new Array(4096); - FS.mount(MEMFS, {}, "/"); - FS.createDefaultDirectories(); - FS.createDefaultDevices(); - FS.createSpecialDirectories(); - FS.filesystems = { - "MEMFS": MEMFS - } - }, - init: function(input, output, error) { - FS.init.initialized = true; - FS.ensureErrnoError(); - Module.stdin = input || Module.stdin; - Module.stdout = output || Module.stdout; - Module.stderr = error || Module.stderr; - FS.createStandardStreams() - }, - quit: function() { - FS.init.initialized = false; - var fflush = Module._fflush; - if (fflush) fflush(0); - for (var i = 0; i < FS.streams.length; i++) { - var stream = FS.streams[i]; - if (!stream) { - continue - } - FS.close(stream) - } - }, - getMode: function(canRead, canWrite) { - var mode = 0; - if (canRead) mode |= 292 | 73; - if (canWrite) mode |= 146; - return mode - }, - findObject: function(path, dontResolveLastLink) { - var ret = FS.analyzePath(path, dontResolveLastLink); - if (ret.exists) { - return ret.object - } else { - setErrNo(ret.error); - return null - } - }, - analyzePath: function(path, dontResolveLastLink) { - try { - var lookup = FS.lookupPath(path, { - follow: !dontResolveLastLink - }); - path = lookup.path - } catch (e) {} - var ret = { - isRoot: false, - exists: false, - error: 0, - name: null, - path: null, - object: null, - parentExists: false, - parentPath: null, - parentObject: null - }; - try { - var lookup = FS.lookupPath(path, { - parent: true - }); - ret.parentExists = true; - ret.parentPath = lookup.path; - ret.parentObject = lookup.node; - ret.name = PATH.basename(path); - lookup = FS.lookupPath(path, { - follow: !dontResolveLastLink - }); - ret.exists = true; - ret.path = lookup.path; - ret.object = lookup.node; - ret.name = lookup.node.name; - ret.isRoot = lookup.path === "/" - } catch (e) { - ret.error = e.errno - } - return ret - }, - createPath: function(parent, path, canRead, canWrite) { - parent = typeof parent === "string" ? parent : FS.getPath(parent); - var parts = path.split("/").reverse(); - while (parts.length) { - var part = parts.pop(); - if (!part) continue; - var current = PATH.join2(parent, part); - try { - FS.mkdir(current) - } catch (e) {} - parent = current - } - return current - }, - createFile: function(parent, name, properties, canRead, canWrite) { - var path = PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name); - var mode = FS.getMode(canRead, canWrite); - return FS.create(path, mode) - }, - createDataFile: function(parent, name, data, canRead, canWrite, canOwn) { - var path = name ? PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name) : parent; - var mode = FS.getMode(canRead, canWrite); - var node = FS.create(path, mode); - if (data) { - if (typeof data === "string") { - var arr = new Array(data.length); - for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i); - data = arr - } - FS.chmod(node, mode | 146); - var stream = FS.open(node, "w"); - FS.write(stream, data, 0, data.length, 0, canOwn); - FS.close(stream); - FS.chmod(node, mode) - } - return node - }, - createDevice: function(parent, name, input, output) { - var path = PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name); - var mode = FS.getMode(!!input, !!output); - if (!FS.createDevice.major) FS.createDevice.major = 64; - var dev = FS.makedev(FS.createDevice.major++, 0); - FS.registerDevice(dev, { - open: function(stream) { - stream.seekable = false - }, - close: function(stream) { - if (output && output.buffer && output.buffer.length) { - output(10) - } - }, - read: function(stream, buffer, offset, length, pos) { - var bytesRead = 0; - for (var i = 0; i < length; i++) { - var result; - try { - result = input() - } catch (e) { - throw new FS.ErrnoError(29) - } - if (result === undefined && bytesRead === 0) { - throw new FS.ErrnoError(6) - } - if (result === null || result === undefined) break; - bytesRead++; - buffer[offset + i] = result - } - if (bytesRead) { - stream.node.timestamp = Date.now() - } - return bytesRead - }, - write: function(stream, buffer, offset, length, pos) { - for (var i = 0; i < length; i++) { - try { - output(buffer[offset + i]) - } catch (e) { - throw new FS.ErrnoError(29) - } - } - if (length) { - stream.node.timestamp = Date.now() - } - return i - } - }); - return FS.mkdev(path, mode, dev) - }, - forceLoadFile: function(obj) { - if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true; - var success = true; - if (typeof XMLHttpRequest !== "undefined") { - throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.") - } else if (read_) { - try { - obj.contents = intArrayFromString(read_(obj.url), true); - obj.usedBytes = obj.contents.length - } catch (e) { - success = false - } - } else { - throw new Error("Cannot load without read() or XMLHttpRequest.") - } - if (!success) setErrNo(29); - return success - }, - createLazyFile: function(parent, name, url, canRead, canWrite) { - function LazyUint8Array() { - this.lengthKnown = false; - this.chunks = [] - } - LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) { - if (idx > this.length - 1 || idx < 0) { - return undefined - } - var chunkOffset = idx % this.chunkSize; - var chunkNum = idx / this.chunkSize | 0; - return this.getter(chunkNum)[chunkOffset] - }; - LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) { - this.getter = getter - }; - LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() { - var xhr = new XMLHttpRequest; - xhr.open("HEAD", url, false); - xhr.send(null); - if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); - var datalength = Number(xhr.getResponseHeader("Content-length")); - var header; - var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; - var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip"; - var chunkSize = 1024 * 1024; - if (!hasByteServing) chunkSize = datalength; - var doXHR = function(from, to) { - if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!"); - if (to > datalength - 1) throw new Error("only " + datalength + " bytes available! programmer error!"); - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); - if (typeof Uint8Array !== "undefined") xhr.responseType = "arraybuffer"; - if (xhr.overrideMimeType) { - xhr.overrideMimeType("text/plain; charset=x-user-defined") - } - xhr.send(null); - if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); - if (xhr.response !== undefined) { - return new Uint8Array(xhr.response || []) - } else { - return intArrayFromString(xhr.responseText || "", true) - } - }; - var lazyArray = this; - lazyArray.setDataGetter(function(chunkNum) { - var start = chunkNum * chunkSize; - var end = (chunkNum + 1) * chunkSize - 1; - end = Math.min(end, datalength - 1); - if (typeof lazyArray.chunks[chunkNum] === "undefined") { - lazyArray.chunks[chunkNum] = doXHR(start, end) - } - if (typeof lazyArray.chunks[chunkNum] === "undefined") throw new Error("doXHR failed!"); - return lazyArray.chunks[chunkNum] - }); - if (usesGzip || !datalength) { - chunkSize = datalength = 1; - datalength = this.getter(0).length; - chunkSize = datalength; - out("LazyFiles on gzip forces download of the whole file when length is accessed") - } - this._length = datalength; - this._chunkSize = chunkSize; - this.lengthKnown = true - }; - if (typeof XMLHttpRequest !== "undefined") { - if (!ENVIRONMENT_IS_WORKER) throw "Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc"; - var lazyArray = new LazyUint8Array; - Object.defineProperties(lazyArray, { - length: { - get: function() { - if (!this.lengthKnown) { - this.cacheLength() - } - return this._length - } - }, - chunkSize: { - get: function() { - if (!this.lengthKnown) { - this.cacheLength() - } - return this._chunkSize - } - } - }); - var properties = { - isDevice: false, - contents: lazyArray - } - } else { - var properties = { - isDevice: false, - url: url - } - } - var node = FS.createFile(parent, name, properties, canRead, canWrite); - if (properties.contents) { - node.contents = properties.contents - } else if (properties.url) { - node.contents = null; - node.url = properties.url - } - Object.defineProperties(node, { - usedBytes: { - get: function() { - return this.contents.length - } - } - }); - var stream_ops = {}; - var keys = Object.keys(node.stream_ops); - keys.forEach(function(key) { - var fn = node.stream_ops[key]; - stream_ops[key] = function forceLoadLazyFile() { - if (!FS.forceLoadFile(node)) { - throw new FS.ErrnoError(29) - } - return fn.apply(null, arguments) - } - }); - stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) { - if (!FS.forceLoadFile(node)) { - throw new FS.ErrnoError(29) - } - var contents = stream.node.contents; - if (position >= contents.length) return 0; - var size = Math.min(contents.length - position, length); - if (contents.slice) { - for (var i = 0; i < size; i++) { - buffer[offset + i] = contents[position + i] - } - } else { - for (var i = 0; i < size; i++) { - buffer[offset + i] = contents.get(position + i) - } - } - return size - }; - node.stream_ops = stream_ops; - return node - }, - createPreloadedFile: function(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) { - Browser.init(); - var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent; - var dep = getUniqueRunDependency("cp " + fullname); - - function processData(byteArray) { - function finish(byteArray) { - if (preFinish) preFinish(); - if (!dontCreateFile) { - FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn) - } - if (onload) onload(); - removeRunDependency(dep) - } - var handled = false; - Module.preloadPlugins.forEach(function(plugin) { - if (handled) return; - if (plugin.canHandle(fullname)) { - plugin.handle(byteArray, fullname, finish, function() { - if (onerror) onerror(); - removeRunDependency(dep) - }); - handled = true - } - }); - if (!handled) finish(byteArray) - } - addRunDependency(dep); - if (typeof url === "string") { - Browser.asyncLoad(url, function(byteArray) { - processData(byteArray) - }, onerror) - } else { - processData(url) - } - }, - indexedDB: function() { - return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB - }, - DB_NAME: function() { - return "EM_FS_" + window.location.pathname - }, - DB_VERSION: 20, - DB_STORE_NAME: "FILE_DATA", - saveFilesToDB: function(paths, onload, onerror) { - onload = onload || function() {}; - onerror = onerror || function() {}; - var indexedDB = FS.indexedDB(); - try { - var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION) - } catch (e) { - return onerror(e) - } - openRequest.onupgradeneeded = function openRequest_onupgradeneeded() { - out("creating db"); - var db = openRequest.result; - db.createObjectStore(FS.DB_STORE_NAME) - }; - openRequest.onsuccess = function openRequest_onsuccess() { - var db = openRequest.result; - var transaction = db.transaction([FS.DB_STORE_NAME], "readwrite"); - var files = transaction.objectStore(FS.DB_STORE_NAME); - var ok = 0; - var fail = 0; - var total = paths.length; - - function finish() { - if (fail == 0) onload(); - else onerror() - } - paths.forEach(function(path) { - var putRequest = files.put(FS.analyzePath(path).object.contents, path); - putRequest.onsuccess = function putRequest_onsuccess() { - ok++; - if (ok + fail == total) finish() - }; - putRequest.onerror = function putRequest_onerror() { - fail++; - if (ok + fail == total) finish() - } - }); - transaction.onerror = onerror - }; - openRequest.onerror = onerror - }, - loadFilesFromDB: function(paths, onload, onerror) { - onload = onload || function() {}; - onerror = onerror || function() {}; - var indexedDB = FS.indexedDB(); - try { - var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION) - } catch (e) { - return onerror(e) - } - openRequest.onupgradeneeded = onerror; - openRequest.onsuccess = function openRequest_onsuccess() { - var db = openRequest.result; - try { - var transaction = db.transaction([FS.DB_STORE_NAME], "readonly") - } catch (e) { - onerror(e); - return - } - var files = transaction.objectStore(FS.DB_STORE_NAME); - var ok = 0; - var fail = 0; - var total = paths.length; - - function finish() { - if (fail == 0) onload(); - else onerror() - } - paths.forEach(function(path) { - var getRequest = files.get(path); - getRequest.onsuccess = function getRequest_onsuccess() { - if (FS.analyzePath(path).exists) { - FS.unlink(path) - } - FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true); - ok++; - if (ok + fail == total) finish() - }; - getRequest.onerror = function getRequest_onerror() { - fail++; - if (ok + fail == total) finish() - } - }); - transaction.onerror = onerror - }; - openRequest.onerror = onerror - } -}; -var SYSCALLS = { - mappings: {}, - DEFAULT_POLLMASK: 5, - umask: 511, - calculateAt: function(dirfd, path) { - if (path[0] !== "/") { - var dir; - if (dirfd === -100) { - dir = FS.cwd() - } else { - var dirstream = FS.getStream(dirfd); - if (!dirstream) throw new FS.ErrnoError(8); - dir = dirstream.path - } - path = PATH.join2(dir, path) - } - return path - }, - doStat: function(func, path, buf) { - try { - var stat = func(path) - } catch (e) { - if (e && e.node && PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))) { - return -54 - } - throw e - } - HEAP32[buf >> 2] = stat.dev; - HEAP32[buf + 4 >> 2] = 0; - HEAP32[buf + 8 >> 2] = stat.ino; - HEAP32[buf + 12 >> 2] = stat.mode; - HEAP32[buf + 16 >> 2] = stat.nlink; - HEAP32[buf + 20 >> 2] = stat.uid; - HEAP32[buf + 24 >> 2] = stat.gid; - HEAP32[buf + 28 >> 2] = stat.rdev; - HEAP32[buf + 32 >> 2] = 0; - tempI64 = [stat.size >>> 0, (tempDouble = stat.size, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0)], HEAP32[buf + 40 >> 2] = tempI64[0], HEAP32[buf + 44 >> 2] = tempI64[1]; - HEAP32[buf + 48 >> 2] = 4096; - HEAP32[buf + 52 >> 2] = stat.blocks; - HEAP32[buf + 56 >> 2] = stat.atime.getTime() / 1e3 | 0; - HEAP32[buf + 60 >> 2] = 0; - HEAP32[buf + 64 >> 2] = stat.mtime.getTime() / 1e3 | 0; - HEAP32[buf + 68 >> 2] = 0; - HEAP32[buf + 72 >> 2] = stat.ctime.getTime() / 1e3 | 0; - HEAP32[buf + 76 >> 2] = 0; - tempI64 = [stat.ino >>> 0, (tempDouble = stat.ino, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0)], HEAP32[buf + 80 >> 2] = tempI64[0], HEAP32[buf + 84 >> 2] = tempI64[1]; - return 0 - }, - doMsync: function(addr, stream, len, flags, offset) { - var buffer = HEAPU8.slice(addr, addr + len); - FS.msync(stream, buffer, offset, len, flags) - }, - doMkdir: function(path, mode) { - path = PATH.normalize(path); - if (path[path.length - 1] === "/") path = path.substr(0, path.length - 1); - FS.mkdir(path, mode, 0); - return 0 - }, - doMknod: function(path, mode, dev) { - switch (mode & 61440) { - case 32768: - case 8192: - case 24576: - case 4096: - case 49152: - break; - default: - return -28 - } - FS.mknod(path, mode, dev); - return 0 - }, - doReadlink: function(path, buf, bufsize) { - if (bufsize <= 0) return -28; - var ret = FS.readlink(path); - var len = Math.min(bufsize, lengthBytesUTF8(ret)); - var endChar = HEAP8[buf + len]; - stringToUTF8(ret, buf, bufsize + 1); - HEAP8[buf + len] = endChar; - return len - }, - doAccess: function(path, amode) { - if (amode & ~7) { - return -28 - } - var node; - var lookup = FS.lookupPath(path, { - follow: true - }); - node = lookup.node; - if (!node) { - return -44 - } - var perms = ""; - if (amode & 4) perms += "r"; - if (amode & 2) perms += "w"; - if (amode & 1) perms += "x"; - if (perms && FS.nodePermissions(node, perms)) { - return -2 - } - return 0 - }, - doDup: function(path, flags, suggestFD) { - var suggest = FS.getStream(suggestFD); - if (suggest) FS.close(suggest); - return FS.open(path, flags, 0, suggestFD, suggestFD).fd - }, - doReadv: function(stream, iov, iovcnt, offset) { - var ret = 0; - for (var i = 0; i < iovcnt; i++) { - var ptr = HEAP32[iov + i * 8 >> 2]; - var len = HEAP32[iov + (i * 8 + 4) >> 2]; - var curr = FS.read(stream, HEAP8, ptr, len, offset); - if (curr < 0) return -1; - ret += curr; - if (curr < len) break - } - return ret - }, - doWritev: function(stream, iov, iovcnt, offset) { - var ret = 0; - for (var i = 0; i < iovcnt; i++) { - var ptr = HEAP32[iov + i * 8 >> 2]; - var len = HEAP32[iov + (i * 8 + 4) >> 2]; - var curr = FS.write(stream, HEAP8, ptr, len, offset); - if (curr < 0) return -1; - ret += curr - } - return ret - }, - varargs: undefined, - get: function() { - SYSCALLS.varargs += 4; - var ret = HEAP32[SYSCALLS.varargs - 4 >> 2]; - return ret - }, - getStr: function(ptr) { - var ret = UTF8ToString(ptr); - return ret - }, - getStreamFromFD: function(fd) { - var stream = FS.getStream(fd); - if (!stream) throw new FS.ErrnoError(8); - return stream - }, - get64: function(low, high) { - return low - } -}; - -function _fd_close(fd) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - FS.close(stream); - return 0 - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e); - return e.errno - } -} - -function _fd_read(fd, iov, iovcnt, pnum) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - var num = SYSCALLS.doReadv(stream, iov, iovcnt); - HEAP32[pnum >> 2] = num; - return 0 - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e); - return e.errno - } -} - -function _fd_seek(fd, offset_low, offset_high, whence, newOffset) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - var HIGH_OFFSET = 4294967296; - var offset = offset_high * HIGH_OFFSET + (offset_low >>> 0); - var DOUBLE_LIMIT = 9007199254740992; - if (offset <= -DOUBLE_LIMIT || offset >= DOUBLE_LIMIT) { - return -61 - } - FS.llseek(stream, offset, whence); - tempI64 = [stream.position >>> 0, (tempDouble = stream.position, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0)], HEAP32[newOffset >> 2] = tempI64[0], HEAP32[newOffset + 4 >> 2] = tempI64[1]; - if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; - return 0 - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e); - return e.errno - } -} - -function _fd_write(fd, iov, iovcnt, pnum) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - var num = SYSCALLS.doWritev(stream, iov, iovcnt); - HEAP32[pnum >> 2] = num; - return 0 - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e); - return e.errno - } -} - -function __isLeapYear(year) { - return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) -} - -function __arraySum(array, index) { - var sum = 0; - for (var i = 0; i <= index; sum += array[i++]) {} - return sum -} -var __MONTH_DAYS_LEAP = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; -var __MONTH_DAYS_REGULAR = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; - -function __addDays(date, days) { - var newDate = new Date(date.getTime()); - while (days > 0) { - var leap = __isLeapYear(newDate.getFullYear()); - var currentMonth = newDate.getMonth(); - var daysInCurrentMonth = (leap ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR)[currentMonth]; - if (days > daysInCurrentMonth - newDate.getDate()) { - days -= daysInCurrentMonth - newDate.getDate() + 1; - newDate.setDate(1); - if (currentMonth < 11) { - newDate.setMonth(currentMonth + 1) - } else { - newDate.setMonth(0); - newDate.setFullYear(newDate.getFullYear() + 1) - } - } else { - newDate.setDate(newDate.getDate() + days); - return newDate - } - } - return newDate -} - -function _strftime(s, maxsize, format, tm) { - var tm_zone = HEAP32[tm + 40 >> 2]; - var date = { - tm_sec: HEAP32[tm >> 2], - tm_min: HEAP32[tm + 4 >> 2], - tm_hour: HEAP32[tm + 8 >> 2], - tm_mday: HEAP32[tm + 12 >> 2], - tm_mon: HEAP32[tm + 16 >> 2], - tm_year: HEAP32[tm + 20 >> 2], - tm_wday: HEAP32[tm + 24 >> 2], - tm_yday: HEAP32[tm + 28 >> 2], - tm_isdst: HEAP32[tm + 32 >> 2], - tm_gmtoff: HEAP32[tm + 36 >> 2], - tm_zone: tm_zone ? UTF8ToString(tm_zone) : "" - }; - var pattern = UTF8ToString(format); - var EXPANSION_RULES_1 = { - "%c": "%a %b %d %H:%M:%S %Y", - "%D": "%m/%d/%y", - "%F": "%Y-%m-%d", - "%h": "%b", - "%r": "%I:%M:%S %p", - "%R": "%H:%M", - "%T": "%H:%M:%S", - "%x": "%m/%d/%y", - "%X": "%H:%M:%S", - "%Ec": "%c", - "%EC": "%C", - "%Ex": "%m/%d/%y", - "%EX": "%H:%M:%S", - "%Ey": "%y", - "%EY": "%Y", - "%Od": "%d", - "%Oe": "%e", - "%OH": "%H", - "%OI": "%I", - "%Om": "%m", - "%OM": "%M", - "%OS": "%S", - "%Ou": "%u", - "%OU": "%U", - "%OV": "%V", - "%Ow": "%w", - "%OW": "%W", - "%Oy": "%y" - }; - for (var rule in EXPANSION_RULES_1) { - pattern = pattern.replace(new RegExp(rule, "g"), EXPANSION_RULES_1[rule]) - } - var WEEKDAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; - var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; - - function leadingSomething(value, digits, character) { - var str = typeof value === "number" ? value.toString() : value || ""; - while (str.length < digits) { - str = character[0] + str - } - return str - } - - function leadingNulls(value, digits) { - return leadingSomething(value, digits, "0") - } - - function compareByDay(date1, date2) { - function sgn(value) { - return value < 0 ? -1 : value > 0 ? 1 : 0 - } - var compare; - if ((compare = sgn(date1.getFullYear() - date2.getFullYear())) === 0) { - if ((compare = sgn(date1.getMonth() - date2.getMonth())) === 0) { - compare = sgn(date1.getDate() - date2.getDate()) - } - } - return compare - } - - function getFirstWeekStartDate(janFourth) { - switch (janFourth.getDay()) { - case 0: - return new Date(janFourth.getFullYear() - 1, 11, 29); - case 1: - return janFourth; - case 2: - return new Date(janFourth.getFullYear(), 0, 3); - case 3: - return new Date(janFourth.getFullYear(), 0, 2); - case 4: - return new Date(janFourth.getFullYear(), 0, 1); - case 5: - return new Date(janFourth.getFullYear() - 1, 11, 31); - case 6: - return new Date(janFourth.getFullYear() - 1, 11, 30) - } - } - - function getWeekBasedYear(date) { - var thisDate = __addDays(new Date(date.tm_year + 1900, 0, 1), date.tm_yday); - var janFourthThisYear = new Date(thisDate.getFullYear(), 0, 4); - var janFourthNextYear = new Date(thisDate.getFullYear() + 1, 0, 4); - var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear); - var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear); - if (compareByDay(firstWeekStartThisYear, thisDate) <= 0) { - if (compareByDay(firstWeekStartNextYear, thisDate) <= 0) { - return thisDate.getFullYear() + 1 - } else { - return thisDate.getFullYear() - } - } else { - return thisDate.getFullYear() - 1 - } - } - var EXPANSION_RULES_2 = { - "%a": function(date) { - return WEEKDAYS[date.tm_wday].substring(0, 3) - }, - "%A": function(date) { - return WEEKDAYS[date.tm_wday] - }, - "%b": function(date) { - return MONTHS[date.tm_mon].substring(0, 3) - }, - "%B": function(date) { - return MONTHS[date.tm_mon] - }, - "%C": function(date) { - var year = date.tm_year + 1900; - return leadingNulls(year / 100 | 0, 2) - }, - "%d": function(date) { - return leadingNulls(date.tm_mday, 2) - }, - "%e": function(date) { - return leadingSomething(date.tm_mday, 2, " ") - }, - "%g": function(date) { - return getWeekBasedYear(date).toString().substring(2) - }, - "%G": function(date) { - return getWeekBasedYear(date) - }, - "%H": function(date) { - return leadingNulls(date.tm_hour, 2) - }, - "%I": function(date) { - var twelveHour = date.tm_hour; - if (twelveHour == 0) twelveHour = 12; - else if (twelveHour > 12) twelveHour -= 12; - return leadingNulls(twelveHour, 2) - }, - "%j": function(date) { - return leadingNulls(date.tm_mday + __arraySum(__isLeapYear(date.tm_year + 1900) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, date.tm_mon - 1), 3) - }, - "%m": function(date) { - return leadingNulls(date.tm_mon + 1, 2) - }, - "%M": function(date) { - return leadingNulls(date.tm_min, 2) - }, - "%n": function() { - return "\n" - }, - "%p": function(date) { - if (date.tm_hour >= 0 && date.tm_hour < 12) { - return "AM" - } else { - return "PM" - } - }, - "%S": function(date) { - return leadingNulls(date.tm_sec, 2) - }, - "%t": function() { - return "\t" - }, - "%u": function(date) { - return date.tm_wday || 7 - }, - "%U": function(date) { - var janFirst = new Date(date.tm_year + 1900, 0, 1); - var firstSunday = janFirst.getDay() === 0 ? janFirst : __addDays(janFirst, 7 - janFirst.getDay()); - var endDate = new Date(date.tm_year + 1900, date.tm_mon, date.tm_mday); - if (compareByDay(firstSunday, endDate) < 0) { - var februaryFirstUntilEndMonth = __arraySum(__isLeapYear(endDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, endDate.getMonth() - 1) - 31; - var firstSundayUntilEndJanuary = 31 - firstSunday.getDate(); - var days = firstSundayUntilEndJanuary + februaryFirstUntilEndMonth + endDate.getDate(); - return leadingNulls(Math.ceil(days / 7), 2) - } - return compareByDay(firstSunday, janFirst) === 0 ? "01" : "00" - }, - "%V": function(date) { - var janFourthThisYear = new Date(date.tm_year + 1900, 0, 4); - var janFourthNextYear = new Date(date.tm_year + 1901, 0, 4); - var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear); - var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear); - var endDate = __addDays(new Date(date.tm_year + 1900, 0, 1), date.tm_yday); - if (compareByDay(endDate, firstWeekStartThisYear) < 0) { - return "53" - } - if (compareByDay(firstWeekStartNextYear, endDate) <= 0) { - return "01" - } - var daysDifference; - if (firstWeekStartThisYear.getFullYear() < date.tm_year + 1900) { - daysDifference = date.tm_yday + 32 - firstWeekStartThisYear.getDate() - } else { - daysDifference = date.tm_yday + 1 - firstWeekStartThisYear.getDate() - } - return leadingNulls(Math.ceil(daysDifference / 7), 2) - }, - "%w": function(date) { - return date.tm_wday - }, - "%W": function(date) { - var janFirst = new Date(date.tm_year, 0, 1); - var firstMonday = janFirst.getDay() === 1 ? janFirst : __addDays(janFirst, janFirst.getDay() === 0 ? 1 : 7 - janFirst.getDay() + 1); - var endDate = new Date(date.tm_year + 1900, date.tm_mon, date.tm_mday); - if (compareByDay(firstMonday, endDate) < 0) { - var februaryFirstUntilEndMonth = __arraySum(__isLeapYear(endDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, endDate.getMonth() - 1) - 31; - var firstMondayUntilEndJanuary = 31 - firstMonday.getDate(); - var days = firstMondayUntilEndJanuary + februaryFirstUntilEndMonth + endDate.getDate(); - return leadingNulls(Math.ceil(days / 7), 2) - } - return compareByDay(firstMonday, janFirst) === 0 ? "01" : "00" - }, - "%y": function(date) { - return (date.tm_year + 1900).toString().substring(2) - }, - "%Y": function(date) { - return date.tm_year + 1900 - }, - "%z": function(date) { - var off = date.tm_gmtoff; - var ahead = off >= 0; - off = Math.abs(off) / 60; - off = off / 60 * 100 + off % 60; - return (ahead ? "+" : "-") + String("0000" + off).slice(-4) - }, - "%Z": function(date) { - return date.tm_zone - }, - "%%": function() { - return "%" - } - }; - for (var rule in EXPANSION_RULES_2) { - if (pattern.indexOf(rule) >= 0) { - pattern = pattern.replace(new RegExp(rule, "g"), EXPANSION_RULES_2[rule](date)) - } - } - var bytes = intArrayFromString(pattern, false); - if (bytes.length > maxsize) { - return 0 - } - writeArrayToMemory(bytes, s); - return bytes.length - 1 -} - -function _strftime_l(s, maxsize, format, tm) { - return _strftime(s, maxsize, format, tm) -} -var FSNode = function(parent, name, mode, rdev) { - if (!parent) { - parent = this - } - this.parent = parent; - this.mount = parent.mount; - this.mounted = null; - this.id = FS.nextInode++; - this.name = name; - this.mode = mode; - this.node_ops = {}; - this.stream_ops = {}; - this.rdev = rdev -}; -var readMode = 292 | 73; -var writeMode = 146; -Object.defineProperties(FSNode.prototype, { - read: { - get: function() { - return (this.mode & readMode) === readMode - }, - set: function(val) { - val ? this.mode |= readMode : this.mode &= ~readMode - } - }, - write: { - get: function() { - return (this.mode & writeMode) === writeMode - }, - set: function(val) { - val ? this.mode |= writeMode : this.mode &= ~writeMode - } - }, - isFolder: { - get: function() { - return FS.isDir(this.mode) - } - }, - isDevice: { - get: function() { - return FS.isChrdev(this.mode) - } - } -}); -FS.FSNode = FSNode; -FS.staticInit(); - -function intArrayFromString(stringy, dontAddNull, length) { - var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1; - var u8array = new Array(len); - var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length); - if (dontAddNull) u8array.length = numBytesWritten; - return u8array -} -__ATINIT__.push({ - func: function() { - ___wasm_call_ctors() - } -}); -var asmLibraryArg = { - "m": ___cxa_allocate_exception, - "l": ___cxa_throw, - "c": _abort, - "k": _emscripten_memcpy_big, - "d": _emscripten_resize_heap, - "f": _environ_get, - "g": _environ_sizes_get, - "i": _fd_close, - "h": _fd_read, - "j": _fd_seek, - "b": _fd_write, - "a": wasmMemory, - "e": _strftime_l -}; -var asm = createWasm(); -var ___wasm_call_ctors = Module.___wasm_call_ctors = function() { - return (___wasm_call_ctors = Module.___wasm_call_ctors = Module.asm.o).apply(null, arguments) -}; -var _Encoder_new = Module._Encoder_new = function() { - return (_Encoder_new = Module._Encoder_new = Module.asm.p).apply(null, arguments) -}; -var _Encoder_delete = Module._Encoder_delete = function() { - return (_Encoder_delete = Module._Encoder_delete = Module.asm.q).apply(null, arguments) -}; -var _Encoder_input = Module._Encoder_input = function() { - return (_Encoder_input = Module._Encoder_input = Module.asm.r).apply(null, arguments) -}; -var _Encoder_output = Module._Encoder_output = function() { - return (_Encoder_output = Module._Encoder_output = Module.asm.s).apply(null, arguments) -}; -var _Decoder_new = Module._Decoder_new = function() { - return (_Decoder_new = Module._Decoder_new = Module.asm.t).apply(null, arguments) -}; -var _Decoder_delete = Module._Decoder_delete = function() { - return (_Decoder_delete = Module._Decoder_delete = Module.asm.u).apply(null, arguments) -}; -var _Decoder_input = Module._Decoder_input = function() { - return (_Decoder_input = Module._Decoder_input = Module.asm.v).apply(null, arguments) -}; -var _Decoder_output = Module._Decoder_output = function() { - return (_Decoder_output = Module._Decoder_output = Module.asm.w).apply(null, arguments) -}; -var _String_size = Module._String_size = function() { - return (_String_size = Module._String_size = Module.asm.x).apply(null, arguments) -}; -var _String_new = Module._String_new = function() { - return (_String_new = Module._String_new = Module.asm.y).apply(null, arguments) -}; -var _String_data = Module._String_data = function() { - return (_String_data = Module._String_data = Module.asm.z).apply(null, arguments) -}; -var _String_delete = Module._String_delete = function() { - return (_String_delete = Module._String_delete = Module.asm.A).apply(null, arguments) -}; -var _Int16Array_size = Module._Int16Array_size = function() { - return (_Int16Array_size = Module._Int16Array_size = Module.asm.B).apply(null, arguments) -}; -var _Int16Array_new = Module._Int16Array_new = function() { - return (_Int16Array_new = Module._Int16Array_new = Module.asm.C).apply(null, arguments) -}; -var _Int16Array_data = Module._Int16Array_data = function() { - return (_Int16Array_data = Module._Int16Array_data = Module.asm.D).apply(null, arguments) -}; -var _Int16Array_delete = Module._Int16Array_delete = function() { - return (_Int16Array_delete = Module._Int16Array_delete = Module.asm.E).apply(null, arguments) -}; -var _malloc = Module._malloc = function() { - return (_malloc = Module._malloc = Module.asm.F).apply(null, arguments) -}; -var _free = Module._free = function() { - return (_free = Module._free = Module.asm.G).apply(null, arguments) -}; -var ___errno_location = Module.___errno_location = function() { - return (___errno_location = Module.___errno_location = Module.asm.H).apply(null, arguments) -}; -var calledRun; - -function ExitStatus(status) { - this.name = "ExitStatus"; - this.message = "Program terminated with exit(" + status + ")"; - this.status = status -} -dependenciesFulfilled = function runCaller() { - if (!calledRun) run(); - if (!calledRun) dependenciesFulfilled = runCaller -}; - -function run(args) { - args = args || arguments_; - if (runDependencies > 0) { - return - } - preRun(); - if (runDependencies > 0) return; - - function doRun() { - if (calledRun) return; - calledRun = true; - Module.calledRun = true; - if (ABORT) return; - initRuntime(); - preMain(); - if (Module.onRuntimeInitialized) Module.onRuntimeInitialized(); - postRun() - } - if (Module.setStatus) { - Module.setStatus("Running..."); - setTimeout(function() { - setTimeout(function() { - Module.setStatus("") - }, 1); - doRun() - }, 1) - } else { - doRun() - } -} -Module.run = run; -if (Module.preInit) { - if (typeof Module.preInit === "function") Module.preInit = [Module.preInit]; - while (Module.preInit.length > 0) { - Module.preInit.pop()() - } -} -noExitRuntime = true; -run(); - -function Encoder(channels, samplerate, bitrate, frame_size, voice_optimization) { - this.enc = Module._Encoder_new.apply(null, arguments); - this.out = Module._String_new() -} -Encoder.prototype.destroy = function() { - Module._Encoder_delete(this.enc); - Module._String_delete(this.out) -}; -Encoder.prototype.input = function(samples) { - var ptr = Module._malloc(samples.length * samples.BYTES_PER_ELEMENT); - var pdata = new Uint8Array(Module.HEAPU8.buffer, ptr, samples.length * samples.BYTES_PER_ELEMENT); - pdata.set(new Uint8Array(samples.buffer, samples.byteOffset, samples.length * samples.BYTES_PER_ELEMENT)); - Module._Encoder_input(this.enc, ptr, samples.length); - Module._free(ptr) -}; -Encoder.prototype.output = function() { - var ok = Module._Encoder_output(this.enc, this.out); - if (ok) { - return new Uint8Array(Module.HEAPU8.buffer, Module._String_data(this.out), Module._String_size(this.out)) - } else { - throw new Error('not ok'); - } -}; - -function Decoder(channels, samplerate) { - this.dec = Module._Decoder_new.apply(null, arguments); - this.out = Module._Int16Array_new() -} -Decoder.prototype.destroy = function() { - Module._Decoder_delete(this.dec); - Module._Int16Array_delete(this.out) -}; -Decoder.prototype.input = function(packet) { - var ptr = Module._malloc(packet.length * packet.BYTES_PER_ELEMENT); - var pdata = new Uint8Array(Module.HEAPU8.buffer, ptr, packet.length * packet.BYTES_PER_ELEMENT); - pdata.set(new Uint8Array(packet.buffer, packet.byteOffset, packet.length * packet.BYTES_PER_ELEMENT)); - Module._Decoder_input(this.dec, ptr, packet.length); - Module._free(ptr) -}; -Decoder.prototype.output = function() { - var ok = Module._Decoder_output(this.dec, this.out); - if (ok) { - return new Int16Array(Module.HEAPU8.buffer, Module._Int16Array_data(this.out), Module._Int16Array_size(this.out)) - // } else { - // throw new Error('not ok'); - } -}; -Module.Encoder = Encoder; -Module.Decoder = Decoder; -if (Module.ENVIRONMENT != "NODE") libopus = Module; -let accept; -const p = new Promise((a, r) => { - accept = a; -}); -libopus.waitForReady = () => p; -libopus.onRuntimeInitialized = () => { - accept(); -}; -export default libopus; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs/libopus.wasm.fs.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs/libopus.wasm.fs.js deleted file mode 100644 index fb1ed4115..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs/libopus.wasm.fs.js +++ /dev/null @@ -1,3741 +0,0 @@ -import path from 'path'; -import fs from 'fs'; - -const loadWasm = p => { - const b = fs.readFileSync(p); - const m = new WebAssembly.Module(b); - return m; -}; - -const dirname = path.dirname(new URL(import.meta.url).pathname); -const wasm = loadWasm(path.join(dirname, '/libopus.wasm')); - -const location = new URL('http://localhost'); - -let libopus; -var Module = typeof Module !== "undefined" ? Module : {}; -Module.onRuntimeInitialized = function() { - if (Module.onload) Module.onload(); - Module.loaded = true -}; -Module.locateFile = function(url) { - if (url == "libopusjs/libopus.wasm" && typeof LIBOPUS_WASM_URL !== "undefined") return LIBOPUS_WASM_URL; - else return url -}; -var moduleOverrides = {}; -var key; -for (key in Module) { - if (Module.hasOwnProperty(key)) { - moduleOverrides[key] = Module[key] - } -} -var arguments_ = []; -var thisProgram = "./this.program"; -var quit_ = function(status, toThrow) { - throw toThrow -}; -var ENVIRONMENT_IS_WEB = true; -var ENVIRONMENT_IS_WORKER = false; -var ENVIRONMENT_IS_NODE = false; -var ENVIRONMENT_IS_SHELL = false; -// ENVIRONMENT_IS_WEB = typeof window === "object"; -// ENVIRONMENT_IS_WORKER = typeof importScripts === "function"; -// ENVIRONMENT_IS_NODE = typeof process === "object" && typeof process.versions === "object" && typeof process.versions.node === "string"; -// ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; -var scriptDirectory = ""; - -function locateFile(path) { - if (Module.locateFile) { - return Module.locateFile(path, scriptDirectory) - } - return scriptDirectory + path -} -var read_, readAsync, readBinary, setWindowTitle; -var nodeFS; -var nodePath; -if (ENVIRONMENT_IS_NODE) { - if (ENVIRONMENT_IS_WORKER) { - scriptDirectory = require("path").dirname(scriptDirectory) + "/" - } else { - scriptDirectory = __dirname + "/" - } - read_ = function shell_read(filename, binary) { - throw new Error("no fs"); - // if (!nodeFS) nodeFS = require("fs"); - if (!nodePath) nodePath = require("path"); - filename = nodePath.normalize(filename); - return nodeFS.readFileSync(filename, binary ? null : "utf8") - }; - readBinary = function readBinary(filename) { - var ret = read_(filename, true); - if (!ret.buffer) { - ret = new Uint8Array(ret) - } - assert(ret.buffer); - return ret - }; - if (process.argv.length > 1) { - thisProgram = process.argv[1].replace(/\\/g, "/") - } - arguments_ = process.argv.slice(2); - // if (typeof module !== "undefined") { - // module.exports = Module - // } - process.on("uncaughtException", function(ex) { - if (!(ex instanceof ExitStatus)) { - throw ex - } - }); - process.on("unhandledRejection", abort); - quit_ = function(status) { - process.exit(status) - }; - Module.inspect = function() { - return "[Emscripten Module object]" - } -} else if (ENVIRONMENT_IS_SHELL) { - if (typeof read !== "undefined") { - read_ = function shell_read(f) { - return read(f) - } - } - readBinary = function readBinary(f) { - var data; - if (typeof readbuffer === "function") { - return new Uint8Array(readbuffer(f)) - } - data = read(f, "binary"); - assert(typeof data === "object"); - return data - }; - if (typeof scriptArgs !== "undefined") { - arguments_ = scriptArgs - } else if (typeof arguments !== "undefined") { - arguments_ = arguments - } - if (typeof quit === "function") { - quit_ = function(status) { - quit(status) - } - } - if (typeof print !== "undefined") { - if (typeof console === "undefined") console = {}; - console.log = print; - console.warn = console.error = typeof printErr !== "undefined" ? printErr : print - } -} else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { - if (ENVIRONMENT_IS_WORKER) { - scriptDirectory = location.href - } else if (globalThis.document?.currentScript) { - scriptDirectory = globalThis.document?.currentScript.src - } - if (scriptDirectory.indexOf("blob:") !== 0) { - scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf("/") + 1) - } else { - scriptDirectory = "" - } { - read_ = function shell_read(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - xhr.send(null); - return xhr.responseText - }; - if (ENVIRONMENT_IS_WORKER) { - readBinary = function readBinary(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - xhr.responseType = "arraybuffer"; - xhr.send(null); - return new Uint8Array(xhr.response) - } - } - readAsync = function readAsync(url, onload, onerror) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, true); - xhr.responseType = "arraybuffer"; - xhr.onload = function xhr_onload() { - if (xhr.status == 200 || xhr.status == 0 && xhr.response) { - onload(xhr.response); - return - } - onerror() - }; - xhr.onerror = onerror; - xhr.send(null) - } - } - setWindowTitle = function(title) { - globalThis.document && (globalThis.document.title = title); - } -} else {} -var out = Module.print || console.log.bind(console); -var err = Module.printErr || console.warn.bind(console); -for (key in moduleOverrides) { - if (moduleOverrides.hasOwnProperty(key)) { - Module[key] = moduleOverrides[key] - } -} -moduleOverrides = null; -if (Module.arguments) arguments_ = Module.arguments; -if (Module.thisProgram) thisProgram = Module.thisProgram; -if (Module.quit) quit_ = Module.quit; -var STACK_ALIGN = 16; - -function alignMemory(size, factor) { - if (!factor) factor = STACK_ALIGN; - return Math.ceil(size / factor) * factor -} -var wasmBinary; -if (Module.wasmBinary) wasmBinary = Module.wasmBinary; -var noExitRuntime; -if (Module.noExitRuntime) noExitRuntime = Module.noExitRuntime; -if (typeof WebAssembly !== "object") { - abort("no native wasm support detected") -} -var wasmMemory; -var wasmTable; -var ABORT = false; -var EXITSTATUS = 0; - -function assert(condition, text) { - if (!condition) { - abort("Assertion failed: " + text) - } -} -var UTF8Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf8") : undefined; - -function UTF8ArrayToString(heap, idx, maxBytesToRead) { - var endIdx = idx + maxBytesToRead; - var endPtr = idx; - while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr; - if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) { - return UTF8Decoder.decode(heap.subarray(idx, endPtr)) - } else { - var str = ""; - while (idx < endPtr) { - var u0 = heap[idx++]; - if (!(u0 & 128)) { - str += String.fromCharCode(u0); - continue - } - var u1 = heap[idx++] & 63; - if ((u0 & 224) == 192) { - str += String.fromCharCode((u0 & 31) << 6 | u1); - continue - } - var u2 = heap[idx++] & 63; - if ((u0 & 240) == 224) { - u0 = (u0 & 15) << 12 | u1 << 6 | u2 - } else { - u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heap[idx++] & 63 - } - if (u0 < 65536) { - str += String.fromCharCode(u0) - } else { - var ch = u0 - 65536; - str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023) - } - } - } - return str -} - -function UTF8ToString(ptr, maxBytesToRead) { - return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : "" -} - -function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) { - if (!(maxBytesToWrite > 0)) return 0; - var startIdx = outIdx; - var endIdx = outIdx + maxBytesToWrite - 1; - for (var i = 0; i < str.length; ++i) { - var u = str.charCodeAt(i); - if (u >= 55296 && u <= 57343) { - var u1 = str.charCodeAt(++i); - u = 65536 + ((u & 1023) << 10) | u1 & 1023 - } - if (u <= 127) { - if (outIdx >= endIdx) break; - heap[outIdx++] = u - } else if (u <= 2047) { - if (outIdx + 1 >= endIdx) break; - heap[outIdx++] = 192 | u >> 6; - heap[outIdx++] = 128 | u & 63 - } else if (u <= 65535) { - if (outIdx + 2 >= endIdx) break; - heap[outIdx++] = 224 | u >> 12; - heap[outIdx++] = 128 | u >> 6 & 63; - heap[outIdx++] = 128 | u & 63 - } else { - if (outIdx + 3 >= endIdx) break; - heap[outIdx++] = 240 | u >> 18; - heap[outIdx++] = 128 | u >> 12 & 63; - heap[outIdx++] = 128 | u >> 6 & 63; - heap[outIdx++] = 128 | u & 63 - } - } - heap[outIdx] = 0; - return outIdx - startIdx -} - -function stringToUTF8(str, outPtr, maxBytesToWrite) { - return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite) -} - -function lengthBytesUTF8(str) { - var len = 0; - for (var i = 0; i < str.length; ++i) { - var u = str.charCodeAt(i); - if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023; - if (u <= 127) ++len; - else if (u <= 2047) len += 2; - else if (u <= 65535) len += 3; - else len += 4 - } - return len -} - -function writeArrayToMemory(array, buffer) { - HEAP8.set(array, buffer) -} - -function writeAsciiToMemory(str, buffer, dontAddNull) { - for (var i = 0; i < str.length; ++i) { - HEAP8[buffer++ >> 0] = str.charCodeAt(i) - } - if (!dontAddNull) HEAP8[buffer >> 0] = 0 -} -var WASM_PAGE_SIZE = 65536; -var buffer, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64; - -function updateGlobalBufferAndViews(buf) { - buffer = buf; - Module.HEAP8 = HEAP8 = new Int8Array(buf); - Module.HEAP16 = HEAP16 = new Int16Array(buf); - Module.HEAP32 = HEAP32 = new Int32Array(buf); - Module.HEAPU8 = HEAPU8 = new Uint8Array(buf); - Module.HEAPU16 = HEAPU16 = new Uint16Array(buf); - Module.HEAPU32 = HEAPU32 = new Uint32Array(buf); - Module.HEAPF32 = HEAPF32 = new Float32Array(buf); - Module.HEAPF64 = HEAPF64 = new Float64Array(buf) -} -var INITIAL_INITIAL_MEMORY = Module.INITIAL_MEMORY || 16777216; -if (Module.wasmMemory) { - wasmMemory = Module.wasmMemory -} else { - wasmMemory = new WebAssembly.Memory({ - "initial": INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE, - "maximum": INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE - }) -} -if (wasmMemory) { - buffer = wasmMemory.buffer -} -INITIAL_INITIAL_MEMORY = buffer.byteLength; -updateGlobalBufferAndViews(buffer); -var __ATPRERUN__ = []; -var __ATINIT__ = []; -var __ATMAIN__ = []; -var __ATPOSTRUN__ = []; -var runtimeInitialized = false; - -function preRun() { - if (Module.preRun) { - if (typeof Module.preRun === "function") Module.preRun = [Module.preRun]; - while (Module.preRun.length) { - addOnPreRun(Module.preRun.shift()) - } - } - callRuntimeCallbacks(__ATPRERUN__) -} - -function initRuntime() { - runtimeInitialized = true; - if (!Module.noFSInit && !FS.init.initialized) FS.init(); - TTY.init(); - callRuntimeCallbacks(__ATINIT__) -} - -function preMain() { - FS.ignorePermissions = false; - callRuntimeCallbacks(__ATMAIN__) -} - -function postRun() { - if (Module.postRun) { - if (typeof Module.postRun === "function") Module.postRun = [Module.postRun]; - while (Module.postRun.length) { - addOnPostRun(Module.postRun.shift()) - } - } - callRuntimeCallbacks(__ATPOSTRUN__) -} - -function addOnPreRun(cb) { - __ATPRERUN__.unshift(cb) -} - -function addOnPostRun(cb) { - __ATPOSTRUN__.unshift(cb) -} -var runDependencies = 0; -var runDependencyWatcher = null; -var dependenciesFulfilled = null; - -function getUniqueRunDependency(id) { - return id -} - -function addRunDependency(id) { - runDependencies++; - if (Module.monitorRunDependencies) { - Module.monitorRunDependencies(runDependencies) - } -} - -function removeRunDependency(id) { - runDependencies--; - if (Module.monitorRunDependencies) { - Module.monitorRunDependencies(runDependencies) - } - if (runDependencies == 0) { - if (runDependencyWatcher !== null) { - clearInterval(runDependencyWatcher); - runDependencyWatcher = null - } - if (dependenciesFulfilled) { - var callback = dependenciesFulfilled; - dependenciesFulfilled = null; - callback() - } - } -} -Module.preloadedImages = {}; -Module.preloadedAudios = {}; - -function abort(what) { - if (Module.onAbort) { - Module.onAbort(what) - } - what += ""; - err(what); - ABORT = true; - EXITSTATUS = 1; - what = "abort(" + what + "). Build with -s ASSERTIONS=1 for more info."; - var e = new WebAssembly.RuntimeError(what); - throw e -} - -function hasPrefix(str, prefix) { - return String.prototype.startsWith ? str.startsWith(prefix) : str.indexOf(prefix) === 0 -} -var dataURIPrefix = "data:application/octet-stream;base64,"; - -function isDataURI(filename) { - return hasPrefix(filename, dataURIPrefix) -} -var fileURIPrefix = "file://"; - -function isFileURI(filename) { - return hasPrefix(filename, fileURIPrefix) -} -var wasmBinaryFile = "libopusjs/libopus.wasm"; -if (!isDataURI(wasmBinaryFile)) { - wasmBinaryFile = locateFile(wasmBinaryFile) -} - -function getBinary() { - try { - if (wasmBinary) { - return new Uint8Array(wasmBinary) - } - if (readBinary) { - return readBinary(wasmBinaryFile) - } else { - throw "both async and sync fetching of the wasm failed" - } - } catch (err) { - abort(err) - } -} - -async function getBinaryPromise() { - return wasm; - /* if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && typeof fetch === "function" && !isFileURI(wasmBinaryFile)) { - console.log('binary promise', { - wasmBinaryFile, - }); - const s = new URL(wasmBinaryFile, 'http://localhost'); - return fetch(s, { - // credentials: "same-origin" - }).then(function(response) { - if (!response.ok) { - throw "failed to load wasm binary file at '" + wasmBinaryFile + "'" - } - return response.arrayBuffer() - }).catch(function() { - return getBinary() - }) - } - return Promise.resolve().then(getBinary) */ -} - -function createWasm() { - var info = { - "a": asmLibraryArg - }; - - function receiveInstance(instance, module) { - var exports = instance.exports; - Module.asm = exports; - wasmTable = Module.asm.n; - removeRunDependency("wasm-instantiate") - } - addRunDependency("wasm-instantiate"); - - function receiveInstantiatedSource(output) { - receiveInstance(output.instance) - } - - function instantiateArrayBuffer(receiver) { - return getBinaryPromise().then(function(binary) { - return WebAssembly.instantiate(binary, info) - }).then(receiver, function(reason) { - err("failed to asynchronously prepare wasm: " + reason); - abort(reason) - }) - } - - async function instantiateAsync() { - const instance = await WebAssembly.instantiate(wasm, info); - receiveInstance(instance); - } - if (Module.instantiateWasm) { - try { - var exports = Module.instantiateWasm(info, receiveInstance); - return exports - } catch (e) { - err("Module.instantiateWasm callback failed with error: " + e); - return false - } - } - instantiateAsync(); - return {} -} -var tempDouble; -var tempI64; - -function callRuntimeCallbacks(callbacks) { - while (callbacks.length > 0) { - var callback = callbacks.shift(); - if (typeof callback === "function") { - callback(Module); - continue - } - var func = callback.func; - if (typeof func === "number") { - if (callback.arg === undefined) { - wasmTable.get(func)() - } else { - wasmTable.get(func)(callback.arg) - } - } else { - func(callback.arg === undefined ? null : callback.arg) - } - } -} - -function demangle(func) { - return func -} - -function demangleAll(text) { - var regex = /\b_Z[\w\d_]+/g; - return text.replace(regex, function(x) { - var y = demangle(x); - return x === y ? x : y + " [" + x + "]" - }) -} - -function jsStackTrace() { - var error = new Error; - if (!error.stack) { - try { - throw new Error - } catch (e) { - error = e - } - if (!error.stack) { - return "(no stack trace available)" - } - } - return error.stack.toString() -} - -function stackTrace() { - var js = jsStackTrace(); - if (Module.extraStackTrace) js += "\n" + Module.extraStackTrace(); - return demangleAll(js) -} -var ExceptionInfoAttrs = { - DESTRUCTOR_OFFSET: 0, - REFCOUNT_OFFSET: 4, - TYPE_OFFSET: 8, - CAUGHT_OFFSET: 12, - RETHROWN_OFFSET: 13, - SIZE: 16 -}; - -function ___cxa_allocate_exception(size) { - return _malloc(size + ExceptionInfoAttrs.SIZE) + ExceptionInfoAttrs.SIZE -} - -function ExceptionInfo(excPtr) { - this.excPtr = excPtr; - this.ptr = excPtr - ExceptionInfoAttrs.SIZE; - this.set_type = function(type) { - HEAP32[this.ptr + ExceptionInfoAttrs.TYPE_OFFSET >> 2] = type - }; - this.get_type = function() { - return HEAP32[this.ptr + ExceptionInfoAttrs.TYPE_OFFSET >> 2] - }; - this.set_destructor = function(destructor) { - HEAP32[this.ptr + ExceptionInfoAttrs.DESTRUCTOR_OFFSET >> 2] = destructor - }; - this.get_destructor = function() { - return HEAP32[this.ptr + ExceptionInfoAttrs.DESTRUCTOR_OFFSET >> 2] - }; - this.set_refcount = function(refcount) { - HEAP32[this.ptr + ExceptionInfoAttrs.REFCOUNT_OFFSET >> 2] = refcount - }; - this.set_caught = function(caught) { - caught = caught ? 1 : 0; - HEAP8[this.ptr + ExceptionInfoAttrs.CAUGHT_OFFSET >> 0] = caught - }; - this.get_caught = function() { - return HEAP8[this.ptr + ExceptionInfoAttrs.CAUGHT_OFFSET >> 0] != 0 - }; - this.set_rethrown = function(rethrown) { - rethrown = rethrown ? 1 : 0; - HEAP8[this.ptr + ExceptionInfoAttrs.RETHROWN_OFFSET >> 0] = rethrown - }; - this.get_rethrown = function() { - return HEAP8[this.ptr + ExceptionInfoAttrs.RETHROWN_OFFSET >> 0] != 0 - }; - this.init = function(type, destructor) { - this.set_type(type); - this.set_destructor(destructor); - this.set_refcount(0); - this.set_caught(false); - this.set_rethrown(false) - }; - this.add_ref = function() { - var value = HEAP32[this.ptr + ExceptionInfoAttrs.REFCOUNT_OFFSET >> 2]; - HEAP32[this.ptr + ExceptionInfoAttrs.REFCOUNT_OFFSET >> 2] = value + 1 - }; - this.release_ref = function() { - var prev = HEAP32[this.ptr + ExceptionInfoAttrs.REFCOUNT_OFFSET >> 2]; - HEAP32[this.ptr + ExceptionInfoAttrs.REFCOUNT_OFFSET >> 2] = prev - 1; - return prev === 1 - } -} -var exceptionLast = 0; - -function __ZSt18uncaught_exceptionv() { - return __ZSt18uncaught_exceptionv.uncaught_exceptions > 0 -} - -function ___cxa_throw(ptr, type, destructor) { - var info = new ExceptionInfo(ptr); - info.init(type, destructor); - exceptionLast = ptr; - if (!("uncaught_exception" in __ZSt18uncaught_exceptionv)) { - __ZSt18uncaught_exceptionv.uncaught_exceptions = 1 - } else { - __ZSt18uncaught_exceptionv.uncaught_exceptions++ - } - throw ptr -} - -function _abort() { - abort() -} - -function _emscripten_memcpy_big(dest, src, num) { - HEAPU8.copyWithin(dest, src, src + num) -} - -function abortOnCannotGrowMemory(requestedSize) { - abort("OOM") -} - -function _emscripten_resize_heap(requestedSize) { - requestedSize = requestedSize >>> 0; - abortOnCannotGrowMemory(requestedSize) -} -var ENV = {}; - -function getExecutableName() { - return thisProgram || "./this.program" -} - -function getEnvStrings() { - if (!getEnvStrings.strings) { - var lang = (typeof navigator === "object" && navigator.languages && navigator.languages[0] || "C").replace("-", "_") + ".UTF-8"; - var env = { - "USER": "web_user", - "LOGNAME": "web_user", - "PATH": "/", - "PWD": "/", - "HOME": "/home/web_user", - "LANG": lang, - "_": getExecutableName() - }; - for (var x in ENV) { - env[x] = ENV[x] - } - var strings = []; - for (var x in env) { - strings.push(x + "=" + env[x]) - } - getEnvStrings.strings = strings - } - return getEnvStrings.strings -} - -function _environ_get(__environ, environ_buf) { - var bufSize = 0; - getEnvStrings().forEach(function(string, i) { - var ptr = environ_buf + bufSize; - HEAP32[__environ + i * 4 >> 2] = ptr; - writeAsciiToMemory(string, ptr); - bufSize += string.length + 1 - }); - return 0 -} - -function _environ_sizes_get(penviron_count, penviron_buf_size) { - var strings = getEnvStrings(); - HEAP32[penviron_count >> 2] = strings.length; - var bufSize = 0; - strings.forEach(function(string) { - bufSize += string.length + 1 - }); - HEAP32[penviron_buf_size >> 2] = bufSize; - return 0 -} -var PATH = { - splitPath: function(filename) { - var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; - return splitPathRe.exec(filename).slice(1) - }, - normalizeArray: function(parts, allowAboveRoot) { - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === ".") { - parts.splice(i, 1) - } else if (last === "..") { - parts.splice(i, 1); - up++ - } else if (up) { - parts.splice(i, 1); - up-- - } - } - if (allowAboveRoot) { - for (; up; up--) { - parts.unshift("..") - } - } - return parts - }, - normalize: function(path) { - var isAbsolute = path.charAt(0) === "/"; - var trailingSlash = path.substr(-1) === "/"; - path = PATH.normalizeArray(path.split("/").filter(function(p) { - return !!p - }), !isAbsolute).join("/"); - if (!path && !isAbsolute) { - path = "." - } - if (path && trailingSlash) { - path += "/" - } - return (isAbsolute ? "/" : "") + path - }, - dirname: function(path) { - var result = PATH.splitPath(path); - var root = result[0]; - var dir = result[1]; - if (!root && !dir) { - return "." - } - if (dir) { - dir = dir.substr(0, dir.length - 1) - } - return root + dir - }, - basename: function(path) { - if (path === "/") return "/"; - path = PATH.normalize(path); - path = path.replace(/\/$/, ""); - var lastSlash = path.lastIndexOf("/"); - if (lastSlash === -1) return path; - return path.substr(lastSlash + 1) - }, - extname: function(path) { - return PATH.splitPath(path)[3] - }, - join: function() { - var paths = Array.prototype.slice.call(arguments, 0); - return PATH.normalize(paths.join("/")) - }, - join2: function(l, r) { - return PATH.normalize(l + "/" + r) - } -}; - -function setErrNo(value) { - HEAP32[___errno_location() >> 2] = value; - return value -} - -function getRandomDevice() { - if (typeof crypto === "object" && typeof crypto.getRandomValues === "function") { - var randomBuffer = new Uint8Array(1); - return function() { - crypto.getRandomValues(randomBuffer); - return randomBuffer[0] - } - } else if (ENVIRONMENT_IS_NODE) { - try { - var crypto_module = require("crypto"); - return function() { - return crypto_module.randomBytes(1)[0] - } - } catch (e) {} - } - return function() { - abort("randomDevice") - } -} -var PATH_FS = { - resolve: function() { - var resolvedPath = ""; - var resolvedAbsolute = false; - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = i >= 0 ? arguments[i] : FS.cwd(); - if (typeof path !== "string") { - throw new TypeError("Arguments to path.resolve must be strings") - } else if (!path) { - return "" - } - resolvedPath = path + "/" + resolvedPath; - resolvedAbsolute = path.charAt(0) === "/" - } - resolvedPath = PATH.normalizeArray(resolvedPath.split("/").filter(function(p) { - return !!p - }), !resolvedAbsolute).join("/"); - return (resolvedAbsolute ? "/" : "") + resolvedPath || "." - }, - relative: function(from, to) { - from = PATH_FS.resolve(from).substr(1); - to = PATH_FS.resolve(to).substr(1); - - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== "") break - } - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== "") break - } - if (start > end) return []; - return arr.slice(start, end - start + 1) - } - var fromParts = trim(from.split("/")); - var toParts = trim(to.split("/")); - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break - } - } - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push("..") - } - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - return outputParts.join("/") - } -}; -var TTY = { - ttys: [], - init: function() {}, - shutdown: function() {}, - register: function(dev, ops) { - TTY.ttys[dev] = { - input: [], - output: [], - ops: ops - }; - FS.registerDevice(dev, TTY.stream_ops) - }, - stream_ops: { - open: function(stream) { - var tty = TTY.ttys[stream.node.rdev]; - if (!tty) { - throw new FS.ErrnoError(43) - } - stream.tty = tty; - stream.seekable = false - }, - close: function(stream) { - stream.tty.ops.flush(stream.tty) - }, - flush: function(stream) { - stream.tty.ops.flush(stream.tty) - }, - read: function(stream, buffer, offset, length, pos) { - if (!stream.tty || !stream.tty.ops.get_char) { - throw new FS.ErrnoError(60) - } - var bytesRead = 0; - for (var i = 0; i < length; i++) { - var result; - try { - result = stream.tty.ops.get_char(stream.tty) - } catch (e) { - throw new FS.ErrnoError(29) - } - if (result === undefined && bytesRead === 0) { - throw new FS.ErrnoError(6) - } - if (result === null || result === undefined) break; - bytesRead++; - buffer[offset + i] = result - } - if (bytesRead) { - stream.node.timestamp = Date.now() - } - return bytesRead - }, - write: function(stream, buffer, offset, length, pos) { - if (!stream.tty || !stream.tty.ops.put_char) { - throw new FS.ErrnoError(60) - } - try { - for (var i = 0; i < length; i++) { - stream.tty.ops.put_char(stream.tty, buffer[offset + i]) - } - } catch (e) { - throw new FS.ErrnoError(29) - } - if (length) { - stream.node.timestamp = Date.now() - } - return i - } - }, - default_tty_ops: { - get_char: function(tty) { - if (!tty.input.length) { - var result = null; - if (ENVIRONMENT_IS_NODE) { - var BUFSIZE = 256; - var buf = Buffer.alloc ? Buffer.alloc(BUFSIZE) : new Buffer(BUFSIZE); - var bytesRead = 0; - try { - bytesRead = nodeFS.readSync(process.stdin.fd, buf, 0, BUFSIZE, null) - } catch (e) { - if (e.toString().indexOf("EOF") != -1) bytesRead = 0; - else throw e - } - if (bytesRead > 0) { - result = buf.slice(0, bytesRead).toString("utf-8") - } else { - result = null - } - } else if (typeof window !== "undefined" && typeof window.prompt === "function") { - result = window.prompt("Input: "); - if (result !== null) { - result += "\n" - } - } else if (typeof readline === "function") { - result = readline(); - if (result !== null) { - result += "\n" - } - } - if (!result) { - return null - } - tty.input = intArrayFromString(result, true) - } - return tty.input.shift() - }, - put_char: function(tty, val) { - if (val === null || val === 10) { - out(UTF8ArrayToString(tty.output, 0)); - tty.output = [] - } else { - if (val != 0) tty.output.push(val) - } - }, - flush: function(tty) { - if (tty.output && tty.output.length > 0) { - out(UTF8ArrayToString(tty.output, 0)); - tty.output = [] - } - } - }, - default_tty1_ops: { - put_char: function(tty, val) { - if (val === null || val === 10) { - err(UTF8ArrayToString(tty.output, 0)); - tty.output = [] - } else { - if (val != 0) tty.output.push(val) - } - }, - flush: function(tty) { - if (tty.output && tty.output.length > 0) { - err(UTF8ArrayToString(tty.output, 0)); - tty.output = [] - } - } - } -}; - -function mmapAlloc(size) { - var alignedSize = alignMemory(size, 16384); - var ptr = _malloc(alignedSize); - while (size < alignedSize) HEAP8[ptr + size++] = 0; - return ptr -} -var MEMFS = { - ops_table: null, - mount: function(mount) { - return MEMFS.createNode(null, "/", 16384 | 511, 0) - }, - createNode: function(parent, name, mode, dev) { - if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { - throw new FS.ErrnoError(63) - } - if (!MEMFS.ops_table) { - MEMFS.ops_table = { - dir: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr, - lookup: MEMFS.node_ops.lookup, - mknod: MEMFS.node_ops.mknod, - rename: MEMFS.node_ops.rename, - unlink: MEMFS.node_ops.unlink, - rmdir: MEMFS.node_ops.rmdir, - readdir: MEMFS.node_ops.readdir, - symlink: MEMFS.node_ops.symlink - }, - stream: { - llseek: MEMFS.stream_ops.llseek - } - }, - file: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr - }, - stream: { - llseek: MEMFS.stream_ops.llseek, - read: MEMFS.stream_ops.read, - write: MEMFS.stream_ops.write, - allocate: MEMFS.stream_ops.allocate, - mmap: MEMFS.stream_ops.mmap, - msync: MEMFS.stream_ops.msync - } - }, - link: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr, - readlink: MEMFS.node_ops.readlink - }, - stream: {} - }, - chrdev: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr - }, - stream: FS.chrdev_stream_ops - } - } - } - var node = FS.createNode(parent, name, mode, dev); - if (FS.isDir(node.mode)) { - node.node_ops = MEMFS.ops_table.dir.node; - node.stream_ops = MEMFS.ops_table.dir.stream; - node.contents = {} - } else if (FS.isFile(node.mode)) { - node.node_ops = MEMFS.ops_table.file.node; - node.stream_ops = MEMFS.ops_table.file.stream; - node.usedBytes = 0; - node.contents = null - } else if (FS.isLink(node.mode)) { - node.node_ops = MEMFS.ops_table.link.node; - node.stream_ops = MEMFS.ops_table.link.stream - } else if (FS.isChrdev(node.mode)) { - node.node_ops = MEMFS.ops_table.chrdev.node; - node.stream_ops = MEMFS.ops_table.chrdev.stream - } - node.timestamp = Date.now(); - if (parent) { - parent.contents[name] = node - } - return node - }, - getFileDataAsRegularArray: function(node) { - if (node.contents && node.contents.subarray) { - var arr = []; - for (var i = 0; i < node.usedBytes; ++i) arr.push(node.contents[i]); - return arr - } - return node.contents - }, - getFileDataAsTypedArray: function(node) { - if (!node.contents) return new Uint8Array(0); - if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); - return new Uint8Array(node.contents) - }, - expandFileStorage: function(node, newCapacity) { - var prevCapacity = node.contents ? node.contents.length : 0; - if (prevCapacity >= newCapacity) return; - var CAPACITY_DOUBLING_MAX = 1024 * 1024; - newCapacity = Math.max(newCapacity, prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125) >>> 0); - if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); - var oldContents = node.contents; - node.contents = new Uint8Array(newCapacity); - if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); - }, - resizeFileStorage: function(node, newSize) { - if (node.usedBytes == newSize) return; - if (newSize == 0) { - node.contents = null; - node.usedBytes = 0; - return - } - if (!node.contents || node.contents.subarray) { - var oldContents = node.contents; - node.contents = new Uint8Array(newSize); - if (oldContents) { - node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))) - } - node.usedBytes = newSize; - return - } - if (!node.contents) node.contents = []; - if (node.contents.length > newSize) node.contents.length = newSize; - else - while (node.contents.length < newSize) node.contents.push(0); - node.usedBytes = newSize - }, - node_ops: { - getattr: function(node) { - var attr = {}; - attr.dev = FS.isChrdev(node.mode) ? node.id : 1; - attr.ino = node.id; - attr.mode = node.mode; - attr.nlink = 1; - attr.uid = 0; - attr.gid = 0; - attr.rdev = node.rdev; - if (FS.isDir(node.mode)) { - attr.size = 4096 - } else if (FS.isFile(node.mode)) { - attr.size = node.usedBytes - } else if (FS.isLink(node.mode)) { - attr.size = node.link.length - } else { - attr.size = 0 - } - attr.atime = new Date(node.timestamp); - attr.mtime = new Date(node.timestamp); - attr.ctime = new Date(node.timestamp); - attr.blksize = 4096; - attr.blocks = Math.ceil(attr.size / attr.blksize); - return attr - }, - setattr: function(node, attr) { - if (attr.mode !== undefined) { - node.mode = attr.mode - } - if (attr.timestamp !== undefined) { - node.timestamp = attr.timestamp - } - if (attr.size !== undefined) { - MEMFS.resizeFileStorage(node, attr.size) - } - }, - lookup: function(parent, name) { - throw FS.genericErrors[44] - }, - mknod: function(parent, name, mode, dev) { - return MEMFS.createNode(parent, name, mode, dev) - }, - rename: function(old_node, new_dir, new_name) { - if (FS.isDir(old_node.mode)) { - var new_node; - try { - new_node = FS.lookupNode(new_dir, new_name) - } catch (e) {} - if (new_node) { - for (var i in new_node.contents) { - throw new FS.ErrnoError(55) - } - } - } - delete old_node.parent.contents[old_node.name]; - old_node.name = new_name; - new_dir.contents[new_name] = old_node; - old_node.parent = new_dir - }, - unlink: function(parent, name) { - delete parent.contents[name] - }, - rmdir: function(parent, name) { - var node = FS.lookupNode(parent, name); - for (var i in node.contents) { - throw new FS.ErrnoError(55) - } - delete parent.contents[name] - }, - readdir: function(node) { - var entries = [".", ".."]; - for (var key in node.contents) { - if (!node.contents.hasOwnProperty(key)) { - continue - } - entries.push(key) - } - return entries - }, - symlink: function(parent, newname, oldpath) { - var node = MEMFS.createNode(parent, newname, 511 | 40960, 0); - node.link = oldpath; - return node - }, - readlink: function(node) { - if (!FS.isLink(node.mode)) { - throw new FS.ErrnoError(28) - } - return node.link - } - }, - stream_ops: { - read: function(stream, buffer, offset, length, position) { - var contents = stream.node.contents; - if (position >= stream.node.usedBytes) return 0; - var size = Math.min(stream.node.usedBytes - position, length); - if (size > 8 && contents.subarray) { - buffer.set(contents.subarray(position, position + size), offset) - } else { - for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i] - } - return size - }, - write: function(stream, buffer, offset, length, position, canOwn) { - if (!length) return 0; - var node = stream.node; - node.timestamp = Date.now(); - if (buffer.subarray && (!node.contents || node.contents.subarray)) { - if (canOwn) { - node.contents = buffer.subarray(offset, offset + length); - node.usedBytes = length; - return length - } else if (node.usedBytes === 0 && position === 0) { - node.contents = buffer.slice(offset, offset + length); - node.usedBytes = length; - return length - } else if (position + length <= node.usedBytes) { - node.contents.set(buffer.subarray(offset, offset + length), position); - return length - } - } - MEMFS.expandFileStorage(node, position + length); - if (node.contents.subarray && buffer.subarray) { - node.contents.set(buffer.subarray(offset, offset + length), position) - } else { - for (var i = 0; i < length; i++) { - node.contents[position + i] = buffer[offset + i] - } - } - node.usedBytes = Math.max(node.usedBytes, position + length); - return length - }, - llseek: function(stream, offset, whence) { - var position = offset; - if (whence === 1) { - position += stream.position - } else if (whence === 2) { - if (FS.isFile(stream.node.mode)) { - position += stream.node.usedBytes - } - } - if (position < 0) { - throw new FS.ErrnoError(28) - } - return position - }, - allocate: function(stream, offset, length) { - MEMFS.expandFileStorage(stream.node, offset + length); - stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length) - }, - mmap: function(stream, address, length, position, prot, flags) { - assert(address === 0); - if (!FS.isFile(stream.node.mode)) { - throw new FS.ErrnoError(43) - } - var ptr; - var allocated; - var contents = stream.node.contents; - if (!(flags & 2) && contents.buffer === buffer) { - allocated = false; - ptr = contents.byteOffset - } else { - if (position > 0 || position + length < contents.length) { - if (contents.subarray) { - contents = contents.subarray(position, position + length) - } else { - contents = Array.prototype.slice.call(contents, position, position + length) - } - } - allocated = true; - ptr = mmapAlloc(length); - if (!ptr) { - throw new FS.ErrnoError(48) - } - HEAP8.set(contents, ptr) - } - return { - ptr: ptr, - allocated: allocated - } - }, - msync: function(stream, buffer, offset, length, mmapFlags) { - if (!FS.isFile(stream.node.mode)) { - throw new FS.ErrnoError(43) - } - if (mmapFlags & 2) { - return 0 - } - var bytesWritten = MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false); - return 0 - } - } -}; -var FS = { - root: null, - mounts: [], - devices: {}, - streams: [], - nextInode: 1, - nameTable: null, - currentPath: "/", - initialized: false, - ignorePermissions: true, - trackingDelegate: {}, - tracking: { - openFlags: { - READ: 1, - WRITE: 2 - } - }, - ErrnoError: null, - genericErrors: {}, - filesystems: null, - syncFSRequests: 0, - handleFSError: function(e) { - if (!(e instanceof FS.ErrnoError)) throw e + " : " + stackTrace(); - return setErrNo(e.errno) - }, - lookupPath: function(path, opts) { - path = PATH_FS.resolve(FS.cwd(), path); - opts = opts || {}; - if (!path) return { - path: "", - node: null - }; - var defaults = { - follow_mount: true, - recurse_count: 0 - }; - for (var key in defaults) { - if (opts[key] === undefined) { - opts[key] = defaults[key] - } - } - if (opts.recurse_count > 8) { - throw new FS.ErrnoError(32) - } - var parts = PATH.normalizeArray(path.split("/").filter(function(p) { - return !!p - }), false); - var current = FS.root; - var current_path = "/"; - for (var i = 0; i < parts.length; i++) { - var islast = i === parts.length - 1; - if (islast && opts.parent) { - break - } - current = FS.lookupNode(current, parts[i]); - current_path = PATH.join2(current_path, parts[i]); - if (FS.isMountpoint(current)) { - if (!islast || islast && opts.follow_mount) { - current = current.mounted.root - } - } - if (!islast || opts.follow) { - var count = 0; - while (FS.isLink(current.mode)) { - var link = FS.readlink(current_path); - current_path = PATH_FS.resolve(PATH.dirname(current_path), link); - var lookup = FS.lookupPath(current_path, { - recurse_count: opts.recurse_count - }); - current = lookup.node; - if (count++ > 40) { - throw new FS.ErrnoError(32) - } - } - } - } - return { - path: current_path, - node: current - } - }, - getPath: function(node) { - var path; - while (true) { - if (FS.isRoot(node)) { - var mount = node.mount.mountpoint; - if (!path) return mount; - return mount[mount.length - 1] !== "/" ? mount + "/" + path : mount + path - } - path = path ? node.name + "/" + path : node.name; - node = node.parent - } - }, - hashName: function(parentid, name) { - var hash = 0; - for (var i = 0; i < name.length; i++) { - hash = (hash << 5) - hash + name.charCodeAt(i) | 0 - } - return (parentid + hash >>> 0) % FS.nameTable.length - }, - hashAddNode: function(node) { - var hash = FS.hashName(node.parent.id, node.name); - node.name_next = FS.nameTable[hash]; - FS.nameTable[hash] = node - }, - hashRemoveNode: function(node) { - var hash = FS.hashName(node.parent.id, node.name); - if (FS.nameTable[hash] === node) { - FS.nameTable[hash] = node.name_next - } else { - var current = FS.nameTable[hash]; - while (current) { - if (current.name_next === node) { - current.name_next = node.name_next; - break - } - current = current.name_next - } - } - }, - lookupNode: function(parent, name) { - var errCode = FS.mayLookup(parent); - if (errCode) { - throw new FS.ErrnoError(errCode, parent) - } - var hash = FS.hashName(parent.id, name); - for (var node = FS.nameTable[hash]; node; node = node.name_next) { - var nodeName = node.name; - if (node.parent.id === parent.id && nodeName === name) { - return node - } - } - return FS.lookup(parent, name) - }, - createNode: function(parent, name, mode, rdev) { - var node = new FS.FSNode(parent, name, mode, rdev); - FS.hashAddNode(node); - return node - }, - destroyNode: function(node) { - FS.hashRemoveNode(node) - }, - isRoot: function(node) { - return node === node.parent - }, - isMountpoint: function(node) { - return !!node.mounted - }, - isFile: function(mode) { - return (mode & 61440) === 32768 - }, - isDir: function(mode) { - return (mode & 61440) === 16384 - }, - isLink: function(mode) { - return (mode & 61440) === 40960 - }, - isChrdev: function(mode) { - return (mode & 61440) === 8192 - }, - isBlkdev: function(mode) { - return (mode & 61440) === 24576 - }, - isFIFO: function(mode) { - return (mode & 61440) === 4096 - }, - isSocket: function(mode) { - return (mode & 49152) === 49152 - }, - flagModes: { - "r": 0, - "rs": 1052672, - "r+": 2, - "w": 577, - "wx": 705, - "xw": 705, - "w+": 578, - "wx+": 706, - "xw+": 706, - "a": 1089, - "ax": 1217, - "xa": 1217, - "a+": 1090, - "ax+": 1218, - "xa+": 1218 - }, - modeStringToFlags: function(str) { - var flags = FS.flagModes[str]; - if (typeof flags === "undefined") { - throw new Error("Unknown file open mode: " + str) - } - return flags - }, - flagsToPermissionString: function(flag) { - var perms = ["r", "w", "rw"][flag & 3]; - if (flag & 512) { - perms += "w" - } - return perms - }, - nodePermissions: function(node, perms) { - if (FS.ignorePermissions) { - return 0 - } - if (perms.indexOf("r") !== -1 && !(node.mode & 292)) { - return 2 - } else if (perms.indexOf("w") !== -1 && !(node.mode & 146)) { - return 2 - } else if (perms.indexOf("x") !== -1 && !(node.mode & 73)) { - return 2 - } - return 0 - }, - mayLookup: function(dir) { - var errCode = FS.nodePermissions(dir, "x"); - if (errCode) return errCode; - if (!dir.node_ops.lookup) return 2; - return 0 - }, - mayCreate: function(dir, name) { - try { - var node = FS.lookupNode(dir, name); - return 20 - } catch (e) {} - return FS.nodePermissions(dir, "wx") - }, - mayDelete: function(dir, name, isdir) { - var node; - try { - node = FS.lookupNode(dir, name) - } catch (e) { - return e.errno - } - var errCode = FS.nodePermissions(dir, "wx"); - if (errCode) { - return errCode - } - if (isdir) { - if (!FS.isDir(node.mode)) { - return 54 - } - if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) { - return 10 - } - } else { - if (FS.isDir(node.mode)) { - return 31 - } - } - return 0 - }, - mayOpen: function(node, flags) { - if (!node) { - return 44 - } - if (FS.isLink(node.mode)) { - return 32 - } else if (FS.isDir(node.mode)) { - if (FS.flagsToPermissionString(flags) !== "r" || flags & 512) { - return 31 - } - } - return FS.nodePermissions(node, FS.flagsToPermissionString(flags)) - }, - MAX_OPEN_FDS: 4096, - nextfd: function(fd_start, fd_end) { - fd_start = fd_start || 0; - fd_end = fd_end || FS.MAX_OPEN_FDS; - for (var fd = fd_start; fd <= fd_end; fd++) { - if (!FS.streams[fd]) { - return fd - } - } - throw new FS.ErrnoError(33) - }, - getStream: function(fd) { - return FS.streams[fd] - }, - createStream: function(stream, fd_start, fd_end) { - if (!FS.FSStream) { - FS.FSStream = function() {}; - FS.FSStream.prototype = { - object: { - get: function() { - return this.node - }, - set: function(val) { - this.node = val - } - }, - isRead: { - get: function() { - return (this.flags & 2097155) !== 1 - } - }, - isWrite: { - get: function() { - return (this.flags & 2097155) !== 0 - } - }, - isAppend: { - get: function() { - return this.flags & 1024 - } - } - } - } - var newStream = new FS.FSStream; - for (var p in stream) { - newStream[p] = stream[p] - } - stream = newStream; - var fd = FS.nextfd(fd_start, fd_end); - stream.fd = fd; - FS.streams[fd] = stream; - return stream - }, - closeStream: function(fd) { - FS.streams[fd] = null - }, - chrdev_stream_ops: { - open: function(stream) { - var device = FS.getDevice(stream.node.rdev); - stream.stream_ops = device.stream_ops; - if (stream.stream_ops.open) { - stream.stream_ops.open(stream) - } - }, - llseek: function() { - throw new FS.ErrnoError(70) - } - }, - major: function(dev) { - return dev >> 8 - }, - minor: function(dev) { - return dev & 255 - }, - makedev: function(ma, mi) { - return ma << 8 | mi - }, - registerDevice: function(dev, ops) { - FS.devices[dev] = { - stream_ops: ops - } - }, - getDevice: function(dev) { - return FS.devices[dev] - }, - getMounts: function(mount) { - var mounts = []; - var check = [mount]; - while (check.length) { - var m = check.pop(); - mounts.push(m); - check.push.apply(check, m.mounts) - } - return mounts - }, - syncfs: function(populate, callback) { - if (typeof populate === "function") { - callback = populate; - populate = false - } - FS.syncFSRequests++; - if (FS.syncFSRequests > 1) { - err("warning: " + FS.syncFSRequests + " FS.syncfs operations in flight at once, probably just doing extra work") - } - var mounts = FS.getMounts(FS.root.mount); - var completed = 0; - - function doCallback(errCode) { - FS.syncFSRequests--; - return callback(errCode) - } - - function done(errCode) { - if (errCode) { - if (!done.errored) { - done.errored = true; - return doCallback(errCode) - } - return - } - if (++completed >= mounts.length) { - doCallback(null) - } - } - mounts.forEach(function(mount) { - if (!mount.type.syncfs) { - return done(null) - } - mount.type.syncfs(mount, populate, done) - }) - }, - mount: function(type, opts, mountpoint) { - var root = mountpoint === "/"; - var pseudo = !mountpoint; - var node; - if (root && FS.root) { - throw new FS.ErrnoError(10) - } else if (!root && !pseudo) { - var lookup = FS.lookupPath(mountpoint, { - follow_mount: false - }); - mountpoint = lookup.path; - node = lookup.node; - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10) - } - if (!FS.isDir(node.mode)) { - throw new FS.ErrnoError(54) - } - } - var mount = { - type: type, - opts: opts, - mountpoint: mountpoint, - mounts: [] - }; - var mountRoot = type.mount(mount); - mountRoot.mount = mount; - mount.root = mountRoot; - if (root) { - FS.root = mountRoot - } else if (node) { - node.mounted = mount; - if (node.mount) { - node.mount.mounts.push(mount) - } - } - return mountRoot - }, - unmount: function(mountpoint) { - var lookup = FS.lookupPath(mountpoint, { - follow_mount: false - }); - if (!FS.isMountpoint(lookup.node)) { - throw new FS.ErrnoError(28) - } - var node = lookup.node; - var mount = node.mounted; - var mounts = FS.getMounts(mount); - Object.keys(FS.nameTable).forEach(function(hash) { - var current = FS.nameTable[hash]; - while (current) { - var next = current.name_next; - if (mounts.indexOf(current.mount) !== -1) { - FS.destroyNode(current) - } - current = next - } - }); - node.mounted = null; - var idx = node.mount.mounts.indexOf(mount); - node.mount.mounts.splice(idx, 1) - }, - lookup: function(parent, name) { - return parent.node_ops.lookup(parent, name) - }, - mknod: function(path, mode, dev) { - var lookup = FS.lookupPath(path, { - parent: true - }); - var parent = lookup.node; - var name = PATH.basename(path); - if (!name || name === "." || name === "..") { - throw new FS.ErrnoError(28) - } - var errCode = FS.mayCreate(parent, name); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - if (!parent.node_ops.mknod) { - throw new FS.ErrnoError(63) - } - return parent.node_ops.mknod(parent, name, mode, dev) - }, - create: function(path, mode) { - mode = mode !== undefined ? mode : 438; - mode &= 4095; - mode |= 32768; - return FS.mknod(path, mode, 0) - }, - mkdir: function(path, mode) { - mode = mode !== undefined ? mode : 511; - mode &= 511 | 512; - mode |= 16384; - return FS.mknod(path, mode, 0) - }, - mkdirTree: function(path, mode) { - var dirs = path.split("/"); - var d = ""; - for (var i = 0; i < dirs.length; ++i) { - if (!dirs[i]) continue; - d += "/" + dirs[i]; - try { - FS.mkdir(d, mode) - } catch (e) { - if (e.errno != 20) throw e - } - } - }, - mkdev: function(path, mode, dev) { - if (typeof dev === "undefined") { - dev = mode; - mode = 438 - } - mode |= 8192; - return FS.mknod(path, mode, dev) - }, - symlink: function(oldpath, newpath) { - if (!PATH_FS.resolve(oldpath)) { - throw new FS.ErrnoError(44) - } - var lookup = FS.lookupPath(newpath, { - parent: true - }); - var parent = lookup.node; - if (!parent) { - throw new FS.ErrnoError(44) - } - var newname = PATH.basename(newpath); - var errCode = FS.mayCreate(parent, newname); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - if (!parent.node_ops.symlink) { - throw new FS.ErrnoError(63) - } - return parent.node_ops.symlink(parent, newname, oldpath) - }, - rename: function(old_path, new_path) { - var old_dirname = PATH.dirname(old_path); - var new_dirname = PATH.dirname(new_path); - var old_name = PATH.basename(old_path); - var new_name = PATH.basename(new_path); - var lookup, old_dir, new_dir; - lookup = FS.lookupPath(old_path, { - parent: true - }); - old_dir = lookup.node; - lookup = FS.lookupPath(new_path, { - parent: true - }); - new_dir = lookup.node; - if (!old_dir || !new_dir) throw new FS.ErrnoError(44); - if (old_dir.mount !== new_dir.mount) { - throw new FS.ErrnoError(75) - } - var old_node = FS.lookupNode(old_dir, old_name); - var relative = PATH_FS.relative(old_path, new_dirname); - if (relative.charAt(0) !== ".") { - throw new FS.ErrnoError(28) - } - relative = PATH_FS.relative(new_path, old_dirname); - if (relative.charAt(0) !== ".") { - throw new FS.ErrnoError(55) - } - var new_node; - try { - new_node = FS.lookupNode(new_dir, new_name) - } catch (e) {} - if (old_node === new_node) { - return - } - var isdir = FS.isDir(old_node.mode); - var errCode = FS.mayDelete(old_dir, old_name, isdir); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - errCode = new_node ? FS.mayDelete(new_dir, new_name, isdir) : FS.mayCreate(new_dir, new_name); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - if (!old_dir.node_ops.rename) { - throw new FS.ErrnoError(63) - } - if (FS.isMountpoint(old_node) || new_node && FS.isMountpoint(new_node)) { - throw new FS.ErrnoError(10) - } - if (new_dir !== old_dir) { - errCode = FS.nodePermissions(old_dir, "w"); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - } - try { - if (FS.trackingDelegate.willMovePath) { - FS.trackingDelegate.willMovePath(old_path, new_path) - } - } catch (e) { - err("FS.trackingDelegate['willMovePath']('" + old_path + "', '" + new_path + "') threw an exception: " + e.message) - } - FS.hashRemoveNode(old_node); - try { - old_dir.node_ops.rename(old_node, new_dir, new_name) - } catch (e) { - throw e - } finally { - FS.hashAddNode(old_node) - } - try { - if (FS.trackingDelegate.onMovePath) FS.trackingDelegate.onMovePath(old_path, new_path) - } catch (e) { - err("FS.trackingDelegate['onMovePath']('" + old_path + "', '" + new_path + "') threw an exception: " + e.message) - } - }, - rmdir: function(path) { - var lookup = FS.lookupPath(path, { - parent: true - }); - var parent = lookup.node; - var name = PATH.basename(path); - var node = FS.lookupNode(parent, name); - var errCode = FS.mayDelete(parent, name, true); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - if (!parent.node_ops.rmdir) { - throw new FS.ErrnoError(63) - } - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10) - } - try { - if (FS.trackingDelegate.willDeletePath) { - FS.trackingDelegate.willDeletePath(path) - } - } catch (e) { - err("FS.trackingDelegate['willDeletePath']('" + path + "') threw an exception: " + e.message) - } - parent.node_ops.rmdir(parent, name); - FS.destroyNode(node); - try { - if (FS.trackingDelegate.onDeletePath) FS.trackingDelegate.onDeletePath(path) - } catch (e) { - err("FS.trackingDelegate['onDeletePath']('" + path + "') threw an exception: " + e.message) - } - }, - readdir: function(path) { - var lookup = FS.lookupPath(path, { - follow: true - }); - var node = lookup.node; - if (!node.node_ops.readdir) { - throw new FS.ErrnoError(54) - } - return node.node_ops.readdir(node) - }, - unlink: function(path) { - var lookup = FS.lookupPath(path, { - parent: true - }); - var parent = lookup.node; - var name = PATH.basename(path); - var node = FS.lookupNode(parent, name); - var errCode = FS.mayDelete(parent, name, false); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - if (!parent.node_ops.unlink) { - throw new FS.ErrnoError(63) - } - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10) - } - try { - if (FS.trackingDelegate.willDeletePath) { - FS.trackingDelegate.willDeletePath(path) - } - } catch (e) { - err("FS.trackingDelegate['willDeletePath']('" + path + "') threw an exception: " + e.message) - } - parent.node_ops.unlink(parent, name); - FS.destroyNode(node); - try { - if (FS.trackingDelegate.onDeletePath) FS.trackingDelegate.onDeletePath(path) - } catch (e) { - err("FS.trackingDelegate['onDeletePath']('" + path + "') threw an exception: " + e.message) - } - }, - readlink: function(path) { - var lookup = FS.lookupPath(path); - var link = lookup.node; - if (!link) { - throw new FS.ErrnoError(44) - } - if (!link.node_ops.readlink) { - throw new FS.ErrnoError(28) - } - return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link)) - }, - stat: function(path, dontFollow) { - var lookup = FS.lookupPath(path, { - follow: !dontFollow - }); - var node = lookup.node; - if (!node) { - throw new FS.ErrnoError(44) - } - if (!node.node_ops.getattr) { - throw new FS.ErrnoError(63) - } - return node.node_ops.getattr(node) - }, - lstat: function(path) { - return FS.stat(path, true) - }, - chmod: function(path, mode, dontFollow) { - var node; - if (typeof path === "string") { - var lookup = FS.lookupPath(path, { - follow: !dontFollow - }); - node = lookup.node - } else { - node = path - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63) - } - node.node_ops.setattr(node, { - mode: mode & 4095 | node.mode & ~4095, - timestamp: Date.now() - }) - }, - lchmod: function(path, mode) { - FS.chmod(path, mode, true) - }, - fchmod: function(fd, mode) { - var stream = FS.getStream(fd); - if (!stream) { - throw new FS.ErrnoError(8) - } - FS.chmod(stream.node, mode) - }, - chown: function(path, uid, gid, dontFollow) { - var node; - if (typeof path === "string") { - var lookup = FS.lookupPath(path, { - follow: !dontFollow - }); - node = lookup.node - } else { - node = path - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63) - } - node.node_ops.setattr(node, { - timestamp: Date.now() - }) - }, - lchown: function(path, uid, gid) { - FS.chown(path, uid, gid, true) - }, - fchown: function(fd, uid, gid) { - var stream = FS.getStream(fd); - if (!stream) { - throw new FS.ErrnoError(8) - } - FS.chown(stream.node, uid, gid) - }, - truncate: function(path, len) { - if (len < 0) { - throw new FS.ErrnoError(28) - } - var node; - if (typeof path === "string") { - var lookup = FS.lookupPath(path, { - follow: true - }); - node = lookup.node - } else { - node = path - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63) - } - if (FS.isDir(node.mode)) { - throw new FS.ErrnoError(31) - } - if (!FS.isFile(node.mode)) { - throw new FS.ErrnoError(28) - } - var errCode = FS.nodePermissions(node, "w"); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - node.node_ops.setattr(node, { - size: len, - timestamp: Date.now() - }) - }, - ftruncate: function(fd, len) { - var stream = FS.getStream(fd); - if (!stream) { - throw new FS.ErrnoError(8) - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(28) - } - FS.truncate(stream.node, len) - }, - utime: function(path, atime, mtime) { - var lookup = FS.lookupPath(path, { - follow: true - }); - var node = lookup.node; - node.node_ops.setattr(node, { - timestamp: Math.max(atime, mtime) - }) - }, - open: function(path, flags, mode, fd_start, fd_end) { - if (path === "") { - throw new FS.ErrnoError(44) - } - flags = typeof flags === "string" ? FS.modeStringToFlags(flags) : flags; - mode = typeof mode === "undefined" ? 438 : mode; - if (flags & 64) { - mode = mode & 4095 | 32768 - } else { - mode = 0 - } - var node; - if (typeof path === "object") { - node = path - } else { - path = PATH.normalize(path); - try { - var lookup = FS.lookupPath(path, { - follow: !(flags & 131072) - }); - node = lookup.node - } catch (e) {} - } - var created = false; - if (flags & 64) { - if (node) { - if (flags & 128) { - throw new FS.ErrnoError(20) - } - } else { - node = FS.mknod(path, mode, 0); - created = true - } - } - if (!node) { - throw new FS.ErrnoError(44) - } - if (FS.isChrdev(node.mode)) { - flags &= ~512 - } - if (flags & 65536 && !FS.isDir(node.mode)) { - throw new FS.ErrnoError(54) - } - if (!created) { - var errCode = FS.mayOpen(node, flags); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - } - if (flags & 512) { - FS.truncate(node, 0) - } - flags &= ~(128 | 512 | 131072); - var stream = FS.createStream({ - node: node, - path: FS.getPath(node), - flags: flags, - seekable: true, - position: 0, - stream_ops: node.stream_ops, - ungotten: [], - error: false - }, fd_start, fd_end); - if (stream.stream_ops.open) { - stream.stream_ops.open(stream) - } - if (Module.logReadFiles && !(flags & 1)) { - if (!FS.readFiles) FS.readFiles = {}; - if (!(path in FS.readFiles)) { - FS.readFiles[path] = 1; - err("FS.trackingDelegate error on read file: " + path) - } - } - try { - if (FS.trackingDelegate.onOpenFile) { - var trackingFlags = 0; - if ((flags & 2097155) !== 1) { - trackingFlags |= FS.tracking.openFlags.READ - } - if ((flags & 2097155) !== 0) { - trackingFlags |= FS.tracking.openFlags.WRITE - } - FS.trackingDelegate.onOpenFile(path, trackingFlags) - } - } catch (e) { - err("FS.trackingDelegate['onOpenFile']('" + path + "', flags) threw an exception: " + e.message) - } - return stream - }, - close: function(stream) { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8) - } - if (stream.getdents) stream.getdents = null; - try { - if (stream.stream_ops.close) { - stream.stream_ops.close(stream) - } - } catch (e) { - throw e - } finally { - FS.closeStream(stream.fd) - } - stream.fd = null - }, - isClosed: function(stream) { - return stream.fd === null - }, - llseek: function(stream, offset, whence) { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8) - } - if (!stream.seekable || !stream.stream_ops.llseek) { - throw new FS.ErrnoError(70) - } - if (whence != 0 && whence != 1 && whence != 2) { - throw new FS.ErrnoError(28) - } - stream.position = stream.stream_ops.llseek(stream, offset, whence); - stream.ungotten = []; - return stream.position - }, - read: function(stream, buffer, offset, length, position) { - if (length < 0 || position < 0) { - throw new FS.ErrnoError(28) - } - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8) - } - if ((stream.flags & 2097155) === 1) { - throw new FS.ErrnoError(8) - } - if (FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(31) - } - if (!stream.stream_ops.read) { - throw new FS.ErrnoError(28) - } - var seeking = typeof position !== "undefined"; - if (!seeking) { - position = stream.position - } else if (!stream.seekable) { - throw new FS.ErrnoError(70) - } - var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position); - if (!seeking) stream.position += bytesRead; - return bytesRead - }, - write: function(stream, buffer, offset, length, position, canOwn) { - if (length < 0 || position < 0) { - throw new FS.ErrnoError(28) - } - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8) - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(8) - } - if (FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(31) - } - if (!stream.stream_ops.write) { - throw new FS.ErrnoError(28) - } - if (stream.seekable && stream.flags & 1024) { - FS.llseek(stream, 0, 2) - } - var seeking = typeof position !== "undefined"; - if (!seeking) { - position = stream.position - } else if (!stream.seekable) { - throw new FS.ErrnoError(70) - } - var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn); - if (!seeking) stream.position += bytesWritten; - try { - if (stream.path && FS.trackingDelegate.onWriteToFile) FS.trackingDelegate.onWriteToFile(stream.path) - } catch (e) { - err("FS.trackingDelegate['onWriteToFile']('" + stream.path + "') threw an exception: " + e.message) - } - return bytesWritten - }, - allocate: function(stream, offset, length) { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8) - } - if (offset < 0 || length <= 0) { - throw new FS.ErrnoError(28) - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(8) - } - if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(43) - } - if (!stream.stream_ops.allocate) { - throw new FS.ErrnoError(138) - } - stream.stream_ops.allocate(stream, offset, length) - }, - mmap: function(stream, address, length, position, prot, flags) { - if ((prot & 2) !== 0 && (flags & 2) === 0 && (stream.flags & 2097155) !== 2) { - throw new FS.ErrnoError(2) - } - if ((stream.flags & 2097155) === 1) { - throw new FS.ErrnoError(2) - } - if (!stream.stream_ops.mmap) { - throw new FS.ErrnoError(43) - } - return stream.stream_ops.mmap(stream, address, length, position, prot, flags) - }, - msync: function(stream, buffer, offset, length, mmapFlags) { - if (!stream || !stream.stream_ops.msync) { - return 0 - } - return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags) - }, - munmap: function(stream) { - return 0 - }, - ioctl: function(stream, cmd, arg) { - if (!stream.stream_ops.ioctl) { - throw new FS.ErrnoError(59) - } - return stream.stream_ops.ioctl(stream, cmd, arg) - }, - readFile: function(path, opts) { - opts = opts || {}; - opts.flags = opts.flags || "r"; - opts.encoding = opts.encoding || "binary"; - if (opts.encoding !== "utf8" && opts.encoding !== "binary") { - throw new Error('Invalid encoding type "' + opts.encoding + '"') - } - var ret; - var stream = FS.open(path, opts.flags); - var stat = FS.stat(path); - var length = stat.size; - var buf = new Uint8Array(length); - FS.read(stream, buf, 0, length, 0); - if (opts.encoding === "utf8") { - ret = UTF8ArrayToString(buf, 0) - } else if (opts.encoding === "binary") { - ret = buf - } - FS.close(stream); - return ret - }, - writeFile: function(path, data, opts) { - opts = opts || {}; - opts.flags = opts.flags || "w"; - var stream = FS.open(path, opts.flags, opts.mode); - if (typeof data === "string") { - var buf = new Uint8Array(lengthBytesUTF8(data) + 1); - var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length); - FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn) - } else if (ArrayBuffer.isView(data)) { - FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn) - } else { - throw new Error("Unsupported data type") - } - FS.close(stream) - }, - cwd: function() { - return FS.currentPath - }, - chdir: function(path) { - var lookup = FS.lookupPath(path, { - follow: true - }); - if (lookup.node === null) { - throw new FS.ErrnoError(44) - } - if (!FS.isDir(lookup.node.mode)) { - throw new FS.ErrnoError(54) - } - var errCode = FS.nodePermissions(lookup.node, "x"); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - FS.currentPath = lookup.path - }, - createDefaultDirectories: function() { - FS.mkdir("/tmp"); - FS.mkdir("/home"); - FS.mkdir("/home/web_user") - }, - createDefaultDevices: function() { - FS.mkdir("/dev"); - FS.registerDevice(FS.makedev(1, 3), { - read: function() { - return 0 - }, - write: function(stream, buffer, offset, length, pos) { - return length - } - }); - FS.mkdev("/dev/null", FS.makedev(1, 3)); - TTY.register(FS.makedev(5, 0), TTY.default_tty_ops); - TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops); - FS.mkdev("/dev/tty", FS.makedev(5, 0)); - FS.mkdev("/dev/tty1", FS.makedev(6, 0)); - var random_device = getRandomDevice(); - FS.createDevice("/dev", "random", random_device); - FS.createDevice("/dev", "urandom", random_device); - FS.mkdir("/dev/shm"); - FS.mkdir("/dev/shm/tmp") - }, - createSpecialDirectories: function() { - FS.mkdir("/proc"); - FS.mkdir("/proc/self"); - FS.mkdir("/proc/self/fd"); - FS.mount({ - mount: function() { - var node = FS.createNode("/proc/self", "fd", 16384 | 511, 73); - node.node_ops = { - lookup: function(parent, name) { - var fd = +name; - var stream = FS.getStream(fd); - if (!stream) throw new FS.ErrnoError(8); - var ret = { - parent: null, - mount: { - mountpoint: "fake" - }, - node_ops: { - readlink: function() { - return stream.path - } - } - }; - ret.parent = ret; - return ret - } - }; - return node - } - }, {}, "/proc/self/fd") - }, - createStandardStreams: function() { - if (Module.stdin) { - FS.createDevice("/dev", "stdin", Module.stdin) - } else { - FS.symlink("/dev/tty", "/dev/stdin") - } - if (Module.stdout) { - FS.createDevice("/dev", "stdout", null, Module.stdout) - } else { - FS.symlink("/dev/tty", "/dev/stdout") - } - if (Module.stderr) { - FS.createDevice("/dev", "stderr", null, Module.stderr) - } else { - FS.symlink("/dev/tty1", "/dev/stderr") - } - var stdin = FS.open("/dev/stdin", "r"); - var stdout = FS.open("/dev/stdout", "w"); - var stderr = FS.open("/dev/stderr", "w") - }, - ensureErrnoError: function() { - if (FS.ErrnoError) return; - FS.ErrnoError = function ErrnoError(errno, node) { - this.node = node; - this.setErrno = function(errno) { - this.errno = errno - }; - this.setErrno(errno); - this.message = "FS error" - }; - FS.ErrnoError.prototype = new Error; - FS.ErrnoError.prototype.constructor = FS.ErrnoError; - [44].forEach(function(code) { - FS.genericErrors[code] = new FS.ErrnoError(code); - FS.genericErrors[code].stack = "" - }) - }, - staticInit: function() { - FS.ensureErrnoError(); - FS.nameTable = new Array(4096); - FS.mount(MEMFS, {}, "/"); - FS.createDefaultDirectories(); - FS.createDefaultDevices(); - FS.createSpecialDirectories(); - FS.filesystems = { - "MEMFS": MEMFS - } - }, - init: function(input, output, error) { - FS.init.initialized = true; - FS.ensureErrnoError(); - Module.stdin = input || Module.stdin; - Module.stdout = output || Module.stdout; - Module.stderr = error || Module.stderr; - FS.createStandardStreams() - }, - quit: function() { - FS.init.initialized = false; - var fflush = Module._fflush; - if (fflush) fflush(0); - for (var i = 0; i < FS.streams.length; i++) { - var stream = FS.streams[i]; - if (!stream) { - continue - } - FS.close(stream) - } - }, - getMode: function(canRead, canWrite) { - var mode = 0; - if (canRead) mode |= 292 | 73; - if (canWrite) mode |= 146; - return mode - }, - findObject: function(path, dontResolveLastLink) { - var ret = FS.analyzePath(path, dontResolveLastLink); - if (ret.exists) { - return ret.object - } else { - setErrNo(ret.error); - return null - } - }, - analyzePath: function(path, dontResolveLastLink) { - try { - var lookup = FS.lookupPath(path, { - follow: !dontResolveLastLink - }); - path = lookup.path - } catch (e) {} - var ret = { - isRoot: false, - exists: false, - error: 0, - name: null, - path: null, - object: null, - parentExists: false, - parentPath: null, - parentObject: null - }; - try { - var lookup = FS.lookupPath(path, { - parent: true - }); - ret.parentExists = true; - ret.parentPath = lookup.path; - ret.parentObject = lookup.node; - ret.name = PATH.basename(path); - lookup = FS.lookupPath(path, { - follow: !dontResolveLastLink - }); - ret.exists = true; - ret.path = lookup.path; - ret.object = lookup.node; - ret.name = lookup.node.name; - ret.isRoot = lookup.path === "/" - } catch (e) { - ret.error = e.errno - } - return ret - }, - createPath: function(parent, path, canRead, canWrite) { - parent = typeof parent === "string" ? parent : FS.getPath(parent); - var parts = path.split("/").reverse(); - while (parts.length) { - var part = parts.pop(); - if (!part) continue; - var current = PATH.join2(parent, part); - try { - FS.mkdir(current) - } catch (e) {} - parent = current - } - return current - }, - createFile: function(parent, name, properties, canRead, canWrite) { - var path = PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name); - var mode = FS.getMode(canRead, canWrite); - return FS.create(path, mode) - }, - createDataFile: function(parent, name, data, canRead, canWrite, canOwn) { - var path = name ? PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name) : parent; - var mode = FS.getMode(canRead, canWrite); - var node = FS.create(path, mode); - if (data) { - if (typeof data === "string") { - var arr = new Array(data.length); - for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i); - data = arr - } - FS.chmod(node, mode | 146); - var stream = FS.open(node, "w"); - FS.write(stream, data, 0, data.length, 0, canOwn); - FS.close(stream); - FS.chmod(node, mode) - } - return node - }, - createDevice: function(parent, name, input, output) { - var path = PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name); - var mode = FS.getMode(!!input, !!output); - if (!FS.createDevice.major) FS.createDevice.major = 64; - var dev = FS.makedev(FS.createDevice.major++, 0); - FS.registerDevice(dev, { - open: function(stream) { - stream.seekable = false - }, - close: function(stream) { - if (output && output.buffer && output.buffer.length) { - output(10) - } - }, - read: function(stream, buffer, offset, length, pos) { - var bytesRead = 0; - for (var i = 0; i < length; i++) { - var result; - try { - result = input() - } catch (e) { - throw new FS.ErrnoError(29) - } - if (result === undefined && bytesRead === 0) { - throw new FS.ErrnoError(6) - } - if (result === null || result === undefined) break; - bytesRead++; - buffer[offset + i] = result - } - if (bytesRead) { - stream.node.timestamp = Date.now() - } - return bytesRead - }, - write: function(stream, buffer, offset, length, pos) { - for (var i = 0; i < length; i++) { - try { - output(buffer[offset + i]) - } catch (e) { - throw new FS.ErrnoError(29) - } - } - if (length) { - stream.node.timestamp = Date.now() - } - return i - } - }); - return FS.mkdev(path, mode, dev) - }, - forceLoadFile: function(obj) { - if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true; - var success = true; - if (typeof XMLHttpRequest !== "undefined") { - throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.") - } else if (read_) { - try { - obj.contents = intArrayFromString(read_(obj.url), true); - obj.usedBytes = obj.contents.length - } catch (e) { - success = false - } - } else { - throw new Error("Cannot load without read() or XMLHttpRequest.") - } - if (!success) setErrNo(29); - return success - }, - createLazyFile: function(parent, name, url, canRead, canWrite) { - function LazyUint8Array() { - this.lengthKnown = false; - this.chunks = [] - } - LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) { - if (idx > this.length - 1 || idx < 0) { - return undefined - } - var chunkOffset = idx % this.chunkSize; - var chunkNum = idx / this.chunkSize | 0; - return this.getter(chunkNum)[chunkOffset] - }; - LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) { - this.getter = getter - }; - LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() { - var xhr = new XMLHttpRequest; - xhr.open("HEAD", url, false); - xhr.send(null); - if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); - var datalength = Number(xhr.getResponseHeader("Content-length")); - var header; - var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; - var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip"; - var chunkSize = 1024 * 1024; - if (!hasByteServing) chunkSize = datalength; - var doXHR = function(from, to) { - if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!"); - if (to > datalength - 1) throw new Error("only " + datalength + " bytes available! programmer error!"); - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); - if (typeof Uint8Array !== "undefined") xhr.responseType = "arraybuffer"; - if (xhr.overrideMimeType) { - xhr.overrideMimeType("text/plain; charset=x-user-defined") - } - xhr.send(null); - if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); - if (xhr.response !== undefined) { - return new Uint8Array(xhr.response || []) - } else { - return intArrayFromString(xhr.responseText || "", true) - } - }; - var lazyArray = this; - lazyArray.setDataGetter(function(chunkNum) { - var start = chunkNum * chunkSize; - var end = (chunkNum + 1) * chunkSize - 1; - end = Math.min(end, datalength - 1); - if (typeof lazyArray.chunks[chunkNum] === "undefined") { - lazyArray.chunks[chunkNum] = doXHR(start, end) - } - if (typeof lazyArray.chunks[chunkNum] === "undefined") throw new Error("doXHR failed!"); - return lazyArray.chunks[chunkNum] - }); - if (usesGzip || !datalength) { - chunkSize = datalength = 1; - datalength = this.getter(0).length; - chunkSize = datalength; - out("LazyFiles on gzip forces download of the whole file when length is accessed") - } - this._length = datalength; - this._chunkSize = chunkSize; - this.lengthKnown = true - }; - if (typeof XMLHttpRequest !== "undefined") { - if (!ENVIRONMENT_IS_WORKER) throw "Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc"; - var lazyArray = new LazyUint8Array; - Object.defineProperties(lazyArray, { - length: { - get: function() { - if (!this.lengthKnown) { - this.cacheLength() - } - return this._length - } - }, - chunkSize: { - get: function() { - if (!this.lengthKnown) { - this.cacheLength() - } - return this._chunkSize - } - } - }); - var properties = { - isDevice: false, - contents: lazyArray - } - } else { - var properties = { - isDevice: false, - url: url - } - } - var node = FS.createFile(parent, name, properties, canRead, canWrite); - if (properties.contents) { - node.contents = properties.contents - } else if (properties.url) { - node.contents = null; - node.url = properties.url - } - Object.defineProperties(node, { - usedBytes: { - get: function() { - return this.contents.length - } - } - }); - var stream_ops = {}; - var keys = Object.keys(node.stream_ops); - keys.forEach(function(key) { - var fn = node.stream_ops[key]; - stream_ops[key] = function forceLoadLazyFile() { - if (!FS.forceLoadFile(node)) { - throw new FS.ErrnoError(29) - } - return fn.apply(null, arguments) - } - }); - stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) { - if (!FS.forceLoadFile(node)) { - throw new FS.ErrnoError(29) - } - var contents = stream.node.contents; - if (position >= contents.length) return 0; - var size = Math.min(contents.length - position, length); - if (contents.slice) { - for (var i = 0; i < size; i++) { - buffer[offset + i] = contents[position + i] - } - } else { - for (var i = 0; i < size; i++) { - buffer[offset + i] = contents.get(position + i) - } - } - return size - }; - node.stream_ops = stream_ops; - return node - }, - createPreloadedFile: function(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) { - Browser.init(); - var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent; - var dep = getUniqueRunDependency("cp " + fullname); - - function processData(byteArray) { - function finish(byteArray) { - if (preFinish) preFinish(); - if (!dontCreateFile) { - FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn) - } - if (onload) onload(); - removeRunDependency(dep) - } - var handled = false; - Module.preloadPlugins.forEach(function(plugin) { - if (handled) return; - if (plugin.canHandle(fullname)) { - plugin.handle(byteArray, fullname, finish, function() { - if (onerror) onerror(); - removeRunDependency(dep) - }); - handled = true - } - }); - if (!handled) finish(byteArray) - } - addRunDependency(dep); - if (typeof url === "string") { - Browser.asyncLoad(url, function(byteArray) { - processData(byteArray) - }, onerror) - } else { - processData(url) - } - }, - indexedDB: function() { - return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB - }, - DB_NAME: function() { - return "EM_FS_" + window.location.pathname - }, - DB_VERSION: 20, - DB_STORE_NAME: "FILE_DATA", - saveFilesToDB: function(paths, onload, onerror) { - onload = onload || function() {}; - onerror = onerror || function() {}; - var indexedDB = FS.indexedDB(); - try { - var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION) - } catch (e) { - return onerror(e) - } - openRequest.onupgradeneeded = function openRequest_onupgradeneeded() { - out("creating db"); - var db = openRequest.result; - db.createObjectStore(FS.DB_STORE_NAME) - }; - openRequest.onsuccess = function openRequest_onsuccess() { - var db = openRequest.result; - var transaction = db.transaction([FS.DB_STORE_NAME], "readwrite"); - var files = transaction.objectStore(FS.DB_STORE_NAME); - var ok = 0; - var fail = 0; - var total = paths.length; - - function finish() { - if (fail == 0) onload(); - else onerror() - } - paths.forEach(function(path) { - var putRequest = files.put(FS.analyzePath(path).object.contents, path); - putRequest.onsuccess = function putRequest_onsuccess() { - ok++; - if (ok + fail == total) finish() - }; - putRequest.onerror = function putRequest_onerror() { - fail++; - if (ok + fail == total) finish() - } - }); - transaction.onerror = onerror - }; - openRequest.onerror = onerror - }, - loadFilesFromDB: function(paths, onload, onerror) { - onload = onload || function() {}; - onerror = onerror || function() {}; - var indexedDB = FS.indexedDB(); - try { - var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION) - } catch (e) { - return onerror(e) - } - openRequest.onupgradeneeded = onerror; - openRequest.onsuccess = function openRequest_onsuccess() { - var db = openRequest.result; - try { - var transaction = db.transaction([FS.DB_STORE_NAME], "readonly") - } catch (e) { - onerror(e); - return - } - var files = transaction.objectStore(FS.DB_STORE_NAME); - var ok = 0; - var fail = 0; - var total = paths.length; - - function finish() { - if (fail == 0) onload(); - else onerror() - } - paths.forEach(function(path) { - var getRequest = files.get(path); - getRequest.onsuccess = function getRequest_onsuccess() { - if (FS.analyzePath(path).exists) { - FS.unlink(path) - } - FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true); - ok++; - if (ok + fail == total) finish() - }; - getRequest.onerror = function getRequest_onerror() { - fail++; - if (ok + fail == total) finish() - } - }); - transaction.onerror = onerror - }; - openRequest.onerror = onerror - } -}; -var SYSCALLS = { - mappings: {}, - DEFAULT_POLLMASK: 5, - umask: 511, - calculateAt: function(dirfd, path) { - if (path[0] !== "/") { - var dir; - if (dirfd === -100) { - dir = FS.cwd() - } else { - var dirstream = FS.getStream(dirfd); - if (!dirstream) throw new FS.ErrnoError(8); - dir = dirstream.path - } - path = PATH.join2(dir, path) - } - return path - }, - doStat: function(func, path, buf) { - try { - var stat = func(path) - } catch (e) { - if (e && e.node && PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))) { - return -54 - } - throw e - } - HEAP32[buf >> 2] = stat.dev; - HEAP32[buf + 4 >> 2] = 0; - HEAP32[buf + 8 >> 2] = stat.ino; - HEAP32[buf + 12 >> 2] = stat.mode; - HEAP32[buf + 16 >> 2] = stat.nlink; - HEAP32[buf + 20 >> 2] = stat.uid; - HEAP32[buf + 24 >> 2] = stat.gid; - HEAP32[buf + 28 >> 2] = stat.rdev; - HEAP32[buf + 32 >> 2] = 0; - tempI64 = [stat.size >>> 0, (tempDouble = stat.size, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0)], HEAP32[buf + 40 >> 2] = tempI64[0], HEAP32[buf + 44 >> 2] = tempI64[1]; - HEAP32[buf + 48 >> 2] = 4096; - HEAP32[buf + 52 >> 2] = stat.blocks; - HEAP32[buf + 56 >> 2] = stat.atime.getTime() / 1e3 | 0; - HEAP32[buf + 60 >> 2] = 0; - HEAP32[buf + 64 >> 2] = stat.mtime.getTime() / 1e3 | 0; - HEAP32[buf + 68 >> 2] = 0; - HEAP32[buf + 72 >> 2] = stat.ctime.getTime() / 1e3 | 0; - HEAP32[buf + 76 >> 2] = 0; - tempI64 = [stat.ino >>> 0, (tempDouble = stat.ino, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0)], HEAP32[buf + 80 >> 2] = tempI64[0], HEAP32[buf + 84 >> 2] = tempI64[1]; - return 0 - }, - doMsync: function(addr, stream, len, flags, offset) { - var buffer = HEAPU8.slice(addr, addr + len); - FS.msync(stream, buffer, offset, len, flags) - }, - doMkdir: function(path, mode) { - path = PATH.normalize(path); - if (path[path.length - 1] === "/") path = path.substr(0, path.length - 1); - FS.mkdir(path, mode, 0); - return 0 - }, - doMknod: function(path, mode, dev) { - switch (mode & 61440) { - case 32768: - case 8192: - case 24576: - case 4096: - case 49152: - break; - default: - return -28 - } - FS.mknod(path, mode, dev); - return 0 - }, - doReadlink: function(path, buf, bufsize) { - if (bufsize <= 0) return -28; - var ret = FS.readlink(path); - var len = Math.min(bufsize, lengthBytesUTF8(ret)); - var endChar = HEAP8[buf + len]; - stringToUTF8(ret, buf, bufsize + 1); - HEAP8[buf + len] = endChar; - return len - }, - doAccess: function(path, amode) { - if (amode & ~7) { - return -28 - } - var node; - var lookup = FS.lookupPath(path, { - follow: true - }); - node = lookup.node; - if (!node) { - return -44 - } - var perms = ""; - if (amode & 4) perms += "r"; - if (amode & 2) perms += "w"; - if (amode & 1) perms += "x"; - if (perms && FS.nodePermissions(node, perms)) { - return -2 - } - return 0 - }, - doDup: function(path, flags, suggestFD) { - var suggest = FS.getStream(suggestFD); - if (suggest) FS.close(suggest); - return FS.open(path, flags, 0, suggestFD, suggestFD).fd - }, - doReadv: function(stream, iov, iovcnt, offset) { - var ret = 0; - for (var i = 0; i < iovcnt; i++) { - var ptr = HEAP32[iov + i * 8 >> 2]; - var len = HEAP32[iov + (i * 8 + 4) >> 2]; - var curr = FS.read(stream, HEAP8, ptr, len, offset); - if (curr < 0) return -1; - ret += curr; - if (curr < len) break - } - return ret - }, - doWritev: function(stream, iov, iovcnt, offset) { - var ret = 0; - for (var i = 0; i < iovcnt; i++) { - var ptr = HEAP32[iov + i * 8 >> 2]; - var len = HEAP32[iov + (i * 8 + 4) >> 2]; - var curr = FS.write(stream, HEAP8, ptr, len, offset); - if (curr < 0) return -1; - ret += curr - } - return ret - }, - varargs: undefined, - get: function() { - SYSCALLS.varargs += 4; - var ret = HEAP32[SYSCALLS.varargs - 4 >> 2]; - return ret - }, - getStr: function(ptr) { - var ret = UTF8ToString(ptr); - return ret - }, - getStreamFromFD: function(fd) { - var stream = FS.getStream(fd); - if (!stream) throw new FS.ErrnoError(8); - return stream - }, - get64: function(low, high) { - return low - } -}; - -function _fd_close(fd) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - FS.close(stream); - return 0 - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e); - return e.errno - } -} - -function _fd_read(fd, iov, iovcnt, pnum) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - var num = SYSCALLS.doReadv(stream, iov, iovcnt); - HEAP32[pnum >> 2] = num; - return 0 - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e); - return e.errno - } -} - -function _fd_seek(fd, offset_low, offset_high, whence, newOffset) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - var HIGH_OFFSET = 4294967296; - var offset = offset_high * HIGH_OFFSET + (offset_low >>> 0); - var DOUBLE_LIMIT = 9007199254740992; - if (offset <= -DOUBLE_LIMIT || offset >= DOUBLE_LIMIT) { - return -61 - } - FS.llseek(stream, offset, whence); - tempI64 = [stream.position >>> 0, (tempDouble = stream.position, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0)], HEAP32[newOffset >> 2] = tempI64[0], HEAP32[newOffset + 4 >> 2] = tempI64[1]; - if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; - return 0 - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e); - return e.errno - } -} - -function _fd_write(fd, iov, iovcnt, pnum) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - var num = SYSCALLS.doWritev(stream, iov, iovcnt); - HEAP32[pnum >> 2] = num; - return 0 - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e); - return e.errno - } -} - -function __isLeapYear(year) { - return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) -} - -function __arraySum(array, index) { - var sum = 0; - for (var i = 0; i <= index; sum += array[i++]) {} - return sum -} -var __MONTH_DAYS_LEAP = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; -var __MONTH_DAYS_REGULAR = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; - -function __addDays(date, days) { - var newDate = new Date(date.getTime()); - while (days > 0) { - var leap = __isLeapYear(newDate.getFullYear()); - var currentMonth = newDate.getMonth(); - var daysInCurrentMonth = (leap ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR)[currentMonth]; - if (days > daysInCurrentMonth - newDate.getDate()) { - days -= daysInCurrentMonth - newDate.getDate() + 1; - newDate.setDate(1); - if (currentMonth < 11) { - newDate.setMonth(currentMonth + 1) - } else { - newDate.setMonth(0); - newDate.setFullYear(newDate.getFullYear() + 1) - } - } else { - newDate.setDate(newDate.getDate() + days); - return newDate - } - } - return newDate -} - -function _strftime(s, maxsize, format, tm) { - var tm_zone = HEAP32[tm + 40 >> 2]; - var date = { - tm_sec: HEAP32[tm >> 2], - tm_min: HEAP32[tm + 4 >> 2], - tm_hour: HEAP32[tm + 8 >> 2], - tm_mday: HEAP32[tm + 12 >> 2], - tm_mon: HEAP32[tm + 16 >> 2], - tm_year: HEAP32[tm + 20 >> 2], - tm_wday: HEAP32[tm + 24 >> 2], - tm_yday: HEAP32[tm + 28 >> 2], - tm_isdst: HEAP32[tm + 32 >> 2], - tm_gmtoff: HEAP32[tm + 36 >> 2], - tm_zone: tm_zone ? UTF8ToString(tm_zone) : "" - }; - var pattern = UTF8ToString(format); - var EXPANSION_RULES_1 = { - "%c": "%a %b %d %H:%M:%S %Y", - "%D": "%m/%d/%y", - "%F": "%Y-%m-%d", - "%h": "%b", - "%r": "%I:%M:%S %p", - "%R": "%H:%M", - "%T": "%H:%M:%S", - "%x": "%m/%d/%y", - "%X": "%H:%M:%S", - "%Ec": "%c", - "%EC": "%C", - "%Ex": "%m/%d/%y", - "%EX": "%H:%M:%S", - "%Ey": "%y", - "%EY": "%Y", - "%Od": "%d", - "%Oe": "%e", - "%OH": "%H", - "%OI": "%I", - "%Om": "%m", - "%OM": "%M", - "%OS": "%S", - "%Ou": "%u", - "%OU": "%U", - "%OV": "%V", - "%Ow": "%w", - "%OW": "%W", - "%Oy": "%y" - }; - for (var rule in EXPANSION_RULES_1) { - pattern = pattern.replace(new RegExp(rule, "g"), EXPANSION_RULES_1[rule]) - } - var WEEKDAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; - var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; - - function leadingSomething(value, digits, character) { - var str = typeof value === "number" ? value.toString() : value || ""; - while (str.length < digits) { - str = character[0] + str - } - return str - } - - function leadingNulls(value, digits) { - return leadingSomething(value, digits, "0") - } - - function compareByDay(date1, date2) { - function sgn(value) { - return value < 0 ? -1 : value > 0 ? 1 : 0 - } - var compare; - if ((compare = sgn(date1.getFullYear() - date2.getFullYear())) === 0) { - if ((compare = sgn(date1.getMonth() - date2.getMonth())) === 0) { - compare = sgn(date1.getDate() - date2.getDate()) - } - } - return compare - } - - function getFirstWeekStartDate(janFourth) { - switch (janFourth.getDay()) { - case 0: - return new Date(janFourth.getFullYear() - 1, 11, 29); - case 1: - return janFourth; - case 2: - return new Date(janFourth.getFullYear(), 0, 3); - case 3: - return new Date(janFourth.getFullYear(), 0, 2); - case 4: - return new Date(janFourth.getFullYear(), 0, 1); - case 5: - return new Date(janFourth.getFullYear() - 1, 11, 31); - case 6: - return new Date(janFourth.getFullYear() - 1, 11, 30) - } - } - - function getWeekBasedYear(date) { - var thisDate = __addDays(new Date(date.tm_year + 1900, 0, 1), date.tm_yday); - var janFourthThisYear = new Date(thisDate.getFullYear(), 0, 4); - var janFourthNextYear = new Date(thisDate.getFullYear() + 1, 0, 4); - var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear); - var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear); - if (compareByDay(firstWeekStartThisYear, thisDate) <= 0) { - if (compareByDay(firstWeekStartNextYear, thisDate) <= 0) { - return thisDate.getFullYear() + 1 - } else { - return thisDate.getFullYear() - } - } else { - return thisDate.getFullYear() - 1 - } - } - var EXPANSION_RULES_2 = { - "%a": function(date) { - return WEEKDAYS[date.tm_wday].substring(0, 3) - }, - "%A": function(date) { - return WEEKDAYS[date.tm_wday] - }, - "%b": function(date) { - return MONTHS[date.tm_mon].substring(0, 3) - }, - "%B": function(date) { - return MONTHS[date.tm_mon] - }, - "%C": function(date) { - var year = date.tm_year + 1900; - return leadingNulls(year / 100 | 0, 2) - }, - "%d": function(date) { - return leadingNulls(date.tm_mday, 2) - }, - "%e": function(date) { - return leadingSomething(date.tm_mday, 2, " ") - }, - "%g": function(date) { - return getWeekBasedYear(date).toString().substring(2) - }, - "%G": function(date) { - return getWeekBasedYear(date) - }, - "%H": function(date) { - return leadingNulls(date.tm_hour, 2) - }, - "%I": function(date) { - var twelveHour = date.tm_hour; - if (twelveHour == 0) twelveHour = 12; - else if (twelveHour > 12) twelveHour -= 12; - return leadingNulls(twelveHour, 2) - }, - "%j": function(date) { - return leadingNulls(date.tm_mday + __arraySum(__isLeapYear(date.tm_year + 1900) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, date.tm_mon - 1), 3) - }, - "%m": function(date) { - return leadingNulls(date.tm_mon + 1, 2) - }, - "%M": function(date) { - return leadingNulls(date.tm_min, 2) - }, - "%n": function() { - return "\n" - }, - "%p": function(date) { - if (date.tm_hour >= 0 && date.tm_hour < 12) { - return "AM" - } else { - return "PM" - } - }, - "%S": function(date) { - return leadingNulls(date.tm_sec, 2) - }, - "%t": function() { - return "\t" - }, - "%u": function(date) { - return date.tm_wday || 7 - }, - "%U": function(date) { - var janFirst = new Date(date.tm_year + 1900, 0, 1); - var firstSunday = janFirst.getDay() === 0 ? janFirst : __addDays(janFirst, 7 - janFirst.getDay()); - var endDate = new Date(date.tm_year + 1900, date.tm_mon, date.tm_mday); - if (compareByDay(firstSunday, endDate) < 0) { - var februaryFirstUntilEndMonth = __arraySum(__isLeapYear(endDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, endDate.getMonth() - 1) - 31; - var firstSundayUntilEndJanuary = 31 - firstSunday.getDate(); - var days = firstSundayUntilEndJanuary + februaryFirstUntilEndMonth + endDate.getDate(); - return leadingNulls(Math.ceil(days / 7), 2) - } - return compareByDay(firstSunday, janFirst) === 0 ? "01" : "00" - }, - "%V": function(date) { - var janFourthThisYear = new Date(date.tm_year + 1900, 0, 4); - var janFourthNextYear = new Date(date.tm_year + 1901, 0, 4); - var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear); - var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear); - var endDate = __addDays(new Date(date.tm_year + 1900, 0, 1), date.tm_yday); - if (compareByDay(endDate, firstWeekStartThisYear) < 0) { - return "53" - } - if (compareByDay(firstWeekStartNextYear, endDate) <= 0) { - return "01" - } - var daysDifference; - if (firstWeekStartThisYear.getFullYear() < date.tm_year + 1900) { - daysDifference = date.tm_yday + 32 - firstWeekStartThisYear.getDate() - } else { - daysDifference = date.tm_yday + 1 - firstWeekStartThisYear.getDate() - } - return leadingNulls(Math.ceil(daysDifference / 7), 2) - }, - "%w": function(date) { - return date.tm_wday - }, - "%W": function(date) { - var janFirst = new Date(date.tm_year, 0, 1); - var firstMonday = janFirst.getDay() === 1 ? janFirst : __addDays(janFirst, janFirst.getDay() === 0 ? 1 : 7 - janFirst.getDay() + 1); - var endDate = new Date(date.tm_year + 1900, date.tm_mon, date.tm_mday); - if (compareByDay(firstMonday, endDate) < 0) { - var februaryFirstUntilEndMonth = __arraySum(__isLeapYear(endDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, endDate.getMonth() - 1) - 31; - var firstMondayUntilEndJanuary = 31 - firstMonday.getDate(); - var days = firstMondayUntilEndJanuary + februaryFirstUntilEndMonth + endDate.getDate(); - return leadingNulls(Math.ceil(days / 7), 2) - } - return compareByDay(firstMonday, janFirst) === 0 ? "01" : "00" - }, - "%y": function(date) { - return (date.tm_year + 1900).toString().substring(2) - }, - "%Y": function(date) { - return date.tm_year + 1900 - }, - "%z": function(date) { - var off = date.tm_gmtoff; - var ahead = off >= 0; - off = Math.abs(off) / 60; - off = off / 60 * 100 + off % 60; - return (ahead ? "+" : "-") + String("0000" + off).slice(-4) - }, - "%Z": function(date) { - return date.tm_zone - }, - "%%": function() { - return "%" - } - }; - for (var rule in EXPANSION_RULES_2) { - if (pattern.indexOf(rule) >= 0) { - pattern = pattern.replace(new RegExp(rule, "g"), EXPANSION_RULES_2[rule](date)) - } - } - var bytes = intArrayFromString(pattern, false); - if (bytes.length > maxsize) { - return 0 - } - writeArrayToMemory(bytes, s); - return bytes.length - 1 -} - -function _strftime_l(s, maxsize, format, tm) { - return _strftime(s, maxsize, format, tm) -} -var FSNode = function(parent, name, mode, rdev) { - if (!parent) { - parent = this - } - this.parent = parent; - this.mount = parent.mount; - this.mounted = null; - this.id = FS.nextInode++; - this.name = name; - this.mode = mode; - this.node_ops = {}; - this.stream_ops = {}; - this.rdev = rdev -}; -var readMode = 292 | 73; -var writeMode = 146; -Object.defineProperties(FSNode.prototype, { - read: { - get: function() { - return (this.mode & readMode) === readMode - }, - set: function(val) { - val ? this.mode |= readMode : this.mode &= ~readMode - } - }, - write: { - get: function() { - return (this.mode & writeMode) === writeMode - }, - set: function(val) { - val ? this.mode |= writeMode : this.mode &= ~writeMode - } - }, - isFolder: { - get: function() { - return FS.isDir(this.mode) - } - }, - isDevice: { - get: function() { - return FS.isChrdev(this.mode) - } - } -}); -FS.FSNode = FSNode; -FS.staticInit(); - -function intArrayFromString(stringy, dontAddNull, length) { - var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1; - var u8array = new Array(len); - var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length); - if (dontAddNull) u8array.length = numBytesWritten; - return u8array -} -__ATINIT__.push({ - func: function() { - ___wasm_call_ctors() - } -}); -var asmLibraryArg = { - "m": ___cxa_allocate_exception, - "l": ___cxa_throw, - "c": _abort, - "k": _emscripten_memcpy_big, - "d": _emscripten_resize_heap, - "f": _environ_get, - "g": _environ_sizes_get, - "i": _fd_close, - "h": _fd_read, - "j": _fd_seek, - "b": _fd_write, - "a": wasmMemory, - "e": _strftime_l -}; -var asm = createWasm(); -var ___wasm_call_ctors = Module.___wasm_call_ctors = function() { - return (___wasm_call_ctors = Module.___wasm_call_ctors = Module.asm.o).apply(null, arguments) -}; -var _Encoder_new = Module._Encoder_new = function() { - return (_Encoder_new = Module._Encoder_new = Module.asm.p).apply(null, arguments) -}; -var _Encoder_delete = Module._Encoder_delete = function() { - return (_Encoder_delete = Module._Encoder_delete = Module.asm.q).apply(null, arguments) -}; -var _Encoder_input = Module._Encoder_input = function() { - return (_Encoder_input = Module._Encoder_input = Module.asm.r).apply(null, arguments) -}; -var _Encoder_output = Module._Encoder_output = function() { - return (_Encoder_output = Module._Encoder_output = Module.asm.s).apply(null, arguments) -}; -var _Decoder_new = Module._Decoder_new = function() { - return (_Decoder_new = Module._Decoder_new = Module.asm.t).apply(null, arguments) -}; -var _Decoder_delete = Module._Decoder_delete = function() { - return (_Decoder_delete = Module._Decoder_delete = Module.asm.u).apply(null, arguments) -}; -var _Decoder_input = Module._Decoder_input = function() { - return (_Decoder_input = Module._Decoder_input = Module.asm.v).apply(null, arguments) -}; -var _Decoder_output = Module._Decoder_output = function() { - return (_Decoder_output = Module._Decoder_output = Module.asm.w).apply(null, arguments) -}; -var _String_size = Module._String_size = function() { - return (_String_size = Module._String_size = Module.asm.x).apply(null, arguments) -}; -var _String_new = Module._String_new = function() { - return (_String_new = Module._String_new = Module.asm.y).apply(null, arguments) -}; -var _String_data = Module._String_data = function() { - return (_String_data = Module._String_data = Module.asm.z).apply(null, arguments) -}; -var _String_delete = Module._String_delete = function() { - return (_String_delete = Module._String_delete = Module.asm.A).apply(null, arguments) -}; -var _Int16Array_size = Module._Int16Array_size = function() { - return (_Int16Array_size = Module._Int16Array_size = Module.asm.B).apply(null, arguments) -}; -var _Int16Array_new = Module._Int16Array_new = function() { - return (_Int16Array_new = Module._Int16Array_new = Module.asm.C).apply(null, arguments) -}; -var _Int16Array_data = Module._Int16Array_data = function() { - return (_Int16Array_data = Module._Int16Array_data = Module.asm.D).apply(null, arguments) -}; -var _Int16Array_delete = Module._Int16Array_delete = function() { - return (_Int16Array_delete = Module._Int16Array_delete = Module.asm.E).apply(null, arguments) -}; -var _malloc = Module._malloc = function() { - return (_malloc = Module._malloc = Module.asm.F).apply(null, arguments) -}; -var _free = Module._free = function() { - return (_free = Module._free = Module.asm.G).apply(null, arguments) -}; -var ___errno_location = Module.___errno_location = function() { - return (___errno_location = Module.___errno_location = Module.asm.H).apply(null, arguments) -}; -var calledRun; - -function ExitStatus(status) { - this.name = "ExitStatus"; - this.message = "Program terminated with exit(" + status + ")"; - this.status = status -} -dependenciesFulfilled = function runCaller() { - if (!calledRun) run(); - if (!calledRun) dependenciesFulfilled = runCaller -}; - -function run(args) { - args = args || arguments_; - if (runDependencies > 0) { - return - } - preRun(); - if (runDependencies > 0) return; - - function doRun() { - if (calledRun) return; - calledRun = true; - Module.calledRun = true; - if (ABORT) return; - initRuntime(); - preMain(); - if (Module.onRuntimeInitialized) Module.onRuntimeInitialized(); - postRun() - } - if (Module.setStatus) { - Module.setStatus("Running..."); - setTimeout(function() { - setTimeout(function() { - Module.setStatus("") - }, 1); - doRun() - }, 1) - } else { - doRun() - } -} -Module.run = run; -if (Module.preInit) { - if (typeof Module.preInit === "function") Module.preInit = [Module.preInit]; - while (Module.preInit.length > 0) { - Module.preInit.pop()() - } -} -noExitRuntime = true; -run(); - -function Encoder(channels, samplerate, bitrate, frame_size, voice_optimization) { - this.enc = Module._Encoder_new.apply(null, arguments); - this.out = Module._String_new() -} -Encoder.prototype.destroy = function() { - Module._Encoder_delete(this.enc); - Module._String_delete(this.out) -}; -Encoder.prototype.input = function(samples) { - var ptr = Module._malloc(samples.length * samples.BYTES_PER_ELEMENT); - var pdata = new Uint8Array(Module.HEAPU8.buffer, ptr, samples.length * samples.BYTES_PER_ELEMENT); - pdata.set(new Uint8Array(samples.buffer, samples.byteOffset, samples.length * samples.BYTES_PER_ELEMENT)); - Module._Encoder_input(this.enc, ptr, samples.length); - Module._free(ptr) -}; -Encoder.prototype.output = function() { - var ok = Module._Encoder_output(this.enc, this.out); - if (ok) { - return new Uint8Array(Module.HEAPU8.buffer, Module._String_data(this.out), Module._String_size(this.out)) - } else { - throw new Error('not ok'); - } -}; - -function Decoder(channels, samplerate) { - this.dec = Module._Decoder_new.apply(null, arguments); - this.out = Module._Int16Array_new() -} -Decoder.prototype.destroy = function() { - Module._Decoder_delete(this.dec); - Module._Int16Array_delete(this.out) -}; -Decoder.prototype.input = function(packet) { - var ptr = Module._malloc(packet.length * packet.BYTES_PER_ELEMENT); - var pdata = new Uint8Array(Module.HEAPU8.buffer, ptr, packet.length * packet.BYTES_PER_ELEMENT); - pdata.set(new Uint8Array(packet.buffer, packet.byteOffset, packet.length * packet.BYTES_PER_ELEMENT)); - Module._Decoder_input(this.dec, ptr, packet.length); - Module._free(ptr) -}; -Decoder.prototype.output = function() { - var ok = Module._Decoder_output(this.dec, this.out); - if (ok) { - return new Int16Array(Module.HEAPU8.buffer, Module._Int16Array_data(this.out), Module._Int16Array_size(this.out)) - // } else { - // throw new Error('not ok'); - } -}; -Module.Encoder = Encoder; -Module.Decoder = Decoder; -if (Module.ENVIRONMENT != "NODE") libopus = Module; -let accept; -const p = new Promise((a, r) => { - accept = a; -}); -libopus.waitForReady = () => p; -libopus.onRuntimeInitialized = () => { - accept(); -}; -export default libopus; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs/libopus.wasm.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs/libopus.wasm.js deleted file mode 100644 index 3b9deceea..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs/libopus.wasm.js +++ /dev/null @@ -1,3731 +0,0 @@ -import wasm from './libopus.wasm'; - -const location = new URL('http://localhost'); - -let libopus; -var Module = typeof Module !== "undefined" ? Module : {}; -Module.onRuntimeInitialized = function() { - if (Module.onload) Module.onload(); - Module.loaded = true -}; -Module.locateFile = function(url) { - if (url == "libopusjs/libopus.wasm" && typeof LIBOPUS_WASM_URL !== "undefined") return LIBOPUS_WASM_URL; - else return url -}; -var moduleOverrides = {}; -var key; -for (key in Module) { - if (Module.hasOwnProperty(key)) { - moduleOverrides[key] = Module[key] - } -} -var arguments_ = []; -var thisProgram = "./this.program"; -var quit_ = function(status, toThrow) { - throw toThrow -}; -var ENVIRONMENT_IS_WEB = true; -var ENVIRONMENT_IS_WORKER = false; -var ENVIRONMENT_IS_NODE = false; -var ENVIRONMENT_IS_SHELL = false; -// ENVIRONMENT_IS_WEB = typeof window === "object"; -// ENVIRONMENT_IS_WORKER = typeof importScripts === "function"; -// ENVIRONMENT_IS_NODE = typeof process === "object" && typeof process.versions === "object" && typeof process.versions.node === "string"; -// ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; -var scriptDirectory = ""; - -function locateFile(path) { - if (Module.locateFile) { - return Module.locateFile(path, scriptDirectory) - } - return scriptDirectory + path -} -var read_, readAsync, readBinary, setWindowTitle; -var nodeFS; -var nodePath; -if (ENVIRONMENT_IS_NODE) { - if (ENVIRONMENT_IS_WORKER) { - scriptDirectory = require("path").dirname(scriptDirectory) + "/" - } else { - scriptDirectory = __dirname + "/" - } - read_ = function shell_read(filename, binary) { - throw new Error("no fs"); - // if (!nodeFS) nodeFS = require("fs"); - if (!nodePath) nodePath = require("path"); - filename = nodePath.normalize(filename); - return nodeFS.readFileSync(filename, binary ? null : "utf8") - }; - readBinary = function readBinary(filename) { - var ret = read_(filename, true); - if (!ret.buffer) { - ret = new Uint8Array(ret) - } - assert(ret.buffer); - return ret - }; - if (process.argv.length > 1) { - thisProgram = process.argv[1].replace(/\\/g, "/") - } - arguments_ = process.argv.slice(2); - // if (typeof module !== "undefined") { - // module.exports = Module - // } - process.on("uncaughtException", function(ex) { - if (!(ex instanceof ExitStatus)) { - throw ex - } - }); - process.on("unhandledRejection", abort); - quit_ = function(status) { - process.exit(status) - }; - Module.inspect = function() { - return "[Emscripten Module object]" - } -} else if (ENVIRONMENT_IS_SHELL) { - if (typeof read !== "undefined") { - read_ = function shell_read(f) { - return read(f) - } - } - readBinary = function readBinary(f) { - var data; - if (typeof readbuffer === "function") { - return new Uint8Array(readbuffer(f)) - } - data = read(f, "binary"); - assert(typeof data === "object"); - return data - }; - if (typeof scriptArgs !== "undefined") { - arguments_ = scriptArgs - } else if (typeof arguments !== "undefined") { - arguments_ = arguments - } - if (typeof quit === "function") { - quit_ = function(status) { - quit(status) - } - } - if (typeof print !== "undefined") { - if (typeof console === "undefined") console = {}; - console.log = print; - console.warn = console.error = typeof printErr !== "undefined" ? printErr : print - } -} else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { - if (ENVIRONMENT_IS_WORKER) { - scriptDirectory = location.href - } else if (globalThis.document?.currentScript) { - scriptDirectory = globalThis.document?.currentScript.src - } - if (scriptDirectory.indexOf("blob:") !== 0) { - scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf("/") + 1) - } else { - scriptDirectory = "" - } { - read_ = function shell_read(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - xhr.send(null); - return xhr.responseText - }; - if (ENVIRONMENT_IS_WORKER) { - readBinary = function readBinary(url) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - xhr.responseType = "arraybuffer"; - xhr.send(null); - return new Uint8Array(xhr.response) - } - } - readAsync = function readAsync(url, onload, onerror) { - var xhr = new XMLHttpRequest; - xhr.open("GET", url, true); - xhr.responseType = "arraybuffer"; - xhr.onload = function xhr_onload() { - if (xhr.status == 200 || xhr.status == 0 && xhr.response) { - onload(xhr.response); - return - } - onerror() - }; - xhr.onerror = onerror; - xhr.send(null) - } - } - setWindowTitle = function(title) { - globalThis.document && (globalThis.document.title = title); - } -} else {} -var out = Module.print || console.log.bind(console); -var err = Module.printErr || console.warn.bind(console); -for (key in moduleOverrides) { - if (moduleOverrides.hasOwnProperty(key)) { - Module[key] = moduleOverrides[key] - } -} -moduleOverrides = null; -if (Module.arguments) arguments_ = Module.arguments; -if (Module.thisProgram) thisProgram = Module.thisProgram; -if (Module.quit) quit_ = Module.quit; -var STACK_ALIGN = 16; - -function alignMemory(size, factor) { - if (!factor) factor = STACK_ALIGN; - return Math.ceil(size / factor) * factor -} -var wasmBinary; -if (Module.wasmBinary) wasmBinary = Module.wasmBinary; -var noExitRuntime; -if (Module.noExitRuntime) noExitRuntime = Module.noExitRuntime; -if (typeof WebAssembly !== "object") { - abort("no native wasm support detected") -} -var wasmMemory; -var wasmTable; -var ABORT = false; -var EXITSTATUS = 0; - -function assert(condition, text) { - if (!condition) { - abort("Assertion failed: " + text) - } -} -var UTF8Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf8") : undefined; - -function UTF8ArrayToString(heap, idx, maxBytesToRead) { - var endIdx = idx + maxBytesToRead; - var endPtr = idx; - while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr; - if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) { - return UTF8Decoder.decode(heap.subarray(idx, endPtr)) - } else { - var str = ""; - while (idx < endPtr) { - var u0 = heap[idx++]; - if (!(u0 & 128)) { - str += String.fromCharCode(u0); - continue - } - var u1 = heap[idx++] & 63; - if ((u0 & 224) == 192) { - str += String.fromCharCode((u0 & 31) << 6 | u1); - continue - } - var u2 = heap[idx++] & 63; - if ((u0 & 240) == 224) { - u0 = (u0 & 15) << 12 | u1 << 6 | u2 - } else { - u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heap[idx++] & 63 - } - if (u0 < 65536) { - str += String.fromCharCode(u0) - } else { - var ch = u0 - 65536; - str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023) - } - } - } - return str -} - -function UTF8ToString(ptr, maxBytesToRead) { - return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : "" -} - -function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) { - if (!(maxBytesToWrite > 0)) return 0; - var startIdx = outIdx; - var endIdx = outIdx + maxBytesToWrite - 1; - for (var i = 0; i < str.length; ++i) { - var u = str.charCodeAt(i); - if (u >= 55296 && u <= 57343) { - var u1 = str.charCodeAt(++i); - u = 65536 + ((u & 1023) << 10) | u1 & 1023 - } - if (u <= 127) { - if (outIdx >= endIdx) break; - heap[outIdx++] = u - } else if (u <= 2047) { - if (outIdx + 1 >= endIdx) break; - heap[outIdx++] = 192 | u >> 6; - heap[outIdx++] = 128 | u & 63 - } else if (u <= 65535) { - if (outIdx + 2 >= endIdx) break; - heap[outIdx++] = 224 | u >> 12; - heap[outIdx++] = 128 | u >> 6 & 63; - heap[outIdx++] = 128 | u & 63 - } else { - if (outIdx + 3 >= endIdx) break; - heap[outIdx++] = 240 | u >> 18; - heap[outIdx++] = 128 | u >> 12 & 63; - heap[outIdx++] = 128 | u >> 6 & 63; - heap[outIdx++] = 128 | u & 63 - } - } - heap[outIdx] = 0; - return outIdx - startIdx -} - -function stringToUTF8(str, outPtr, maxBytesToWrite) { - return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite) -} - -function lengthBytesUTF8(str) { - var len = 0; - for (var i = 0; i < str.length; ++i) { - var u = str.charCodeAt(i); - if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | str.charCodeAt(++i) & 1023; - if (u <= 127) ++len; - else if (u <= 2047) len += 2; - else if (u <= 65535) len += 3; - else len += 4 - } - return len -} - -function writeArrayToMemory(array, buffer) { - HEAP8.set(array, buffer) -} - -function writeAsciiToMemory(str, buffer, dontAddNull) { - for (var i = 0; i < str.length; ++i) { - HEAP8[buffer++ >> 0] = str.charCodeAt(i) - } - if (!dontAddNull) HEAP8[buffer >> 0] = 0 -} -var WASM_PAGE_SIZE = 65536; -var buffer, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64; - -function updateGlobalBufferAndViews(buf) { - buffer = buf; - Module.HEAP8 = HEAP8 = new Int8Array(buf); - Module.HEAP16 = HEAP16 = new Int16Array(buf); - Module.HEAP32 = HEAP32 = new Int32Array(buf); - Module.HEAPU8 = HEAPU8 = new Uint8Array(buf); - Module.HEAPU16 = HEAPU16 = new Uint16Array(buf); - Module.HEAPU32 = HEAPU32 = new Uint32Array(buf); - Module.HEAPF32 = HEAPF32 = new Float32Array(buf); - Module.HEAPF64 = HEAPF64 = new Float64Array(buf) -} -var INITIAL_INITIAL_MEMORY = Module.INITIAL_MEMORY || 16777216; -if (Module.wasmMemory) { - wasmMemory = Module.wasmMemory -} else { - wasmMemory = new WebAssembly.Memory({ - "initial": INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE, - "maximum": INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE - }) -} -if (wasmMemory) { - buffer = wasmMemory.buffer -} -INITIAL_INITIAL_MEMORY = buffer.byteLength; -updateGlobalBufferAndViews(buffer); -var __ATPRERUN__ = []; -var __ATINIT__ = []; -var __ATMAIN__ = []; -var __ATPOSTRUN__ = []; -var runtimeInitialized = false; - -function preRun() { - if (Module.preRun) { - if (typeof Module.preRun === "function") Module.preRun = [Module.preRun]; - while (Module.preRun.length) { - addOnPreRun(Module.preRun.shift()) - } - } - callRuntimeCallbacks(__ATPRERUN__) -} - -function initRuntime() { - runtimeInitialized = true; - if (!Module.noFSInit && !FS.init.initialized) FS.init(); - TTY.init(); - callRuntimeCallbacks(__ATINIT__) -} - -function preMain() { - FS.ignorePermissions = false; - callRuntimeCallbacks(__ATMAIN__) -} - -function postRun() { - if (Module.postRun) { - if (typeof Module.postRun === "function") Module.postRun = [Module.postRun]; - while (Module.postRun.length) { - addOnPostRun(Module.postRun.shift()) - } - } - callRuntimeCallbacks(__ATPOSTRUN__) -} - -function addOnPreRun(cb) { - __ATPRERUN__.unshift(cb) -} - -function addOnPostRun(cb) { - __ATPOSTRUN__.unshift(cb) -} -var runDependencies = 0; -var runDependencyWatcher = null; -var dependenciesFulfilled = null; - -function getUniqueRunDependency(id) { - return id -} - -function addRunDependency(id) { - runDependencies++; - if (Module.monitorRunDependencies) { - Module.monitorRunDependencies(runDependencies) - } -} - -function removeRunDependency(id) { - runDependencies--; - if (Module.monitorRunDependencies) { - Module.monitorRunDependencies(runDependencies) - } - if (runDependencies == 0) { - if (runDependencyWatcher !== null) { - clearInterval(runDependencyWatcher); - runDependencyWatcher = null - } - if (dependenciesFulfilled) { - var callback = dependenciesFulfilled; - dependenciesFulfilled = null; - callback() - } - } -} -Module.preloadedImages = {}; -Module.preloadedAudios = {}; - -function abort(what) { - if (Module.onAbort) { - Module.onAbort(what) - } - what += ""; - err(what); - ABORT = true; - EXITSTATUS = 1; - what = "abort(" + what + "). Build with -s ASSERTIONS=1 for more info."; - var e = new WebAssembly.RuntimeError(what); - throw e -} - -function hasPrefix(str, prefix) { - return String.prototype.startsWith ? str.startsWith(prefix) : str.indexOf(prefix) === 0 -} -var dataURIPrefix = "data:application/octet-stream;base64,"; - -function isDataURI(filename) { - return hasPrefix(filename, dataURIPrefix) -} -var fileURIPrefix = "file://"; - -function isFileURI(filename) { - return hasPrefix(filename, fileURIPrefix) -} -var wasmBinaryFile = "libopusjs/libopus.wasm"; -if (!isDataURI(wasmBinaryFile)) { - wasmBinaryFile = locateFile(wasmBinaryFile) -} - -function getBinary() { - try { - if (wasmBinary) { - return new Uint8Array(wasmBinary) - } - if (readBinary) { - return readBinary(wasmBinaryFile) - } else { - throw "both async and sync fetching of the wasm failed" - } - } catch (err) { - abort(err) - } -} - -async function getBinaryPromise() { - return wasm; - /* if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && typeof fetch === "function" && !isFileURI(wasmBinaryFile)) { - console.log('binary promise', { - wasmBinaryFile, - }); - const s = new URL(wasmBinaryFile, 'http://localhost'); - return fetch(s, { - // credentials: "same-origin" - }).then(function(response) { - if (!response.ok) { - throw "failed to load wasm binary file at '" + wasmBinaryFile + "'" - } - return response.arrayBuffer() - }).catch(function() { - return getBinary() - }) - } - return Promise.resolve().then(getBinary) */ -} - -function createWasm() { - var info = { - "a": asmLibraryArg - }; - - function receiveInstance(instance, module) { - var exports = instance.exports; - Module.asm = exports; - wasmTable = Module.asm.n; - removeRunDependency("wasm-instantiate") - } - addRunDependency("wasm-instantiate"); - - function receiveInstantiatedSource(output) { - receiveInstance(output.instance) - } - - function instantiateArrayBuffer(receiver) { - return getBinaryPromise().then(function(binary) { - return WebAssembly.instantiate(binary, info) - }).then(receiver, function(reason) { - err("failed to asynchronously prepare wasm: " + reason); - abort(reason) - }) - } - - async function instantiateAsync() { - const instance = await WebAssembly.instantiate(wasm, info); - receiveInstance(instance); - } - if (Module.instantiateWasm) { - try { - var exports = Module.instantiateWasm(info, receiveInstance); - return exports - } catch (e) { - err("Module.instantiateWasm callback failed with error: " + e); - return false - } - } - instantiateAsync(); - return {} -} -var tempDouble; -var tempI64; - -function callRuntimeCallbacks(callbacks) { - while (callbacks.length > 0) { - var callback = callbacks.shift(); - if (typeof callback === "function") { - callback(Module); - continue - } - var func = callback.func; - if (typeof func === "number") { - if (callback.arg === undefined) { - wasmTable.get(func)() - } else { - wasmTable.get(func)(callback.arg) - } - } else { - func(callback.arg === undefined ? null : callback.arg) - } - } -} - -function demangle(func) { - return func -} - -function demangleAll(text) { - var regex = /\b_Z[\w\d_]+/g; - return text.replace(regex, function(x) { - var y = demangle(x); - return x === y ? x : y + " [" + x + "]" - }) -} - -function jsStackTrace() { - var error = new Error; - if (!error.stack) { - try { - throw new Error - } catch (e) { - error = e - } - if (!error.stack) { - return "(no stack trace available)" - } - } - return error.stack.toString() -} - -function stackTrace() { - var js = jsStackTrace(); - if (Module.extraStackTrace) js += "\n" + Module.extraStackTrace(); - return demangleAll(js) -} -var ExceptionInfoAttrs = { - DESTRUCTOR_OFFSET: 0, - REFCOUNT_OFFSET: 4, - TYPE_OFFSET: 8, - CAUGHT_OFFSET: 12, - RETHROWN_OFFSET: 13, - SIZE: 16 -}; - -function ___cxa_allocate_exception(size) { - return _malloc(size + ExceptionInfoAttrs.SIZE) + ExceptionInfoAttrs.SIZE -} - -function ExceptionInfo(excPtr) { - this.excPtr = excPtr; - this.ptr = excPtr - ExceptionInfoAttrs.SIZE; - this.set_type = function(type) { - HEAP32[this.ptr + ExceptionInfoAttrs.TYPE_OFFSET >> 2] = type - }; - this.get_type = function() { - return HEAP32[this.ptr + ExceptionInfoAttrs.TYPE_OFFSET >> 2] - }; - this.set_destructor = function(destructor) { - HEAP32[this.ptr + ExceptionInfoAttrs.DESTRUCTOR_OFFSET >> 2] = destructor - }; - this.get_destructor = function() { - return HEAP32[this.ptr + ExceptionInfoAttrs.DESTRUCTOR_OFFSET >> 2] - }; - this.set_refcount = function(refcount) { - HEAP32[this.ptr + ExceptionInfoAttrs.REFCOUNT_OFFSET >> 2] = refcount - }; - this.set_caught = function(caught) { - caught = caught ? 1 : 0; - HEAP8[this.ptr + ExceptionInfoAttrs.CAUGHT_OFFSET >> 0] = caught - }; - this.get_caught = function() { - return HEAP8[this.ptr + ExceptionInfoAttrs.CAUGHT_OFFSET >> 0] != 0 - }; - this.set_rethrown = function(rethrown) { - rethrown = rethrown ? 1 : 0; - HEAP8[this.ptr + ExceptionInfoAttrs.RETHROWN_OFFSET >> 0] = rethrown - }; - this.get_rethrown = function() { - return HEAP8[this.ptr + ExceptionInfoAttrs.RETHROWN_OFFSET >> 0] != 0 - }; - this.init = function(type, destructor) { - this.set_type(type); - this.set_destructor(destructor); - this.set_refcount(0); - this.set_caught(false); - this.set_rethrown(false) - }; - this.add_ref = function() { - var value = HEAP32[this.ptr + ExceptionInfoAttrs.REFCOUNT_OFFSET >> 2]; - HEAP32[this.ptr + ExceptionInfoAttrs.REFCOUNT_OFFSET >> 2] = value + 1 - }; - this.release_ref = function() { - var prev = HEAP32[this.ptr + ExceptionInfoAttrs.REFCOUNT_OFFSET >> 2]; - HEAP32[this.ptr + ExceptionInfoAttrs.REFCOUNT_OFFSET >> 2] = prev - 1; - return prev === 1 - } -} -var exceptionLast = 0; - -function __ZSt18uncaught_exceptionv() { - return __ZSt18uncaught_exceptionv.uncaught_exceptions > 0 -} - -function ___cxa_throw(ptr, type, destructor) { - var info = new ExceptionInfo(ptr); - info.init(type, destructor); - exceptionLast = ptr; - if (!("uncaught_exception" in __ZSt18uncaught_exceptionv)) { - __ZSt18uncaught_exceptionv.uncaught_exceptions = 1 - } else { - __ZSt18uncaught_exceptionv.uncaught_exceptions++ - } - throw ptr -} - -function _abort() { - abort() -} - -function _emscripten_memcpy_big(dest, src, num) { - HEAPU8.copyWithin(dest, src, src + num) -} - -function abortOnCannotGrowMemory(requestedSize) { - abort("OOM") -} - -function _emscripten_resize_heap(requestedSize) { - requestedSize = requestedSize >>> 0; - abortOnCannotGrowMemory(requestedSize) -} -var ENV = {}; - -function getExecutableName() { - return thisProgram || "./this.program" -} - -function getEnvStrings() { - if (!getEnvStrings.strings) { - var lang = (typeof navigator === "object" && navigator.languages && navigator.languages[0] || "C").replace("-", "_") + ".UTF-8"; - var env = { - "USER": "web_user", - "LOGNAME": "web_user", - "PATH": "/", - "PWD": "/", - "HOME": "/home/web_user", - "LANG": lang, - "_": getExecutableName() - }; - for (var x in ENV) { - env[x] = ENV[x] - } - var strings = []; - for (var x in env) { - strings.push(x + "=" + env[x]) - } - getEnvStrings.strings = strings - } - return getEnvStrings.strings -} - -function _environ_get(__environ, environ_buf) { - var bufSize = 0; - getEnvStrings().forEach(function(string, i) { - var ptr = environ_buf + bufSize; - HEAP32[__environ + i * 4 >> 2] = ptr; - writeAsciiToMemory(string, ptr); - bufSize += string.length + 1 - }); - return 0 -} - -function _environ_sizes_get(penviron_count, penviron_buf_size) { - var strings = getEnvStrings(); - HEAP32[penviron_count >> 2] = strings.length; - var bufSize = 0; - strings.forEach(function(string) { - bufSize += string.length + 1 - }); - HEAP32[penviron_buf_size >> 2] = bufSize; - return 0 -} -var PATH = { - splitPath: function(filename) { - var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; - return splitPathRe.exec(filename).slice(1) - }, - normalizeArray: function(parts, allowAboveRoot) { - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === ".") { - parts.splice(i, 1) - } else if (last === "..") { - parts.splice(i, 1); - up++ - } else if (up) { - parts.splice(i, 1); - up-- - } - } - if (allowAboveRoot) { - for (; up; up--) { - parts.unshift("..") - } - } - return parts - }, - normalize: function(path) { - var isAbsolute = path.charAt(0) === "/"; - var trailingSlash = path.substr(-1) === "/"; - path = PATH.normalizeArray(path.split("/").filter(function(p) { - return !!p - }), !isAbsolute).join("/"); - if (!path && !isAbsolute) { - path = "." - } - if (path && trailingSlash) { - path += "/" - } - return (isAbsolute ? "/" : "") + path - }, - dirname: function(path) { - var result = PATH.splitPath(path); - var root = result[0]; - var dir = result[1]; - if (!root && !dir) { - return "." - } - if (dir) { - dir = dir.substr(0, dir.length - 1) - } - return root + dir - }, - basename: function(path) { - if (path === "/") return "/"; - path = PATH.normalize(path); - path = path.replace(/\/$/, ""); - var lastSlash = path.lastIndexOf("/"); - if (lastSlash === -1) return path; - return path.substr(lastSlash + 1) - }, - extname: function(path) { - return PATH.splitPath(path)[3] - }, - join: function() { - var paths = Array.prototype.slice.call(arguments, 0); - return PATH.normalize(paths.join("/")) - }, - join2: function(l, r) { - return PATH.normalize(l + "/" + r) - } -}; - -function setErrNo(value) { - HEAP32[___errno_location() >> 2] = value; - return value -} - -function getRandomDevice() { - if (typeof crypto === "object" && typeof crypto.getRandomValues === "function") { - var randomBuffer = new Uint8Array(1); - return function() { - crypto.getRandomValues(randomBuffer); - return randomBuffer[0] - } - } else if (ENVIRONMENT_IS_NODE) { - try { - var crypto_module = require("crypto"); - return function() { - return crypto_module.randomBytes(1)[0] - } - } catch (e) {} - } - return function() { - abort("randomDevice") - } -} -var PATH_FS = { - resolve: function() { - var resolvedPath = ""; - var resolvedAbsolute = false; - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = i >= 0 ? arguments[i] : FS.cwd(); - if (typeof path !== "string") { - throw new TypeError("Arguments to path.resolve must be strings") - } else if (!path) { - return "" - } - resolvedPath = path + "/" + resolvedPath; - resolvedAbsolute = path.charAt(0) === "/" - } - resolvedPath = PATH.normalizeArray(resolvedPath.split("/").filter(function(p) { - return !!p - }), !resolvedAbsolute).join("/"); - return (resolvedAbsolute ? "/" : "") + resolvedPath || "." - }, - relative: function(from, to) { - from = PATH_FS.resolve(from).substr(1); - to = PATH_FS.resolve(to).substr(1); - - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== "") break - } - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== "") break - } - if (start > end) return []; - return arr.slice(start, end - start + 1) - } - var fromParts = trim(from.split("/")); - var toParts = trim(to.split("/")); - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break - } - } - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push("..") - } - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - return outputParts.join("/") - } -}; -var TTY = { - ttys: [], - init: function() {}, - shutdown: function() {}, - register: function(dev, ops) { - TTY.ttys[dev] = { - input: [], - output: [], - ops: ops - }; - FS.registerDevice(dev, TTY.stream_ops) - }, - stream_ops: { - open: function(stream) { - var tty = TTY.ttys[stream.node.rdev]; - if (!tty) { - throw new FS.ErrnoError(43) - } - stream.tty = tty; - stream.seekable = false - }, - close: function(stream) { - stream.tty.ops.flush(stream.tty) - }, - flush: function(stream) { - stream.tty.ops.flush(stream.tty) - }, - read: function(stream, buffer, offset, length, pos) { - if (!stream.tty || !stream.tty.ops.get_char) { - throw new FS.ErrnoError(60) - } - var bytesRead = 0; - for (var i = 0; i < length; i++) { - var result; - try { - result = stream.tty.ops.get_char(stream.tty) - } catch (e) { - throw new FS.ErrnoError(29) - } - if (result === undefined && bytesRead === 0) { - throw new FS.ErrnoError(6) - } - if (result === null || result === undefined) break; - bytesRead++; - buffer[offset + i] = result - } - if (bytesRead) { - stream.node.timestamp = Date.now() - } - return bytesRead - }, - write: function(stream, buffer, offset, length, pos) { - if (!stream.tty || !stream.tty.ops.put_char) { - throw new FS.ErrnoError(60) - } - try { - for (var i = 0; i < length; i++) { - stream.tty.ops.put_char(stream.tty, buffer[offset + i]) - } - } catch (e) { - throw new FS.ErrnoError(29) - } - if (length) { - stream.node.timestamp = Date.now() - } - return i - } - }, - default_tty_ops: { - get_char: function(tty) { - if (!tty.input.length) { - var result = null; - if (ENVIRONMENT_IS_NODE) { - var BUFSIZE = 256; - var buf = Buffer.alloc ? Buffer.alloc(BUFSIZE) : new Buffer(BUFSIZE); - var bytesRead = 0; - try { - bytesRead = nodeFS.readSync(process.stdin.fd, buf, 0, BUFSIZE, null) - } catch (e) { - if (e.toString().indexOf("EOF") != -1) bytesRead = 0; - else throw e - } - if (bytesRead > 0) { - result = buf.slice(0, bytesRead).toString("utf-8") - } else { - result = null - } - } else if (typeof window !== "undefined" && typeof window.prompt === "function") { - result = window.prompt("Input: "); - if (result !== null) { - result += "\n" - } - } else if (typeof readline === "function") { - result = readline(); - if (result !== null) { - result += "\n" - } - } - if (!result) { - return null - } - tty.input = intArrayFromString(result, true) - } - return tty.input.shift() - }, - put_char: function(tty, val) { - if (val === null || val === 10) { - out(UTF8ArrayToString(tty.output, 0)); - tty.output = [] - } else { - if (val != 0) tty.output.push(val) - } - }, - flush: function(tty) { - if (tty.output && tty.output.length > 0) { - out(UTF8ArrayToString(tty.output, 0)); - tty.output = [] - } - } - }, - default_tty1_ops: { - put_char: function(tty, val) { - if (val === null || val === 10) { - err(UTF8ArrayToString(tty.output, 0)); - tty.output = [] - } else { - if (val != 0) tty.output.push(val) - } - }, - flush: function(tty) { - if (tty.output && tty.output.length > 0) { - err(UTF8ArrayToString(tty.output, 0)); - tty.output = [] - } - } - } -}; - -function mmapAlloc(size) { - var alignedSize = alignMemory(size, 16384); - var ptr = _malloc(alignedSize); - while (size < alignedSize) HEAP8[ptr + size++] = 0; - return ptr -} -var MEMFS = { - ops_table: null, - mount: function(mount) { - return MEMFS.createNode(null, "/", 16384 | 511, 0) - }, - createNode: function(parent, name, mode, dev) { - if (FS.isBlkdev(mode) || FS.isFIFO(mode)) { - throw new FS.ErrnoError(63) - } - if (!MEMFS.ops_table) { - MEMFS.ops_table = { - dir: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr, - lookup: MEMFS.node_ops.lookup, - mknod: MEMFS.node_ops.mknod, - rename: MEMFS.node_ops.rename, - unlink: MEMFS.node_ops.unlink, - rmdir: MEMFS.node_ops.rmdir, - readdir: MEMFS.node_ops.readdir, - symlink: MEMFS.node_ops.symlink - }, - stream: { - llseek: MEMFS.stream_ops.llseek - } - }, - file: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr - }, - stream: { - llseek: MEMFS.stream_ops.llseek, - read: MEMFS.stream_ops.read, - write: MEMFS.stream_ops.write, - allocate: MEMFS.stream_ops.allocate, - mmap: MEMFS.stream_ops.mmap, - msync: MEMFS.stream_ops.msync - } - }, - link: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr, - readlink: MEMFS.node_ops.readlink - }, - stream: {} - }, - chrdev: { - node: { - getattr: MEMFS.node_ops.getattr, - setattr: MEMFS.node_ops.setattr - }, - stream: FS.chrdev_stream_ops - } - } - } - var node = FS.createNode(parent, name, mode, dev); - if (FS.isDir(node.mode)) { - node.node_ops = MEMFS.ops_table.dir.node; - node.stream_ops = MEMFS.ops_table.dir.stream; - node.contents = {} - } else if (FS.isFile(node.mode)) { - node.node_ops = MEMFS.ops_table.file.node; - node.stream_ops = MEMFS.ops_table.file.stream; - node.usedBytes = 0; - node.contents = null - } else if (FS.isLink(node.mode)) { - node.node_ops = MEMFS.ops_table.link.node; - node.stream_ops = MEMFS.ops_table.link.stream - } else if (FS.isChrdev(node.mode)) { - node.node_ops = MEMFS.ops_table.chrdev.node; - node.stream_ops = MEMFS.ops_table.chrdev.stream - } - node.timestamp = Date.now(); - if (parent) { - parent.contents[name] = node - } - return node - }, - getFileDataAsRegularArray: function(node) { - if (node.contents && node.contents.subarray) { - var arr = []; - for (var i = 0; i < node.usedBytes; ++i) arr.push(node.contents[i]); - return arr - } - return node.contents - }, - getFileDataAsTypedArray: function(node) { - if (!node.contents) return new Uint8Array(0); - if (node.contents.subarray) return node.contents.subarray(0, node.usedBytes); - return new Uint8Array(node.contents) - }, - expandFileStorage: function(node, newCapacity) { - var prevCapacity = node.contents ? node.contents.length : 0; - if (prevCapacity >= newCapacity) return; - var CAPACITY_DOUBLING_MAX = 1024 * 1024; - newCapacity = Math.max(newCapacity, prevCapacity * (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125) >>> 0); - if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256); - var oldContents = node.contents; - node.contents = new Uint8Array(newCapacity); - if (node.usedBytes > 0) node.contents.set(oldContents.subarray(0, node.usedBytes), 0); - }, - resizeFileStorage: function(node, newSize) { - if (node.usedBytes == newSize) return; - if (newSize == 0) { - node.contents = null; - node.usedBytes = 0; - return - } - if (!node.contents || node.contents.subarray) { - var oldContents = node.contents; - node.contents = new Uint8Array(newSize); - if (oldContents) { - node.contents.set(oldContents.subarray(0, Math.min(newSize, node.usedBytes))) - } - node.usedBytes = newSize; - return - } - if (!node.contents) node.contents = []; - if (node.contents.length > newSize) node.contents.length = newSize; - else - while (node.contents.length < newSize) node.contents.push(0); - node.usedBytes = newSize - }, - node_ops: { - getattr: function(node) { - var attr = {}; - attr.dev = FS.isChrdev(node.mode) ? node.id : 1; - attr.ino = node.id; - attr.mode = node.mode; - attr.nlink = 1; - attr.uid = 0; - attr.gid = 0; - attr.rdev = node.rdev; - if (FS.isDir(node.mode)) { - attr.size = 4096 - } else if (FS.isFile(node.mode)) { - attr.size = node.usedBytes - } else if (FS.isLink(node.mode)) { - attr.size = node.link.length - } else { - attr.size = 0 - } - attr.atime = new Date(node.timestamp); - attr.mtime = new Date(node.timestamp); - attr.ctime = new Date(node.timestamp); - attr.blksize = 4096; - attr.blocks = Math.ceil(attr.size / attr.blksize); - return attr - }, - setattr: function(node, attr) { - if (attr.mode !== undefined) { - node.mode = attr.mode - } - if (attr.timestamp !== undefined) { - node.timestamp = attr.timestamp - } - if (attr.size !== undefined) { - MEMFS.resizeFileStorage(node, attr.size) - } - }, - lookup: function(parent, name) { - throw FS.genericErrors[44] - }, - mknod: function(parent, name, mode, dev) { - return MEMFS.createNode(parent, name, mode, dev) - }, - rename: function(old_node, new_dir, new_name) { - if (FS.isDir(old_node.mode)) { - var new_node; - try { - new_node = FS.lookupNode(new_dir, new_name) - } catch (e) {} - if (new_node) { - for (var i in new_node.contents) { - throw new FS.ErrnoError(55) - } - } - } - delete old_node.parent.contents[old_node.name]; - old_node.name = new_name; - new_dir.contents[new_name] = old_node; - old_node.parent = new_dir - }, - unlink: function(parent, name) { - delete parent.contents[name] - }, - rmdir: function(parent, name) { - var node = FS.lookupNode(parent, name); - for (var i in node.contents) { - throw new FS.ErrnoError(55) - } - delete parent.contents[name] - }, - readdir: function(node) { - var entries = [".", ".."]; - for (var key in node.contents) { - if (!node.contents.hasOwnProperty(key)) { - continue - } - entries.push(key) - } - return entries - }, - symlink: function(parent, newname, oldpath) { - var node = MEMFS.createNode(parent, newname, 511 | 40960, 0); - node.link = oldpath; - return node - }, - readlink: function(node) { - if (!FS.isLink(node.mode)) { - throw new FS.ErrnoError(28) - } - return node.link - } - }, - stream_ops: { - read: function(stream, buffer, offset, length, position) { - var contents = stream.node.contents; - if (position >= stream.node.usedBytes) return 0; - var size = Math.min(stream.node.usedBytes - position, length); - if (size > 8 && contents.subarray) { - buffer.set(contents.subarray(position, position + size), offset) - } else { - for (var i = 0; i < size; i++) buffer[offset + i] = contents[position + i] - } - return size - }, - write: function(stream, buffer, offset, length, position, canOwn) { - if (!length) return 0; - var node = stream.node; - node.timestamp = Date.now(); - if (buffer.subarray && (!node.contents || node.contents.subarray)) { - if (canOwn) { - node.contents = buffer.subarray(offset, offset + length); - node.usedBytes = length; - return length - } else if (node.usedBytes === 0 && position === 0) { - node.contents = buffer.slice(offset, offset + length); - node.usedBytes = length; - return length - } else if (position + length <= node.usedBytes) { - node.contents.set(buffer.subarray(offset, offset + length), position); - return length - } - } - MEMFS.expandFileStorage(node, position + length); - if (node.contents.subarray && buffer.subarray) { - node.contents.set(buffer.subarray(offset, offset + length), position) - } else { - for (var i = 0; i < length; i++) { - node.contents[position + i] = buffer[offset + i] - } - } - node.usedBytes = Math.max(node.usedBytes, position + length); - return length - }, - llseek: function(stream, offset, whence) { - var position = offset; - if (whence === 1) { - position += stream.position - } else if (whence === 2) { - if (FS.isFile(stream.node.mode)) { - position += stream.node.usedBytes - } - } - if (position < 0) { - throw new FS.ErrnoError(28) - } - return position - }, - allocate: function(stream, offset, length) { - MEMFS.expandFileStorage(stream.node, offset + length); - stream.node.usedBytes = Math.max(stream.node.usedBytes, offset + length) - }, - mmap: function(stream, address, length, position, prot, flags) { - assert(address === 0); - if (!FS.isFile(stream.node.mode)) { - throw new FS.ErrnoError(43) - } - var ptr; - var allocated; - var contents = stream.node.contents; - if (!(flags & 2) && contents.buffer === buffer) { - allocated = false; - ptr = contents.byteOffset - } else { - if (position > 0 || position + length < contents.length) { - if (contents.subarray) { - contents = contents.subarray(position, position + length) - } else { - contents = Array.prototype.slice.call(contents, position, position + length) - } - } - allocated = true; - ptr = mmapAlloc(length); - if (!ptr) { - throw new FS.ErrnoError(48) - } - HEAP8.set(contents, ptr) - } - return { - ptr: ptr, - allocated: allocated - } - }, - msync: function(stream, buffer, offset, length, mmapFlags) { - if (!FS.isFile(stream.node.mode)) { - throw new FS.ErrnoError(43) - } - if (mmapFlags & 2) { - return 0 - } - var bytesWritten = MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false); - return 0 - } - } -}; -var FS = { - root: null, - mounts: [], - devices: {}, - streams: [], - nextInode: 1, - nameTable: null, - currentPath: "/", - initialized: false, - ignorePermissions: true, - trackingDelegate: {}, - tracking: { - openFlags: { - READ: 1, - WRITE: 2 - } - }, - ErrnoError: null, - genericErrors: {}, - filesystems: null, - syncFSRequests: 0, - handleFSError: function(e) { - if (!(e instanceof FS.ErrnoError)) throw e + " : " + stackTrace(); - return setErrNo(e.errno) - }, - lookupPath: function(path, opts) { - path = PATH_FS.resolve(FS.cwd(), path); - opts = opts || {}; - if (!path) return { - path: "", - node: null - }; - var defaults = { - follow_mount: true, - recurse_count: 0 - }; - for (var key in defaults) { - if (opts[key] === undefined) { - opts[key] = defaults[key] - } - } - if (opts.recurse_count > 8) { - throw new FS.ErrnoError(32) - } - var parts = PATH.normalizeArray(path.split("/").filter(function(p) { - return !!p - }), false); - var current = FS.root; - var current_path = "/"; - for (var i = 0; i < parts.length; i++) { - var islast = i === parts.length - 1; - if (islast && opts.parent) { - break - } - current = FS.lookupNode(current, parts[i]); - current_path = PATH.join2(current_path, parts[i]); - if (FS.isMountpoint(current)) { - if (!islast || islast && opts.follow_mount) { - current = current.mounted.root - } - } - if (!islast || opts.follow) { - var count = 0; - while (FS.isLink(current.mode)) { - var link = FS.readlink(current_path); - current_path = PATH_FS.resolve(PATH.dirname(current_path), link); - var lookup = FS.lookupPath(current_path, { - recurse_count: opts.recurse_count - }); - current = lookup.node; - if (count++ > 40) { - throw new FS.ErrnoError(32) - } - } - } - } - return { - path: current_path, - node: current - } - }, - getPath: function(node) { - var path; - while (true) { - if (FS.isRoot(node)) { - var mount = node.mount.mountpoint; - if (!path) return mount; - return mount[mount.length - 1] !== "/" ? mount + "/" + path : mount + path - } - path = path ? node.name + "/" + path : node.name; - node = node.parent - } - }, - hashName: function(parentid, name) { - var hash = 0; - for (var i = 0; i < name.length; i++) { - hash = (hash << 5) - hash + name.charCodeAt(i) | 0 - } - return (parentid + hash >>> 0) % FS.nameTable.length - }, - hashAddNode: function(node) { - var hash = FS.hashName(node.parent.id, node.name); - node.name_next = FS.nameTable[hash]; - FS.nameTable[hash] = node - }, - hashRemoveNode: function(node) { - var hash = FS.hashName(node.parent.id, node.name); - if (FS.nameTable[hash] === node) { - FS.nameTable[hash] = node.name_next - } else { - var current = FS.nameTable[hash]; - while (current) { - if (current.name_next === node) { - current.name_next = node.name_next; - break - } - current = current.name_next - } - } - }, - lookupNode: function(parent, name) { - var errCode = FS.mayLookup(parent); - if (errCode) { - throw new FS.ErrnoError(errCode, parent) - } - var hash = FS.hashName(parent.id, name); - for (var node = FS.nameTable[hash]; node; node = node.name_next) { - var nodeName = node.name; - if (node.parent.id === parent.id && nodeName === name) { - return node - } - } - return FS.lookup(parent, name) - }, - createNode: function(parent, name, mode, rdev) { - var node = new FS.FSNode(parent, name, mode, rdev); - FS.hashAddNode(node); - return node - }, - destroyNode: function(node) { - FS.hashRemoveNode(node) - }, - isRoot: function(node) { - return node === node.parent - }, - isMountpoint: function(node) { - return !!node.mounted - }, - isFile: function(mode) { - return (mode & 61440) === 32768 - }, - isDir: function(mode) { - return (mode & 61440) === 16384 - }, - isLink: function(mode) { - return (mode & 61440) === 40960 - }, - isChrdev: function(mode) { - return (mode & 61440) === 8192 - }, - isBlkdev: function(mode) { - return (mode & 61440) === 24576 - }, - isFIFO: function(mode) { - return (mode & 61440) === 4096 - }, - isSocket: function(mode) { - return (mode & 49152) === 49152 - }, - flagModes: { - "r": 0, - "rs": 1052672, - "r+": 2, - "w": 577, - "wx": 705, - "xw": 705, - "w+": 578, - "wx+": 706, - "xw+": 706, - "a": 1089, - "ax": 1217, - "xa": 1217, - "a+": 1090, - "ax+": 1218, - "xa+": 1218 - }, - modeStringToFlags: function(str) { - var flags = FS.flagModes[str]; - if (typeof flags === "undefined") { - throw new Error("Unknown file open mode: " + str) - } - return flags - }, - flagsToPermissionString: function(flag) { - var perms = ["r", "w", "rw"][flag & 3]; - if (flag & 512) { - perms += "w" - } - return perms - }, - nodePermissions: function(node, perms) { - if (FS.ignorePermissions) { - return 0 - } - if (perms.indexOf("r") !== -1 && !(node.mode & 292)) { - return 2 - } else if (perms.indexOf("w") !== -1 && !(node.mode & 146)) { - return 2 - } else if (perms.indexOf("x") !== -1 && !(node.mode & 73)) { - return 2 - } - return 0 - }, - mayLookup: function(dir) { - var errCode = FS.nodePermissions(dir, "x"); - if (errCode) return errCode; - if (!dir.node_ops.lookup) return 2; - return 0 - }, - mayCreate: function(dir, name) { - try { - var node = FS.lookupNode(dir, name); - return 20 - } catch (e) {} - return FS.nodePermissions(dir, "wx") - }, - mayDelete: function(dir, name, isdir) { - var node; - try { - node = FS.lookupNode(dir, name) - } catch (e) { - return e.errno - } - var errCode = FS.nodePermissions(dir, "wx"); - if (errCode) { - return errCode - } - if (isdir) { - if (!FS.isDir(node.mode)) { - return 54 - } - if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) { - return 10 - } - } else { - if (FS.isDir(node.mode)) { - return 31 - } - } - return 0 - }, - mayOpen: function(node, flags) { - if (!node) { - return 44 - } - if (FS.isLink(node.mode)) { - return 32 - } else if (FS.isDir(node.mode)) { - if (FS.flagsToPermissionString(flags) !== "r" || flags & 512) { - return 31 - } - } - return FS.nodePermissions(node, FS.flagsToPermissionString(flags)) - }, - MAX_OPEN_FDS: 4096, - nextfd: function(fd_start, fd_end) { - fd_start = fd_start || 0; - fd_end = fd_end || FS.MAX_OPEN_FDS; - for (var fd = fd_start; fd <= fd_end; fd++) { - if (!FS.streams[fd]) { - return fd - } - } - throw new FS.ErrnoError(33) - }, - getStream: function(fd) { - return FS.streams[fd] - }, - createStream: function(stream, fd_start, fd_end) { - if (!FS.FSStream) { - FS.FSStream = function() {}; - FS.FSStream.prototype = { - object: { - get: function() { - return this.node - }, - set: function(val) { - this.node = val - } - }, - isRead: { - get: function() { - return (this.flags & 2097155) !== 1 - } - }, - isWrite: { - get: function() { - return (this.flags & 2097155) !== 0 - } - }, - isAppend: { - get: function() { - return this.flags & 1024 - } - } - } - } - var newStream = new FS.FSStream; - for (var p in stream) { - newStream[p] = stream[p] - } - stream = newStream; - var fd = FS.nextfd(fd_start, fd_end); - stream.fd = fd; - FS.streams[fd] = stream; - return stream - }, - closeStream: function(fd) { - FS.streams[fd] = null - }, - chrdev_stream_ops: { - open: function(stream) { - var device = FS.getDevice(stream.node.rdev); - stream.stream_ops = device.stream_ops; - if (stream.stream_ops.open) { - stream.stream_ops.open(stream) - } - }, - llseek: function() { - throw new FS.ErrnoError(70) - } - }, - major: function(dev) { - return dev >> 8 - }, - minor: function(dev) { - return dev & 255 - }, - makedev: function(ma, mi) { - return ma << 8 | mi - }, - registerDevice: function(dev, ops) { - FS.devices[dev] = { - stream_ops: ops - } - }, - getDevice: function(dev) { - return FS.devices[dev] - }, - getMounts: function(mount) { - var mounts = []; - var check = [mount]; - while (check.length) { - var m = check.pop(); - mounts.push(m); - check.push.apply(check, m.mounts) - } - return mounts - }, - syncfs: function(populate, callback) { - if (typeof populate === "function") { - callback = populate; - populate = false - } - FS.syncFSRequests++; - if (FS.syncFSRequests > 1) { - err("warning: " + FS.syncFSRequests + " FS.syncfs operations in flight at once, probably just doing extra work") - } - var mounts = FS.getMounts(FS.root.mount); - var completed = 0; - - function doCallback(errCode) { - FS.syncFSRequests--; - return callback(errCode) - } - - function done(errCode) { - if (errCode) { - if (!done.errored) { - done.errored = true; - return doCallback(errCode) - } - return - } - if (++completed >= mounts.length) { - doCallback(null) - } - } - mounts.forEach(function(mount) { - if (!mount.type.syncfs) { - return done(null) - } - mount.type.syncfs(mount, populate, done) - }) - }, - mount: function(type, opts, mountpoint) { - var root = mountpoint === "/"; - var pseudo = !mountpoint; - var node; - if (root && FS.root) { - throw new FS.ErrnoError(10) - } else if (!root && !pseudo) { - var lookup = FS.lookupPath(mountpoint, { - follow_mount: false - }); - mountpoint = lookup.path; - node = lookup.node; - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10) - } - if (!FS.isDir(node.mode)) { - throw new FS.ErrnoError(54) - } - } - var mount = { - type: type, - opts: opts, - mountpoint: mountpoint, - mounts: [] - }; - var mountRoot = type.mount(mount); - mountRoot.mount = mount; - mount.root = mountRoot; - if (root) { - FS.root = mountRoot - } else if (node) { - node.mounted = mount; - if (node.mount) { - node.mount.mounts.push(mount) - } - } - return mountRoot - }, - unmount: function(mountpoint) { - var lookup = FS.lookupPath(mountpoint, { - follow_mount: false - }); - if (!FS.isMountpoint(lookup.node)) { - throw new FS.ErrnoError(28) - } - var node = lookup.node; - var mount = node.mounted; - var mounts = FS.getMounts(mount); - Object.keys(FS.nameTable).forEach(function(hash) { - var current = FS.nameTable[hash]; - while (current) { - var next = current.name_next; - if (mounts.indexOf(current.mount) !== -1) { - FS.destroyNode(current) - } - current = next - } - }); - node.mounted = null; - var idx = node.mount.mounts.indexOf(mount); - node.mount.mounts.splice(idx, 1) - }, - lookup: function(parent, name) { - return parent.node_ops.lookup(parent, name) - }, - mknod: function(path, mode, dev) { - var lookup = FS.lookupPath(path, { - parent: true - }); - var parent = lookup.node; - var name = PATH.basename(path); - if (!name || name === "." || name === "..") { - throw new FS.ErrnoError(28) - } - var errCode = FS.mayCreate(parent, name); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - if (!parent.node_ops.mknod) { - throw new FS.ErrnoError(63) - } - return parent.node_ops.mknod(parent, name, mode, dev) - }, - create: function(path, mode) { - mode = mode !== undefined ? mode : 438; - mode &= 4095; - mode |= 32768; - return FS.mknod(path, mode, 0) - }, - mkdir: function(path, mode) { - mode = mode !== undefined ? mode : 511; - mode &= 511 | 512; - mode |= 16384; - return FS.mknod(path, mode, 0) - }, - mkdirTree: function(path, mode) { - var dirs = path.split("/"); - var d = ""; - for (var i = 0; i < dirs.length; ++i) { - if (!dirs[i]) continue; - d += "/" + dirs[i]; - try { - FS.mkdir(d, mode) - } catch (e) { - if (e.errno != 20) throw e - } - } - }, - mkdev: function(path, mode, dev) { - if (typeof dev === "undefined") { - dev = mode; - mode = 438 - } - mode |= 8192; - return FS.mknod(path, mode, dev) - }, - symlink: function(oldpath, newpath) { - if (!PATH_FS.resolve(oldpath)) { - throw new FS.ErrnoError(44) - } - var lookup = FS.lookupPath(newpath, { - parent: true - }); - var parent = lookup.node; - if (!parent) { - throw new FS.ErrnoError(44) - } - var newname = PATH.basename(newpath); - var errCode = FS.mayCreate(parent, newname); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - if (!parent.node_ops.symlink) { - throw new FS.ErrnoError(63) - } - return parent.node_ops.symlink(parent, newname, oldpath) - }, - rename: function(old_path, new_path) { - var old_dirname = PATH.dirname(old_path); - var new_dirname = PATH.dirname(new_path); - var old_name = PATH.basename(old_path); - var new_name = PATH.basename(new_path); - var lookup, old_dir, new_dir; - lookup = FS.lookupPath(old_path, { - parent: true - }); - old_dir = lookup.node; - lookup = FS.lookupPath(new_path, { - parent: true - }); - new_dir = lookup.node; - if (!old_dir || !new_dir) throw new FS.ErrnoError(44); - if (old_dir.mount !== new_dir.mount) { - throw new FS.ErrnoError(75) - } - var old_node = FS.lookupNode(old_dir, old_name); - var relative = PATH_FS.relative(old_path, new_dirname); - if (relative.charAt(0) !== ".") { - throw new FS.ErrnoError(28) - } - relative = PATH_FS.relative(new_path, old_dirname); - if (relative.charAt(0) !== ".") { - throw new FS.ErrnoError(55) - } - var new_node; - try { - new_node = FS.lookupNode(new_dir, new_name) - } catch (e) {} - if (old_node === new_node) { - return - } - var isdir = FS.isDir(old_node.mode); - var errCode = FS.mayDelete(old_dir, old_name, isdir); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - errCode = new_node ? FS.mayDelete(new_dir, new_name, isdir) : FS.mayCreate(new_dir, new_name); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - if (!old_dir.node_ops.rename) { - throw new FS.ErrnoError(63) - } - if (FS.isMountpoint(old_node) || new_node && FS.isMountpoint(new_node)) { - throw new FS.ErrnoError(10) - } - if (new_dir !== old_dir) { - errCode = FS.nodePermissions(old_dir, "w"); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - } - try { - if (FS.trackingDelegate.willMovePath) { - FS.trackingDelegate.willMovePath(old_path, new_path) - } - } catch (e) { - err("FS.trackingDelegate['willMovePath']('" + old_path + "', '" + new_path + "') threw an exception: " + e.message) - } - FS.hashRemoveNode(old_node); - try { - old_dir.node_ops.rename(old_node, new_dir, new_name) - } catch (e) { - throw e - } finally { - FS.hashAddNode(old_node) - } - try { - if (FS.trackingDelegate.onMovePath) FS.trackingDelegate.onMovePath(old_path, new_path) - } catch (e) { - err("FS.trackingDelegate['onMovePath']('" + old_path + "', '" + new_path + "') threw an exception: " + e.message) - } - }, - rmdir: function(path) { - var lookup = FS.lookupPath(path, { - parent: true - }); - var parent = lookup.node; - var name = PATH.basename(path); - var node = FS.lookupNode(parent, name); - var errCode = FS.mayDelete(parent, name, true); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - if (!parent.node_ops.rmdir) { - throw new FS.ErrnoError(63) - } - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10) - } - try { - if (FS.trackingDelegate.willDeletePath) { - FS.trackingDelegate.willDeletePath(path) - } - } catch (e) { - err("FS.trackingDelegate['willDeletePath']('" + path + "') threw an exception: " + e.message) - } - parent.node_ops.rmdir(parent, name); - FS.destroyNode(node); - try { - if (FS.trackingDelegate.onDeletePath) FS.trackingDelegate.onDeletePath(path) - } catch (e) { - err("FS.trackingDelegate['onDeletePath']('" + path + "') threw an exception: " + e.message) - } - }, - readdir: function(path) { - var lookup = FS.lookupPath(path, { - follow: true - }); - var node = lookup.node; - if (!node.node_ops.readdir) { - throw new FS.ErrnoError(54) - } - return node.node_ops.readdir(node) - }, - unlink: function(path) { - var lookup = FS.lookupPath(path, { - parent: true - }); - var parent = lookup.node; - var name = PATH.basename(path); - var node = FS.lookupNode(parent, name); - var errCode = FS.mayDelete(parent, name, false); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - if (!parent.node_ops.unlink) { - throw new FS.ErrnoError(63) - } - if (FS.isMountpoint(node)) { - throw new FS.ErrnoError(10) - } - try { - if (FS.trackingDelegate.willDeletePath) { - FS.trackingDelegate.willDeletePath(path) - } - } catch (e) { - err("FS.trackingDelegate['willDeletePath']('" + path + "') threw an exception: " + e.message) - } - parent.node_ops.unlink(parent, name); - FS.destroyNode(node); - try { - if (FS.trackingDelegate.onDeletePath) FS.trackingDelegate.onDeletePath(path) - } catch (e) { - err("FS.trackingDelegate['onDeletePath']('" + path + "') threw an exception: " + e.message) - } - }, - readlink: function(path) { - var lookup = FS.lookupPath(path); - var link = lookup.node; - if (!link) { - throw new FS.ErrnoError(44) - } - if (!link.node_ops.readlink) { - throw new FS.ErrnoError(28) - } - return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link)) - }, - stat: function(path, dontFollow) { - var lookup = FS.lookupPath(path, { - follow: !dontFollow - }); - var node = lookup.node; - if (!node) { - throw new FS.ErrnoError(44) - } - if (!node.node_ops.getattr) { - throw new FS.ErrnoError(63) - } - return node.node_ops.getattr(node) - }, - lstat: function(path) { - return FS.stat(path, true) - }, - chmod: function(path, mode, dontFollow) { - var node; - if (typeof path === "string") { - var lookup = FS.lookupPath(path, { - follow: !dontFollow - }); - node = lookup.node - } else { - node = path - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63) - } - node.node_ops.setattr(node, { - mode: mode & 4095 | node.mode & ~4095, - timestamp: Date.now() - }) - }, - lchmod: function(path, mode) { - FS.chmod(path, mode, true) - }, - fchmod: function(fd, mode) { - var stream = FS.getStream(fd); - if (!stream) { - throw new FS.ErrnoError(8) - } - FS.chmod(stream.node, mode) - }, - chown: function(path, uid, gid, dontFollow) { - var node; - if (typeof path === "string") { - var lookup = FS.lookupPath(path, { - follow: !dontFollow - }); - node = lookup.node - } else { - node = path - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63) - } - node.node_ops.setattr(node, { - timestamp: Date.now() - }) - }, - lchown: function(path, uid, gid) { - FS.chown(path, uid, gid, true) - }, - fchown: function(fd, uid, gid) { - var stream = FS.getStream(fd); - if (!stream) { - throw new FS.ErrnoError(8) - } - FS.chown(stream.node, uid, gid) - }, - truncate: function(path, len) { - if (len < 0) { - throw new FS.ErrnoError(28) - } - var node; - if (typeof path === "string") { - var lookup = FS.lookupPath(path, { - follow: true - }); - node = lookup.node - } else { - node = path - } - if (!node.node_ops.setattr) { - throw new FS.ErrnoError(63) - } - if (FS.isDir(node.mode)) { - throw new FS.ErrnoError(31) - } - if (!FS.isFile(node.mode)) { - throw new FS.ErrnoError(28) - } - var errCode = FS.nodePermissions(node, "w"); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - node.node_ops.setattr(node, { - size: len, - timestamp: Date.now() - }) - }, - ftruncate: function(fd, len) { - var stream = FS.getStream(fd); - if (!stream) { - throw new FS.ErrnoError(8) - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(28) - } - FS.truncate(stream.node, len) - }, - utime: function(path, atime, mtime) { - var lookup = FS.lookupPath(path, { - follow: true - }); - var node = lookup.node; - node.node_ops.setattr(node, { - timestamp: Math.max(atime, mtime) - }) - }, - open: function(path, flags, mode, fd_start, fd_end) { - if (path === "") { - throw new FS.ErrnoError(44) - } - flags = typeof flags === "string" ? FS.modeStringToFlags(flags) : flags; - mode = typeof mode === "undefined" ? 438 : mode; - if (flags & 64) { - mode = mode & 4095 | 32768 - } else { - mode = 0 - } - var node; - if (typeof path === "object") { - node = path - } else { - path = PATH.normalize(path); - try { - var lookup = FS.lookupPath(path, { - follow: !(flags & 131072) - }); - node = lookup.node - } catch (e) {} - } - var created = false; - if (flags & 64) { - if (node) { - if (flags & 128) { - throw new FS.ErrnoError(20) - } - } else { - node = FS.mknod(path, mode, 0); - created = true - } - } - if (!node) { - throw new FS.ErrnoError(44) - } - if (FS.isChrdev(node.mode)) { - flags &= ~512 - } - if (flags & 65536 && !FS.isDir(node.mode)) { - throw new FS.ErrnoError(54) - } - if (!created) { - var errCode = FS.mayOpen(node, flags); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - } - if (flags & 512) { - FS.truncate(node, 0) - } - flags &= ~(128 | 512 | 131072); - var stream = FS.createStream({ - node: node, - path: FS.getPath(node), - flags: flags, - seekable: true, - position: 0, - stream_ops: node.stream_ops, - ungotten: [], - error: false - }, fd_start, fd_end); - if (stream.stream_ops.open) { - stream.stream_ops.open(stream) - } - if (Module.logReadFiles && !(flags & 1)) { - if (!FS.readFiles) FS.readFiles = {}; - if (!(path in FS.readFiles)) { - FS.readFiles[path] = 1; - err("FS.trackingDelegate error on read file: " + path) - } - } - try { - if (FS.trackingDelegate.onOpenFile) { - var trackingFlags = 0; - if ((flags & 2097155) !== 1) { - trackingFlags |= FS.tracking.openFlags.READ - } - if ((flags & 2097155) !== 0) { - trackingFlags |= FS.tracking.openFlags.WRITE - } - FS.trackingDelegate.onOpenFile(path, trackingFlags) - } - } catch (e) { - err("FS.trackingDelegate['onOpenFile']('" + path + "', flags) threw an exception: " + e.message) - } - return stream - }, - close: function(stream) { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8) - } - if (stream.getdents) stream.getdents = null; - try { - if (stream.stream_ops.close) { - stream.stream_ops.close(stream) - } - } catch (e) { - throw e - } finally { - FS.closeStream(stream.fd) - } - stream.fd = null - }, - isClosed: function(stream) { - return stream.fd === null - }, - llseek: function(stream, offset, whence) { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8) - } - if (!stream.seekable || !stream.stream_ops.llseek) { - throw new FS.ErrnoError(70) - } - if (whence != 0 && whence != 1 && whence != 2) { - throw new FS.ErrnoError(28) - } - stream.position = stream.stream_ops.llseek(stream, offset, whence); - stream.ungotten = []; - return stream.position - }, - read: function(stream, buffer, offset, length, position) { - if (length < 0 || position < 0) { - throw new FS.ErrnoError(28) - } - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8) - } - if ((stream.flags & 2097155) === 1) { - throw new FS.ErrnoError(8) - } - if (FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(31) - } - if (!stream.stream_ops.read) { - throw new FS.ErrnoError(28) - } - var seeking = typeof position !== "undefined"; - if (!seeking) { - position = stream.position - } else if (!stream.seekable) { - throw new FS.ErrnoError(70) - } - var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position); - if (!seeking) stream.position += bytesRead; - return bytesRead - }, - write: function(stream, buffer, offset, length, position, canOwn) { - if (length < 0 || position < 0) { - throw new FS.ErrnoError(28) - } - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8) - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(8) - } - if (FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(31) - } - if (!stream.stream_ops.write) { - throw new FS.ErrnoError(28) - } - if (stream.seekable && stream.flags & 1024) { - FS.llseek(stream, 0, 2) - } - var seeking = typeof position !== "undefined"; - if (!seeking) { - position = stream.position - } else if (!stream.seekable) { - throw new FS.ErrnoError(70) - } - var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn); - if (!seeking) stream.position += bytesWritten; - try { - if (stream.path && FS.trackingDelegate.onWriteToFile) FS.trackingDelegate.onWriteToFile(stream.path) - } catch (e) { - err("FS.trackingDelegate['onWriteToFile']('" + stream.path + "') threw an exception: " + e.message) - } - return bytesWritten - }, - allocate: function(stream, offset, length) { - if (FS.isClosed(stream)) { - throw new FS.ErrnoError(8) - } - if (offset < 0 || length <= 0) { - throw new FS.ErrnoError(28) - } - if ((stream.flags & 2097155) === 0) { - throw new FS.ErrnoError(8) - } - if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) { - throw new FS.ErrnoError(43) - } - if (!stream.stream_ops.allocate) { - throw new FS.ErrnoError(138) - } - stream.stream_ops.allocate(stream, offset, length) - }, - mmap: function(stream, address, length, position, prot, flags) { - if ((prot & 2) !== 0 && (flags & 2) === 0 && (stream.flags & 2097155) !== 2) { - throw new FS.ErrnoError(2) - } - if ((stream.flags & 2097155) === 1) { - throw new FS.ErrnoError(2) - } - if (!stream.stream_ops.mmap) { - throw new FS.ErrnoError(43) - } - return stream.stream_ops.mmap(stream, address, length, position, prot, flags) - }, - msync: function(stream, buffer, offset, length, mmapFlags) { - if (!stream || !stream.stream_ops.msync) { - return 0 - } - return stream.stream_ops.msync(stream, buffer, offset, length, mmapFlags) - }, - munmap: function(stream) { - return 0 - }, - ioctl: function(stream, cmd, arg) { - if (!stream.stream_ops.ioctl) { - throw new FS.ErrnoError(59) - } - return stream.stream_ops.ioctl(stream, cmd, arg) - }, - readFile: function(path, opts) { - opts = opts || {}; - opts.flags = opts.flags || "r"; - opts.encoding = opts.encoding || "binary"; - if (opts.encoding !== "utf8" && opts.encoding !== "binary") { - throw new Error('Invalid encoding type "' + opts.encoding + '"') - } - var ret; - var stream = FS.open(path, opts.flags); - var stat = FS.stat(path); - var length = stat.size; - var buf = new Uint8Array(length); - FS.read(stream, buf, 0, length, 0); - if (opts.encoding === "utf8") { - ret = UTF8ArrayToString(buf, 0) - } else if (opts.encoding === "binary") { - ret = buf - } - FS.close(stream); - return ret - }, - writeFile: function(path, data, opts) { - opts = opts || {}; - opts.flags = opts.flags || "w"; - var stream = FS.open(path, opts.flags, opts.mode); - if (typeof data === "string") { - var buf = new Uint8Array(lengthBytesUTF8(data) + 1); - var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length); - FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn) - } else if (ArrayBuffer.isView(data)) { - FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn) - } else { - throw new Error("Unsupported data type") - } - FS.close(stream) - }, - cwd: function() { - return FS.currentPath - }, - chdir: function(path) { - var lookup = FS.lookupPath(path, { - follow: true - }); - if (lookup.node === null) { - throw new FS.ErrnoError(44) - } - if (!FS.isDir(lookup.node.mode)) { - throw new FS.ErrnoError(54) - } - var errCode = FS.nodePermissions(lookup.node, "x"); - if (errCode) { - throw new FS.ErrnoError(errCode) - } - FS.currentPath = lookup.path - }, - createDefaultDirectories: function() { - FS.mkdir("/tmp"); - FS.mkdir("/home"); - FS.mkdir("/home/web_user") - }, - createDefaultDevices: function() { - FS.mkdir("/dev"); - FS.registerDevice(FS.makedev(1, 3), { - read: function() { - return 0 - }, - write: function(stream, buffer, offset, length, pos) { - return length - } - }); - FS.mkdev("/dev/null", FS.makedev(1, 3)); - TTY.register(FS.makedev(5, 0), TTY.default_tty_ops); - TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops); - FS.mkdev("/dev/tty", FS.makedev(5, 0)); - FS.mkdev("/dev/tty1", FS.makedev(6, 0)); - var random_device = getRandomDevice(); - FS.createDevice("/dev", "random", random_device); - FS.createDevice("/dev", "urandom", random_device); - FS.mkdir("/dev/shm"); - FS.mkdir("/dev/shm/tmp") - }, - createSpecialDirectories: function() { - FS.mkdir("/proc"); - FS.mkdir("/proc/self"); - FS.mkdir("/proc/self/fd"); - FS.mount({ - mount: function() { - var node = FS.createNode("/proc/self", "fd", 16384 | 511, 73); - node.node_ops = { - lookup: function(parent, name) { - var fd = +name; - var stream = FS.getStream(fd); - if (!stream) throw new FS.ErrnoError(8); - var ret = { - parent: null, - mount: { - mountpoint: "fake" - }, - node_ops: { - readlink: function() { - return stream.path - } - } - }; - ret.parent = ret; - return ret - } - }; - return node - } - }, {}, "/proc/self/fd") - }, - createStandardStreams: function() { - if (Module.stdin) { - FS.createDevice("/dev", "stdin", Module.stdin) - } else { - FS.symlink("/dev/tty", "/dev/stdin") - } - if (Module.stdout) { - FS.createDevice("/dev", "stdout", null, Module.stdout) - } else { - FS.symlink("/dev/tty", "/dev/stdout") - } - if (Module.stderr) { - FS.createDevice("/dev", "stderr", null, Module.stderr) - } else { - FS.symlink("/dev/tty1", "/dev/stderr") - } - var stdin = FS.open("/dev/stdin", "r"); - var stdout = FS.open("/dev/stdout", "w"); - var stderr = FS.open("/dev/stderr", "w") - }, - ensureErrnoError: function() { - if (FS.ErrnoError) return; - FS.ErrnoError = function ErrnoError(errno, node) { - this.node = node; - this.setErrno = function(errno) { - this.errno = errno - }; - this.setErrno(errno); - this.message = "FS error" - }; - FS.ErrnoError.prototype = new Error; - FS.ErrnoError.prototype.constructor = FS.ErrnoError; - [44].forEach(function(code) { - FS.genericErrors[code] = new FS.ErrnoError(code); - FS.genericErrors[code].stack = "" - }) - }, - staticInit: function() { - FS.ensureErrnoError(); - FS.nameTable = new Array(4096); - FS.mount(MEMFS, {}, "/"); - FS.createDefaultDirectories(); - FS.createDefaultDevices(); - FS.createSpecialDirectories(); - FS.filesystems = { - "MEMFS": MEMFS - } - }, - init: function(input, output, error) { - FS.init.initialized = true; - FS.ensureErrnoError(); - Module.stdin = input || Module.stdin; - Module.stdout = output || Module.stdout; - Module.stderr = error || Module.stderr; - FS.createStandardStreams() - }, - quit: function() { - FS.init.initialized = false; - var fflush = Module._fflush; - if (fflush) fflush(0); - for (var i = 0; i < FS.streams.length; i++) { - var stream = FS.streams[i]; - if (!stream) { - continue - } - FS.close(stream) - } - }, - getMode: function(canRead, canWrite) { - var mode = 0; - if (canRead) mode |= 292 | 73; - if (canWrite) mode |= 146; - return mode - }, - findObject: function(path, dontResolveLastLink) { - var ret = FS.analyzePath(path, dontResolveLastLink); - if (ret.exists) { - return ret.object - } else { - setErrNo(ret.error); - return null - } - }, - analyzePath: function(path, dontResolveLastLink) { - try { - var lookup = FS.lookupPath(path, { - follow: !dontResolveLastLink - }); - path = lookup.path - } catch (e) {} - var ret = { - isRoot: false, - exists: false, - error: 0, - name: null, - path: null, - object: null, - parentExists: false, - parentPath: null, - parentObject: null - }; - try { - var lookup = FS.lookupPath(path, { - parent: true - }); - ret.parentExists = true; - ret.parentPath = lookup.path; - ret.parentObject = lookup.node; - ret.name = PATH.basename(path); - lookup = FS.lookupPath(path, { - follow: !dontResolveLastLink - }); - ret.exists = true; - ret.path = lookup.path; - ret.object = lookup.node; - ret.name = lookup.node.name; - ret.isRoot = lookup.path === "/" - } catch (e) { - ret.error = e.errno - } - return ret - }, - createPath: function(parent, path, canRead, canWrite) { - parent = typeof parent === "string" ? parent : FS.getPath(parent); - var parts = path.split("/").reverse(); - while (parts.length) { - var part = parts.pop(); - if (!part) continue; - var current = PATH.join2(parent, part); - try { - FS.mkdir(current) - } catch (e) {} - parent = current - } - return current - }, - createFile: function(parent, name, properties, canRead, canWrite) { - var path = PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name); - var mode = FS.getMode(canRead, canWrite); - return FS.create(path, mode) - }, - createDataFile: function(parent, name, data, canRead, canWrite, canOwn) { - var path = name ? PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name) : parent; - var mode = FS.getMode(canRead, canWrite); - var node = FS.create(path, mode); - if (data) { - if (typeof data === "string") { - var arr = new Array(data.length); - for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i); - data = arr - } - FS.chmod(node, mode | 146); - var stream = FS.open(node, "w"); - FS.write(stream, data, 0, data.length, 0, canOwn); - FS.close(stream); - FS.chmod(node, mode) - } - return node - }, - createDevice: function(parent, name, input, output) { - var path = PATH.join2(typeof parent === "string" ? parent : FS.getPath(parent), name); - var mode = FS.getMode(!!input, !!output); - if (!FS.createDevice.major) FS.createDevice.major = 64; - var dev = FS.makedev(FS.createDevice.major++, 0); - FS.registerDevice(dev, { - open: function(stream) { - stream.seekable = false - }, - close: function(stream) { - if (output && output.buffer && output.buffer.length) { - output(10) - } - }, - read: function(stream, buffer, offset, length, pos) { - var bytesRead = 0; - for (var i = 0; i < length; i++) { - var result; - try { - result = input() - } catch (e) { - throw new FS.ErrnoError(29) - } - if (result === undefined && bytesRead === 0) { - throw new FS.ErrnoError(6) - } - if (result === null || result === undefined) break; - bytesRead++; - buffer[offset + i] = result - } - if (bytesRead) { - stream.node.timestamp = Date.now() - } - return bytesRead - }, - write: function(stream, buffer, offset, length, pos) { - for (var i = 0; i < length; i++) { - try { - output(buffer[offset + i]) - } catch (e) { - throw new FS.ErrnoError(29) - } - } - if (length) { - stream.node.timestamp = Date.now() - } - return i - } - }); - return FS.mkdev(path, mode, dev) - }, - forceLoadFile: function(obj) { - if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true; - var success = true; - if (typeof XMLHttpRequest !== "undefined") { - throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.") - } else if (read_) { - try { - obj.contents = intArrayFromString(read_(obj.url), true); - obj.usedBytes = obj.contents.length - } catch (e) { - success = false - } - } else { - throw new Error("Cannot load without read() or XMLHttpRequest.") - } - if (!success) setErrNo(29); - return success - }, - createLazyFile: function(parent, name, url, canRead, canWrite) { - function LazyUint8Array() { - this.lengthKnown = false; - this.chunks = [] - } - LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) { - if (idx > this.length - 1 || idx < 0) { - return undefined - } - var chunkOffset = idx % this.chunkSize; - var chunkNum = idx / this.chunkSize | 0; - return this.getter(chunkNum)[chunkOffset] - }; - LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) { - this.getter = getter - }; - LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() { - var xhr = new XMLHttpRequest; - xhr.open("HEAD", url, false); - xhr.send(null); - if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); - var datalength = Number(xhr.getResponseHeader("Content-length")); - var header; - var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; - var usesGzip = (header = xhr.getResponseHeader("Content-Encoding")) && header === "gzip"; - var chunkSize = 1024 * 1024; - if (!hasByteServing) chunkSize = datalength; - var doXHR = function(from, to) { - if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!"); - if (to > datalength - 1) throw new Error("only " + datalength + " bytes available! programmer error!"); - var xhr = new XMLHttpRequest; - xhr.open("GET", url, false); - if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); - if (typeof Uint8Array !== "undefined") xhr.responseType = "arraybuffer"; - if (xhr.overrideMimeType) { - xhr.overrideMimeType("text/plain; charset=x-user-defined") - } - xhr.send(null); - if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); - if (xhr.response !== undefined) { - return new Uint8Array(xhr.response || []) - } else { - return intArrayFromString(xhr.responseText || "", true) - } - }; - var lazyArray = this; - lazyArray.setDataGetter(function(chunkNum) { - var start = chunkNum * chunkSize; - var end = (chunkNum + 1) * chunkSize - 1; - end = Math.min(end, datalength - 1); - if (typeof lazyArray.chunks[chunkNum] === "undefined") { - lazyArray.chunks[chunkNum] = doXHR(start, end) - } - if (typeof lazyArray.chunks[chunkNum] === "undefined") throw new Error("doXHR failed!"); - return lazyArray.chunks[chunkNum] - }); - if (usesGzip || !datalength) { - chunkSize = datalength = 1; - datalength = this.getter(0).length; - chunkSize = datalength; - out("LazyFiles on gzip forces download of the whole file when length is accessed") - } - this._length = datalength; - this._chunkSize = chunkSize; - this.lengthKnown = true - }; - if (typeof XMLHttpRequest !== "undefined") { - if (!ENVIRONMENT_IS_WORKER) throw "Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc"; - var lazyArray = new LazyUint8Array; - Object.defineProperties(lazyArray, { - length: { - get: function() { - if (!this.lengthKnown) { - this.cacheLength() - } - return this._length - } - }, - chunkSize: { - get: function() { - if (!this.lengthKnown) { - this.cacheLength() - } - return this._chunkSize - } - } - }); - var properties = { - isDevice: false, - contents: lazyArray - } - } else { - var properties = { - isDevice: false, - url: url - } - } - var node = FS.createFile(parent, name, properties, canRead, canWrite); - if (properties.contents) { - node.contents = properties.contents - } else if (properties.url) { - node.contents = null; - node.url = properties.url - } - Object.defineProperties(node, { - usedBytes: { - get: function() { - return this.contents.length - } - } - }); - var stream_ops = {}; - var keys = Object.keys(node.stream_ops); - keys.forEach(function(key) { - var fn = node.stream_ops[key]; - stream_ops[key] = function forceLoadLazyFile() { - if (!FS.forceLoadFile(node)) { - throw new FS.ErrnoError(29) - } - return fn.apply(null, arguments) - } - }); - stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) { - if (!FS.forceLoadFile(node)) { - throw new FS.ErrnoError(29) - } - var contents = stream.node.contents; - if (position >= contents.length) return 0; - var size = Math.min(contents.length - position, length); - if (contents.slice) { - for (var i = 0; i < size; i++) { - buffer[offset + i] = contents[position + i] - } - } else { - for (var i = 0; i < size; i++) { - buffer[offset + i] = contents.get(position + i) - } - } - return size - }; - node.stream_ops = stream_ops; - return node - }, - createPreloadedFile: function(parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn, preFinish) { - Browser.init(); - var fullname = name ? PATH_FS.resolve(PATH.join2(parent, name)) : parent; - var dep = getUniqueRunDependency("cp " + fullname); - - function processData(byteArray) { - function finish(byteArray) { - if (preFinish) preFinish(); - if (!dontCreateFile) { - FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn) - } - if (onload) onload(); - removeRunDependency(dep) - } - var handled = false; - Module.preloadPlugins.forEach(function(plugin) { - if (handled) return; - if (plugin.canHandle(fullname)) { - plugin.handle(byteArray, fullname, finish, function() { - if (onerror) onerror(); - removeRunDependency(dep) - }); - handled = true - } - }); - if (!handled) finish(byteArray) - } - addRunDependency(dep); - if (typeof url === "string") { - Browser.asyncLoad(url, function(byteArray) { - processData(byteArray) - }, onerror) - } else { - processData(url) - } - }, - indexedDB: function() { - return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB - }, - DB_NAME: function() { - return "EM_FS_" + window.location.pathname - }, - DB_VERSION: 20, - DB_STORE_NAME: "FILE_DATA", - saveFilesToDB: function(paths, onload, onerror) { - onload = onload || function() {}; - onerror = onerror || function() {}; - var indexedDB = FS.indexedDB(); - try { - var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION) - } catch (e) { - return onerror(e) - } - openRequest.onupgradeneeded = function openRequest_onupgradeneeded() { - out("creating db"); - var db = openRequest.result; - db.createObjectStore(FS.DB_STORE_NAME) - }; - openRequest.onsuccess = function openRequest_onsuccess() { - var db = openRequest.result; - var transaction = db.transaction([FS.DB_STORE_NAME], "readwrite"); - var files = transaction.objectStore(FS.DB_STORE_NAME); - var ok = 0; - var fail = 0; - var total = paths.length; - - function finish() { - if (fail == 0) onload(); - else onerror() - } - paths.forEach(function(path) { - var putRequest = files.put(FS.analyzePath(path).object.contents, path); - putRequest.onsuccess = function putRequest_onsuccess() { - ok++; - if (ok + fail == total) finish() - }; - putRequest.onerror = function putRequest_onerror() { - fail++; - if (ok + fail == total) finish() - } - }); - transaction.onerror = onerror - }; - openRequest.onerror = onerror - }, - loadFilesFromDB: function(paths, onload, onerror) { - onload = onload || function() {}; - onerror = onerror || function() {}; - var indexedDB = FS.indexedDB(); - try { - var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION) - } catch (e) { - return onerror(e) - } - openRequest.onupgradeneeded = onerror; - openRequest.onsuccess = function openRequest_onsuccess() { - var db = openRequest.result; - try { - var transaction = db.transaction([FS.DB_STORE_NAME], "readonly") - } catch (e) { - onerror(e); - return - } - var files = transaction.objectStore(FS.DB_STORE_NAME); - var ok = 0; - var fail = 0; - var total = paths.length; - - function finish() { - if (fail == 0) onload(); - else onerror() - } - paths.forEach(function(path) { - var getRequest = files.get(path); - getRequest.onsuccess = function getRequest_onsuccess() { - if (FS.analyzePath(path).exists) { - FS.unlink(path) - } - FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true); - ok++; - if (ok + fail == total) finish() - }; - getRequest.onerror = function getRequest_onerror() { - fail++; - if (ok + fail == total) finish() - } - }); - transaction.onerror = onerror - }; - openRequest.onerror = onerror - } -}; -var SYSCALLS = { - mappings: {}, - DEFAULT_POLLMASK: 5, - umask: 511, - calculateAt: function(dirfd, path) { - if (path[0] !== "/") { - var dir; - if (dirfd === -100) { - dir = FS.cwd() - } else { - var dirstream = FS.getStream(dirfd); - if (!dirstream) throw new FS.ErrnoError(8); - dir = dirstream.path - } - path = PATH.join2(dir, path) - } - return path - }, - doStat: function(func, path, buf) { - try { - var stat = func(path) - } catch (e) { - if (e && e.node && PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))) { - return -54 - } - throw e - } - HEAP32[buf >> 2] = stat.dev; - HEAP32[buf + 4 >> 2] = 0; - HEAP32[buf + 8 >> 2] = stat.ino; - HEAP32[buf + 12 >> 2] = stat.mode; - HEAP32[buf + 16 >> 2] = stat.nlink; - HEAP32[buf + 20 >> 2] = stat.uid; - HEAP32[buf + 24 >> 2] = stat.gid; - HEAP32[buf + 28 >> 2] = stat.rdev; - HEAP32[buf + 32 >> 2] = 0; - tempI64 = [stat.size >>> 0, (tempDouble = stat.size, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0)], HEAP32[buf + 40 >> 2] = tempI64[0], HEAP32[buf + 44 >> 2] = tempI64[1]; - HEAP32[buf + 48 >> 2] = 4096; - HEAP32[buf + 52 >> 2] = stat.blocks; - HEAP32[buf + 56 >> 2] = stat.atime.getTime() / 1e3 | 0; - HEAP32[buf + 60 >> 2] = 0; - HEAP32[buf + 64 >> 2] = stat.mtime.getTime() / 1e3 | 0; - HEAP32[buf + 68 >> 2] = 0; - HEAP32[buf + 72 >> 2] = stat.ctime.getTime() / 1e3 | 0; - HEAP32[buf + 76 >> 2] = 0; - tempI64 = [stat.ino >>> 0, (tempDouble = stat.ino, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0)], HEAP32[buf + 80 >> 2] = tempI64[0], HEAP32[buf + 84 >> 2] = tempI64[1]; - return 0 - }, - doMsync: function(addr, stream, len, flags, offset) { - var buffer = HEAPU8.slice(addr, addr + len); - FS.msync(stream, buffer, offset, len, flags) - }, - doMkdir: function(path, mode) { - path = PATH.normalize(path); - if (path[path.length - 1] === "/") path = path.substr(0, path.length - 1); - FS.mkdir(path, mode, 0); - return 0 - }, - doMknod: function(path, mode, dev) { - switch (mode & 61440) { - case 32768: - case 8192: - case 24576: - case 4096: - case 49152: - break; - default: - return -28 - } - FS.mknod(path, mode, dev); - return 0 - }, - doReadlink: function(path, buf, bufsize) { - if (bufsize <= 0) return -28; - var ret = FS.readlink(path); - var len = Math.min(bufsize, lengthBytesUTF8(ret)); - var endChar = HEAP8[buf + len]; - stringToUTF8(ret, buf, bufsize + 1); - HEAP8[buf + len] = endChar; - return len - }, - doAccess: function(path, amode) { - if (amode & ~7) { - return -28 - } - var node; - var lookup = FS.lookupPath(path, { - follow: true - }); - node = lookup.node; - if (!node) { - return -44 - } - var perms = ""; - if (amode & 4) perms += "r"; - if (amode & 2) perms += "w"; - if (amode & 1) perms += "x"; - if (perms && FS.nodePermissions(node, perms)) { - return -2 - } - return 0 - }, - doDup: function(path, flags, suggestFD) { - var suggest = FS.getStream(suggestFD); - if (suggest) FS.close(suggest); - return FS.open(path, flags, 0, suggestFD, suggestFD).fd - }, - doReadv: function(stream, iov, iovcnt, offset) { - var ret = 0; - for (var i = 0; i < iovcnt; i++) { - var ptr = HEAP32[iov + i * 8 >> 2]; - var len = HEAP32[iov + (i * 8 + 4) >> 2]; - var curr = FS.read(stream, HEAP8, ptr, len, offset); - if (curr < 0) return -1; - ret += curr; - if (curr < len) break - } - return ret - }, - doWritev: function(stream, iov, iovcnt, offset) { - var ret = 0; - for (var i = 0; i < iovcnt; i++) { - var ptr = HEAP32[iov + i * 8 >> 2]; - var len = HEAP32[iov + (i * 8 + 4) >> 2]; - var curr = FS.write(stream, HEAP8, ptr, len, offset); - if (curr < 0) return -1; - ret += curr - } - return ret - }, - varargs: undefined, - get: function() { - SYSCALLS.varargs += 4; - var ret = HEAP32[SYSCALLS.varargs - 4 >> 2]; - return ret - }, - getStr: function(ptr) { - var ret = UTF8ToString(ptr); - return ret - }, - getStreamFromFD: function(fd) { - var stream = FS.getStream(fd); - if (!stream) throw new FS.ErrnoError(8); - return stream - }, - get64: function(low, high) { - return low - } -}; - -function _fd_close(fd) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - FS.close(stream); - return 0 - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e); - return e.errno - } -} - -function _fd_read(fd, iov, iovcnt, pnum) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - var num = SYSCALLS.doReadv(stream, iov, iovcnt); - HEAP32[pnum >> 2] = num; - return 0 - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e); - return e.errno - } -} - -function _fd_seek(fd, offset_low, offset_high, whence, newOffset) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - var HIGH_OFFSET = 4294967296; - var offset = offset_high * HIGH_OFFSET + (offset_low >>> 0); - var DOUBLE_LIMIT = 9007199254740992; - if (offset <= -DOUBLE_LIMIT || offset >= DOUBLE_LIMIT) { - return -61 - } - FS.llseek(stream, offset, whence); - tempI64 = [stream.position >>> 0, (tempDouble = stream.position, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0)], HEAP32[newOffset >> 2] = tempI64[0], HEAP32[newOffset + 4 >> 2] = tempI64[1]; - if (stream.getdents && offset === 0 && whence === 0) stream.getdents = null; - return 0 - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e); - return e.errno - } -} - -function _fd_write(fd, iov, iovcnt, pnum) { - try { - var stream = SYSCALLS.getStreamFromFD(fd); - var num = SYSCALLS.doWritev(stream, iov, iovcnt); - HEAP32[pnum >> 2] = num; - return 0 - } catch (e) { - if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError)) abort(e); - return e.errno - } -} - -function __isLeapYear(year) { - return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) -} - -function __arraySum(array, index) { - var sum = 0; - for (var i = 0; i <= index; sum += array[i++]) {} - return sum -} -var __MONTH_DAYS_LEAP = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; -var __MONTH_DAYS_REGULAR = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; - -function __addDays(date, days) { - var newDate = new Date(date.getTime()); - while (days > 0) { - var leap = __isLeapYear(newDate.getFullYear()); - var currentMonth = newDate.getMonth(); - var daysInCurrentMonth = (leap ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR)[currentMonth]; - if (days > daysInCurrentMonth - newDate.getDate()) { - days -= daysInCurrentMonth - newDate.getDate() + 1; - newDate.setDate(1); - if (currentMonth < 11) { - newDate.setMonth(currentMonth + 1) - } else { - newDate.setMonth(0); - newDate.setFullYear(newDate.getFullYear() + 1) - } - } else { - newDate.setDate(newDate.getDate() + days); - return newDate - } - } - return newDate -} - -function _strftime(s, maxsize, format, tm) { - var tm_zone = HEAP32[tm + 40 >> 2]; - var date = { - tm_sec: HEAP32[tm >> 2], - tm_min: HEAP32[tm + 4 >> 2], - tm_hour: HEAP32[tm + 8 >> 2], - tm_mday: HEAP32[tm + 12 >> 2], - tm_mon: HEAP32[tm + 16 >> 2], - tm_year: HEAP32[tm + 20 >> 2], - tm_wday: HEAP32[tm + 24 >> 2], - tm_yday: HEAP32[tm + 28 >> 2], - tm_isdst: HEAP32[tm + 32 >> 2], - tm_gmtoff: HEAP32[tm + 36 >> 2], - tm_zone: tm_zone ? UTF8ToString(tm_zone) : "" - }; - var pattern = UTF8ToString(format); - var EXPANSION_RULES_1 = { - "%c": "%a %b %d %H:%M:%S %Y", - "%D": "%m/%d/%y", - "%F": "%Y-%m-%d", - "%h": "%b", - "%r": "%I:%M:%S %p", - "%R": "%H:%M", - "%T": "%H:%M:%S", - "%x": "%m/%d/%y", - "%X": "%H:%M:%S", - "%Ec": "%c", - "%EC": "%C", - "%Ex": "%m/%d/%y", - "%EX": "%H:%M:%S", - "%Ey": "%y", - "%EY": "%Y", - "%Od": "%d", - "%Oe": "%e", - "%OH": "%H", - "%OI": "%I", - "%Om": "%m", - "%OM": "%M", - "%OS": "%S", - "%Ou": "%u", - "%OU": "%U", - "%OV": "%V", - "%Ow": "%w", - "%OW": "%W", - "%Oy": "%y" - }; - for (var rule in EXPANSION_RULES_1) { - pattern = pattern.replace(new RegExp(rule, "g"), EXPANSION_RULES_1[rule]) - } - var WEEKDAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; - var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; - - function leadingSomething(value, digits, character) { - var str = typeof value === "number" ? value.toString() : value || ""; - while (str.length < digits) { - str = character[0] + str - } - return str - } - - function leadingNulls(value, digits) { - return leadingSomething(value, digits, "0") - } - - function compareByDay(date1, date2) { - function sgn(value) { - return value < 0 ? -1 : value > 0 ? 1 : 0 - } - var compare; - if ((compare = sgn(date1.getFullYear() - date2.getFullYear())) === 0) { - if ((compare = sgn(date1.getMonth() - date2.getMonth())) === 0) { - compare = sgn(date1.getDate() - date2.getDate()) - } - } - return compare - } - - function getFirstWeekStartDate(janFourth) { - switch (janFourth.getDay()) { - case 0: - return new Date(janFourth.getFullYear() - 1, 11, 29); - case 1: - return janFourth; - case 2: - return new Date(janFourth.getFullYear(), 0, 3); - case 3: - return new Date(janFourth.getFullYear(), 0, 2); - case 4: - return new Date(janFourth.getFullYear(), 0, 1); - case 5: - return new Date(janFourth.getFullYear() - 1, 11, 31); - case 6: - return new Date(janFourth.getFullYear() - 1, 11, 30) - } - } - - function getWeekBasedYear(date) { - var thisDate = __addDays(new Date(date.tm_year + 1900, 0, 1), date.tm_yday); - var janFourthThisYear = new Date(thisDate.getFullYear(), 0, 4); - var janFourthNextYear = new Date(thisDate.getFullYear() + 1, 0, 4); - var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear); - var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear); - if (compareByDay(firstWeekStartThisYear, thisDate) <= 0) { - if (compareByDay(firstWeekStartNextYear, thisDate) <= 0) { - return thisDate.getFullYear() + 1 - } else { - return thisDate.getFullYear() - } - } else { - return thisDate.getFullYear() - 1 - } - } - var EXPANSION_RULES_2 = { - "%a": function(date) { - return WEEKDAYS[date.tm_wday].substring(0, 3) - }, - "%A": function(date) { - return WEEKDAYS[date.tm_wday] - }, - "%b": function(date) { - return MONTHS[date.tm_mon].substring(0, 3) - }, - "%B": function(date) { - return MONTHS[date.tm_mon] - }, - "%C": function(date) { - var year = date.tm_year + 1900; - return leadingNulls(year / 100 | 0, 2) - }, - "%d": function(date) { - return leadingNulls(date.tm_mday, 2) - }, - "%e": function(date) { - return leadingSomething(date.tm_mday, 2, " ") - }, - "%g": function(date) { - return getWeekBasedYear(date).toString().substring(2) - }, - "%G": function(date) { - return getWeekBasedYear(date) - }, - "%H": function(date) { - return leadingNulls(date.tm_hour, 2) - }, - "%I": function(date) { - var twelveHour = date.tm_hour; - if (twelveHour == 0) twelveHour = 12; - else if (twelveHour > 12) twelveHour -= 12; - return leadingNulls(twelveHour, 2) - }, - "%j": function(date) { - return leadingNulls(date.tm_mday + __arraySum(__isLeapYear(date.tm_year + 1900) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, date.tm_mon - 1), 3) - }, - "%m": function(date) { - return leadingNulls(date.tm_mon + 1, 2) - }, - "%M": function(date) { - return leadingNulls(date.tm_min, 2) - }, - "%n": function() { - return "\n" - }, - "%p": function(date) { - if (date.tm_hour >= 0 && date.tm_hour < 12) { - return "AM" - } else { - return "PM" - } - }, - "%S": function(date) { - return leadingNulls(date.tm_sec, 2) - }, - "%t": function() { - return "\t" - }, - "%u": function(date) { - return date.tm_wday || 7 - }, - "%U": function(date) { - var janFirst = new Date(date.tm_year + 1900, 0, 1); - var firstSunday = janFirst.getDay() === 0 ? janFirst : __addDays(janFirst, 7 - janFirst.getDay()); - var endDate = new Date(date.tm_year + 1900, date.tm_mon, date.tm_mday); - if (compareByDay(firstSunday, endDate) < 0) { - var februaryFirstUntilEndMonth = __arraySum(__isLeapYear(endDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, endDate.getMonth() - 1) - 31; - var firstSundayUntilEndJanuary = 31 - firstSunday.getDate(); - var days = firstSundayUntilEndJanuary + februaryFirstUntilEndMonth + endDate.getDate(); - return leadingNulls(Math.ceil(days / 7), 2) - } - return compareByDay(firstSunday, janFirst) === 0 ? "01" : "00" - }, - "%V": function(date) { - var janFourthThisYear = new Date(date.tm_year + 1900, 0, 4); - var janFourthNextYear = new Date(date.tm_year + 1901, 0, 4); - var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear); - var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear); - var endDate = __addDays(new Date(date.tm_year + 1900, 0, 1), date.tm_yday); - if (compareByDay(endDate, firstWeekStartThisYear) < 0) { - return "53" - } - if (compareByDay(firstWeekStartNextYear, endDate) <= 0) { - return "01" - } - var daysDifference; - if (firstWeekStartThisYear.getFullYear() < date.tm_year + 1900) { - daysDifference = date.tm_yday + 32 - firstWeekStartThisYear.getDate() - } else { - daysDifference = date.tm_yday + 1 - firstWeekStartThisYear.getDate() - } - return leadingNulls(Math.ceil(daysDifference / 7), 2) - }, - "%w": function(date) { - return date.tm_wday - }, - "%W": function(date) { - var janFirst = new Date(date.tm_year, 0, 1); - var firstMonday = janFirst.getDay() === 1 ? janFirst : __addDays(janFirst, janFirst.getDay() === 0 ? 1 : 7 - janFirst.getDay() + 1); - var endDate = new Date(date.tm_year + 1900, date.tm_mon, date.tm_mday); - if (compareByDay(firstMonday, endDate) < 0) { - var februaryFirstUntilEndMonth = __arraySum(__isLeapYear(endDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, endDate.getMonth() - 1) - 31; - var firstMondayUntilEndJanuary = 31 - firstMonday.getDate(); - var days = firstMondayUntilEndJanuary + februaryFirstUntilEndMonth + endDate.getDate(); - return leadingNulls(Math.ceil(days / 7), 2) - } - return compareByDay(firstMonday, janFirst) === 0 ? "01" : "00" - }, - "%y": function(date) { - return (date.tm_year + 1900).toString().substring(2) - }, - "%Y": function(date) { - return date.tm_year + 1900 - }, - "%z": function(date) { - var off = date.tm_gmtoff; - var ahead = off >= 0; - off = Math.abs(off) / 60; - off = off / 60 * 100 + off % 60; - return (ahead ? "+" : "-") + String("0000" + off).slice(-4) - }, - "%Z": function(date) { - return date.tm_zone - }, - "%%": function() { - return "%" - } - }; - for (var rule in EXPANSION_RULES_2) { - if (pattern.indexOf(rule) >= 0) { - pattern = pattern.replace(new RegExp(rule, "g"), EXPANSION_RULES_2[rule](date)) - } - } - var bytes = intArrayFromString(pattern, false); - if (bytes.length > maxsize) { - return 0 - } - writeArrayToMemory(bytes, s); - return bytes.length - 1 -} - -function _strftime_l(s, maxsize, format, tm) { - return _strftime(s, maxsize, format, tm) -} -var FSNode = function(parent, name, mode, rdev) { - if (!parent) { - parent = this - } - this.parent = parent; - this.mount = parent.mount; - this.mounted = null; - this.id = FS.nextInode++; - this.name = name; - this.mode = mode; - this.node_ops = {}; - this.stream_ops = {}; - this.rdev = rdev -}; -var readMode = 292 | 73; -var writeMode = 146; -Object.defineProperties(FSNode.prototype, { - read: { - get: function() { - return (this.mode & readMode) === readMode - }, - set: function(val) { - val ? this.mode |= readMode : this.mode &= ~readMode - } - }, - write: { - get: function() { - return (this.mode & writeMode) === writeMode - }, - set: function(val) { - val ? this.mode |= writeMode : this.mode &= ~writeMode - } - }, - isFolder: { - get: function() { - return FS.isDir(this.mode) - } - }, - isDevice: { - get: function() { - return FS.isChrdev(this.mode) - } - } -}); -FS.FSNode = FSNode; -FS.staticInit(); - -function intArrayFromString(stringy, dontAddNull, length) { - var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1; - var u8array = new Array(len); - var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length); - if (dontAddNull) u8array.length = numBytesWritten; - return u8array -} -__ATINIT__.push({ - func: function() { - ___wasm_call_ctors() - } -}); -var asmLibraryArg = { - "m": ___cxa_allocate_exception, - "l": ___cxa_throw, - "c": _abort, - "k": _emscripten_memcpy_big, - "d": _emscripten_resize_heap, - "f": _environ_get, - "g": _environ_sizes_get, - "i": _fd_close, - "h": _fd_read, - "j": _fd_seek, - "b": _fd_write, - "a": wasmMemory, - "e": _strftime_l -}; -var asm = createWasm(); -var ___wasm_call_ctors = Module.___wasm_call_ctors = function() { - return (___wasm_call_ctors = Module.___wasm_call_ctors = Module.asm.o).apply(null, arguments) -}; -var _Encoder_new = Module._Encoder_new = function() { - return (_Encoder_new = Module._Encoder_new = Module.asm.p).apply(null, arguments) -}; -var _Encoder_delete = Module._Encoder_delete = function() { - return (_Encoder_delete = Module._Encoder_delete = Module.asm.q).apply(null, arguments) -}; -var _Encoder_input = Module._Encoder_input = function() { - return (_Encoder_input = Module._Encoder_input = Module.asm.r).apply(null, arguments) -}; -var _Encoder_output = Module._Encoder_output = function() { - return (_Encoder_output = Module._Encoder_output = Module.asm.s).apply(null, arguments) -}; -var _Decoder_new = Module._Decoder_new = function() { - return (_Decoder_new = Module._Decoder_new = Module.asm.t).apply(null, arguments) -}; -var _Decoder_delete = Module._Decoder_delete = function() { - return (_Decoder_delete = Module._Decoder_delete = Module.asm.u).apply(null, arguments) -}; -var _Decoder_input = Module._Decoder_input = function() { - return (_Decoder_input = Module._Decoder_input = Module.asm.v).apply(null, arguments) -}; -var _Decoder_output = Module._Decoder_output = function() { - return (_Decoder_output = Module._Decoder_output = Module.asm.w).apply(null, arguments) -}; -var _String_size = Module._String_size = function() { - return (_String_size = Module._String_size = Module.asm.x).apply(null, arguments) -}; -var _String_new = Module._String_new = function() { - return (_String_new = Module._String_new = Module.asm.y).apply(null, arguments) -}; -var _String_data = Module._String_data = function() { - return (_String_data = Module._String_data = Module.asm.z).apply(null, arguments) -}; -var _String_delete = Module._String_delete = function() { - return (_String_delete = Module._String_delete = Module.asm.A).apply(null, arguments) -}; -var _Int16Array_size = Module._Int16Array_size = function() { - return (_Int16Array_size = Module._Int16Array_size = Module.asm.B).apply(null, arguments) -}; -var _Int16Array_new = Module._Int16Array_new = function() { - return (_Int16Array_new = Module._Int16Array_new = Module.asm.C).apply(null, arguments) -}; -var _Int16Array_data = Module._Int16Array_data = function() { - return (_Int16Array_data = Module._Int16Array_data = Module.asm.D).apply(null, arguments) -}; -var _Int16Array_delete = Module._Int16Array_delete = function() { - return (_Int16Array_delete = Module._Int16Array_delete = Module.asm.E).apply(null, arguments) -}; -var _malloc = Module._malloc = function() { - return (_malloc = Module._malloc = Module.asm.F).apply(null, arguments) -}; -var _free = Module._free = function() { - return (_free = Module._free = Module.asm.G).apply(null, arguments) -}; -var ___errno_location = Module.___errno_location = function() { - return (___errno_location = Module.___errno_location = Module.asm.H).apply(null, arguments) -}; -var calledRun; - -function ExitStatus(status) { - this.name = "ExitStatus"; - this.message = "Program terminated with exit(" + status + ")"; - this.status = status -} -dependenciesFulfilled = function runCaller() { - if (!calledRun) run(); - if (!calledRun) dependenciesFulfilled = runCaller -}; - -function run(args) { - args = args || arguments_; - if (runDependencies > 0) { - return - } - preRun(); - if (runDependencies > 0) return; - - function doRun() { - if (calledRun) return; - calledRun = true; - Module.calledRun = true; - if (ABORT) return; - initRuntime(); - preMain(); - if (Module.onRuntimeInitialized) Module.onRuntimeInitialized(); - postRun() - } - if (Module.setStatus) { - Module.setStatus("Running..."); - setTimeout(function() { - setTimeout(function() { - Module.setStatus("") - }, 1); - doRun() - }, 1) - } else { - doRun() - } -} -Module.run = run; -if (Module.preInit) { - if (typeof Module.preInit === "function") Module.preInit = [Module.preInit]; - while (Module.preInit.length > 0) { - Module.preInit.pop()() - } -} -noExitRuntime = true; -run(); - -function Encoder(channels, samplerate, bitrate, frame_size, voice_optimization) { - this.enc = Module._Encoder_new.apply(null, arguments); - this.out = Module._String_new() -} -Encoder.prototype.destroy = function() { - Module._Encoder_delete(this.enc); - Module._String_delete(this.out) -}; -Encoder.prototype.input = function(samples) { - var ptr = Module._malloc(samples.length * samples.BYTES_PER_ELEMENT); - var pdata = new Uint8Array(Module.HEAPU8.buffer, ptr, samples.length * samples.BYTES_PER_ELEMENT); - pdata.set(new Uint8Array(samples.buffer, samples.byteOffset, samples.length * samples.BYTES_PER_ELEMENT)); - Module._Encoder_input(this.enc, ptr, samples.length); - Module._free(ptr) -}; -Encoder.prototype.output = function() { - var ok = Module._Encoder_output(this.enc, this.out); - if (ok) { - return new Uint8Array(Module.HEAPU8.buffer, Module._String_data(this.out), Module._String_size(this.out)) - } else { - throw new Error('not ok'); - } -}; - -function Decoder(channels, samplerate) { - this.dec = Module._Decoder_new.apply(null, arguments); - this.out = Module._Int16Array_new() -} -Decoder.prototype.destroy = function() { - Module._Decoder_delete(this.dec); - Module._Int16Array_delete(this.out) -}; -Decoder.prototype.input = function(packet) { - var ptr = Module._malloc(packet.length * packet.BYTES_PER_ELEMENT); - var pdata = new Uint8Array(Module.HEAPU8.buffer, ptr, packet.length * packet.BYTES_PER_ELEMENT); - pdata.set(new Uint8Array(packet.buffer, packet.byteOffset, packet.length * packet.BYTES_PER_ELEMENT)); - Module._Decoder_input(this.dec, ptr, packet.length); - Module._free(ptr) -}; -Decoder.prototype.output = function() { - var ok = Module._Decoder_output(this.dec, this.out); - if (ok) { - return new Int16Array(Module.HEAPU8.buffer, Module._Int16Array_data(this.out), Module._Int16Array_size(this.out)) - // } else { - // throw new Error('not ok'); - } -}; -Module.Encoder = Encoder; -Module.Decoder = Decoder; -if (Module.ENVIRONMENT != "NODE") libopus = Module; -let accept; -const p = new Promise((a, r) => { - accept = a; -}); -libopus.waitForReady = () => p; -libopus.onRuntimeInitialized = () => { - accept(); -}; -export default libopus; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs/package.json b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs/package.json deleted file mode 100644 index 5bc889e56..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "libopusjs", - "type": "module" -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/README.md b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/README.md deleted file mode 100644 index 74b5e714d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/README.md +++ /dev/null @@ -1,264 +0,0 @@ -# `mpg123-decoder` - -`mpg123-decoder` is a Web Assembly MPEG Layer (I/II/III) audio decoder. - * 84.6 KiB minified bundle size - * Browser and NodeJS support - * Built in Web Worker support - * Based on [`mpg123`](https://www.mpg123.de/) - -See the [homepage](https://github.com/eshaz/wasm-audio-decoders) of this repository for more Web Assembly audio decoders like this one. - -### [Checkout the demo here](https://eshaz.github.io/wasm-audio-decoders/) - -## Installing -* Install from [NPM](https://www.npmjs.com/package/mpg123-decoder). - - Run `npm i mpg123-decoder` - - ```javascript - import { MPEGDecoder } from 'mpg123-decoder'; - - const decoder = new MPEGDecoder(); - ``` - -* Or download the [build](https://github.com/eshaz/wasm-audio-decoders/tree/master/src/mpg123-decoder/dist) and include it as a script. - ```html - - - ``` - -## Usage - -1. Create a new instance and wait for the WASM to finish compiling. Decoding can be done on the main thread synchronously, or in a webworker asynchronously. - - **Main thread synchronous decoding** - ```javascript - import { MPEGDecoder } from 'mpg123-decoder'; - - const decoder = new MPEGDecoder(); - - // wait for the WASM to be compiled - await decoder.ready; - ``` - - **Web Worker asynchronous decoding** - ```javascript - import { MPEGDecoderWebWorker } from 'mpg123-decoder'; - - const decoder = new MPEGDecoderWebWorker(); - - // wait for the WASM to be compiled - await decoder.ready; - ``` - -1. Begin decoding MPEG data. - - ```javascript - // Decode Uint8Array of MPEG data - const {channelData, samplesDecoded, sampleRate} = decoder.decode(mpegData); - - // Decode an individual MPEG frame - const {channelData, samplesDecoded, sampleRate} = decoder.decodeFrame(mpegFrame); - - // Decode an array of individual MPEG frames - const {channelData, samplesDecoded, sampleRate} = decoder.decodeFrames(mpegFrameArray); - ``` - -1. When done decoding, reset the decoder to decode a new stream, or free up the memory being used by the WASM module if you have no more audio to decode. - - ```javascript - // `reset()` clears the decoder state and allows you do decode a new stream of MPEG data. - await decoder.reset(); - - // `free()` de-allocates the memory used by the decoder. You will need to create a new instance after calling `free()` to start decoding again. - decoder.free(); - ``` - -## API - -Decoded audio is always returned in the below structure. - -```javascript -{ - channelData: [ - leftAudio, // Float32Array of PCM samples for the left channel - rightAudio // Float32Array of PCM samples for the right channel - ], - samplesDecoded: 1234, // number of PCM samples that were decoded per channel - sampleRate: 44100, // sample rate of the decoded PCM - errors: [ // array containing descriptions for any decode errors - { - message: "-1 MPG123_ERR", - frameLength: 1008, // length of the frame or data in bytes that encountered an error - frameNumber: 0, // position of error relative to total frames decoded - inputBytes: 2160, // position of error relative to total input bytes - outputSamples: 1152, // position of error relative to total output samples - } - ] -} -``` - -Each Float32Array within `channelData` can be used directly in the WebAudio API for playback. - -Decoding will proceed through any errors. Any errors encountered may result in gaps in the decoded audio. - -## `MPEGDecoder` - -Class that decodes MPEG data or frames synchronously on the main thread. - -### Options -```javascript -const decoder = new MPEGDecoder({ enableGapless: true }); -``` - -* `enableGapless` *optional, defaults to `true`* - * Set to `false` to disable gapless decoding. - * Gapless decoding reads the XING / Lame header to determine delay (start) and padding (end) samples and trims the output accordingly. - -### Getters -* `decoder.ready` *async* - * Returns a promise that is resolved when the WASM is compiled and ready to use. - -### Methods - -* `decoder.decode(mpegData)` - * `mpegData` Uint8Array of MPEG audio data. -* `decoder.decodeFrame(mpegFrame)` - * `mpegFrame` Uint8Array containing a single MPEG frame. -* `decoder.decodeFrames(mpegFrames)` - * `mpegFrames` Array of Uint8Arrays containing MPEG frames. -* `decoder.reset()` *async* - * Resets the decoder so that a new stream of MPEG data can be decoded. -* `decoder.free()` - * De-allocates the memory used by the decoder. - * After calling `free()`, the current instance is made unusable, and a new instance will need to be created to decode additional MPEG data. - -## `MPEGDecoderWebWorker` - -Class that decodes MPEG data or frames asynchronously within a WebWorker. Decoding is performed in a separate, non-blocking thread. Each new instance spawns a new worker allowing you to run multiple workers for concurrent decoding of multiple streams. - -### Options -```javascript -const decoder = new MPEGDecoderWebWorker({ enableGapless: true }); -``` - -* `enableGapless` *optional, defaults to `true`* - * Set to `false` to disable gapless decoding. - * Gapless decoding reads the XING / Lame header to determine delay (start) and padding (end) samples and trims the output accordingly. - -### Getters -* `decoder.ready` *async* - * Returns a promise that is resolved when the WASM is compiled and ready to use. - -### Methods - -* `decoder.decode(mpegData)` *async* - * `mpegData` Uint8Array of MPEG audio data. -* `decoder.decodeFrame(mpegFrame)` *async* - * `mpegFrame` Uint8Array containing a single MPEG frame. -* `decoder.decodeFrames(mpegFrames)` *async* - * `mpegFrames` Array of Uint8Arrays containing MPEG frames. -* `decoder.reset()` *async* - * Resets the decoder so that a new stream of MPEG data can be decoded. -* `decoder.free()` *async* - * De-allocates the memory used by the decoder and terminates the web worker. - * After calling `free()`, the current instance is made unusable, and a new instance will need to be created to decode additional MPEG data. - -### Properly using the Web Worker interface - -`MPEGDecoderWebWorker` uses async functions to send operations to the web worker without blocking the main thread. To fully take advantage of the concurrency provided by web workers, your code should avoid using `await` on decode operations where it will block the main thread. - -Each method call on a `MPEGDecoderWebWorker` instance will queue up an operation to the web worker. Operations will complete within the web worker thread one at a time and in the same order in which the methods were called. - - * **Good** Main thread is not blocked during each decode operation. The example `playAudio` function is called when each decode operation completes. Also, the next decode operation can begin while `playAudio` is doing work on the main thread. - ```javascript - const playAudio = ({ channelData, samplesDecoded, sampleRate }) => { - // does something to play the audio data. - } - - decoder.decodeFrame(frameData1).then(playAudio); - decoder.decodeFrame(frameData2).then(playAudio); - decoder.decodeFrame(frameData3).then(playAudio); - - // do some other operations while the audio is decoded - ``` - - * **Bad** Main thread is being blocked by `await` during each decode operation. Synchronous code is halted while decoding completes, negating the benefits of using a webworker. - ```javascript - const decoded1 = await decoder.decodeFrame(frameData1); // blocks the main thread - playAudio(decoded1); - - const decoded2 = await decoder.decodeFrame(frameData2); // blocks the main thread - playAudio(decoded2); - - const decoded3 = await decoder.decodeFrame(frameData3); // blocks the main thread - playAudio(decoded3); - ``` - -## Examples - -### Decoding multiple files using a **single** instance of `MPEGDecoderWebWorker` - -This example shows how to decode multiple files using a single `MPEGDecoderWebWorker` instance. This code iterates over an array of input files (Array of Uint8Arrays) and queues up each file to be decoded one at a time. - -First, wait for the decoder to become ready by calling `decoder.ready`. - -For each iteration, `decode()` is called, it's result is pushed to the `decodedFiles` array, and `decoder.reset()` is called to prepare the decoder for a new file. These operations are queued up to the decoder instance and will complete one after another. - -Finally, a call to `decoder.free()` is queued to clean up the memory stored by the decoder. This resolves when it and all of the other operations before it complete. - -It's important to note that there is only one `await` operations in this example. Decoding can happen asynchronously and you only need to `await` when you need to use the results of the decode operation. - -```javascript - const inputFiles = [file1, file2, file3] // Array of Uint8Array file data - - const decoder = new MPEGDecoderWebWorker(); - - const decodedFiles = []; - - const decodePromise = decoder.ready // wait for the decoder to be ready - .then(() => { - for (const file of inputFiles) { - decoder.decode(file) // queue the decode operation - .then((result) => decodedFiles.push(result)); // save the decode result after decode completes - decoder.reset(); // queue the reset operation - } - }) - .then(() => decoder.free()); // queue the free operation that will execute after the above operations - - // do sync operations here - - // await when you need to have the all of the audio data decoded - await decodePromise; -``` -### Decoding multiple files using **multiple** instances of `MPEGDecoderWebWorker` - -This example shows how to decode multiple files using multiple instances of `MPEGDecoderWebWorker`. This code iterates over an array of input files (Array of Uint8Arrays) and spawns a new `MPEGDecoderWebWorker` instance for each file and decodes the file. If you want to take full advantage of multi-core devices, this is the approach you will want to take since it will parallelize the decoding - -For each input file, a new decoder is created, and the file is decoded using the `decode()` after `decoder.ready` is resolved. The result of the `decode()` operation is returned, and a `finally()` function on the promise calls `decoder.free()` to free up the instance after the decode operations are completed. - -Finally, `Promise.all()` wraps this array of promises and resolves when all decode operations are complete. - -It's important to note that there is only one `await` operation in this example. Decoding can happen asynchronously and you only need to `await` when you need to use the results of the decode operation. - -```javascript - const inputFiles = [file1, file2, file3] // Array of Uint8Array file data - - // loops through each Uint8Array in `inputFiles` and decodes the files in separate threads - const decodePromise = Promise.all( - inputFiles.map((file) => { - const decoder = new MPEGDecoderWebWorker(); - - return decoder.ready - .then(() => decoder.decode(file)) // decode the input file - .finally(() => decoder.free()); // free the decoder after resolving the decode result - }) - ); - - // do sync operations here - - // await when you need to have the all of the audio data decoded - const decodedFiles = await decodePromise; -``` diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/index.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/index.js deleted file mode 100644 index 3b05df9d1..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import MPEGDecoder from "./src/MPEGDecoder.js"; -import MPEGDecoderWebWorker from "./src/MPEGDecoderWebWorker.js"; -import { assignNames } from "@wasm-audio-decoders/common"; - -assignNames(MPEGDecoder, "MPEGDecoder"); -assignNames(MPEGDecoderWebWorker, "MPEGDecoderWebWorker"); - -export { MPEGDecoder, MPEGDecoderWebWorker }; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/package.json b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/package.json deleted file mode 100644 index 709f0e577..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "mpg123-decoder", - "version": "1.0.0", - "description": "Web Assembly streaming MPEG Layer I/II/III decoder", - "type": "module", - "main": "./index.js", - "exports": { - "types": "./types.d.ts", - "default": "./index.js" - }, - "sideEffects": false, - "types": "types.d.ts", - "files": [ - "index.js", - "types.d.ts", - "src/EmscriptenWasm.js", - "src/MPEGDecoder.js", - "src/MPEGDecoderWebWorker.js", - "dist/mpg123-decoder.min.js", - "dist/mpg123-decoder.min.js.map" - ], - "keywords": [ - "MPEG", - "mp1", - "mp2", - "mp3", - "audio", - "decoder", - "stream", - "streams", - "mpg123", - "libmpg123", - "Web Assembly", - "Wasm", - "Web Worker" - ], - "author": { - "name": "Ethan Halsall", - "email": "ethanhalsall@pm.me" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/eshaz/wasm-audio-decoders/issues" - }, - "homepage": "https://github.com/eshaz/wasm-audio-decoders/tree/master/src/mpg123-decoder", - "repository": { - "type": "git", - "url": "git+https://github.com/eshaz/wasm-audio-decoders.git", - "directory": "src/mpg123-decoder" - }, - "funding": { - "type": "individual", - "url": "https://github.com/sponsors/eshaz" - }, - "dependencies": { - "@wasm-audio-decoders/common": "file:./packages/wasm-audio-decoders-common" - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/index.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/index.js deleted file mode 100644 index e8453deaf..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import WASMAudioDecoderCommon from "./src/WASMAudioDecoderCommon.js"; -import WASMAudioDecoderWorker from "./src/WASMAudioDecoderWorker.js"; -import { assignNames } from "./src/utilities.js"; - -export { WASMAudioDecoderCommon, WASMAudioDecoderWorker, assignNames }; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/package.json b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/package.json deleted file mode 100644 index ff17d72b8..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "@wasm-audio-decoders/common", - "version": "9.0.5", - "description": "Web Assembly Audio Decoders Common", - "module": "index.js", - "main": "index.js", - "types": "types.d.ts", - "sideEffects": false, - "files": [ - "index.js", - "types.d.ts", - "src/*" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/eshaz/wasm-audio-decoders.git" - }, - "type": "module", - "author": { - "name": "Ethan Halsall", - "email": "ethanhalsall@pm.me" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/eshaz/wasm-audio-decoders/issues" - }, - "homepage": "https://github.com/eshaz/wasm-audio-decoders/tree/master/src/common", - "dependencies": { - "@eshaz/web-worker": "1.2.2", - "simple-yenc": "^1.0.4" - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/WASMAudioDecoderCommon.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/WASMAudioDecoderCommon.js deleted file mode 100644 index be0b3d9bf..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/WASMAudioDecoderCommon.js +++ /dev/null @@ -1,231 +0,0 @@ -import { decode } from "simple-yenc"; - -export default function WASMAudioDecoderCommon() { - // setup static methods - const uint8Array = Uint8Array; - const float32Array = Float32Array; - - if (!WASMAudioDecoderCommon.modules) { - Object.defineProperties(WASMAudioDecoderCommon, { - modules: { - value: new WeakMap(), - }, - - setModule: { - value(Ref, module) { - WASMAudioDecoderCommon.modules.set(Ref, Promise.resolve(module)); - }, - }, - - getModule: { - value(Ref, wasmString) { - let module = WASMAudioDecoderCommon.modules.get(Ref); - - if (!module) { - if (!wasmString) { - wasmString = Ref.wasm; - module = WASMAudioDecoderCommon.inflateDynEncodeString( - wasmString, - ).then((data) => WebAssembly.compile(data)); - } else { - module = WebAssembly.compile(decode(wasmString)); - } - - WASMAudioDecoderCommon.modules.set(Ref, module); - } - - return module; - }, - }, - - concatFloat32: { - value(buffers, length) { - let ret = new float32Array(length), - i = 0, - offset = 0; - - while (i < buffers.length) { - ret.set(buffers[i], offset); - offset += buffers[i++].length; - } - - return ret; - }, - }, - - getDecodedAudio: { - value: (errors, channelData, samplesDecoded, sampleRate, bitDepth) => ({ - errors, - channelData, - samplesDecoded, - sampleRate, - bitDepth, - }), - }, - - getDecodedAudioMultiChannel: { - value( - errors, - input, - channelsDecoded, - samplesDecoded, - sampleRate, - bitDepth, - ) { - let channelData = [], - i, - j; - - for (i = 0; i < channelsDecoded; i++) { - const channel = []; - for (j = 0; j < input.length; ) channel.push(input[j++][i] || []); - channelData.push( - WASMAudioDecoderCommon.concatFloat32(channel, samplesDecoded), - ); - } - - return WASMAudioDecoderCommon.getDecodedAudio( - errors, - channelData, - samplesDecoded, - sampleRate, - bitDepth, - ); - }, - }, - - /* - ****************** - * Compression Code - ****************** - */ - - inflateDynEncodeString: { - value(source) { - source = decode(source); - - return new Promise((resolve) => { - // prettier-ignore - const puffString = String.raw`dynEncode0114db91da9bu‡Â*t“““t“““““t““““$#“U¤¤“U¤¤3ÂyÂĠ„‰zzss|yu„svu‡yÚ&ˆ“4<054<,5T44^T44<(6U~J(44< ~A544U~6J0444ˆ†545 444J0444‰J,4U“4ˆU“‡…Ã’“7U45“4U4Z“4U4U^/6545T4T44BUˆ~64CU~O4U54U~5 U5T4B4Z!4U~5U5U5T4U~6U4ZTU5U5T44~4O4U2ZTU5T44Z!4B6T44Uˆ~64B6U~O44Uˆ~4O4U~54U~5 44~C4~54U~5 44~5454Uˆ4B6Ub!444~UO4U~5 “U5“4U4ZTUŠ#44U$4†64<4~B6^“4<444~Uˆ~B4U~54Uˆ544~544~Uˆ5 µ“Uä#UJUè#5TT4U0ZTTUX5U5T4T4Uà#~4OU4U $~Cˆ4~54U~5 T44$6U\!TTT4UaT4<6T4<64<Z!44~4N4<U~5 4U”Z!4U±_TUŠ#44U•Uˆ6UÔ~B$544$6U\!4Uˆ6U¤#~B44Uä#~B$~64<6_TU‰#444U”~B~6~54<Y!44<_!T4Y!4<64~444~AN44<U~6J4U5 44J4U”[!U#44UŠO4U~54U~5 U54 “7U6844J44J 4UJ4UJ04VK(44<J44<J$4U´~54U~5 4U¤~5!TTT4U$5"U“5TTTTTTT4U$"4VK,U54<(6U~64<$6_!4< 64~6A54A544U~6#J(UÂ’54A4U‡[!44J(44#~A4Uˆ6U“‡UŠUÂ…[!44†64~64_!4<64~54<6T4<4]TU5 T4Y!44~44~AN4U~54U~54U5 44J(44J UÄA!U5U”#UôJU"UÔJUœ#UÔ"JU˜#U´"JT4U´ZTU5T4UôZTU5T4UDZTU5T4U$[T44~UO4U~5 UÔUô4U~U´$.U5T4UP[T4U~4~UO4U~5 U˜#<Uœ#<4U~U2$.UÄUN 44 ~UO4U~5 44!~UO4U~5 4U~4~UO4U~5 44J44J(U5 44U¤~J@44Uä~J<44UD~J844U~J44U$54U$5U‘54U$54U1^4U1^†!4U•~54U~5U”54U~6U4U^/65T4T4U$54U~4BUˆ~4O4U54U~5 UU'464U'_/54UˆU”~5T4T4U~4BUˆ~UO4U54U~5 UÂ54Uä~4U¤~4U~U'$!44~5U5T44\T44U<~$6U\!4U#aT4U~4Uˆ~4O4U~5 U5U5U5TTT4U$"4YTUÂ5 4Uˆ4~C5U5 U5U5444$4~64~\TUÂŽ5 4U~4Uˆ~5T4Y!44O4U~54U~54U5 4CYTU‹5 4Uä~4U¤~4U~4$6TUÂ54U\!44Bæ4Bä~[!4U~4UD~4U~4Uˆ~4$6TUÂŒ54U\!44B†4B„~[!44U<~4U4~$5 4U"U˜#$544"†Y!454U^!44<J44<(J454U~84­U”N!#%'+/37?GOWgw‡—·×÷Uä;U”9$%& !"#`; - - WASMAudioDecoderCommon.getModule(WASMAudioDecoderCommon, puffString) - .then((wasm) => WebAssembly.instantiate(wasm, {})) - .then(({ exports }) => { - // required for minifiers that mangle the __heap_base property - const instanceExports = new Map(Object.entries(exports)); - - const puff = instanceExports.get("puff"); - const memory = instanceExports.get("memory")["buffer"]; - const dataArray = new uint8Array(memory); - const heapView = new DataView(memory); - - let heapPos = instanceExports.get("__heap_base"); - - // source length - const sourceLength = source.length; - const sourceLengthPtr = heapPos; - heapPos += 4; - heapView.setInt32(sourceLengthPtr, sourceLength, true); - - // source data - const sourcePtr = heapPos; - heapPos += sourceLength; - dataArray.set(source, sourcePtr); - - // destination length - const destLengthPtr = heapPos; - heapPos += 4; - heapView.setInt32( - destLengthPtr, - dataArray.byteLength - heapPos, - true, - ); - - // destination data fills in the rest of the heap - puff(heapPos, destLengthPtr, sourcePtr, sourceLengthPtr); - - resolve( - dataArray.slice( - heapPos, - heapPos + heapView.getInt32(destLengthPtr, true), - ), - ); - }); - }); - }, - }, - }); - } - - Object.defineProperty(this, "wasm", { - enumerable: true, - get: () => this._wasm, - }); - - this.getOutputChannels = (outputData, channelsDecoded, samplesDecoded) => { - let output = [], - i = 0; - - while (i < channelsDecoded) - output.push( - outputData.slice( - i * samplesDecoded, - i++ * samplesDecoded + samplesDecoded, - ), - ); - - return output; - }; - - this.allocateTypedArray = (len, TypedArray, setPointer = true) => { - const ptr = this._wasm.malloc(TypedArray.BYTES_PER_ELEMENT * len); - if (setPointer) this._pointers.add(ptr); - - return { - ptr: ptr, - len: len, - buf: new TypedArray(this._wasm.HEAP, ptr, len), - }; - }; - - this.free = () => { - this._pointers.forEach((ptr) => { - this._wasm.free(ptr); - }); - this._pointers.clear(); - }; - - this.codeToString = (ptr) => { - const characters = [], - heap = new Uint8Array(this._wasm.HEAP); - for (let character = heap[ptr]; character !== 0; character = heap[++ptr]) - characters.push(character); - - return String.fromCharCode.apply(null, characters); - }; - - this.addError = ( - errors, - message, - frameLength, - frameNumber, - inputBytes, - outputSamples, - ) => { - errors.push({ - message: message, - frameLength: frameLength, - frameNumber: frameNumber, - inputBytes: inputBytes, - outputSamples: outputSamples, - }); - }; - - this.instantiate = (_EmscriptenWASM, _module) => { - if (_module) WASMAudioDecoderCommon.setModule(_EmscriptenWASM, _module); - this._wasm = new _EmscriptenWASM(WASMAudioDecoderCommon).instantiate(); - this._pointers = new Set(); - - return this._wasm.ready.then(() => this); - }; -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/WASMAudioDecoderWorker.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/WASMAudioDecoderWorker.js deleted file mode 100644 index 97ea3f066..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/WASMAudioDecoderWorker.js +++ /dev/null @@ -1,129 +0,0 @@ -import NodeWorker from "@eshaz/web-worker"; -import WASMAudioDecoderCommon from "./WASMAudioDecoderCommon.js"; - -const getWorker = () => globalThis.Worker || NodeWorker; - -export default class WASMAudioDecoderWorker extends getWorker() { - constructor(options, name, Decoder, EmscriptenWASM) { - if (!WASMAudioDecoderCommon.modules) new WASMAudioDecoderCommon(); - - let source = WASMAudioDecoderCommon.modules.get(Decoder); - - if (!source) { - let type = "text/javascript", - isNode, - webworkerSourceCode = - "'use strict';" + - // dependencies need to be manually resolved when stringifying this function - `(${((_Decoder, _WASMAudioDecoderCommon, _EmscriptenWASM) => { - // We're in a Web Worker - - // setup Promise that will be resolved once the WebAssembly Module is received - let decoder, - moduleResolve, - modulePromise = new Promise((resolve) => { - moduleResolve = resolve; - }); - - self.onmessage = ({ data: { id, command, data } }) => { - let messagePromise = modulePromise, - messagePayload = { id }, - transferList; - - if (command === "init") { - Object.defineProperties(_Decoder, { - WASMAudioDecoderCommon: { value: _WASMAudioDecoderCommon }, - EmscriptenWASM: { value: _EmscriptenWASM }, - module: { value: data.module }, - isWebWorker: { value: true }, - }); - - decoder = new _Decoder(data.options); - moduleResolve(); - } else if (command === "free") { - decoder.free(); - } else if (command === "ready") { - messagePromise = messagePromise.then(() => decoder.ready); - } else if (command === "reset") { - messagePromise = messagePromise.then(() => decoder.reset()); - } else { - // "decode": - // "decodeFrame": - // "decodeFrames": - Object.assign( - messagePayload, - decoder[command]( - // detach buffers - Array.isArray(data) - ? data.map((data) => new Uint8Array(data)) - : new Uint8Array(data), - ), - ); - // The "transferList" parameter transfers ownership of channel data to main thread, - // which avoids copying memory. - transferList = messagePayload.channelData - ? messagePayload.channelData.map((channel) => channel.buffer) - : []; - } - - messagePromise.then(() => - self.postMessage(messagePayload, transferList), - ); - }; - }).toString()})(${Decoder}, ${WASMAudioDecoderCommon}, ${EmscriptenWASM})`; - - try { - isNode = typeof process.versions.node !== "undefined"; - } catch {} - - source = isNode - ? `data:${type};base64,${Buffer.from(webworkerSourceCode).toString( - "base64", - )}` - : URL.createObjectURL(new Blob([webworkerSourceCode], { type })); - - WASMAudioDecoderCommon.modules.set(Decoder, source); - } - - super(source, { name }); - - this._id = Number.MIN_SAFE_INTEGER; - this._enqueuedOperations = new Map(); - - this.onmessage = ({ data }) => { - const { id, ...rest } = data; - this._enqueuedOperations.get(id)(rest); - this._enqueuedOperations.delete(id); - }; - - new EmscriptenWASM(WASMAudioDecoderCommon).getModule().then((module) => { - this.postToDecoder("init", { module, options }); - }); - } - - async postToDecoder(command, data) { - return new Promise((resolve) => { - this.postMessage({ - command, - id: this._id, - data, - }); - - this._enqueuedOperations.set(this._id++, resolve); - }); - } - - get ready() { - return this.postToDecoder("ready"); - } - - async free() { - await this.postToDecoder("free").finally(() => { - this.terminate(); - }); - } - - async reset() { - await this.postToDecoder("reset"); - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/puff/README b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/puff/README deleted file mode 100644 index 74b184cdb..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/puff/README +++ /dev/null @@ -1,67 +0,0 @@ -This copy of puff has been altered from the original to be inlined into this library. - -See the original code for puff here: https://github.com/madler/zlib/tree/master/contrib/puff - -Puff -- A Simple Inflate -3 Mar 2003 -Mark Adler -madler@alumni.caltech.edu - -What this is -- - -puff.c provides the routine puff() to decompress the deflate data format. It -does so more slowly than zlib, but the code is about one-fifth the size of the -inflate code in zlib, and written to be very easy to read. - -Why I wrote this -- - -puff.c was written to document the deflate format unambiguously, by virtue of -being working C code. It is meant to supplement RFC 1951, which formally -describes the deflate format. I have received many questions on details of the -deflate format, and I hope that reading this code will answer those questions. -puff.c is heavily commented with details of the deflate format, especially -those little nooks and cranies of the format that might not be obvious from a -specification. - -puff.c may also be useful in applications where code size or memory usage is a -very limited resource, and speed is not as important. - -How to use it -- - -Well, most likely you should just be reading puff.c and using zlib for actual -applications, but if you must ... - -Include puff.h in your code, which provides this prototype: - -int puff(unsigned char *dest, /* pointer to destination pointer */ - unsigned long *destlen, /* amount of output space */ - unsigned char *source, /* pointer to source data pointer */ - unsigned long *sourcelen); /* amount of input available */ - -Then you can call puff() to decompress a deflate stream that is in memory in -its entirety at source, to a sufficiently sized block of memory for the -decompressed data at dest. puff() is the only external symbol in puff.c The -only C library functions that puff.c needs are setjmp() and longjmp(), which -are used to simplify error checking in the code to improve readabilty. puff.c -does no memory allocation, and uses less than 2K bytes off of the stack. - -If destlen is not enough space for the uncompressed data, then inflate will -return an error without writing more than destlen bytes. Note that this means -that in order to decompress the deflate data successfully, you need to know -the size of the uncompressed data ahead of time. - -If needed, puff() can determine the size of the uncompressed data with no -output space. This is done by passing dest equal to (unsigned char *)0. Then -the initial value of *destlen is ignored and *destlen is set to the length of -the uncompressed data. So if the size of the uncompressed data is not known, -then two passes of puff() can be used--first to determine the size, and second -to do the actual inflation after allocating the appropriate memory. Not -pretty, but it works. (This is one of the reasons you should be using zlib.) - -The deflate format is self-terminating. If the deflate stream does not end -in *sourcelen bytes, puff() will return an error without reading at or past -endsource. - -On return, *sourcelen is updated to the amount of input data consumed, and -*destlen is updated to the size of the uncompressed data. See the comments -in puff.c for the possible return codes for puff(). diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/puff/build_puff.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/puff/build_puff.js deleted file mode 100644 index 7115d32ef..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/puff/build_puff.js +++ /dev/null @@ -1,31 +0,0 @@ -import fs from "fs"; -import { dynamicEncode } from "simple-yenc"; - -const puffWasmPath = "src/common/src/puff/Puff.wasm"; -const wasmCommonPath = "src/common/src/WASMAudioDecoderCommon.js"; - -const puffWasm = fs.readFileSync(puffWasmPath); - -const puffEncoded = dynamicEncode(puffWasm, "`"); - -const wasmCommon = fs.readFileSync(wasmCommonPath).toString(); - -const puffString = wasmCommon.match(/const puffString = String.raw`.*`;/s)[0]; - -const wasmStartIdx = wasmCommon.indexOf(puffString); -const wasmEndIdx = wasmStartIdx + puffString.length; - -// Concatenate the strings as buffers to preserve extended ascii -const wasmCommonWithPuff = Buffer.concat( - [ - wasmCommon.substring(0, wasmStartIdx), - "const puffString = String.raw`", - puffEncoded, - "`;", - wasmCommon.substring(wasmEndIdx), - ].map((string) => Buffer.from(string, { encoding: "binary" })), -); - -fs.writeFileSync(wasmCommonPath, wasmCommonWithPuff, { encoding: "binary" }); - -console.log(puffWasm.length); diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/puff/puff.c b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/puff/puff.c deleted file mode 100644 index 4e9bc7b99..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/puff/puff.c +++ /dev/null @@ -1,863 +0,0 @@ -/* - * puff.c - * Copyright (C) 2002-2013 Mark Adler - * For conditions of distribution and use, see copyright notice in puff.h - * version 2.3, 21 Jan 2013 - * - * puff.c is a simple inflate written to be an unambiguous way to specify the - * deflate format. It is not written for speed but rather simplicity. As a - * side benefit, this code might actually be useful when small code is more - * important than speed, such as bootstrap applications. For typical deflate - * data, zlib's inflate() is about four times as fast as puff(). zlib's - * inflate compiles to around 20K on my machine, whereas puff.c compiles to - * around 4K on my machine (a PowerPC using GNU cc). If the faster decode() - * function here is used, then puff() is only twice as slow as zlib's - * inflate(). - * - * All dynamically allocated memory comes from the stack. The stack required - * is less than 2K bytes. This code is compatible with 16-bit int's and - * assumes that long's are at least 32 bits. puff.c uses the short data type, - * assumed to be 16 bits, for arrays in order to conserve memory. The code - * works whether integers are stored big endian or little endian. - * - * In the comments below are "Format notes" that describe the inflate process - * and document some of the less obvious aspects of the format. This source - * code is meant to supplement RFC 1951, which formally describes the deflate - * format: - * - * http://www.zlib.org/rfc-deflate.html - */ - -/* - * Change history: - * - * 1.0 10 Feb 2002 - First version - * 1.1 17 Feb 2002 - Clarifications of some comments and notes - * - Update puff() dest and source pointers on negative - * errors to facilitate debugging deflators - * - Remove longest from struct huffman -- not needed - * - Simplify offs[] index in construct() - * - Add input size and checking, using longjmp() to - * maintain easy readability - * - Use short data type for large arrays - * - Use pointers instead of long to specify source and - * destination sizes to avoid arbitrary 4 GB limits - * 1.2 17 Mar 2002 - Add faster version of decode(), doubles speed (!), - * but leave simple version for readabilty - * - Make sure invalid distances detected if pointers - * are 16 bits - * - Fix fixed codes table error - * - Provide a scanning mode for determining size of - * uncompressed data - * 1.3 20 Mar 2002 - Go back to lengths for puff() parameters [Gailly] - * - Add a puff.h file for the interface - * - Add braces in puff() for else do [Gailly] - * - Use indexes instead of pointers for readability - * 1.4 31 Mar 2002 - Simplify construct() code set check - * - Fix some comments - * - Add FIXLCODES #define - * 1.5 6 Apr 2002 - Minor comment fixes - * 1.6 7 Aug 2002 - Minor format changes - * 1.7 3 Mar 2003 - Added test code for distribution - * - Added zlib-like license - * 1.8 9 Jan 2004 - Added some comments on no distance codes case - * 1.9 21 Feb 2008 - Fix bug on 16-bit integer architectures [Pohland] - * - Catch missing end-of-block symbol error - * 2.0 25 Jul 2008 - Add #define to permit distance too far back - * - Add option in TEST code for puff to write the data - * - Add option in TEST code to skip input bytes - * - Allow TEST code to read from piped stdin - * 2.1 4 Apr 2010 - Avoid variable initialization for happier compilers - * - Avoid unsigned comparisons for even happier compilers - * 2.2 25 Apr 2010 - Fix bug in variable initializations [Oberhumer] - * - Add const where appropriate [Oberhumer] - * - Split if's and ?'s for coverage testing - * - Break out test code to separate file - * - Move NIL to puff.h - * - Allow incomplete code only if single code length is 1 - * - Add full code coverage test to Makefile - * 2.3 21 Jan 2013 - Check for invalid code length codes in dynamic blocks - */ - -//#include /* for setjmp(), longjmp(), and jmp_buf */ -#include "puff.h" /* prototype for puff() */ - -#define local static /* for local function definitions */ - -/* - * Maximums for allocations and loops. It is not useful to change these -- - * they are fixed by the deflate format. - */ -#define MAXBITS 15 /* maximum bits in a code */ -#define MAXLCODES 286 /* maximum number of literal/length codes */ -#define MAXDCODES 30 /* maximum number of distance codes */ -#define MAXCODES (MAXLCODES+MAXDCODES) /* maximum codes lengths to read */ -#define FIXLCODES 288 /* number of fixed literal/length codes */ - -/* input and output state */ -struct state { - /* output state */ - unsigned char *out; /* output buffer */ - unsigned long outlen; /* available space at out */ - unsigned long outcnt; /* bytes written to out so far */ - - /* input state */ - const unsigned char *in; /* input buffer */ - unsigned long inlen; /* available input at in */ - unsigned long incnt; /* bytes read so far */ - int bitbuf; /* bit buffer */ - int bitcnt; /* number of bits in bit buffer */ - - /* input limit error return state for bits() and decode() */ -// jmp_buf env; -}; - -/* - * Return need bits from the input stream. This always leaves less than - * eight bits in the buffer. bits() works properly for need == 0. - * - * Format notes: - * - * - Bits are stored in bytes from the least significant bit to the most - * significant bit. Therefore bits are dropped from the bottom of the bit - * buffer, using shift right, and new bytes are appended to the top of the - * bit buffer, using shift left. - */ -local int bits(struct state *s, int need) -{ - long val; /* bit accumulator (can use up to 20 bits) */ - - /* load at least need bits into val */ - val = s->bitbuf; - while (s->bitcnt < need) { -// if (s->incnt == s->inlen) -// longjmp(s->env, 1); /* out of input */ - val |= (long)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */ - s->bitcnt += 8; - } - - /* drop need bits and update buffer, always zero to seven bits left */ - s->bitbuf = (int)(val >> need); - s->bitcnt -= need; - - /* return need bits, zeroing the bits above that */ - return (int)(val & ((1L << need) - 1)); -} - -/* - * Process a stored block. - * - * Format notes: - * - * - After the two-bit stored block type (00), the stored block length and - * stored bytes are byte-aligned for fast copying. Therefore any leftover - * bits in the byte that has the last bit of the type, as many as seven, are - * discarded. The value of the discarded bits are not defined and should not - * be checked against any expectation. - * - * - The second inverted copy of the stored block length does not have to be - * checked, but it's probably a good idea to do so anyway. - * - * - A stored block can have zero length. This is sometimes used to byte-align - * subsets of the compressed data for random access or partial recovery. - */ -local int stored(struct state *s) -{ - unsigned len; /* length of stored block */ - - /* discard leftover bits from current byte (assumes s->bitcnt < 8) */ - s->bitbuf = 0; - s->bitcnt = 0; - - /* get length and check against its one's complement */ - if (s->incnt + 4 > s->inlen) - return 2; /* not enough input */ - len = s->in[s->incnt++]; - len |= s->in[s->incnt++] << 8; - if (s->in[s->incnt++] != (~len & 0xff) || - s->in[s->incnt++] != ((~len >> 8) & 0xff)) - return -2; /* didn't match complement! */ - - /* copy len bytes from in to out */ - if (s->incnt + len > s->inlen) - return 2; /* not enough input */ - if (s->out != NIL) { - if (s->outcnt + len > s->outlen) - return 1; /* not enough output space */ - while (len--) - s->out[s->outcnt++] = s->in[s->incnt++]; - } - else { /* just scanning */ - s->outcnt += len; - s->incnt += len; - } - - /* done with a valid stored block */ - return 0; -} - -/* - * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of - * each length, which for a canonical code are stepped through in order. - * symbol[] are the symbol values in canonical order, where the number of - * entries is the sum of the counts in count[]. The decoding process can be - * seen in the function decode() below. - */ -struct huffman { - short *count; /* number of symbols of each length */ - short *symbol; /* canonically ordered symbols */ -}; - -/* - * Decode a code from the stream s using huffman table h. Return the symbol or - * a negative value if there is an error. If all of the lengths are zero, i.e. - * an empty code, or if the code is incomplete and an invalid code is received, - * then -10 is returned after reading MAXBITS bits. - * - * Format notes: - * - * - The codes as stored in the compressed data are bit-reversed relative to - * a simple integer ordering of codes of the same lengths. Hence below the - * bits are pulled from the compressed data one at a time and used to - * build the code value reversed from what is in the stream in order to - * permit simple integer comparisons for decoding. A table-based decoding - * scheme (as used in zlib) does not need to do this reversal. - * - * - The first code for the shortest length is all zeros. Subsequent codes of - * the same length are simply integer increments of the previous code. When - * moving up a length, a zero bit is appended to the code. For a complete - * code, the last code of the longest length will be all ones. - * - * - Incomplete codes are handled by this decoder, since they are permitted - * in the deflate format. See the format notes for fixed() and dynamic(). - */ -#ifdef SLOW -local int decode(struct state *s, const struct huffman *h) -{ - int len; /* current number of bits in code */ - int code; /* len bits being decoded */ - int first; /* first code of length len */ - int count; /* number of codes of length len */ - int index; /* index of first code of length len in symbol table */ - - code = first = index = 0; - for (len = 1; len <= MAXBITS; len++) { - code |= bits(s, 1); /* get next bit */ - count = h->count[len]; - if (code - count < first) /* if length len, return symbol */ - return h->symbol[index + (code - first)]; - index += count; /* else update for next length */ - first += count; - first <<= 1; - code <<= 1; - } - return -10; /* ran out of codes */ -} - -/* - * A faster version of decode() for real applications of this code. It's not - * as readable, but it makes puff() twice as fast. And it only makes the code - * a few percent larger. - */ -#else /* !SLOW */ -local int decode(struct state *s, const struct huffman *h) -{ - int len; /* current number of bits in code */ - int code; /* len bits being decoded */ - int first; /* first code of length len */ - int count; /* number of codes of length len */ - int index; /* index of first code of length len in symbol table */ - int bitbuf; /* bits from stream */ - int left; /* bits left in next or left to process */ - short *next; /* next number of codes */ - - bitbuf = s->bitbuf; - left = s->bitcnt; - code = first = index = 0; - len = 1; - next = h->count + 1; - while (1) { - while (left--) { - code |= bitbuf & 1; - bitbuf >>= 1; - count = *next++; - if (code - count < first) { /* if length len, return symbol */ - s->bitbuf = bitbuf; - s->bitcnt = (s->bitcnt - len) & 7; - return h->symbol[index + (code - first)]; - } - index += count; /* else update for next length */ - first += count; - first <<= 1; - code <<= 1; - len++; - } - left = (MAXBITS+1) - len; - if (left == 0) - break; -// if (s->incnt == s->inlen) -// longjmp(s->env, 1); /* out of input */ - bitbuf = s->in[s->incnt++]; - if (left > 8) - left = 8; - } - return -10; /* ran out of codes */ -} -#endif /* SLOW */ - -/* - * Given the list of code lengths length[0..n-1] representing a canonical - * Huffman code for n symbols, construct the tables required to decode those - * codes. Those tables are the number of codes of each length, and the symbols - * sorted by length, retaining their original order within each length. The - * return value is zero for a complete code set, negative for an over- - * subscribed code set, and positive for an incomplete code set. The tables - * can be used if the return value is zero or positive, but they cannot be used - * if the return value is negative. If the return value is zero, it is not - * possible for decode() using that table to return an error--any stream of - * enough bits will resolve to a symbol. If the return value is positive, then - * it is possible for decode() using that table to return an error for received - * codes past the end of the incomplete lengths. - * - * Not used by decode(), but used for error checking, h->count[0] is the number - * of the n symbols not in the code. So n - h->count[0] is the number of - * codes. This is useful for checking for incomplete codes that have more than - * one symbol, which is an error in a dynamic block. - * - * Assumption: for all i in 0..n-1, 0 <= length[i] <= MAXBITS - * This is assured by the construction of the length arrays in dynamic() and - * fixed() and is not verified by construct(). - * - * Format notes: - * - * - Permitted and expected examples of incomplete codes are one of the fixed - * codes and any code with a single symbol which in deflate is coded as one - * bit instead of zero bits. See the format notes for fixed() and dynamic(). - * - * - Within a given code length, the symbols are kept in ascending order for - * the code bits definition. - */ -local int construct(struct huffman *h, const short *length, int n) -{ - int symbol; /* current symbol when stepping through length[] */ - int len; /* current length when stepping through h->count[] */ - int left; /* number of possible codes left of current length */ - short offs[MAXBITS+1]; /* offsets in symbol table for each length */ - - /* count number of codes of each length */ - for (len = 0; len <= MAXBITS; len++) - h->count[len] = 0; - for (symbol = 0; symbol < n; symbol++) - (h->count[length[symbol]])++; /* assumes lengths are within bounds */ - if (h->count[0] == n) /* no codes! */ - return 0; /* complete, but decode() will fail */ - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; /* one possible code of zero length */ - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; /* one more bit, double codes left */ - left -= h->count[len]; /* deduct count from possible codes */ - if (left < 0) - return left; /* over-subscribed--return negative */ - } /* left > 0 means incomplete */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + h->count[len]; - - /* - * put symbols in table sorted by length, by symbol order within each - * length - */ - for (symbol = 0; symbol < n; symbol++) - if (length[symbol] != 0) - h->symbol[offs[length[symbol]]++] = symbol; - - /* return zero for complete set, positive for incomplete set */ - return left; -} - -/* - * Decode literal/length and distance codes until an end-of-block code. - * - * Format notes: - * - * - Compressed data that is after the block type if fixed or after the code - * description if dynamic is a combination of literals and length/distance - * pairs terminated by and end-of-block code. Literals are simply Huffman - * coded bytes. A length/distance pair is a coded length followed by a - * coded distance to represent a string that occurs earlier in the - * uncompressed data that occurs again at the current location. - * - * - Literals, lengths, and the end-of-block code are combined into a single - * code of up to 286 symbols. They are 256 literals (0..255), 29 length - * symbols (257..285), and the end-of-block symbol (256). - * - * - There are 256 possible lengths (3..258), and so 29 symbols are not enough - * to represent all of those. Lengths 3..10 and 258 are in fact represented - * by just a length symbol. Lengths 11..257 are represented as a symbol and - * some number of extra bits that are added as an integer to the base length - * of the length symbol. The number of extra bits is determined by the base - * length symbol. These are in the static arrays below, lens[] for the base - * lengths and lext[] for the corresponding number of extra bits. - * - * - The reason that 258 gets its own symbol is that the longest length is used - * often in highly redundant files. Note that 258 can also be coded as the - * base value 227 plus the maximum extra value of 31. While a good deflate - * should never do this, it is not an error, and should be decoded properly. - * - * - If a length is decoded, including its extra bits if any, then it is - * followed a distance code. There are up to 30 distance symbols. Again - * there are many more possible distances (1..32768), so extra bits are added - * to a base value represented by the symbol. The distances 1..4 get their - * own symbol, but the rest require extra bits. The base distances and - * corresponding number of extra bits are below in the static arrays dist[] - * and dext[]. - * - * - Literal bytes are simply written to the output. A length/distance pair is - * an instruction to copy previously uncompressed bytes to the output. The - * copy is from distance bytes back in the output stream, copying for length - * bytes. - * - * - Distances pointing before the beginning of the output data are not - * permitted. - * - * - Overlapped copies, where the length is greater than the distance, are - * allowed and common. For example, a distance of one and a length of 258 - * simply copies the last byte 258 times. A distance of four and a length of - * twelve copies the last four bytes three times. A simple forward copy - * ignoring whether the length is greater than the distance or not implements - * this correctly. You should not use memcpy() since its behavior is not - * defined for overlapped arrays. You should not use memmove() or bcopy() - * since though their behavior -is- defined for overlapping arrays, it is - * defined to do the wrong thing in this case. - */ -local void build_bits_base(short *bits, short *base, int delta, int first) { - /* build bits table */ - for (int i = 0; i < delta; ++i) bits[i] = 0; - for (int i = 0; i < 30 - delta; ++i) bits[i + delta] = i / delta; - - /* build base table */ - for (int sum = first, i = 0; i < 30; ++i) { - base[i] = sum; - sum += 1 << bits[i]; - } -}; - -local int codes(struct state *s, - const struct huffman *lencode, - const struct huffman *distcode) -{ - int symbol; /* decoded symbol */ - int len; /* length for copy */ - unsigned dist; /* distance for copy */ - static short lens[29] = { /* Size base for length codes 257..285 */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258}; - static short lext[29] = { /* Extra bits for length codes 257..285 */ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; -// static const short dists[30] = { /* Offset base for distance codes 0..29 */ -// 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, -// 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, -// 8193, 12289, 16385, 24577}; -// static const short dext[30] = { /* Extra bits for distance codes 0..29 */ -// 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, -// 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, -// 12, 12, 13, 13}; - -// static short lens[30]; -// static short lext[30]; -// build_bits_base(lext, lens, 4, 3); -// -// lens[29] = 0; -// lext[29] = 258; - - static short dists[30]; - static short dext[30]; - build_bits_base(dext, dists, 2, 1); - - /* decode literals and length/distance pairs */ - do { - symbol = decode(s, lencode); - if (symbol < 0) - return symbol; /* invalid symbol */ - if (symbol < 256) { /* literal: symbol is the byte */ - /* write out the literal */ - if (s->out != NIL) { - if (s->outcnt == s->outlen) - return 1; - s->out[s->outcnt] = symbol; - } - s->outcnt++; - } - else if (symbol > 256) { /* length */ - /* get and compute length */ - symbol -= 257; - if (symbol >= 29) - return -10; /* invalid fixed code */ - len = lens[symbol] + bits(s, lext[symbol]); - - /* get and check distance */ - symbol = decode(s, distcode); - if (symbol < 0) - return symbol; /* invalid symbol */ - dist = dists[symbol] + bits(s, dext[symbol]); -#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - if (dist > s->outcnt) - return -11; /* distance too far back */ -#endif - - /* copy length bytes from distance bytes back */ - if (s->out != NIL) { - if (s->outcnt + len > s->outlen) - return 1; - while (len--) { - s->out[s->outcnt] = -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - dist > s->outcnt ? - 0 : -#endif - s->out[s->outcnt - dist]; - s->outcnt++; - } - } - else - s->outcnt += len; - } - } while (symbol != 256); /* end of block symbol */ - - /* done with a valid fixed or dynamic block */ - return 0; -} - -/* - * Process a fixed codes block. - * - * Format notes: - * - * - This block type can be useful for compressing small amounts of data for - * which the size of the code descriptions in a dynamic block exceeds the - * benefit of custom codes for that block. For fixed codes, no bits are - * spent on code descriptions. Instead the code lengths for literal/length - * codes and distance codes are fixed. The specific lengths for each symbol - * can be seen in the "for" loops below. - * - * - The literal/length code is complete, but has two symbols that are invalid - * and should result in an error if received. This cannot be implemented - * simply as an incomplete code since those two symbols are in the "middle" - * of the code. They are eight bits long and the longest literal/length\ - * code is nine bits. Therefore the code must be constructed with those - * symbols, and the invalid symbols must be detected after decoding. - * - * - The fixed distance codes also have two invalid symbols that should result - * in an error if received. Since all of the distance codes are the same - * length, this can be implemented as an incomplete code. Then the invalid - * codes are detected while decoding. - */ -local int fixed(struct state *s) -{ - static int virgin = 1; - static short lencnt[MAXBITS+1], lensym[FIXLCODES]; - static short distcnt[MAXBITS+1], distsym[MAXDCODES]; - static struct huffman lencode, distcode; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - int symbol; - short lengths[FIXLCODES]; - - /* construct lencode and distcode */ - lencode.count = lencnt; - lencode.symbol = lensym; - distcode.count = distcnt; - distcode.symbol = distsym; - - /* literal/length table */ - for (symbol = 0; symbol < 144; symbol++) - lengths[symbol] = 8; - for (; symbol < 256; symbol++) - lengths[symbol] = 9; - for (; symbol < 280; symbol++) - lengths[symbol] = 7; - for (; symbol < FIXLCODES; symbol++) - lengths[symbol] = 8; - construct(&lencode, lengths, FIXLCODES); - - /* distance table */ - for (symbol = 0; symbol < MAXDCODES; symbol++) - lengths[symbol] = 5; - construct(&distcode, lengths, MAXDCODES); - - /* do this just once */ - virgin = 0; - } - - /* decode data until end-of-block code */ - return codes(s, &lencode, &distcode); -} - -/* - * Process a dynamic codes block. - * - * Format notes: - * - * - A dynamic block starts with a description of the literal/length and - * distance codes for that block. New dynamic blocks allow the compressor to - * rapidly adapt to changing data with new codes optimized for that data. - * - * - The codes used by the deflate format are "canonical", which means that - * the actual bits of the codes are generated in an unambiguous way simply - * from the number of bits in each code. Therefore the code descriptions - * are simply a list of code lengths for each symbol. - * - * - The code lengths are stored in order for the symbols, so lengths are - * provided for each of the literal/length symbols, and for each of the - * distance symbols. - * - * - If a symbol is not used in the block, this is represented by a zero as - * as the code length. This does not mean a zero-length code, but rather - * that no code should be created for this symbol. There is no way in the - * deflate format to represent a zero-length code. - * - * - The maximum number of bits in a code is 15, so the possible lengths for - * any code are 1..15. - * - * - The fact that a length of zero is not permitted for a code has an - * interesting consequence. Normally if only one symbol is used for a given - * code, then in fact that code could be represented with zero bits. However - * in deflate, that code has to be at least one bit. So for example, if - * only a single distance base symbol appears in a block, then it will be - * represented by a single code of length one, in particular one 0 bit. This - * is an incomplete code, since if a 1 bit is received, it has no meaning, - * and should result in an error. So incomplete distance codes of one symbol - * should be permitted, and the receipt of invalid codes should be handled. - * - * - It is also possible to have a single literal/length code, but that code - * must be the end-of-block code, since every dynamic block has one. This - * is not the most efficient way to create an empty block (an empty fixed - * block is fewer bits), but it is allowed by the format. So incomplete - * literal/length codes of one symbol should also be permitted. - * - * - If there are only literal codes and no lengths, then there are no distance - * codes. This is represented by one distance code with zero bits. - * - * - The list of up to 286 length/literal lengths and up to 30 distance lengths - * are themselves compressed using Huffman codes and run-length encoding. In - * the list of code lengths, a 0 symbol means no code, a 1..15 symbol means - * that length, and the symbols 16, 17, and 18 are run-length instructions. - * Each of 16, 17, and 18 are follwed by extra bits to define the length of - * the run. 16 copies the last length 3 to 6 times. 17 represents 3 to 10 - * zero lengths, and 18 represents 11 to 138 zero lengths. Unused symbols - * are common, hence the special coding for zero lengths. - * - * - The symbols for 0..18 are Huffman coded, and so that code must be - * described first. This is simply a sequence of up to 19 three-bit values - * representing no code (0) or the code length for that symbol (1..7). - * - * - A dynamic block starts with three fixed-size counts from which is computed - * the number of literal/length code lengths, the number of distance code - * lengths, and the number of code length code lengths (ok, you come up with - * a better name!) in the code descriptions. For the literal/length and - * distance codes, lengths after those provided are considered zero, i.e. no - * code. The code length code lengths are received in a permuted order (see - * the order[] array below) to make a short code length code length list more - * likely. As it turns out, very short and very long codes are less likely - * to be seen in a dynamic code description, hence what may appear initially - * to be a peculiar ordering. - * - * - Given the number of literal/length code lengths (nlen) and distance code - * lengths (ndist), then they are treated as one long list of nlen + ndist - * code lengths. Therefore run-length coding can and often does cross the - * boundary between the two sets of lengths. - * - * - So to summarize, the code description at the start of a dynamic block is - * three counts for the number of code lengths for the literal/length codes, - * the distance codes, and the code length codes. This is followed by the - * code length code lengths, three bits each. This is used to construct the - * code length code which is used to read the remainder of the lengths. Then - * the literal/length code lengths and distance lengths are read as a single - * set of lengths using the code length codes. Codes are constructed from - * the resulting two sets of lengths, and then finally you can start - * decoding actual compressed data in the block. - * - * - For reference, a "typical" size for the code description in a dynamic - * block is around 80 bytes. - */ -local int dynamic(struct state *s) -{ - int nlen, ndist, ncode; /* number of lengths in descriptor */ - int index; /* index of lengths[] */ - int err; /* construct() return value */ - short lengths[MAXCODES]; /* descriptor code lengths */ - short lencnt[MAXBITS+1], lensym[MAXLCODES]; /* lencode memory */ - short distcnt[MAXBITS+1], distsym[MAXDCODES]; /* distcode memory */ - struct huffman lencode, distcode; /* length and distance codes */ - static const short order[19] = /* permutation of code length codes */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* construct lencode and distcode */ - lencode.count = lencnt; - lencode.symbol = lensym; - distcode.count = distcnt; - distcode.symbol = distsym; - - /* get number of lengths in each table, check lengths */ - nlen = bits(s, 5) + 257; - ndist = bits(s, 5) + 1; - ncode = bits(s, 4) + 4; - if (nlen > MAXLCODES || ndist > MAXDCODES) - return -3; /* bad counts */ - - /* read code length code lengths (really), missing lengths are zero */ - for (index = 0; index < ncode; index++) - lengths[order[index]] = bits(s, 3); - for (; index < 19; index++) - lengths[order[index]] = 0; - - /* build huffman table for code lengths codes (use lencode temporarily) */ - err = construct(&lencode, lengths, 19); - if (err != 0) /* require complete code set here */ - return -4; - - /* read length/literal and distance code length tables */ - index = 0; - while (index < nlen + ndist) { - int symbol; /* decoded value */ - int len; /* last length to repeat */ - - symbol = decode(s, &lencode); - if (symbol < 0) - return symbol; /* invalid symbol */ - if (symbol < 16) /* length in 0..15 */ - lengths[index++] = symbol; - else { /* repeat instruction */ - len = 0; /* assume repeating zeros */ - if (symbol == 16) { /* repeat last length 3..6 times */ - if (index == 0) - return -5; /* no last length! */ - len = lengths[index - 1]; /* last length */ - symbol = 3 + bits(s, 2); - } - else if (symbol == 17) /* repeat zero 3..10 times */ - symbol = 3 + bits(s, 3); - else /* == 18, repeat zero 11..138 times */ - symbol = 11 + bits(s, 7); - if (index + symbol > nlen + ndist) - return -6; /* too many lengths! */ - while (symbol--) /* repeat last or zero symbol times */ - lengths[index++] = len; - } - } - - /* check for end-of-block code -- there better be one! */ - if (lengths[256] == 0) - return -9; - - /* build huffman table for literal/length codes */ - err = construct(&lencode, lengths, nlen); - if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1])) - return -7; /* incomplete code ok only for single length 1 code */ - - /* build huffman table for distance codes */ - err = construct(&distcode, lengths + nlen, ndist); - if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1])) - return -8; /* incomplete code ok only for single length 1 code */ - - /* decode data until end-of-block code */ - return codes(s, &lencode, &distcode); -} - -/* - * Inflate source to dest. On return, destlen and sourcelen are updated to the - * size of the uncompressed data and the size of the deflate data respectively. - * On success, the return value of puff() is zero. If there is an error in the - * source data, i.e. it is not in the deflate format, then a negative value is - * returned. If there is not enough input available or there is not enough - * output space, then a positive error is returned. In that case, destlen and - * sourcelen are not updated to facilitate retrying from the beginning with the - * provision of more input data or more output space. In the case of invalid - * inflate data (a negative error), the dest and source pointers are updated to - * facilitate the debugging of deflators. - * - * puff() also has a mode to determine the size of the uncompressed output with - * no output written. For this dest must be (unsigned char *)0. In this case, - * the input value of *destlen is ignored, and on return *destlen is set to the - * size of the uncompressed output. - * - * The return codes are: - * - * 2: available inflate data did not terminate - * 1: output space exhausted before completing inflate - * 0: successful inflate - * -1: invalid block type (type == 3) - * -2: stored block length did not match one's complement - * -3: dynamic block code description: too many length or distance codes - * -4: dynamic block code description: code lengths codes incomplete - * -5: dynamic block code description: repeat lengths with no first length - * -6: dynamic block code description: repeat more than specified lengths - * -7: dynamic block code description: invalid literal/length code lengths - * -8: dynamic block code description: invalid distance code lengths - * -9: dynamic block code description: missing end-of-block code - * -10: invalid literal/length or distance code in fixed or dynamic block - * -11: distance is too far back in fixed or dynamic block - * - * Format notes: - * - * - Three bits are read for each block to determine the kind of block and - * whether or not it is the last block. Then the block is decoded and the - * process repeated if it was not the last block. - * - * - The leftover bits in the last byte of the deflate data after the last - * block (if it was a fixed or dynamic block) are undefined and have no - * expected values to check. - */ -int puff(unsigned char *dest, /* pointer to destination pointer */ - unsigned long *destlen, /* amount of output space */ - const unsigned char *source, /* pointer to source data pointer */ - unsigned long *sourcelen) /* amount of input available */ -{ - struct state s; /* input/output state */ - int last, type; /* block information */ - int err; /* return value */ - - /* initialize output state */ - s.out = dest; - s.outlen = *destlen; /* ignored if dest is NIL */ - s.outcnt = 0; - - /* initialize input state */ - s.in = source; - s.inlen = *sourcelen; - s.incnt = 0; - s.bitbuf = 0; - s.bitcnt = 0; - - /* return if bits() or decode() tries to read past available input */ -// if (setjmp(s.env) != 0) /* if came back here via longjmp() */ -// err = 2; /* then skip do-loop, return error */ -// else { - /* process blocks until last block or error */ - do { - last = bits(&s, 1); /* one if last block */ - type = bits(&s, 2); /* block type 0..3 */ - err = type == 0 ? - stored(&s) : - (type == 1 ? - fixed(&s) : - (type == 2 ? - dynamic(&s) : - -1)); /* type == 3, invalid */ - if (err != 0) - break; /* return with error */ - } while (!last); -// } - - /* update the lengths and return */ - if (err <= 0) { - *destlen = s.outcnt; - *sourcelen = s.incnt; - } - return err; -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/puff/puff.h b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/puff/puff.h deleted file mode 100644 index e23a24543..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/puff/puff.h +++ /dev/null @@ -1,35 +0,0 @@ -/* puff.h - Copyright (C) 2002-2013 Mark Adler, all rights reserved - version 2.3, 21 Jan 2013 - - This software is provided 'as-is', without any express or implied - warranty. In no event will the author be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Mark Adler madler@alumni.caltech.edu - */ - - -/* - * See puff.c for purpose and usage. - */ -#ifndef NIL -# define NIL ((unsigned char *)0) /* for no output option */ -#endif - -int puff(unsigned char *dest, /* pointer to destination pointer */ - unsigned long *destlen, /* amount of output space */ - const unsigned char *source, /* pointer to source data pointer */ - unsigned long *sourcelen); /* amount of input available */ diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/utilities.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/utilities.js deleted file mode 100644 index 183314fcb..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/src/utilities.js +++ /dev/null @@ -1,3 +0,0 @@ -export const assignNames = (Class, name) => { - Object.defineProperty(Class, "name", { value: name }); -}; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/types.d.ts b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/types.d.ts deleted file mode 100644 index dbc827214..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common/types.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface DecodeError { - message: string; - frameLength: number; - frameNumber: number; - inputBytes: number; - outputSamples: number; -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/rollup.json b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/rollup.json deleted file mode 100644 index 164d7d456..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/rollup.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "external": ["@eshaz/web-worker"], - "output": { - "format": "umd", - "name": "mpg123-decoder", - "globals": { - "@eshaz/web-worker": "Worker" - } - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/EmscriptenWasm.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/EmscriptenWasm.js deleted file mode 100644 index 1ba066ec5..000000000 Binary files a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/EmscriptenWasm.js and /dev/null differ diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/MPEGDecoder.fetch.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/MPEGDecoder.fetch.js deleted file mode 100644 index b81143333..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/MPEGDecoder.fetch.js +++ /dev/null @@ -1,221 +0,0 @@ -import WASMAudioDecoderCommon from "@wasm-audio-decoders/common/src/WASMAudioDecoderCommon.js"; - -import EmscriptenWASM from "./EmscriptenWasm.js"; - -import wasmAudioDecoderCommonUrl from './wasm-audio-decoder-common.wasm'; -import emscriptenWasmUrl from './emscripten-wasm.wasm'; - -export default function MPEGDecoder(options = {}) { - // injects dependencies when running as a web worker - // async - this._init = () => { - return Promise.resolve(null) - .then(async () => { - const common = new this._WASMAudioDecoderCommon(); - const [ - wasmAudioDecoderCommon, - emscriptenWasm, - ] = await Promise.all([ - (async () => { - const res = await fetch(wasmAudioDecoderCommonUrl); - return await WebAssembly.compileStreaming(res); - })(), - (async () => { - const res = await fetch(emscriptenWasmUrl); - return await WebAssembly.compileStreaming(res); - })(), - ]); - this._WASMAudioDecoderCommon.setModule(this._WASMAudioDecoderCommon, wasmAudioDecoderCommon); - this._WASMAudioDecoderCommon.setModule(this._EmscriptenWASM, emscriptenWasm); - return await common.instantiate(this._EmscriptenWASM, this._module); - }) - .then((common) => { - this._common = common; - - this._sampleRate = 0; - this._inputBytes = 0; - this._outputSamples = 0; - this._frameNumber = 0; - - this._input = this._common.allocateTypedArray( - this._inputSize, - Uint8Array, - ); - - this._output = this._common.allocateTypedArray( - this._outputSize, - Float32Array, - ); - - const decoderPtr = this._common.allocateTypedArray(1, Uint32Array); - this._samplesDecodedPtr = this._common.allocateTypedArray( - 1, - Uint32Array, - ); - this._sampleRatePtr = this._common.allocateTypedArray(1, Uint32Array); - this._errorStringPtr = this._common.allocateTypedArray(1, Uint32Array); - - const error = this._common.wasm.mpeg_frame_decoder_create( - decoderPtr.ptr, - options.enableGapless === false ? 0 : 1, // default to enabled - ); - - if (error) { - throw Error(this._getErrorMessage(error)); - } - - this._decoder = decoderPtr.buf[0]; - }); - }; - - Object.defineProperty(this, "ready", { - enumerable: true, - get: () => this._ready, - }); - - this._getErrorMessage = (error) => - error + " " + this._common.codeToString(this._errorStringPtr.buf[0]); - - // async - this.reset = () => { - this.free(); - return this._init(); - }; - - this.free = () => { - this._common.wasm.mpeg_frame_decoder_destroy(this._decoder); - this._common.wasm.free(this._decoder); - - this._common.free(); - }; - - this.decode = (data) => { - let output = [], - errors = [], - samples = 0; - - if (!(data instanceof Uint8Array)) - throw Error( - "Data to decode must be Uint8Array. Instead got " + typeof data, - ); - - feed: for ( - let dataOffset = 0, dataChunkLength = 0; - dataOffset < data.length; - dataOffset += dataChunkLength - ) { - const dataChunk = data.subarray(dataOffset, this._input.len + dataOffset); - dataChunkLength = dataChunk.length; - this._inputBytes += dataChunkLength; - - this._input.buf.set(dataChunk); - - // feed data in chunks as large as the input buffer - let error = this._common.wasm.mpeg_decoder_feed( - this._decoder, - this._input.ptr, - dataChunkLength, - ); - - if (error === -10) { - continue feed; // MPG123_NEED_MORE - } - - // decode data in chunks as large as the input buffer - read: while (true) { - this._samplesDecodedPtr.buf[0] = 0; - - error = this._common.wasm.mpeg_decoder_read( - this._decoder, - this._output.ptr, - this._output.len, - this._samplesDecodedPtr.ptr, - this._sampleRatePtr.ptr, - this._errorStringPtr.ptr, - ); - - const samplesDecoded = this._samplesDecodedPtr.buf[0]; - this._outputSamples += samplesDecoded; - - if (samplesDecoded) { - samples += samplesDecoded; - output.push([ - this._output.buf.slice(0, samplesDecoded), - this._output.buf.slice(samplesDecoded, samplesDecoded * 2), - ]); - } - - if (error == -11) { - continue read; // MPG123_NEW_FORMAT, usually the start of a new stream - } else if (error === -10) { - continue feed; // MPG123_NEED_MORE - } else if (error) { - const message = this._getErrorMessage(error); - console.error("mpg123-decoder: " + message); - - this._common.addError( - errors, - message, - 0, - this._frameNumber, - this._inputBytes, - this._outputSamples, - ); - } - } - } - - return this._WASMAudioDecoderCommon.getDecodedAudioMultiChannel( - errors, - output, - 2, - samples, - this._sampleRatePtr.buf[0], - ); - }; - - this.decodeFrame = (mpegFrame) => { - const decoded = this.decode(mpegFrame); - this._frameNumber++; - return decoded; - }; - - this.decodeFrames = (mpegFrames) => { - let output = [], - errors = [], - samples = 0, - i = 0; - - while (i < mpegFrames.length) { - const decoded = this.decodeFrame(mpegFrames[i++]); - - output.push(decoded.channelData); - errors = errors.concat(decoded.errors); - samples += decoded.samplesDecoded; - } - - return this._WASMAudioDecoderCommon.getDecodedAudioMultiChannel( - errors, - output, - 2, - samples, - this._sampleRatePtr.buf[0], - ); - }; - - // constructor - - // injects dependencies when running as a web worker - this._isWebWorker = MPEGDecoder.isWebWorker; - this._WASMAudioDecoderCommon = - MPEGDecoder.WASMAudioDecoderCommon || WASMAudioDecoderCommon; - this._EmscriptenWASM = MPEGDecoder.EmscriptenWASM || EmscriptenWASM; - this._module = MPEGDecoder.module; - - this._inputSize = 2 ** 16; - this._outputSize = 2889 * 16 * 2; - - this._ready = this._init(); - - return this; -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/MPEGDecoder.fs.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/MPEGDecoder.fs.js deleted file mode 100644 index 9fa1b85ad..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/MPEGDecoder.fs.js +++ /dev/null @@ -1,216 +0,0 @@ -import WASMAudioDecoderCommon from "@wasm-audio-decoders/common/src/WASMAudioDecoderCommon.js"; - -import EmscriptenWASM from "./EmscriptenWasm.js"; - -import path from 'path'; -import fs from 'fs'; - -const loadWasm = p => { - const b = fs.readFileSync(p); - const m = new WebAssembly.Module(b); - return m; -}; - -let dirname = path.dirname(new URL(import.meta.url).pathname); -const wasmAudioDecoderCommon = loadWasm(path.join(dirname, '/wasm-audio-decoder-common.wasm')); -const emscriptenWasm = loadWasm(path.join(dirname, '/emscripten-wasm.wasm')); - -export default function MPEGDecoder(options = {}) { - // injects dependencies when running as a web worker - // async - this._init = () => { - const common = new this._WASMAudioDecoderCommon(); - this._WASMAudioDecoderCommon.setModule(this._WASMAudioDecoderCommon, wasmAudioDecoderCommon); - this._WASMAudioDecoderCommon.setModule(this._EmscriptenWASM, emscriptenWasm); - return common - .instantiate(this._EmscriptenWASM, this._module) - .then((common) => { - this._common = common; - - this._sampleRate = 0; - this._inputBytes = 0; - this._outputSamples = 0; - this._frameNumber = 0; - - this._input = this._common.allocateTypedArray( - this._inputSize, - Uint8Array, - ); - - this._output = this._common.allocateTypedArray( - this._outputSize, - Float32Array, - ); - - const decoderPtr = this._common.allocateTypedArray(1, Uint32Array); - this._samplesDecodedPtr = this._common.allocateTypedArray( - 1, - Uint32Array, - ); - this._sampleRatePtr = this._common.allocateTypedArray(1, Uint32Array); - this._errorStringPtr = this._common.allocateTypedArray(1, Uint32Array); - - const error = this._common.wasm.mpeg_frame_decoder_create( - decoderPtr.ptr, - options.enableGapless === false ? 0 : 1, // default to enabled - ); - - if (error) { - throw Error(this._getErrorMessage(error)); - } - - this._decoder = decoderPtr.buf[0]; - }); - }; - - Object.defineProperty(this, "ready", { - enumerable: true, - get: () => this._ready, - }); - - this._getErrorMessage = (error) => - error + " " + this._common.codeToString(this._errorStringPtr.buf[0]); - - // async - this.reset = () => { - this.free(); - return this._init(); - }; - - this.free = () => { - this._common.wasm.mpeg_frame_decoder_destroy(this._decoder); - this._common.wasm.free(this._decoder); - - this._common.free(); - }; - - this.decode = (data) => { - let output = [], - errors = [], - samples = 0; - - if (!(data instanceof Uint8Array)) - throw Error( - "Data to decode must be Uint8Array. Instead got " + typeof data, - ); - - feed: for ( - let dataOffset = 0, dataChunkLength = 0; - dataOffset < data.length; - dataOffset += dataChunkLength - ) { - const dataChunk = data.subarray(dataOffset, this._input.len + dataOffset); - dataChunkLength = dataChunk.length; - this._inputBytes += dataChunkLength; - - this._input.buf.set(dataChunk); - - // feed data in chunks as large as the input buffer - let error = this._common.wasm.mpeg_decoder_feed( - this._decoder, - this._input.ptr, - dataChunkLength, - ); - - if (error === -10) { - continue feed; // MPG123_NEED_MORE - } - - // decode data in chunks as large as the input buffer - read: while (true) { - this._samplesDecodedPtr.buf[0] = 0; - - error = this._common.wasm.mpeg_decoder_read( - this._decoder, - this._output.ptr, - this._output.len, - this._samplesDecodedPtr.ptr, - this._sampleRatePtr.ptr, - this._errorStringPtr.ptr, - ); - - const samplesDecoded = this._samplesDecodedPtr.buf[0]; - this._outputSamples += samplesDecoded; - - if (samplesDecoded) { - samples += samplesDecoded; - output.push([ - this._output.buf.slice(0, samplesDecoded), - this._output.buf.slice(samplesDecoded, samplesDecoded * 2), - ]); - } - - if (error == -11) { - continue read; // MPG123_NEW_FORMAT, usually the start of a new stream - } else if (error === -10) { - continue feed; // MPG123_NEED_MORE - } else if (error) { - const message = this._getErrorMessage(error); - console.error("mpg123-decoder: " + message); - - this._common.addError( - errors, - message, - 0, - this._frameNumber, - this._inputBytes, - this._outputSamples, - ); - } - } - } - - return this._WASMAudioDecoderCommon.getDecodedAudioMultiChannel( - errors, - output, - 2, - samples, - this._sampleRatePtr.buf[0], - ); - }; - - this.decodeFrame = (mpegFrame) => { - const decoded = this.decode(mpegFrame); - this._frameNumber++; - return decoded; - }; - - this.decodeFrames = (mpegFrames) => { - let output = [], - errors = [], - samples = 0, - i = 0; - - while (i < mpegFrames.length) { - const decoded = this.decodeFrame(mpegFrames[i++]); - - output.push(decoded.channelData); - errors = errors.concat(decoded.errors); - samples += decoded.samplesDecoded; - } - - return this._WASMAudioDecoderCommon.getDecodedAudioMultiChannel( - errors, - output, - 2, - samples, - this._sampleRatePtr.buf[0], - ); - }; - - // constructor - - // injects dependencies when running as a web worker - this._isWebWorker = MPEGDecoder.isWebWorker; - this._WASMAudioDecoderCommon = - MPEGDecoder.WASMAudioDecoderCommon || WASMAudioDecoderCommon; - this._EmscriptenWASM = MPEGDecoder.EmscriptenWASM || EmscriptenWASM; - this._module = MPEGDecoder.module; - - this._inputSize = 2 ** 16; - this._outputSize = 2889 * 16 * 2; - - this._ready = this._init(); - - return this; -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/MPEGDecoder.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/MPEGDecoder.js deleted file mode 100644 index e8ffbbdb7..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/MPEGDecoder.js +++ /dev/null @@ -1,206 +0,0 @@ -import WASMAudioDecoderCommon from "@wasm-audio-decoders/common/src/WASMAudioDecoderCommon.js"; - -import EmscriptenWASM from "./EmscriptenWasm.js"; - -import wasmAudioDecoderCommon from './wasm-audio-decoder-common.wasm'; -import emscriptenWasm from './emscripten-wasm.wasm'; - -export default function MPEGDecoder(options = {}) { - // injects dependencies when running as a web worker - // async - this._init = () => { - const common = new this._WASMAudioDecoderCommon(); - this._WASMAudioDecoderCommon.setModule(this._WASMAudioDecoderCommon, wasmAudioDecoderCommon); - this._WASMAudioDecoderCommon.setModule(this._EmscriptenWASM, emscriptenWasm); - return common - .instantiate(this._EmscriptenWASM, this._module) - .then((common) => { - this._common = common; - - this._sampleRate = 0; - this._inputBytes = 0; - this._outputSamples = 0; - this._frameNumber = 0; - - this._input = this._common.allocateTypedArray( - this._inputSize, - Uint8Array, - ); - - this._output = this._common.allocateTypedArray( - this._outputSize, - Float32Array, - ); - - const decoderPtr = this._common.allocateTypedArray(1, Uint32Array); - this._samplesDecodedPtr = this._common.allocateTypedArray( - 1, - Uint32Array, - ); - this._sampleRatePtr = this._common.allocateTypedArray(1, Uint32Array); - this._errorStringPtr = this._common.allocateTypedArray(1, Uint32Array); - - const error = this._common.wasm.mpeg_frame_decoder_create( - decoderPtr.ptr, - options.enableGapless === false ? 0 : 1, // default to enabled - ); - - if (error) { - throw Error(this._getErrorMessage(error)); - } - - this._decoder = decoderPtr.buf[0]; - }); - }; - - Object.defineProperty(this, "ready", { - enumerable: true, - get: () => this._ready, - }); - - this._getErrorMessage = (error) => - error + " " + this._common.codeToString(this._errorStringPtr.buf[0]); - - // async - this.reset = () => { - this.free(); - return this._init(); - }; - - this.free = () => { - this._common.wasm.mpeg_frame_decoder_destroy(this._decoder); - this._common.wasm.free(this._decoder); - - this._common.free(); - }; - - this.decode = (data) => { - let output = [], - errors = [], - samples = 0; - - if (!(data instanceof Uint8Array)) - throw Error( - "Data to decode must be Uint8Array. Instead got " + typeof data, - ); - - feed: for ( - let dataOffset = 0, dataChunkLength = 0; - dataOffset < data.length; - dataOffset += dataChunkLength - ) { - const dataChunk = data.subarray(dataOffset, this._input.len + dataOffset); - dataChunkLength = dataChunk.length; - this._inputBytes += dataChunkLength; - - this._input.buf.set(dataChunk); - - // feed data in chunks as large as the input buffer - let error = this._common.wasm.mpeg_decoder_feed( - this._decoder, - this._input.ptr, - dataChunkLength, - ); - - if (error === -10) { - continue feed; // MPG123_NEED_MORE - } - - // decode data in chunks as large as the input buffer - read: while (true) { - this._samplesDecodedPtr.buf[0] = 0; - - error = this._common.wasm.mpeg_decoder_read( - this._decoder, - this._output.ptr, - this._output.len, - this._samplesDecodedPtr.ptr, - this._sampleRatePtr.ptr, - this._errorStringPtr.ptr, - ); - - const samplesDecoded = this._samplesDecodedPtr.buf[0]; - this._outputSamples += samplesDecoded; - - if (samplesDecoded) { - samples += samplesDecoded; - output.push([ - this._output.buf.slice(0, samplesDecoded), - this._output.buf.slice(samplesDecoded, samplesDecoded * 2), - ]); - } - - if (error == -11) { - continue read; // MPG123_NEW_FORMAT, usually the start of a new stream - } else if (error === -10) { - continue feed; // MPG123_NEED_MORE - } else if (error) { - const message = this._getErrorMessage(error); - console.error("mpg123-decoder: " + message); - - this._common.addError( - errors, - message, - 0, - this._frameNumber, - this._inputBytes, - this._outputSamples, - ); - } - } - } - - return this._WASMAudioDecoderCommon.getDecodedAudioMultiChannel( - errors, - output, - 2, - samples, - this._sampleRatePtr.buf[0], - ); - }; - - this.decodeFrame = (mpegFrame) => { - const decoded = this.decode(mpegFrame); - this._frameNumber++; - return decoded; - }; - - this.decodeFrames = (mpegFrames) => { - let output = [], - errors = [], - samples = 0, - i = 0; - - while (i < mpegFrames.length) { - const decoded = this.decodeFrame(mpegFrames[i++]); - - output.push(decoded.channelData); - errors = errors.concat(decoded.errors); - samples += decoded.samplesDecoded; - } - - return this._WASMAudioDecoderCommon.getDecodedAudioMultiChannel( - errors, - output, - 2, - samples, - this._sampleRatePtr.buf[0], - ); - }; - - // constructor - - // injects dependencies when running as a web worker - this._isWebWorker = MPEGDecoder.isWebWorker; - this._WASMAudioDecoderCommon = - MPEGDecoder.WASMAudioDecoderCommon || WASMAudioDecoderCommon; - this._EmscriptenWASM = MPEGDecoder.EmscriptenWASM || EmscriptenWASM; - this._module = MPEGDecoder.module; - - this._inputSize = 2 ** 16; - this._outputSize = 2889 * 16 * 2; - - this._ready = this._init(); - - return this; -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/MPEGDecoderWebWorker.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/MPEGDecoderWebWorker.js deleted file mode 100644 index ebacd33b6..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/MPEGDecoderWebWorker.js +++ /dev/null @@ -1,21 +0,0 @@ -import { WASMAudioDecoderWorker } from "@wasm-audio-decoders/common"; -import EmscriptenWASM from "./EmscriptenWasm.js"; -import MPEGDecoder from "./MPEGDecoder.js"; - -export default class MPEGDecoderWebWorker extends WASMAudioDecoderWorker { - constructor(options) { - super(options, "mpg123-decoder", MPEGDecoder, EmscriptenWASM); - } - - async decode(data) { - return this.postToDecoder("decode", data); - } - - async decodeFrame(data) { - return this.postToDecoder("decodeFrame", data); - } - - async decodeFrames(data) { - return this.postToDecoder("decodeFrames", data); - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/emscripten-post.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/emscripten-post.js deleted file mode 100644 index dca1e2a83..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/emscripten-post.js +++ /dev/null @@ -1,11 +0,0 @@ -this.ready = new Promise((resolve) => { - ready = resolve; -}).then(() => { - this.HEAP = wasmMemory.buffer; - this.malloc = _malloc; - this.free = _free; - this.mpeg_decoder_feed = _mpeg_decoder_feed; - this.mpeg_decoder_read = _mpeg_decoder_read; - this.mpeg_frame_decoder_create = _mpeg_frame_decoder_create; - this.mpeg_frame_decoder_destroy = _mpeg_frame_decoder_destroy; -}); diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/emscripten-pre.js b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/emscripten-pre.js deleted file mode 100644 index 8999b37d2..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/emscripten-pre.js +++ /dev/null @@ -1 +0,0 @@ -Module = {}; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/emscripten-wasm.wasm b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/emscripten-wasm.wasm deleted file mode 100644 index 90cd99437..000000000 Binary files a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/emscripten-wasm.wasm and /dev/null differ diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/mpeg_frame_decoder.c b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/mpeg_frame_decoder.c deleted file mode 100644 index 67f7e9277..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/mpeg_frame_decoder.c +++ /dev/null @@ -1,94 +0,0 @@ -//#include -#include "mpeg_frame_decoder.h" - -#define MIN(a, b) a < b ? a : b - -int mpeg_frame_decoder_create(MPEGFrameDecoder **ptr, int enable_gapless) { - MPEGFrameDecoder *decoder = malloc(sizeof(MPEGFrameDecoder)); - *ptr = decoder; - - int error_code = 0; - - decoder->mh = mpg123_new(NULL, &error_code); - if (error_code) return error_code; - - error_code = mpg123_param(decoder->mh, MPG123_FLAGS, - MPG123_SKIP_ID3V2 | - MPG123_PLAIN_ID3TEXT | - MPG123_NO_PEEK_END | - MPG123_NO_READAHEAD | - MPG123_FORCE_STEREO | - MPG123_QUIET, 0); - if (error_code) return error_code; - - if (enable_gapless) { - error_code = mpg123_param(decoder->mh, MPG123_ADD_FLAGS, MPG123_GAPLESS, 0); - if (error_code) return error_code; - } - - error_code = mpg123_open_feed(decoder->mh); - if (error_code) return error_code; - - return error_code; -} - -int mpeg_decoder_feed( - MPEGFrameDecoder *decoder, - const unsigned char *in, - size_t in_size -) { - return mpg123_feed( - decoder->mh, - in, - in_size - ); -} - -int mpeg_decoder_read( - MPEGFrameDecoder *decoder, - float *out, - size_t out_size, - size_t *samples_decoded, - unsigned int *sample_rate, - char **error_string_ptr -) { - size_t bytes_decoded = 0; - int error = mpg123_read( - decoder->mh, - (unsigned char *) decoder->pcm, - MPEG_PCM_OUT_SIZE, - &bytes_decoded - ); - - *samples_decoded = bytes_decoded / sizeof(float) / 2; - - // deinterleave - int output_channels = 2; // TODO: remove force stereo - for (int in_idx=(*samples_decoded * output_channels) -1; in_idx >= 0; in_idx--) { - int sample = in_idx / output_channels; - int channel = (in_idx % output_channels) * *samples_decoded; - out[sample+channel] = decoder->pcm[in_idx]; - } - - if (error != MPG123_OK && error >= MPG123_ERR) { - *error_string_ptr = error_messages[error + 1]; - } else if (error < -1) { - // -12 MPG123_DONE - // -11 MPG123_NEW_FORMAT - // -10 MPG123_NEED_MORE - // needed by MPEGDecoder.js - } else { - error = 0; - } - - // MPG123_NEW_FORMAT, usually the start of a new stream, so read the sample rate - mpg123_info(decoder->mh, &decoder->fr); - *sample_rate = (int) decoder->fr.rate; - - return error; -} - -void mpeg_frame_decoder_destroy(MPEGFrameDecoder *decoder) { - mpg123_delete(decoder->mh); - free(decoder); -}; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/mpeg_frame_decoder.h b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/mpeg_frame_decoder.h deleted file mode 100644 index 9bdee64f7..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/mpeg_frame_decoder.h +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include - -// https://lists.mars.org/hyperkitty/list/mad-dev@lists.mars.org/message/23ACZCLN3DMTR62GDAQNBGNUUMXORWYR/ -#define MPEG_PCM_OUT_SIZE 2889*16*2 // max_mpeg_frame_size * bit_reservoir * channels - -typedef struct { - float pcm[MPEG_PCM_OUT_SIZE]; - mpg123_handle *mh; - struct mpg123_frameinfo fr; -} MPEGFrameDecoder; - -int mpeg_frame_decoder_create( - MPEGFrameDecoder **ptr, // pointer to store new handle - int enable_gapless // enable gapless decoding -); - -int mpeg_decoder_feed( - MPEGFrameDecoder *decoder, - const unsigned char *in, - size_t in_size -); - -int mpeg_decoder_read( - MPEGFrameDecoder *decoder, - float *out, - size_t out_size, - size_t *samples_decoded, - unsigned int *sample_rate, - char **error_string_ptr -); - -static char* error_messages[] = { - "MPG123_ERR", - "", //"MPG123_OK", - "MPG123_BAD_OUTFORMAT", - "MPG123_BAD_CHANNEL", - "MPG123_BAD_RATE", - "MPG123_ERR_16TO8TABLE", - "MPG123_BAD_PARAM", - "MPG123_BAD_BUFFER", - "MPG123_OUT_OF_MEM", - "MPG123_NOT_INITIALIZED", - "MPG123_BAD_DECODER", - "MPG123_BAD_HANDLE", - "MPG123_NO_BUFFERS", - "MPG123_BAD_RVA", - "MPG123_NO_GAPLESS", - "MPG123_NO_SPACE", - "MPG123_BAD_TYPES", - "MPG123_BAD_BAND", - "MPG123_ERR_NULL", - "MPG123_ERR_READER", - "MPG123_NO_SEEK_FROM_END", - "MPG123_BAD_WHENCE", - "MPG123_NO_TIMEOUT", - "MPG123_BAD_FILE", - "MPG123_NO_SEEK", - "MPG123_NO_READER", - "MPG123_BAD_PARS", - "MPG123_BAD_INDEX_PAR", - "MPG123_OUT_OF_SYNC", - "MPG123_RESYNC_FAIL", - "MPG123_NO_8BIT", - "MPG123_BAD_ALIGN", - "MPG123_NULL_BUFFER", - "MPG123_NO_RELSEEK", - "MPG123_NULL_POINTER", - "MPG123_BAD_KEY", - "MPG123_NO_INDEX", - "MPG123_INDEX_FAIL", - "MPG123_BAD_DECODER_SETUP", - "MPG123_MISSING_FEATURE", - "MPG123_BAD_VALUE", - "MPG123_LSEEK_FAILED", - "MPG123_BAD_CUSTOM_IO", - "MPG123_LFS_OVERFLOW", - "MPG123_INT_OVERFLOW", - "MPG123_BAD_FLOAT" -}; - -void mpeg_frame_decoder_destroy(MPEGFrameDecoder *st); diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/wasm-audio-decoder-common.wasm b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/wasm-audio-decoder-common.wasm deleted file mode 100644 index 7ce6c205c..000000000 Binary files a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/src/wasm-audio-decoder-common.wasm and /dev/null differ diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/terser.json b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/terser.json deleted file mode 100644 index f4f1e9933..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/terser.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "sourceMap": { - "url": "mpg123-decoder.min.js.map" - }, - "output": { - "preamble": "/* Copyright 2021-2024 Ethan Halsall. This file is part of wasm-audio-decoders. https://github.com/eshaz/wasm-audio-decoders */" - }, - "compress": { - "ecma": 2021, - "passes": 5, - "toplevel": true, - "unsafe": true, - "unsafe_methods": true, - "unsafe_arrows": true - }, - "mangle": { - "module": true, - "properties": { - "keep_quoted": true, - "debug": false, - "reserved": [ - "MPEGDecoder", - "MPEGDecoderWebWorker", - "instance", - "decode", - "decodeFrame", - "decodeFrames", - "free", - "ready", - "reset", - "channelData", - "samplesDecoded", - "bitDepth", - "message", - "frameLength", - "frameNumber", - "inputBytes", - "outputSamples", - "enableGapless" - ] - } - }, - "ecma": 2021, - "safari10": true, - "module": true -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/types.d.ts b/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/types.d.ts deleted file mode 100644 index 5b101c974..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/types.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { DecodeError } from "@wasm-audio-decoders/common"; - -export interface MPEGDecodedAudio { - channelData: Float32Array[]; - samplesDecoded: number; - sampleRate: number; - errors: DecodeError[]; -} - -export class MPEGDecoder { - constructor(options?: { enableGapless?: boolean }); - ready: Promise; - reset: () => Promise; - free: () => void; - decode: (mpegData: Uint8Array) => MPEGDecodedAudio; - decodeFrame: (mpegFrame: Uint8Array) => MPEGDecodedAudio; - decodeFrames: (mpegFrames: Uint8Array[]) => MPEGDecodedAudio; -} - -export class MPEGDecoderWebWorker { - constructor(options?: { enableGapless?: boolean }); - ready: Promise; - reset: () => Promise; - free: () => Promise; - decode: (mpegData: Uint8Array) => Promise; - decodeFrame: (mpegFrame: Uint8Array) => Promise; - decodeFrames: (mpegFrames: Uint8Array[]) => Promise; -} - -export { DecodeError }; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/resample.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/resample.mjs deleted file mode 100644 index a849d7b5e..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/resample.mjs +++ /dev/null @@ -1,23 +0,0 @@ -export const resample = (sampleArray, srcSampleRate, targetSampleRate) => { - if (srcSampleRate === targetSampleRate) { - return sampleArray.slice(); - } - - const conversionFactor = srcSampleRate / targetSampleRate; - const outputLength = Math.ceil(sampleArray.length / conversionFactor); - const outputArray = new Float32Array(outputLength); - - for (let i = 0; i < outputLength; ++i) { - const position = i * conversionFactor; - const index = Math.floor(position); - const fraction = position - index; - - if (index + 1 < sampleArray.length) { - outputArray[i] = sampleArray[index] * (1 - fraction) + sampleArray[index + 1] * fraction; - } else { - outputArray[i] = sampleArray[index]; - } - } - - return outputArray; -}; diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/webp-codec.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/webp-codec.mjs deleted file mode 100644 index 56d77886e..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/webp-codec.mjs +++ /dev/null @@ -1,83 +0,0 @@ -import { zbencode, zbdecode } from 'zjs'; - -export class WebPEncoder { - constructor() { - this.worker = new Worker(new URL('./webp-worker.mjs', import.meta.url), { - type: 'module', - }); - - this.worker.onmessage = e => { - const promise = this.promises.shift(); - if (promise) { - const b = e.data; - const o = zbdecode(b); - const { - error, - result, - } = o; - if (!error) { - promise.resolve(result); - } else { - promise.reject(result); - } - } else { - console.warn('WebPEncoder unexpected message', e.data); - } - }; - this.worker.onerror = err => { - console.warn('WebPEncoder error', err); - }; - - this.promises = []; - } - async encode(imageData, { - quality = 75, - lossless = false, - } = {}) { - const b = zbencode({ - method: 'encode', - args: { - imageData, - opts: { - quality, - lossless: +lossless, // int is expected in the backend - }, - }, - }); - this.worker.postMessage(b, [b.buffer]); - - const { - promise, - resolve, - reject, - } = Promise.withResolvers(); - this.promises.push({ - resolve, - }); - - return await promise; - } - async decode(encodedData) { - const b = zbencode({ - method: 'decode', - args: { - encodedData, - }, - }); - this.worker.postMessage(b, [b.buffer]); - - const { - promise, - resolve, - reject, - } = Promise.withResolvers(); - this.promises.push({ - resolve, - }); - - return await promise; - } - close() { - this.worker.terminate(); - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/webp-worker.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/webp-worker.mjs deleted file mode 100644 index db710cdb1..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/webp-worker.mjs +++ /dev/null @@ -1,60 +0,0 @@ -import webp from 'webp-wasm'; -import { zbdecode, zbencode } from 'zjs'; -import { QueueManager } from 'queue-manager'; - -const encodeWebp = async (imageData, opts) => { - const outputBuffer = await webp.encode(imageData, opts); - const uint8Array = new Uint8Array(outputBuffer.buffer, outputBuffer.byteOffset, outputBuffer.byteLength); - return uint8Array; -}; -const decodeWebp = async (encodedData) => { - const arrayBuffer = encodedData.buffer.slice(encodedData.byteOffset, encodedData.byteOffset + encodedData.byteLength); - const imageData = await webp.decode(arrayBuffer); - return imageData; -}; - -const queueManager = new QueueManager(); -globalThis.onmessage = async (e) => { - await queueManager.waitForTurn(async () => { - let error, result; - try { - const b = e.data; - const o = zbdecode(b); - const { - method, - args, - } = o; - switch (method) { - case 'encode': { - const { - imageData, - opts, - } = args; - result = await encodeWebp(imageData, opts); - break; - } - case 'decode': { - const { - encodedData, - } = args; - result = await decodeWebp(encodedData); - break; - } - default: { - throw new Error('unknown method: ' + method); - } - } - } catch(err) { - console.error(err); - error = err; - } - - let b; - if (!error) { - b = zbencode({ error: null, result }); - } else { - b = zbencode({ error, result: null }); - } - postMessage(b, [b.buffer]); - }); -}; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-codec-runtime-edge.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/ws-codec-runtime-edge.mjs deleted file mode 100644 index 368a8013b..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-codec-runtime-edge.mjs +++ /dev/null @@ -1,9 +0,0 @@ -import libopus from './packages/libopusjs/libopus.wasm.js'; -import { makeOpusCodec } from './ws-opus-codec.mjs'; -export const WsOpusCodec = makeOpusCodec(libopus); - -export { WsMp3Encoder } from './ws-mp3-encoder.mjs'; - -import MPEGDecoder from './packages/mpg123-decoder/src/MPEGDecoder.js'; -import { makeMp3Decoder } from './ws-mp3-decoder.mjs'; -export const WsMp3Decoder = makeMp3Decoder(MPEGDecoder); \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-codec-runtime-fs.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/ws-codec-runtime-fs.mjs deleted file mode 100644 index bd0cd26d3..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-codec-runtime-fs.mjs +++ /dev/null @@ -1,9 +0,0 @@ -import libopus from './packages/libopusjs/libopus.wasm.fs.js'; -import { makeOpusCodec } from './ws-opus-codec.mjs'; -export const WsOpusCodec = makeOpusCodec(libopus); - -export { WsMp3Encoder } from './ws-mp3-encoder.mjs'; - -import MPEGDecoder from './packages/mpg123-decoder/src/MPEGDecoder.fs.js'; -import { makeMp3Decoder } from './ws-mp3-decoder.mjs'; -export const WsMp3Decoder = makeMp3Decoder(MPEGDecoder); \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-codec-runtime-worker.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/ws-codec-runtime-worker.mjs deleted file mode 100644 index 929465afb..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-codec-runtime-worker.mjs +++ /dev/null @@ -1,58 +0,0 @@ -export class WsOpusCodec { - constructor() { - this.worker = new Worker(new URL(`./ws-opus-codec-worker.js`, import.meta.url), { - type: 'module', - }); - } - postMessage(data) { - this.worker.postMessage(data); - } - addEventListener(event, listener) { - this.worker.addEventListener(event, listener); - } - removeEventListener(event, listener) { - this.worker.removeEventListener(event, listener); - } - terminate() { - this.worker.terminate(); - } -} -export class WsMp3Encoder { - constructor() { - this.worker = new Worker(new URL(`./ws-mp3-encoder-worker.mjs`, import.meta.url), { - type: 'module', - }); - } - postMessage(data) { - this.worker.postMessage(data); - } - addEventListener(event, listener) { - this.worker.addEventListener(event, listener); - } - removeEventListener(event, listener) { - this.worker.removeEventListener(event, listener); - } - terminate() { - this.worker.terminate(); - } -} - -export class WsMp3Decoder { - constructor() { - this.worker = new Worker(new URL(`./ws-mp3-decoder-worker.mjs`, import.meta.url), { - type: 'module', - }); - } - postMessage(data) { - this.worker.postMessage(data); - } - addEventListener(event, listener) { - this.worker.addEventListener(event, listener); - } - removeEventListener(event, listener) { - this.worker.removeEventListener(event, listener); - } - terminate() { - this.worker.terminate(); - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-codec-util.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/ws-codec-util.mjs deleted file mode 100644 index 33a2988af..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-codec-util.mjs +++ /dev/null @@ -1,111 +0,0 @@ -import { resample } from './resample.mjs'; - -export class FakeAudioData { - constructor() { - this.data = null; - this.buffer = { - getChannelData: n => { - return this.data; - }, - }; - } - - set(data) { - this.data = data; - } -} -export class FakeIteratorResult { - constructor(value) { - this.value = value; - this.done = false; - } - - setDone(done) { - this.done = done; - } -} -export class WsMediaStreamAudioReader { - constructor(mediaStream, { - audioContext, - // if passed, resample audio to this rate - // otherwise, use the rate of the audio context - sampleRate = undefined, - }) { - if (!audioContext) { - console.warn('need audio context'); - debugger; - } - - this.buffers = []; - this.cbs = []; - this.fakeAudioData = new FakeAudioData(); - this.fakeIteratorResult = new FakeIteratorResult(this.fakeAudioData); - - const mediaStreamSourceNode = audioContext.createMediaStreamSource(mediaStream); - - const audioWorkletNode = new AudioWorkletNode(audioContext, 'ws-input-worklet'); - audioWorkletNode.onprocessorerror = err => { - console.warn('audio worklet error', err); - }; - audioWorkletNode.port.onmessage = e => { - let f32 = e.data; - // console.warn('push audio data', f32, audioContext.sampleRate, sampleRate); - if (sampleRate !== undefined) { - f32 = resample(f32, audioContext.sampleRate, sampleRate); - } - this.pushAudioData(f32); - }; - - mediaStreamSourceNode.connect(audioWorkletNode); - - const close = e => { - this.cancel(); - }; - mediaStream.addEventListener('close', close); - this.cleanup = () => { - mediaStream.removeEventListener('close', close); - }; - } - - read() { - if (this.buffers.length > 0) { - const b = this.buffers.shift(); - if (b) { - this.fakeAudioData.set(b); - } else { - this.fakeIteratorResult.setDone(true); - } - return Promise.resolve(this.fakeIteratorResult); - } else { - let accept; - const p = new Promise((a, r) => { - accept = a; - }); - this.cbs.push(b => { - if (b) { - this.fakeAudioData.set(b); - } else { - this.fakeIteratorResult.setDone(true); - } - accept(this.fakeIteratorResult); - }); - return p; - } - } - - cancel() { - this.pushAudioData(null); - this.cleanup(); - } - - pushAudioData(b) { - if (this.cbs.length > 0) { - this.cbs.shift()(b); - } else { - this.buffers.push(b); - } - } -} -export function WsEncodedAudioChunk(o) { - return o; -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-codec.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/ws-codec.mjs deleted file mode 100644 index 41826a443..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-codec.mjs +++ /dev/null @@ -1,148 +0,0 @@ -import { - FakeAudioData, -} from './ws-codec-util.mjs'; - -export class OpusAudioEncoder { - constructor({sampleRate, codecs, output, error}) { - if (!codecs.WsOpusCodec) { - console.warn('no WsOpusCodec', codecs); - throw new Error('no WsOpusCodec'); - } - this.worker = new codecs.WsOpusCodec(); - this.worker.addEventListener('message', e => { - output(e.data); - }); - this.worker.addEventListener('error', error); - this.worker.postMessage({ - mode: 'encode', - sampleRate, - }); - } - - encode(audioData) { - this.worker.postMessage(audioData.data, audioData.data !== null ? [audioData.data.buffer] : []); - } - - close() { - this.worker.terminate(); - } -} - -export class OpusAudioDecoder { - constructor({sampleRate, format, codecs, output, error}) { - if (!codecs.WsOpusCodec) { - console.warn('no WsOpusCodec', codecs); - throw new Error('no WsOpusCodec'); - } - this.worker = new codecs.WsOpusCodec(); - const fakeAudioData = new FakeAudioData(); - this.worker.addEventListener('message', e => { - if (e.data) { - fakeAudioData.set(e.data); - output(fakeAudioData); - } else { - output(null); - } - }); - this.worker.addEventListener('error', error); - this.worker.postMessage({ - mode: 'decode', - sampleRate, - format, - }); - } - - decode(data) { - this.worker.postMessage(data, data !== null ? [data.buffer] : []); - } -} - -export class Mp3AudioEncoder { - constructor({ - sampleRate, - bitrate = 128, - transferBuffers = true, - codecs, - output, - error, - }) { - if (!sampleRate) { - debugger; - } - - this.transferBuffers = transferBuffers; - - if (!codecs.WsMp3Encoder) { - console.warn('no WsMp3Encoder', codecs); - throw new Error('no WsMp3Encoder'); - } - this.worker = new codecs.WsMp3Encoder(); - - this.worker.addEventListener('message', e => { - output(e.data); - }); - this.worker.addEventListener('error', error); - this.worker.postMessage({ - sampleRate, - bitrate, - }); - } - - encode(audioData) { - this.worker.postMessage(audioData.data, this.transferBuffers && audioData.data !== null ? [audioData.data.buffer] : []); - } - - close() { - this.worker.terminate(); - } -} - -export class Mp3AudioDecoder { - constructor({ - sampleRate, - format, - transferBuffers = true, - codecs, - output, - error, - }) { - if (!sampleRate) { - throw new Error('no sample rate'); - } - if (!codecs) { - throw new Error('no codecs'); - } - - this.transferBuffers = transferBuffers; - - if (!codecs.WsMp3Decoder) { - console.warn('no WsMp3Decoder', codecs); - throw new Error('no WsMp3Decoder'); - } - this.worker = new codecs.WsMp3Decoder(); - - const fakeAudioData = new FakeAudioData(); - this.worker.addEventListener('message', e => { - // console.log('worker got data', e.data); - if (e.data.data) { - fakeAudioData.set(e.data.data); - output(fakeAudioData); - } else { - output(null); - } - }); - this.worker.addEventListener('error', error); - this.worker.postMessage({ - sampleRate, - format, - }); - } - - decode(data) { - this.worker.postMessage(data, this.transferBuffers && data !== null ? [data.buffer] : []); - } - - close() { - this.worker.terminate(); - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-constants-server.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/ws-constants-server.mjs deleted file mode 100644 index daf85a034..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-constants-server.mjs +++ /dev/null @@ -1,9 +0,0 @@ -export const MESSAGE = (() => { - let i = 1; - return { - INIT: i++, - AUDIO: i++, - STATE_UPDATE: i++, - STATE_REFRESH: i++, - }; -})(); \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-constants.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/ws-constants.mjs deleted file mode 100644 index ff50bb9c1..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-constants.mjs +++ /dev/null @@ -1,28 +0,0 @@ -export const channelCount = 1; -// export const sampleRate = 48000; -export const bitrate = 60000; -export const kbps = 128; -export const frameSize = 20; -export const voiceOptimization = true; -// export const metadataPrefix = 'metadata'; -// export const roomEntitiesPrefix = 'entities'; -export const MESSAGE = (() => { - let i = 1; - return { - INIT: i++, - AUDIO: i++, - STATE_UPDATE: i++, - STATE_REFRESH: i++, - }; -})(); -export const TYPE = (() => { - let i = 1; - return { - INT: i++, - FLOAT: i++, - STRING: i++, - UINT32ARRAY: i++, - FLOAT32ARRAY: i++, - UINT8ARRAY: i++, - }; -})(); \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-mp3-decoder-worker.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/ws-mp3-decoder-worker.mjs deleted file mode 100644 index 18492f649..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-mp3-decoder-worker.mjs +++ /dev/null @@ -1,18 +0,0 @@ -import MPEGDecoder from './packages/mpg123-decoder/src/MPEGDecoder.fetch.js'; -import { makeMp3Decoder } from './ws-mp3-decoder.mjs'; -const WsMp3Decoder = makeMp3Decoder(MPEGDecoder); - -const codec = new WsMp3Decoder(); -onmessage = e => { - codec.postMessage(e.data); -}; -codec.addEventListener('message', e => { - const { - data, - transferList, - } = e; - postMessage(data, transferList); -}); -codec.addEventListener('close', () => { - globalThis.close(); -}); \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-mp3-decoder.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/ws-mp3-decoder.mjs deleted file mode 100644 index 0e5c99c8c..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-mp3-decoder.mjs +++ /dev/null @@ -1,84 +0,0 @@ -import { resample } from './resample.mjs'; -import { formatSamples } from './format.mjs'; -import { QueueManager } from 'queue-manager'; - -export const makeMp3Decoder = (MPEGDecoder) => -class WsMp3Decoder extends EventTarget { - constructor() { - super(); - - const mp3decoder = new MPEGDecoder(); - const queueManager = new QueueManager(); - - this.handlemessage = e => { - const { - sampleRate: globalSampleRate, - format, - } = e.data; - this.handlemessage = async e => { - await queueManager.waitForTurn(async () => { - // console.log('wait for decoder ready 1'); - await mp3decoder.ready; - // console.log('wait for decoder ready 2'); - - if (e.data) { - const mp3Data = e.data; - // console.log('decode data 1', mp3Data); - const result = mp3decoder.decode(mp3Data); - // console.log('decode data 2', result); - const {channelData, samplesDecoded, sampleRate: localSampleRate} = result; - if (samplesDecoded > 0) { - const firstChannelData = channelData[0]; - // console.log('resampling 1'); - const resampled = localSampleRate === globalSampleRate ? - firstChannelData - : - resample(firstChannelData, localSampleRate, globalSampleRate); - // console.log('resampling 2', format); - const formatted = formatSamples(resampled, format, 'f32'); - // console.log('formatted', formatted); - this.dispatchMessage({ - data: formatted, - timestamp: 0, // fake - duration: 1, // fake - }, [formatted.buffer]); - } - } else { - // const data = mp3decoder.flush(); - // this.dispatchMessage({ - // data, - // timestamp: 0, // fake - // duration: 1, // fake - // }, [data.buffer]); - - this.dispatchMessage({ - data: null, - timestamp: 0, // fake - duration: 1, // fake - }); - - this.close(); - } - }); - }; - }; - } - postMessage(data, transferList) { - // console.log('mp3 decoder postMessage', data); - this.handlemessage({ - data, - transferList, - }); - } - dispatchMessage(data, transferList) { - this.dispatchEvent(new MessageEvent('message', { - data, - transferList, - })); - } - close() { - this.dispatchEvent(new MessageEvent('close', { - data: null, - })); - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-mp3-encoder-worker.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/ws-mp3-encoder-worker.mjs deleted file mode 100644 index 5993f7321..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-mp3-encoder-worker.mjs +++ /dev/null @@ -1,18 +0,0 @@ -import { - WsMp3Encoder, -} from './ws-mp3-encoder.mjs'; - -const codec = new WsMp3Encoder(); -onmessage = e => { - codec.postMessage(e.data); -}; -codec.addEventListener('message', e => { - const { - data, - transferList, - } = e; - postMessage(data, transferList); -}); -codec.addEventListener('close', () => { - globalThis.close(); -}); \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-mp3-encoder.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/ws-mp3-encoder.mjs deleted file mode 100644 index 70808866d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-mp3-encoder.mjs +++ /dev/null @@ -1,65 +0,0 @@ -import lamejs from './packages/lamejs/lame.all.js'; -import {channelCount, /*frameSize, voiceOptimization*/} from './ws-constants.mjs'; -import { floatTo16Bit, int16ToFloat32 } from './convert.mjs'; - -export class WsMp3Encoder extends EventTarget { - constructor() { - super(); - - this.handlemessage = e => { - const { - sampleRate, - bitrate, - } = e.data; - const mp3encoder = new lamejs.Mp3Encoder(channelCount, sampleRate, bitrate); - - this.handlemessage = e => { - if (e.data) { - const samples = floatTo16Bit(e.data); - const i8Array = mp3encoder.encodeBuffer(samples); - const uint8Array = new Uint8Array(i8Array.buffer, i8Array.byteOffset, i8Array.byteLength); - const data = uint8Array; - this.dispatchMessage({ - data, - timestamp: 0, // fake - duration: 1, // fake - }, [data.buffer]); - } else { - const i8Array = mp3encoder.flush(); - const uint8Array = new Uint8Array(i8Array.buffer, i8Array.byteOffset, i8Array.byteLength); - const data = uint8Array; - this.dispatchMessage({ - data, - timestamp: 0, // fake - duration: 1, // fake - }, [data.buffer]); - - this.dispatchMessage({ - data: null, - timestamp: 0, // fake - duration: 1, // fake - }); - - this.close(); - } - }; - } - } - postMessage(data, transferList) { - this.handlemessage({ - data, - transferList, - }); - } - dispatchMessage(data, transferList) { - this.dispatchEvent(new MessageEvent('message', { - data, - transferList, - })); - } - close() { - this.dispatchEvent(new MessageEvent('close', { - data: null, - })); - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-opus-codec-worker.js b/packages/usdk/packages/upstreet-agent/packages/codecs/ws-opus-codec-worker.js deleted file mode 100644 index 5ca8af2f9..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-opus-codec-worker.js +++ /dev/null @@ -1,21 +0,0 @@ -import libopus from './packages/libopusjs/libopus.wasm.fetch.js'; -import { - makeOpusCodec, -} from './ws-opus-codec.mjs'; - -const WsOpusCodec = makeOpusCodec(libopus); - -const codec = new WsOpusCodec(); -onmessage = e => { - codec.postMessage(e.data); -}; -codec.addEventListener('message', e => { - const { - data, - transferList, - } = e; - postMessage(data, transferList); -}); -codec.addEventListener('close', () => { - globalThis.close(); -}); \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-opus-codec.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/ws-opus-codec.mjs deleted file mode 100644 index d14fbae5e..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-opus-codec.mjs +++ /dev/null @@ -1,107 +0,0 @@ -import {channelCount, bitrate, frameSize, voiceOptimization} from './ws-constants.mjs'; -import { QueueManager } from 'queue-manager'; -import { floatTo16Bit } from './convert.mjs'; -import { formatSamples } from './format.mjs'; - -export const makeOpusCodec = (libopus) => -class WsOpusCodec extends EventTarget { - constructor() { - super(); - - const readyPromise = libopus.waitForReady(); - - this.handlemessage = e => { - const { - mode, - sampleRate, - format, - } = e.data; - switch (mode) { - case 'encode': { - const encoderPromise = (async () => { - await readyPromise; - const enc = new libopus.Encoder(channelCount, sampleRate, bitrate, frameSize, voiceOptimization); - return enc; - })(); - const queueManager = new QueueManager(); - - this.handlemessage = async e => { - await queueManager.waitForTurn(async () => { - const enc = await encoderPromise; - - if (e.data) { - const samples = floatTo16Bit(e.data); - enc.input(samples); - - let output; - while (output = enc.output()) { - output = output.slice(); - this.dispatchMessage({ - data: output, - timestamp: 0, // fake - duration: 1, // fake - }, [output.buffer]); - } - } else { - this.dispatchMessage({ - data: null, - timestamp: 0, // fake - duration: 1, // fake - }); - - this.close(); - } - }); - } - break; - } - case 'decode': { - const decoderPromise = (async () => { - await readyPromise; - const dec = new libopus.Decoder(channelCount, sampleRate); - return dec; - })(); - const queueManager = new QueueManager(); - - this.handlemessage = async e => { - await queueManager.waitForTurn(async () => { - const dec = await decoderPromise; - - if (e.data) { - dec.input(e.data); - - let output; - while (output = dec.output()) { - const formatted = formatSamples(output, format, 'i16'); - this.dispatchMessage(formatted, [formatted.buffer]); - } - } else { - this.dispatchMessage(null); - - this.close(); - } - }); - }; - break; - } - } - }; - } - postMessage(data, transferList) { - this.handlemessage({ - data, - transferList, - }); - } - dispatchMessage(data, transferList) { - this.dispatchEvent(new MessageEvent('message', { - data, - transferList, - })); - } - close() { - this.dispatchEvent(new MessageEvent('close', { - data: null, - })); - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-util-server.mjs b/packages/usdk/packages/upstreet-agent/packages/codecs/ws-util-server.mjs deleted file mode 100644 index b8e471255..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/codecs/ws-util-server.mjs +++ /dev/null @@ -1,35 +0,0 @@ -const textEncoder = new TextEncoder(); -const encodedMessageUint8Array = new Uint8Array(32 * 1024); -const encodedMessageDataView = new DataView(encodedMessageUint8Array.buffer, encodedMessageUint8Array.byteOffset); -export const encodeMessage = parts => { - let index = 0; - for (const part of parts) { - if (typeof part === 'number') { - encodedMessageDataView.setUint32(index, part, true); - index += Uint32Array.BYTES_PER_ELEMENT; - } else if (typeof part === 'string') { - const {written} = textEncoder.encodeInto(part, new Uint8Array(encodedMessageUint8Array.buffer, encodedMessageUint8Array.byteOffset + index + Uint32Array.BYTES_PER_ELEMENT)); - encodedMessageDataView.setUint32(index, written, true); - index += Uint32Array.BYTES_PER_ELEMENT; - index += written; - } else if (part.byteLength >= 0) { - if (!part.staticSize) { - encodedMessageDataView.setUint32(index, part.byteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - } - encodedMessageUint8Array.set(new Uint8Array(part.buffer, part.byteOffset, part.byteLength), index); - index += part.byteLength; - } else { - throw new Error('unknown part: ' + JSON.stringify(part)); - } - } - return new Uint8Array(encodedMessageUint8Array.buffer, encodedMessageUint8Array.byteOffset, index); -}; -/* // hack to fix toJSON() -module.exports.loadState = state => { - const objects = state.getArray('objects'); - for (let i = 0; i < objects.length; i++) { - const objectId = objects.get(i); - const object = state.getMap('objects.' + objectId); - } -}; */ \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/debouncer/debouncer.mjs b/packages/usdk/packages/upstreet-agent/packages/debouncer/debouncer.mjs deleted file mode 100644 index 2a50e0365..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/debouncer/debouncer.mjs +++ /dev/null @@ -1,106 +0,0 @@ -export class Debouncer extends EventTarget { - queueLength = 0; - running = false; - queue = []; - constructor({ - queueLength = 1, - } = {}) { - super(); - - this.queueLength = queueLength; - } - isIdle() { - return !this.running; - } - async waitForTurn(fn) { - if (!this.running) { - this.running = true; - this.dispatchEvent(new MessageEvent('idlechange', { - data: { - idle: false, - }, - })); - - let result, error; - try { - result = await fn(); - } catch(err) { - error = err; - } - - this.running = false; - if (this.queue.length > 0) { - const entry = this.queue.shift(); - this.waitForTurn(entry.call); - } else { - this.dispatchEvent(new MessageEvent('idlechange', { - data: { - idle: true, - }, - })); - } - - if (!error) { - return result; - } else { - throw error; - } - } else { - const { - promise, - resolve, - reject, - } = Promise.withResolvers(); - const call = async () => { - let result, error; - try { - result = await fn(); - } catch(err) { - error = err; - } - - if (!error) { - resolve(result); - return result; - } else { - reject(error); - throw error; - } - }; - const entry = { - call, - resolve, - reject, - }; - this.queue.push(entry); - while (this.queue.length > this.queueLength) { - const entry = this.queue.shift(); - entry.resolve(); - } - const result = await promise; - return result; - } - } -} - -/* export class MultiDebouncer { - constructor(opts) { - this.opts = opts; - - this.debouncers = new Map(); - } - async waitForTurn(key, fn) { - let debouncer = this.debouncers.get(key); - if (!debouncer) { - debouncer = new Debouncer(this.opts); - this.debouncers.set(key, debouncer); - debouncer.addEventListener('idlechange', e => { - const { idle } = e.data; - if (idle) { - this.debouncers.delete(key); - } - }); - } - return await debouncer.waitForTurn(fn); - } -} */ \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/debouncer/package.json b/packages/usdk/packages/upstreet-agent/packages/debouncer/package.json deleted file mode 100644 index 28f4607b6..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/debouncer/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "debouncer", - "version": "0.0.1", - "main": "debouncer.mjs" -} diff --git a/packages/usdk/packages/upstreet-agent/packages/queue-manager/package.json b/packages/usdk/packages/upstreet-agent/packages/queue-manager/package.json deleted file mode 100644 index fdbebe4db..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/queue-manager/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "queue-manager", - "version": "0.0.1", - "main": "queue-manager.mjs" -} diff --git a/packages/usdk/packages/upstreet-agent/packages/queue-manager/queue-manager.mjs b/packages/usdk/packages/upstreet-agent/packages/queue-manager/queue-manager.mjs deleted file mode 100644 index 04f0047d2..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/queue-manager/queue-manager.mjs +++ /dev/null @@ -1,137 +0,0 @@ -class Entry { - fn; - abortController; - constructor(fn, abortController = new AbortController()) { - this.fn = fn; - this.abortController = abortController; - } -} - -const abortError = new Error('abort'); -abortError.isAbortError = true; - -export class QueueManager extends EventTarget { - constructor({ - parallelism = 1, - } = {}) { - super(); - - this.parallelism = parallelism; - - this.runningEntries = []; - this.queue = []; - } - isIdle() { - return this.runningEntries.length === 0; - } - next(n = 1) { - let i; - for (i = 0; i < n; i++) { - const entry = this.runningEntries.shift(); - if (entry) { - entry.abortController.abort(abortError); - continue; - } - } - // return whether we were able to abort all the entries - return i === n; - } - async waitForTurn(fn) { - const entry = new Entry(fn); - return await this.#waitForTurnEntry(entry); - } - async #waitForTurnEntry(entry) { - if (this.runningEntries.length < this.parallelism) { - this.runningEntries.push(entry); - - if (this.runningEntries.length === 1) { - this.dispatchEvent(new MessageEvent('idlechange', { - data: { - idle: false, - }, - })); - } - - let result, error; - try { - const { fn, abortController } = entry; - const { signal } = abortController; - result = await fn({ - signal, - }); - } catch(err) { - error = err; - } - - const index = this.runningEntries.indexOf(entry); - this.runningEntries.splice(index, 1); - if (this.queue.length > 0) { - const entry = this.queue.shift(); - this.#waitForTurnEntry(entry); - } else { - if (this.runningEntries.length === 0) { - this.dispatchEvent(new MessageEvent('idlechange', { - data: { - idle: true, - }, - })); - } - } - - if (error === undefined || error === abortError) { - return result; - } else { - throw error; - } - } else { - const { fn, abortController } = entry; - const { - promise, - resolve, - reject, - } = Promise.withResolvers(); - const fn2 = async (...args) => { - let result, error; - try { - result = await fn(...args); - } catch(err) { - error = err; - } - - if (error === undefined || error === abortError) { - resolve(result); - return result; - } else { - reject(error); - throw error; - } - }; - const entry2 = new Entry(fn2, abortController); - this.queue.push(entry2); - const result = await promise; - return result; - } - } -} - -export class MultiQueueManager { - constructor(opts) { - this.opts = opts; - - this.queueManagers = new Map(); - } - async waitForTurn(key, fn) { - let queueManager = this.queueManagers.get(key); - if (!queueManager) { - queueManager = new QueueManager(this.opts); - this.queueManagers.set(key, queueManager); - queueManager.addEventListener('idlechange', e => { - const { idle } = e.data; - if (idle) { - this.queueManagers.delete(key); - } - }); - } - return await queueManager.waitForTurn(fn); - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-browser/package.json b/packages/usdk/packages/upstreet-agent/packages/react-agents-browser/package.json index 37ad986f7..092c7dc87 100644 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-browser/package.json +++ b/packages/usdk/packages/upstreet-agent/packages/react-agents-browser/package.json @@ -3,6 +3,6 @@ "main": "browser-runtime.ts", "dependencies": { "react-agents": "file:../react-agents", - "codecs": "file:../codecs" + "agent-codecs": "^0.0.3" } } diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/package.json b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/package.json index 7cce48b7c..bfbc05dfc 100644 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/package.json +++ b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/package.json @@ -4,6 +4,6 @@ "main": "react-agents-client.mjs", "dependencies": { "react-agents": "file:../react-agents", - "@upstreet/multiplayer": "file:./packages/multiplayer" + "agent-multiplayer": "^0.0.8" } } diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/.eslintrc.json b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/.eslintrc.json deleted file mode 100644 index 9c238269d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/.eslintrc.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": ["../../.eslintrc.json"], - "ignorePatterns": ["public/**/*", "node_modules/**/*", "node_modules"] -} diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/.gitignore b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/.gitignore deleted file mode 100644 index ac53dbb36..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -credentials.conf -metadata.json -node_modules -.wrangler diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/README.md b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/README.md deleted file mode 100644 index c5707651f..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# Cloudflare Edge Chat Demo - -This is a demo app written on [Cloudflare Workers](https://workers.cloudflare.com/) utilizing [Durable Objects](https://blog.cloudflare.com/introducing-workers-durable-objects) to implement real-time chat with stored history. This app runs 100% on Cloudflare's edge. - -Try it here: https://edge-chat-demo.cloudflareworkers.com - -The reason this demo is remarkable is because it deals with state. Before Durable Objects, Workers were stateless, and state had to be stored elsewhere. State can mean storage, but it also means the ability to coordinate. In a chat room, when one user sends a message, the app must somehow route that message to other users, via connections that those other users already had open. These connections are state, and coordinating them in a stateless framework is hard if not impossible. - -## How does it work? - -This chat app uses a Durable Object to control each chat room. Users connect to the object using WebSockets. Messages from one user are broadcast to all the other users. The chat history is also stored in durable storage, but this is only for history. Real-time messages are relayed directly from one user to others without going through the storage layer. - -Additionally, this demo uses Durable Objects for a second purpose: Applying a rate limit to messages from any particular IP. Each IP is assigned a Durable Object that tracks recent request frequency, so that users who send too many messages can be temporarily blocked -- even across multiple chat rooms. Interestingly, these objects don't actually store any durable state at all, because they only care about very recent history, and it's not a big deal if a rate limiter randomly resets on occasion. So, these rate limiter objects are an example of a pure coordination object with no storage. - -This chat app is only a few hundred lines of code. The deployment configuration is only a few lines. Yet, it will scale seamlessly to any number of chat rooms, limited only by Cloudflare's available resources. Of course, any individual chat room's scalability has a limit, since each object is single-threaded. But, that limit is far beyond what a human participant could keep up with anyway. - -For more details, take a look at the code! It is well-commented. - -## Learn More - -* [Durable Objects introductory blog post](https://blog.cloudflare.com/introducing-workers-durable-objects) -* [Durable Objects documentation](https://developers.cloudflare.com/workers/learning/using-durable-objects) - -## Deploy it yourself - -If you haven't already, join the Durable Objects beta by visiting the [Cloudflare dashboard](https://dash.cloudflare.com/) and navigating to "Workers" and then "Durable Objects". - -Then, make sure you have [Wrangler](https://developers.cloudflare.com/workers/cli-wrangler/install-update), the official Workers CLI, installed. Version 1.19.3 or newer is required to publish this example as written. - -After installing it, run `wrangler login` to [connect it to your Cloudflare account](https://developers.cloudflare.com/workers/cli-wrangler/authentication). - -Once you're in the Durable Objects beta and have Wrangler installed and authenticated, you can deploy the app for the first time by adding your Cloudflare account ID (which can be viewed by running `wrangler whoami`) to the wrangler.toml file and then running: - - wrangler publish - -If you get an error saying "Cannot create binding for class [...] because it is not currently configured to implement durable objects", you need to update your version of Wrangler. - -This command will deploy the app to your account under the name `edge-chat-demo`. - -## What are the dependencies? - -This demo code does not have any dependencies, aside from Cloudflare Workers (for the server side, `chat.mjs`) and a modern web browser (for the client side, `views/chat.html`). Deploying the code requires Wrangler. - -## How to uninstall - -Modify wrangler.toml to remove the durable_objects bindings and add a deleted_classes migration. The bottom of your wrangler.toml should look like: - -``` -[durable_objects] -bindings = [ -] - -# Indicate that you want the ChatRoom and RateLimiter classes to be callable as Durable Objects. -[[migrations]] -tag = "v1" # Should be unique for each entry -new_classes = ["ChatRoom", "RateLimiter"] - -[[migrations]] -tag = "v2" -deleted_classes = ["ChatRoom", "RateLimiter"] -``` - -Then run `wrangler publish`, which will delete the Durable Objects and all data stored in them. To remove the Worker, go to [dash.cloudflare.com](dash.cloudflare.com) and navigate to Workers -> Overview -> edge-chat-demo -> Manage Service -> Delete (bottom of page) diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/index.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/index.mjs deleted file mode 100644 index 8d026390d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/index.mjs +++ /dev/null @@ -1,155 +0,0 @@ -import path from 'path'; -import child_process from 'child_process'; - -const MULTIPLAYER_PORT = 2222; - -// - -const dirname = path.dirname(import.meta.url.replace(/^file:\/\//, '')); -Error.stackTraceLimit = 300; - -// - -const _waitForRegex = (process, regex) => { - return new Promise((resolve, reject) => { - const onerror = err => { - reject(err); - cleanup(); - }; - process.on('error', onerror); - - process.stdout.setEncoding('utf8'); - const ondata = data => { - if (regex.test(data)) { - resolve(); - cleanup(); - } - }; - process.stdout.on('data', ondata); - - const cleanup = () => { - process.removeListener('error', onerror); - process.stdout.removeListener('data', ondata); - }; - }); -}; -const makeWaitForExit = cp => { - let exited = false; - cp.on('close', (code, signal) => { - exited = true; - }); - - return to => { - if (!exited) { - return new Promise((accept, reject) => { - const timeout = setTimeout(() => { - reject(new Error('timeout in process: ' + cp)); - }, to); - - const close = (code, signal) => { - accept(code); - cleanup(); - }; - cp.on('close', close); - cp.on('error', err => { - reject(err); - cleanup(); - }); - const cleanup = () => { - cp.removeListener('close', close); - cp.removeListener('error', reject); - clearTimeout(timeout); - }; - }); - } else { - return Promise.resolve(); - } - }; -}; - -// let httpServer = null; -let logging = false; -let quitted = false; -const loggedProcesses = []; -const _logProcess = childProcess => { - const tombstoneLogs = { - stdout: [], - stderr: [], - }; - childProcess.stdout.on('data', data => { - if (logging && !quitted) { - process.stdout.write(data); - } - tombstoneLogs.stderr.push(data); - while (tombstoneLogs.stderr.length > 1000) { - tombstoneLogs.stderr.shift(); - } - }); - childProcess.stderr.on('data', data => { - if (logging && !quitted) { - process.stderr.write(data); - } - tombstoneLogs.stderr.push(data); - while (tombstoneLogs.stderr.length > 1000) { - tombstoneLogs.stderr.shift(); - } - }); - loggedProcesses.push(childProcess); - - childProcess.on('close', (exitCode, signal) => { - if (!quitted) { - console.log(`${childProcess.name} process exited with code ${exitCode} and signal ${signal}`); - if (exitCode !== 0) { - console.log('stdout:\n', tombstoneLogs.stdout.join('')); - console.log('stderr:\n', tombstoneLogs.stderr.join('')); - } - } - }); -}; -{ - if(process.stdin.setRawMode) - process.stdin.setRawMode(true); - process.stdin.resume(); - process.stdin.setEncoding('utf8'); - const killall = async () => { - quitted = true; - // console.log('quit 2'); - for (const cp of loggedProcesses) { - console.log('kill pid', cp.name, cp.pid); - // treeKill(cp.pid, 9); - try { - process.kill(cp.pid, 'SIGTERM'); - } catch(err) { - if (err.code !== 'ESRCH') { - console.warn(err.stack); - } - } - } - await Promise.all(loggedProcesses.map(cp => cp.waitForExit(10 * 1000))); - }; -} - - - -const _startMultiplayer = async () => { - const multiplayerPath = path.join(dirname); - const wranglerPath = path.join(dirname, 'node_modules', 'wrangler'); - const multiplayerProcess = child_process.spawn(process.argv[0], [wranglerPath, 'dev', '-l', '--port', MULTIPLAYER_PORT + ''], { - cwd: multiplayerPath, - env: { - ...process.env, - PORT: MULTIPLAYER_PORT, - }, - // uid: oldUid, - }); - multiplayerProcess.name = 'multiplayer'; - multiplayerProcess.waitForExit = makeWaitForExit(multiplayerProcess); - - _logProcess(multiplayerProcess); - - await _waitForRegex(multiplayerProcess, /starting/i); - - return multiplayerProcess; -}; - -_startMultiplayer() \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/package.json b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/package.json deleted file mode 100644 index f8e96afe6..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "multiplayer", - "version": "0.6.0", - "description": "", - "main": "index.mjs", - "type": "module", - "repository": { - "type": "git", - "url": "git+https://github.com/UpstreetAI/upstreet.git" - }, - "author": "Upstreet", - "license": "MIT", - "bugs": { - "url": "https://github.com/UpstreetAI/upstreet/issues" - }, - "homepage": "https://github.com/UpstreetAI/upstreet", - "scripts": { - "dev": "wrangler dev --port 2222", - "deploy": "wrangler deploy" - }, - "dependencies": { - "@cloudflare/kv-asset-handler": "^0.3.4", - "yjs": "^13.6.18" - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/README.md b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/README.md deleted file mode 100644 index 41ff9ad19..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# zjs - -API-compatible [yjs](https://github.com/yjs/yjs) CRDT, but faster for game engine usage. - -## Benefits - -- Small memory footprint (O(data) objects garbage) -- Fast conflict resolution based on single clock, resolution priority, and binary history buffer -- Supports all JSON and binary data (typed arrays) - -## Restrictions - -- Only SFU supported -- Can only push one element at a time -- Cannot move elements diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/encoding.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/encoding.mjs deleted file mode 100644 index d97a9a78c..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/encoding.mjs +++ /dev/null @@ -1,343 +0,0 @@ -const HTMLImageElement = typeof globalThis.window !== 'undefined' ? globalThis.window.HTMLImageElement : function() {}; -const HTMLCanvasElement = typeof globalThis.window !== 'undefined' ? globalThis.window.HTMLCanvasElement : function() {}; -const ImageData = typeof globalThis.window !== 'undefined' ? globalThis.window.ImageData : function() {}; -const ImageBitmap = typeof globalThis.window !== 'undefined' ? globalThis.window.ImageBitmap : function() {}; - -const align = (v, N) => { - const r = v % N; - return r === 0 ? v : v - r + N; -}; -const align4 = v => align(v, 4); - -const ADDENDUM_TYPES = (() => { - let iota = 0; - const result = new Map(); - result.set(Uint8Array, ++iota); - result.set(Uint16Array, ++iota); - result.set(Uint32Array, ++iota); - result.set(Int8Array, ++iota); - result.set(Int16Array, ++iota); - result.set(Int32Array, ++iota); - result.set(Float32Array, ++iota); - result.set(Float64Array, ++iota); - result.set(ArrayBuffer, ++iota); - - { - const imageIota = ++iota; - result.set(HTMLImageElement, imageIota); - result.set(HTMLCanvasElement, imageIota); - result.set(ImageData, imageIota); - result.set(ImageBitmap, imageIota); - } - - result.set(Uint8ClampedArray, ++iota); - - return result; -})(); -const ADDENDUM_CONSTRUCTORS = (() => { - const _construct = constructor => - (buffer, offset, byteLength) => - new constructor(buffer, offset, byteLength / constructor.BYTES_PER_ELEMENT) - return [ - null, // start at 1 - _construct(Uint8Array), - _construct(Uint16Array), - _construct(Uint32Array), - _construct(Int8Array), - _construct(Int16Array), - _construct(Int32Array), - _construct(Float32Array), - _construct(Float64Array), - (buffer, offset, byteLength) => buffer.slice(offset, offset + byteLength), // ArrayBuffer - (buffer, offset, byteLength) => { // ImageData - const dataView = new DataView(buffer, offset, byteLength); - const width = dataView.getUint32(0, true); - const height = dataView.getUint32(4, true); - const data = new Uint8ClampedArray(buffer, offset + 8, byteLength - 8); - const imageData = new ImageData(data, width, height); - return imageData; - }, - _construct(Uint8ClampedArray), - ]; -})(); -const ADDENDUM_SERIALIZERS = (() => { - const _serializedTypedArray = (typedArray, uint8Array, index) => { - uint8Array.set(new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength), index); - }; - _serializedTypedArray.normalize = a => a; - _serializedTypedArray.getSize = typedArray => typedArray.byteLength; - - const _serializeArrayBuffer = (arrayBuffer, uint8Array, index) => { - uint8Array.set(new Uint8Array(arrayBuffer), index); - }; - _serializeArrayBuffer.normalize = a => a; - _serializeArrayBuffer.getSize = arrayBuffer => arrayBuffer.byteLength; - - const _serializeImage = (imageData, uint8Array, index) => { - const dataView = new DataView(uint8Array.buffer, index); - dataView.setUint32(0, imageData.width, true); - dataView.setUint32(4, imageData.height, true); - const srcData = new Uint8Array(imageData.data.buffer, imageData.data.byteOffset, imageData.data.byteLength); - uint8Array.set(srcData, index + 8); - }; - _serializeImage.normalize = image => { - if (!(image instanceof ImageData)) { - // draw to canvas to convert to ImageData - const canvas = document.createElement('canvas'); - canvas.width = image.width; - canvas.height = image.height; - const context = canvas.getContext('2d'); - context.drawImage(image, 0, 0); - image = context.getImageData(0, 0, image.width, image.height); - } - return image; - }; - _serializeImage.getSize = imageData => { - const size = 8 + imageData.data.byteLength; - // if (align4(imageData.data.byteLength) !== imageData.data.byteLength) { - // throw new Error('invalid image data size'); - // } - return size; - }; - - return [ - null, // start at 1 - _serializedTypedArray, // Uint8Array - _serializedTypedArray, // Uint16Array - _serializedTypedArray, // Uint32Array - _serializedTypedArray, // Int8Array - _serializedTypedArray, // Int16Array - _serializedTypedArray, // Int32Array - _serializedTypedArray, // Float32Array - _serializedTypedArray, // Float64Array - _serializeArrayBuffer, // ArrayBuffer - _serializeImage, // ImageData - _serializedTypedArray, // Uint8ClampedArray - ]; -})(); - -const textEncoder = new TextEncoder(); -const textDecoder = new TextDecoder(); -let textUint8Array = new Uint8Array(4 * 1024 * 1024); // 4 MB - -const encodableConstructors = [ - Uint8Array, - Uint16Array, - Uint32Array, - Int8Array, - Int16Array, - Int32Array, - Float32Array, - Float64Array, - ArrayBuffer, - HTMLImageElement, - HTMLCanvasElement, - ImageData, - ImageBitmap, - Uint8ClampedArray, -]; -const _isAddendumEncodable = o => - encodableConstructors.includes( - o?.constructor - ); -const nullUint8Array = textEncoder.encode('null'); -function zbencode(o) { - const addendums = []; - const addendumIndexes = []; - const addendumTypes = []; - const _getSb = () => { - if (_isAddendumEncodable(o)) { // common fast path - addendums.push(o); - addendumIndexes.push(1); - addendumTypes.push(ADDENDUM_TYPES.get(o.constructor)); - return nullUint8Array; - } else { - let recursionIndex = 0; - const _recurseExtractAddendums = o => { - recursionIndex++; - if (_isAddendumEncodable(o)) { - addendums.push(o); - addendumIndexes.push(recursionIndex); - const addendumType = ADDENDUM_TYPES.get(o.constructor); - addendumTypes.push(addendumType) - return null; - } else { - return o; - } - }; - const s = JSON.stringify(o, function(k, v) { - return _recurseExtractAddendums(v); - }); - let result; - for (;;) { - result = textEncoder.encodeInto(s, textUint8Array); - if (result.read === s.length) { - break; - } else { - textUint8Array = new Uint8Array(textUint8Array.length * 2); - console.warn('zjs: resizing buffer'); - } - } - return textUint8Array.subarray(0, result.written); - } - }; - const sb = _getSb(); - - let totalSize = 0; - totalSize += Uint32Array.BYTES_PER_ELEMENT; // length - totalSize += sb.byteLength; // data - totalSize = align4(totalSize); - totalSize += Uint32Array.BYTES_PER_ELEMENT; // count - for (let i = 0; i < addendums.length; i++) { - const addendum = addendums[i]; - - totalSize += Uint32Array.BYTES_PER_ELEMENT; // index - totalSize += Uint32Array.BYTES_PER_ELEMENT; // type - totalSize += Uint32Array.BYTES_PER_ELEMENT; // length - - // totalSize += addendum.byteLength; // data - const addendumType = addendumTypes[i]; - const Serializer = ADDENDUM_SERIALIZERS[addendumType]; - const normalizedAddendum = Serializer.normalize(addendum); - addendums[i] = normalizedAddendum; - const addendumByteLength = Serializer.getSize(normalizedAddendum); - totalSize += align4(addendumByteLength); - } - - const ab = new ArrayBuffer(totalSize); - const uint8Array = new Uint8Array(ab); - const dataView = new DataView(ab); - { - let index = 0; - // sb - { - dataView.setUint32(index, sb.byteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - uint8Array.set(sb, index); - index += sb.byteLength; - index = align4(index); - } - // addendums - dataView.setUint32(index, addendums.length, true); - index += Uint32Array.BYTES_PER_ELEMENT; - for (let i = 0; i < addendums.length; i++) { - const addendum = addendums[i]; - const addendumIndex = addendumIndexes[i]; - const addendumType = addendumTypes[i]; - - dataView.setUint32(index, addendumIndex, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - dataView.setUint32(index, addendumType, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const Serializer = ADDENDUM_SERIALIZERS[addendumType]; - const addendumByteLength = Serializer.getSize(addendum); - - dataView.setUint32(index, addendumByteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - Serializer(addendum, uint8Array, index); - index += align4(addendumByteLength); - } - } - return uint8Array; -} -function zbdecode(uint8Array) { - // console.log('zbdecode 1', uint8Array, new Error().stack); - const dataView = new DataView(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength); - // console.log('zbdecode 2', dataView, new Error().stack); - - let index = 0; - const sbLength = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const sb = new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index, sbLength); - index += sbLength; - index = align4(index); - const s = textDecoder.decode(sb); - let j = JSON.parse(s); - - const numAddendums = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const addendums = Array(numAddendums); - const addendumIndexes = Array(numAddendums); - const addendumTypes = Array(numAddendums); - for (let i = 0; i < numAddendums; i++) { - const addendumIndex = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const addendumType = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const addendumByteLength = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const TypedArrayCons = ADDENDUM_CONSTRUCTORS[addendumType]; - /* if (!TypedArrayCons) { - console.warn('failed to find typed array cons for', addendumType); - } */ - const addendum = TypedArrayCons( - uint8Array.buffer, - uint8Array.byteOffset + index, - addendumByteLength - ); - index += addendumByteLength; - index = align4(index); - - addendums[i] = addendum; - addendumIndexes[i] = addendumIndex; - addendumTypes[i] = addendumType; - } - - { - let recursionIndex = 0; - let currentAddendum = 0; - const _recurseBindAddendums = o => { - recursionIndex++; - - const addendumIndex = addendumIndexes[currentAddendum]; - if (addendumIndex === recursionIndex) { - const addendum = addendums[currentAddendum]; - currentAddendum++; - return addendum; - } else if (Array.isArray(o)) { - for (let i = 0; i < o.length; i++) { - const addendum = _recurseBindAddendums(o[i]); - if (addendum) { - o[i] = addendum; - } - } - } else if (typeof o === 'object' && o !== null) { - for (const k in o) { - const addendum = _recurseBindAddendums(o[k]); - if (addendum) { - o[k] = addendum; - } - } - } - return null; - }; - const j2 = _recurseBindAddendums(j); - if (j2 !== null) { - j = j2; - } - if (currentAddendum !== addendums.length) { - console.warn('did not bind all addendums', j, currentAddendum, addendums); - debugger; - } - return j; - } -} - -function zbclone(o) { - return zbdecode(zbencode(o)); -} - -export { - zbencode, - zbdecode, - zbclone, -}; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/package.json b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/package.json deleted file mode 100644 index c22d76838..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "@upstreet/zjs", - "version": "0.6.0", - "main": "encoding.mjs", - "scripts": { - "test": "mocha --timeout 60000" - }, - "devDependencies": { - "alea": "^1.0.1", - "mocha": "^9.1.3" - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/test/test.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/test/test.mjs deleted file mode 100644 index 3495e74c0..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/test/test.mjs +++ /dev/null @@ -1,1490 +0,0 @@ -import assert from 'assert'; -import Z from '../z.mjs'; -import alea from 'alea'; - -const rng = new alea('lol'); -Z.setRng(rng); - -function rngndc() { - return (rng() - 0.5) * 2; -} - -/* const keypress = async () => { - process.stdin.setRawMode(true) - return new Promise(resolve => process.stdin.once('data', () => { - process.stdin.setRawMode(false) - resolve() - })) -}; */ - -describe('zbencode + zbdecode', function() { - describe('basic', function() { - it('should support basic operations', function() { - const s = 'lol'; - assert.equal(s, Z.zbdecode(Z.zbencode(s))); - - const n = 42; - assert.equal(n, Z.zbdecode(Z.zbencode(n))); - - const a = [s, n]; - assert.deepEqual(a, Z.zbdecode(Z.zbencode(a))); - - const o = { - s, - }; - assert.deepEqual(o, Z.zbdecode(Z.zbencode(o))); - - const float32Array = Float32Array.from([1, 2, 2]); - const o2 = { - float32Array, - }; - assert.deepEqual(o2, Z.zbdecode(Z.zbencode(o2))); - - const uint8Array = Uint8Array.from([1, 2, 2]); - const int16Array = Int8Array.from([1, 2, 2]); - const o3 = { - uint8Array, - int16Array, - float32Array, - }; - assert.deepEqual(o3, Z.zbdecode(Z.zbencode(o3))); - }); - }); -}); - -describe('ZMap', function() { - describe('detached', function() { - const map = new Z.Map(); - - map.set('key', 'value'); - assert.equal(map.get('key'), 'value'); - assert.equal(map.get('key2'), undefined); - }); - describe('inline', function() { - it('should support basic operations', function() { - const doc = new Z.Doc(); - const map = doc.getMap('map'); - - map.set('key', 'value'); - assert.equal(map.get('key'), 'value'); - assert.equal(map.get('key2'), undefined); - - const keys = Array.from(map.keys()); - assert.deepEqual(keys, ['key']); - - const values = Array.from(map.values()); - assert.deepEqual(values, [{ - content: { - type: 'value', - }, - }]); - - const entries = Array.from(map.entries()); - assert.deepEqual(entries, [['key', { - content: { - type: 'value', - }, - }]]); - - map.set('key2', 'value2'); - assert.equal(map.get('key2'), 'value2'); - }); - }); - describe('delayed attach', function() { - const map = new Z.Map(); - map.set('key', 'value'); - - const doc = new Z.Doc(); - const array = doc.getArray('array'); - array.push([map]); - - assert.deepEqual(doc.toJSON(), { - array: [ - { - key: 'value', - }, - ], - }); - }); -}); - -describe('ZArray', function() { - describe('detached', function() { - const array = new Z.Array(); - - array.push([1]); - assert.equal(array.get(0), 1); - assert.equal(array.get(1), undefined); - assert.equal(array.length, 1); - assert.deepEqual(array.toJSON(), [1]); - }); - describe('inline', function() { - it('should support basic operations', function() { - const doc = new Z.Doc(); - const array = doc.getArray('array'); - - array.push([1]); - assert.equal(array.get(0), 1); - assert.equal(array.get(1), undefined); - assert.equal(array.length, 1); - assert.deepEqual(array.toJSON(), [1]); - - array.push([2]); - assert.equal(array.length, 2); - assert.equal(array.get(0), 1); - assert.equal(array.get(1), 2); - assert.equal(array.get(2), undefined); - assert.deepEqual(array.toJSON(), [1, 2]); - - array.delete(0); - assert.equal(array.length, 1); - assert.equal(array.get(0), 2); - assert.equal(array.get(1), undefined); - assert.deepEqual(array.toJSON(), [2]); - }); - }); - describe('delayed attach', function() { - const array = new Z.Array(); - array.push([1]); - - const doc = new Z.Doc(); - const map = doc.getMap('map'); - map.set('array', array); - - assert.deepEqual(doc.toJSON(), { - map: { - array: [1], - }, - }); - }); -}); - -describe('api limits', function() { - it('array limits', function() { - const doc = new Z.Doc(); - const array = doc.getArray('array'); - - { - let numThrows = 0; - try { - array.push([1, 2]); - } catch (err) { - numThrows++; - } - assert.equal(numThrows, 1); - } - { - let numThrows = 0; - try { - array.insert(0, [1, 2]); - } catch (err) { - numThrows++; - } - assert.equal(numThrows, 1); - } - { - let numThrows = 0; - try { - array.push([1, 2]); - } catch (err) { - numThrows++; - } - assert.equal(numThrows, 1); - } - { - let numThrows = 0; - try { - array.unshift([1, 2]); - } catch (err) { - numThrows++; - } - assert.equal(numThrows, 1); - } - }); -}); - -describe('complex data', function() { - it('mixed map array', function() { - const doc = new Z.Doc(); - const array = doc.getArray('array'); - const map = doc.getMap('map'); - - array.push([1]); - map.set('key', 'value'); - assert.deepEqual(doc.toJSON(), {array: [1], map: {key: 'value'}}); - }); - it('array of maps', function() { - const doc = new Z.Doc(); - const array = doc.getArray('array'); - - const map1 = new Z.Map(); - const map2 = new Z.Map(); - const map3 = new Z.Map(); - array.push([map1]); - array.push([map2]); - array.push([map3]); - - map2.set('lol2', 'zol2'); - map1.set('lol1', 32.5); - const float32Array = Float32Array.from([1, 2, 3]); - map3.set('lol3', float32Array); - - assert.deepEqual(doc.toJSON(), { - array: [ - { - lol1: 32.5, - }, - { - lol2: 'zol2', - }, - { - lol3: float32Array, - }, - ], - }); - }); -}); - -describe('observers', function() { - describe('basic', function() { - it('array observers', function() { - { - const doc = new Z.Doc(); - const array = doc.getArray('array'); - let numObserves = 0; - const observe = e => { - const rawValue = 1; - const value = { - content: { - type: rawValue, - } - } - assert.deepEqual(e.changes, { - added: new Set([value]), - deleted: new Set([]), - keys: new Map([[ - 0, - { - action: 'add', - value: rawValue, - }, - ]]), - }); - - numObserves++; - }; - array.observe(observe); - array.push([1]); - assert.equal(numObserves, 1); - } - { - const doc = new Z.Doc(); - const array = doc.getArray('array'); - let numObserves = 0; - const observe = e => { - numObserves++; - }; - array.observe(observe); - array.unobserve(observe); - array.push([1]); - assert.equal(numObserves, 0); - } - }); - it('map observers', function() { - { - const doc = new Z.Doc(); - const map = doc.getMap('map'); - let numObserves = 0; - const observe = e => { - const rawValue = 'value'; - const value = { - content: { - type: rawValue, - }, - }; - assert.deepEqual(e.changes, { - added: new Set([value]), - deleted: new Set([]), - keys: new Map([[ - 'key', - { - action: 'update', - value: rawValue, - }, - ]]), - }); - - numObserves++; - }; - map.observe(observe); - map.set('key', 'value'); - assert.equal(numObserves, 1); - } - { - const doc = new Z.Doc(); - const map = doc.getMap('map'); - let numObserves = 0; - const observe = e => { - numObserves++; - }; - map.observe(observe); - map.unobserve(observe); - map.set('key', 'value'); - assert.equal(numObserves, 0); - } - }); - }); -}); - -describe('sync', function() { - describe('state reset', function() { - it('basic state reset', function() { - const doc1 = new Z.Doc(); - const map1 = doc1.getMap('map'); - const array1 = doc1.getArray('array'); - - const doc2 = new Z.Doc(); - const map2 = doc2.getMap('map'); - const array2 = doc2.getArray('array'); - - const doc3 = new Z.Doc(); - const map3 = doc3.getMap('map'); - const array3 = doc3.getArray('array'); - - map1.set('key', 'value'); - array1.push([7]); - - { - const uint8Array = Z.encodeStateAsUpdate(doc1); - Z.applyUpdate(doc2, uint8Array); - - assert.deepEqual(map1.toJSON(), {key: 'value'}); - assert.deepEqual(map2.toJSON(), {key: 'value'}); - assert.deepEqual(array1.toJSON(), [7]); - assert.deepEqual(array2.toJSON(), [7]); - } - { - let numObserves = 0; - const observe1 = e => { - const rawValue = 'value'; - const value = { - content: { - type: rawValue, - }, - }; - assert.deepEqual(e.changes, { - added: new Set([value]), - deleted: new Set([]), - keys: new Map([[ - 'key', - { - action: 'add', - value: rawValue, - }, - ]]), - }); - - numObserves++ - }; - map3.observe(observe1); - - const observe2 = e => { - const rawValue = 7; - const value = { - content: { - type: rawValue, - }, - }; - assert.deepEqual(e.changes, { - added: new Set([value]), - deleted: new Set([]), - keys: new Map([[ - 0, - { - action: 'add', - value: rawValue, - }, - ]]), - }); - - numObserves++ - }; - array3.observe(observe2); - - const uint8Array = Z.encodeStateAsUpdate(doc2); - Z.applyUpdate(doc3, uint8Array); - - assert.equal(numObserves, 2); - assert.deepEqual(map3.toJSON(), {key: 'value'}); - assert.deepEqual(array3.toJSON(), [7]); - } - }); - }); - describe('basic transactions', function() { - it('array push', function() { - const doc1 = new Z.Doc(); - const array1 = doc1.getArray('array'); - - const doc2 = new Z.Doc(); - const array2 = doc2.getArray('array'); - - doc1.on('update', (uint8Array, origin, doc, transaction) => { - Z.applyUpdate(doc2, uint8Array, origin); - }); - doc1.transact(() => { - array1.push(['lol']); - }); - assert.deepEqual(array1.toJSON(), ['lol']); - assert.deepEqual(array2.toJSON(), ['lol']); - }); - it('array delete', function() { - const doc1 = new Z.Doc(); - const array1 = doc1.getArray('array'); - - const doc2 = new Z.Doc(); - const array2 = doc2.getArray('array'); - - doc1.on('update', (uint8Array, origin, doc, transaction) => { - Z.applyUpdate(doc2, uint8Array, origin); - }); - doc1.transact(() => { - array1.push(['lol']); - array1.delete(0); - }); - assert.deepEqual(array1.toJSON(), []); - assert.deepEqual(array2.toJSON(), []); - }); - it('map set', function() { - const doc1 = new Z.Doc(); - const map1 = doc1.getMap('map'); - - const doc2 = new Z.Doc(); - const map2 = doc2.getMap('map'); - - doc1.on('update', (uint8Array, origin, doc, transaction) => { - Z.applyUpdate(doc2, uint8Array, origin); - }); - doc1.transact(() => { - map1.set('key', 'value'); - }); - assert.deepEqual(map1.toJSON(), {key: 'value'}); - assert.deepEqual(map2.toJSON(), {key: 'value'}); - }); - it('map delete', function() { - const doc1 = new Z.Doc(); - const map1 = doc1.getMap('map'); - - const doc2 = new Z.Doc(); - const map2 = doc2.getMap('map'); - - doc1.on('update', (uint8Array, origin, doc, transaction) => { - Z.applyUpdate(doc2, uint8Array, origin); - }); - doc1.transact(() => { - map1.set('key', 'value'); - map1.delete('key'); - }); - assert.deepEqual(map1.toJSON(), {}); - assert.deepEqual(map2.toJSON(), {}); - }); - }); - describe('non-conflicting transactions', function() { - const run = forward => function() { - const doc1 = new Z.Doc(); - const array1 = doc1.getArray('array'); - const map1 = doc1.getMap('map'); - - const doc2 = new Z.Doc(); - const array2 = doc2.getArray('array'); - const map2 = doc2.getMap('map'); - - const doc3 = new Z.Doc(); - doc3.setMirror(true); - const array3 = doc3.getArray('array'); - const map3 = doc3.getMap('map'); - - let doc1Update; - doc1.on('update', (uint8Array, origin, doc, transaction) => { - if (origin === 'doc1') { - doc1Update = uint8Array; - } - }); - let doc2Update; - doc2.on('update', (uint8Array, origin, doc, transaction) => { - if (origin === 'doc2') { - doc2Update = uint8Array; - } - }); - doc3.on('update', (uint8Array, origin, doc, transaction) => { - if (origin === 'doc1') { - Z.applyUpdate(doc2, uint8Array, origin); - } else if (origin === 'doc2') { - Z.applyUpdate(doc1, uint8Array, origin); - } - }); - - doc1.transact(() => { - array1.push(['lol']); - }, 'doc1'); - doc2.transact(() => { - map2.set('lol', 'zol'); - }, 'doc2'); - - let fns = [ - () => { - Z.applyUpdate(doc3, doc1Update, 'doc1'); - }, - () => { - Z.applyUpdate(doc3, doc2Update, 'doc2'); - }, - ]; - if (!forward) { - fns = fns.reverse(); - } - for (const fn of fns) { - fn(); - } - - assert.deepEqual(array3.toJSON(), ['lol']); - assert.deepEqual(map3.toJSON(), {lol: 'zol'}); - assert.deepEqual(array1.toJSON(), ['lol']); - assert.deepEqual(map1.toJSON(), {lol: 'zol'}); - assert.deepEqual(array2.toJSON(), ['lol']); - assert.deepEqual(map2.toJSON(), {lol: 'zol'}); - - assert.equal(doc1.clock, 2); - assert.equal(doc2.clock, 2); - assert.equal(doc3.clock, 2); - } - it('array + map', run(true)); - it('array + map reverse', run(false)); - }); - describe('conflicting transactions', function() { - { - const run = forward => function() { - const doc1 = new Z.Doc(); - doc1.setResolvePriority(1); - const array1 = doc1.getArray('array'); - const map1 = doc1.getMap('map'); - - const doc2 = new Z.Doc(); - doc2.setResolvePriority(1); - const array2 = doc2.getArray('array'); - const map2 = doc2.getMap('map'); - - const doc3 = new Z.Doc(); - doc3.setResolvePriority(0); - const array3 = doc3.getArray('array'); - const map3 = doc3.getMap('map'); - - // initialize - { - array1.push([1]); - const uint8Array = Z.encodeStateAsUpdate(doc1); - Z.applyUpdate(doc2, uint8Array); - Z.applyUpdate(doc3, uint8Array); - } - - let doc1Update; - doc1.on('update', (uint8Array, origin, doc, transaction) => { - if (origin === 'doc1') { - doc1Update = uint8Array; - } - }); - let doc2Update; - doc2.on('update', (uint8Array, origin, doc, transaction) => { - if (origin === 'doc2') { - doc2Update = uint8Array; - } - }); - - doc1.transact(() => { - array1.push([2]); - }, 'doc1'); - doc2.transact(() => { - array2.delete(0); - }, 'doc2'); - - if (forward) { - Z.applyUpdate(doc3, doc1Update, 'doc1'); - Z.applyUpdate(doc3, doc2Update, 'doc2'); - } else { - Z.applyUpdate(doc3, doc2Update, 'doc2'); - Z.applyUpdate(doc3, doc1Update, 'doc1'); - } - - assert.deepEqual(array3.toJSON(), [2]); - }; - it('conflicting array push delete', run(true)); - it('conflicting array push delete', run(false)); - } - { - const run = forward => function() { - const doc1 = new Z.Doc(); - doc1.setResolvePriority(1); - const array1 = doc1.getArray('array'); - const map1 = doc1.getMap('map'); - - const doc2 = new Z.Doc(); - doc2.setResolvePriority(1); - const array2 = doc2.getArray('array'); - const map2 = doc2.getMap('map'); - - const doc3 = new Z.Doc(); - doc3.setResolvePriority(0); - const array3 = doc3.getArray('array'); - const map3 = doc3.getMap('map'); - - // initialize - { - array1.push([1]); - array1.push([2]); - const uint8Array = Z.encodeStateAsUpdate(doc1); - Z.applyUpdate(doc2, uint8Array); - Z.applyUpdate(doc3, uint8Array); - } - - let doc1Update; - doc1.on('update', (uint8Array, origin, doc, transaction) => { - if (origin === 'doc1') { - doc1Update = uint8Array; - } - }); - let doc2Update; - doc2.on('update', (uint8Array, origin, doc, transaction) => { - if (origin === 'doc2') { - doc2Update = uint8Array; - } - }); - - doc1.transact(() => { - array1.delete(0); - }, 'doc1'); - doc2.transact(() => { - array2.delete(0); - }, 'doc2'); - - if (forward) { - Z.applyUpdate(doc3, doc1Update, 'doc1'); - Z.applyUpdate(doc3, doc2Update, 'doc2'); - } else { - Z.applyUpdate(doc3, doc2Update, 'doc2'); - Z.applyUpdate(doc3, doc1Update, 'doc1'); - } - - assert.deepEqual(array3.toJSON(), [2]); - }; - it('conflicting array delete same', run(true)); - it('conflicting array delete same reverse', run(true)); - } - { - const run = forward => function() { - const doc1 = new Z.Doc(); - doc1.setResolvePriority(1); - const array1 = doc1.getArray('array'); - const map1 = doc1.getMap('map'); - - const doc2 = new Z.Doc(); - doc2.setResolvePriority(1); - const array2 = doc2.getArray('array'); - const map2 = doc2.getMap('map'); - - const doc3 = new Z.Doc(); - doc3.setResolvePriority(0); - const array3 = doc3.getArray('array'); - const map3 = doc3.getMap('map'); - - // initialize - { - array1.push([1]); - array1.push([2]); - array1.push([3]); - const uint8Array = Z.encodeStateAsUpdate(doc1); - Z.applyUpdate(doc2, uint8Array); - Z.applyUpdate(doc3, uint8Array); - } - - let doc1Update; - doc1.on('update', (uint8Array, origin, doc, transaction) => { - if (origin === 'doc1') { - doc1Update = uint8Array; - } - }); - let doc2Update; - doc2.on('update', (uint8Array, origin, doc, transaction) => { - if (origin === 'doc2') { - doc2Update = uint8Array; - } - }); - - doc1.transact(() => { - array1.delete(0); - }, 'doc1'); - doc2.transact(() => { - array2.delete(2); - }, 'doc2'); - - if (forward) { - Z.applyUpdate(doc3, doc1Update, 'doc1'); - Z.applyUpdate(doc3, doc2Update, 'doc2'); - } else { - Z.applyUpdate(doc3, doc2Update, 'doc2'); - Z.applyUpdate(doc3, doc1Update, 'doc1'); - } - - assert.deepEqual(array3.toJSON(), [2]); - }; - it('conflicting array delete different', run(true)); - it('conflicting array delete different reverse', run(false)); - } - { - const run = forward => function() { - const doc1 = new Z.Doc(); - doc1.setResolvePriority(1); - const array1 = doc1.getArray('array'); - - const doc2 = new Z.Doc(); - doc2.setResolvePriority(1); - const array2 = doc2.getArray('array'); - - const doc3 = new Z.Doc(); - doc3.setResolvePriority(0); - const array3 = doc3.getArray('array'); - - const map1 = new Z.Map(); - const map2 = new Z.Map(); - const map3 = new Z.Map(); - - // initialize - { - array1.push([map1]); - array1.push([map2]); - array1.push([map3]); - - map2.set('lol2', 'zol2'); - map3.set('lol3', 'zol3'); - - const uint8Array = Z.encodeStateAsUpdate(doc1); - Z.applyUpdate(doc2, uint8Array); - Z.applyUpdate(doc3, uint8Array); - } - - let doc1Update; - doc1.on('update', (uint8Array, origin, doc, transaction) => { - if (origin === 'doc1') { - doc1Update = uint8Array; - } - }); - let doc2Update; - doc2.on('update', (uint8Array, origin, doc, transaction) => { - if (origin === 'doc2') { - doc2Update = uint8Array; - } - }); - - doc1.transact(() => { - map1.set('lol1', 'zol1'); - }, 'doc1'); - doc2.transact(() => { - array2.delete(0); - }, 'doc2'); - - if (forward){ - Z.applyUpdate(doc3, doc1Update, 'doc1'); - Z.applyUpdate(doc3, doc2Update, 'doc2'); - } else { - Z.applyUpdate(doc3, doc2Update, 'doc2'); - Z.applyUpdate(doc3, doc1Update, 'doc1'); - } - - assert.deepEqual(array3.toJSON(), [ - { - lol2: 'zol2', - }, - { - lol3: 'zol3', - } - ]); - }; - it('conflicting deep array > map', run(true)); - it('conflicting deep array > map reverse', run(false)); - } - { - const run = forward => function() { - const doc1 = new Z.Doc(); - doc1.setResolvePriority(1); - const map1 = doc1.getMap('map'); - - const doc2 = new Z.Doc(); - doc2.setResolvePriority(1); - const map2 = doc2.getMap('map'); - - const doc3 = new Z.Doc(); - doc3.setResolvePriority(0); - const map3 = doc3.getMap('map'); - - const array11 = new Z.Array(); - const array12 = new Z.Array(); - const array13 = new Z.Array(); - - const array21 = new Z.Array(); - const array22 = new Z.Array(); - const array23 = new Z.Array(); - - // initialize - { - map1.set('array1', array11); - map1.set('array2', array12); - map1.set('array3', array13); - - map2.set('array1', array21); - map2.set('array2', array22); - map2.set('array3', array23); - - array11.push([1]); - array11.push([2]); - array11.push([3]); - - array12.push([4]); - array12.push([5]); - array12.push([6]); - - array13.push([7]); - array13.push([8]); - array13.push([9]); - - const uint8Array = Z.encodeStateAsUpdate(doc1); - Z.applyUpdate(doc2, uint8Array); - Z.applyUpdate(doc3, uint8Array); - } - - let doc1Update; - doc1.on('update', (uint8Array, origin, doc, transaction) => { - if (origin === 'doc1') { - doc1Update = uint8Array; - } - }); - let doc2Update; - doc2.on('update', (uint8Array, origin, doc, transaction) => { - if (origin === 'doc2') { - doc2Update = uint8Array; - } - }); - - doc1.transact(() => { - map1.set('array1', 42); - map1.set('array1', 20); - map1.delete('array1'); - map1.set('array1', null); - }, 'doc1'); - doc2.transact(() => { - array21.delete(0); - array21.push([100]); - array21.delete(2); - array21.push([100]); - array21.push([101]); - array21.delete(0); - }, 'doc2'); - - if (forward) { - Z.applyUpdate(doc3, doc1Update, 'doc1'); - Z.applyUpdate(doc3, doc2Update, 'doc2'); - } else { - Z.applyUpdate(doc3, doc2Update, 'doc2'); - Z.applyUpdate(doc3, doc1Update, 'doc1'); - } - - { - const map3 = doc3.getMap('map'); - const array31 = map3.get('array1'); - const array32 = map3.get('array2', Z.Array); - const array33 = map3.get('array3', Z.Array); - } - - assert.deepEqual(doc3.toJSON(), { - map: { - array1: null, - array2: [4, 5, 6], - array3: [7, 8, 9], - }, - }); - }; - it('conflicting deep map > array', run(true)); - it('conflicting deep map > array reverse', run(false)); - } - }); -}); -describe('stress test', function() { - const _makeId = () => rng().toString(36).substr(2, 5); - const _makeDataView = uint8Array => new DataView(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength); - const MESSAGES = (() => { - let iota = 0; - return { - STATE_RESET: ++iota, - TRANSACTION: ++iota, - }; - })(); - const _parsePacketData = uint8Array =>{ - const dataView = _makeDataView(uint8Array); - - let index = 0; - const method = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const _handleStateMessage = () => { - const clock = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const encodedData = new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index); - const state = Z.zbdecode(encodedData); - return { - clock, - state, - }; - }; - const _handleTransactionMessage = () => { - let transactionCache = Z.TransactionCache.deserializeUpdate(uint8Array); - const events = transactionCache.events.map(event => { - return { - name: event.constructor.name, - keyPath: JSON.stringify(event.keyPath), - keyTypes: event.keyTypes, - arr: event.arr, - startClock: transactionCache.startClock, - }; - }); - return events; - }; - switch (method) { - case MESSAGES.STATE_RESET: { - return _handleStateMessage(); - } - case MESSAGES.TRANSACTION: { - return _handleTransactionMessage(); - } - default: { - console.warn('unknown method:', method); - return null; - } - } - }; - const _parsePacket = packet => { - const uint8Array = packet.data; - return _parsePacketData(uint8Array); - }; - - const appId = _makeId(); - - class Simulation { - constructor(server, clients = []) { - if (server === undefined) { - server = new ServerWorldView(); - server.bind(); - } - - this.server = server; - this.clients = clients; - } - update() { - // add client - { - const r = rng(); - if (r < 0.25) { - const client = new ClientWorldView(); - - const _packet = packet => { - client.removeEventListener('packet', _packet); - client.bind(); - }; - client.addEventListener('packet', _packet); - - const pipe = this.server.pipe(client); - client.pipe(this.server); - - this.server.emitInitialPacket(pipe); - - this.clients.push(client); - } - } - // remove client - { - const r = rng(); - if (r < 0.2) { - if (this.clients.length > 0) { - const index = Math.floor(rng() * this.clients.length); - const client = this.clients[index]; - - this.server.unpipe(client); - client.unpipe(this.server); - this.clients.splice(index, 1); - - this.server.clearPlayer(client.playerId); - } - } - } - // tick all clients - { - for (const client of this.clients) { - client.update(); - } - } - // tick server - { - this.server.update(); - } - } - clone() { - const server = this.server.clone(); - const clients = this.clients.map(client => client.clone()); - for (let i = 0; i < clients.length; i++) { - const serverToOldClientPipe = server.pipes.find(pipe => pipe.destination === this.clients[i]); - serverToOldClientPipe.destination = clients[i]; - - const clientToOldServerPipe = clients[i].pipes.find(pipe => pipe.destination === this.server); - clientToOldServerPipe.destination = server; - } - - return new Simulation( - server, - clients - ); - } - flush() { - const _flushClients = () => { - for (const client of this.clients) { - client.flush(); - } - }; - const _flushServer = () => { - this.server.flush(); - }; - - _flushClients(); - _flushServer(); - _flushClients(); - } - verify() { - const serverWorldAppManagerAppArray = this.server.doc.getArray('world.apps'); - const serverPlayersArray = this.server.doc.getArray('players'); - const serverPlayersArray2 = Array(serverPlayersArray.length); - for (let i = 0; i < serverPlayersArray.length; i++) { - serverPlayersArray2[i] = serverPlayersArray.get(i, Z.Map); - } - const serverPlayersMap = new Map(serverPlayersArray2.map(player => { - return [ - player.get('playerId'), - player.toJSON(), - ]; - })); - - for (const client of this.clients) { - const clientWorldAppManagerAppArray = client.doc.getArray('world.apps'); - const clientPlayersArray = client.doc.getArray('players'); - const clientPlayersArray2 = Array(clientPlayersArray.length); - for (let i = 0; i < clientPlayersArray.length; i++) { - clientPlayersArray2[i] = clientPlayersArray.get(i, Z.Map); - } - const clientPlayersMap = new Map(clientPlayersArray2.map(player => { - return [ - player.get('playerId'), - player.toJSON(), - ]; - })); - - assert.deepEqual(clientWorldAppManagerAppArray.toJSON(), serverWorldAppManagerAppArray.toJSON()); - assert.deepEqual(serverPlayersMap, clientPlayersMap); - } - } - } - class AppManager { - constructor(appId, appsArray) { - this.appId = appId; - this.appsArray = appsArray; - } - update() { - const r = rng(); - if (r < 0.25) { // perform app action - // find existing app - let appMap = (() => { - for (let i = 0; i < this.appsArray.length; i++) { - const appMap = this.appsArray.get(i, Z.Map); - if (appMap.get('appId') === this.appId) { - return appMap; - } - } - return null; - })(); - // ensure app is added - if (!appMap) { - appMap = new Z.Map(); - appMap.set('appId', this.appId); - this.appsArray.push([appMap]); - } - } - } - } - class PacketQueueEntry { - constructor(data, delay, origin) { - this.data = data; - this.delay = delay; - this.origin = origin; - } - clone() { - return new PacketQueueEntry(this.data, this.delay, this.origin); - } - } - class Pipe { - constructor(destination, outPacketQueue = []) { - this.destination = destination; - this.outPacketQueue = outPacketQueue; - } - pushPacket(data, origin) { - const delay = Math.round(rng() * 2); - const packet = new PacketQueueEntry(data, delay, origin); - this.outPacketQueue.push(packet); - } - clone() { - const pipe = new Pipe( - this.destination, - this.outPacketQueue.map(e => e.clone()) - ); - return pipe; - } - } - class WorldView extends EventTarget { - constructor(doc = new Z.Doc()) { - super(); - - this.doc = doc; - this.appManager = null; - this.remotePlayers = []; - this.isBound = false; - - // packet buffer - this.pipes = []; - this.outPacketQueue = []; - - // listen for players - const playersArray = this.getPlayersArray(); - playersArray.observe(e => { - // remove old players - for (const d of e.changes.deleted.values()) { - const { - content: { - type: oldPlayerMap, - }, - } = d; - const playerId = oldPlayerMap.get('playerId'); - const oldPlayerIndex = this.remotePlayers.findIndex(player => player.playerId === playerId); - if (oldPlayerIndex !== -1) { - const oldPlayer = this.remotePlayers[oldPlayerIndex]; - oldPlayer.destroy(); - this.remotePlayers.splice(oldPlayerIndex, 1); - } else { - throw new Error('delete nonexistent player: ' + playerId); - } - } - - // add new players - for (const a of e.changes.added.values()) { - let { - content: { - type: newPlayerMap, - }, - } = a; - // players in the new state will not be typed if they are not in the old state - // therefore, perform the type binding here - if (!newPlayerMap.isZMap) { - for (let i = 0; i < playersArray.length; i++) { - const playerMap = playersArray.get(i, Z.Map); - if (playerMap.get('playerId') === newPlayerMap.playerId) { - newPlayerMap = playerMap; - break; - } - } - } - const newPlayer = new Player(newPlayerMap); - this.remotePlayers.push(newPlayer); - } - }); - } - getPlayersArray() { - return this.doc.getArray('players'); - } - pipe(packetDestination) { - if (!packetDestination) { - throw new Error('packet destination is null'); - } - const pipe = new Pipe(packetDestination); - this.pipes.push(pipe); - return pipe; - } - unpipe(packetDestination) { - const index = this.pipes.findIndex(pipe => pipe.destination === packetDestination); - if (index !== -1) { - this.pipes.splice(index, 1); - } else { - throw new Error('unpipe nonexistent packet destination'); - } - } - bind(opts) { - this.isBound = true; - } - update() { - if (this.isBound) { - const _tickPackets = () => { - let maxNumDelays = 0; - for (const pipe of this.pipes) { - let numDelays = 0; - for (const packet of pipe.outPacketQueue) { - numDelays += packet.delay; - } - maxNumDelays = Math.max(maxNumDelays, numDelays); - } - - const numTicks = Math.max(Math.floor(rng() * maxNumDelays), 1); - for (let i = 0; i < numTicks; i++) { - for (const pipe of this.pipes) { - // globalThis.maxQueueLength = Math.max(globalThis.maxQueueLength, pipe.outPacketQueue.length); - while (pipe.outPacketQueue.length > 0) { - const packet = pipe.outPacketQueue[0]; - if (packet.delay > 0) { - packet.delay--; - break; - } else { - const packetDestination = pipe.destination; - packetDestination.handlePacket(packet); - pipe.outPacketQueue.shift(); - } - } - } - } - }; - _tickPackets(); - } - } - flush() { - for (const pipe of this.pipes) { - if (pipe.outPacketQueue.length > 0) { - for (const packet of pipe.outPacketQueue) { - const packetDestination = pipe.destination; - packetDestination.handlePacket(packet); - } - pipe.outPacketQueue.length = 0; - } - } - } - handlePacket(packet) { - Z.applyUpdate(this.doc, packet.data, packet.origin, this.playerId); - - this.dispatchEvent(new MessageEvent('packet', { - data: packet, - })); - } - clone() { - const newDoc = this.doc.clone(); - const result = (() => { - if (this instanceof ServerWorldView) { - return new ServerWorldView(newDoc, { - initialize: false, - }); - } else if (this instanceof ClientWorldView) { - return new ClientWorldView(newDoc, { - initialize: false, - }); - } else { - throw new Error('unknown world view type'); - } - })(); - result.playerId = this.playerId; - result.pipes = this.pipes.map(pipe => pipe.clone()); - - const playersArray = newDoc.getArray('players'); - for (let i = 0; i < playersArray.length; i++) { - const playerMap = playersArray.get(i, Z.Map); - const player = new Player(playerMap); - result.remotePlayers.push(player); - } - - if (this.isBound) { - result.bind({ - initialize: false, - }); - } - - return result; - } - } - // let numEmits = 0; - class ServerWorldView extends WorldView { - constructor(doc = new Z.Doc(), {initialize = true} = {}) { - super(doc); - - this.doc.setResolvePriority(0); - this.doc.setMirror(true); - - // listen for server document updates/mirrors - this.doc.on('update', (uint8Array, origin, doc, transaction) => { - for (const pipe of this.pipes) { - if (pipe.destination.playerId !== origin) { // do not mirror recursively - pipe.pushPacket(uint8Array, origin); - } - } - }); - - if (initialize) { - this.playerId = 'server'; - } else { - this.playerId = null; - } - this.appManager = null; - } - bind(opts = {}) { - super.bind(opts); - - const appsArray = this.doc.getArray('world.apps'); - this.appManager = new AppManager(appId, appsArray); - } - emitInitialPacket(pipe) { - const uint8Array = Z.encodeStateAsUpdate(this.doc); - pipe.pushPacket(uint8Array); - } - update() { - super.update(); - } - clearPlayer(playerId) { - const playerIndex = this.remotePlayers.findIndex(player => player.playerId === playerId); - if (playerIndex !== -1) { - const playersArray = this.getPlayersArray(); - /* const playerMap = playersArray.get(playerIndex, Z.Map); - if (playerMap.get('playerId') !== playerId) { - console.warn('deleting the wrong player id', playerId, playerMap.get('playerId')); - throw new Error('fail'); - } */ - playersArray.delete(playerIndex); - } /* else { - throw new Error('failed to clear player: ' + playerId); - } */ - } - } - class ClientWorldView extends WorldView { - constructor(doc = new Z.Doc(), {initialize = true} = {}) { - super(doc); - - this.doc.setResolvePriority(1); - - // listen for client document updates - this.doc.on('update', (uint8Array, origin, doc, transaction) => { - for (const pipe of this.pipes) { - pipe.pushPacket(uint8Array, this.playerId); - } - }); - - if (initialize) { - this.playerId = 'player.' + _makeId(); - } else { - this.playerId = null; - } - this.localPlayer = null; - this.appManager = null; - this.worldAppManager = null; - } - bind(opts = {}) { - super.bind(opts); - - const {initialize = true} = opts; - - const playersArray = this.getPlayersArray(); - if (initialize) { - this.doc.transact(() => { - const localPlayerMap = new Z.Map(); - localPlayerMap.set('playerId', this.playerId); - const position = Float32Array.from([rngndc(), rngndc(), rngndc()]); - localPlayerMap.set('position', position); - const appsArray = new Z.Array(); - - localPlayerMap.set('apps', appsArray); - - playersArray.push([localPlayerMap]); - - this.localPlayer = new Player(localPlayerMap); - this.appManager = new AppManager(appId, appsArray); - }); - } else { - let localPlayerMap = (() => { - for (let i = 0; i < playersArray.length; i++) { - const playerMap = playersArray.get(i, Z.Map); - if (playerMap.get('playerId') === this.playerId) { - return playerMap; - } - } - return null; - })(); - if (localPlayerMap) { - const appsArray = localPlayerMap.get('apps', Z.Array); - this.localPlayer = new Player(localPlayerMap); - this.appManager = new AppManager(appId, appsArray); - } else { - throw new Error('could not bind world client'); - } - } - - const worldAppsArray = this.doc.getArray('world.apps'); - this.worldAppManager = new AppManager(appId, worldAppsArray); - } - update() { - const r = rng(); - if (this.isBound) { - if (r < 1/3) { - const newPosition = Float32Array.from([rngndc(), rngndc(), rngndc()]); - this.localPlayer.playerMap.set('position', newPosition); - } - - if (this.appManager.appsArray.doc !== this.doc) { - console.warn('app manager doc mismatch 3'); - process.exit(1); - throw new Error('app manager doc mismatch 3'); - } - this.appManager.update(); - } - - super.update(); - } - } - class Player { - constructor(playerMap) { - this.playerMap = playerMap; - const appsArray = playerMap.get('apps', Z.Array); - this.appManager = new AppManager(appId, appsArray); - } - get playerId() { - return this.playerMap.get('playerId'); - } - set playerId(playerId) { - this.playerMap.set('playerId', playerId); - } - destroy() { - // XXX - } - } - const _check = simulation => { - const simulation2 = simulation.clone(); - simulation2.flush(); - simulation2.verify(); - }; - const _stressTest = (numIterations = 1) => { - const simulation = new Simulation(); - for (let i = 0; i < numIterations; i++) { - // console.log('iteration', i); - simulation.update(); - // console.log('verify', i, simulation.clients.length, globalThis.maxHistoryLength, globalThis.maxHistoryTailLength); - // _check(simulation); - } - _check(simulation); - }; - it('should survive 1000 iterations', /* async */function() { - // await keypress(); - _stressTest(1000); - // await keypress(); - }); -}); \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/util.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/util.mjs deleted file mode 100644 index 086663ba4..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/util.mjs +++ /dev/null @@ -1,10 +0,0 @@ -const alignN = n => index => { - const r = index % n; - return r === 0 ? index : (index + n - r); -}; -const align4 = alignN(4); - -export { - alignN, - align4, -}; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/z.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/z.mjs deleted file mode 100644 index 36ec6f872..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs/z.mjs +++ /dev/null @@ -1,2066 +0,0 @@ -import { - zbencode, - zbdecode, - zbclone, -} from './encoding.mjs'; -import {align4} from './util.mjs'; - -const MESSAGES = (() => { - let iota = 0; - return { - STATE_RESET: ++iota, - TRANSACTION: ++iota, - }; -})(); - -// XXX can use a power-of-two buffer cache for memory - -let rng = Math.random; -function setRng(r) { - rng = r; -} -const _makeId = () => Math.floor(rng() * 0xFFFFFF); -const _jsonify = o => { - const impl = bindingsMap.get(o); - if (impl?.isZArray) { - return o.e.map(_jsonify); - } else if (Array.isArray(o)) { - return o.map(_jsonify); - } else if ( - o instanceof Uint8Array || - o instanceof Uint16Array || - o instanceof Uint32Array || - o instanceof Int8Array || - o instanceof Int16Array || - o instanceof Int32Array || - o instanceof Float32Array || - o instanceof Float64Array - ) { - return o; - } else if (o !== null && typeof o === 'object') { - const result = {}; - for (const k in o) { - result[k] = _jsonify(o[k]); - } - return result; - } else { - return o; - } -}; -const _getBindingForValue = e => { - if (e?.isZMap || e?.isZArray) { - return e.binding; - } else { - return e; - } -}; -const _getBindingForArray = arr => arr.map(_getBindingForValue); - -const _makeDataView = uint8Array => new DataView(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength); -const _parseBoundEvent = encodedEventData => { - const dataView = _makeDataView(encodedEventData); - - let index = 0; - const method = dataView.getUint32(index, true); - const Cons = ZEVENT_CONSTRUCTORS[method]; - if (Cons) { - return Cons.deserializeUpdate(encodedEventData); - } else { - console.warn('could not parse bound event due to incorrect method', method, ZEVENT_CONSTRUCTORS); - return null; - } -}; - -const textEncoder = new TextEncoder(); -const textDecoder = new TextDecoder(); -const observersMap = new WeakMap(); -const bindingsMap = new WeakMap(); -const bindingParentsMap = new WeakMap(); - -class ZEventEmitter { - constructor() { - this.listeners = {}; - } - on(k, fn) { - let ls = this.listeners[k]; - if (!ls) { - ls = []; - this.listeners[k] = ls; - } - ls.push(fn); - } - once(k, fn) { - this.on(k, fn); - - const fn2 = () => { - this.off(k, fn); - this.off(k, fn2); - }; - this.on(k, fn2); - } - off(k, fn) { - const ls = this.listeners[k]; - if (ls) { - for (;;) { - const index = ls.indexOf(fn); - if (index !== -1) { - ls.splice(index, 1); - } else { - break; - } - } - } - } - dispatchEvent(k, a, b, c, d) { - const listeners = this.listeners[k]; - if (listeners) { - for (const fn of listeners) { - fn(a, b, c, d); - } - } - } -} - -const conflictSpec = { - weAreHighestPriority: false, -}; -const _uint8ArrayEquals = (a, b) => { - if (a === b) { - return true; - } else if (a.length === b.length) { - for (let i = 0; i < a.length; i++) { - if (a[i] !== b[i]) { - return false; - } - } - return true; - } else { - return false; - } -}; -const _keyPathEquals = _uint8ArrayEquals; -const _uint8ArrayPrefixEquals = (a, b) => { - if (a === b) { - return true; - } else if (a.length < b.length) { - for (let i = 0; i < a.length; i++) { - if (a[i] !== b[i]) { - return false; - } - } - return true; - } else { - return false; - } -}; -const _isKeyPathPrefix = _uint8ArrayPrefixEquals; -const _getHistoryDataView = (historyData, historyOffsets, historyIndex) => { - return new DataView( - historyData.buffer, - historyData.byteOffset + historyOffsets[historyIndex], - ); -}; -const _getHistoryMethod = (historyData, historyOffsets, historyIndex) => { - const dataView = _getHistoryDataView(historyData, historyOffsets, historyIndex); - - let index = 0; - const eventType = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - return eventType; -}; -const _getHistoryResolvePriority = (historyData, historyOffsets, historyIndex) => { - const dataView = _getHistoryDataView(historyData, historyOffsets, historyIndex); - - let index = 0; - // const eventType = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const resolvePriority = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - return resolvePriority; -}; -const _getHistoryKeyPathBuffer = (historyData, historyOffsets, historyIndex) => { - const dataView = _getHistoryDataView(historyData, historyOffsets, historyIndex); - - let index = 0; - // const eventType = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - // const resolvePriority = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const kpjbLength = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - const kpjb = new Uint8Array(dataView.buffer, dataView.byteOffset + index, kpjbLength); - - return kpjb; -}; -const _parentWasSet = (event, historyStartIndex, historyEndIndex, historyData, historyOffsets) => { - for (let i = historyStartIndex; i < historyEndIndex; i++) { - // const e = _parseHistoryBuffer(historyData, historyOffsets, i); - - const historyMethod = _getHistoryMethod(historyData, historyOffsets, i); - if (historyMethod !== ZNullEvent.METHOD) { - const historyKeyPathBuffer = _getHistoryKeyPathBuffer(historyData, historyOffsets, i); - // console.log('check key path', [textDecoder.decode(historyKeyPathBuffer), textDecoder.decode(event.getKeyPathBuffer())]); - if ( // if this is a parent - _isKeyPathPrefix(historyKeyPathBuffer, event.getKeyPathBuffer()) - ) { - // console.log('check prefix yes', historyMethod, [textDecoder.decode(historyKeyPathBuffer), textDecoder.decode(event.getKeyPathBuffer())]); - if ( // if this is an overwrite type - historyMethod === ZMapSetEvent.METHOD || - historyMethod === ZMapDeleteEvent.METHOD || - historyMethod === ZArrayDeleteEvent.METHOD - ) { - return true; - } - } - } - } - return false; -}; -const _getConflicts = (event, historyStartIndex, historyEndIndex, historyData, historyOffsets, resolvePriority, conflictSpec) => { - let conflictFound = false; - conflictSpec.weAreHighestPriority = true; - - for (let i = historyStartIndex; i < historyEndIndex; i++) { - // const e = _parseHistoryBuffer(historyData, historyOffsets, i); - const historyMethod = _getHistoryMethod(historyData, historyOffsets, i); - if ( // if this is an overwrite type - historyMethod === ZMapSetEvent.METHOD || - historyMethod === ZMapDeleteEvent.METHOD - ) { - const historyKeyPathBuffer = _getHistoryKeyPathBuffer(historyData, historyOffsets, i); - if (_keyPathEquals(historyKeyPathBuffer, event.getKeyPathBuffer())) { // if it is the same keypath - conflictFound = true; - - const historyResolvePriority = _getHistoryResolvePriority(historyData, historyOffsets, i); - if (historyResolvePriority > resolvePriority) { - conflictSpec.weAreHighestPriority = false; - break; - } - } - } - } - - return conflictFound; -}; -const _alreadyDeleted = (event, historyStartIndex, historyEndIndex, historyData, historyOffsets) => { - for (let i = historyStartIndex; i < historyEndIndex; i++) { - const historyMethod = _getHistoryMethod(historyData, historyOffsets, i); - if (historyMethod === ZArrayDeleteEvent.METHOD) { - const historyKeyPathBuffer = _getHistoryKeyPathBuffer(historyData, historyOffsets, i); - if (_keyPathEquals(historyKeyPathBuffer, event.getKeyPathBuffer())) { - return true; - } - } - } - return false; -}; - -class TransactionCache { - constructor(doc = null, origin = undefined, startClock = doc.clock, resolvePriority = doc.resolvePriority, events = [], observerEvents = []) { - this.doc = doc; - this.origin = origin; - this.startClock = startClock; - this.resolvePriority = resolvePriority; - this.events = events; - this.observerEvents = observerEvents; - } - pushEvent(event) { - this.events.push(event); - } - pushObserverEvent(impl, e) { - this.observerEvents.push(impl.triggerObservers.bind(impl, e)); - } - triggerObserverEvents() { - for (let i = 0; i < this.observerEvents.length; i++) { - this.observerEvents[i](); - } - } - rebase() { - const historyTailLength = this.doc.clock - this.startClock; - // globalThis.maxHistoryTailLength = Math.max(globalThis.maxHistoryTailLength, historyTailLength); - const historyStartIndex = this.startClock; - const historyEndIndex = this.doc.clock; - const {historyData, historyOffsets} = this.doc; - - for (let i = 0; i < this.events.length; i++) { - const event = this.events[i]; - if (event.isZMapSetEvent || event.isZMapDeleteEvent) { - if (_parentWasSet(event, historyStartIndex, historyEndIndex, historyData, historyOffsets)) { - // console.log('torpedo self due to parent conflict'); - this.events[i] = nullEvent; - } else if (_getConflicts(event, historyStartIndex, historyEndIndex, historyData, historyOffsets, this.resolvePriority, conflictSpec)) { - /* const _isHighestPriority = () => { - return conflicts.every(([p, e]) => { - return this.resolvePriority <= p; - }); - }; */ - - if (conflictSpec.weAreHighestPriority) { - // console.log('survive due to high prio'); - } else { - // console.log('torpedo self due to low prio'); - this.events[i] = nullEvent; - } - } else { - // console.log('no conflicts'); - } - } else if (event.isZArrayPushEvent) { - if (_parentWasSet(event, historyStartIndex, historyEndIndex, historyData, historyOffsets)) { - this.events[i] = nullEvent; - } else { - // console.log('no conflicts'); - } - } else if (event.isZArrayDeleteEvent) { - if ( - _parentWasSet(event, historyStartIndex, historyEndIndex, historyData, historyOffsets) || - _alreadyDeleted(event, historyStartIndex, historyEndIndex, historyData, historyOffsets) - ) { - // console.log('torpedo self due to parent conflict'); - this.events[i] = nullEvent; - } else { - // console.log('no conflicts'); - } - } else if (event.isZNullEvent) { - // console.log('skip null event'); - } else { - console.warn('unknown event type', event); - } - } - this.startClock += historyTailLength; - } - serializeUpdate() { - let totalSize = 0; - totalSize += Uint32Array.BYTES_PER_ELEMENT; // method - totalSize += Uint32Array.BYTES_PER_ELEMENT; // clock - totalSize += Uint32Array.BYTES_PER_ELEMENT; // resolve priority - totalSize += Uint32Array.BYTES_PER_ELEMENT; // num events - const updateByteLengths = this.events.map(event => { - totalSize += Uint32Array.BYTES_PER_ELEMENT; // length - const updateByteLength = event.computeUpdateByteLength(); - totalSize += updateByteLength; - return updateByteLength; - }); - - const ab = new ArrayBuffer(totalSize); - const uint8Array = new Uint8Array(ab); - const dataView = new DataView(ab); - let index = 0; - - dataView.setUint32(index, MESSAGES.TRANSACTION, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - // XXX setBigUint64 - dataView.setUint32(index, this.startClock, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - dataView.setUint32(index, this.resolvePriority, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - dataView.setUint32(index, this.events.length, true); - index += Uint32Array.BYTES_PER_ELEMENT; - for (let i = 0; i < this.events.length; i++) { - const event = this.events[i]; - const updateByteLength = updateByteLengths[i]; - - dataView.setUint32(index, updateByteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; // length - - event.serializeUpdate(new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index, updateByteLength)); - index += updateByteLength; - } - return uint8Array; - } - static deserializeUpdate(uint8Array) { - const dataView = _makeDataView(uint8Array); - - let index = 0; - // skip method - index += Uint32Array.BYTES_PER_ELEMENT; - - const startClock = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const resolvePriority = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const numEvents = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - const events = Array(numEvents); - for (let i = 0; i < numEvents; i++) { - const eventLength = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const encodedEventData = new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index, eventLength); - const event = _parseBoundEvent(encodedEventData); - events[i] = event; - index += eventLength; - index = align4(index); - } - - const transactionCache = new TransactionCache(undefined, undefined, startClock, resolvePriority, events); - return transactionCache; - } -} - -const HISTORY_DATA_SIZE = 1024 * 1024; // 1 MB -const HISTORY_LENGTH = 1024; -class ZDoc extends ZEventEmitter { - constructor( - state = {}, - clock = 0, - historyData = new Uint8Array(HISTORY_DATA_SIZE), - historyOffsets = new Uint32Array(HISTORY_LENGTH), - ) { - super(); - - this.state = state; - this.clock = clock; - - this.historyData = historyData; - this.historyOffsets = historyOffsets; - - this.transactionDepth = 0; - this.transactionCache = null; - this.resolvePriority = _makeId(); - this.mirror = false; - - this.isZDoc = true; - - bindingsMap.set(this.state, this); - } - get(k, Type) { - let binding = this.state[k]; - if (binding === undefined) { - binding = Type.nativeConstructor(); - this.state[k] = binding; - } - let impl = bindingsMap.get(binding); - if (!impl) { - impl = new Type(binding, this); - bindingsMap.set(binding, impl); - bindingParentsMap.set(binding, this.state); - } - return impl; - } - getArray(k) { - return this.get(k, ZArray); - } - getMap(k) { - return this.get(k, ZMap); - } - transact(fn, origin) { - this.pushTransaction(origin); - fn(); - this.popTransaction(); - } - setResolvePriority(resolvePriority) { - this.resolvePriority = resolvePriority; - } - setMirror(mirror) { - this.mirror = mirror; - } - toJSON() { - return _jsonify(this.state); - } - pushHistory(resolvePriority, event) { - let byteOffset = this.historyOffsets[this.clock % this.historyOffsets.length]; - if (byteOffset >= this.historyData.byteLength / 2) { - // console.log('truncate history'); - byteOffset = 0; - } - const eventTargetBuffer = new Uint8Array( - this.historyData.buffer, - this.historyData.byteOffset + byteOffset, - ); - const eventByteLength = event.serializeHistory(resolvePriority, eventTargetBuffer); - - this.clock++; - this.historyOffsets[this.clock % this.historyOffsets.length] = byteOffset + eventByteLength; - - // globalThis.maxHistoryLength = Math.max(globalThis.maxHistoryLength, this.clock); // XXX temp - } - pushTransaction(origin) { - if (++this.transactionDepth === 1) { - this.transactionCache = new TransactionCache(this, origin); - } - } - popTransaction() { - if (--this.transactionDepth === 0) { - // trigger observers - this.transactionCache.triggerObserverEvents(); - - // emit update - const uint8Array = this.transactionCache.serializeUpdate(); - if (uint8Array) { - this.dispatchEvent('update', uint8Array, this.transactionCache.origin, this, null); - } - - // push history - for (const event of this.transactionCache.events) { - this.pushHistory(this.transactionCache.resolvePriority, event); - } - - // clear transaction cache - this.transactionCache = null; - } - } - setClockState(clock, state) { - const observerEvents = []; - - const _emitDeleteEvents = state => { - const _recurse = binding => { - const impl = bindingsMap.get(binding); - - if (impl.isZDoc) { - for (const k in impl.state) { - _recurse(impl.state[k]); - } - } else if (impl.isZArray) { - if (impl.length > 0) { - const indexes = []; - for (let i = 0; i < impl.length; i++) { - indexes.push(i); - } - - const e = { - changes: { - added: new Set([]), - deleted: new Set(indexes), - keys: new Map(indexes.map(index => { - let value = impl.binding.e[index]; - value = bindingsMap.get(value) ?? value; - return [ - index, - { - action: 'delete', - value, - }, - ]; - })), - }, - }; - observerEvents.push([impl, e]); - } - - for (let i = 0; i < impl.binding.length; i++) { - _recurse(impl.binding[i]); - } - } else if (impl.isZMap) { - const keys = Array.from(impl.keys()); - if (keys.length > 0) { - const values = Array.from(impl.values()); - const e = { - changes: { - added: new Set([]), - deleted: new Set(values), - keys: new Map(keys.map((key, index) => { - const value = values[index]; - return [ - key, - { - action: 'delete', - value: value.content.type, - }, - ]; - })), - }, - }; - observerEvents.push([impl, e]); - } - - for (const k in impl.binding) { - _recurse(impl.binding[k]); - } - } else { - // nothing - } - }; - _recurse(state); - }; - const _emitAddEvents = state => { - const _recurse = binding => { - const impl = bindingsMap.get(binding); - - if (impl?.isZDoc) { - for (const k in impl.state) { - _recurse(impl.state[k]); - } - } else if (impl?.isZArray) { - if (impl.length > 0) { - const rawValues = impl.binding.e.map(value => bindingsMap.get(value) ?? value); - const values = rawValues.map(rawValue => { - return { - content: { - type: rawValue, - }, - }; - }); - - const e = { - changes: { - added: new Set(values), - deleted: new Set([]), - keys: new Map(values.map((value, index) => { - const rawValue = rawValues[index]; - return [ - index, - { - action: 'add', - value: rawValue, - }, - ]; - })), - }, - }; - observerEvents.push([impl, e]); - } - - for (let i = 0; i < impl.binding.length; i++) { - _recurse(impl.binding[i]); - } - } else if (impl?.isZMap) { - const keys = Array.from(impl.keys()); - if (keys.length > 0) { - const rawValues = Array.from(impl.values())//.map(value => bindingsMap.get(value) ?? value); - const values = rawValues/*.map(rawValue => { - return { - content: { - type: rawValue, - }, - }; - }); */ - - const e = { - changes: { - added: new Set(values), - deleted: new Set([]), - keys: new Map(keys.map((key, index) => { - const value = values[index]; - return [ - key, - { - action: 'add', - value: value.content.type, - }, - ]; - })), - }, - }; - observerEvents.push([impl, e]); - } - - for (const k in impl.binding) { - _recurse(impl.binding[k]); - } - } else { - // nothing - } - }; - _recurse(state); - }; - const _remapState = (oldState, newState) => { - // remap old impls onto new bindings - const _lookupKeyPath = (binding, keyPath) => { - for (let i = 0; i < keyPath.length; i++) { - const key = keyPath[i]; - if (key in binding) { - binding = binding[key]; - } else { - return undefined; - } - } - return binding; - }; - const _lookupKeyPathParent = (binding, keyPath) => { - for (let i = 0; i < keyPath.length - 1; i++) { - const key = keyPath[i]; - if (key in binding) { - binding = binding[key]; - } else { - return undefined; - } - } - return binding; - }; - const _recurseRemapState = (newBinding, keyPath) => { - const oldBinding = _lookupKeyPath(oldState, keyPath); - const newParent = keyPath.length > 0 ? _lookupKeyPathParent(newState, keyPath) : null; - let oldImpl; - if (oldBinding !== undefined) { - oldImpl = bindingsMap.get(oldBinding); - oldImpl.binding = newBinding; - bindingsMap.set(newBinding, oldImpl); - if (newParent) { - bindingParentsMap.set(newBinding, newParent); - } - } - - if (oldImpl?.isZArray) { - for (let i = 0; i < newBinding.e.length; i++) { - const zid = newBinding.i[i]; - const index = oldBinding.i.indexOf(zid); - _recurseRemapState(newBinding.e[i], keyPath.concat(['e', index])); - } - } else if (Array.isArray(newBinding)) { - for (let i = 0; i < newBinding.length; i++) { - _recurseRemapState(newBinding[i], keyPath.concat([i])); - } - } else if (newBinding !== null && typeof newBinding === 'object') { - for (const k in newBinding) { - _recurseRemapState(newBinding[k], keyPath.concat([k])); - } - } else { - // nothing - } - }; - _recurseRemapState(newState, []); - }; - - _emitDeleteEvents(this.state); - _remapState(this.state, state); - _emitAddEvents(state); - - this.clock = clock; - this.state = state; - // this.historyData = new Uint8Array(HISTORY_DATA_SIZE); - // this.historyOffsets = new Uint32Array(HISTORY_LENGTH); - - for (const [impl, e] of observerEvents) { - impl.triggerObservers(e); - } - } - getImplByKeyPathParent(keyPath, keyTypes) { - let binding = this.state; - let impl = bindingsMap.get(binding); - for (let i = 0; i < keyPath.length - 1; i++) { - const key = keyPath[i]; - const keyType = keyTypes[i]; - - const child = (() => { - switch (keyType) { - case KEY_TYPES.ARRAY: return impl.get(key, ZArray); - case KEY_TYPES.MAP: return impl.get(key, ZMap); - case KEY_TYPES.VALUE: return impl.get(key); - case (KEY_TYPES.ELEMENT|KEY_TYPES.ARRAY): return impl.getId(key, ZArray); - case (KEY_TYPES.ELEMENT|KEY_TYPES.MAP): return impl.getId(key, ZMap); - case (KEY_TYPES.ELEMENT|KEY_TYPES.VALUE): return impl.getId(key); - default: return 'lol'; - } - })(); -`` - /* if (child === 'lol') { - console.warn(`Key path does not exist`, JSON.stringify([keyType, KEY_TYPES.ARRAY]), keyPath, binding.array); - throw new Error(`Key path ${keyPath} ${keyType} ${binding.array} does not exist`); - } */ - - if (child) { - impl = child; - binding = child.binding; - } else { - // console.warn('could not look up key path', [key, type], impl); - return undefined; - } - } - return impl; - } - clone() { - const oldState = this.state; - const newState = zbclone(this.state); - // console.log('old history', this.state, this.history.length, this.history[0]); - const newDoc = new ZDoc( - newState, - this.clock, - this.historyData, - this.historyOffsets, - ); - - // remap old impls onto new bindings - const _recurseDocClone = (oldBinding, newBinding) => { - const oldImpl = bindingsMap.get(oldBinding); - if (oldImpl?.isZDoc) { - for (const k in oldBinding) { - _recurseDocClone(oldBinding[k], newBinding[k]); - bindingParentsMap.set(newBinding[k], newBinding); - } - } else if (oldImpl?.isZArray) { - const newImpl = new ZArray(newBinding, newDoc); - bindingsMap.set(newBinding, newImpl); - - for (let i = 0; i < oldBinding.e.length; i++) { - _recurseDocClone(oldBinding.e[i], newBinding.e[i]); - - const childImpl = bindingsMap.get(newBinding.e[i]); - if (childImpl) { - bindingParentsMap.set(newBinding.e[i], newBinding); - } - } - } else if (oldImpl?.isZMap) { - const newImpl = new ZMap(newBinding, newDoc); - bindingsMap.set(newBinding, newImpl); - - for (const k in oldBinding) { - _recurseDocClone(oldBinding[k], newBinding[k]); - - const childImpl = bindingsMap.get(newBinding[k]); - if (childImpl) { - bindingParentsMap.set(newBinding[k], newBinding); - } - } - } else if (Array.isArray(oldBinding)) { - for (let i = 0; i < oldBinding.length; i++) { - _recurseDocClone(oldBinding[i], newBinding[i]); - } - } else if (oldBinding !== null && typeof oldBinding === 'object') { - for (const k in oldBinding) { - _recurseDocClone(oldBinding[k], newBinding[k]); - } - } else { - // nothing - } - }; - _recurseDocClone(oldState, newState); - - return newDoc; - } -} - -const KEY_TYPES = { - NONE: 0, - ARRAY: 1, - MAP: 2, - VALUE: 4, - ELEMENT: 8, -}; -const _getImplKeyType = impl => { - if (impl?.isZArray) { - return KEY_TYPES.ARRAY; - } else if (impl?.isZMap) { - return KEY_TYPES.MAP; - } else { - return KEY_TYPES.NONE; - } -}; -const _getImplConstructorForKeyType = type => { - if (type & KEY_TYPES.ARRAY) { - return ZArray; - } else if (type & KEY_TYPES.MAP) { - return ZMap; - } else { - return null; - } -}; -class ZObservable { - constructor(binding, doc) { - this.binding = binding; - this.doc = doc; - } - observe(fn) { - let observers = observersMap.get(this); - if (!observers) { - observers = []; - observersMap.set(this, observers); - } - observers.push(fn); - } - unobserve(fn) { - const observers = observersMap.get(this); - if (observers) { - const index = observers.indexOf(fn); - if (index !== -1) { - observers.splice(index, 1); - } - } - } - triggerObservers(e) { - const observers = observersMap.get(this); - if (observers) { - for (const fn of observers) { - fn(e); - } - } - } - getKeyPathSpec() { - const keyPath = []; - const keyTypes = []; - for (let binding = this.binding;;) { - const parentBinding = bindingParentsMap.get(binding); - - if (parentBinding) { - const parentImpl = bindingsMap.get(parentBinding); - if (parentImpl) { - if (parentImpl.isZDoc) { - let key; - for (const k in parentBinding) { - if (parentBinding[k] === binding) { - key = k; - break; - } - } - - const impl = bindingsMap.get(binding); - const keyType = _getImplKeyType(impl); - - keyPath.push(key); - keyTypes.push(keyType); - } else if (parentImpl.isZArray) { - const index = parentImpl.binding.e.indexOf(binding); - const zid = parentImpl.binding.i[index]; - const impl = bindingsMap.get(binding); - const type = (_getImplKeyType(impl) || KEY_TYPES.VALUE) | KEY_TYPES.ELEMENT; - keyPath.push(zid); - keyTypes.push(type); - } else if (parentImpl.isZMap) { - let key; - for (const k in parentBinding) { - if (parentBinding[k] === binding) { - key = k; - break; - } - } - - const impl = bindingsMap.get(binding); - const keyType = _getImplKeyType(impl) || KEY_TYPES.VALUE; - - keyPath.push(key); - keyTypes.push(keyType); - } else { - console.log('failed to find binding getting key path', binding); - } - } - binding = parentBinding; - } else { - break; - } - } - return { - keyPath: keyPath.reverse(), - keyTypes: keyTypes.reverse(), - }; - } - toJSON() { - return this.binding; - } -} - -const _ensureImplBound = (v, parent) => { - const isZArray = v?.isZArray; - const isZMap = v?.isZMap; - if (isZArray || isZMap) { - bindingsMap.set(v.binding, v); - bindingParentsMap.set(v.binding, parent.binding); - v.doc = parent.doc; - - const _recurseChildren = o => { - if (o?.isZMap) { - o.doc = parent.doc; - for (const k in o.binding) { - const impl = bindingsMap.get(o.binding[k]); - if (impl) { - _recurseChildren(impl); - } - } - } - if (o?.isZArray) { - o.doc = parent.doc; - for (const e of o.binding.e) { - const impl = bindingsMap.get(e); - if (impl) { - _recurseChildren(impl); - } - } - } - }; - _recurseChildren(v); - } -}; -class ZMap extends ZObservable { - constructor(binding = ZMap.nativeConstructor(), doc = null) { - super(binding, doc); - - this.isZMap = true; - } - static nativeConstructor = () => ({}); - has(k) { - return k in this.binding; - } - get(k, Type) { - if (Type) { - let binding = this.binding[k]; - if (binding === undefined) { - binding = Type.nativeConstructor(); - this.binding[k] = binding; - // throw new Error('map lookup nonexistent typed element'); - // return undefined; - } - let impl = bindingsMap.get(binding); - if (!impl) { - impl = new Type(binding, this.doc); - bindingsMap.set(binding, impl); - bindingParentsMap.set(binding, this.binding); - } - return impl; - } else { - const v = this.binding[k]; - return bindingsMap.get(v) ?? v; - } - } - set(k, v) { - _ensureImplBound(v, this); - - const {keyPath, keyTypes} = this.getKeyPathSpec(); - const keyType = _getImplKeyType(v) || KEY_TYPES.VALUE; - keyPath.push(k); - keyTypes.push(keyType); - const event = new ZMapSetEvent( - keyPath, - keyTypes, - v - ); - event.bindToImpl(this); - if (this.doc) { - this.doc.pushTransaction(); - this.doc.transactionCache.pushEvent(event); - } - event.apply(); - const e = event.getObserverEvent(); - if (this.doc) { - this.doc.transactionCache.pushObserverEvent(event.impl, e); - this.doc.popTransaction(); - } else { - this.triggerObservers(e); - } - } - delete(k) { - delete this.binding[k]; - const {keyPath, keyTypes} = this.getKeyPathSpec(); - keyPath.push(k); - keyTypes.push(KEY_TYPES.MAP); - const event = new ZMapDeleteEvent( - keyPath, - keyTypes - ); - event.bindToImpl(this); - if (this.doc) { - this.doc.pushTransaction(); - this.doc.transactionCache.pushEvent(event); - } - event.apply(); - const e = event.getObserverEvent(); - if (this.doc) { - this.doc.transactionCache.pushObserverEvent(event.impl, e); - this.doc.popTransaction(); - } else { - this.triggerObservers(e); - } - } - get _map() { // match yjs api - const result = new Map(); - for (const k in this.binding) { - const rawValue = this.binding[k]; - const value = bindingsMap.get(rawValue) ?? rawValue; - result.set(k, { - content: { - arr: [ - value, - ], - }, - }); - } - return result; - } - keys() { - const keys = Object.keys(this.binding); - let i = 0; - const next = () => { - if (i < keys.length) { - const key = keys[i++]; - return { - done: false, - value: key, - }; - } else { - return { - done: true, - value: null, - }; - } - }; - return { - next, - [Symbol.iterator]: () => ({next}), - }; - } - values() { - const keys = Object.keys(this.binding); - let i = 0; - const next = () => { - if (i < keys.length) { - const key = keys[i++]; - const rawValue = this.get(key); - const type = bindingsMap.get(rawValue) ?? rawValue; - const value = { - content: { - type, - }, - }; - return { - done: false, - value, - }; - } else { - return { - done: true, - value: null, - }; - } - }; - return { - next, - [Symbol.iterator]: () => ({next}), - }; - } - entries() { - const keys = Object.keys(this.binding); - let i = 0; - const next = () => { - if (i < keys.length) { - const key = keys[i++]; - const rawValue = this.get(key); - const type = bindingsMap.get(rawValue) ?? rawValue; - const value = { - content: { - type, - }, - }; - return { - done: false, - value: [key, value], - }; - } else { - return { - done: true, - value: null, - }; - } - }; - return { - next, - [Symbol.iterator]: () => ({next}), - }; - } -} - -class ZArray extends ZObservable { - constructor(binding = ZArray.nativeConstructor(), doc = null) { - super(binding, doc); - - this.isZArray = true; - } - static nativeConstructor = () => ({ - e: [], - i: [], - }); - get length() { - return this.binding.e.length; - } - set length(length) { - throw new Error('ZArray.length is read-only'); - /* this.binding.e.length = length; - this.binding.i.length = length; */ - } - get(index, Type) { - if (Type) { - let binding = this.binding.e[index]; - if (binding === undefined) { - // binding = Type.nativeConstructor(); - // this.state[k] = binding; - // throw new Error('array lookup nonexistent typed element'); - return undefined; - } - let impl = bindingsMap.get(binding); - if (!impl) { - impl = new Type(binding, this.doc); - bindingsMap.set(binding, impl); - bindingParentsMap.set(binding, this.binding); - } - return impl; - } else { - const value = this.binding.e[index]; - return bindingsMap.get(value) ?? value; - } - } - getId(zid, Type) { - const index = this.binding.i.indexOf(zid); - if (index !== -1) { - return this.get(index, Type); - } else { - return undefined; - } - } - push(arr) { - if (arr.length !== 1) { - throw new Error('only length 1 is supported'); - } - - for (const e of arr) { - _ensureImplBound(e, this); - } - - const zid = _makeId().toString(16); - - const {keyPath, keyTypes} = this.getKeyPathSpec(); - const impl = bindingsMap.get(arr[0]) ?? arr[0]; - const keyType = (_getImplKeyType(impl) || KEY_TYPES.VALUE) | KEY_TYPES.ELEMENT; - keyPath.push(zid); - keyTypes.push(keyType); - const event = new ZArrayPushEvent( - keyPath, - keyTypes, - arr - ); - event.bindToImpl(this); - if (this.doc) { - this.doc.pushTransaction(); - this.doc.transactionCache.pushEvent(event); - } - event.apply(); - const e = event.getObserverEvent(); - if (this.doc) { - this.doc.transactionCache.pushObserverEvent(event.impl, e); - this.doc.popTransaction(); - } else { - this.triggerObservers(e); - } - } - delete(index, length = 1) { - if (length !== 1) { - throw new Error('only length 1 is supported'); - } - - const zid = this.binding.i[index]; - - const {keyPath, keyTypes} = this.getKeyPathSpec(); - keyPath.push(zid); - keyTypes.push(KEY_TYPES.ELEMENT|KEY_TYPES.VALUE); - const event = new ZArrayDeleteEvent( - keyPath, - keyTypes, - ); - event.bindToImpl(this); - if (this.doc) { - this.doc.pushTransaction(); - this.doc.transactionCache.pushEvent(event); - } - event.apply(); - const e = event.getObserverEvent(); - if (this.doc) { - this.doc.transactionCache.pushObserverEvent(event.impl, e); - this.doc.popTransaction(); - } else { - this.triggerObservers(e); - } - } - forEach(callback, thisArg) { - for (let i = 0; i < this.binding.e.length; i++) { - callback.call(thisArg, this.get(i), i, this); - } - } - toJSON() { - return this.binding.e.map(_jsonify); - } - [Symbol.iterator] = () => { - let i = 0; - return { - next: () => { - if (i < this.length) { - const rawValue = this.get(i++); - const value = bindingsMap.get(rawValue) ?? rawValue; - return { - done: false, - value, - }; - } else { - return { - done: true, - value: null, - }; - } - }, - }; - } -} - -const uint8ArrayBuffer = new Uint8Array(1024); // 1 kb -const _parseKeyPathBuffer = uint8Array => { - const keyPath = []; - let index = 0; - while (index < uint8Array.length) { - const nextNullIndex = uint8Array.indexOf(0, index); - const key = textDecoder.decode(uint8Array.subarray(index, nextNullIndex)); - keyPath.push(key); - index = nextNullIndex + 1; - } - return keyPath; -}; - -let zEventsIota = 0; -class ZEvent { - constructor(keyPath, keyTypes) { - this.keyPath = keyPath; - this.keyTypes = keyTypes; - - this.impl = null; - this.keyPathBuffer = null; - this.keyTypesBuffer = null; - } - bindToDoc(doc) { - if (doc) { - this.impl = doc.getImplByKeyPathParent(this.keyPath, this.keyTypes); - if (!this.impl) { - console.warn('cannot bind impl to key path', doc.state, this.keyPath, this.keyTypes); - throw new Error('cannot bind impl to key path'); - } - } else { - this.impl = null; - } - } - bindToImpl(impl) { - this.impl = impl; - } - getObserverEvent() { - const actionSpec = this.getAction(); - if (actionSpec) { - const value = bindingsMap.get(actionSpec.value) ?? actionSpec.value; - const added = new Set(/add|update/.test(actionSpec.action) ? [{ - content: { - type: value, - }, - }] : []); - const deleted = new Set(actionSpec.action === 'delete' ? [{ - content: { - type: value, - }, - }] : []); - return { - changes: { - added, - deleted, - keys: new Map([[ - actionSpec.key, - { - action: actionSpec.action, - value, - }, - ]]), - }, - }; - } else { - return null; - } - } - getKey() { - return this.keyPath[this.keyPath.length - 1]; - } - getKeyPathBuffer() { - if (this.keyPathBuffer === null) { - let index = 0; - for (let i = 0; i < this.keyPath.length; i++) { - const key = this.keyPath[i]; - const {written} = textEncoder.encodeInto(key, uint8ArrayBuffer.subarray(index)); - index += written; - - uint8ArrayBuffer[index++] = 0; // null separator - } - this.keyPathBuffer = uint8ArrayBuffer.slice(0, index); - } - return this.keyPathBuffer; - } - getKeyTypesBuffer() { - if (this.keyTypesBuffer === null) { - this.keyTypesBuffer = new Uint8Array(this.keyTypes.length); - for (let i = 0; i < this.keyTypes.length; i++) { - this.keyTypesBuffer[i] = this.keyTypes[i]; - } - } - return this.keyTypesBuffer; - } - computeUpdateByteLength() { - throw new Error('not implemented'); - } - serializeUpdate(uint8Array) { - throw new Error('not implemented'); - } - static deserializeUpdate(uint8Array) { - throw new Error('not implemented'); - } - serializeHistory(resolvePriority, uint8Array) { - const dataView = _makeDataView(uint8Array); - - let index = 0; - dataView.setUint32(index, this.constructor.METHOD, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - dataView.setUint32(index, resolvePriority, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const kpjb = this.getKeyPathBuffer(); - dataView.setUint32(index, kpjb.byteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - uint8Array.set(kpjb, index); - index += kpjb.byteLength; - index = align4(index); - - return index; - } - clone() { - const event = new this.constructor(...this.getConstructorArgs()); - event.impl = this.impl; - return event; - } -} -class ZNullEvent extends ZEvent { - constructor() { - super([], []); - - this.isZNullEvent = true; - } - static METHOD = ++zEventsIota; - apply() { - // nothing - } - getConstructorArgs() { - return []; - } - getAction() { - return null; - } - computeUpdateByteLength() { - let totalSize = 0; - totalSize += Uint32Array.BYTES_PER_ELEMENT; // method - - return totalSize; - } - serializeUpdate(uint8Array) { - const dataView = _makeDataView(uint8Array); - - let index = 0; - dataView.setUint32(index, this.constructor.METHOD, true); - index += Uint32Array.BYTES_PER_ELEMENT; - } - static deserializeUpdate(uint8Array) { - return nullEvent; - } -} -class ZMapEvent extends ZEvent { - constructor(keyPath, keyTypes) { - super(keyPath, keyTypes); - - this.key = null; - this.value = null; - this.keyBuffer = null; - this.valueBuffer = null; - - this.isZMapEvent = true; - } - getKeyBuffer() { - if (this.keyBuffer === null) { - this.keyBuffer = textEncoder.encode(this.key); - } - return this.keyBuffer; - } - getValueBuffer() { - if (this.valueBuffer === null) { - this.valueBuffer = zbencode(this.value); - } - return this.valueBuffer; - } -} -class ZArrayEvent extends ZEvent { - constructor(keyPath, keyTypes) { - super(keyPath, keyTypes); - - this.arr = null; - this.arrBuffer = null; - - this.isZArrayEvent = true; - } - getArrBuffer() { - if (this.arrBuffer === null) { - this.arrBuffer = zbencode(this.arr); - } - return this.arrBuffer; - } -} -class ZMapSetEvent extends ZMapEvent { - constructor(keyPath, keyTypes, value) { - super(keyPath, keyTypes); - - this.value = _getBindingForValue(value); - - this.isZMapSetEvent = true; - } - static METHOD = ++zEventsIota; - static Type = ZMap; - apply() { - const key = this.getKey(); - this.impl.binding[key] = this.value; - } - getConstructorArgs() { - return [this.keyPath, this.keyTypes, this.value]; - } - getAction() { - return { - action: 'update', - key: this.getKey(), - value: this.value, - }; - } - computeUpdateByteLength() { - let totalSize = 0; - totalSize += Uint32Array.BYTES_PER_ELEMENT; // method - - totalSize += Uint32Array.BYTES_PER_ELEMENT; // key path length - totalSize += this.getKeyPathBuffer().byteLength; // key path data - totalSize = align4(totalSize); - - totalSize += Uint32Array.BYTES_PER_ELEMENT; // key types length - totalSize += this.getKeyTypesBuffer().byteLength; // key types data - totalSize = align4(totalSize); - - totalSize += Uint32Array.BYTES_PER_ELEMENT; // value length - totalSize += this.getValueBuffer().byteLength; // value data - totalSize = align4(totalSize); - - return totalSize; - } - serializeUpdate(uint8Array) { - const dataView = _makeDataView(uint8Array); - - let index = 0; - dataView.setUint32(index, this.constructor.METHOD, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const kpjb = this.getKeyPathBuffer(); - dataView.setUint32(index, kpjb.byteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - uint8Array.set(kpjb, index); - index += kpjb.byteLength; - index = align4(index); - - const ktjb = this.getKeyTypesBuffer(); - dataView.setUint32(index, ktjb.byteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - uint8Array.set(ktjb, index); - index += ktjb.byteLength; - index = align4(index); - - const vb = this.getValueBuffer(); - dataView.setUint32(index, vb.byteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - uint8Array.set(vb, index); - index += vb.byteLength; - index = align4(index); - } - static deserializeUpdate(uint8Array) { - const dataView = _makeDataView(uint8Array); - - let index = 0; - // skip method - index += Uint32Array.BYTES_PER_ELEMENT; - - const kpjbLength = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - const keyPath = _parseKeyPathBuffer(new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index, kpjbLength)); - index += kpjbLength; - index = align4(index); - - const ktjbLength = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - const keyTypes = Array.from(new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index, ktjbLength)); - index += ktjbLength; - index = align4(index); - - const vbLength = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - const vb = new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index, vbLength); - const value = zbdecode(vb); - index += vbLength; - index = align4(index); - - return new this( - keyPath, - keyTypes, - value - ); - } -} -class ZMapDeleteEvent extends ZMapEvent { - constructor(keyPath, keyTypes, oldValue = null) { - super(keyPath, keyTypes); - - this.oldValue = oldValue; - - this.isZMapDeleteEvent = true; - } - static METHOD = ++zEventsIota; - static Type = ZMap; - apply() { - const key = this.getKey(); - this.oldValue = this.impl.binding[key]; - delete this.impl.binding[key]; - } - getConstructorArgs() { - return [this.keyPath, this.keyTypes, this.oldValue]; - } - getAction() { - return { - action: 'delete', - key: this.getKey(), - value: this.oldValue, - }; - } - computeUpdateByteLength() { - let totalSize = 0; - totalSize += Uint32Array.BYTES_PER_ELEMENT; // method - - totalSize += Uint32Array.BYTES_PER_ELEMENT; // key path length - totalSize += this.getKeyPathBuffer().byteLength; // key path data - totalSize = align4(totalSize); - - totalSize += Uint32Array.BYTES_PER_ELEMENT; // key types length - totalSize += this.getKeyTypesBuffer().byteLength; // key types data - totalSize = align4(totalSize); - - totalSize += Uint32Array.BYTES_PER_ELEMENT; // key length - totalSize += this.getKeyBuffer().byteLength; // key data - totalSize = align4(totalSize); - - return totalSize; - } - serializeUpdate(uint8Array) { - const dataView = _makeDataView(uint8Array); - - let index = 0; - dataView.setUint32(index, this.constructor.METHOD, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const kpjb = this.getKeyPathBuffer(); - dataView.setUint32(index, kpjb.byteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - uint8Array.set(kpjb, index); - index += kpjb.byteLength; - index = align4(index); - - const ktjb = this.getKeyTypesBuffer(); - dataView.setUint32(index, ktjb.byteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - uint8Array.set(ktjb, index); - index += ktjb.byteLength; - index = align4(index); - - const kb = this.getKeyBuffer(); - dataView.setUint32(index, kb.byteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - uint8Array.set(kb, index); - index += kb.byteLength; - index = align4(index); - } - static deserializeUpdate(uint8Array) { - const dataView = _makeDataView(uint8Array); - - let index = 0; - // skip method - index += Uint32Array.BYTES_PER_ELEMENT; - - const kpjbLength = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - const keyPath = _parseKeyPathBuffer(new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index, kpjbLength)); - index += kpjbLength; - index = align4(index); - - const ktjbLength = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - const keyTypes = Array.from(new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index, ktjbLength)); - index += ktjbLength; - index = align4(index); - - const kbLength = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - const kb = new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index, kbLength); - const key = textDecoder.decode(kb); - index += kbLength; - index = align4(index); - - return new this( - keyPath, - keyTypes, - key - ); - } -} -class ZArrayPushEvent extends ZArrayEvent { - constructor(keyPath, keyTypes, arr) { - super(keyPath, keyTypes); - - this.arr = _getBindingForArray(arr); - this.index = -1; - - this.isZArrayPushEvent = true; - } - static METHOD = ++zEventsIota; - static Type = ZArray; - apply() { - const arrBinding = this.arr; - this.index = this.impl.binding.e.length; - this.impl.binding.e.push.apply(this.impl.binding.e, arrBinding); - const zid = this.keyPath[this.keyPath.length - 1]; - this.impl.binding.i.push(zid); - - const keyType = this.keyTypes[this.keyTypes.length - 1]; - const Type = _getImplConstructorForKeyType(keyType); - const value = this.arr[0]; - let impl = bindingsMap.get(value); - if (Type && !(impl instanceof Type)) { - const binding = value; - impl = new Type(binding, this.impl.doc); - bindingsMap.set(binding, impl); - bindingParentsMap.set(binding, this.impl.binding); - // console.log('forge array value during apply', binding, impl); - } - } - getConstructorArgs() { - return [this.keyPath, this.keyTypes, this.arr]; - } - getAction() { - const keyType = this.keyTypes[this.keyTypes.length - 1]; - const Type = _getImplConstructorForKeyType(keyType); - const value = this.arr[0]; - let impl = bindingsMap.get(value); - if (Type && !(impl instanceof Type)) { - const binding = value; - impl = new Type(binding, this.impl.doc); - bindingsMap.set(binding, impl); - bindingParentsMap.set(binding, this.impl.binding); - // console.log('forge array value during change event emit', binding, impl); - } - - return { - action: 'add', - key: this.index, - value: this.arr[0], - }; - } - computeUpdateByteLength() { - let totalSize = 0; - totalSize += Uint32Array.BYTES_PER_ELEMENT; // method - - totalSize += Uint32Array.BYTES_PER_ELEMENT; // key path length - totalSize += this.getKeyPathBuffer().byteLength; // key path data - totalSize = align4(totalSize); - - totalSize += Uint32Array.BYTES_PER_ELEMENT; // key types length - totalSize += this.getKeyTypesBuffer().byteLength; // key types data - totalSize = align4(totalSize); - - totalSize += Uint32Array.BYTES_PER_ELEMENT; // arr length - totalSize += this.getArrBuffer().byteLength; // arr data - totalSize = align4(totalSize); - - return totalSize; - } - serializeUpdate(uint8Array) { - const dataView = _makeDataView(uint8Array); - - let index = 0; - dataView.setUint32(index, this.constructor.METHOD, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const kpjb = this.getKeyPathBuffer(); - dataView.setUint32(index, kpjb.byteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - uint8Array.set(kpjb, index); - index += kpjb.byteLength; - index = align4(index); - - const ktjb = this.getKeyTypesBuffer(); - dataView.setUint32(index, ktjb.byteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - uint8Array.set(ktjb, index); - index += ktjb.byteLength; - index = align4(index); - - const arrb = this.getArrBuffer(); - dataView.setUint32(index, arrb.byteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - uint8Array.set(arrb, index); - index += arrb.byteLength; - index = align4(index); - } - static deserializeUpdate(uint8Array) { - const dataView = _makeDataView(uint8Array); - - let index = 0; - // skip method - index += Uint32Array.BYTES_PER_ELEMENT; - - const kpjbLength = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - const keyPath = _parseKeyPathBuffer(new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index, kpjbLength)); - index += kpjbLength; - index = align4(index); - - const ktjbLength = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - const keyTypes = Array.from(new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index, ktjbLength)); - index += ktjbLength; - index = align4(index); - - const arrLength = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const arrb = new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index, arrLength); - const arr = zbdecode(arrb); - index += arrLength; - index = align4(index); - - return new this( - keyPath, - keyTypes, - arr - ); - } -} -class ZArrayDeleteEvent extends ZArrayEvent { - constructor(keyPath, keyTypes) { - super(keyPath, keyTypes); - - this.index = -1; - this.oldValue = null; - - this.isZArrayDeleteEvent = true; - } - static METHOD = ++zEventsIota; - static Type = ZArray; - apply() { - const zid = this.keyPath[this.keyPath.length - 1]; - this.index = this.impl.binding.i.indexOf(zid); - this.oldValue = this.impl.binding.e.splice(this.index, 1)[0]; - this.impl.binding.i.splice(this.index, 1); - } - getConstructorArgs() { - return [this.keyPath, this.keyTypes]; - } - getAction() { - return { - action: 'delete', - key: this.index, - value: this.oldValue, - }; - } - computeUpdateByteLength() { - let totalSize = 0; - totalSize += Uint32Array.BYTES_PER_ELEMENT; // method - - totalSize += Uint32Array.BYTES_PER_ELEMENT; // key path length - totalSize += this.getKeyPathBuffer().byteLength; // key path data - totalSize = align4(totalSize); - - totalSize += Uint32Array.BYTES_PER_ELEMENT; // key types length - totalSize += this.getKeyTypesBuffer().byteLength; // key types data - totalSize = align4(totalSize); - - totalSize += Uint32Array.BYTES_PER_ELEMENT; // op index - totalSize += Uint32Array.BYTES_PER_ELEMENT; // op length - - return totalSize; - } - serializeUpdate(uint8Array) { - const dataView = _makeDataView(uint8Array); - - let index = 0; - dataView.setUint32(index, this.constructor.METHOD, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const kpjb = this.getKeyPathBuffer(); - dataView.setUint32(index, kpjb.byteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - uint8Array.set(kpjb, index); - index += kpjb.byteLength; - index = align4(index); - - const ktjb = this.getKeyTypesBuffer(); - dataView.setUint32(index, ktjb.byteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - uint8Array.set(ktjb, index); - index += ktjb.byteLength; - index = align4(index); - } - static deserializeUpdate(uint8Array) { - const dataView = _makeDataView(uint8Array); - - let index = 0; - // skip method - index += Uint32Array.BYTES_PER_ELEMENT; - - const kpjbLength = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - const keyPath = _parseKeyPathBuffer(new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index, kpjbLength)); - index += kpjbLength; - index = align4(index); - - const ktjbLength = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - const keyTypes = Array.from(new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index, ktjbLength)); - index += ktjbLength; - index = align4(index); - - return new this( - keyPath, - keyTypes, - ); - } -} -const ZEVENT_CONSTRUCTORS = [ - null, // start at 1 - ZNullEvent, - ZMapSetEvent, - ZMapDeleteEvent, - ZArrayPushEvent, - ZArrayDeleteEvent, -]; -const nullEvent = new ZNullEvent(); - -// globalThis.maxHistoryLength = 0; -// globalThis.maxHistoryTailLength = 0; -function applyUpdate(doc, uint8Array, transactionOrigin, playerId) { - const dataView = _makeDataView(uint8Array); - - let index = 0; - const method = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const _handleStateMessage = () => { - const clock = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const encodedData = new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index); - const state = zbdecode(encodedData); - doc.setClockState(clock, state); - - if (doc.mirror) { - // console.log('mirror yes'); - doc.dispatchEvent('update', encodedData, transactionOrigin, this, null); - } /* else { - console.log('mirror no'); - } */ - }; - const _handleTransactionMessage = () => { - let transactionCache = TransactionCache.deserializeUpdate(uint8Array); - transactionCache.doc = doc; - transactionCache.origin = transactionOrigin; - - // rebase on top of local history as needed - if (transactionCache.startClock === doc.clock) { - // nothing - } else if (transactionCache.startClock < doc.clock) { - transactionCache.rebase(); - } else { - throw new Error('transaction skipped clock ticks; desynced'); - } - - for (const event of transactionCache.events) { - event.bindToDoc(transactionCache.doc); - event.apply(); - if (event.impl?.isZArray || event.impl?.isZMap) { - transactionCache.pushObserverEvent(event.impl, event.getObserverEvent()); - } - } - - for (const event of transactionCache.events) { - doc.pushHistory(transactionCache.resolvePriority, event); - } - - if (doc.mirror) { - // console.log('mirror yes'); - transactionCache.resolvePriority = doc.resolvePriority; - const uint8Array = transactionCache.serializeUpdate(); - doc.dispatchEvent('update', uint8Array, transactionOrigin, this, null); - } /* else { - console.log('mirror no'); - } */ - transactionCache.triggerObserverEvents(); - }; - switch (method) { - case MESSAGES.STATE_RESET: { - _handleStateMessage(); - break; - } - case MESSAGES.TRANSACTION: { - _handleTransactionMessage(); - break; - } - default: { - console.warn('unknown method:', method); - break; - } - } -} - -function encodeStateAsUpdate(doc) { - const encodedData = zbencode(doc.state); - - const totalSize = - Uint32Array.BYTES_PER_ELEMENT + - Uint32Array.BYTES_PER_ELEMENT + - encodedData.byteLength; - const ab = new ArrayBuffer(totalSize); - const uint8Array = new Uint8Array(ab); - const dataView = new DataView(ab); - - let index = 0; - dataView.setUint32(index, MESSAGES.STATE_RESET, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - dataView.setUint32(index, doc.clock, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - uint8Array.set(new Uint8Array(encodedData.buffer, encodedData.byteOffset, encodedData.byteLength), index); - index += encodedData.byteLength; - - return uint8Array; -} - -export { - ZDoc as Doc, - ZMap as Map, - ZArray as Array, - TransactionCache, - applyUpdate, - encodeStateAsUpdate, - setRng, - zbencode, - zbdecode, -}; - -const Z = { - Doc: ZDoc, - Map: ZMap, - Array: ZArray, - TransactionCache, - applyUpdate, - encodeStateAsUpdate, - setRng, - zbencode, - zbdecode, -}; -export default Z; -/* globalThis.Z = Z; // XXX testing only - -import * as Y from 'yjs'; // XXX testing only -globalThis.Y = Y; */ \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/audio/networked-audio-client-utils.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/audio/networked-audio-client-utils.mjs deleted file mode 100644 index db6bb8f61..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/audio/networked-audio-client-utils.mjs +++ /dev/null @@ -1,9 +0,0 @@ -import {UPDATE_METHODS} from '../update-types.mjs'; - -export const handlesMethod = method => { - return [ - UPDATE_METHODS.AUDIO, - UPDATE_METHODS.AUDIO_START, - UPDATE_METHODS.AUDIO_END, - ].includes(method); -}; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/audio/networked-audio-client.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/audio/networked-audio-client.mjs deleted file mode 100644 index 416c8913a..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/audio/networked-audio-client.mjs +++ /dev/null @@ -1,200 +0,0 @@ -import {UPDATE_METHODS} from '../update-types.mjs'; -import {parseUpdateObject, makeId} from '../util.mjs'; -import {zbencode} from 'zjs'; -import {handlesMethod} from './networked-audio-client-utils.mjs'; - -export class NetworkedAudioClient extends EventTarget { - constructor({ - playerId = makeId(), - }) { - super(); - - this.playerId = playerId; - - this.ws = null; - - this.audioSourceCleanups = new Map(); // playerId:streamId -> function - } - - addAudioSource(playableAudioStream) { - // console.log('add audio source', new Error().stack); - - const { - id, - // output, - type, - disposition, - } = playableAudioStream; - if (typeof id !== 'string') { - throw new Error('audio source id must be a string'); - } - if (typeof type !== 'string') { - throw new Error('audio source type must be a string'); - } - if (typeof disposition !== 'string') { - throw new Error('audio source disposition must be a string'); - } - - // console.log('send start', [ - // this.playerId, - // id, - // type, - // disposition, - // ]); - this.ws.send(zbencode({ - method: UPDATE_METHODS.AUDIO_START, - args: [ - this.playerId, - id, - type, - disposition, - ], - })); - - // pump the reader - let live = true; - const finishPromise = (async () => { - for await (const chunk of playableAudioStream) { - if (live) { - // console.log('send audio', [ - // this.playerId, - // id, - // chunk, - // ]); - this.ws.send(zbencode({ - method: UPDATE_METHODS.AUDIO, - args: [ - this.playerId, - id, - chunk, - ], - })); - } else { - break; - } - } - })(); - - // add the cleanup fn - const cleanup = () => { - live = false; - - // console.log('send audio end', [ - // this.playerId, - // id, - // ]); - this.ws.send(zbencode({ - method: UPDATE_METHODS.AUDIO_END, - args: [ - this.playerId, - id, - ], - })); - }; - this.audioSourceCleanups.set(id, cleanup); - - return { - waitForFinish: () => finishPromise, - }; - } - - removeAudioSource(readableAudioStream) { - // console.log('remove audio source'); - const cleanupFn = this.audioSourceCleanups.get(readableAudioStream.id); - cleanupFn(); - this.audioSourceCleanups.delete(readableAudioStream.id); - } - - async connect(ws) { - this.ws = ws; - - const _waitForOpen = () => new Promise((resolve, reject) => { - resolve = (resolve => () => { - resolve(); - _cleanup(); - })(resolve); - reject = (reject => () => { - reject(); - _cleanup(); - })(reject); - - this.ws.addEventListener('open', resolve); - this.ws.addEventListener('error', reject); - - const _cleanup = () => { - this.ws.removeEventListener('open', resolve); - this.ws.removeEventListener('error', reject); - }; - }); - await _waitForOpen(); - - // console.log('irc listen'); - this.ws.addEventListener('message', e => { - // console.log('got irc data', e.data); - if (e?.data?.byteLength > 0) { - const updateBuffer = e.data; - const uint8Array = new Uint8Array(updateBuffer); - const updateObject = parseUpdateObject(uint8Array); - - const {method /*, args */} = updateObject; - if (handlesMethod(method)) { - this.handleUpdateObject(updateObject); - } - } else { - // debugger; - } - }); - } - - handleUpdateObject(updateObject) { - const {method, args} = updateObject; - // console.log('audio update object', {method, args}); - if (method === UPDATE_METHODS.AUDIO) { - // console.log('got irc chat', {method, args}); - const [ - playerId, - streamId, - data, - ] = args; - - this.dispatchEvent(new MessageEvent('audio', { - data: { - playerId, - streamId, - data, - }, - })); - } else if (method === UPDATE_METHODS.AUDIO_START) { - const [ - playerId, - streamId, - type, - disposition, - ] = args; - - this.dispatchEvent(new MessageEvent('audiostart', { - data: { - playerId, - streamId, - type, - disposition, - }, - })); - } else if (method === UPDATE_METHODS.AUDIO_END) { - const [ - playerId, - streamId, - ] = args; - - this.dispatchEvent(new MessageEvent('audioend', { - data: { - playerId, - streamId, - }, - })); - } else { - console.warn('unhandled audio method: ' + method, updateObject); - throw new Error('unhandled audio method: ' + method); - } - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/audio/ws-util.js b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/audio/ws-util.js deleted file mode 100644 index afca6e67d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/audio/ws-util.js +++ /dev/null @@ -1,198 +0,0 @@ -import {TYPE} from './ws-constants.js'; - -const textEncoder = new TextEncoder(); -const textDecoder = new TextDecoder(); -const encodedMessageUint8Array = new Uint8Array(32 * 1024); -const encodedMessageDataView = new DataView(encodedMessageUint8Array.buffer, encodedMessageUint8Array.byteOffset); -export const encodeMessage = parts => { - let index = 0; - for (const part of parts) { - if (typeof part === 'number') { - encodedMessageDataView.setUint32(index, part, true); - index += Uint32Array.BYTES_PER_ELEMENT; - } else if (typeof part === 'string') { - const {written} = textEncoder.encodeInto(part, new Uint8Array(encodedMessageUint8Array.buffer, encodedMessageUint8Array.byteOffset + index + Uint32Array.BYTES_PER_ELEMENT)); - encodedMessageDataView.setUint32(index, written, true); - index += Uint32Array.BYTES_PER_ELEMENT; - index += written; - } else if (part.byteLength >= 0) { - if (!part.staticSize) { - encodedMessageDataView.setUint32(index, part.byteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - } - encodedMessageUint8Array.set(new Uint8Array(part.buffer, part.byteOffset, part.byteLength), index); - index += part.byteLength; - } else { - throw new Error('unknown part: ' + JSON.stringify(part)); - } - } - return new Uint8Array(encodedMessageUint8Array.buffer, encodedMessageUint8Array.byteOffset, index); -}; -export const encodeAudioMessage = (method, id, type, timestamp, data) => { - let index = 0; - encodedMessageDataView.setUint32(index, method, true); - index += Uint32Array.BYTES_PER_ELEMENT; - encodedMessageDataView.setUint32(index, id, true); - index += Uint32Array.BYTES_PER_ELEMENT; - encodedMessageDataView.setUint32(index, type === 'key' ? 0 : 1, true); - index += Uint32Array.BYTES_PER_ELEMENT; - encodedMessageDataView.setFloat32(index, timestamp, true); - index += Float32Array.BYTES_PER_ELEMENT; - encodedMessageDataView.setUint32(index, data.byteLength, true); - index += Uint32Array.BYTES_PER_ELEMENT; - encodedMessageUint8Array.set(data, index); - index += data.byteLength; - return new Uint8Array(encodedMessageUint8Array.buffer, encodedMessageUint8Array.byteOffset, index); -}; -export const encodePoseMessage = (method, id, p, q, s, extraUint8ArrayFull, extraUint8ArrayByteLength) => { - let index = 0; - - encodedMessageDataView.setUint32(index, method, true); - index += Uint32Array.BYTES_PER_ELEMENT; - encodedMessageDataView.setUint32(index, id, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - encodedMessageUint8Array.set(new Uint8Array(p.buffer, p.byteOffset, p.byteLength), index); - index += p.byteLength; - encodedMessageUint8Array.set(new Uint8Array(q.buffer, q.byteOffset, q.byteLength), index); - index += q.byteLength; - encodedMessageUint8Array.set(new Uint8Array(s.buffer, s.byteOffset, s.byteLength), index); - index += s.byteLength; - - encodedMessageUint8Array.set(new Uint8Array(extraUint8ArrayFull.buffer, extraUint8ArrayFull.byteOffset, extraUint8ArrayByteLength), index); - index += extraUint8ArrayByteLength; - - return new Uint8Array(encodedMessageUint8Array.buffer, encodedMessageUint8Array.byteOffset, index); -}; -const _align = (index, n) => index + (n - (index % n)); -const _align4 = index => _align(index, 4); -export const encodeTypedMessage = (uint8Array, parts) => { - const dataView = new DataView(uint8Array.buffer, uint8Array.byteOffset); - - let index = 0; - for (const part of parts) { - if (typeof part === 'number') { - if (Number.isInteger(part)) { - dataView.setUint32(index, TYPE.INT, true); - index += Uint32Array.BYTES_PER_ELEMENT; - dataView.setUint32(index, part, true) - index += Uint32Array.BYTES_PER_ELEMENT; - } else { - dataView.setUint32(index, TYPE.FLOAT, true); - index += Uint32Array.BYTES_PER_ELEMENT; - dataView.setFloat32(index, part, true); - index += Float32Array.BYTES_PER_ELEMENT; - } - } else if (typeof part === 'string') { - dataView.setUint32(index, TYPE.STRING, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const {written} = textEncoder.encodeInto(part, new Uint8Array(uint8Array.buffer, uint8Array.byteOffset + index + Uint32Array.BYTES_PER_ELEMENT)); - dataView.setUint32(index, written, true); - index += Uint32Array.BYTES_PER_ELEMENT; - index += written; - index = _align4(index); - } else if (part instanceof Uint32Array) { - dataView.setUint32(index, TYPE.UINT32ARRAY, true); - index += Uint32Array.BYTES_PER_ELEMENT; - dataView.setUint32(index, part.length, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - uint8Array.set(new Uint8Array(part.buffer, part.byteOffset, part.byteLength), index); - index += part.byteLength; - } else if (part instanceof Float32Array) { - dataView.setUint32(index, TYPE.FLOAT32ARRAY, true); - index += Uint32Array.BYTES_PER_ELEMENT; - dataView.setUint32(index, part.length, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - uint8Array.set(new Uint8Array(part.buffer, part.byteOffset, part.byteLength), index); - index += part.byteLength; - } else if (part instanceof Uint8Array) { - dataView.setUint32(index, TYPE.UINT32ARRAY, true); - index += Uint32Array.BYTES_PER_ELEMENT; - dataView.setUint32(index, part.length, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - uint8Array.set(part, index); - index += part.byteLength; - index = _align4(index); - } else { - throw new Error('unknown part: ' + JSON.stringify(part)); - } - } - return index; -}; -export const decodeTypedMessage = (uint8Array, uint8ArrayByteLength, parts) => { - const dataView = new DataView(uint8Array.buffer, uint8Array.byteOffset); - - parts.length = 0; - for (let index = 0; index < uint8ArrayByteLength;) { - const type = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - switch (type) { - case TYPE.INT: { - const part = dataView.getUint32(index, true); - parts.push(part); - index += Uint32Array.BYTES_PER_ELEMENT; - break; - } - case TYPE.FLOAT: { - const part = dataView.getFloat32(index, true); - parts.push(part); - index += Float32Array.BYTES_PER_ELEMENT; - break; - } - case TYPE.STRING: { - const byteLength = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const part = textDecoder.decode(new Uint8Array(uint8Array.buffer, index, byteLength)); - parts.push(part); - index += byteLength; - index = _align4(index); - break; - } - case TYPE.UINT32ARRAY: { - const length = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const part = new Uint32Array(uint8Array.buffer, index, length); - parts.push(part); - index += part.byteLength; - break; - } - case TYPE.FLOAT32ARRAY: { - const length = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const part = new Float32Array(uint8Array.buffer, index, length); - parts.push(part); - index += part.byteLength; - break; - } - case TYPE.UINT8ARRAY: { - const length = dataView.getUint32(index, true); - index += Uint32Array.BYTES_PER_ELEMENT; - - const part = new Uint8Array(uint8Array.buffer, index, length); - parts.push(part); - index += part.byteLength; - index = _align4(index); - break; - } - default: { - throw new Error('cannot parse message part with type ' + type); - } - } - } -}; -/* // hack to fix toJSON() -export const loadState = state => { - const objects = state.getArray('objects'); - for (let i = 0; i < objects.length; i++) { - const objectId = objects.get(i); - const object = state.getMap('objects.' + objectId); - } -}; */ \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/constants.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/constants.mjs deleted file mode 100644 index 3cc5eff4f..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/constants.mjs +++ /dev/null @@ -1,4 +0,0 @@ -export const frameSize = 64; -export const realmSize = 300; -export const inventoryFrameSize = 30; -export const MULTIPLAYER_PORT = 2222; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/crdt-client.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/crdt-client.mjs deleted file mode 100644 index f1f4d3e59..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/crdt-client.mjs +++ /dev/null @@ -1,133 +0,0 @@ -import * as Y from 'yjs' -import {UPDATE_METHODS} from "./update-types.mjs"; -import { - // createWs, - // makePromise, - // makeId, - parseUpdateObject, - serializeMessage, -} from './util.mjs'; - -export class NetworkedCrdtClient extends EventTarget { - static handlesMethod(method) { - return [UPDATE_METHODS.CRDT_UPDATE].includes(method); - } - - doc = null; - constructor({ - initialUpdate = null, - } = {}) { - super(); - - this.doc = new Y.Doc(); - if (initialUpdate) { - Y.applyUpdateV2(this.doc, initialUpdate, 'constructor'); - } - this.doc.on('updateV2', (update, origin, doc) => { - this.dispatchEvent(new MessageEvent('update', { - data: { - update, - origin, - doc, - }, - })); - }); - } - getDoc() { - return this.doc; - } - update(uint8Array, origin) { - Y.applyUpdateV2(this.doc, uint8Array, origin); - } - getStateAsUpdate() { - return Y.encodeStateAsUpdateV2(this.doc); - } - getInitialUpdateMessage() { - const update = this.getStateAsUpdate(); - return new MessageEvent('crdtUpdate', { - data: { - update, - }, - }); - } - - // client connects to server - async connect(ws) { - const _waitForOpen = async () => { - await new Promise((resolve, reject) => { - resolve = (resolve => () => { - resolve(); - _cleanup(); - })(resolve); - reject = (reject => () => { - reject(); - _cleanup(); - })(reject); - - ws.addEventListener('open', resolve); - ws.addEventListener('error', reject); - - const _cleanup = () => { - ws.removeEventListener('open', resolve); - ws.removeEventListener('error', reject); - }; - }); - }; - const _waitForInitialImport = async () => { - await new Promise((resolve, reject) => { - const initialMessage = e => { - // console.log('got message', e.data); - if (e.data instanceof ArrayBuffer && e.data.byteLength > 0) { - const updateBuffer = e.data; - const uint8Array = new Uint8Array(updateBuffer); - const updateObject = parseUpdateObject(uint8Array); - - const {method, args} = updateObject; - if (method === UPDATE_METHODS.CRDT_UPDATE) { - const [update] = args; - this.update(update); - - resolve(); - - ws.removeEventListener('message', initialMessage); - } - } - }; - ws.addEventListener('message', initialMessage); - }); - }; - await Promise.all([ - _waitForOpen(), - _waitForInitialImport(), - ]); - - // console.log('irc listen'); - ws.addEventListener('message', e => { - // if some other listener hasn't consumed the message already - if (e?.data?.byteLength > 0) { - const updateBuffer = e.data; - // console.log('irc data', e.data); - const uint8Array = new Uint8Array(updateBuffer); - const updateObject = parseUpdateObject(uint8Array); - - const {method, args} = updateObject; - if (method === UPDATE_METHODS.CRDT_UPDATE) { - const [update] = args; - this.update(update); - } - } else { - // debugger; - } - }); - - this.addEventListener('update', e => { - const {update, origin, doc} = e.data; - const m = new MessageEvent('crdtUpdate', { - data: { - update, - }, - }); - ws.send(serializeMessage(m)); - }); - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/data-client.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/data-client.mjs deleted file mode 100644 index be9d95ec3..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/data-client.mjs +++ /dev/null @@ -1,1250 +0,0 @@ -import {zbencode, zbdecode} from 'zjs'; -import {UPDATE_METHODS} from './update-types.mjs'; -import { - parseUpdateObject, - makeId, - serializeMessage, -} from './util.mjs'; - -// - -export const convertValToCrdtVal = val => { - const startEpoch = 0; - const crdtVal = {}; - for (const k in val) { - const v = val[k]; - crdtVal[k] = [startEpoch, v]; - } - return crdtVal; -}; - -export const convertCrdtValToVal = crdtVal => { - const val = {}; - for (const k in crdtVal) { - const [epoch, v] = crdtVal[k]; - val[k] = v; - } - return val; -}; - -export const convertMapToObject = map => { - const o = {}; - for (const [key, val] of map) { - o[key] = val; - } - return o; -}; - -export const convertObjectToMap = map => { - const o = new Map(); - for (const key in map) { - const val = map[key]; - o.set(key, val); - } - return o; -}; - -// - -const _key = (arrayId, arrayIndexId) => `${arrayId}:${arrayIndexId}`; - -export class DCMap extends EventTarget { - constructor(arrayId, arrayIndexId, dataClient) { - super(); - - this.arrayId = arrayId; - this.arrayIndexId = arrayIndexId; - this.dataClient = dataClient; - - this.cleanupFn = null; - } - - key() { - return _key(this.arrayId, this.arrayIndexId); - } - - getRawObject() { - const key = this.key(); - // if (!key) { - // debugger; - // } - const crdtWrap = this.dataClient.crdt.get(key); - // if (!crdtWrap) { - // debugger; - // } - const rawObject = crdtWrap[1]; - return rawObject; - } - - getKeys() { - const rawObject = this.getRawObject(); - return Object.keys(rawObject); - } - - setRawObject(rawObject, epoch) { - const key = this.key(); - const crdtWrap = [ - epoch, - rawObject, - ]; - this.dataClient.crdt.set(key, crdtWrap); - } - - getMapEpoch() { - const key = this.key(); - const crdtWrap = this.dataClient.crdt.get(key); - const epoch = crdtWrap[0]; - return epoch; - } - - toObject() { - const object = this.getRawObject(); - if (object) { - const result = {}; - for (const key in object) { - const [epoch, val] = object[key]; - result[key] = val; - } - return result; - } else { - debugger; - return {}; - } - } - - getKey(key) { - const object = this.getRawObject(); - if (object) { - const valSpec = object[key]; - if (valSpec !== undefined) { - const [epoch, val] = valSpec; - return val; - } else { - return undefined; - } - } else { - return undefined; - } - } - - getKeyEpoch(key) { - const object = this.getRawObject(); - if (object) { - const valSpec = object[key]; - if (valSpec !== undefined) { - const [epoch, val] = valSpec; - return epoch; - } else { - return 0; - } - } else { - return 0; - } - } - - // client - setKeyEpochValue(key, epoch, val) { - const object = this.getRawObject(); - if (!object) { - debugger; - throw new Error('setKeyEpochValue on nonexistent object'); - } - if (object[key]) { // already had key; update - object[key][0] = epoch; - object[key][1] = val; - } else { // did not have key; add - object[key] = [epoch, val]; - } - } - - setKeyValueUpdate(key, val) { - const oldEpoch = this.getKeyEpoch(key); - const newEpoch = oldEpoch + 1; - this.setKeyEpochValue(key, newEpoch, val); - - return new MessageEvent('set.' + this.arrayId + '.' + this.arrayIndexId, { - data: { - key, - epoch: newEpoch, - val, - }, - }); - } - - setKeyEpochValueUpdate(key, epoch, val) { - this.setKeyEpochValue(key, epoch, val); - - return new MessageEvent('set.' + this.arrayId + '.' + this.arrayIndexId, { - data: { - key, - epoch, - val, - }, - }); - } - - removeUpdate() { - const key = this.key(); - this.dataClient.crdt.delete(key); - - const array = this.dataClient.crdt.get(this.arrayId); - if (!array) { - throw new Error('remove from nonexistent array!'); - } - delete array[this.arrayIndexId]; - - return new MessageEvent('remove.' + this.arrayId, { - data: { - arrayIndexId: this.arrayIndexId, // XXX is this needed? - }, - }); - } - - importMapUpdate() { - const map = this; - const {arrayIndexId} = map; - - // convert the current value to JSON - // notice that this loses per-key epoch information - // however, during a migration, the map's overall epoch is increased - // migration conflicts are detected at the map level, not the key level - const crdtVal = map.getRawObject(); - const val = convertCrdtValToVal(crdtVal); - const epoch = map.getMapEpoch() + 1; - - // console.log('export epoch', epoch); - return new MessageEvent('add.' + this.arrayId, { - data: { - arrayIndexId, - map, - val, - epoch, - }, - }); - } - - // server - trySetKeyEpochValue(key, epoch, val) { - let object = this.getRawObject(); - if (!object) { - object = {}; - this.setRawObject(object, 0); - } - - const oldEpoch = object[key] ? object[key][0] : 0; - if (epoch > oldEpoch) { - if (object[key]) { - object[key][0] = epoch; - object[key][1] = val; - } else { - object[key] = [epoch, val]; - } - return undefined; - } else { - return object[key]; - } - } - - listen() { - const setKey = 'set.' + this.arrayId + '.' + this.arrayIndexId; - const setFn = e => { - const {key, epoch, val} = e.data; - this.dispatchEvent(new MessageEvent('update', { - data: { - key, - epoch, - val, - }, - })); - }; - this.dataClient.addEventListener(setKey, setFn); - - const removeKey = 'remove.' + this.arrayId; - const removeFn = e => { - const {arrayIndexId} = e.data; - if (arrayIndexId === this.arrayIndexId) { - this.dispatchEvent(new MessageEvent('remove', { - data: { - arrayIndexId, - }, - })); - } - }; - this.dataClient.addEventListener(removeKey, removeFn); - - /* const importMapKey = 'importMap.' + this.arrayId; - const importMapFn = e => { - const {arrayIndexId} = e.data; - const key = this.getKey(); - const map = this.dataClient.crdt.get(key); - const array = this.dataClient.crdt.get(this.arrayId); - console.log('dc handle import map', {array, map}); - }; - this.dataClient.addEventListener(importMapKey, importMapFn); */ - - // listener - // this.dataClient.arrayMapListeners.set(this.arrayIndexId, this); - - this.cleanupFn = () => { - // console.log('map unlink', setKey); - this.dataClient.removeEventListener(setKey, setFn); - this.dataClient.removeEventListener(removeKey, removeFn); - // this.dataClient.removeEventListener(importMapKey, importMapFn); - - // listener - // this.dataClient.arrayMapListeners.delete(this.arrayIndexId); - }; - } - - unlisten() { - if (this.cleanupFn) { - this.cleanupFn(); - this.cleanupFn = null; - } - } -} - -// - -export class DCArray extends EventTarget { - constructor(arrayId, dataClient) { - super(); - - this.arrayId = arrayId; - this.dataClient = dataClient; - - this.cleanupFn = null; - } - - getKeys() { - const array = this.dataClient.crdt.get(this.arrayId); - if (array) { - return Object.keys(array); - } else { - return []; - } - } - - getMaps() { - const array = this.dataClient.crdt.get(this.arrayId); - if (array) { - return Object.keys(array).map(arrayIndexId => { - return this.getMap(arrayIndexId, { - listen: false, - }); - }); - } else { - return []; - } - } - - getMap(arrayIndexId, {listen = true} = {}) { - const map = new DCMap(this.arrayId, arrayIndexId, this.dataClient); - listen && map.listen(); - return map; - } - - hasKey(key) { - const array = this.dataClient.crdt.get(this.arrayId); - return array ? (array[key] !== undefined) : false; - } - - getIndex(index, opts) { - const array = this.dataClient.crdt.get(this.arrayId); - if (array) { - let i = 0; - for (const k in array) { - if (i === index) { - return this.getMap(k, opts); - } - i++; - } - return undefined; - } else { - return undefined; - } - } - - getSize() { - const array = this.dataClient.crdt.get(this.arrayId); - return array ? Object.keys(array).length : 0; - } - - toArray() { - const array = this.dataClient.crdt.get(this.arrayId); - if (array) { - const arrayMaps = []; - for (const arrayIndexId in array) { - const key = _key(this.arrayId, arrayIndexId); - const crdtWrap = this.dataClient.crdt.get(key); - const crdtVal = crdtWrap[1]; - const val = convertCrdtValToVal(crdtVal); - arrayMaps.push(val); - } - return arrayMaps; - } else { - return []; - } - } - - importArrayUpdates() { - const arrayVal = this.dataClient.crdt.get(this.arrayId); - - const messages = []; - for (const arrayIndexId in arrayVal) { - const map = this.getMap(arrayIndexId, { - listen: false, - }); - const crdtVal = map.getRawObject(); - const val = convertCrdtValToVal(crdtVal); - const epoch = map.getMapEpoch() + 1; - - if (typeof epoch !== 'number') { - debugger; - } - const m = new MessageEvent('add.' + this.arrayId, { - data: { - arrayIndexId, - map, - val, - epoch, - }, - }); - messages.push(m); - } - return messages; - } - - add(val, epoch, opts) { - return this.dataClient.createArrayMapElement(this.arrayId, val, epoch, opts); - } - - addAt(arrayIndexId, val, epoch, opts) { - return this.dataClient.addArrayMapElement(this.arrayId, arrayIndexId, val, epoch, opts); - } - - removeAt(arrayIndexId) { - return this.dataClient.removeArrayMapElement(this.arrayId, arrayIndexId); - } - - listen() { - const _addMap = (arrayIndexId, val) => { - const map = new DCMap(this.arrayId, arrayIndexId, this.dataClient); - this.dispatchEvent(new MessageEvent('add', { - data: { - arrayIndexId, - map, - val, - }, - })); - }; - - const addKey = 'add.' + this.arrayId; - const addFn = e => { - const { - arrayIndexId, - val, - } = e.data; - // console.log('dispatch add', {arrayIndexId, val}); - _addMap(arrayIndexId, val); - }; - this.dataClient.addEventListener(addKey, addFn); - - const removeKey = 'remove.' + this.arrayId; - const removeFn = e => { - const { - arrayIndexId, - } = e.data; - // console.log('dispatch remove', {arrayIndexId}); - this.dispatchEvent(new MessageEvent('remove', { - data: { - arrayIndexId, - }, - })); - }; - this.dataClient.addEventListener(removeKey, removeFn); - this.cleanupFn = () => { - this.dataClient.removeEventListener(addKey, addFn); - this.dataClient.removeEventListener(removeKey, removeFn); - }; - } - - unlisten() { - if (this.cleanupFn) { - this.cleanupFn(); - this.cleanupFn = null; - } - } -} - -// - -export class DataClient extends EventTarget { - constructor({ - crdt = null, - userData = null, - } = {}) { - super(); - - this.crdt = crdt; - this.userData = userData; - } - - // for both client and server - serializeMessage(m) { - const parsedMessage = this.parseMessage(m); - const {type, arrayId, arrayIndexId} = parsedMessage; - switch (type) { - case 'import': { - const {crdtExport} = parsedMessage; - return zbencode({ - method: UPDATE_METHODS.IMPORT, - args: [ - crdtExport, - ], - }); - } - case 'syn': { - const {synId} = parsedMessage; - return zbencode({ - method: UPDATE_METHODS.SYN, - args: [ - synId, - ], - }); - } - case 'synAck': { - const {synId} = parsedMessage; - return zbencode({ - method: UPDATE_METHODS.SYN_ACK, - args: [ - synId, - ], - }); - } - case 'set': { - const {key, epoch, val} = m.data; - return zbencode({ - method: UPDATE_METHODS.SET, - args: [ - arrayId, - arrayIndexId, - key, - epoch, - val, - ], - }); - } - case 'add': { - const {arrayIndexId, val, epoch} = m.data; - if (typeof epoch !== 'number') { - debugger; - } - return zbencode({ - method: UPDATE_METHODS.ADD, - args: [ - arrayId, - arrayIndexId, - val, - epoch, - ], - }); - } - case 'remove': { - const {arrayIndexId} = m.data; - return zbencode({ - method: UPDATE_METHODS.REMOVE, - args: [ - arrayId, - arrayIndexId, - ], - }); - } - case 'removeArray': { - return zbencode({ - method: UPDATE_METHODS.REMOVE_ARRAY, - args: [ - arrayId, - ], - }); - } - case 'rollback': { - const {arrayId, arrayIndexId, key, oldEpoch, oldVal} = m.data; - return zbencode({ - method: UPDATE_METHODS.ROLLBACK, - args: [ - arrayId, - arrayIndexId, - key, - oldEpoch, - oldVal, - ], - }); - } - case 'deadhand': { - // console.log('serialize dead hand'); - const {keys, deadHand} = m.data; - return zbencode({ - method: UPDATE_METHODS.DEAD_HAND, - args: [ - keys, - deadHand, - ], - }); - } - case 'livehand': { - // console.log('serialize live hand'); - const {keys, liveHand} = m.data; - return zbencode({ - method: UPDATE_METHODS.LIVE_HAND, - args: [ - keys, - liveHand, - ], - }); - } - default: { - throw new Error('invalid message type: ' + type); - } - } - } - - getImportMessage() { - const crtdObject = convertMapToObject(this.crdt); - const crdtExport = zbencode(crtdObject); - return new MessageEvent('import', { - data: { - crdtExport, - }, - }); - } - - getSynMessage(synId) { - if (!synId) { - debugger; - } - return new MessageEvent('syn', { - data: { - synId, - }, - }); - } - - getSynAckMessage(synId) { - if (!synId) { - debugger; - } - return new MessageEvent('synAck', { - data: { - synId, - }, - }); - } - - deadHandKeys(keys, deadHand) { - return new MessageEvent('deadhand', { - data: { - keys, - deadHand, - }, - }); - } - - deadHandArrayMap(arrayId, arrayIndexId, deadHand) { - if (typeof arrayIndexId !== 'string') { - debugger; - } - return this.deadHandKeys([arrayId + '.' + arrayIndexId], deadHand); - } - - deadHandArrayMaps(arrayId, arrayIndexId, deadHand) { - return this.deadHandKeys(arrayIndexId.map(arrayIndexId => arrayId + '.' + arrayIndexId), deadHand); - } - - liveHandKeys(keys, liveHand) { - return new MessageEvent('livehand', { - data: { - keys, - liveHand, - }, - }); - } - - liveHandArrayMap(arrayId, arrayIndexId, liveHand) { - return this.liveHandKeys([arrayId + '.' + arrayIndexId], liveHand); - } - - liveHandArrayMaps(arrayId, arrayIndex, liveHand) { - return this.liveHandKeys(arrayIndex.map(arrayIndexId => arrayId + '.' + arrayIndexId), liveHand); - } - - applyUint8Array(uint8Array, opts) { - const updateObject = parseUpdateObject(uint8Array); - return this.applyUpdateObject(updateObject, opts); - } - - applyUpdateObject(updateObject, { - force = false, // force if it's coming from the server - } = {}) { - let rollback = null; - let update = null; - - const {method, args} = updateObject; - switch (method) { - case UPDATE_METHODS.IMPORT: { - const [crdtExport] = args; - this.crdt = convertObjectToMap(zbdecode(crdtExport)); - update = new MessageEvent('import', { - data: { - crdtExport, - }, - }); - break; - } - case UPDATE_METHODS.SET: { - const [arrayId, arrayIndexId, key, epoch, val] = args; - // console.log('apply update', {arrayId, arrayIndexId, key, epoch, val}); - const arrayMap = new DCMap(arrayId, arrayIndexId, this); - let oldObject; - if (force) { - arrayMap.setKeyEpochValue(key, epoch, val); - } else { - oldObject = arrayMap.trySetKeyEpochValue(key, epoch, val); - } - if (oldObject === undefined) { - // accept update - update = new MessageEvent('set.' + arrayId + '.' + arrayIndexId, { - data: { - key, - epoch, - val, - }, - }); - } else { - const [oldEpoch, oldVal] = oldObject; - // reject update and roll back - rollback = new MessageEvent('rollback', { - data: { - arrayId, - arrayIndexId, - key, - oldEpoch, - oldVal, - }, - }); - } - break; - } - case UPDATE_METHODS.ADD: { - const [arrayId, arrayIndexId, val, epoch] = args; - if (typeof epoch !== 'number') { - debugger; - } - - const key = _key(arrayId, arrayIndexId); - if (!this.crdt.has(key)) { - const crdtVal = convertValToCrdtVal(val); - const crdtWrap = [ - epoch, - crdtVal, - ]; - this.crdt.set(key, crdtWrap); - - let array = this.crdt.get(arrayId); - if (!array) { - array = {}; - this.crdt.set(arrayId, array); - } - array[arrayIndexId] = true; - - update = new MessageEvent('add.' + arrayId, { - data: { - // arrayId, - arrayIndexId, - val, - epoch, - }, - }); - } else { - console.warn('multiplayer ignoring existing app add', { - key, - }); - } - // console.log('add event', update); - break; - } - case UPDATE_METHODS.REMOVE: { - const [arrayId, arrayIndexId] = args; - - // remove from array - const array = this.crdt.get(arrayId); - if (!array) { - throw new Error('remove from nonexistent array: ' + arrayId); - } - delete array[arrayIndexId]; - - // remove from array map - const key = _key(arrayId, arrayIndexId); - this.crdt.delete(key); - - update = new MessageEvent('remove.' + arrayId, { - data: { - // arrayId, - arrayIndexId, - }, - }); - break; - } - case UPDATE_METHODS.ROLLBACK: { - const [arrayId, arrayIndexId, key, epoch, val] = args; - const object = this.crdt.get(arrayIndexId); - if (object) { - if (object[key]) { - object[key][0] = epoch; - object[key][1] = val; - } else { - object[key] = [epoch, val]; - } - - update = new MessageEvent('set.' + arrayId + '.' + arrayIndexId, { - data: { - key, - epoch, - val, - }, - }); - } else { - throw new Error('got rollback for nonexistent object: ' + arrayId + ':' + arrayIndexId); - } - - break; - } - case UPDATE_METHODS.DEAD_HAND: { - const [keys, deadHand] = args; - // console.log('handle dead hand', {arrayId, arrayIndexId, deadHand}); - this.dispatchEvent(new MessageEvent('deadhand', { - data: { - keys, - deadHand, - }, - })); - break; - } - case UPDATE_METHODS.LIVE_HAND: { - const [keys, liveHand] = args; - // console.log('handle live hand', {arrayId, arrayIndexId, liveHand}); - this.dispatchEvent(new MessageEvent('livehand', { - data: { - keys, - liveHand, - }, - })); - break; - } - case UPDATE_METHODS.SYN: { - const [synId] = args; - // console.log('got syn', { - // synId, - // }); - update = new MessageEvent('syn', { - data: { - synId, - }, - }); - break; - } - case UPDATE_METHODS.SYN_ACK: { - const [synId] = args; - // console.log('got synAck', { - // synId, - // }); - update = new MessageEvent('synAck', { - data: { - synId, - }, - }); - break; - } - } - return { - rollback, - update, - }; - } - - // for server - parseMessage(m) { - const match = m.type.match(/^set\.(.+?)\.(.+?)$/); - if (match) { - const arrayId = match[1]; - const arrayIndexId = match[2]; - const {key, epoch, val} = m.data; - return { - type: 'set', - arrayId, - arrayIndexId, - key, - epoch, - val, - }; - } else { - const match = m.type.match(/^add\.(.+?)$/); - if (match) { - const arrayId = match[1]; - const {arrayIndexId, val, epoch} = m.data; - if (typeof epoch !== 'number') { - debugger; - } - return { - type: 'add', - arrayId, - arrayIndexId, - val, - epoch, - }; - } else { - const match = m.type.match(/^remove\.(.+?)$/); - if (match) { - const arrayId = match[1]; - const {arrayIndexId} = m.data; - return { - type: 'remove', - arrayId, - arrayIndexId, - }; - } else { - if (m.type === 'rollback') { - const {arrayId, arrayIndexId, key, oldEpoch, oldVal} = m.data; - return { - type: 'rollback', - arrayId, - arrayIndexId, - key, - oldEpoch, - oldVal, - }; - } else if (m.type === 'import') { - return { - type: 'import', - crdtExport: m.data.crdtExport, - }; - } else if (m.type === 'deadhand') { - const {keys, deadHand} = m.data; - return { - type: 'deadhand', - keys, - deadHand, - }; - } else if (m.type === 'livehand') { - const {keys, liveHand} = m.data; - return { - type: 'livehand', - keys, - liveHand, - }; - } else if (m.type === 'syn') { - const {synId} = m.data; - return { - type: 'syn', - synId, - }; - } else if (m.type === 'synAck') { - const {synId} = m.data; - return { - type: 'synAck', - synId, - }; - } else { - throw new Error('unrecognized message type: ' + m.type); - } - } - } - } - } - - getSaveKeys(m) { - const mo = this.parseMessage(m); - const {type, arrayId, arrayIndexId} = mo; - - const saveKeys = []; - const saveKeyFn = name => { - saveKeys.push(name); - }; - - if (type === 'set') { - saveKeyFn(arrayIndexId); - } else if (type === 'add' || type === 'remove') { - saveKeyFn(arrayIndexId); - saveKeyFn(arrayId); - } else if (type === 'removeArray') { - saveKeyFn(arrayId); - } else if (type === 'rollback') { - saveKeyFn(arrayIndexId); - } else if (type === 'import') { - saveKeyFn('*'); - } else { - debugger; - throw new Error('unrecognized message type: ' + m.type); - } - - return saveKeys; - } - - emitUpdate(messageEvent) { - this.dispatchEvent(messageEvent); - } - - // for client - getArray(arrayId, {listen = true} = {}) { - const array = new DCArray(arrayId, this); - listen && array.listen(); - return array; - } - - getArrayMap(arrayId, arrayIndexId, {listen = true} = {}) { - const map = new DCMap(arrayId, arrayIndexId, this); - listen && map.listen(); - return map; - } - - createArrayMapElement(arrayId, val, epoch, opts) { - const arrayIndexId = makeId(); - return this.addArrayMapElement(arrayId, arrayIndexId, val, epoch, opts); - } - - addArrayMapElement(arrayId, arrayIndexId, val, epoch, { - listen = true, - } = {}) { - // if (typeof epoch !== 'number') { - // debugger; - // } - - const crdtVal = convertValToCrdtVal(val); - - const key = _key(arrayId, arrayIndexId); - const crdtWrap = [ - epoch, - crdtVal, - ]; - this.crdt.set(key, crdtWrap); - - let array = this.crdt.get(arrayId); - if (!array) { - array = {}; - this.crdt.set(arrayId, array); - } - array[arrayIndexId] = true; - - const map = new DCMap(arrayId, arrayIndexId, this); - listen && map.listen(); - - const update = new MessageEvent('add.' + arrayId, { - data: { - // arrayId, - arrayIndexId, - val, - epoch, - }, - }); - return {map, update}; - } - - removeArrayMapElement(arrayId, arrayIndexId) { - let array = this.crdt.get(arrayId); - if (!array) { - array = {}; - this.crdt.set(arrayId, array); - } - if (array[arrayIndexId]) { - const key = _key(arrayId, arrayIndexId); - if (this.crdt.has(key)) { - this.crdt.delete(key); - - delete array[arrayIndexId]; - - const update = new MessageEvent('remove.' + arrayId, { - data: { - // arrayId, - arrayIndexId, - }, - }); - return update; - } else { - debugger; - throw new Error('array map key not found in crdt'); - } - } else { - debugger; - throw new Error('array index not found in array'); - } - } - - readBinding(arrayNames) { - const arrays = {}; - const arrayMaps = {}; - if (this.crdt) { - arrayNames.forEach(arrayId => { - const array = this.crdt.get(arrayId); - const localArrayMaps = []; - if (array) { - for (const arrayIndexId in array) { - const arrayMap = new DCMap(arrayId, arrayIndexId, this); - arrayMap.listen(); - localArrayMaps.push(arrayMap); - } - } - - arrays[arrayId] = new DCArray(arrayId, this); - arrays[arrayId].listen(); - arrayMaps[arrayId] = localArrayMaps; - }); - return { - arrays, - arrayMaps, - }; - } else { - throw new Error('crdt was not initialized; it has not gotten its first message'); - } - } -} - -// - -export class NetworkedDataClient extends EventTarget { - constructor(dataClient, { - userData = {}, - } = {}) { - super(); - - this.dataClient = dataClient; - this.userData = userData; - - this.ws = null; - } - - static handlesMethod(method) { - return [ - UPDATE_METHODS.IMPORT, - UPDATE_METHODS.SYN, - UPDATE_METHODS.SYN_ACK, - UPDATE_METHODS.SET, - UPDATE_METHODS.ADD, - UPDATE_METHODS.REMOVE, - UPDATE_METHODS.ROLLBACK, - UPDATE_METHODS.DEAD_HAND, - UPDATE_METHODS.LIVE_HAND, - ].includes(method); - } - - async connect(ws) { - this.ws = ws; - - const _waitForOpen = () => new Promise((resolve, reject) => { - resolve = (resolve => () => { - resolve(); - _cleanup(); - })(resolve); - reject = (reject => () => { - reject(); - _cleanup(); - })(reject); - - this.ws.addEventListener('open', resolve); - this.ws.addEventListener('error', reject); - - const _cleanup = () => { - this.ws.removeEventListener('open', resolve); - this.ws.removeEventListener('error', reject); - }; - }); - const _waitForInitialImport = async () => { - await new Promise((resolve, reject) => { - const initialMessage = e => { - if (e?.data?.byteLength > 0) { - const updateBuffer = e.data; - const uint8Array = new Uint8Array(updateBuffer); - const updateObject = parseUpdateObject(uint8Array); - - const {method, args} = updateObject; - if (method === UPDATE_METHODS.IMPORT) { - const [crdtExport] = args; - - const importMessage = new MessageEvent('import', { - data: { - crdtExport, - }, - }); - const uint8Array = serializeMessage(importMessage); - const updateObject = parseUpdateObject(uint8Array); - - const { - rollback, - update, - } = this.dataClient.applyUpdateObject(updateObject, { - force: true, // since coming from the server - }); - if (rollback) { - throw new Error('initial import failed 1'); - } - if (update) { - this.dataClient.emitUpdate(update); - } else { - throw new Error('initial import failed 2'); - } - - resolve(); - this.ws.removeEventListener('message', initialMessage); - } - } else { - // debugger; - } - }; - this.ws.addEventListener('message', initialMessage); - }); - }; - await Promise.all([ - _waitForOpen, - _waitForInitialImport(), - ]); - - const mainMessage = e => { - // if some other listener hasn't consumed the message already - if (e?.data?.byteLength > 0) { - const updateBuffer = e.data; - const uint8Array = new Uint8Array(updateBuffer); - const updateObject = parseUpdateObject(uint8Array); - - const {method} = updateObject; - // console.log('got message', updateObject); - if (NetworkedDataClient.handlesMethod(method)) { - const { - rollback, - update, - } = this.dataClient.applyUpdateObject(updateObject, { - force: true, // force since coming from the server - }); - if (rollback) { - console.warn('rollback', rollback); - throw new Error('unexpected rollback'); - } - - this.dataClient.emitUpdate(update); - } - } else { - // debugger; - } - }; - this.ws.addEventListener('message', mainMessage); - } - - /* disconnect() { - } */ - - send(msg) { - this.ws.send(msg); - } - - emitUpdate(update) { - this.send(this.dataClient.serializeMessage(update)); - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/favicon.ico b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/favicon.ico deleted file mode 100644 index 184540c70..000000000 Binary files a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/favicon.ico and /dev/null differ diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/game.js b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/game.js deleted file mode 100644 index c853ee003..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/game.js +++ /dev/null @@ -1,768 +0,0 @@ -import {makeId, zstringify} from './util.mjs'; -import {frameSize, realmSize} from './constants.js'; - -import {RemotePlayerCursorHtmlRenderer, AppsHtmlRenderer, GameRealmsCanvases, GamePlayerCanvas} from "./renderers/html-renderer.js"; -import {NetworkRealms} from "./network-realms.mjs"; - -// - -// throttle a function every ms, queueing -const _throttleFn = (fn, ms) => { - let running = false; - let queued = false; - let timeout; - return (...args) => { - if (!running) { - running = true; - fn(...args); - timeout = setTimeout(() => { - running = false; - if (queued) { - queued = false; - fn(...args); - } - }, ms); - } else { - queued = true; - } - }; -}; -const _updateCoord = _throttleFn(coord => { - const u = new URL(window.location.href); - u.searchParams.set('coord', JSON.stringify(coord)); - history.replaceState({}, '', u); -}, 500); - -// - -export const startGame = async ({ - initialCoord = [0, 0, 0], -} = {}) => { - // locals - const playerId = makeId(); - let localPlayerCanvas = null; - const remotePlayerCanvases = new Map(); - - // realms - console.warn('need to port NetworkRealms to new endpointUrl API'); - debugger; - throw new Error('need to port NetworkRealms'); - const realms = new NetworkRealms('scene', playerId); - const realmCleanupFns = new Map(); - realms.addEventListener('realmconnecting', e => { - const {realm} = e.data; - const el = Array.from(realmsCanvases.element.childNodes).find(el => { - return el.min[0] === realm.min[0] && el.min[2] === realm.min[2]; - }); - if (el) { - el.classList.add('connecting'); - } - }); - const getRealmElement = realm => Array.from(realmsCanvases.element.childNodes).find(el => { - return el.min[0] === realm.min[0] && el.min[2] === realm.min[2]; - }); - - /* const onentityadd2 = e => { - // const {entity} = e.data; - // console.log('world app entity add', e.data); - }; - realms.getVirtualWorld().worldApps.addEventListener('needledentityadd', onentityadd2); - const onentityremove2 = e => { - // console.log('world app entity remove', e.data); - }; - realms.getVirtualWorld().worldApps.addEventListener('entityremove', onentityremove2); */ - - realms.addEventListener('realmjoin', e => { - const {realm} = e.data; - - const {dataClient} = realm; - - // console.log('realm join', realm.key); - - const cleanupFns = []; - - const el = getRealmElement(realm); - if (el) { - el.classList.add('connected'); - el.classList.remove('connecting'); - - el.updateText(dataClient); - - const playersArray = dataClient.getArray('players'); - // const worldApps = dataClient.getArray('worldApps'); - - const onadd = e => { - // console.log('game players array add', realm.key, e.data, playersArray.toArray()); - const {map: playerMap} = e.data; - - playerMap.listen(); - playerMap.addEventListener('update', e => { - // console.log('player map update', e.data); - - el.updateText(dataClient); - }); - - el.updateText(dataClient); - }; - playersArray.addEventListener('add', onadd); - - // console.log('game players array listen on realm', realm.key); - const onremove = e => { - // console.log('game players array remove', realm.key, e.data, playersArray.toArray()); - const {map: playerMap} = e.data; - - el.updateText(dataClient); - }; - playersArray.addEventListener('remove', onremove); - - const onentityadd3 = e => { - // const {entity} = e.data; - el.updateText(dataClient); - }; - virtualWorld.worldApps.addEventListener('needledentityadd', onentityadd3); - - const onentityremove3 = e => { - // const {entity} = e.data; - el.updateText(dataClient); - }; - virtualWorld.worldApps.addEventListener('needledentityremove', onentityremove3); - - cleanupFns.push(() => { - playersArray.removeEventListener('add', onadd); - playersArray.removeEventListener('remove', onremove); - virtualWorld.worldApps.removeEventListener('needledentityadd', onentityadd3); - virtualWorld.worldApps.removeEventListener('needledentityremove', onentityremove3); - - playersArray.unlisten(); - }); - } - realmCleanupFns.set(realm, () => { - for (const cleanupFn of cleanupFns) { - cleanupFn(); - } - }); - }); - realms.addEventListener('realmleave', e => { - const {realm} = e.data; - - // console.log('realm leave', realm.key); - - const el = Array.from(realmsCanvases.element.childNodes).find(el => { - return el.min[0] === realm.min[0] && el.min[2] === realm.min[2]; - }); - if (el) { - el.classList.remove('connected'); - el.classList.remove('connecting'); - } - realmCleanupFns.get(realm)(); - realmCleanupFns.delete(realm); - }); - - // local objects - const virtualWorld = realms.getVirtualWorld(); - const virtualPlayers = realms.getVirtualPlayers(); - - // states - const keyState = { - W: false, - A: false, - S: false, - D: false, - }; - const _resetKeys = () => { - for (const k in keyState) { - keyState[k] = false; - } - }; - const mouseState = { - buttons: 0, - x: 0, - y: 0, - }; - const lastMouseState = { - buttons: 0, - x: 0, - y: 0, - }; - - // main game element - const gameEl = document.getElementById('engine-canvas'); - // realms canvases - const realmsCanvases = new GameRealmsCanvases(realms); - gameEl.appendChild(realmsCanvases.element); - - const _initRenderers = () => { - GamePlayerCanvas.waitForLoad(); // note: not actually waiting - - // players wrapper element - const playersEl = document.createElement('div'); - playersEl.id = 'players'; - playersEl.classList.add('players'); - gameEl.appendChild(playersEl); - - // local player rendering - localPlayerCanvas = new GamePlayerCanvas(realms.localPlayer, { - local: true, - }); - - // controls tracking - let localPlayerFocused = true; - localPlayerCanvas.element.addEventListener('focus', e => { - localPlayerFocused = true; - }); - localPlayerCanvas.element.addEventListener('blur', e => { - localPlayerFocused = false; - }); - - // reset keys on blur - window.document.addEventListener('contextmenu', e => { - _resetKeys(); - }); - window.addEventListener('blur', e => { - _resetKeys(); - }); - - window.addEventListener('keydown', e => { - // if it's Ctrl, ignore - if (e.ctrlKey) { - // nothing - } else { - if (localPlayerFocused) { - e.preventDefault(); - e.stopPropagation(); - - // WASD - switch (e.code) { - case 'KeyW': { - keyState.W = true; - // localPlayerCanvas.velocity[2] = -1; - break; - } - case 'KeyA': { - keyState.A = true; - // localPlayerCanvas.velocity[0] = -1; - break; - } - case 'KeyS': { - keyState.S = true; - // localPlayerCanvas.velocity[2] = 1; - break; - } - case 'KeyD': { - keyState.D = true; - // localPlayerCanvas.velocity[0] = 1; - break; - } - case 'KeyE': { - _pickupDrop(); - break; - } - case 'KeyT': { - realms.toggleMic(); - break; - } - } - } - } - }); - window.addEventListener('keyup', e => { - // if it's Ctrl, ignore - if (e.ctrlKey) { - // nothing - } else { - if (localPlayerFocused) { - e.preventDefault(); - e.stopPropagation(); - - switch (e.code) { - case 'KeyW': { - keyState.W = false; - break; - } - case 'KeyA': { - keyState.A = false; - break; - } - case 'KeyS': { - keyState.S = false; - break; - } - case 'KeyD': { - keyState.D = false; - break; - } - } - } - } - }); - localPlayerCanvas.element.focus(); - document.body.addEventListener('click', e => { - localPlayerCanvas.element.focus(); - }); - playersEl.appendChild(localPlayerCanvas.element); - - // remote players rendering - realms.players.addEventListener('join', e => { - const {playerId, player} = e.data; - // console.log('join', e.data); - - if (playerId !== realms.playerId) { - const remotePlayer = player; - const remotePlayerCanvas = new GamePlayerCanvas(remotePlayer, { - local: false, - }); - playersEl.appendChild(remotePlayerCanvas.element); - remotePlayerCanvases.set(playerId, remotePlayerCanvas); - } - }); - realms.players.addEventListener('leave', e => { - const {playerId} = e.data; - // console.log('leave', e.data); - - if (playerId !== realms.playerId) { - const remotePlayerCanvas = remotePlayerCanvases.get(playerId); - remotePlayerCanvas.element.parentNode.removeChild(remotePlayerCanvas.element); - remotePlayerCanvas.destroy(); - remotePlayerCanvases.delete(playerId); - } - }); - - // action methods - const _pickupDrop = () => { - // console.log('drop 1'); - const position = localPlayerCanvas.virtualPlayer.getKeyValue('position'); - const direction = localPlayerCanvas.virtualPlayer.getKeyValue('direction'); - const targetPosition = [ - position[0] + direction[0] * frameSize, - 0, - position[2] + direction[2] * frameSize - frameSize / 2, - ]; - const targetBox = { - min: [ - targetPosition[0] - frameSize / 2, - 0, - targetPosition[2] - frameSize / 2, - ], - max: [ - targetPosition[0] + frameSize / 2, - 0, - targetPosition[2] + frameSize / 2, - ], - }; - const _boxContains = (box, position) => { - return position[0] >= box.min[0] && position[0] <= box.max[0] && - position[1] >= box.min[1] && position[1] <= box.max[1] && - position[2] >= box.min[2] && position[2] <= box.max[2]; - }; - const _needledEntityIsWorn = needledEntity => { - const actions = realms.localPlayer.playerActions.toArray(); - const action = actions.find(action => action.action === 'wear' && action.appId === needledEntity.entityMap.arrayIndexId); - return !!action; - }; - const _getCollision = () => { - return Array.from(virtualWorld.worldApps.needledVirtualEntities.values()).find(needledEntityMap => { - const worn = _needledEntityIsWorn(needledEntityMap); - if (!worn) { - const position = needledEntityMap.get('position'); - return !!position && _boxContains(targetBox, position); - } else { - return false; - } - }); - }; - - const collidedVirtualMap = _getCollision(); - if (collidedVirtualMap) { - // deadhand - // Is emitted by addEntity(). - /* - const sourceRealm = collidedVirtualMap.headTracker.getHeadRealm(); - const deadHandUpdate = sourceRealm.dataClient.deadHandArrayMaps( - realms.localPlayer.playerApps.arrayId, - [collidedVirtualMap.entityMap.arrayIndexId], - realms.playerId, - ); - sourceRealm.emitUpdate(deadHandUpdate); - */ - - // track - // collidedVirtualMap.setHeadTracker(realms.localPlayer.playerApps.headTracker); - - // add app to the new location (player) - const collidedAppJson = collidedVirtualMap.toObject(); - const targetRealm = realms.localPlayer.headTracker.getHeadRealm(); - const newAppMap = realms.localPlayer.playerApps.addEntityAt( - collidedVirtualMap.entityMap.arrayIndexId, - collidedAppJson, - targetRealm, - ); - - // add new action - const action = { - position: targetPosition, - action: 'wear', - appId: collidedVirtualMap.entityMap.arrayIndexId, - }; - const newActionMap = realms.localPlayer.playerActions.addEntity(action, targetRealm); - - // remove from the old location (world) - // collidedVirtualMap.remove(); - virtualWorld.worldApps.removeEntityAt(collidedVirtualMap.entityMap.arrayIndexId); - - // livehand - // Is emitted by addEntity(). - /* - const liveHandUpdate = targetRealm.dataClient.liveHandArrayMaps( - realms.localPlayer.playerApps.arrayId, - [collidedVirtualMap.entityMap.arrayIndexId], - realms.playerId, - ); - sourceRealm.emitUpdate(liveHandUpdate); - */ - } else { - // console.log('got player apps', realms.localPlayer.playerApps.getSize()); - if (realms.localPlayer.playerActions.getSize() > 0) { - const targetRealm = realms.getClosestRealm(targetPosition); - if (targetRealm) { - // console.log('drop to target realm', targetRealm.key, targetRealm); - - // the app we will be dropping - const actions = realms.localPlayer.playerActions.toArray(); - const wearActionIndex = actions.findIndex(action => action.action === 'wear'); - const wearAction = actions[wearActionIndex]; - const {appId} = wearAction; - - const appIds = realms.localPlayer.playerApps.getKeys(); - const wearAppIndex = appIds.indexOf(appId); - - const firstAction = realms.localPlayer.playerActions.getVirtualMapAt(wearActionIndex); - const firstApp = realms.localPlayer.playerApps.getVirtualMapAt(wearAppIndex); - - // const newHeadTracker = new HeadTracker('drop'); - // newHeadTracker.setHeadRealm(firstApp.headTracker.getHeadRealm()); - // newHeadTracker.setConnectedRealms(firstApp.headTracker.getConnectedRealms()); - // firstApp.setHeadTracker(newHeadTracker); - - // firstApp.set('position', targetPosition); - - // set dead hands - // old location: player - // the player already has deadhand on all of its apps, probably? - // const deadHandUpdate = firstApp.headRealm.dataClient.deadHandArrayMaps( - // realms.localPlayer.playerApps.arrayId, - // [firstApp.entityMap.arrayIndexId], - // realms.playerId, - // ); - // firstApp.headRealm.emitUpdate(deadHandUpdate); - // new location: world - // deadhand - // Is emitted by addEntityAt(). - /* - const deadHandUpdate = targetRealm.dataClient.deadHandArrayMaps( - 'worldApps', - [firstApp.entityMap.arrayIndexId], - realms.playerId, - ); - targetRealm.emitUpdate(deadHandUpdate); - */ - - // add at the new location (world) - const firstAppJson = firstApp.toObject(); - firstAppJson.position = targetPosition; - const newPlayerAppMap = virtualWorld.worldApps.addEntityAt( - firstApp.entityMap.arrayIndexId, - firstAppJson, - targetRealm, - ); - // const newPlayerApp = virtualWorld.worldApps.getVirtualMap(newPlayerAppMap.arrayIndexId); - // newPlayerApp.headTracker.setHeadRealm(targetRealm); - - // remove from the old location (player) - // firstApp.remove(); - // firstAction.remove(); - realms.localPlayer.playerApps.removeEntityAt(appId); - realms.localPlayer.playerActions.removeEntityAt(firstAction.arrayIndexId); - - // livehand - // Is emitted by addEntity(). - /* - const liveHandUpdate = targetRealm.dataClient.liveHandArrayMap( - 'worldApps', - [firstApp.entityMap.arrayIndexId], - realms.playerId, - ); - targetRealm.emitUpdate(liveHandUpdate); - */ - - } else { - console.warn('no containing realm to drop to'); - } - } else { - console.warn('nothing to drop'); - } - } - }; - }; - _initRenderers(); - - const _initLogic = () => { - // world - // const worldItemRenderers = []; - // bind - - // local player - const localPlayerCursorRenderer = new RemotePlayerCursorHtmlRenderer(realms.playerId, realms.playerId, realms.localPlayer); - const appsRenderer = new AppsHtmlRenderer(realms); - - const imageNode = new Image(); - imageNode.src = '/public/images/audio.svg'; - imageNode.classList.add('audio-icon'); - let roster = document.querySelector("#roster"); - - const _addPlayer = player => { - // ui - const p = document.createElement("p"); - p.classList.add('player'); - - p.appendChild(imageNode.cloneNode()); - - const span = document.createElement('span'); - span.classList.add('name'); - span.innerText = player.arrayIndexId; - p.appendChild(span); - - p.playerId = player.arrayIndexId; - roster.appendChild(p); - - // render - const playerCursorRenderer = new RemotePlayerCursorHtmlRenderer(player.arrayIndexId, playerId, player); - playerCursorRenderers.push(playerCursorRenderer); - }; - const _removePlayer = playerId => { - for (let i = 0; i < roster.children.length; i++) { - const p = roster.children[i]; - if (p.playerId === playerId) { - roster.removeChild(p); - break; - } - } - - for (let i = 0; i < playerCursorRenderers.length; i++) { - const playerCursorRenderer = playerCursorRenderers[i]; - if (playerCursorRenderer.remotePlayerId === playerId) { - playerCursorRenderers.splice(i, 1); - playerCursorRenderer.destroy(); - break; - } - } - }; - - // players - const playerCursorRenderers = []; - virtualPlayers.addEventListener('join', e => { - // console.log('add virtual player', e.data); - const {player} = e.data; - _addPlayer(player); - }); - virtualPlayers.addEventListener('leave', e => { - // console.log('remove virtual player', e.data); - const {playerId} = e.data; - _removePlayer(playerId); - }); - _addPlayer(realms.localPlayer); - - // audio - const _enableAudioOutput = playerId => { - for (let i = 0; i < roster.children.length; i++) { - const p = roster.children[i]; - const textNode = p.children[1]; - if (textNode.playerId === playerId) { - // console.log('swap on'); - p.classList.add('speaking'); - break; - } - } - }; - const _disableAudioOutput = playerId => { - for (let i = 0; i < roster.children.length; i++) { - const p = roster.children[i]; - const textNode = p.children[1]; - if (textNode.playerId === playerId) { - // console.log('swap off'); - p.classList.remove('speaking'); - break; - } - } - }; - realms.addEventListener('audiostreamstart', e => { - const {playerId} = e.data; - // console.log('stream start', playerId); - _enableAudioOutput(playerId); - }); - realms.addEventListener('audiostreamend', e => { - const {playerId} = e.data; - // console.log('stream end', playerId); - _disableAudioOutput(playerId); - }); - - // wait for the network to be ready befor binding controls - // realms.addEventListener('networkreconfigure', e => { - // }, {once: true}); - }; - _initLogic(); - - const _startFrameLoop = () => { - let connected = false; - const onConnect = position => { - console.log('on connect'); - if (!position) { - debugger; - } - const appVals = [ - { - start_url: 'rock', - position: new Float32Array(3), - }, - { - start_url: 'rock', - position: new Float32Array(3), - }, - ]; - const appIds = Array(appVals.length); - for (let i = 0; i < appIds.length; i++) { - appIds[i] = makeId(); - } - - const actionVals = [ - { - action: 'wear', - appId: appIds[0], - }, - { - action: 'wear', - appId: appIds[1], - }, - ]; - - const o = { - position: position.slice(), - direction: [0, 0, 1], - cursorPosition: [0, 0, 0], - name: 'Hanna', - }; - // console.log('initialize player', o); - realms.localPlayer.initializePlayer(o, { - appVals, - appIds, - actionVals, - }); - - connected = true; - }; - const _setInitialCoord = () => { - // console.log('set initial coord', initialCoord); - const initialPosition = [ - initialCoord[0], - 0, - initialCoord[1], - ]; - realms.updatePosition(initialPosition, realmSize, { - onConnect, - }); - }; - _setInitialCoord(); - - let frame; - const _recurse = () => { - frame = requestAnimationFrame(_recurse); - - if (connected) { - // move the cursor - if (mouseState.x !== lastMouseState.x || mouseState.y !== lastMouseState.y) { - realms.localPlayer.setKeyValue('cursorPosition', [ - lastMouseState.x, - lastMouseState.y, - 0, - ]); - - lastMouseState.x = mouseState.x; - lastMouseState.y = mouseState.y; - } - - const _normalize = p => { - const l = Math.sqrt(p[0]*p[0] + p[1]*p[1] + p[2]*p[2]); - if (l > 0) { - p[0] /= l; - p[1] /= l; - p[2] /= l; - } - }; - const _updateVelocity = () => { - localPlayerCanvas.velocity[0] = 0; - localPlayerCanvas.velocity[1] = 0; - localPlayerCanvas.velocity[2] = 0; - if (keyState.W) { - localPlayerCanvas.velocity[2] -= 1; - } - if (keyState.S) { - localPlayerCanvas.velocity[2] += 1; - } - if (keyState.A) { - localPlayerCanvas.velocity[0] -= 1; - } - if (keyState.D) { - localPlayerCanvas.velocity[0] += 1; - } - _normalize(localPlayerCanvas.velocity); - }; - _updateVelocity(); - - // move the local player - localPlayerCanvas.move(); - - // render the frame - const _renderPlayers = () => { - localPlayerCanvas.draw(); - for (const remotePlayerCanvas of remotePlayerCanvases.values()) { - remotePlayerCanvas.draw(); - } - }; - _renderPlayers(); - - const _renderRealms = () => { - realmsCanvases.update(); - }; - _renderRealms(); - - // update realms set - const position = realms.localPlayer.getKeyValue('position'); - realms.updatePosition(position, realmSize, { - // onConnect, - }); - - // draw the world - const gameEl = document.getElementById(`game`); - const localPlayerEl = document.getElementById(`player-${realms.playerId}`); - const worldAppsEl = document.getElementById('world-apps'); - const networkRealmsEl = document.getElementById('network-realms'); - const cssTransformText = `translate3d(${-position[0]}px, ${-position[2]}px, 0px)`; - gameEl.style.transform = cssTransformText; - const cssTransformText2 = `translate3d(${position[0]}px, ${position[2]}px, 0px)`; - localPlayerEl.style.transform = cssTransformText2; - // worldAppsEl.style.transform = cssTransformText; - // networkRealmsEl.style.transform = cssTransformText; - - // latch last coord - const coord = [ - position[0], - position[2], - ]; - _updateCoord(coord); - } - }; - _recurse(); - }; - _startFrameLoop(); - - return realms; -}; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/images/audio.svg b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/images/audio.svg deleted file mode 100644 index aa2d65d3a..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/images/audio.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/images/fire-mage.png b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/images/fire-mage.png deleted file mode 100644 index a69ac965d..000000000 Binary files a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/images/fire-mage.png and /dev/null differ diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/images/rock.png b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/images/rock.png deleted file mode 100644 index 065243168..000000000 Binary files a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/images/rock.png and /dev/null differ diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/irc-client.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/irc-client.mjs deleted file mode 100644 index 1c18a0bb5..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/irc-client.mjs +++ /dev/null @@ -1,169 +0,0 @@ -import {zbencode} from 'zjs'; -import {UPDATE_METHODS} from './update-types.mjs'; -import {parseUpdateObject, makeId} from './util.mjs'; - -export class NetworkedIrcClient extends EventTarget { - constructor(playerId = makeId()) { - super(); - - this.playerId = playerId; - this.playerIds = []; - - this.ws = null; - } - - static handlesMethod(method) { - return [ - UPDATE_METHODS.NETWORK_INIT, - UPDATE_METHODS.JOIN, - UPDATE_METHODS.LEAVE, - UPDATE_METHODS.REGISTER, - UPDATE_METHODS.CHAT, - ].includes(method); - } - - async connect(ws) { - this.ws = ws; - - const _waitForOpen = () => new Promise((resolve, reject) => { - resolve = (resolve => () => { - resolve(); - _cleanup(); - })(resolve); - reject = (reject => () => { - reject(); - _cleanup(); - })(reject); - - this.ws.addEventListener('open', resolve); - this.ws.addEventListener('error', reject); - - const _cleanup = () => { - this.ws.removeEventListener('open', resolve); - this.ws.removeEventListener('error', reject); - }; - }); - const _waitForInitialImport = async () => { - await new Promise((resolve, reject) => { - const initialMessage = e => { - // console.log('got message', e.data); - if (e.data instanceof ArrayBuffer && e.data.byteLength > 0) { - const updateBuffer = e.data; - const uint8Array = new Uint8Array(updateBuffer); - const updateObject = parseUpdateObject(uint8Array); - - const {method/*, args */} = updateObject; - if (method === UPDATE_METHODS.NETWORK_INIT) { - this.handleUpdateObject(updateObject); - - resolve(); - - this.ws.removeEventListener('message', initialMessage); - } - } - }; - this.ws.addEventListener('message', initialMessage); - }); - }; - await Promise.all([ - _waitForOpen(), - _waitForInitialImport(), - ]); - - // console.log('irc listen'); - this.ws.addEventListener('message', e => { - // if some other listener hasn't consumed the message already - if (e?.data?.byteLength > 0) { - const updateBuffer = e.data; - // console.log('irc data', e.data); - const uint8Array = new Uint8Array(updateBuffer); - const updateObject = parseUpdateObject(uint8Array); - - const {method/*, args */} = updateObject; - if (NetworkedIrcClient.handlesMethod(method)) { - this.handleUpdateObject(updateObject); - } - } else { - // debugger; - } - }); - } - - handleUpdateObject(updateObject) { - const {method, args} = updateObject; - // console.log('got irc event', {method, args}); - if (method === UPDATE_METHODS.NETWORK_INIT) { - const [playerIds] = args; - this.playerIds = playerIds; - - for (let i = 0; i < playerIds.length; i++) { - const playerId = playerIds[i]; - // console.log('dispatch join', playerId); - this.dispatchEvent(new MessageEvent('join', { - data: { - playerId, - }, - })); - } - } else if (method === UPDATE_METHODS.CHAT) { - // console.log('got irc chat', JSON.stringify({method, args}, null, 2)); - const [playerId, message] = args; - const chatMessage = new MessageEvent('chat', { - data: { - playerId, - message, - }, - }); - this.dispatchEvent(chatMessage); - } else if (method === UPDATE_METHODS.JOIN) { - const [playerId] = args; - this.playerIds.push(playerId); - this.dispatchEvent(new MessageEvent('join', { - data: { - playerId, - }, - })); - } else if (method === UPDATE_METHODS.LEAVE) { - const [playerId] = args; - const index = this.playerIds.indexOf(playerId); - this.playerIds.splice(index, 1); - this.dispatchEvent(new MessageEvent('leave', { - data: { - playerId, - }, - })); - } else if (method === UPDATE_METHODS.REGISTER) { - const [playerId] = args; - const index = this.playerIds.indexOf(playerId); - this.playerIds.splice(index, 1); - this.dispatchEvent(new MessageEvent('register', { - data: { - playerId, - }, - })); - } else { - console.warn('unhandled irc method', {method, args}); - } - } - - sendRegisterMessage() { - const buffer = zbencode({ - method: UPDATE_METHODS.REGISTER, - args: [ - this.playerId, - ], - }); - this.ws.send(buffer); - } - - sendChatMessage(message) { - const buffer = zbencode({ - method: UPDATE_METHODS.CHAT, - args: [ - this.playerId, - message, - ], - }); - this.ws.send(buffer); - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/lock-client.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/lock-client.mjs deleted file mode 100644 index 6a356158d..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/lock-client.mjs +++ /dev/null @@ -1,204 +0,0 @@ -import { UPDATE_METHODS } from "./update-types.mjs"; -import { - // createWs, - // makePromise, - // makeId, - parseUpdateObject, - serializeMessage, -} from './util.mjs'; - -class LockRealm { - constructor({ - lockName, - }) { - this.lockName = lockName; - this.queue = []; - this.currentLockedSession = null; - } - lock({ - session, - }) { - if (!this.currentLockedSession) { - this.currentLockedSession = session; - - // reply to the session that we are locked - const m = new MessageEvent('lockResponse', { - data: { - playerId: session.playerId, - lockName: this.lockName, - }, - }); - session.webSocket.send(serializeMessage(m)); - } else { - this.queue.push(session); - } - } - unlock({ - session, - }) { - if (this.currentLockedSession === session) { - this.currentLockedSession = null; - - if (this.queue.length > 0) { - const nextSession = this.queue.shift(); - this.lock({ - session: nextSession, - }); - } - } else { - this.queue = this.queue.filter(s => s !== session); - } - } -} - -export class NetworkedLockClient extends EventTarget { - static handlesMethod(method) { - return [ - UPDATE_METHODS.LOCK_REQUEST, // client -> server - UPDATE_METHODS.LOCK_RESPONSE, // server -> client - UPDATE_METHODS.LOCK_RELEASE, // client -> server - ].includes(method); - } - - ws = null; // client - locks = new Map(); // server; string -> LockRealm - constructor() { - super(); - } - - // client request lock - async lock(lockName, { - signal, - }) { - // send the lock - const m = new MessageEvent('lockRequest', { - data: { - lockName, - }, - }); - this.ws.send(serializeMessage(m)); - - // when the signal aborts,send the release - signal.addEventListener('abort', (e) => { - const m = new MessageEvent('lockRelease', { - data: { - lockName, - }, - }); - this.ws.send(serializeMessage(m)); - }); - - // wait for the unlock - await new Promise((resolve, reject) => { - const onmessage = (e) => { - if (e.data instanceof ArrayBuffer && e.data.byteLength > 0) { - const updateBuffer = e.data; - const uint8Array = new Uint8Array(updateBuffer); - const updateObject = parseUpdateObject(uint8Array); - - const {method, args} = updateObject; - if (method === UPDATE_METHODS.LOCK_RESPONSE) { - const [_lockName] = args; - if (_lockName === lockName) { - resolve(); - cleanup(); - } - } - } - }; - this.ws.addEventListener('message', onmessage); - - // const onabort = (e) => { - // resolve(); - // cleanup(); - // }; - // signal.addEventListener('abort', onabort); - - const cleanup = () => { - this.ws.removeEventListener('message', onmessage); - // signal.removeEventListener('abort', onabort); - }; - }); - } - - // server force unlock on disconnect - ensureLockRealm() { - let lockRealm = this.locks.get(lockName); - if (!lockRealm) { - lockRealm = new LockRealm(); - this.locks.set(lockName, lockRealm); - } - return lockRealm; - } - serverLock(session, lockName) { - const lockRealm = this.ensureLockRealm(lockName); - lockRealm.lock({ - session, - }); - } - serverUnlock(session, lockName) { - const lockRealm = this.ensureLockRealm(lockName); - lockRealm.unlock({ - session, - }); - } - serverUnlockSession(session) { - for (const lockRealm of Array.from(this.locks)) { - lockRealm.unlock({ - session, - }); - } - } - - // client connects to server - async connect(ws) { - this.ws = ws; - - const _waitForOpen = async () => { - await new Promise((resolve, reject) => { - resolve = (resolve => () => { - resolve(); - _cleanup(); - })(resolve); - reject = (reject => () => { - reject(); - _cleanup(); - })(reject); - - ws.addEventListener('open', resolve); - ws.addEventListener('error', reject); - - const _cleanup = () => { - ws.removeEventListener('open', resolve); - ws.removeEventListener('error', reject); - }; - }); - }; - await _waitForOpen(); - } - - // server handles message - handle(e) { - const { type } = e; - const { session, lockName } = e.data; - if (!playerId || !lockName) { - throw new Error('lock client message missing args: ' + JSON.stringify(e.data)); - } - switch (type) { - case 'lockRequest': { - this.serverLock(session, lockName); - break; - } - case 'lockResponse': { - throw new Error('server should not receive lockResponse'); - } - case 'lockRelease': { - this.serverUnlock(session, lockName); - break; - } - default: { - throw new Error('unrecognized lock client message type: ' + type); - } - } - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/network-realms.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/network-realms.mjs deleted file mode 100644 index 48ab48fd2..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/network-realms.mjs +++ /dev/null @@ -1,2089 +0,0 @@ -import {DataClient, NetworkedDataClient, DCMap, DCArray} from './data-client.mjs'; -import {NetworkedCrdtClient} from './crdt-client.mjs'; -import {NetworkedLockClient} from './lock-client.mjs'; -import {NetworkedIrcClient} from './irc-client.mjs'; -import {NetworkedAudioClient} from './audio/networked-audio-client.mjs'; -import {NetworkedVideoClient} from './video/networked-video-client.mjs'; -import { - createWs, - makePromise, - makeId, - parseUpdateObject, - serializeMessage, -} from './util.mjs'; - -// - -const arrayEquals = (a, b) => { - if (a.length !== b.length) { - return false; - } else { - for (let i = 0; i < a.length; i++) { - if (a[i] !== b[i]) { - return false; - } - } - return true; - } -}; - -const makeTransactionHandler = () => { - const queue = []; - async function handle(fn) { - if (!handle.running) { - handle.running = true; - let result; - let error; - try { - result = await fn(); - } catch (err) { - error = err; - } - handle.running = false; - if (queue.length > 0) { - queue.shift()(); - } - if (!error) { - return result; - } else { - throw error; - } - } else { - const promise = makePromise(); - queue.push(promise.resolve); - await promise; - return handle(fn); - } - } - handle.running = false; - return handle; -}; - -// - -const _getContainingHeadRealm = (realmKey, realms) => { - // console.log('get containing realm', realmKey, realms); - - for (const realm of realms) { - if (realm.connected) { - if (realm.key === realmKey) { - return realm; - } - // const box = { - // min: realm.min, - // max: [ - // realm.min[0] + realm.size, - // realm.min[1] + realm.size, - // realm.min[2] + realm.size, - // ], - // }; - // if (boxContains(box, position)) { - // return realm; - // } - } - } - return null; -}; - -// - -class HeadTrackedEntity extends EventTarget { - constructor(headTracker) { - super(); - - this.headTracker = headTracker || new HeadTracker(this); - } -} - -// - -class HeadTracker extends EventTarget { - constructor(headTrackedEntity) { - super(); - - this.headTrackedEntity = headTrackedEntity; - - this.onMigrate = null; - this.cleanupFns = new Map(); - } - - #needsUpdate = false; - #currentHeadRealm = null; // based on position, used for migrate + write - #cachedHeadRealm = null; // based on linkage, used for events + read - #connectedRealms = new Map(); // realm -> link count - - getHeadRealm() { - if (this.#needsUpdate) { - this.#updateCachedHeadRealm(); - this.#needsUpdate = false; - } - return this.#cachedHeadRealm; - } - - #updateCachedHeadRealm() { - this.#cachedHeadRealm = this.#computeHeadRealm(); - } - - #computeHeadRealm() { - if (this.#connectedRealms.size === 1) { // by far the most common case - return this.#connectedRealms.keys().next().value; - } else { - const {arrayId, arrayIndexId} = this.headTrackedEntity; - let dcMaps = []; - for (const realm of this.#connectedRealms.keys()) { - const {dataClient} = realm; - const dcArray = dataClient.getArray(arrayId, { - listen: false, - }); - if (dcArray.hasKey(arrayIndexId)) { - const dcMap = dcArray.getMap(arrayIndexId, { - listen: false, - }); - dcMaps.push(dcMap); - } else { - // nothing - } - } - - if (dcMaps.length > 0) { - let dcMap; - if (dcMaps.length === 1) { - dcMap = dcMaps[0]; - } else { - dcMaps = dcMaps.sort((a, b) => { - return b.getMapEpoch() - a.getMapEpoch(); - }); - dcMap = dcMaps[0]; - } - return dcMap.dataClient.userData.realm; - } else { - // XXX if we got here, that means that this entity does not exist in the data. - // XXX if the caller is trying to create this data, they should call getHeadRealmForCreate() instead - debugger; - throw new Error('cannot get head realm: entity does not exist in data'); - } - } - } - - getHeadRealmForCreate(realmKey) { - const headRealm = _getContainingHeadRealm(realmKey, this.#connectedRealms.keys()); - return headRealm; - } - - async tryMigrate(realmKey) { - // console.log('try migrate', realmKey, this.isLinked()); - if (this.isLinked()) { - if (realmKey) { - const newHeadRealm = _getContainingHeadRealm(realmKey, Array.from(this.#connectedRealms.keys())); - if (!this.#currentHeadRealm) { - this.#currentHeadRealm = newHeadRealm; - // console.log('init head realm', newHeadRealm.key); - } else { - const oldHeadRealm = this.#currentHeadRealm; - /* if (!newHeadRealm) { - console.log('missing realm', this, realmKey); - debugger; - } - if (!oldHeadRealm) { - console.log('missing realm', this, this.#currentHeadRealm); - debugger; - } */ - if (newHeadRealm.key !== oldHeadRealm.key) { - this.#currentHeadRealm = newHeadRealm; - - this.onMigrate && await this.onMigrate(new MessageEvent('migrate', { - data: { - oldHeadRealm, - newHeadRealm, - }, - })); - } else { - console.log('keys same! why are you updating me?'); - debugger; - } - } - } else { - this.#currentHeadRealm = null; - } - } else { - debugger; - throw new Error('try to get head realm for fully unlinked player ' + this.playerId); - } - } - - isLinked() { - return this.#connectedRealms.size > 0; - } - - linkRealm(realm) { - // listen for array add/remove which might trigger head update - const _listen = () => { - const {arrayId} = this.headTrackedEntity; - const {dataClient} = realm; - const dcArray = dataClient.getArray(arrayId); // note: auto-listen - const onadd = e => { - this.#needsUpdate = true; - }; - dcArray.addEventListener('add', onadd); - const onremove = e => { - this.#needsUpdate = true; - }; - dcArray.addEventListener('remove', onremove); - - this.cleanupFns.set(realm, () => { - // stop listening for array add/remove - dcArray.unlisten(); - dcArray.removeEventListener('add', onadd); - dcArray.removeEventListener('remove', onremove); - }); - }; - - // add connected realm - let val = this.#connectedRealms.get(realm) ?? 0; - val++; - if (val === 1) { - _listen(); - } - this.#connectedRealms.set(realm, val); - this.#needsUpdate = true; - } - - unlinkRealm(realm) { - // remove connected realm - let val = this.#connectedRealms.get(realm); - val--; - if (val <= 0) { - this.#connectedRealms.delete(realm); - - this.cleanupFns.get(realm)(); - this.cleanupFns.delete(realm); - } - this.#needsUpdate = true; - } -} - -// - -class EntityTracker extends EventTarget { - constructor() { - super(); - - this.virtualMaps = new Map(); - // this.linkedRealms = new Map(); - this.cleanupFns = new Map(); - } - - getSize() { - return this.virtualMaps.size; - } - - linkMap(realm, map) { - // bind local array maps to virtual maps - const _getOrCreateVirtualMap = arrayIndexId => { - let virtualMap = this.virtualMaps.get(map.arrayIndexId); - if (!virtualMap) { - // console.log('*** create new', map.arrayId, arrayIndexId); - virtualMap = new HeadlessVirtualEntityMap(arrayIndexId); - this.virtualMaps.set(map.arrayIndexId, virtualMap); - - virtualMap.addEventListener('garbagecollect', e => { - this.virtualMaps.delete(map.arrayIndexId); - this.dispatchEvent(new MessageEvent('entityremove', { - data: { - arrayId: map.arrayId, - entityId: arrayIndexId, - entity: virtualMap, - realm, - }, - })); - }); - } else { - // console.log('*** create old', map.arrayId, arrayIndexId); - } - return virtualMap; - }; - - const added = !this.virtualMaps.has(map.arrayIndexId); - const virtualMap = _getOrCreateVirtualMap(map.arrayIndexId); - - virtualMap.link(map.arrayId, realm); - - if (added) { - this.dispatchEvent(new MessageEvent('entityadd', { - data: { - arrayId: map.arrayId, - entityId: map.arrayIndexId, - entity: virtualMap, - realm, - }, - })); - } else { - this.dispatchEvent(new MessageEvent('entitytransplant', { - data: { - arrayId: map.arrayId, - entityId: map.arrayIndexId, - entity: virtualMap, - realm, - }, - })); - } - return virtualMap; - } - - unlinkMap(realm, arrayId, arrayIndexId) { - // console.log('entity tracker unlink map', realm, arrayIndexId); - - const virtualMap = this.virtualMaps.get(arrayIndexId); - virtualMap.unlink(arrayId, realm); - } - - // each realm will only be linked once - #linkInternal(arrayId, realm) { - const key = arrayId + ':' + realm.key; - - const {dataClient} = realm; - const dcArray = dataClient.getArray(arrayId); // note: auto listen - - const localVirtualMaps = new Map(); - const _bind = map => { - const virtualMap = this.linkMap(realm, map); - localVirtualMaps.set(map.arrayIndexId, virtualMap); - }; - const _unbind = arrayIndexId => { - this.unlinkMap(realm, dcArray.arrayId, arrayIndexId); - localVirtualMaps.delete(arrayIndexId); - }; - - const onimport = e => { - const keys = dcArray.getKeys(); - for (const arrayIndexId of keys) { - const map = dcArray.dataClient.getArrayMap(arrayId, arrayIndexId, { - listen: false, - }); - _bind(map); - } - }; - dcArray.dataClient.addEventListener('import', onimport); - - const addKey = 'add.' + dcArray.arrayId; - const onadd = e => { - const {arrayIndexId} = e.data; - const map = dcArray.getMap(arrayIndexId, { - listen: false, - }); - _bind(map); - }; - dcArray.dataClient.addEventListener(addKey, onadd); - const removeKey = 'remove.' + dcArray.arrayId; - const onremove = e => { - const {arrayIndexId} = e.data; - _unbind(arrayIndexId); - }; - dcArray.dataClient.addEventListener(removeKey, onremove); - - // initial listen for existing elements - const arrayIndexIds = dcArray.getKeys(); - for (const arrayIndexId of arrayIndexIds) { - const map = new DCMap(arrayId, arrayIndexId, realm.dataClient); - _bind(map); - } - - this.cleanupFns.set(key, () => { - dcArray.unlisten(); - dcArray.dataClient.removeEventListener('import', onimport); - dcArray.dataClient.removeEventListener(addKey, onadd); - dcArray.dataClient.removeEventListener(removeKey, onremove); - - for (const arrayIndexId of localVirtualMaps.keys()) { - this.unlinkMap(realm, dcArray.arrayId, arrayIndexId); - } - }); - } - - // returns whether the realm was linked - link(arrayId, realm) { - this.#linkInternal(arrayId, realm); - } - - #unlinkInternal(arrayId, realm) { - const key = arrayId + ':' + realm.key; - this.cleanupFns.get(key)(); - this.cleanupFns.delete(key); - } - - // returns whether the realm was unlinked - unlink(arrayId, realm) { - this.#unlinkInternal(arrayId, realm); - } -} - -class VirtualPlayer extends HeadTrackedEntity { - constructor(arrayId, arrayIndexId, realms, name, opts) { - super(opts?.headTracker); - - this.arrayId = arrayId; - this.arrayIndexId = arrayIndexId; - this.realms = realms; - this.name = name; - - this.headTracker = new HeadTracker(this); - - this.playerApps = new VirtualEntityArray('playerApps:' + this.arrayIndexId, this.realms, { - entityTracker: opts?.appsEntityTracker, - }); - this.playerActions = new VirtualEntityArray('playerActions:' + this.arrayIndexId, this.realms, { - entityTracker: new EntityTracker(), - }); - this.cleanupMapFns = new Map(); - } - - initializePlayer(o, { - appVals = [], - appIds = [], - actionVals = [], - actionValIds = [], - } = {}) { - const headRealm = this.headTracker.getHeadRealmForCreate(o.realmKey); - // if (!headRealm) { - // debugger; - // } - - // console.log('initialize app', headRealm.key, o.position.join(',')); - - const _initializeApps = () => { - for (let i = 0; i < appVals.length; i++) { - const appVal = appVals[i]; - const appId = appIds[i] ?? makeId(); - const deadHandUpdate = headRealm.dataClient.deadHandArrayMap(this.playerApps.arrayId, appId, this.realms.playerId); - headRealm.emitUpdate(deadHandUpdate); - - this.playerApps.addEntityAt(appId, appVal, headRealm); - } - }; - _initializeApps(); - - const _initializeActions = () => { - for (let i = 0; i < actionVals.length; i++) { - const actionVal = actionVals[i]; - const actionId = actionValIds[i] ?? makeId(); - const deadHandUpdate = headRealm.dataClient.deadHandArrayMap(this.playerActions.arrayId, actionId, this.realms.playerId); - headRealm.emitUpdate(deadHandUpdate); - - this.playerActions.addEntityAt(actionId, actionVal, headRealm); - } - }; - _initializeActions(); - - const _initializePlayer = () => { - const deadHandUpdate = headRealm.dataClient.deadHandArrayMap(this.arrayId, this.arrayIndexId, this.realms.playerId); - headRealm.emitUpdate(deadHandUpdate); - - const playersArray = headRealm.dataClient.getArray(this.arrayId, { - listen: false, - }); - const epoch = 0; - const { - // map, - update, - } = playersArray.addAt(this.arrayIndexId, o, epoch, { - listen: false, - }); - headRealm.emitUpdate(update); - }; - _initializePlayer(); - } - - link(realm) { - const {dataClient} = realm; - const map = dataClient.getArrayMap(this.arrayId, this.arrayIndexId); // note: this map might not exist in the crdt yet - const update = e => { - this.dispatchEvent(new MessageEvent('update', { - data: e.data, - })); - }; - map.addEventListener('update', update); - - // link child arrays - this.playerApps.link(realm); - this.playerActions.link(realm); - - // link initial position - // console.log('player link to realm', !this.headTracker.isLinked(), realm); - if (!this.headTracker.isLinked()) { - // console.log('dispatching join event', this); - this.dispatchEvent(new MessageEvent('join', { - data: {}, - })); - } - this.headTracker.linkRealm(realm); - - // cleanup - this.cleanupMapFns.set(realm, () => { - this.headTracker.unlinkRealm(realm); - - map.unlisten(); - map.removeEventListener('update', update); - - this.playerApps.unlink(realm); - this.playerActions.unlink(realm); - }); - } - - unlink(realm) { - this.cleanupMapFns.get(realm)(); - this.cleanupMapFns.delete(realm); - - if (!this.headTracker.isLinked()) { - this.dispatchEvent(new MessageEvent('leave', { - data: {}, - })); - } - } - - getKeys() { - const headRealm = this.headTracker.getHeadRealm(); - const {dataClient} = headRealm; - const valueMap = dataClient.getArrayMap(this.arrayId, this.arrayIndexId, { - listen: false, - }); - const keys = valueMap.getKeys(); - return keys; - } - - getKeyValue(key) { - const headRealm = this.headTracker.getHeadRealm(); - const {dataClient} = headRealm; - const valueMap = dataClient.getArrayMap(this.arrayId, this.arrayIndexId, { - listen: false, - }); - return valueMap.getKey(key); - } - - getEpoch() { - const headRealm = this.headTracker.getHeadRealm(); - const {dataClient} = headRealm; - const valueMap = dataClient.getArrayMap(this.arrayId, this.arrayIndexId, { - listen: false, - }); - return valueMap.getEpoch(); - } - - setKeyValue(key, val) { - const headRealm = this.headTracker.getHeadRealm(); - const {dataClient} = headRealm; - const valueMap = dataClient.getArrayMap(this.arrayId, this.arrayIndexId, { - listen: false, - }); - const update = valueMap.setKeyValueUpdate(key, val); - headRealm.emitUpdate(update); - } -} - -class VirtualPlayersArray extends EventTarget { - constructor(arrayId, parent, opts) { - super(); - - this.arrayId = arrayId; - this.parent = parent; - this.opts = opts; - - this.virtualPlayers = new Map(); - this.cleanupFns = new Map(); - } - - getOrCreateVirtualPlayer(playerId) { - // console.log('get or create virtual player', { - // playerId, - // }); - let virtualPlayer = this.virtualPlayers.get(playerId); - if (!virtualPlayer) { - virtualPlayer = new VirtualPlayer(this.arrayId, playerId, this.parent, 'remote', { - appsEntityTracker: this.opts?.appsEntityTracker, - // actionsEntityTracker: this.opts?.actionsEntityTracker, - }); - this.virtualPlayers.set(playerId, virtualPlayer); - } - return virtualPlayer; - } - - getSize() { - return this.virtualPlayers.size; - } - - getKeys() { - return Array.from(this.virtualPlayers.keys()); - } - getValues() { - return Array.from(this.virtualPlayers.values()); - } - - link(realm) { - const {dataClient, networkedDataClient, networkedAudioClient, networkedVideoClient} = realm; - - const _linkData = () => { - const playersArray = dataClient.getArray(this.arrayId); - - const _linkPlayer = arrayIndexId => { - // console.log('link player', arrayIndexId, realm.key); - const playerId = arrayIndexId; - if (playerId === this.parent.playerId) { - // nothing - } else { - const created = !this.virtualPlayers.has(playerId); - const virtualPlayer = this.getOrCreateVirtualPlayer(playerId); - virtualPlayer.link(realm); - - if (created) { - this.dispatchEvent(new MessageEvent('join', { - data: { - player: virtualPlayer, - playerId, - }, - })); - } - } - }; - - const _unlinkPlayer = arrayIndexId => { - const playerId = arrayIndexId; - - // console.log('unlink player', arrayIndexId, realm.key); - - if (playerId === this.parent.playerId) { - // nothing - } else { - const virtualPlayer = this.virtualPlayers.get(playerId); - if (virtualPlayer) { - virtualPlayer.unlink(realm); - - if (!virtualPlayer.headTracker.isLinked()) { - this.virtualPlayers.delete(playerId); - - this.dispatchEvent(new MessageEvent('leave', { - data: { - player: virtualPlayer, - playerId, - }, - })); - } - } else { - console.warn('removing nonexistent player', playerId, this.players); - } - } - }; - - const onadd = e => { - // console.log('player add', e.data); - const {arrayIndexId /*, map, val */} = e.data; - _linkPlayer(arrayIndexId); - }; - playersArray.addEventListener('add', onadd); - - const onremove = e => { - // console.log('player remove', e.data, realm.key); - const {arrayIndexId} = e.data; - _unlinkPlayer(arrayIndexId); - }; - playersArray.addEventListener('remove', onremove); - - // link initial players - for (const arrayIndexId of playersArray.getKeys()) { - // console.log('player initial', arrayIndexId); - _linkPlayer(arrayIndexId); - } - - this.cleanupFns.set(networkedDataClient, () => { - playersArray.unlisten(); - - // console.log('player unlisten', realm.key, new Error().stack); - - playersArray.removeEventListener('add', onadd); - playersArray.removeEventListener('remove', onremove); - }); - }; - _linkData(); - - const _linkAudio = () => { - const audio = e => { - this.dispatchEvent(new MessageEvent('audio', { - data: e.data, - })); - }; - networkedAudioClient.addEventListener('audio', audio); - const audiostart = e => { - this.dispatchEvent(new MessageEvent('audiostart', { - data: e.data, - })); - }; - networkedAudioClient.addEventListener('audiostart', audiostart); - const audioend = e => { - this.dispatchEvent(new MessageEvent('audioend', { - data: e.data, - })); - }; - networkedAudioClient.addEventListener('audioend', audioend); - - this.cleanupFns.set(networkedAudioClient, () => { - networkedAudioClient.removeEventListener('audio', audio); - networkedAudioClient.removeEventListener('audiostart', audiostart); - networkedAudioClient.removeEventListener('audioend', audioend); - }); - }; - _linkAudio(); - - const _linkVideo = () => { - const video = e => { - this.dispatchEvent(new MessageEvent('video', { - data: e.data, - })); - }; - networkedVideoClient.addEventListener('video', video); - const videostart = e => { - this.dispatchEvent(new MessageEvent('videostart', { - data: e.data, - })); - }; - networkedVideoClient.addEventListener('videostart', videostart); - const videoend = e => { - this.dispatchEvent(new MessageEvent('videoend', { - data: e.data, - })); - }; - networkedVideoClient.addEventListener('videoend', videoend); - - this.cleanupFns.set(networkedVideoClient, () => { - networkedAudioClient.removeEventListener('video', video); - networkedAudioClient.removeEventListener('videostart', videostart); - networkedAudioClient.removeEventListener('videoend', videoend); - }); - }; - _linkVideo(); - } - - unlink(realm) { - const {networkedDataClient, networkedAudioClient, networkedVideoClient} = realm; - - this.cleanupFns.get(networkedDataClient)(); - this.cleanupFns.delete(networkedDataClient); - - this.cleanupFns.get(networkedAudioClient)(); - this.cleanupFns.delete(networkedAudioClient); - - this.cleanupFns.get(networkedVideoClient)(); - this.cleanupFns.delete(networkedVideoClient); - - } -} - -class VirtualEntityArray extends VirtualPlayersArray { - constructor(arrayId, realms, opts) { - super(arrayId, realms); - - // note: the head tracker is only for passing down to needled virtual entities we create - // we do not use the head tracker in this class, because arrays do not have a head - // this.headTracker = opts?.headTracker ?? null; - this.entityTracker = opts?.entityTracker ?? null; - - this.needledVirtualEntities = new Map(); // entity -> needled entity - - const onentityadd = e => { - // console.log('entity add', e.data); - const {entityId, entity} = e.data; - - const needledEntity = new NeedledVirtualEntityMap(arrayId, entity); - - needledEntity.cleanupFn = () => { - needledEntity.destroy(); - - this.needledVirtualEntities.delete(entity); - - this.dispatchEvent(new MessageEvent('needledentityremove', { - data: { - entityId, - needledEntity, - }, - })); - }; - this.needledVirtualEntities.set(entity, needledEntity); - - this.dispatchEvent(new MessageEvent('needledentityadd', { - data: { - entityId, - needledEntity, - }, - })); - }; - - this.entityTracker.addEventListener('entityadd', onentityadd); - - const onentityremove = e => { - // console.log('entity remove', e.data); - const {/* entityId, */ entity} = e.data; - - const needledEntity = this.needledVirtualEntities.get(entity); - if (needledEntity) { - needledEntity.cleanupFn(); - } - }; - - this.entityTracker.addEventListener('entityremove', onentityremove); - - // // console.log('adding defaults', arrayId, this.entityTracker.virtualMaps, this.entityTracker.virtualMaps.size); - // for (const [entityId, entity] of this.entityTracker.virtualMaps.entries()) { - // // console.log('add initial entity', arrayId, entityId, entity); - // onentityadd(new MessageEvent('entityadd', { - // data: { - // entityId, - // entity, - // }, - // })); - // } - } - - addEntityAt(arrayIndexId, val, realm) { - const deadHandUpdate = realm.dataClient.deadHandArrayMap(this.arrayId, arrayIndexId, this.parent.playerId); - realm.emitUpdate(deadHandUpdate); - - const array = new DCArray(this.arrayId, realm.dataClient); - const epoch = 0; - const { - map, - update, - } = array.addAt(arrayIndexId, val, epoch); - realm.emitUpdate(update); - - const liveHandUpdate = realm.dataClient.liveHandArrayMap(this.arrayId, arrayIndexId, this.parent.playerId); - realm.emitUpdate(liveHandUpdate); - - return map; - } - - removeEntityAt(arrayIndexId) { - this.getVirtualMap(arrayIndexId).remove(); - } - - getMapEntity(map) { - let entity = null; - const realms = this.parent; - for (const e of realms.world.worldApps.needledVirtualEntities.keys()) { - if (e.arrayIndexId === map.arrayIndexId) { - entity = e; - break; - } - } - // if (!entity) { - // debugger; - // } - return entity; - } - - transplantEntityToRealm(arrayIndexId, targetRealm) { - console.log('transplant entity', { - arrayIndexId, - targetRealm, - }); - debugger; - // const collidedAppJson = collidedVirtualMap.toObject(); - // const targetRealm = realms.localPlayer.headTracker.getHeadRealm(); - const realms = this.parent; - const newAppMap = realms.localPlayer.playerApps.addEntityAt( - collidedVirtualMap.entityMap.arrayIndexId, - collidedAppJson, - targetRealm, - ); - - // add new action - const action = { - position: targetPosition, - action: 'wear', - appId: collidedVirtualMap.entityMap.arrayIndexId, - }; - const newActionMap = realms.localPlayer.playerActions.addEntity(action, targetRealm); - - // remove from the old location (world) - // collidedVirtualMap.remove(); - virtualWorld.worldApps.removeEntityAt(collidedVirtualMap.entityMap.arrayIndexId); - - // action methods - const _pickupDrop = () => { - // console.log('drop 1'); - const position = localPlayerCanvas.virtualPlayer.getKeyValue('position'); - const direction = localPlayerCanvas.virtualPlayer.getKeyValue('direction'); - const targetPosition = [ - position[0] + direction[0] * frameSize, - 0, - position[2] + direction[2] * frameSize - frameSize / 2, - ]; - const targetBox = { - min: [ - targetPosition[0] - frameSize / 2, - 0, - targetPosition[2] - frameSize / 2, - ], - max: [ - targetPosition[0] + frameSize / 2, - 0, - targetPosition[2] + frameSize / 2, - ], - }; - const _boxContains = (box, position) => { - return position[0] >= box.min[0] && position[0] <= box.max[0] && - position[1] >= box.min[1] && position[1] <= box.max[1] && - position[2] >= box.min[2] && position[2] <= box.max[2]; - }; - const _needledEntityIsWorn = needledEntity => { - const actions = realms.localPlayer.playerActions.toArray(); - const action = actions.find(action => action.action === 'wear' && action.appId === needledEntity.entityMap.arrayIndexId); - return !!action; - }; - const _getCollision = () => { - return Array.from(virtualWorld.worldApps.needledVirtualEntities.values()).find(needledEntityMap => { - const worn = _needledEntityIsWorn(needledEntityMap); - if (!worn) { - const position = needledEntityMap.get('position'); - return !!position && _boxContains(targetBox, position); - } else { - return false; - } - }); - }; - - const collidedVirtualMap = _getCollision(); - if (collidedVirtualMap) { - // deadhand - // Is emitted by addEntity(). - /* - const sourceRealm = collidedVirtualMap.headTracker.getHeadRealm(); - const deadHandUpdate = sourceRealm.dataClient.deadHandArrayMaps( - realms.localPlayer.playerApps.arrayId, - [collidedVirtualMap.entityMap.arrayIndexId], - realms.playerId, - ); - sourceRealm.emitUpdate(deadHandUpdate); - */ - - // track - // collidedVirtualMap.setHeadTracker(realms.localPlayer.playerApps.headTracker); - - // add app to the new location (player) - const collidedAppJson = collidedVirtualMap.toObject(); - const targetRealm = realms.localPlayer.headTracker.getHeadRealm(); - const newAppMap = realms.localPlayer.playerApps.addEntityAt( - collidedVirtualMap.entityMap.arrayIndexId, - collidedAppJson, - targetRealm, - ); - - // add new action - const action = { - position: targetPosition, - action: 'wear', - appId: collidedVirtualMap.entityMap.arrayIndexId, - }; - const newActionMap = realms.localPlayer.playerActions.addEntity(action, targetRealm); - - // remove from the old location (world) - // collidedVirtualMap.remove(); - virtualWorld.worldApps.removeEntityAt(collidedVirtualMap.entityMap.arrayIndexId); - - // livehand - // Is emitted by addEntity(). - /* - const liveHandUpdate = targetRealm.dataClient.liveHandArrayMaps( - realms.localPlayer.playerApps.arrayId, - [collidedVirtualMap.entityMap.arrayIndexId], - realms.playerId, - ); - sourceRealm.emitUpdate(liveHandUpdate); - */ - } else { - // console.log('got player apps', realms.localPlayer.playerApps.getSize()); - if (realms.localPlayer.playerActions.getSize() > 0) { - const targetRealm = realms.getClosestRealm(targetPosition); - if (targetRealm) { - // console.log('drop to target realm', targetRealm.key, targetRealm); - - // the app we will be dropping - const actions = realms.localPlayer.playerActions.toArray(); - const wearActionIndex = actions.findIndex(action => action.action === 'wear'); - const wearAction = actions[wearActionIndex]; - const {appId} = wearAction; - - const appIds = realms.localPlayer.playerApps.getKeys(); - const wearAppIndex = appIds.indexOf(appId); - - const firstAction = realms.localPlayer.playerActions.getVirtualMapAt(wearActionIndex); - const firstApp = realms.localPlayer.playerApps.getVirtualMapAt(wearAppIndex); - - // const newHeadTracker = new HeadTracker('drop'); - // newHeadTracker.setHeadRealm(firstApp.headTracker.getHeadRealm()); - // newHeadTracker.setConnectedRealms(firstApp.headTracker.getConnectedRealms()); - // firstApp.setHeadTracker(newHeadTracker); - - // firstApp.set('position', targetPosition); - - // set dead hands - // old location: player - // the player already has deadhand on all of its apps, probably? - // const deadHandUpdate = firstApp.headRealm.dataClient.deadHandArrayMaps( - // realms.localPlayer.playerApps.arrayId, - // [firstApp.entityMap.arrayIndexId], - // realms.playerId, - // ); - // firstApp.headRealm.emitUpdate(deadHandUpdate); - // new location: world - // deadhand - // Is emitted by addEntityAt(). - /* - const deadHandUpdate = targetRealm.dataClient.deadHandArrayMaps( - 'worldApps', - [firstApp.entityMap.arrayIndexId], - realms.playerId, - ); - targetRealm.emitUpdate(deadHandUpdate); - */ - - // add at the new location (world) - const firstAppJson = firstApp.toObject(); - firstAppJson.position = targetPosition; - const newPlayerAppMap = virtualWorld.worldApps.addEntityAt( - firstApp.entityMap.arrayIndexId, - firstAppJson, - targetRealm, - ); - // const newPlayerApp = virtualWorld.worldApps.getVirtualMap(newPlayerAppMap.arrayIndexId); - // newPlayerApp.headTracker.setHeadRealm(targetRealm); - - // remove from the old location (player) - // firstApp.remove(); - // firstAction.remove(); - realms.localPlayer.playerApps.removeEntityAt(appId); - realms.localPlayer.playerActions.removeEntityAt(firstAction.arrayIndexId); - - // livehand - // Is emitted by addEntity(). - /* - const liveHandUpdate = targetRealm.dataClient.liveHandArrayMap( - 'worldApps', - [firstApp.entityMap.arrayIndexId], - realms.playerId, - ); - targetRealm.emitUpdate(liveHandUpdate); - */ - - } else { - console.warn('no containing realm to drop to'); - } - } else { - console.warn('nothing to drop'); - } - } - }; - } - - getSize() { - return this.entityTracker.getSize(); - } - - addEntity(val, realm) { - return this.addEntityAt(makeId(), val, realm); - } - - getVirtualMap(arrayIndexId) { - const entityMap = this.entityTracker.virtualMaps.get(arrayIndexId); - const needledEntity = this.needledVirtualEntities.get(entityMap); - return needledEntity; - } - - getVirtualMapAt(index) { - return Array.from(this.needledVirtualEntities.values())[index]; - } - - getKeys() { - return Array.from(this.needledVirtualEntities.keys()).map(entityMap => { - return entityMap.arrayIndexId; - }); - } - - getValues() { - return Array.from(this.needledVirtualEntities.values()); - } - - toArray() { - return Array.from(this.needledVirtualEntities.values()).map(needledEntity => { - const realm = needledEntity.headTracker.getHeadRealm(); - const entityMap = needledEntity.entityMap; - const headMap = entityMap.getHeadMapFromRealm(realm); - return headMap.toObject(); - }); - } - - // linkedRealms = new Map(); - - link(realm) { - // if (!this.linkedRealms.has(realm.key)) { - // this.linkedRealms.set(realm.key, new Error().stack); - // } else { - // debugger; - // } - - // link the entity tracker - this.entityTracker.link(this.arrayId, realm); - - this.cleanupFns.set(realm, () => { - // unlink the entity tracker - this.entityTracker.unlink(this.arrayId, realm); - }); - } - - unlink(realm) { - // if (this.linkedRealms.has(realm.key)) { - // this.linkedRealms.delete(realm.key); - // } else { - // debugger; - // } - - this.cleanupFns.get(realm)(); - this.cleanupFns.delete(realm); - } -} - -// - -class VirtualIrc { - constructor(parent) { - this.parent = parent; - this.cleanupFns = new Map(); - } - - link(realm) { - const {networkedIrcClient} = realm; - - // note: this is not a good place for this, since it doesn't have to do with players - // it's here for convenience - const onchat = e => { - this.parent.dispatchEvent(new MessageEvent('chat', { - data: e.data, - })); - }; - networkedIrcClient.addEventListener('chat', onchat); - - this.cleanupFns.set(networkedIrcClient, () => { - networkedIrcClient.removeEventListener('chat', onchat); - }); - } - - unlink(realm) { - const {networkedIrcClient} = realm; - - this.cleanupFns.get(networkedIrcClient)(); - this.cleanupFns.delete(networkedIrcClient); - } -} - -// - -// one per arrayIndexId per EntityTracker -class HeadlessVirtualEntityMap extends EventTarget { - constructor(arrayIndexId) { - super(); - - this.arrayIndexId = arrayIndexId; - - this.maps = new Map(); // bound dc maps - this.cleanupFns = new Map(); - } - - getInitial(key) { // can only be used if there is one bound map - if (this.maps.size !== 1) { - debugger; - throw new Error('cannot get initial value: ' + this.maps.size); - } else { - const map = this.maps.values().next().value.map; - return map.getKey(key); - } - } - - getHeadMapFromRealm(realm) { - for (const map of this.maps.values()) { - if (map.map.dataClient === realm.dataClient) { - return map.map; - } - } - debugger; - return null; - } - - link(arrayId, realm) { - const key = arrayId + ':' + realm.key; - - // listen - const map = new DCMap(arrayId, this.arrayIndexId, realm.dataClient); - map.listen(); - this.maps.set(key, { - map, - realm, - }); - - const update = e => { - this.dispatchEvent(new MessageEvent('update', { - data: e.data, - })); - }; - map.addEventListener('update', update); - - this.dispatchEvent(new MessageEvent('link', { - data: { - appId: this.arrayIndexId, - arrayId, - realm, - }, - })); - - this.cleanupFns.set(key, () => { - map.removeEventListener('update', update); - - this.maps.delete(key); - - this.dispatchEvent(new MessageEvent('unlink', { - data: { - appId: this.arrayIndexId, - arrayId, - realm, - }, - })); - }); - } - - unlink(arrayId, realm) { - // console.log('unlink realm', realm.key, this.arrayIndexId); - - const key = arrayId + ':' + realm.key; - - this.cleanupFns.get(key)(); - this.cleanupFns.delete(key); - - // garbage collect - if (this.maps.size === 0) { - this.dispatchEvent(new MessageEvent('garbagecollect')); - } - } -} - -class NeedledVirtualEntityMap extends HeadTrackedEntity { - constructor(arrayId, entityMap) { - super(); - - this.arrayId = arrayId; - this.entityMap = entityMap; // headless entity map - - const onlink = e => { - const {realm} = e.data; - // console.log('needled entity map link', realm.key); - this.headTracker.linkRealm(realm); - }; - this.entityMap.addEventListener('link', onlink); - const onunlink = e => { - const {realm} = e.data; - // console.log('needled entity map unlink', realm.key); - this.headTracker.unlinkRealm(realm); - }; - this.entityMap.addEventListener('unlink', onunlink); - - this.destroy = () => { - this.entityMap.removeEventListener('link', onlink); - this.entityMap.removeEventListener('unlink', onunlink); - }; - - for (const {/* map, */ realm} of this.entityMap.maps.values()) { - this.headTracker.linkRealm(realm); - } - } - - get arrayIndexId() { - return this.entityMap.arrayIndexId; - } - - set arrayIndexId(arrayIndexId) { - throw new Error('cannot set arrayIndexId'); - } - - get(key) { - const realm = this.headTracker.getHeadRealm(); - const map = this.entityMap.getHeadMapFromRealm(realm); - return map.getKey(key); - } - - set(key, val) { - const realm = this.headTracker.getHeadRealm(); - const map = this.entityMap.getHeadMapFromRealm(realm); - const update = map.setKeyValueUpdate(key, val); - realm.emitUpdate(update); - } - - remove() { - const realm = this.headTracker.getHeadRealm(); - const map = this.entityMap.getHeadMapFromRealm(realm); - const array = map.dataClient.getArray(map.arrayId, map.arrayIndexId, { - listen: false, - }); - const update = array.removeAt(this.entityMap.arrayIndexId); - realm.emitUpdate(update); - } - - getKeys() { - const realm = this.headTracker.getHeadRealm(); - const map = this.entityMap.getHeadMapFromRealm(realm); - const keys = map.getKeys(); - return keys; - } - - toObject() { - const realm = this.headTracker.getHeadRealm(); - const map = this.entityMap.getHeadMapFromRealm(realm); - return map.toObject(); - } -} - -// - -export class NetworkRealm extends EventTarget { - constructor(key, parent) { - super(); - - this.parent = parent; - - this.key = key; - this.connected = false; - - const dc1 = new DataClient({ - crdt: new Map(), - userData: { - realm: this, - }, - }); - this.dataClient = dc1; - this.ws = null; - this.networkedDataClient = new NetworkedDataClient(dc1, { - userData: { - realm: this, - }, - }); - this.networkedCrdtClient = new NetworkedCrdtClient(); - this.networkedLockClient = new NetworkedLockClient(); - this.networkedIrcClient = new NetworkedIrcClient(this.parent.playerId); - this.networkedAudioClient = new NetworkedAudioClient({ - playerId: this.parent.playerId, - // audioManager: this.parent.audioManager, - }); - this.networkedVideoClient = new NetworkedVideoClient({ - playerId: this.parent.playerId, - }); - - // this.microphoneSource = null; - } - - sendChatMessage(message) { - this.networkedIrcClient.sendChatMessage(message); - } - - async connect() { - this.dispatchEvent(new Event('connecting')); - - const ws1 = createWs(this.parent.endpointUrl, 'realm:' + this.key, this.parent.playerId); - ws1.binaryType = 'arraybuffer'; - this.ws = ws1; - this.ws.onerror = err => { - console.warn(err); - // if (this.connected) { - // this.disconnect({ - // errored: true, - // }); - // } - }; - this.ws.onclose = () => { - // if (this.connected) { - this.disconnect(); - // } - }; - await Promise.all([ - this.networkedDataClient.connect(ws1).then(() => { - // console.log('networkedDataClient connected'); - }), - this.networkedCrdtClient.connect(ws1).then(() => { - // console.log('networkedCrdtClient connected'); - }), - this.networkedLockClient.connect(ws1).then(() => { - // console.log('networkedLockClient connected'); - }), - this.networkedIrcClient.connect(ws1).then(() => { - // console.log('networkedIrcClient connected'); - }), - this.networkedAudioClient.connect(ws1).then(() => { - // console.log('networkedAudioClient connected'); - }), - this.networkedVideoClient.connect(ws1).then(() => { - // console.log('networkedVideoClient connected'); - }), - ]); - this.connected = true; - - this.dispatchEvent(new Event('connect')); - } - - *getClearUpdateFns() { - const playersArray = this.dataClient.getArray('players', { - listen: false, - }); - - // players - const playerIds = playersArray.getKeys(); - for (const playerId of playerIds) { - const playerAppsArray = this.dataClient.getArray('playerApps:' + playerId, { - listen: false, - }); - const playerActionsArray = this.dataClient.getArray('playerActions:' + playerId, { - listen: false, - }); - - // actions - for (const actionId of playerActionsArray.getKeys()) { - yield () => playerActionsArray.removeAt(actionId); - } - // apps - for (const appId of playerAppsArray.getKeys()) { - yield () => playerAppsArray.removeAt(appId); - } - // player - yield () => playersArray.removeAt(playerId); - } - } - - flush() { - const clearUpdateFns = this.getClearUpdateFns(); - for (const clearUpdateFn of clearUpdateFns) { - const clearUpdate = clearUpdateFn(); - this.dataClient.emitUpdate(clearUpdate); - } - } - - disconnect() { - // this.dispatchEvent(new Event('disconnecting')); - - this.connected = false; - - if (this.ws.readyState === WebSocket.OPEN) { - if (this.ws.terminate) { - this.ws.terminate(); - } else { - this.ws.close(); - } - } - - this.dispatchEvent(new MessageEvent('disconnect', { - data: {}, - })); - } - - emitUpdate(update) { - this.dataClient.emitUpdate(update); - this.networkedDataClient.emitUpdate(update); - } -} - -// - -class VirtualWorld extends EventTarget { - constructor(arrayId, realms, opts) { - super(); - - this.worldApps = new VirtualEntityArray(arrayId, realms, { - entityTracker: opts?.entityTracker, - }); - } - - link(realm) { - this.worldApps.link(realm); - } - - unlink(realm) { - this.worldApps.unlink(realm); - } -} - -// - -// The set of network realms at and surrounding the player's current location in the current scene. -// Properties: -// - localPlayer - The user's player object. -// Events: -// - realmconnecting - MessageEvent fired when a connection to a new realm is being established. Event data contains the -// NetworkRealm being connected to. -// - realmjoin - MessageEvent fired when a connection to a new realm has been established. Event data contains the NetworkRealm -// that has been connected to. -// - realmleave - MessageEvent fired when a connection to an old realm has been removed. Event data contains the NetworkRealm -// that has been disconnected from. -// - networkreconfigure - MessageEvent fired when the set of realms connected to changes. Event data is empty. -// - chat - MessageEvent fired when a chat message is receive from a remote player in the realms. Event data contains the chat -// message. -export class NetworkRealms extends EventTarget { - // Constructs a NetworkRealms object and connects the local player to multiplayer. - // - endpointUrl - The URL of the multiplayer server to connect to. - // - sceneId - A unique alphanumeric string identifying the scene. - // - playerId - A unique alphanumeric string identifying the local player. - // - audioContext - The Web Audio API AudioContext to use for audio. - // The 'chat' event is dispatched within VirtualIrc. - constructor({ - endpointUrl, - playerId, - // audioManager, - // metadata = null, - }) { - super(); - - if (!endpointUrl /* || !playerId || !audioManager*/) { - console.warn('got bad network realms args', { - endpointUrl, - // playerId, - // audioManager, - }); - // throw new Error('invalid arguments'); - debugger; - } - this.endpointUrl = endpointUrl; - this.playerId = playerId; - // this.audioManager = audioManager; - // this.metadata = metadata; - - // this.lastKey = ''; - // this.lastPosition = [NaN, NaN, NaN]; - this.appsEntityTracker = new EntityTracker(); - this.localPlayer = this.playerId ? new VirtualPlayer('players', this.playerId, this, 'local', { - appsEntityTracker: this.appsEntityTracker, - }) : null; - this.world = new VirtualWorld('worldApps', this, { - entityTracker: this.appsEntityTracker, - }); - - this.lastRealmsKeys = []; - this.lastRootRealmKey = null; - - // Provide entity add/remove events. - this.appsEntityTracker.addEventListener('entityadd', e => { - // Add to the event queue after allowing internal event handlers to have been called. - // setTimeout(() => { - // console.log('check is updating', e.data.realm.parent.isUpdating()); - if (!e.data.realm.parent.isUpdating()) { - this.dispatchEvent(new MessageEvent('entityadd', {data: e.data})); - } - // }, 0); - }); - this.appsEntityTracker.addEventListener('entityremove', e => { - // Add to the event queue after allowing internal event handlers to have been called. - // setTimeout(() => { - if (!e.data.realm.parent.isUpdating()) { - this.dispatchEvent(new MessageEvent('entityremove', {data: e.data})); - } - // }, 0); - }); - this.appsEntityTracker.addEventListener('entitytransplant', e => { - if (!e.data.realm.parent.isUpdating()) { - this.dispatchEvent(new MessageEvent('entitytransplant', {data: e.data})); - } - }); - - this.players = new VirtualPlayersArray('players', this, { - appsEntityTracker: this.appsEntityTracker, - }); - if (this.localPlayer) { - this.localPlayer.headTracker.onMigrate = async e => { - const {oldHeadRealm, newHeadRealm} = e.data; - - console.log('migrate', oldHeadRealm.key, '->', newHeadRealm.key); - - // old objects - const oldPlayersArray = oldHeadRealm.dataClient.getArray(this.localPlayer.arrayId, { - listen: false, - }); - const oldPlayerAppsArray = oldHeadRealm.dataClient.getArray('playerApps:' + this.playerId, { - listen: false, - }); - const oldPlayerActionsArray = oldHeadRealm.dataClient.getArray('playerActions:' + this.playerId, { - listen: false, - }); - const oldPlayerMap = oldPlayersArray.getMap(this.playerId, { - listen: false, - }); - - // new objects - /* const newPlayersArray = newHeadRealm.dataClient.getArray(this.localPlayer.arrayId, { - listen: false, - }); - const newPlayerAppsArray = newHeadRealm.dataClient.getArray('playerApps:' + this.playerId, { - listen: false, - }); - const newPlayerActionsArray = newHeadRealm.dataClient.getArray('playerActions:' + this.playerId, { - listen: false, - }); */ - - // set dead hands - const deadHandKeys = [ - this.localPlayer.arrayId + '.' + this.localPlayer.arrayIndexId, // player - 'playerApps:' + this.localPlayer.arrayIndexId, // playerApps - 'playerActions:' + this.localPlayer.arrayIndexId, // playerActions - ]; - const _emitDeadHands = realm => { - const deadHandupdate = realm.dataClient.deadHandKeys(deadHandKeys, this.playerId); - realm.emitUpdate(deadHandupdate); - }; - _emitDeadHands(oldHeadRealm); - _emitDeadHands(newHeadRealm); - - // add new - // import apps - const _applyMessageToRealm = (realm, message) => { - const uint8Array = serializeMessage(message); - const updateObject = parseUpdateObject(uint8Array); - const { - rollback, - update, - } = realm.dataClient.applyUpdateObject(updateObject, { - force: true, // since coming from the server - }); - if (rollback) { - throw new Error('migrate failed 1'); - } - if (update) { - realm.emitUpdate(update); - } else { - throw new Error('migrate failed 2'); - } - }; - const _importPlayer = () => { - const playerAppsImportMessages = oldPlayerAppsArray.importArrayUpdates(); - for (const m of playerAppsImportMessages) { - _applyMessageToRealm(newHeadRealm, m); - } - // import actions - const playerActionsImportMessages = oldPlayerActionsArray.importArrayUpdates(); - for (const m of playerActionsImportMessages) { - _applyMessageToRealm(newHeadRealm, m); - } - // import player - const playerImportMessage = oldPlayerMap.importMapUpdate(); - _applyMessageToRealm(newHeadRealm, playerImportMessage); - }; - _importPlayer(); - - // migrate networked audio client - this.migrateAudioRealm(oldHeadRealm, newHeadRealm); - this.migrateVideoRealm(oldHeadRealm, newHeadRealm); - - await this.sync(); - - // delete old - // delete apps - const _deleteOldArrayMaps = () => { - for (const arrayIndexId of oldPlayerAppsArray.getKeys()) { - const update = oldPlayerAppsArray.removeAt(arrayIndexId); - oldHeadRealm.emitUpdate(update); - } - // delete actions - for (const arrayIndexId of oldPlayerActionsArray.getKeys()) { - const update = oldPlayerActionsArray.removeAt(arrayIndexId); - oldHeadRealm.emitUpdate(update); - } - // delete player - const oldPlayerRemoveUpdate = oldPlayerMap.removeUpdate(); - oldHeadRealm.emitUpdate(oldPlayerRemoveUpdate); - }; - _deleteOldArrayMaps(); - }; - } - - this.irc = new VirtualIrc(this); - this.connectedRealms = new Set(); - this.migrateTx = makeTransactionHandler(); - - this.realmsCleanupFns = new Map(); - this.addEventListener('realmjoin', e => { - const {realm} = e.data; - const {dataClient, networkedDataClient} = realm; - - const onsyn = e => { - const {synId} = e.data; - const synAckMessage = dataClient.getSynAckMessage(synId); - networkedDataClient.emitUpdate(synAckMessage); - }; - dataClient.addEventListener('syn', onsyn); - - const cleanupFns = [ - () => { - dataClient.removeEventListener('syn', onsyn); - }, - ]; - - this.realmsCleanupFns.set(realm, () => { - for (const cleanupFn of cleanupFns) { - cleanupFn(); - } - }); - }); - this.addEventListener('realmleave', e => { - const {realm} = e.data; - - const fn =this.realmsCleanupFns.get(realm); - if (fn) { - fn(); - this.realmsCleanupFns.delete(realm); - } - - this.connectedRealms.delete(realm); - - // if no more realms, dispatchEvent disconnect - // console.log('remaining size', this.connectedRealms.size); - if (this.connectedRealms.size === 0) { - this.dispatchEvent(new MessageEvent('disconnect', { - data: {}, - })); - } - }); - - this.audioSources = []; - this.videoSources = []; - } - - #updating = false; - isUpdating() { - return this.#updating; - } - tx(fn) { - this.#updating = true; - // console.log('set updating 1'); - try { - fn(); - } finally { - this.#updating = false; - // console.log('set updating 2'); - } - } - - // Gets the other players also present in the local player's NetworkRealms. - getVirtualPlayers() { - return this.players; - } - - // Gets the world of apps present in the local player's NetworkRealms. - getVirtualWorld() { - return this.world; - } - - // Gets the realm connected to at the player's position. - // Returns: The NetworkRealm at the player's position if there is one connected to, null if there's none. - // XXX in the future, this can be done by passing in a predicate function - getClosestRealm(realmKey) { - for (const realm of this.connectedRealms) { - if (realm.connected) { - if (realm.key === realmKey) { - return realm; - } - } - } - return null; - } - - // Internal method. - async sync() { - // for all realms - const promises = Array.from(this.connectedRealms.values()).map(async realm => { - const {dataClient} = realm; - - const playersArray = dataClient.getArray('players', { - listen: false, - }); - const playersArrayMaps = playersArray.getMaps(); - const numPlayers = playersArrayMaps.filter(player => player.arrayIndexId !== this.playerId).length; - // console.log('sync', numPlayers, playersArray.getKeys(), playersArrayMaps, this.playerId); - if (numPlayers > 0) { - const synId = makeId(); - const synMessage = dataClient.getSynMessage(synId); - realm.networkedDataClient.emitUpdate(synMessage); - // console.log('emit to ws', realm.key, playersArrayMaps.map(p => p.arrayIndexId), realm.networkedDataClient.ws.readyState); - - // wait for >= numPlayers synAcks, with a 2-second timeout - await new Promise((resolve, reject) => { - let seenSynAcks = 0; - const onSynAck = e => { - if (e.data.synId === synId) { - seenSynAcks++; - if (seenSynAcks >= numPlayers) { - cleanup(); - resolve(); - } - } - }; - dataClient.addEventListener('synAck', onSynAck); - - const timeout = setTimeout(() => { - console.log('timeout', realm.key, playersArrayMaps); - cleanup(); - resolve(); - }, 2000); - - const cleanup = () => { - dataClient.removeEventListener('synAck', onSynAck); - clearTimeout(timeout); - }; - }); - } else { - // throw new Error('expected at least 1 player'); - } - }); - await Promise.all(promises); - } - - addAudioSource(audioSource) { - const headRealm = this.localPlayer.headTracker.getHeadRealm(); - const {networkedAudioClient} = headRealm; - - this.audioSources.push(audioSource); - - return networkedAudioClient.addAudioSource(audioSource); - } - removeAudioSource(audioSource) { - const index = this.audioSources.indexOf(audioSource); - if (index !== -1) { - this.audioSources.splice(index, 1); - - const headRealm = this.localPlayer.headTracker.getHeadRealm(); - const {networkedAudioClient} = headRealm; - networkedAudioClient.removeAudioSource(audioSource); - } else { - console.warn('audio source not found', audioSource); - } - } - // Internal method. - migrateAudioRealm(oldRealm, newRealm) { - const {networkedAudioClient: oldNetworkedAudioClient} = oldRealm; - const {networkedAudioClient: newNetworkedAudioClient} = newRealm; - for (const audioSource of this.audioSources) { - oldNetworkedAudioClient.removeAudioSource(audioSource); - newNetworkedAudioClient.addAudioSource(audioSource); - } - } - - addVideoSource(videoSource) { - const headRealm = this.localPlayer.headTracker.getHeadRealm(); - const {networkedVideoClient} = headRealm; - - return networkedVideoClient.addVideoSource(videoSource); - } - removeVideoSource(videoSource) { - const index = this.videoSources.indexOf(videoSource); - if (index !== -1) { - this.videoSources.splice(index, 1); - - const headRealm = this.localPlayer.headTracker.getHeadRealm(); - const {networkedVideoClient} = headRealm; - networkedVideoClient.removeVideoSource(videoSource); - } else { - console.warn('video source not found', videoSource); - } - } - // Internal method. - migrateVideoRealm(oldRealm, newRealm) { - const {networkedVideoClient: oldNetworkedVideoClient} = oldRealm; - const {networkedVideoClient: newNetworkedVideoClient} = newRealm; - for (const videoSource of this.videoSources) { - oldNetworkedVideoClient.removeVideoSource(videoSource); - newNetworkedVideoClient.addVideoSource(videoSource); - } - } - - isConnected() { - const headRealm = this.getClosestRealm(this.lastRootRealmKey); - return !!headRealm; - } - - // Sends a chat message to the realm that the local player is in. - // - message - String to send. - sendChatMessage(message) { - // const headRealm = this.localPlayer.headTracker.getHeadRealm(); - const headRealm = this.getClosestRealm(this.lastRootRealmKey); - if (headRealm) { - headRealm.sendChatMessage(message); - } else { - throw new Error('no connected realm to send chat message to: ' + this.lastRootRealmKey + ': ' + Array.from(this.connectedRealms.values()).map(realm => realm.key).join(',') + '\n' + new Error().stack); - } - } - - // Updates the set of realms connected to based on the local player's position. - // - realmsKeys: The realm string keys to connect to; the first one is the one the local player is in. - // - onConnect: Optional callback to call when the realms are connected to. - async updateRealmsKeys({ - realmsKeys = [], - rootRealmKey = realmsKeys.length > 0 ? realmsKeys[0] : null, - } = {}) { - // if (realmsKeys.length === 0) { - // throw new Error('at least one realm key required'); - // } - - // const snappedPosition = position.map(v => Math.floor(v / realmSize) * realmSize); - /* if (!arrayEquals(snappedPosition, this.lastPosition)) */ - if (!arrayEquals(realmsKeys, this.lastRealmsKeys)) { - // this.lastPosition[0] = snappedPosition[0]; - // this.lastPosition[1] = snappedPosition[1]; - // this.lastPosition[2] = snappedPosition[2]; - this.lastRealmsKeys = realmsKeys; - - await this.migrateTx(async () => { - const oldNumConnectedRealms = this.connectedRealms.size; - - const candidateRealms = []; - for (let i = 0; i < realmsKeys.length; i++) { - const realmsKey = realmsKeys[i]; - // for (let dx = -1; dx <= 1; dx++) { - // const min = [ - // Math.floor((snappedPosition[0] + dx * realmSize) / realmSize) * realmSize, - // 0, - // Math.floor((snappedPosition[2] + dz * realmSize) / realmSize) * realmSize, - // ]; - const realm = new NetworkRealm(realmsKey, /*min, realmSize,*/ this); - realm.addEventListener('disconnect', e => { - // const { - // errored, - // } = e.data; - - // if (errored) { - // this.connectedRealms.delete(realm); - // this performs the actual removal - this.dispatchEvent(new MessageEvent('realmleave', { - data: { - realm, - }, - })); - // } - }); - candidateRealms.push(realm); - // } - } - - // check if we need to connect to new realms - const connectPromises = []; - for (const realm of candidateRealms) { - let foundRealm = null; - for (const connectedRealm of this.connectedRealms) { - if (connectedRealm.key === realm.key) { - foundRealm = connectedRealm; - break; - } - } - - if (!foundRealm) { - this.dispatchEvent(new MessageEvent('realmconnecting', { - data: { - realm, - }, - })); - - const connectPromise = (async () => { - await realm.connect(); - - this.players.link(realm); - this.localPlayer && this.localPlayer.link(realm); - this.world.link(realm); - this.irc.link(realm); - - this.connectedRealms.add(realm); - - this.dispatchEvent(new MessageEvent('realmjoin', { - data: { - realm, - }, - })); - })(); - connectPromises.push(connectPromise); - } - } - await Promise.all(connectPromises); - - this.lastRootRealmKey = rootRealmKey; - - // if this is the first network configuration, initialize our local player - if (oldNumConnectedRealms === 0 && connectPromises.length > 0) { - // onConnect && await onConnect(); - let promise = Promise.resolve(); - const e = new MessageEvent('connect', { - data: { - rootRealmKey, - }, - }); - e.waitUntil = p => { - promise = p; - }; - this.dispatchEvent(e); - - await promise; - } - // we are in the middle of a network configuration, so take the opportunity to migrate the local player if necessary - // await this.localPlayer.headTracker.tryMigrate(position); - this.localPlayer && await this.localPlayer.headTracker.tryMigrate(rootRealmKey); - - // check if we need to disconnect from any realms - const oldRealms = []; - for (const connectedRealm of this.connectedRealms) { - if (!candidateRealms.find(candidateRealm => candidateRealm.key === connectedRealm.key)) { - // first, disconnect to make sure no corrupted state goes on the network - connectedRealm.disconnect(); - - // note: we must perform a flush before unlinking - // otherwise, the remove handlers will be unlinked by the time we emit - connectedRealm.flush(); - - // unlink arrays - this.players.unlink(connectedRealm); - this.localPlayer && this.localPlayer.unlink(connectedRealm); - this.world.unlink(connectedRealm); - this.irc.unlink(connectedRealm); - - // bookkeeping - // this.connectedRealms.delete(connectedRealm); - oldRealms.push(connectedRealm); - } - } - for (const oldRealm of oldRealms) { - // this performs the actual removal - this.dispatchEvent(new MessageEvent('realmleave', { - data: { - realm: oldRealm, - }, - })); - } - - // emit the fact that the network was reconfigured - this.dispatchEvent(new MessageEvent('networkreconfigure', { - data: {}, - })); - }); - } - } - - // Disconnects the local player from multiplayer. - disconnect() { - for (const connectedRealm of this.connectedRealms) { - connectedRealm.disconnect(); - connectedRealm.flush(); - this.players.unlink(connectedRealm); - this.localPlayer.unlink(connectedRealm); - this.world.unlink(connectedRealm); - this.irc.unlink(connectedRealm); - // this.connectedRealms.delete(connectedRealm); - // this performs the actual removal - // this.dispatchEvent(new MessageEvent('realmleave', { - // data: { - // realm: connectedRealm, - // }, - // })); - } - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/renderers/html-renderer.js b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/renderers/html-renderer.js deleted file mode 100644 index bc8867e86..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/renderers/html-renderer.js +++ /dev/null @@ -1,625 +0,0 @@ -import {frameSize, realmSize, inventoryFrameSize} from '../constants.js'; -import {zstringify} from '../util.mjs'; - -// - -const rockImg = new Image(); -rockImg.src = '/public/images/rock.png'; - -// - -/* export class LocalPlayerHtmlRenderer { - constructor(localPlayerId, virtualPlayer) { - this.localPlayerId = localPlayerId; - this.virtualPlayer = virtualPlayer; - - const div = document.createElement('div'); - div.id = 'inventory'; - document.body.appendChild(div); - - // const playerAppsEntityAdd = e => { - // console.log('html renderer got player apps add', e.data); - // }; - // virtualPlayer.playerApps.addEventListener('entityadd', playerAppsEntityAdd); - - // const playerActionsEntityAdd = e => { - // console.log('html renderer got player actions add', e.data); - // }; - // virtualPlayer.playerActions.addEventListener('entityadd', playerActionsEntityAdd); - - this.cleanupFn = () => { - document.body.removeChild(div); - - // virtualPlayer.removeEventListener('entityadd', playerAppsEntityAdd); - // virtualPlayer.removeEventListener('entityadd', playerActionsEntityAdd); - }; - } - destroy() { - this.cleanupFn(); - } -} */ - -export class RemotePlayerCursorHtmlRenderer { - constructor(remotePlayerId, localPlayerId, virtualPlayer) { - this.remotePlayerId = remotePlayerId; - this.localPlayerId = localPlayerId; - this.virtualPlayer = virtualPlayer; - - const div = document.createElement('div'); - div.className = 'player-cursor'; - div.style.cssText = `\ - background-color: ${this.remotePlayerId === this.localPlayerId ? 'blue' : 'red'}; - `; - document.body.appendChild(div); - - // console.log('new cursor'); - - // const map = this.dataClient.getArrayMap('players', this.remotePlayerId); - // console.log('virtual player update listen'); - const update = e => { - // console.log('html renderer got player map update', e.data); - - const {key, val} = e.data; - // console.log('got key', key); - if (key === 'cursorPosition') { - const [x, y, z] = val; - div.style.transform = `translate3d(${x}px, ${y}px, 0)`; - } - }; - virtualPlayer.addEventListener('update', update); - - this.cleanupFn = () => { - document.body.removeChild(div); - - virtualPlayer.removeEventListener('update', update); - }; - } - - destroy() { - this.cleanupFn(); - } -} - -// - -export class AppsHtmlRenderer { - constructor(realms) { - const _render = () => { - const worldAppsEl = document.getElementById('world-apps'); - - let worldAppIndex = 0; - const playerAppIndexes = new Map(); - const _makeAppEl = () => { - const appEl = rockImg.cloneNode(); - appEl.classList.add('world-app'); - return appEl; - }; - const _pushWorldApp = needledEntity => { - const wearSpec = _getWearSpec(needledEntity); - if (wearSpec) { - // console.log('got wear spec', wearSpec); - const { - wearPlayerId, - wearNeedledEntity, - } = wearSpec; - // if (wearPlayerId !== realms.playerId) { - // debugger; - // throw new Error('only local player is supported'); - // } - - const playerAppIndex = playerAppIndexes.get(wearPlayerId) ?? 0; - playerAppIndexes.set(wearPlayerId, playerAppIndex + 1); - - const playerEl = document.getElementById(`player-${wearPlayerId}`); - const playerApps = playerEl.querySelector('.player-apps'); - const had = !!playerApps.childNodes[playerAppIndex]; - const appEl = playerApps.childNodes[playerAppIndex] || _makeAppEl(); - - // appEl.style.left = `${playerAppIndex * inventoryFrameSize}px`; - // appEl.style.top = null; - appEl.style.transform = `translate3d(${playerAppIndex * inventoryFrameSize}px, 0, 0)`; - - // console.log('append child', wearPlayerId, needledEntity.arrayIndexId); - - !had && playerApps.appendChild(appEl); - - // debugger; - } else { - // console.log('world app'); - - const had = !!worldAppsEl.childNodes[worldAppIndex]; - const appEl = worldAppsEl.childNodes[worldAppIndex] || _makeAppEl(); - - const app = needledEntity.toObject(); - const position = app.position ?? [0, 0, 0]; - // appEl.style.left = `${position[0]}px`; - // appEl.style.top = `${position[2]}px`; - appEl.style.transform = `translate3d(${position[0]}px, ${position[2]}px, 0)`; - - !had && worldAppsEl.appendChild(appEl); - - worldAppIndex++; - } - }; - const _finalizeWorldApps = () => { - while (worldAppsEl.children.length > worldAppIndex) { - worldAppsEl.removeChild(worldAppsEl.lastChild); - } - - const playersEl = document.getElementById('players'); - for (const playerEl of playersEl.childNodes) { - const playerApps = playerEl.querySelector('.player-apps'); - const playerId = playerEl.id.slice('player-'.length); - const playerAppIndex = playerAppIndexes.get(playerId) ?? 0; - while (playerApps.children.length > playerAppIndex) { - playerApps.removeChild(playerApps.lastChild); - } - } - }; - - for (const needledEntity of worldAppEntities.values()) { - _pushWorldApp(needledEntity); - } - _finalizeWorldApps(); - }; - const update = () => { - _render(); - }; - const _getWearSpec = virtualEntity => { - const playerActionIdsMap = new Map(); - const allPlayerActions = Array.from(playerActions.values()).concat( - Array.from(remotePlayerActions.values()) - .flatMap(set => Array.from(set)), - ); - /* const allPlayerActions = realms.localPlayer.playerActions.getValues() - .concat( - realms.players.getValues() - .flatMap(player => player.playerActions.getValues()) - ); */ - allPlayerActions.forEach(playerAction => { - const match = playerAction.arrayId.match(/^([^:]+?):([^:]+?)$/); - if (match) { - const playerId = match[2]; - playerActionIdsMap.set(playerAction.entityMap.arrayIndexId, playerId); - } else { - debugger; - } - }); - - const actionIds = allPlayerActions.map(a => a.arrayIndexId); - const actions = Array.from(allPlayerActions.values()).map(playerAction => playerAction.toObject()); - const wearActionIndex = actions.findIndex(action => action.action === 'wear' && action.appId === virtualEntity.entityMap.arrayIndexId); - const wearAction = actions[wearActionIndex]; - const wearActionId = actionIds[wearActionIndex]; // XXX wrong - - if (wearAction) { - const wearPlayerId = playerActionIdsMap.get(wearActionId); - const wearNeedledEntity = playerApps.get(wearAction.appId); - return { - wearPlayerId, - wearNeedledEntity, - }; - } else { - return null; - } - }; - - // local players - const playerApps = new Map(); - const playerActions = new Map(); - realms.localPlayer.playerApps.addEventListener('needledentityadd', e => { - // console.log('got app', e.data); - const {needledEntity} = e.data; - playerApps.set(needledEntity.entityMap.arrayIndexId, needledEntity); - - needledEntity.addEventListener('update', update); - }); - realms.localPlayer.playerApps.addEventListener('needledentityremove', e => { - // console.log('remove app', e.data); - const {needledEntity} = e.data; - - needledEntity.removeEventListener('update', update); - - playerApps.delete(needledEntity.entityMap.arrayIndexId); - }); - realms.localPlayer.playerActions.addEventListener('needledentityadd', e => { - const {needledEntity} = e.data; - playerActions.set(needledEntity.entityMap.arrayIndexId, needledEntity); - - update(); - }); - realms.localPlayer.playerActions.addEventListener('needledentityremove', e => { - const {needledEntity} = e.data; - playerActions.delete(needledEntity.entityMap.arrayIndexId); - - update(); - }); - - // remote players - const remotePlayerActions = new Map(); - const remotePlayersCleanupFns = new Map(); - realms.players.addEventListener('join', e => { - // console.log('remote player join', e.data); - const {playerId, player} = e.data; - - const localRemotePlayerActions = new Set(); - remotePlayerActions.set(playerId, localRemotePlayerActions); - const onappadd = e => { - const {entityId, needledEntity} = e.data; - localRemotePlayerActions.add(needledEntity); - - update(); - }; - player.playerActions.addEventListener('needledentityadd', onappadd); - const onappremove = e => { - const {entityId, needledEntity} = e.data; - // if (!needledEntity) { - // debugger; - // } - localRemotePlayerActions.delete(needledEntity); - - update(); - }; - player.playerActions.addEventListener('needledentityremove', onappremove); - - // intialize starting actions - for (const playerActionId of player.playerActions.getKeys()) { - const needledEntity = player.playerActions.getVirtualMap(playerActionId); - localRemotePlayerActions.add(needledEntity); - } - - remotePlayersCleanupFns.set(playerId, () => { - player.playerApps.removeEventListener('needledentityadd', onappadd); - player.playerApps.removeEventListener('needledentityremove', onappremove); - - remotePlayerActions.delete(playerId); - }); - - update(); - }); - realms.players.addEventListener('leave', e => { - // console.log('remote player leave', e.data); - const {playerId} = e.data; - remotePlayersCleanupFns.get(playerId)(); - remotePlayersCleanupFns.delete(playerId); - - update(); - }); - - // world apps - const worldAppEntities = new Map(); - const virtualWorld = realms.getVirtualWorld(); - virtualWorld.worldApps.addEventListener('needledentityadd', e => { - const {needledEntity} = e.data; - - worldAppEntities.set(needledEntity.entityMap.arrayIndexId, needledEntity); - - // needledEntity.addEventListener('update', update); - - update(); - }); - virtualWorld.worldApps.addEventListener('needledentityremove', e => { - const {needledEntity} = e.data; - // const realm = needledEntity.headTracker.getHeadRealm(); - - worldAppEntities.delete(needledEntity.entityMap.arrayIndexId); - - // needledEntity.removeEventListener('update', update); - - update(); - }); - - window.realms = realms; - window.playerApps = playerApps; - window.playerActions = playerActions; - window.worldAppEntities = worldAppEntities; - window.sanityCheck = () => { - Array.from(playerActions.values()).map(playerAction => playerAction.toObject()); - }; - } -} - -// - -const spriteUrl = '/public/images/fire-mage.png'; -export class GamePlayerCanvas { - constructor(virtualPlayer, { - local = true, - } = {}) { - this.virtualPlayer = virtualPlayer; - this.local = local; - - this.element = document.createElement('div'); - this.element.id = `player-${virtualPlayer.arrayIndexId}`; - // this.element.className = 'game-player'; - this.element.classList.add('player-sprite'); - - this.element.tabIndex = -1; - - this.canvas = document.createElement('canvas'); - this.canvas.width = frameSize; - this.canvas.height = frameSize; - this.ctx = this.canvas.getContext('2d'); - this.element.appendChild(this.canvas); - - const playerAppsEl = document.createElement('div'); - playerAppsEl.className = 'player-apps'; - this.element.appendChild(playerAppsEl); - - this.velocity = [0, 0, 0]; - this.cancelFn = null; - - const update = e => { - const {key, val} = e.data; - if (['position', 'direction'].includes(key)) { - this.draw(); - } - if (key === 'position') { - // console.log('position update event', key, val, new Error().stack); - } - }; - virtualPlayer.addEventListener('update', update); - - this.destroy = () => { - virtualPlayer.removeEventListener('update', update); - }; - } - - move() { - const oldPosition = this.virtualPlayer.getKeyValue('position'); - const oldDirection = this.virtualPlayer.getKeyValue('direction'); - - const speed = 5; - - const _updatePosition = () => { - const position = [ - oldPosition[0], - oldPosition[1], - oldPosition[2], - ]; - if (this.velocity[0] !== 0 || this.velocity[2] !== 0) { - position[0] += this.velocity[0] * speed; - position[2] += this.velocity[2] * speed; - - this.virtualPlayer.setKeyValue('position', position); - } - }; - _updatePosition(); - const _updateDirection = () => { - const direction = [ - oldDirection[0], - oldDirection[1], - oldDirection[2], - ]; - let directionChanged = false; - if (this.velocity[2] < 0) { - direction[0] = 0; - direction[2] = -1; - directionChanged = true; - } else if (this.velocity[0] < 0) { - direction[0] = -1; - direction[2] = 0; - directionChanged = true; - } else if (this.velocity[0] > 0) { - direction[0] = 1; - direction[2] = 0; - directionChanged = true; - } else if (this.velocity[2] > 0) { - direction[0] = 0; - direction[2] = 1; - directionChanged = true; - } else { - // nothing - } - if (directionChanged) { - this.virtualPlayer.setKeyValue('direction', direction); - } - }; - _updateDirection(); - } - - draw() { - if (GamePlayerCanvas.#spriteImg) { - const direction = this.virtualPlayer.getKeyValue('direction'); - - let row; - if (direction[0] === -1) { - row = 1; - } else if (direction[0] === 1) { - row = 2; - } else if (direction[2] === -1) { - row = 3; - } else { - row = 0; - } - const timestamp = performance.now(); - const frameLoopTime = 200; - const col = Math.floor(timestamp / frameLoopTime) % 3; - - this.ctx.clearRect(0, 0, frameSize, frameSize); - this.ctx.drawImage(GamePlayerCanvas.#spriteImg, col * frameSize, row * frameSize, frameSize, frameSize, 0, 0, frameSize, frameSize); - - if (!this.local) { - const remotePlayerPosition = this.virtualPlayer.getKeyValue('position'); - // const localPlayerPosition = realms.localPlayer.getKeyValue('position'); - - this.element.style.transform = `translate3d(${remotePlayerPosition[0]}px, ${remotePlayerPosition[2]}px, 0)`; - } - } - } - - static #spriteImg = null; - static async waitForLoad() { - this.#spriteImg = await new Promise((accept, reject) => { - const img = new Image(); - img.onload = () => { - const canvas = document.createElement('canvas'); - canvas.width = img.width; - canvas.height = img.height; - const ctx = canvas.getContext('2d'); - // replace the color #24886d with transparent - ctx.drawImage(img, 0, 0); - const imageData = ctx.getImageData(0, 0, img.width, img.height); - const data = imageData.data; - const _isInRange = (v, base, range) => v >= (base - range) && v <= (base + range); - const _isInRangeN = (v, base) => _isInRange(v, base, 5); - for (let i = 0; i < data.length; i += 4) { - if (_isInRangeN(data[i], 0x24) && _isInRangeN(data[i+1], 0x88) && _isInRangeN(data[i+2], 0x6d)) { - data[i+3] = 0; - } - } - ctx.putImageData(imageData, 0, 0); - - accept(canvas); - }; - img.onerror = err => { - reject(err); - }; - img.src = spriteUrl; - }); - } - /* destroy() { - // nothing - } */ -} - -// - -const _drawRectangle = (ctx, color) => { - const innerBorder = 3; - const borderWidth = 3; - ctx.fillStyle = color; - ctx.fillRect(innerBorder, innerBorder, realmSize - innerBorder * 2, borderWidth); // top - ctx.fillRect(innerBorder, realmSize - borderWidth - innerBorder, realmSize - innerBorder * 2, borderWidth); // bottom - ctx.fillRect(innerBorder, innerBorder, borderWidth, realmSize - innerBorder * 2); // left - ctx.fillRect(realmSize - borderWidth - innerBorder, innerBorder, borderWidth, realmSize - innerBorder * 2); // right -}; -export class GameRealmsCanvases { - constructor(realms) { - // realm sections - this.element = document.createElement('div'); - this.element.id = 'network-realms'; - this.element.className = 'network-realms'; - - for (let dx = -1; dx <= 1; dx++) { - for (let dz = -1; dz <= 1; dz++) { - const canvas = document.createElement('canvas'); - canvas.className = 'canvas'; - canvas.width = realmSize; - canvas.height = realmSize; - const ctx = canvas.getContext('2d'); - _drawRectangle(ctx, '#CCC'); - - const x = dx + 1; - const z = dz + 1; - - const text = document.createElement('div'); - text.className = 'text'; - const text1 = document.createElement('div'); - text1.textContent = `${x}:${z}`; - text.appendChild(text1); - const text2 = document.createElement('div'); - text.appendChild(text2); - - const div = document.createElement('div'); - div.className = 'network-realm'; - // div.style.transform = `translate3d(${x * realmSize}px, ${z * realmSize}px, 0)`; - div.style.left = `${x * realmSize}px`; - div.style.top = `${z * realmSize}px`; - div.appendChild(canvas); - div.appendChild(text); - div.min = [x * realmSize, 0, z * realmSize]; - div.size = realmSize; - div.setColor = color => { - _drawRectangle(ctx, color); - }; - div.setText = text => { - text2.innerText = text; - // console.log('update text', div.min.join(',')); - }; - let needsTextUpdate = ''; - div.updateText = dataClient => { - const playersArray = dataClient.getArray('players', { - listen: false, - }); - const worldApps = dataClient.getArray('worldApps', { - listen: false, - }); - - const _formatArray = array => { - array = array.getKeys().map(arrayIndexId => { - const playerApp = array.getMap(arrayIndexId, { - listen: false, - }); - const playerAppJson = playerApp.toObject(); - return playerAppJson; - }); - return zstringify(array); - }; - const _updateText = () => { - let playersString = ''; - if (playersArray.getSize() > 0) { - playersString = `players: [\n${zstringify(playersArray.toArray())}\n]`; - } else { - playersString = `players: []`; - } - - for (const arrayIndexId of playersArray.getKeys()) { - // player apps - let playerAppsString = ''; - const playerAppsArray = dataClient.getArray('playerApps:' + arrayIndexId, { - listen: false, - }); - if (playerAppsArray.getSize() > 0) { - playerAppsString = ` playerApps: [\n${_formatArray(playerAppsArray)}\n]`; - } else { - playerAppsString = ` playerApps: []`; - } - playersString += '\n' + playerAppsString; - - // player actions - let playerActionsString = ''; - const playerActionsArray = dataClient.getArray('playerActions:' + arrayIndexId, { - listen: false, - }); - if (playerActionsArray.getSize()) { - playerActionsString = ` playerActions: [\n${_formatArray(playerActionsArray)}\n]`; - } else { - playerActionsString = ` playerActions: []`; - } - playersString += '\n' + playerActionsString; - } - - let worldAppsString = ''; - if (worldApps.getSize() > 0) { - worldAppsString = `worldApps: [\n${zstringify(worldApps.toArray())}\n]`; - } else { - worldAppsString = `worldApps: []`; - } - - const s = [ - playersString, - worldAppsString, - ].join('\n'); - needsTextUpdate = s; - }; - _updateText(); - }; - div.update = () => { - if (needsTextUpdate) { - div.setText(needsTextUpdate); - needsTextUpdate = ''; - } - }; - - this.element.appendChild(div); - } - } - } - - update() { - for (const div of this.element.childNodes) { - div.update(); - } - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/update-types.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/update-types.mjs deleted file mode 100644 index e73f843c2..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/update-types.mjs +++ /dev/null @@ -1,26 +0,0 @@ -export const UPDATE_METHODS = { - IMPORT: 1, - SYN: 2, - SYN_ACK: 3, - SET: 4, - ADD: 5, - REMOVE: 6, - ROLLBACK: 7, - DEAD_HAND: 8, - LIVE_HAND: 9, - NETWORK_INIT: 10, - JOIN: 11, - LEAVE: 12, - REGISTER: 13, - CHAT: 14, - AUDIO: 15, - AUDIO_START: 16, - AUDIO_END: 17, - VIDEO: 18, - VIDEO_START: 19, - VIDEO_END: 20, - CRDT_UPDATE: 21, - LOCK_REQUEST: 22, - LOCK_RESPONSE: 23, - LOCK_RELEASE: 24, -}; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/util.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/util.mjs deleted file mode 100644 index 5678b8da7..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/util.mjs +++ /dev/null @@ -1,408 +0,0 @@ -// import {MULTIPLAYER_PORT} from './constants.mjs'; -import {zbencode, zbdecode} from 'zjs'; -import {UPDATE_METHODS} from './update-types.mjs'; - -const alignN = n => index => { - const r = index % n; - return r === 0 ? index : (index + n - r); -}; -const align4 = alignN(4); - -const parseUpdateObject = uint8Array => zbdecode(uint8Array); - -function makeid(length) { - var result = ''; - var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - var charactersLength = characters.length; - for (var i = 0; i < length; i++) { - result += characters.charAt(Math.floor(Math.random() * charactersLength)); - } - return result; -} -const makeId = () => makeid(10); - -function parseMessage(m) { - const match = m.type.match(/^set\.(.+?)\.(.+?)$/); - if (match) { - const arrayId = match[1]; - const arrayIndexId = match[2]; - const {key, epoch, val} = m.data; - return { - type: 'set', - arrayId, - arrayIndexId, - key, - epoch, - val, - }; - } else { - const match = m.type.match(/^add\.(.+?)$/); - if (match) { - const arrayId = match[1]; - const {arrayIndexId, val} = m.data; - return { - type: 'add', - arrayId, - arrayIndexId, - val, - }; - } else { - const match = m.type.match(/^remove\.(.+?)$/); - if (match) { - const arrayId = match[1]; - const {arrayIndexId} = m.data; - return { - type: 'remove', - arrayId, - arrayIndexId, - }; - } else { - if (m.type === 'rollback') { - const {arrayId, arrayIndexId, key, oldEpoch, oldVal} = m.data; - return { - type: 'rollback', - arrayId, - arrayIndexId, - key, - oldEpoch, - oldVal, - }; - } else if (m.type === 'import') { - return { - type: 'import', - crdtExport: m.data.crdtExport, - }; - } else if (m.type === 'syn') { - const {synId} = m.data; - return { - type: 'syn', - synId, - }; - } else if (m.type === 'synAck') { - const {synId} = m.data; - return { - type: 'synAck', - synId, - }; - } else if (m.type === 'deadhand') { - const {keys, deadHand} = m.data; - return { - type: 'deadhand', - keys, - deadHand, - }; - } else if (m.type === 'livehand') { - const {keys, liveHand} = m.data; - return { - type: 'livehand', - keys, - liveHand, - }; - } else if (m.type === 'networkinit') { - return { - type: 'networkinit', - playerIds: m.data.playerIds, - }; - } else if (m.type === 'join') { - return { - type: 'join', - playerId: m.data.playerId, - }; - } else if (m.type === 'leave') { - return { - type: 'leave', - playerId: m.data.playerId, - }; - } else if (m.type === 'register') { - const {playerId} = m.data; - return { - type: 'register', - playerId, - }; - } else if (m.type === 'crdtUpdate') { - const {update} = m.data; - return { - type: 'crdtUpdate', - update, - }; - } else if (m.type === 'lockRequest') { - const {lockName} = m.data; - return { - type: 'lockRequest', - lockName, - }; - } else if (m.type === 'lockResponse') { - const {lockName} = m.data; - return { - type: 'lockResponse', - lockName, - }; - } else if (m.type === 'lockRelease') { - const {lockName} = m.data; - return { - type: 'lockRelease', - lockName, - }; - } else { - console.warn('failed to parse', m); - throw new Error('unrecognized message type: ' + m.type); - } - } - } - } -} - -function serializeMessage(m) { - const parsedMessage = parseMessage(m); - const {type, arrayId, arrayIndexId} = parsedMessage; - switch (type) { - case 'import': { - const {crdtExport} = parsedMessage; - return zbencode({ - method: UPDATE_METHODS.IMPORT, - args: [ - crdtExport, - ], - }); - } - case 'syn': { - const {synId} = parsedMessage; - return zbencode({ - method: UPDATE_METHODS.SYN, - args: [ - synId, - ], - }); - } - case 'synAck': { - const {synId} = parsedMessage; - return zbencode({ - method: UPDATE_METHODS.SYN_ACK, - args: [ - synId, - ], - }); - } - case 'set': { - const {key, epoch, val} = m.data; - return zbencode({ - method: UPDATE_METHODS.SET, - args: [ - arrayId, - arrayIndexId, - key, - epoch, - val, - ], - }); - } - case 'add': { - const {arrayIndexId, val, epoch} = m.data; - return zbencode({ - method: UPDATE_METHODS.ADD, - args: [ - arrayId, - arrayIndexId, - val, - epoch, - ], - }); - } - case 'remove': { - const {arrayIndexId} = m.data; - return zbencode({ - method: UPDATE_METHODS.REMOVE, - args: [ - arrayId, - arrayIndexId, - ], - }); - } - case 'removeArray': { - return zbencode({ - method: UPDATE_METHODS.REMOVE_ARRAY, - args: [ - arrayId, - ], - }); - } - case 'rollback': { - const {arrayId, arrayIndexId, key, oldEpoch, oldVal} = m.data; - return zbencode({ - method: UPDATE_METHODS.ROLLBACK, - args: [ - arrayId, - arrayIndexId, - key, - oldEpoch, - oldVal, - ], - }); - } - case 'deadhand': { - // console.log('serialize dead hand'); - const {keys, deadHand} = m.data; - return zbencode({ - method: UPDATE_METHODS.DEAD_HAND, - args: [ - keys, - deadHand, - ], - }); - } - case 'livehand': { - // console.log('serialize live hand'); - const {keys, liveHand} = m.data; - return zbencode({ - method: UPDATE_METHODS.LIVE_HAND, - args: [ - keys, - liveHand, - ], - }); - } - case 'networkinit': { - const {playerIds} = m.data; - return zbencode({ - method: UPDATE_METHODS.NETWORK_INIT, - args: [ - playerIds, - ], - }); - } - case 'join': { - const {playerId} = m.data; - return zbencode({ - method: UPDATE_METHODS.JOIN, - args: [ - playerId, - ], - }); - } - case 'leave': { - const {playerId} = m.data; - return zbencode({ - method: UPDATE_METHODS.LEAVE, - args: [ - playerId, - ], - }); - } - case 'register': { - const {playerId} = m.data; - return zbencode({ - method: UPDATE_METHODS.REGISTER, - args: [ - playerId, - ], - }); - } - case 'crdtUpdate': { - const {update} = m.data; - return zbencode({ - method: UPDATE_METHODS.CRDT_UPDATE, - args: [ - update, - ], - }); - } - case 'lockRequest': { - const {lockName} = m.data; - return zbencode({ - method: UPDATE_METHODS.LOCK_REQUEST, - args: [ - lockName, - ], - }); - } - case 'lockResponse': { - const {lockName} = m.data; - return zbencode({ - method: UPDATE_METHODS.LOCK_RESPONSE, - args: [ - lockName, - ], - }); - } - case 'lockRelease': { - const {lockName} = m.data; - return zbencode({ - method: UPDATE_METHODS.LOCK_RELEASE, - args: [ - lockName, - ], - }); - } - default: { - console.warn('unrecognized message type', type); - throw new Error('unrecognized message type: ' + type); - } - } -} - -const getEndpoint = () => { - const wss = 'wss://'; - let hostname = 'multiplayer.webaverse.workers.dev'; - - // The local development server's WebSocket is provided at ws://localhost. - const isDevelopment = location.hostname === 'local.webaverse.com'; - if (isDevelopment) { - // wss = 'ws://'; - // hostname = `localhost:${MULTIPLAYER_PORT}`; - hostname = location.host; - } - - return `${wss}${hostname}`; -}; -const createWs = (endpoint, roomname, playerId) => { - const u = `${endpoint}/api/room/${roomname}/websocket${playerId ? `?playerId=${playerId}` : ''}`; - const ws = new WebSocket(u); - return ws; -}; - -const makePromise = () => { - let resolve; - let reject; - const promise = new Promise((res, rej) => { - resolve = res; - reject = rej; - }); - promise.resolve = resolve; - promise.reject = reject; - return promise; -}; - -const zstringify = o => { - let result = ''; - for (const k in o) { - if (result) { - result += '\n'; - } - - const v = o[k]; - if (v instanceof Float32Array) { - result += `${JSON.stringify(k)}: Float32Array(${v.join(',')})`; - } else { - const s = JSON.stringify(v); - if (s.length >= 20 && v instanceof Object && v !== null) { - result += `${JSON.stringify(k)}:\n${zstringify(v)}`; - } else { - result += `${JSON.stringify(k)}: ${s}`; - } - } - } - return result; -}; - -export { - alignN, - align4, - parseUpdateObject, - makeId, - parseMessage, - serializeMessage, - getEndpoint, - createWs, - makePromise, - zstringify, -}; diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/video/networked-video-client-utils.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/video/networked-video-client-utils.mjs deleted file mode 100644 index 718e4006b..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/video/networked-video-client-utils.mjs +++ /dev/null @@ -1,9 +0,0 @@ -import {UPDATE_METHODS} from '../update-types.mjs'; - -export const handlesMethod = method => { - return [ - UPDATE_METHODS.VIDEO, - UPDATE_METHODS.VIDEO_START, - UPDATE_METHODS.VIDEO_END, - ].includes(method); -}; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/video/networked-video-client.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/video/networked-video-client.mjs deleted file mode 100644 index ee5a4e357..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/video/networked-video-client.mjs +++ /dev/null @@ -1,199 +0,0 @@ -import {UPDATE_METHODS} from '../update-types.mjs'; -import {handlesMethod} from './networked-video-client-utils.mjs'; -import {parseUpdateObject, makeId} from '../util.mjs'; -import {zbencode} from 'zjs'; - -export class NetworkedVideoClient extends EventTarget { - constructor({ - playerId = makeId(), - }) { - super(); - - this.playerId = playerId; - - this.ws = null; - - this.videoSourceCleanups = new Map(); // playerId:streamId -> function - } - - addVideoSource(playableVideoStream) { - // console.log('add video source', new Error().stack); - - const { - id, - // output, - type, - disposition, - } = playableVideoStream; - if (typeof id !== 'string') { - throw new Error('video source id must be a string'); - } - if (typeof type !== 'string') { - throw new Error('video source type must be a string'); - } - if (typeof disposition !== 'string') { - throw new Error('video source disposition must be a string'); - } - - // console.log('send start', [ - // this.playerId, - // id, - // type, - // disposition, - // ]); - this.ws.send(zbencode({ - method: UPDATE_METHODS.VIDEO_START, - args: [ - this.playerId, - id, - type, - disposition, - ], - })); - - // pump the reader - let live = true; - const finishPromise = (async () => { - for await (const data of playableVideoStream) { - if (live) { - console.log('send video', [ - this.playerId, - id, - data, - ]); - this.ws.send(zbencode({ - method: UPDATE_METHODS.VIDEO, - args: [ - this.playerId, - id, - data, - ], - })); - } else { - break; - } - } - })(); - - // add the cleanup fn - const cleanup = () => { - live = false; - - // console.log('send audio end', [ - // this.playerId, - // id, - // ]); - this.ws.send(zbencode({ - method: UPDATE_METHODS.VIDEO_END, - args: [ - this.playerId, - id, - ], - })); - }; - this.videoSourceCleanups.set(id, cleanup); - - return { - waitForFinish: () => finishPromise, - }; - } - - removeVideoSource(readableVideoStream) { - // console.log('remove video source'); - const cleanupFn = this.videoSourceCleanups.get(readableVideoStream.id); - cleanupFn(); - this.videoSourceCleanups.delete(readableVideoStream.id); - } - - async connect(ws) { - this.ws = ws; - - const _waitForOpen = () => new Promise((resolve, reject) => { - resolve = (resolve => () => { - resolve(); - _cleanup(); - })(resolve); - reject = (reject => () => { - reject(); - _cleanup(); - })(reject); - - this.ws.addEventListener('open', resolve); - this.ws.addEventListener('error', reject); - - const _cleanup = () => { - this.ws.removeEventListener('open', resolve); - this.ws.removeEventListener('error', reject); - }; - }); - await _waitForOpen(); - - // console.log('irc listen'); - this.ws.addEventListener('message', e => { - // console.log('got irc data', e.data); - if (e?.data?.byteLength > 0) { - const updateBuffer = e.data; - const uint8Array = new Uint8Array(updateBuffer); - const updateObject = parseUpdateObject(uint8Array); - - const {method /*, args */} = updateObject; - if (handlesMethod(method)) { - this.handleUpdateObject(updateObject); - } - } else { - // debugger; - } - }); - } - handleUpdateObject(updateObject) { - const {method, args} = updateObject; - // console.log('video update object', {method, args}); - if (method === UPDATE_METHODS.VIDEO) { - // console.log('got video data', {method, args}); - const [ - playerId, - streamId, - data, - ] = args; - - this.dispatchEvent(new MessageEvent('video', { - data: { - playerId, - streamId, - data, - }, - })); - } else if (method === UPDATE_METHODS.VIDEO_START) { - const [ - playerId, - streamId, - type, - disposition, - ] = args; - - this.dispatchEvent(new MessageEvent('videostart', { - data: { - playerId, - streamId, - type, - disposition, - }, - })); - } else if (method === UPDATE_METHODS.VIDEO_END) { - const [ - playerId, - streamId, - ] = args; - - this.dispatchEvent(new MessageEvent('videoend', { - data: { - playerId, - streamId, - }, - })); - } else { - console.warn('unhandled video method: ' + method, updateObject); - throw new Error('unhandled video method: ' + method); - } - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/video/video-classes.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/video/video-classes.mjs deleted file mode 100644 index e39266011..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/video/video-classes.mjs +++ /dev/null @@ -1,31 +0,0 @@ -export class VideoOutput extends EventTarget { - constructor() { - super(); - - this.live = true; - } - write(data) { - this.dispatchEvent(new MessageEvent('data', { - data, - })); - } - end() { - this.live = false; - this.dispatchEvent(new MessageEvent('end')); - } - readAll() { - return new Promise((accept, reject) => { - const bs = []; - if (this.live) { - this.addEventListener('data', e => { - bs.push(e.data); - }); - this.addEventListener('end', () => { - accept(bs); - }); - } else { - accept(bs); - } - }); - } -} \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/video/video-client.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/video/video-client.mjs deleted file mode 100644 index 1d145c972..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/public/video/video-client.mjs +++ /dev/null @@ -1,72 +0,0 @@ -import {VideoOutput} from './video-classes.mjs'; -import { makeId, makePromise } from '../util.mjs'; - -const type ='image/webp'; -const quality = 0.; - -export const createVideoSource = ({ - mediaStream, -}) => { - // get the video stream - const video = document.createElement('video'); - video.srcObject = mediaStream; - // video.style.cssText = `\ - // position: fixed; - // bottom: 0; - // right: 0; - // width: 300px; - // z-index: 1000; - // `; - // document.body.appendChild(video); - - // use the canvas 2d api to read the media stream and stream out the data and end events - const canvas = document.createElement('canvas'); - const ctx = canvas.getContext('2d'); - let live = true; - let videoFrameRequestId; - const handleVideoFrame = async () => { - ctx.drawImage(video, 0, 0, canvas.width, canvas.height); - // const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); - // const data = imageData.data; - // console.log('write data', data); - // output.write(data); // Dispatch data event to the output - - // get the canvas blob - const blob = await new Promise((accept, reject) => { - canvas.toBlob(accept, type, quality); - }); - // get the array buffer - const arrayBuffer = await blob.arrayBuffer(); - const uint8Array = new Uint8Array(arrayBuffer); - output.write(uint8Array); - - videoFrameRequestId = video.requestVideoFrameCallback(handleVideoFrame); - }; - - video.addEventListener('loadedmetadata', () => { - if (live) { - console.log('got video loadedmetadata event', video.videoWidth, video.videoHeight); - canvas.width = video.videoWidth; - canvas.height = video.videoHeight; - video.play(); - videoFrameRequestId = video.requestVideoFrameCallback(handleVideoFrame); - } - }); - - const output = new VideoOutput(); - - const id = makeId(10); - - return { - id, - output, - mediaStream, - close() { - live = false; - if (videoFrameRequestId) { - video.cancelVideoFrameCallback(videoFrameRequestId); - } - output.end(); - }, - }; -}; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/src/chat.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/src/chat.mjs deleted file mode 100644 index a3ca7fb0b..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/src/chat.mjs +++ /dev/null @@ -1,985 +0,0 @@ -// This is the Edge Chat Demo Worker, built using Durable Objects! - -// =============================== -// Introduction to Modules -// =============================== -// -// The first thing you might notice, if you are familiar with the Workers platform, is that this -// Worker is written differently from others you may have seen. It even has a different file -// extension. The `mjs` extension means this JavaScript is an ES Module, which, among other things, -// means it has imports and exports. Unlike other Workers, this code doesn't use -// `addEventListener("fetch", handler)` to register its main HTTP handler; instead, it _exports_ -// a handler, as we'll see below. -// -// This is a new way of writing Workers that we expect to introduce more broadly in the future. We -// like this syntax because it is *composable*: You can take two workers written this way and -// merge them into one worker, by importing the two Workers' exported handlers yourself, and then -// exporting a new handler that call into the other Workers as appropriate. -// -// This new syntax is required when using Durable Objects, because your Durable Objects are -// implemented by classes, and those classes need to be exported. The new syntax can be used for -// writing regular Workers (without Durable Objects) too, but for now, you must be in the Durable -// Objects beta to be able to use the new syntax, while we work out the quirks. -// -// To see an example configuration for uploading module-based Workers, check out the wrangler.toml -// file or one of our Durable Object templates for Wrangler: -// * https://github.com/cloudflare/durable-objects-template -// * https://github.com/cloudflare/durable-objects-rollup-esm -// * https://github.com/cloudflare/durable-objects-webpack-commonjs - -// =============================== -// Required Environment -// =============================== -// -// This worker, when deployed, must be configured with two environment bindings: -// * rooms: A Durable Object namespace binding mapped to the ChatRoom class. -// * limiters: A Durable Object namespace binding mapped to the RateLimiter class. -// -// Incidentally, in pre-modules Workers syntax, "bindings" (like KV bindings, secrets, etc.) -// appeared in your script as global variables, but in the new modules syntax, this is no longer -// the case. Instead, bindings are now delivered in an "environment object" when an event handler -// (or Durable Object class constructor) is called. Look for the variable `env` below. -// -// We made this change, again, for composability: The global scope is global, but if you want to -// call into existing code that has different environment requirements, then you need to be able -// to pass the environment as a parameter instead. -// -// Once again, see the wrangler.toml file to understand how the environment is configured. - -// ======================================================================================= -// The regular Worker part... -// -// This section of the code implements a normal Worker that receives HTTP requests from external -// clients. This part is stateless. - -// With the introduction of modules, we're experimenting with allowing text/data blobs to be -// uploaded and exposed as synthetic modules. In wrangler.toml we specify a rule that files ending -// in .html should be uploaded as "Data", equivalent to content-type `application/octet-stream`. -// So when we import it as `HTML` here, we get the HTML content as an `ArrayBuffer`. This lets us -// serve our app's static asset without relying on any separate storage. (However, the space -// available for assets served this way is very limited; larger sites should continue to use Workers -// KV to serve assets.) -import HTML from "./chat.html"; -import { getAssetFromKV, mapRequestToAsset } from '@cloudflare/kv-asset-handler' -import manifestJSON from '__STATIC_CONTENT_MANIFEST' -const assetManifest = JSON.parse(manifestJSON); -import {DataClient, NetworkedDataClient/*, DCMap, DCArray*/} from "../public/data-client.mjs"; -import {NetworkedIrcClient} from "../public/irc-client.mjs"; -import {NetworkedCrdtClient} from "../public/crdt-client.mjs"; -import {NetworkedLockClient} from "../public/lock-client.mjs"; -import {handlesMethod as networkedAudioClientHandlesMethod} from "../public/audio/networked-audio-client-utils.mjs"; -import {handlesMethod as networkedVideoClientHandlesMethod} from "../public/video/networked-video-client-utils.mjs"; -import {parseUpdateObject, serializeMessage} from "../public/util.mjs"; -import {UPDATE_METHODS} from "../public/update-types.mjs"; - -// `handleErrors()` is a little utility function that can wrap an HTTP request handler in a -// try/catch and return errors to the client. You probably wouldn't want to use this in production -// code but it is convenient when debugging and iterating. -async function handleErrors(request, func) { - try { - return await func(); - } catch (err) { - if (request.headers.get("Upgrade") == "websocket") { - // Annoyingly, if we return an HTTP error in response to a WebSocket request, Chrome devtools - // won't show us the response body! So... let's send a WebSocket response with an error - // frame instead. - let pair = new WebSocketPair(); - pair[1].accept(); - pair[1].send(JSON.stringify({error: err.stack})); - pair[1].close(1011, "Uncaught exception during session setup"); - return new Response(null, { status: 101, webSocket: pair[0] }); - } else { - return new Response(err.stack, {status: 500}); - } - } -} - -// In modules-syntax workers, we use `export default` to export our script's main event handlers. -// Here, we export one handler, `fetch`, for receiving HTTP requests. In pre-modules workers, the -// fetch handler was registered using `addEventHandler("fetch", event => { ... })`; this is just -// new syntax for essentially the same thing. -// -// `fetch` isn't the only handler. If your worker runs on a Cron schedule, it will receive calls -// to a handler named `scheduled`, which should be exported here in a similar way. We will be -// adding other handlers for other types of events over time. -export default { - async fetch(request, env, ctx) { - return await handleErrors(request, async () => { - // We have received an HTTP request! Parse the URL and route the request. - - let url = new URL(request.url); - let path = url.pathname.slice(1).split('/'); - - if (!path[0]) { - // Serve our HTML at the root path. - return new Response(HTML, {headers: {"Content-Type": "text/html;charset=UTF-8"}}); - } - - switch (path[0]) { - case "api": - // This is a request for `/api/...`, call the API handler. - return handleApiRequest(path.slice(1), request, env); - case 'public': - return handlePublicRequest(path.slice(1), request, env, ctx); - default: - return new Response("Not found", {status: 404}); - } - }); - } -} - -async function handlePublicRequest(path, request, env, ctx) { - try { - const event = { - request, - waitUntil(promise) { - return ctx.waitUntil(promise) - }, - } - const options = {}; - function handlePrefix(prefix) { - return request => { - // compute the default (e.g. / -> index.html) - let defaultAssetKey = mapRequestToAsset(request) - let url = new URL(defaultAssetKey.url) - - // strip the prefix from the path for lookup - url.pathname = url.pathname.replace(prefix, '/') - - // inherit all other props from the default request - return new Request(url.toString(), defaultAssetKey) - } - } - options.mapRequestToAsset = handlePrefix(/^\/public/); - options.ASSET_NAMESPACE = env.__STATIC_CONTENT; - options.ASSET_MANIFEST = assetManifest; - const page = await getAssetFromKV(event, options) - - // allow headers to be altered - const response = new Response(page.body, page); - - // console.log('got response', response); - - return response; - } catch(err) { - console.log('error', err); - return new Response(err.stack, { - status: 500, - }) - } -} - -async function handleApiRequest(path, request, env) { - // We've received at API request. Route the request based on the path. - - switch (path[0]) { - case "room": { - // Request for `/api/room/...`. - - if (!path[1]) { - // The request is for just "/api/room", with no ID. - if (request.method == "POST") { - // POST to /api/room creates a private room. - // - // Incidentally, this code doesn't actually store anything. It just generates a valid - // unique ID for this namespace. Each durable object namespace has its own ID space, but - // IDs from one namespace are not valid for any other. - // - // The IDs returned by `newUniqueId()` are unguessable, so are a valid way to implement - // "anyone with the link can access" sharing. Additionally, IDs generated this way have - // a performance benefit over IDs generated from names: When a unique ID is generated, - // the system knows it is unique without having to communicate with the rest of the - // world -- i.e., there is no way that someone in the UK and someone in New Zealand - // could coincidentally create the same ID at the same time, because unique IDs are, - // well, unique! - let id = env.rooms.newUniqueId(); - return new Response(id.toString(), {headers: {"Access-Control-Allow-Origin": "*"}}); - } else { - // If we wanted to support returning a list of public rooms, this might be a place to do - // it. The list of room names might be a good thing to store in KV, though a singleton - // Durable Object is also a possibility as long as the Cache API is used to cache reads. - // (A caching layer would be needed because a single Durable Object is single-threaded, - // so the amount of traffic it can handle is limited. Also, caching would improve latency - // for users who don't happen to be located close to the singleton.) - // - // For this demo, though, we're not implementing a public room list, mainly because - // inevitably some trolls would probably register a bunch of offensive room names. Sigh. - return new Response("Method not allowed", {status: 405}); - } - } - - // OK, the request is for `/api/room//...`. It's time to route to the Durable Object - // for the specific room. - let name = path[1]; - - // Each Durable Object has a 256-bit unique ID. IDs can be derived from string names, or - // chosen randomly by the system. - let id; - /* if (name.match(/^[0-9a-f]{64}$/)) { - // The name is 64 hex digits, so let's assume it actually just encodes an ID. We use this - // for private rooms. `idFromString()` simply parses the text as a hex encoding of the raw - // ID (and verifies that this is a valid ID for this namespace). - id = env.rooms.idFromString(name); - } else */if (name.length <= 128) { - // Treat as a string room name (limited to 32 characters). `idFromName()` consistently - // derives an ID from a string. - id = env.rooms.idFromName(name); - } else { - return new Response("Name too long", {status: 404}); - } - - // Get the Durable Object stub for this room! The stub is a client object that can be used - // to send messages to the remote Durable Object instance. The stub is returned immediately; - // there is no need to await it. This is important because you would not want to wait for - // a network round trip before you could start sending requests. Since Durable Objects are - // created on-demand when the ID is first used, there's nothing to wait for anyway; we know - // an object will be available somewhere to receive our requests. - let roomObject = env.rooms.get(id); - - // Compute a new URL with `/api/room/` removed. We'll forward the rest of the path - // to the Durable Object. - let newUrl = new URL(request.url); - newUrl.pathname = "/" + name + "/" + path.slice(2).join("/"); - - // Send the request to the object. The `fetch()` method of a Durable Object stub has the - // same signature as the global `fetch()` function, but the request is always sent to the - // object, regardless of the request's URL. - return roomObject.fetch(newUrl, request); - } - - default: - return new Response("Not found", {status: 404}); - } -} - -// - -const readCrdtFromStorage = async (storage, arrayNames) => { - const crdt = new Map(); - for (const arrayId of arrayNames) { - const array = await storage.get(arrayId) ?? {}; - crdt.set(arrayId, array); - - for (const arrayIndexId in array) { - const val = await storage.get(arrayIndexId) ?? [ - 0, - {}, - ]; - crdt.set(arrayIndexId, val); - } - } - return crdt; -}; -const dataClientPromises = new Map(); -const crdtClientPromises = new Map(); -const lockClientPromises = new Map(); - -// - -const schemaArrayNames = [ - 'worldApps', -]; - -const _pauseWebSocket = (ws) => { - const queue = []; - const onmessage = e => { - queue.push(e.data); - }; - ws.addEventListener('message', onmessage); - return () => { - for (const data of queue) { - ws.dispatchEvent(new MessageEvent('message', {data})); - } - queue.length = 0; - - ws.removeEventListener('message', onmessage); - }; -}; - -// ======================================================================================= -// The ChatRoom Durable Object Class - -// ChatRoom implements a Durable Object that coordinates an individual chat room. Participants -// connect to the room using WebSockets, and the room broadcasts messages from each participant -// to all others. -export class ChatRoom { - constructor(controller, env) { - // `controller.storage` provides access to our durable storage. It provides a simple KV - // get()/put() interface. - this.storage = controller.storage; - - // `env` is our environment bindings (discussed earlier). - this.env = env; - - // We will put the WebSocket objects for each client, along with some metadata, into - // `sessions`. - this.sessions = []; - - // We keep track of the last-seen message's timestamp just so that we can assign monotonically - // increasing timestamps even if multiple messages arrive simultaneously (see below). There's - // no need to store this to disk since we assume if the object is destroyed and recreated, much - // more than a millisecond will have gone by. - this.lastTimestamp = 0; - } - - // The system will call fetch() whenever an HTTP request is sent to this Object. Such requests - // can only be sent from other Worker code, such as the code above; these requests don't come - // directly from the internet. In the future, we will support other formats than HTTP for these - // communications, but we started with HTTP for its familiarity. - async fetch(request) { - return await handleErrors(request, async () => { - let url = new URL(request.url); - const match = url.pathname.match(/^\/([^\/]+?)\/([^\/]+?)$/); - const roomName = match ? match[1] : ''; - const methodName = match ? match[2] : ''; - - switch (methodName) { - case "websocket": { - // The request is to `/api/room//websocket`. A client is trying to establish a new - // WebSocket session. - if (request.headers.get("Upgrade") != "websocket") { - return new Response("expected websocket", {status: 400}); - } - - // Get the client's IP address for use with the rate limiter. - let ip = request.headers.get("CF-Connecting-IP"); - - // To accept the WebSocket request, we create a WebSocketPair (which is like a socketpair, - // i.e. two WebSockets that talk to each other), we return one end of the pair in the - // response, and we operate on the other end. Note that this API is not part of the - // Fetch API standard; unfortunately, the Fetch API / Service Workers specs do not define - // any way to act as a WebSocket server today. - let pair = new WebSocketPair(); - - // We're going to take pair[1] as our end, and return pair[0] to the client. - await this.handleSession(pair[1], ip, roomName, url); - - // Now we return the other end of the pair to the client. - return new Response(null, { status: 101, webSocket: pair[0] }); - } - - case 'get': { - break; - } - - case 'set': { - break; - } - - default: - return new Response("Not found", {status: 404}); - } - }); - } - - // handleSession() implements our WebSocket-based chat protocol. - async handleSession(webSocket, ip, roomName, url) { - // Accept our end of the WebSocket. This tells the runtime that we'll be terminating the - // WebSocket in JavaScript, not sending it elsewhere. - webSocket.accept(); - - const playerId = url.searchParams.get('playerId') ?? null; - /* if (!playerId) { - console.log('closing due to no playerId'); - webSocket.close(); - return; - } */ - - const realm = { - key: roomName, - }; - - let dataClientPromise = dataClientPromises.get(roomName); - if (!dataClientPromise) { - dataClientPromise = (async () => { - const crdt = await readCrdtFromStorage(this.storage, schemaArrayNames); - const dataClient = new DataClient({ - crdt, - userData: { - realm, - }, - }); - return dataClient; - })(); - dataClientPromises.set(roomName, dataClientPromise); - } - let crdtClientPromise = crdtClientPromises.get(roomName); - if (!crdtClientPromise) { - crdtClientPromise = (async () => { - let initialUpdate = await this.storage.get('crdt'); - console.log('get room crdt', initialUpdate); - const crdtClient = new NetworkedCrdtClient({ - initialUpdate, - }); - crdtClient.addEventListener('update', async e => { - const uint8array = crdtClient.getStateAsUpdate(); - // console.log('put room crdt', uint8array); - await this.storage.put('crdt', uint8array); - }); - return crdtClient; - })(); - crdtClientPromises.set(roomName, crdtClientPromise); - } - let lockClientPromise = lockClientPromises.get(roomName); - if (!lockClientPromise) { - lockClientPromise = (async () => { - const lockClient = new NetworkedLockClient(); - return lockClient; - })(); - lockClientPromises.set(roomName, lockClientPromise); - } - - const _resumeWebsocket = _pauseWebSocket(webSocket); - - const dataClient = await dataClientPromise; - const crdtClient = await crdtClientPromise; - const lockClient = await lockClientPromise; - const networkClient = { - /* serializeMessage(message) { - if (message.type === 'networkinit') { - const {playerIds} = message.data; - return zbencode({ - method: UPDATE_METHODS.NETWORK_INIT, - args: [ - playerIds, - ], - }); - } else { - throw new Error('invalid message type: ' + message.type); - } - }, */ - getNetworkInitMessage: () => { - return new MessageEvent('networkinit', { - data: { - playerIds: this.sessions - .map((session) => session.playerId) - .filter((playerId) => playerId !== null), - }, - }); - }, - }; - - let session = {webSocket, playerId/*, blockedMessages: []*/}; - this.sessions.push(session); - - // send import - webSocket.send(serializeMessage(dataClient.getImportMessage())); - // send initial update - webSocket.send(serializeMessage(crdtClient.getInitialUpdateMessage())); - // send network init - webSocket.send(serializeMessage(networkClient.getNetworkInitMessage())); - - // set up dead hands tracking - const deadHands = new Map(); - // let triggered = false; - const _triggerDeadHands = () => { - // console.log('trigger dead hands'); - // if (triggered) { - // throw new Error('double trigger'); - // } else { - // triggered = true; - // } - // const entries = Array.from(deadHands.entries()); - for (const [key, {arrayId, arrayIndexId}] of deadHands.entries()) { - const array = dataClient.getArray(arrayId, { - listen: false, - }); - if (arrayIndexId !== null) { // map mode - // console.log('dead hand map', arrayId, arrayIndexId); - // const map = dataClient.getArrayMap(arrayId, arrayIndexId, { - // listen: false, - // }); - if (array.hasKey(arrayIndexId)) { - const map = array.getMap(arrayIndexId, { - listen: false, - }); - const removeMapUpdate = map.removeUpdate(); - const removeMapUpdateBuffer = serializeMessage(removeMapUpdate); - proxyMessageToPeers(removeMapUpdateBuffer); - - /* const array = dataClient.getArray(arrayId, { - listen: false, - }); - for (const arrayIndexId of array.getKeys()) { - const map = array.getMap(arrayIndexId, { - listen: false, - }); - const removeMessage = map.removeUpdate(); - const removeArrayUpdateBuffer = serializeMessage(removeMessage); - proxyMessageToPeers(removeArrayUpdateBuffer); - } */ - } - } else { // array mode - // console.log('dead hand array', arrayId); - - for (const arrayIndexId of array.getKeys()) { - const map = array.getMap(arrayIndexId, { - listen: false, - }); - const removeMessage = map.removeUpdate(); - const removeArrayUpdateBuffer = serializeMessage(removeMessage); - proxyMessageToPeers(removeArrayUpdateBuffer); - } - } - // console.log('iter end'); - } - }; - const _triggerUnlocks = () => { - lockClient.serverUnlockSession(session); - }; - - dataClient.addEventListener('deadhand', e => { - const {keys, deadHand} = e.data; - if (deadHand === playerId) { - // const key = `${arrayId}:${arrayIndexId}`; - for (const key of keys) { - let match; - if (match = key.match(/^([^\.]+?)\.([^\.]+)$/)) { - const arrayId = match[1]; - const arrayIndexId = match[2]; - deadHands.set(key, { - arrayId, - arrayIndexId, - }); - } else if (match = key.match(/^([^\.]+)$/)) { - const arrayId = match[1]; - deadHands.set(key, { - arrayId, - arrayIndexId: null, - }); - } else { - throw new Error('invalid deadhand key: ' + key); - } - } - // console.log('register dead hand', e.data, {arrayId, arrayIndexId, deadHand}); - } - }); - dataClient.addEventListener('livehand', e => { - const {keys, liveHand} = e.data; - if (liveHand === playerId) { - for (const key of keys) { - deadHands.delete(key); - } - // console.log('register live hand', e.data, {arrayId, arrayIndexId, liveHand}); - } - }); - - // Set up our rate limiter client. - // let limiterId = this.env.limiters.idFromName(ip); - // let limiter = new RateLimiterClient( - // () => this.env.limiters.get(limiterId), - // err => webSocket.close(1011, err.stack)); - - // Create our session and add it to the sessions list. - // We don't send any messages to the client until it has sent us the initial user info - // message. Until then, we will queue messages in `session.blockedMessages`. - - // Queue "join" messages for all online users, to populate the client's roster. - // this.sessions.forEach(otherSession => { - // if (otherSession.name) { - // session.blockedMessages.push(JSON.stringify({joined: otherSession.name})); - // } - // }); - - // respond back to the client - const respondToSelf = message => { - session.webSocket.send(message); - }; - - // send a message to everyone on the list except us - const proxyMessageToPeers = m => { - for (const s of this.sessions) { - if (s !== session) { - s.webSocket.send(m); - } - } - }; - // send a message to all peers - const reflectMessageToPeers = m => { - for (const s of this.sessions) { - s.webSocket.send(m); - } - }; - - // Load the last 100 messages from the chat history stored on disk, and send them to the - // client. - // let storage = await this.storage.list({reverse: true, limit: 100}); - /* let backlog = [...storage.values()]; - backlog.reverse(); - backlog.forEach(value => { - session.blockedMessages.push(value); - }); */ - - const handleBinaryMessage = (arrayBuffer) => { - const uint8Array = new Uint8Array(arrayBuffer); - const updateObject = parseUpdateObject(uint8Array); - - const {method, args} = updateObject; - if (NetworkedDataClient.handlesMethod(method)) { - const {rollback, update} = dataClient.applyUint8Array(uint8Array); - if (rollback) { - const rollbackBuffer = serializeMessage(rollback); - respondToSelf(rollbackBuffer); - } - if (update) { - dataClient.emitUpdate(update); - proxyMessageToPeers(uint8Array); - } - } - if (NetworkedCrdtClient.handlesMethod(method)) { - const [update] = args; - crdtClient.update(update); - proxyMessageToPeers(uint8Array); - } - if (NetworkedLockClient.handlesMethod(method)) { - const m = (() => { - const [lockName] = args; - switch (method) { - case UPDATE_METHODS.LOCK_REQUEST: { - return new MessageEvent('lockRequest', { - data: { - playerId, - lockName, - }, - }); - } - case UPDATE_METHODS.LOCK_RESPONSE: { - return new MessageEvent('lockResponse', { - data: { - playerId, - lockName, - }, - }); - } - case UPDATE_METHODS.LOCK_RELEASE: { - return new MessageEvent('lockRelease', { - data: { - playerId, - lockName, - }, - }); - } - default: { - console.warn('unrecognized lock method', method); - break - } - } - })(); - lockClient.handle(m); - } - if (NetworkedIrcClient.handlesMethod(method)) { - // console.log('route', method, args, this.sessions); - reflectMessageToPeers(uint8Array); - } - if ( - networkedAudioClientHandlesMethod(method) || - networkedVideoClientHandlesMethod(method) - ) { - proxyMessageToPeers(uint8Array); - } - }; - - const _sendJoinMessage = (playerId) => { - if (playerId) { - const joinMessage = new MessageEvent('join', { - data: { - playerId, - }, - }); - const joinBuffer = serializeMessage(joinMessage); - dataClient.emitUpdate(joinMessage); - proxyMessageToPeers(joinBuffer); - } - }; - _sendJoinMessage(playerId); - - /* const _sendLeaveMessage = () => { - console.log('send leave message', roomName, playerId); - const leaveMessage = new MessageEvent('leave', { - data: { - playerId, - }, - }); - const leaveBuffer = serializeMessage(leaveMessage); - dataClient.emitUpdate(leaveMessage); - proxyMessageToPeers(leaveBuffer); - }; */ - - // Set event handlers to receive messages. - // let receivedUserInfo = false; - webSocket.addEventListener("message", async msg => { - try { - if (session.quit) { - // Whoops, when trying to send to this WebSocket in the past, it threw an exception and - // we marked it broken. But somehow we got another message? I guess try sending a - // close(), which might throw, in which case we'll try to send an error, which will also - // throw, and whatever, at least we won't accept the message. (This probably can't - // actually happen. This is defensive coding.) - console.log('closing due to webasocket broken'); - webSocket.close(1011, "WebSocket broken."); - return; - } - - // Check if the user is over their rate limit and reject the message if so. - /* if (!limiter.checkLimit()) { - webSocket.send(JSON.stringify({ - error: "Your IP is being rate-limited, please try again later." - })); - return; - } */ - - if (msg.data instanceof ArrayBuffer) { - const arrayBuffer = msg.data; - handleBinaryMessage(arrayBuffer); - } else { - // I guess we'll use JSON. - throw new Error('got non-binary message'); - } - - /* if (!receivedUserInfo) { - // The first message the client sends is the user info message with their name. Save it - // into their session object. - session.name = "" + (data.name || "anonymous"); - - // Don't let people use ridiculously long names. (This is also enforced on the client, - // so if they get here they are not using the intended client.) - if (session.name.length > 32) { - webSocket.send(JSON.stringify({error: "Name too long."})); - webSocket.close(1009, "Name too long."); - return; - } - - // Deliver all the messages we queued up since the user connected. - session.blockedMessages.forEach(queued => { - webSocket.send(queued); - }); - delete session.blockedMessages; - - // Broadcast to all other connections that this user has joined. - this.broadcast({joined: session.name}); - - webSocket.send(JSON.stringify({ready: true})); - - // Note that we've now received the user info message. - receivedUserInfo = true; - - return; - } - - // Construct sanitized message for storage and broadcast. - data = { name: session.name, message: "" + data.message }; - - // Block people from sending overly long messages. This is also enforced on the client, - // so to trigger this the user must be bypassing the client code. - if (data.message.length > 256) { - webSocket.send(JSON.stringify({error: "Message too long."})); - return; - } - - // Add timestamp. Here's where this.lastTimestamp comes in -- if we receive a bunch of - // messages at the same time (or if the clock somehow goes backwards????), we'll assign - // them sequential timestamps, so at least the ordering is maintained. - data.timestamp = Math.max(Date.now(), this.lastTimestamp + 1); - this.lastTimestamp = data.timestamp; - - // Broadcast the message to all other WebSockets. - let dataStr = JSON.stringify(data); - this.broadcast(dataStr); - - // Save message. - let key = new Date(data.timestamp).toISOString(); - await this.storage.put(key, dataStr); (*/ - } catch (err) { - // Report any exceptions directly back to the client. As with our handleErrors() this - // probably isn't what you'd want to do in production, but it's convenient when testing. - console.warn(err); - webSocket.send(JSON.stringify({error: err.stack})); - } - }); - - // On "close" and "error" events, remove the WebSocket from the sessions list and broadcast - // a quit message. - let closeOrErrorHandler = evt => { - try { - session.quit = true; - this.sessions = this.sessions.filter(member => member !== session); - - _triggerDeadHands(); - _triggerUnlocks(); - - // console.log('send leave', new Error().stack); - // _sendLeaveMessage(); - - /* if (session.name) { - this.broadcast({quit: session.name}); - } */ - } catch(err) { - console.warn(err.stack); - throw err; - } finally { - cleanup(); - } - }; - webSocket.addEventListener("close", closeOrErrorHandler); - webSocket.addEventListener("error", closeOrErrorHandler); - - const cleanup = () => { - webSocket.removeEventListener("close", closeOrErrorHandler); - webSocket.removeEventListener("error", closeOrErrorHandler); - }; - - _resumeWebsocket(); - } - - // broadcast() broadcasts a message to all clients. - broadcast(message) { - // Apply JSON if we weren't given a string to start with. - if (typeof message !== 'string') { - message = JSON.stringify(message); - } - - try { - for (const session of this.sessions) { - session.webSocket.send(message); - } - } catch (err) { - console.warn(err.stack); - } - - /* // Iterate over all the sessions sending them messages. - let quitters = []; - this.sessions = this.sessions.filter(session => { - if (session.name) { - try { - session.webSocket.send(message); - return true; - } catch (err) { - // Whoops, this connection is dead. Remove it from the list and arrange to notify - // everyone below. - session.quit = true; - quitters.push(session); - return false; - } - } else { - // This session hasn't sent the initial user info message yet, so we're not sending them - // messages yet (no secret lurking!). Queue the message to be sent later. - // session.blockedMessages.push(message); - return true; - } - }); - - quitters.forEach(quitter => { - if (quitter.name) { - this.broadcast({quit: quitter.name}); - } - }); */ - } -} - -// ======================================================================================= -// The RateLimiter Durable Object class. - -// RateLimiter implements a Durable Object that tracks the frequency of messages from a particular -// source and decides when messages should be dropped because the source is sending too many -// messages. -// -// We utilize this in ChatRoom, above, to apply a per-IP-address rate limit. These limits are -// global, i.e. they apply across all chat rooms, so if a user spams one chat room, they will find -// themselves rate limited in all other chat rooms simultaneously. -export class RateLimiter { - constructor(controller, env) { - // Timestamp at which this IP will next be allowed to send a message. Start in the distant - // past, i.e. the IP can send a message now. - this.nextAllowedTime = 0; - } - - // Our protocol is: POST when the IP performs an action, or GET to simply read the current limit. - // Either way, the result is the number of seconds to wait before allowing the IP to perform its - // next action. - async fetch(request) { - return await handleErrors(request, async () => { - let now = Date.now() / 1000; - - this.nextAllowedTime = Math.max(now, this.nextAllowedTime); - - if (request.method == "POST") { - // POST request means the user performed an action. - // We allow one action per 5 seconds. - this.nextAllowedTime += 5; - } - - // Return the number of seconds that the client needs to wait. - // - // We provide a "grace" period of 20 seconds, meaning that the client can make 4-5 requests - // in a quick burst before they start being limited. - let cooldown = Math.max(0, this.nextAllowedTime - now - 20); - return new Response(cooldown); - }) - } -} - -// RateLimiterClient implements rate limiting logic on the caller's side. -class RateLimiterClient { - // The constructor takes two functions: - // * getLimiterStub() returns a new Durable Object stub for the RateLimiter object that manages - // the limit. This may be called multiple times as needed to reconnect, if the connection is - // lost. - // * reportError(err) is called when something goes wrong and the rate limiter is broken. It - // should probably disconnect the client, so that they can reconnect and start over. - constructor(getLimiterStub, reportError) { - this.getLimiterStub = getLimiterStub; - this.reportError = reportError; - - // Call the callback to get the initial stub. - this.limiter = getLimiterStub(); - - // When `inCooldown` is true, the rate limit is currently applied and checkLimit() will return - // false. - this.inCooldown = false; - } - - // Call checkLimit() when a message is received to decide if it should be blocked due to the - // rate limit. Returns `true` if the message should be accepted, `false` to reject. - checkLimit() { - if (this.inCooldown) { - return false; - } - this.inCooldown = true; - this.callLimiter(); - return true; - } - - // callLimiter() is an internal method which talks to the rate limiter. - async callLimiter() { - try { - let response; - try { - // Currently, fetch() needs a valid URL even though it's not actually going to the - // internet. We may loosen this in the future to accept an arbitrary string. But for now, - // we have to provide a dummy URL that will be ignored at the other end anyway. - response = await this.limiter.fetch("https://dummy-url", {method: "POST"}); - } catch (err) { - // `fetch()` threw an exception. This is probably because the limiter has been - // disconnected. Stubs implement E-order semantics, meaning that calls to the same stub - // are delivered to the remote object in order, until the stub becomes disconnected, after - // which point all further calls fail. This guarantee makes a lot of complex interaction - // patterns easier, but it means we must be prepared for the occasional disconnect, as - // networks are inherently unreliable. - // - // Anyway, get a new limiter and try again. If it fails again, something else is probably - // wrong. - this.limiter = this.getLimiterStub(); - response = await this.limiter.fetch("https://dummy-url", {method: "POST"}); - } - - // The response indicates how long we want to pause before accepting more requests. - let cooldown = +(await response.text()); - await new Promise(resolve => setTimeout(resolve, cooldown * 1000)); - - // Done waiting. - this.inCooldown = false; - } catch (err) { - this.reportError(err); - } - } -} diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/start.sh b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/start.sh deleted file mode 100755 index 5d8163b78..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/start.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -# use sed to replace the line starting with "command2 = isWsl" in the file -# this is needed to fix looking for the wrong powershell.exe on non-C:\ drives -sed -i 's/command2 = isWsl.*/command2 = "powershell.exe"/' ./node_modules/wrangler/wrangler-dist/cli.js - -RESOLVED_PORT=$PORT -if [ -z "$PORT" ]; then - RESOLVED_PORT=2222 -fi -echo "http://localhost:$RESOLVED_PORT/" - -# start local development server -node ./node_modules/wrangler dev -l --port $RESOLVED_PORT diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/wrangler.toml b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/wrangler.toml deleted file mode 100644 index cb783bdfa..000000000 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/wrangler.toml +++ /dev/null @@ -1,25 +0,0 @@ -name = "multiplayer" -workers_dev = true -compatibility_date = "2023-06-01" -# Add your account ID here - -main = "src/chat.mjs" - -[site] -bucket = "./public" - -[durable_objects] -bindings = [ - { name = "rooms", class_name = "ChatRoom" }, - { name = "limiters", class_name = "RateLimiter" } -] - -[[rules]] -type = "Data" -globs = ["**/*.html"] -fallthrough = false - -# Indicate that you want the ChatRoom and RateLimiter classes to be callable as Durable Objects. -[[migrations]] -tag = "v1" # Should be unique for each entry -new_classes = ["ChatRoom", "RateLimiter"] \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/react-agents-client.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/react-agents-client.mjs index 4b0934715..287e87624 100644 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/react-agents-client.mjs +++ b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/react-agents-client.mjs @@ -1,8 +1,9 @@ import { multiplayerEndpointUrl, } from 'react-agents/util/endpoints.mjs'; -import { NetworkRealms } from './packages/multiplayer/public/network-realms.mjs'; // XXX should be a deduplicated import, in a separate npm module -// import { webbrowserActionsToText } from './packages/upstreet-agent/packages/react-agents/util/browser-action-utils.mjs'; +import * as agentMultiplayer from 'agent-multiplayer'; +import { METHODS, METHOD_NAMES } from 'agent-multiplayer'; +// import type { AgentMultiplayerApi } from 'agent-multiplayer'; import { Player, } from './util/player.mjs'; @@ -12,7 +13,8 @@ import { SpeakerMap, } from './util/maps.mjs'; -export class ReactAgentsClient { +// XXX handle joins +/* export class ReactAgentsClient { url; constructor(url) { this.url = url; @@ -56,9 +58,230 @@ export class ReactAgentsClient { } } } -} +} */ + +const waitForMessageType = (agentMultiplayerApi, method) => { + const methodName = METHOD_NAMES[method]; + if (!methodName) { + throw new Error(`Unknown method: ${method}`); + } + + return new Promise((resolve, reject) => { + const onmethod = (o) => { + resolve(o); + webSocket.removeEventListener(methodName, onmethod); + webSocket.removeEventListener('close', onclose); + webSocket.removeEventListener('error', onerror); + }; + agentMultiplayerApi.addEventListener(methodName, onmethod); + + const onclose = () => { + reject(new Error('AgentMultiplayerApi closed')); + }; + agentMultiplayerApi.addEventListener('close', onclose); + + const onerror = (e) => { + reject(e); + }; + agentMultiplayerApi.addEventListener('error', onerror); + }); +}; + +// type ReactAgentsMultiplayerConnectionApi = { +// playersMap: PlayersMap; +// typingMap: TypingMap; +// speakerMap: SpeakerMap; +// log: (...args: any[]) => void; +// }; + +class ReactAgentsMultiplayerConnection { + static async connect({ + agentMultiplayerConnection, + profile, + signal, + }) { + // 1. set the player data + // 2. wait for network init message + // 3. bind listeners + + agentMultiplayerConnection.send({ + method: METHODS.SET_PLAYER_DATA, + args: { + playerData: profile, + }, + }); + + const networkInitMessage = await waitForMessageType(agentMultiplayerConnection, METHODS.NETWORK_INIT); + if (signal?.aborted) { + throw new Error('Connection aborted'); + } + const { + playerId, + players, + } = networkInitMessage.args; + + // set up result + const result = new EventTarget(); + // members + result.playerId = playerId; + const playersMap = new PlayersMap(); + result.playersMap = playersMap; + const typingMap = new TypingMap(); + result.typingMap = typingMap; + const speakerMap = new SpeakerMap(); + result.speakerMap = speakerMap; + // methods + result.log = (...args) => { + agentMultiplayerConnection.send({ + method: METHODS.LOG, + args: { + playerId, + args, + }, + }); + }; + result.sendChatMessage = (message, attachments) => { + agentMultiplayerConnection.send({ + method: METHODS.CHAT, + args: { + playerId, + message, + attachments, + }, + }); + }; + result.setTyping = (typing) => { + agentMultiplayerConnection.send({ + method: METHODS.TYPING, + args: { + playerId, + typing, + }, + }); + }; + result.setSpeaking = (speaking) => { + agentMultiplayerConnection.send({ + method: METHODS.SPEAKING, + args: { + playerId, + speaking, + }, + }); + }; + + // initialize local player + const localPlayer = new Player(playerId, profile); + playersMap.add(playerId, localPlayer); + + // initialize remote players + for (const player of players) { + const { + playerId, + playerData, + } = player; + const remotePlayer = new Player(playerId, playerData); + playersMap.add(playerId, remotePlayer); + } + + // bind listeners + [ + [METHODS.CHAT, 'chat'], + [METHODS.LOG, 'log'], + [METHODS.AUDIO, 'audio'], + [METHODS.AUDIOSTART, 'audiostart'], + [METHODS.AUDIOEND, 'audioend'], + [METHODS.VIDEO, 'video'], + [METHODS.VIDEOSTART, 'videostart'], + [METHODS.VIDEOEND, 'videoend'], + ].forEach(([method, eventName]) => { + const methodName = METHOD_NAMES[method]; + if (!methodName) { + throw new Error(`Unknown method: ${method}`); + } + agentMultiplayerConnection.addEventListener(methodName, e => { + result.dispatchEvent(new MessageEvent(eventName, { + data: e.data, + })); + }); + }); + agentMultiplayerConnection.addEventListener(METHOD_NAMES[METHODS.JOIN], e => { + const { + playerId, + playerData, + } = e.data; + let remotePlayer = playersMap.get(playerId); + if (!remotePlayer) { + remotePlayer = new Player(playerId, playerData); + playersMap.add(playerId, remotePlayer); + + result.dispatchEvent(new MessageEvent('join', { + data: { + player: remotePlayer, + }, + })); + } else { + result.log('remote player already in playersMap', playerId); + throw new Error('remote player already in playersMap: ' + playerId); + } + }); + agentMultiplayerConnection.addEventListener(METHOD_NAMES[METHODS.LEAVE], e => { + const { + playerId, + } = e.data; + const remotePlayer = playersMap.get(playerId); + if (remotePlayer) { + playersMap.remove(playerId); + result.dispatchEvent(new MessageEvent('leave', { + data: { + player: remotePlayer, + }, + })); + } else { + result.log('remote player not found during leave', playerId); + throw new Error('remote player not found during leave'); + } + }); + agentMultiplayerConnection.addEventListener(METHOD_NAMES[METHODS.TYPING], e => { + const { + playerId, + typing, + } = e.data; + typingMap.set(playerId, typing); + }); + agentMultiplayerConnection.addEventListener(METHOD_NAMES[METHODS.SPEAKING], e => { + const { + playerId, + speaking, + } = e.data; + speakerMap.set(playerId, speaking); + }); + agentMultiplayerConnection.addEventListener(METHOD_NAMES[METHODS.SET_PLAYER_DATA], e => { + const { + playerId, + playerData, + } = e.data; + const player = playersMap.get(playerId); + if (player) { + player.setPlayerData(playerData); + } else { + result.log('player not found during set player data', playerId); + throw new Error('player not found during set player data: ' + playerId); + } + }); + [ + 'close', + 'error', + ].forEach(eventName => { + agentMultiplayerConnection.addEventListener(eventName, e => { + result.dispatchEvent(new MessageEvent(eventName, { + data: e.data, + })); + }); + }); + + return result; + } -export class ReactAgentsMultiplayerConnection extends EventTarget { static logLevels = { error: 0, warn: 1, @@ -66,7 +289,8 @@ export class ReactAgentsMultiplayerConnection extends EventTarget { debug: 3, }; static defaultLogLevel = ReactAgentsMultiplayerConnection.logLevels.info; - room; + + /* room; profile; metadata; playersMap = new PlayersMap(); @@ -74,19 +298,19 @@ export class ReactAgentsMultiplayerConnection extends EventTarget { speakerMap = new SpeakerMap(); realms; connectPromise; - constructor({ - room, - profile, - metadata = {}, - }) { - super(); + // constructor({ + // room, + // profile, + // metadata = {}, + // }) { + // super(); - this.room = room; - this.profile = profile; - this.metadata = metadata; + // this.room = room; + // this.profile = profile; + // this.metadata = metadata; - this.connectPromise = this.connect(); - } + // this.connectPromise = this.connect(); + // } log(...args) { this.dispatchEvent(new MessageEvent('log', { data: { @@ -313,16 +537,22 @@ export class ReactAgentsMultiplayerConnection extends EventTarget { } removeVideoSource(videoSource) { return this.realms.removeVideoSource(videoSource); - } + } */ } + export const connect = async ({ room, profile, + signal, }) => { - const connection = new ReactAgentsMultiplayerConnection({ - room, + const u = `${multiplayerEndpointUrl}/room/${room}/websocket`; + const agentMultiplayerConnection = await agentMultiplayer.connect(u, { + signal, + }); + const ramConnection = await ReactAgentsMultiplayerConnection.connect({ + agentMultiplayerConnection, profile, + signal, }); - await connection.waitForConnect(); - return connection; + return ramConnection; }; \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/util/maps.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/util/maps.mjs index 2eac76cea..bb0316ae1 100644 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents-client/util/maps.mjs +++ b/packages/usdk/packages/upstreet-agent/packages/react-agents-client/util/maps.mjs @@ -43,19 +43,28 @@ export class PlayersMap extends EventTarget { } export class TypingMap extends EventTarget { #internalMap = new Map(); // playerId: string -> { userId: string, name: string, typing: boolean } - getMap() { - return this.#internalMap; + // getMap() { + // return this.#internalMap; + // } + get(playerId) { + return this.#internalMap.get(playerId); } - set(playerId, spec) { - this.#internalMap.set(playerId, spec); + set(playerId, typing) { + this.#internalMap.set(playerId, typing); this.dispatchEvent(new MessageEvent('typingchange', { - data: spec, + data: { + playerId, + typing, + }, })); } clear() { - for (const [playerId, spec] of this.#internalMap) { + for (const [playerId, typing] of this.#internalMap) { this.dispatchEvent(new MessageEvent('typingchange', { - data: spec, + data: { + playerId, + typing, + }, })); } this.#internalMap.clear(); @@ -63,7 +72,34 @@ export class TypingMap extends EventTarget { } export class SpeakerMap extends EventTarget { #internalMap = new Map(); // playerId: string -> boolean - #localSpeakingCount = 0; + // getMap() { + // return this.#internalMap; + // } + get(playerId) { + return this.#internalMap.get(playerId); + } + set(playerId, speaking) { + this.#internalMap.set(playerId, speaking); + this.dispatchEvent(new MessageEvent('speakingchange', { + data: { + playerId, + speaking, + }, + })); + } + clear() { + for (const [playerId, speaking] of this.#internalMap) { + this.dispatchEvent(new MessageEvent('speakingchange', { + data: { + playerId, + speaking, + }, + })); + } + this.#internalMap.clear(); + } + + /* #localSpeakingCount = 0; #lastPlaying = false; getRemote(playerId) { return this.#internalMap.get(playerId) ?? 0; @@ -172,5 +208,5 @@ export class SpeakerMap extends EventTarget { this.#internalMap.clear(); this.#localSpeakingCount = 0; this.#lastPlaying = false; - } + } */ } \ No newline at end of file diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents/devices/audio-transcriber.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents/devices/audio-transcriber.mjs index cdfc304f6..d5096f41d 100644 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents/devices/audio-transcriber.mjs +++ b/packages/usdk/packages/upstreet-agent/packages/react-agents/devices/audio-transcriber.mjs @@ -1,5 +1,5 @@ import { transcribeRealtime } from '../util/audio-perception.mjs'; -import { resample } from 'codecs/resample.mjs'; +import { resample } from 'agent-codecs/resample.mjs'; import { AudioChunker } from '../util/audio-chunker.mjs'; // diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents/devices/video-input.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents/devices/video-input.mjs index 37c849dc1..5eb43323d 100644 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents/devices/video-input.mjs +++ b/packages/usdk/packages/upstreet-agent/packages/react-agents/devices/video-input.mjs @@ -4,8 +4,8 @@ import { Jimp } from 'jimp'; import { intToRGBA } from '@jimp/utils'; import chalk from 'chalk'; import ansiEscapeSequences from 'ansi-escape-sequences'; -import { QueueManager } from 'queue-manager'; -import { WebPEncoder } from 'codecs/webp-codec.mjs'; +import { QueueManager } from 'queue-manager-async'; +import { WebPEncoder } from 'agent-codecs/webp-codec.mjs'; // diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents/util/audio-perception.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents/util/audio-perception.mjs index be879f390..c5d73fad6 100644 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents/util/audio-perception.mjs +++ b/packages/usdk/packages/upstreet-agent/packages/react-agents/util/audio-perception.mjs @@ -2,9 +2,9 @@ import { mulaw } from '../lib/alawmulaw/dist/alawmulaw.mjs'; import { floatTo16Bit, // int16ToFloat32, -} from 'codecs/convert.mjs'; -import { AudioEncodeStream } from 'codecs/audio-encode.mjs'; -import { QueueManager } from 'queue-manager'; +} from 'agent-codecs/convert.mjs'; +import { AudioEncodeStream } from 'agent-codecs/audio-encode.mjs'; +import { QueueManager } from 'queue-manager-async'; import { aiHost, } from './endpoints.mjs'; diff --git a/packages/usdk/packages/upstreet-agent/packages/react-agents/util/endpoints.mjs b/packages/usdk/packages/upstreet-agent/packages/react-agents/util/endpoints.mjs index 5db4ba4ec..cd7d19379 100644 --- a/packages/usdk/packages/upstreet-agent/packages/react-agents/util/endpoints.mjs +++ b/packages/usdk/packages/upstreet-agent/packages/react-agents/util/endpoints.mjs @@ -1,7 +1,7 @@ export const aiHost = `https://ai.upstreet.ai`; export const aiProxyHost = `ai-proxy.isekaichat.workers.dev`; export const authHost = 'https://auth.upstreet.ai'; -export const multiplayerEndpointUrl = 'wss://multiplayer.isekaichat.workers.dev'; +export const multiplayerEndpointUrl = 'wss://agent-multiplayer.isekaichat.workers.dev'; export const deployEndpointUrl = `https://deploy.upstreet.ai`; export const r2EndpointUrl = `https://r2.upstreet.ai`; export const chatEndpointUrl = `https://upstreet.ai`; diff --git a/packages/usdk/util/connect-utils.mjs b/packages/usdk/util/connect-utils.mjs index 28d027634..bf0f92370 100644 --- a/packages/usdk/util/connect-utils.mjs +++ b/packages/usdk/util/connect-utils.mjs @@ -7,7 +7,7 @@ import alea from 'alea'; import pc from 'picocolors'; import { uniqueNamesGenerator, adjectives, colors, animals } from 'unique-names-generator'; -import { QueueManager } from '../packages/upstreet-agent/packages/queue-manager/queue-manager.mjs'; +import { QueueManager } from 'queue-manager-async'; // import { lembed } from '../packages/upstreet-agent/packages/react-agents/util/embedding.mjs'; import { makeId } from '../packages/upstreet-agent/packages/react-agents/util/util.mjs'; import { parseAgentSpecs } from '../lib/agent-spec-utils.mjs'; @@ -19,6 +19,7 @@ import { workersHost, aiProxyHost, usdkDiscordUrl, + multiplayerEndpointUrl, } from '../packages/upstreet-agent/packages/react-agents/util/endpoints.mjs'; import { @@ -32,9 +33,11 @@ import { TerminalVideoRenderer, } from '../packages/upstreet-agent/packages/react-agents/devices/video-input.mjs'; import { getLoginJwt } from '../util/login-util.mjs'; -import { ReactAgentsClient, ReactAgentsMultiplayerConnection } from '../packages/upstreet-agent/packages/react-agents-client/react-agents-client.mjs'; -import { AudioDecodeStream } from '../packages/upstreet-agent/packages/codecs/audio-decode.mjs'; -import * as codecs from '../packages/upstreet-agent/packages/codecs/ws-codec-runtime-fs.mjs'; +// import { ReactAgentsClient, ReactAgentsMultiplayerConnection } from '../packages/upstreet-agent/packages/react-agents-client/react-agents-client.mjs'; +import * as reactAgentsClient from '../packages/upstreet-agent/packages/react-agents-client/react-agents-client.mjs'; +// XXX finish this +import { AudioDecodeStream } from 'agent-codecs/audio-decode.mjs'; +import * as codecs from 'agent-codecs/ws-codec-runtime-fs.mjs'; import { webbrowserActionsToText } from '../packages/upstreet-agent/packages/react-agents/util/browser-action-utils.mjs'; import { @@ -87,6 +90,40 @@ const getUserProfile = async () => { return user; }; +const agentJoin = async ({ + agentUrl, + endpointUrl, + room, + only, +}) => { + const res = await fetch(`${agentUrl}/join`, { + method: 'POST', + body: JSON.stringify({ + endpointUrl, + room, + only, + }), + }); + const json = await res.json(); + return json; +}; + +const agentLeave = async ({ + agentUrl, + endpointUrl, + room, +}) => { + const res = await fetch(`${agentUrl}/leave`, { + method: 'POST', + body: JSON.stringify({ + endpointUrl, + room, + }), + }); + const json = await res.json(); + return json; +}; + const startMultiplayerRepl = ({ profile, realms, @@ -930,11 +967,19 @@ export const join = async (args) => { if (room) { try { const joinPromises = agentSpecs.map(async (agentSpec) => { - const u = `${getAgentSpecHost(agentSpec)}`; - const agentClient = new ReactAgentsClient(u); - await agentClient.join(room, { + const agentUrl = `${getAgentSpecHost(agentSpec)}`; + await agentJoin({ + agentUrl, + endpointUrl: multiplayerEndpointUrl, + room, only: true, }); + + // const u = `${getAgentSpecHost(agentSpec)}`; + // const agentClient = new ReactAgentsClient(u); + // await agentClient.join(room, { + // only: true, + // }); }); await Promise.all(joinPromises); } catch (err) { @@ -953,15 +998,21 @@ export const leave = async (args) => { if (agentSpecs.length === 1) { if (room) { const _leaveAgent = async (agentSpec, room) => { - const u = `${getAgentSpecHost(agentSpec)}/leave`; - const leaveReq = await fetch(u, { - method: 'POST', - body: JSON.stringify({ - room, - }), + const agentUrl = `${getAgentSpecHost(agentSpec)}`; + await agentLeave({ + agentUrl, + endpointUrl: multiplayerEndpointUrl, + room, }); - const leaveJson = await leaveReq.json(); - // console.log('leave json', leaveJson); + + // const u = `${getAgentSpecHost(agentSpec)}/leave`; + // const leaveReq = await fetch(u, { + // method: 'POST', + // body: JSON.stringify({ + // room, + // }), + // }); + // const leaveJson = await leaveReq.json(); }; return await _leaveAgent(agentSpecs[0], room); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eae781386..f75aba262 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -98,9 +98,6 @@ importers: '@types/three': specifier: ^0.167.1 version: 0.167.2 - '@upstreet/multiplayer': - specifier: file:../../packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer - version: multiplayer@file:packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer '@vercel/analytics': specifier: 1.1.2 version: 1.1.2 @@ -110,6 +107,12 @@ importers: '@vercel/og': specifier: 0.6.2 version: 0.6.2 + agent-codecs: + specifier: ^0.0.3 + version: 0.0.3 + agent-multiplayer: + specifier: ^0.0.8 + version: 0.0.8 ai: specifier: 3.1.5 version: 3.1.5(openai@4.76.1(zod@3.24.1))(react@18.2.0)(solid-js@1.9.3)(svelte@4.2.19)(vue@3.5.13(typescript@5.7.2))(zod@3.24.1) @@ -122,9 +125,6 @@ importers: clsx: specifier: 2.1.0 version: 2.1.0 - codecs: - specifier: file:../../packages/usdk/packages/upstreet-agent/packages/codecs - version: link:../../packages/usdk/packages/upstreet-agent/packages/codecs cookie: specifier: ^0.6.0 version: 0.6.0 @@ -176,9 +176,9 @@ importers: openai: specifier: ^4.55.4 version: 4.76.1(zod@3.24.1) - queue-manager: - specifier: file:../../packages/usdk/packages/upstreet-agent/packages/queue-manager - version: link:../../packages/usdk/packages/upstreet-agent/packages/queue-manager + queue-manager-async: + specifier: ^0.0.1 + version: 0.0.1 react: specifier: ^18.2.0 version: 18.2.0 @@ -242,6 +242,9 @@ importers: three: specifier: ^0.167.1 version: 0.167.1 + u8-encoder: + specifier: ^0.0.5 + version: 0.0.5 ucom: specifier: file:../../packages/ucom/src version: file:packages/ucom/src @@ -251,9 +254,6 @@ importers: web-worker: specifier: 1.2.0 version: 1.2.0 - zjs: - specifier: file:../../packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs - version: '@upstreet/zjs@file:packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs' zod: specifier: ^3.23.8 version: 3.24.1 @@ -639,9 +639,9 @@ importers: '@types/estree': specifier: ^1.0.5 version: 1.0.6 - '@wasm-audio-decoders/common': - specifier: file:./packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common - version: file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common + agent-codecs: + specifier: ^0.0.3 + version: 0.0.3 alea: specifier: ^1.0.1 version: 1.0.1 @@ -666,9 +666,6 @@ importers: cli-table3: specifier: ^0.6.4 version: 0.6.5 - codecs: - specifier: file:./packages/upstreet-agent/packages/codecs - version: link:packages/upstreet-agent/packages/codecs commander: specifier: ^12.0.0 version: 12.1.0 @@ -681,9 +678,9 @@ importers: cross-spawn: specifier: ^7.0.3 version: 7.0.6 - debouncer: - specifier: file:./packages/upstreet-agent/packages/debouncer - version: link:packages/upstreet-agent/packages/debouncer + debouncer-async: + specifier: ^0.0.1 + version: 0.0.1 dedent: specifier: ^1.5.3 version: 1.5.3(babel-plugin-macros@3.1.0) @@ -741,15 +738,9 @@ importers: jszip: specifier: ^3.10.1 version: 3.10.1 - lamejs: - specifier: file:./packages/upstreet-agent/packages/codecs/packages/lamejs - version: file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs latest-version: specifier: ^9.0.0 version: 9.0.0 - libopusjs: - specifier: file:./packages/upstreet-agent/packages/codecs/packages/libopusjs - version: file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs memoize-one: specifier: ^6.0.0 version: 6.0.0 @@ -759,9 +750,6 @@ importers: mkdirp: specifier: ^3.0.1 version: 3.0.1 - mpg123-decoder: - specifier: file:./packages/upstreet-agent/packages/codecs/packages/mpg123-decoder - version: file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder open: specifier: ^10.1.0 version: 10.1.0 @@ -789,9 +777,9 @@ importers: pupa: specifier: ^3.1.0 version: 3.1.0 - queue-manager: - specifier: file:./packages/upstreet-agent/packages/queue-manager - version: link:packages/upstreet-agent/packages/queue-manager + queue-manager-async: + specifier: ^0.0.1 + version: 0.0.1 react-agents: specifier: file:./packages/upstreet-agent/packages/react-agents version: link:packages/upstreet-agent/packages/react-agents @@ -822,6 +810,9 @@ importers: simple-yenc: specifier: ^1.0.4 version: 1.0.4 + u8-encoder: + specifier: ^0.0.5 + version: 0.0.5 unique-names-generator: specifier: ^4.7.1 version: 4.7.1 @@ -858,9 +849,6 @@ importers: yjs: specifier: ^13.6.18 version: 13.6.20 - zjs: - specifier: file:./packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs - version: '@upstreet/zjs@file:packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs' zod: specifier: ^3.23.8 version: 3.24.1 @@ -954,15 +942,15 @@ importers: '@types/jest': specifier: ^29.5.13 version: 29.5.14 + agent-codecs: + specifier: ^0.0.3 + version: 0.0.3 browser-util-inspect: specifier: ^0.2.0 version: 0.2.0 - codecs: - specifier: file:./packages/codecs - version: link:packages/codecs - debouncer: - specifier: file:./packages/debouncer - version: link:packages/debouncer + debouncer-async: + specifier: ^0.0.1 + version: 0.0.1 dedent: specifier: ^1.5.3 version: 1.5.3(babel-plugin-macros@3.1.0) @@ -993,15 +981,12 @@ importers: openai: specifier: ^4.56.0 version: 4.76.1(zod@3.24.1) - path-util: - specifier: file:./packages/path-util - version: link:packages/path-util playwright-core-lite: specifier: file:./packages/playwright-core-lite version: link:packages/playwright-core-lite - queue-manager: - specifier: file:./packages/queue-manager - version: link:packages/queue-manager + queue-manager-async: + specifier: ^0.0.1 + version: 0.0.1 react: specifier: file:./packages/react version: link:packages/react @@ -1032,15 +1017,15 @@ importers: typescript: specifier: ^5.6.2 version: 5.7.2 + u8-encoder: + specifier: ^0.0.5 + version: 0.0.5 uuid-by-string: specifier: ^4.0.0 version: 4.0.0 yjs: specifier: ^13.6.18 version: 13.6.20 - zjs: - specifier: file:./packages/react-agents-client/packages/multiplayer/packages/zjs - version: '@upstreet/zjs@file:packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs' zod: specifier: ^3.23.8 version: 3.24.1 @@ -1061,41 +1046,17 @@ importers: specifier: ^29.7.0 version: 29.7.0(@types/node@22.8.1)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.10.1(@swc/helpers@0.5.13))(@types/node@22.8.1)(typescript@5.7.2)) - packages/usdk/packages/upstreet-agent/packages/codecs: - dependencies: - lamejs: - specifier: file:./packages/lamejs - version: file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs - libopusjs: - specifier: file:./packages/libopusjs - version: file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs - mpg123-decoder: - specifier: file:./packages/mpg123-decoder - version: file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder - queue-manager: - specifier: file:../queue-manager - version: link:../queue-manager - zjs: - specifier: file:../react-agents-client/packages/multiplayer/packages/zjs - version: '@upstreet/zjs@file:packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs' - - packages/usdk/packages/upstreet-agent/packages/debouncer: {} - - packages/usdk/packages/upstreet-agent/packages/path-util: {} - packages/usdk/packages/upstreet-agent/packages/playwright-core-lite: {} - packages/usdk/packages/upstreet-agent/packages/queue-manager: {} - packages/usdk/packages/upstreet-agent/packages/react: {} packages/usdk/packages/upstreet-agent/packages/react-agents: {} packages/usdk/packages/upstreet-agent/packages/react-agents-browser: dependencies: - codecs: - specifier: file:../codecs - version: link:../codecs + agent-codecs: + specifier: ^0.0.3 + version: 0.0.3 react-agents: specifier: file:../react-agents version: link:../react-agents @@ -1111,9 +1072,9 @@ importers: packages/usdk/packages/upstreet-agent/packages/react-agents-client: dependencies: - '@upstreet/multiplayer': - specifier: file:./packages/multiplayer - version: multiplayer@file:packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer + agent-multiplayer: + specifier: ^0.0.8 + version: 0.0.8 react-agents: specifier: file:../react-agents version: link:../react-agents @@ -6045,9 +6006,6 @@ packages: '@upstash/redis@1.25.1': resolution: {integrity: sha512-ACj0GhJ4qrQyBshwFgPod6XufVEfKX2wcaihsEvSdLYnY+m+pa13kGt1RXm/yTHKf4TQi/Dy2A8z/y6WUEOmlg==} - '@upstreet/zjs@file:packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs': - resolution: {directory: packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs, type: directory} - '@use-gesture/core@10.3.1': resolution: {integrity: sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==} @@ -6173,9 +6131,6 @@ packages: '@vue/shared@3.5.13': resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} - '@wasm-audio-decoders/common@file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common': - resolution: {directory: packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common, type: directory} - '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -6314,6 +6269,12 @@ packages: resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} + agent-codecs@0.0.3: + resolution: {integrity: sha512-xVZPYW5UqRBOuB7hQxASh/+h1bqJLEgRgKBItqpPQKvF0NyCCwWsML3Z825K9tVE4Aro1hiWEhosEOyeHx0ybg==} + + agent-multiplayer@0.0.8: + resolution: {integrity: sha512-/R19mMbGKVvQn41lqk43nAni251rCMXqDxylKOJ3WF5ximus/gw0D1yHfcLu+2ImVSSHwYhhgONWk6FwjwQKPA==} + agentkeepalive@4.5.0: resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} engines: {node: '>= 8.0.0'} @@ -7148,9 +7109,6 @@ packages: code-red@1.0.4: resolution: {integrity: sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==} - codecs@file:packages/usdk/packages/upstreet-agent/packages/codecs: - resolution: {directory: packages/usdk/packages/upstreet-agent/packages/codecs, type: directory} - collapse-white-space@2.1.0: resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} @@ -7595,8 +7553,8 @@ packages: debounce@1.2.1: resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} - debouncer@file:packages/usdk/packages/upstreet-agent/packages/debouncer: - resolution: {directory: packages/usdk/packages/upstreet-agent/packages/debouncer, type: directory} + debouncer-async@0.0.1: + resolution: {integrity: sha512-6H5dq8Cz9Gz9LnwUJr8MiFLXXnGy+jlBflBzB0X/tAGS0RWHT1kS+7X/vcFDn55cDpOengu0fi09iwfQrSVW5A==} debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} @@ -10214,9 +10172,6 @@ packages: resolution: {integrity: sha512-Sz49ZWR/BjNOq+2UK1k9ONZUVq8eyuCj30Zgc8VrRNtFlTBZduzuvehUd5kjQF6/Fms3Ir3EYqzJryw9tRvsSw==} engines: {node: '>=18'} - lamejs@file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs: - resolution: {directory: packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs, type: directory} - language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -10255,9 +10210,6 @@ packages: engines: {node: '>=16'} hasBin: true - libopusjs@file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs: - resolution: {directory: packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs, type: directory} - lie@3.1.1: resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==} @@ -10981,9 +10933,6 @@ packages: motion-utils@11.13.0: resolution: {integrity: sha512-lq6TzXkH5c/ysJQBxgLXgM01qwBH1b4goTPh57VvZWJbVJZF/0SB31UWEn4EIqbVPf3au88n2rvK17SpDTja1A==} - mpg123-decoder@file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder: - resolution: {directory: packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder, type: directory} - mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -10997,9 +10946,6 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - multiplayer@file:packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer: - resolution: {directory: packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer, type: directory} - mustache@4.2.0: resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} hasBin: true @@ -11549,9 +11495,6 @@ packages: resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==} engines: {node: '>=12'} - path-util@file:packages/usdk/packages/upstreet-agent/packages/path-util: - resolution: {directory: packages/usdk/packages/upstreet-agent/packages/path-util, type: directory} - pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} @@ -12155,8 +12098,8 @@ packages: querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - queue-manager@file:packages/usdk/packages/upstreet-agent/packages/queue-manager: - resolution: {directory: packages/usdk/packages/upstreet-agent/packages/queue-manager, type: directory} + queue-manager-async@0.0.1: + resolution: {integrity: sha512-vyc19znNJbJSWcomO7VG0G+AbSBgk3wmhBbKKSHC0X12L/ceIDkvyMPcW+sBemkXe6iTHXLIfRbnAuUYRnNStg==} queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -13739,6 +13682,12 @@ packages: engines: {node: '>=14.17'} hasBin: true + u8-encoder@0.0.4: + resolution: {integrity: sha512-dI0lrSax+ymc0LNKiFhLkmqoxWHJYNQ3ryi74jg8/SvDWHL+9nLVnyUwxW3b6PouXtwavIpFaDL199mhU1lODw==} + + u8-encoder@0.0.5: + resolution: {integrity: sha512-AOwAoUlu8DiT0AwNeRSt5oT+Dsz6Iy172FUD+Jvvb7ZRHtGWO6+DShGd0if8u0y/QQWwUrW1Mixo/vA/Qa5IsQ==} + ucom@file:packages/ucom/src: resolution: {directory: packages/ucom/src, type: directory} @@ -13964,9 +13913,6 @@ packages: '@types/react': optional: true - use-strict@1.0.1: - resolution: {integrity: sha512-IeiWvvEXfW5ltKVMkxq6FvNf2LojMKvB2OCeja6+ct24S1XOmQw2dGr2JyndwACWAGJva9B7yPHwAmeA9QCqAQ==} - use-sync-external-store@1.2.2: resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==} peerDependencies: @@ -20692,8 +20638,6 @@ snapshots: dependencies: crypto-js: 4.2.0 - '@upstreet/zjs@file:packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs': {} - '@use-gesture/core@10.3.1': {} '@use-gesture/react@10.3.1(react@18.2.0)': @@ -20954,11 +20898,6 @@ snapshots: '@vue/shared@3.5.13': {} - '@wasm-audio-decoders/common@file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common': - dependencies: - '@eshaz/web-worker': 1.2.2 - simple-yenc: 1.0.4 - '@webassemblyjs/ast@1.14.1': dependencies: '@webassemblyjs/helper-numbers': 1.13.2 @@ -21113,6 +21052,17 @@ snapshots: agent-base@7.1.3: {} + agent-codecs@0.0.3: + dependencies: + queue-manager-async: 0.0.1 + u8-encoder: 0.0.5 + + agent-multiplayer@0.0.8: + dependencies: + '@cloudflare/kv-asset-handler': 0.3.4 + u8-encoder: 0.0.4 + yjs: 13.6.20 + agentkeepalive@4.5.0: dependencies: humanize-ms: 1.2.1 @@ -22045,14 +21995,6 @@ snapshots: estree-walker: 3.0.3 periscopic: 3.1.0 - codecs@file:packages/usdk/packages/upstreet-agent/packages/codecs: - dependencies: - lamejs: file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs - libopusjs: file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs - mpg123-decoder: file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder - queue-manager: file:packages/usdk/packages/upstreet-agent/packages/queue-manager - zjs: '@upstreet/zjs@file:packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs' - collapse-white-space@2.1.0: {} collect-v8-coverage@1.0.2: {} @@ -22549,7 +22491,7 @@ snapshots: debounce@1.2.1: {} - debouncer@file:packages/usdk/packages/upstreet-agent/packages/debouncer: {} + debouncer-async@0.0.1: {} debug@2.6.9: dependencies: @@ -26112,10 +26054,6 @@ snapshots: ky@1.7.3: {} - lamejs@file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/lamejs: - dependencies: - use-strict: 1.0.1 - language-subtag-registry@0.3.23: {} language-tags@1.0.9: @@ -26185,8 +26123,6 @@ snapshots: dependencies: isomorphic.js: 0.2.5 - libopusjs@file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/libopusjs: {} - lie@3.1.1: dependencies: immediate: 3.0.6 @@ -27333,10 +27269,6 @@ snapshots: motion-utils@11.13.0: {} - mpg123-decoder@file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder: - dependencies: - '@wasm-audio-decoders/common': file:packages/usdk/packages/upstreet-agent/packages/codecs/packages/mpg123-decoder/packages/wasm-audio-decoders-common - mri@1.2.0: {} ms@2.0.0: {} @@ -27345,11 +27277,6 @@ snapshots: ms@2.1.3: {} - multiplayer@file:packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer: - dependencies: - '@cloudflare/kv-asset-handler': 0.3.4 - yjs: 13.6.20 - mustache@4.2.0: {} mz@2.7.0: @@ -27895,8 +27822,6 @@ snapshots: path-type@5.0.0: {} - path-util@file:packages/usdk/packages/upstreet-agent/packages/path-util: {} - pathe@1.1.2: {} peek-readable@4.1.0: {} @@ -28424,7 +28349,7 @@ snapshots: querystringify@2.2.0: {} - queue-manager@file:packages/usdk/packages/upstreet-agent/packages/queue-manager: {} + queue-manager-async@0.0.1: {} queue-microtask@1.2.3: {} @@ -28492,7 +28417,7 @@ snapshots: react-agents-client@file:packages/usdk/packages/upstreet-agent/packages/react-agents-client: dependencies: - '@upstreet/multiplayer': multiplayer@file:packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer + agent-multiplayer: 0.0.8 react-agents: file:packages/usdk/packages/upstreet-agent/packages/react-agents react-agents-node@file:packages/usdk/packages/upstreet-agent/packages/react-agents-node: @@ -30532,6 +30457,10 @@ snapshots: typescript@5.7.2: {} + u8-encoder@0.0.4: {} + + u8-encoder@0.0.5: {} + ucom@file:packages/ucom/src: {} ufo@1.5.4: {} @@ -30708,9 +30637,9 @@ snapshots: '@supabase/supabase-js': 2.47.5 '@tsndr/cloudflare-worker-jwt': 2.5.3 '@types/jest': 29.5.14 + agent-codecs: 0.0.3 browser-util-inspect: 0.2.0 - codecs: file:packages/usdk/packages/upstreet-agent/packages/codecs - debouncer: file:packages/usdk/packages/upstreet-agent/packages/debouncer + debouncer-async: 0.0.1 dedent: 1.5.3(babel-plugin-macros@3.1.0) dotenv: 16.4.7 ethers: 6.13.4 @@ -30721,9 +30650,8 @@ snapshots: memoize-one: 6.0.0 minimatch: 9.0.5 openai: 4.76.1(zod@3.24.1) - path-util: file:packages/usdk/packages/upstreet-agent/packages/path-util playwright-core-lite: file:packages/usdk/packages/upstreet-agent/packages/playwright-core-lite - queue-manager: file:packages/usdk/packages/upstreet-agent/packages/queue-manager + queue-manager-async: 0.0.1 react: file:packages/usdk/packages/upstreet-agent/packages/react react-agents: file:packages/usdk/packages/upstreet-agent/packages/react-agents react-agents-client: file:packages/usdk/packages/upstreet-agent/packages/react-agents-client @@ -30734,9 +30662,9 @@ snapshots: ts-jest: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(esbuild@0.20.2)(jest@29.7.0(@types/node@18.19.68)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.10.1(@swc/helpers@0.5.13))(@types/node@18.19.68)(typescript@4.9.5)))(typescript@5.7.2) twitter-api-sdk: 1.2.1 typescript: 5.7.2 + u8-encoder: 0.0.5 uuid-by-string: 4.0.0 yjs: 13.6.20 - zjs: '@upstreet/zjs@file:packages/usdk/packages/upstreet-agent/packages/react-agents-client/packages/multiplayer/packages/zjs' zod: 3.24.1 zod-to-json-schema: 3.24.1(zod@3.24.1) zod-to-ts: 1.2.0(typescript@5.7.2)(zod@3.24.1) @@ -30844,8 +30772,6 @@ snapshots: optionalDependencies: '@types/react': 18.3.16 - use-strict@1.0.1: {} - use-sync-external-store@1.2.2(react@18.2.0): dependencies: react: 18.2.0