mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-28 10:58:15 -05:00
Update #44 - WebAssembly GC support, fix more WebRTC bugs
This commit is contained in:
293
sources/wasm-gc-teavm/java/com/jcraft/jogg/Buffer.java
Normal file
293
sources/wasm-gc-teavm/java/com/jcraft/jogg/Buffer.java
Normal file
@ -0,0 +1,293 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jogg;
|
||||
|
||||
public class Buffer {
|
||||
private static final int BUFFER_INCREMENT = 256;
|
||||
|
||||
private static final int[] mask = { 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f,
|
||||
0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff,
|
||||
0x00007fff, 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
|
||||
0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
|
||||
0xffffffff };
|
||||
|
||||
int ptr = 0;
|
||||
byte[] buffer = null;
|
||||
int endbit = 0;
|
||||
int endbyte = 0;
|
||||
int storage = 0;
|
||||
|
||||
public void writeinit() {
|
||||
buffer = new byte[BUFFER_INCREMENT];
|
||||
ptr = 0;
|
||||
buffer[0] = (byte) '\0';
|
||||
storage = BUFFER_INCREMENT;
|
||||
}
|
||||
|
||||
public void write(byte[] s) {
|
||||
for (int i = 0; i < s.length; i++) {
|
||||
if (s[i] == 0)
|
||||
break;
|
||||
write(s[i], 8);
|
||||
}
|
||||
}
|
||||
|
||||
public void read(byte[] s, int bytes) {
|
||||
int i = 0;
|
||||
while (bytes-- != 0) {
|
||||
s[i++] = (byte) (read(8));
|
||||
}
|
||||
}
|
||||
|
||||
void reset() {
|
||||
ptr = 0;
|
||||
buffer[0] = (byte) '\0';
|
||||
endbit = endbyte = 0;
|
||||
}
|
||||
|
||||
public void writeclear() {
|
||||
buffer = null;
|
||||
}
|
||||
|
||||
public void readinit(byte[] buf, int bytes) {
|
||||
readinit(buf, 0, bytes);
|
||||
}
|
||||
|
||||
public void readinit(byte[] buf, int start, int bytes) {
|
||||
ptr = start;
|
||||
buffer = buf;
|
||||
endbit = endbyte = 0;
|
||||
storage = bytes;
|
||||
}
|
||||
|
||||
public void write(int value, int bits) {
|
||||
if (endbyte + 4 >= storage) {
|
||||
byte[] foo = new byte[storage + BUFFER_INCREMENT];
|
||||
System.arraycopy(buffer, 0, foo, 0, storage);
|
||||
buffer = foo;
|
||||
storage += BUFFER_INCREMENT;
|
||||
}
|
||||
|
||||
value &= mask[bits];
|
||||
bits += endbit;
|
||||
buffer[ptr] |= (byte) (value << endbit);
|
||||
|
||||
if (bits >= 8) {
|
||||
buffer[ptr + 1] = (byte) (value >>> (8 - endbit));
|
||||
if (bits >= 16) {
|
||||
buffer[ptr + 2] = (byte) (value >>> (16 - endbit));
|
||||
if (bits >= 24) {
|
||||
buffer[ptr + 3] = (byte) (value >>> (24 - endbit));
|
||||
if (bits >= 32) {
|
||||
if (endbit > 0)
|
||||
buffer[ptr + 4] = (byte) (value >>> (32 - endbit));
|
||||
else
|
||||
buffer[ptr + 4] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endbyte += bits / 8;
|
||||
ptr += bits / 8;
|
||||
endbit = bits & 7;
|
||||
}
|
||||
|
||||
public int look(int bits) {
|
||||
int ret;
|
||||
int m = mask[bits];
|
||||
|
||||
bits += endbit;
|
||||
|
||||
if (endbyte + 4 >= storage) {
|
||||
if (endbyte + (bits - 1) / 8 >= storage)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ret = ((buffer[ptr]) & 0xff) >>> endbit;
|
||||
if (bits > 8) {
|
||||
ret |= ((buffer[ptr + 1]) & 0xff) << (8 - endbit);
|
||||
if (bits > 16) {
|
||||
ret |= ((buffer[ptr + 2]) & 0xff) << (16 - endbit);
|
||||
if (bits > 24) {
|
||||
ret |= ((buffer[ptr + 3]) & 0xff) << (24 - endbit);
|
||||
if (bits > 32 && endbit != 0) {
|
||||
ret |= ((buffer[ptr + 4]) & 0xff) << (32 - endbit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (m & ret);
|
||||
}
|
||||
|
||||
public int look1() {
|
||||
if (endbyte >= storage)
|
||||
return (-1);
|
||||
return ((buffer[ptr] >> endbit) & 1);
|
||||
}
|
||||
|
||||
public void adv(int bits) {
|
||||
bits += endbit;
|
||||
ptr += bits / 8;
|
||||
endbyte += bits / 8;
|
||||
endbit = bits & 7;
|
||||
}
|
||||
|
||||
public void adv1() {
|
||||
++endbit;
|
||||
if (endbit > 7) {
|
||||
endbit = 0;
|
||||
ptr++;
|
||||
endbyte++;
|
||||
}
|
||||
}
|
||||
|
||||
public int read(int bits) {
|
||||
int ret;
|
||||
int m = mask[bits];
|
||||
|
||||
bits += endbit;
|
||||
|
||||
if (endbyte + 4 >= storage) {
|
||||
ret = -1;
|
||||
if (endbyte + (bits - 1) / 8 >= storage) {
|
||||
ptr += bits / 8;
|
||||
endbyte += bits / 8;
|
||||
endbit = bits & 7;
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
|
||||
ret = ((buffer[ptr]) & 0xff) >>> endbit;
|
||||
if (bits > 8) {
|
||||
ret |= ((buffer[ptr + 1]) & 0xff) << (8 - endbit);
|
||||
if (bits > 16) {
|
||||
ret |= ((buffer[ptr + 2]) & 0xff) << (16 - endbit);
|
||||
if (bits > 24) {
|
||||
ret |= ((buffer[ptr + 3]) & 0xff) << (24 - endbit);
|
||||
if (bits > 32 && endbit != 0) {
|
||||
ret |= ((buffer[ptr + 4]) & 0xff) << (32 - endbit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret &= m;
|
||||
|
||||
ptr += bits / 8;
|
||||
endbyte += bits / 8;
|
||||
endbit = bits & 7;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
public int readB(int bits) {
|
||||
int ret;
|
||||
int m = 32 - bits;
|
||||
|
||||
bits += endbit;
|
||||
|
||||
if (endbyte + 4 >= storage) {
|
||||
/* not the main path */
|
||||
ret = -1;
|
||||
if (endbyte * 8 + bits > storage * 8) {
|
||||
ptr += bits / 8;
|
||||
endbyte += bits / 8;
|
||||
endbit = bits & 7;
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
|
||||
ret = (buffer[ptr] & 0xff) << (24 + endbit);
|
||||
if (bits > 8) {
|
||||
ret |= (buffer[ptr + 1] & 0xff) << (16 + endbit);
|
||||
if (bits > 16) {
|
||||
ret |= (buffer[ptr + 2] & 0xff) << (8 + endbit);
|
||||
if (bits > 24) {
|
||||
ret |= (buffer[ptr + 3] & 0xff) << (endbit);
|
||||
if (bits > 32 && (endbit != 0))
|
||||
ret |= (buffer[ptr + 4] & 0xff) >> (8 - endbit);
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = (ret >>> (m >> 1)) >>> ((m + 1) >> 1);
|
||||
|
||||
ptr += bits / 8;
|
||||
endbyte += bits / 8;
|
||||
endbit = bits & 7;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
public int read1() {
|
||||
int ret;
|
||||
if (endbyte >= storage) {
|
||||
ret = -1;
|
||||
endbit++;
|
||||
if (endbit > 7) {
|
||||
endbit = 0;
|
||||
ptr++;
|
||||
endbyte++;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
ret = (buffer[ptr] >> endbit) & 1;
|
||||
|
||||
endbit++;
|
||||
if (endbit > 7) {
|
||||
endbit = 0;
|
||||
ptr++;
|
||||
endbyte++;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
public int bytes() {
|
||||
return (endbyte + (endbit + 7) / 8);
|
||||
}
|
||||
|
||||
public int bits() {
|
||||
return (endbyte * 8 + endbit);
|
||||
}
|
||||
|
||||
public byte[] buffer() {
|
||||
return (buffer);
|
||||
}
|
||||
|
||||
public static int ilog(int v) {
|
||||
int ret = 0;
|
||||
while (v > 0) {
|
||||
ret++;
|
||||
v >>>= 1;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
public static void report(String in) {
|
||||
System.err.println(in);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
45
sources/wasm-gc-teavm/java/com/jcraft/jogg/Packet.java
Normal file
45
sources/wasm-gc-teavm/java/com/jcraft/jogg/Packet.java
Normal file
@ -0,0 +1,45 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jogg;
|
||||
|
||||
public class Packet {
|
||||
public byte[] packet_base;
|
||||
public int packet;
|
||||
public int bytes;
|
||||
public int b_o_s;
|
||||
public int e_o_s;
|
||||
|
||||
public long granulepos;
|
||||
|
||||
/**
|
||||
* sequence number for decode; the framing knows where there's a hole in the
|
||||
* data, but we need coupling so that the codec (which is in a seperate
|
||||
* abstraction layer) also knows about the gap
|
||||
*/
|
||||
public long packetno;
|
||||
|
||||
}
|
130
sources/wasm-gc-teavm/java/com/jcraft/jogg/Page.java
Normal file
130
sources/wasm-gc-teavm/java/com/jcraft/jogg/Page.java
Normal file
@ -0,0 +1,130 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jogg;
|
||||
|
||||
public class Page {
|
||||
private static int[] crc_lookup = new int[256];
|
||||
static {
|
||||
for (int i = 0; i < crc_lookup.length; i++) {
|
||||
crc_lookup[i] = crc_entry(i);
|
||||
}
|
||||
}
|
||||
|
||||
private static int crc_entry(int index) {
|
||||
int r = index << 24;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if ((r & 0x80000000) != 0) {
|
||||
r = (r << 1) ^ 0x04c11db7; /*
|
||||
* The same as the ethernet generator polynomial, although we use an
|
||||
* unreflected alg and an init/final of 0, not 0xffffffff
|
||||
*/
|
||||
} else {
|
||||
r <<= 1;
|
||||
}
|
||||
}
|
||||
return (r & 0xffffffff);
|
||||
}
|
||||
|
||||
public byte[] header_base;
|
||||
public int header;
|
||||
public int header_len;
|
||||
public byte[] body_base;
|
||||
public int body;
|
||||
public int body_len;
|
||||
|
||||
int version() {
|
||||
return header_base[header + 4] & 0xff;
|
||||
}
|
||||
|
||||
int continued() {
|
||||
return (header_base[header + 5] & 0x01);
|
||||
}
|
||||
|
||||
public int bos() {
|
||||
return (header_base[header + 5] & 0x02);
|
||||
}
|
||||
|
||||
public int eos() {
|
||||
return (header_base[header + 5] & 0x04);
|
||||
}
|
||||
|
||||
public long granulepos() {
|
||||
long foo = header_base[header + 13] & 0xff;
|
||||
foo = (foo << 8) | (header_base[header + 12] & 0xff);
|
||||
foo = (foo << 8) | (header_base[header + 11] & 0xff);
|
||||
foo = (foo << 8) | (header_base[header + 10] & 0xff);
|
||||
foo = (foo << 8) | (header_base[header + 9] & 0xff);
|
||||
foo = (foo << 8) | (header_base[header + 8] & 0xff);
|
||||
foo = (foo << 8) | (header_base[header + 7] & 0xff);
|
||||
foo = (foo << 8) | (header_base[header + 6] & 0xff);
|
||||
return (foo);
|
||||
}
|
||||
|
||||
public int serialno() {
|
||||
return (header_base[header + 14] & 0xff) | ((header_base[header + 15] & 0xff) << 8)
|
||||
| ((header_base[header + 16] & 0xff) << 16) | ((header_base[header + 17] & 0xff) << 24);
|
||||
}
|
||||
|
||||
int pageno() {
|
||||
return (header_base[header + 18] & 0xff) | ((header_base[header + 19] & 0xff) << 8)
|
||||
| ((header_base[header + 20] & 0xff) << 16) | ((header_base[header + 21] & 0xff) << 24);
|
||||
}
|
||||
|
||||
void checksum() {
|
||||
int crc_reg = 0;
|
||||
|
||||
for (int i = 0; i < header_len; i++) {
|
||||
crc_reg = (crc_reg << 8) ^ crc_lookup[((crc_reg >>> 24) & 0xff) ^ (header_base[header + i] & 0xff)];
|
||||
}
|
||||
for (int i = 0; i < body_len; i++) {
|
||||
crc_reg = (crc_reg << 8) ^ crc_lookup[((crc_reg >>> 24) & 0xff) ^ (body_base[body + i] & 0xff)];
|
||||
}
|
||||
header_base[header + 22] = (byte) crc_reg;
|
||||
header_base[header + 23] = (byte) (crc_reg >>> 8);
|
||||
header_base[header + 24] = (byte) (crc_reg >>> 16);
|
||||
header_base[header + 25] = (byte) (crc_reg >>> 24);
|
||||
}
|
||||
|
||||
public Page copy() {
|
||||
return copy(new Page());
|
||||
}
|
||||
|
||||
public Page copy(Page p) {
|
||||
byte[] tmp = new byte[header_len];
|
||||
System.arraycopy(header_base, header, tmp, 0, header_len);
|
||||
p.header_len = header_len;
|
||||
p.header_base = tmp;
|
||||
p.header = 0;
|
||||
tmp = new byte[body_len];
|
||||
System.arraycopy(body_base, body, tmp, 0, body_len);
|
||||
p.body_len = body_len;
|
||||
p.body_base = tmp;
|
||||
p.body = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
}
|
538
sources/wasm-gc-teavm/java/com/jcraft/jogg/StreamState.java
Normal file
538
sources/wasm-gc-teavm/java/com/jcraft/jogg/StreamState.java
Normal file
@ -0,0 +1,538 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jogg;
|
||||
|
||||
public class StreamState {
|
||||
byte[] body_data; /* bytes from packet bodies */
|
||||
int body_storage; /* storage elements allocated */
|
||||
int body_fill; /* elements stored; fill mark */
|
||||
private int body_returned; /* elements of fill returned */
|
||||
|
||||
int[] lacing_vals; /* The values that will go to the segment table */
|
||||
long[] granule_vals; /*
|
||||
* pcm_pos values for headers. Not compact this way, but it is simple coupled to
|
||||
* the lacing fifo
|
||||
*/
|
||||
int lacing_storage;
|
||||
int lacing_fill;
|
||||
int lacing_packet;
|
||||
int lacing_returned;
|
||||
|
||||
byte[] header = new byte[282]; /* working space for header encode */
|
||||
int header_fill;
|
||||
|
||||
public int e_o_s; /*
|
||||
* set when we have buffered the last packet in the logical bitstream
|
||||
*/
|
||||
int b_o_s; /*
|
||||
* set after we've written the initial page of a logical bitstream
|
||||
*/
|
||||
int serialno;
|
||||
int pageno;
|
||||
long packetno; /*
|
||||
* sequence number for decode; the framing knows where there's a hole in the
|
||||
* data, but we need coupling so that the codec (which is in a seperate
|
||||
* abstraction layer) also knows about the gap
|
||||
*/
|
||||
long granulepos;
|
||||
|
||||
public StreamState() {
|
||||
init();
|
||||
}
|
||||
|
||||
StreamState(int serialno) {
|
||||
this();
|
||||
init(serialno);
|
||||
}
|
||||
|
||||
void init() {
|
||||
body_storage = 16 * 1024;
|
||||
body_data = new byte[body_storage];
|
||||
lacing_storage = 1024;
|
||||
lacing_vals = new int[lacing_storage];
|
||||
granule_vals = new long[lacing_storage];
|
||||
}
|
||||
|
||||
public void init(int serialno) {
|
||||
if (body_data == null) {
|
||||
init();
|
||||
} else {
|
||||
for (int i = 0; i < body_data.length; i++)
|
||||
body_data[i] = 0;
|
||||
for (int i = 0; i < lacing_vals.length; i++)
|
||||
lacing_vals[i] = 0;
|
||||
for (int i = 0; i < granule_vals.length; i++)
|
||||
granule_vals[i] = 0;
|
||||
}
|
||||
this.serialno = serialno;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
body_data = null;
|
||||
lacing_vals = null;
|
||||
granule_vals = null;
|
||||
}
|
||||
|
||||
void destroy() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void body_expand(int needed) {
|
||||
if (body_storage <= body_fill + needed) {
|
||||
body_storage += (needed + 1024);
|
||||
byte[] foo = new byte[body_storage];
|
||||
System.arraycopy(body_data, 0, foo, 0, body_data.length);
|
||||
body_data = foo;
|
||||
}
|
||||
}
|
||||
|
||||
void lacing_expand(int needed) {
|
||||
if (lacing_storage <= lacing_fill + needed) {
|
||||
lacing_storage += (needed + 32);
|
||||
int[] foo = new int[lacing_storage];
|
||||
System.arraycopy(lacing_vals, 0, foo, 0, lacing_vals.length);
|
||||
lacing_vals = foo;
|
||||
|
||||
long[] bar = new long[lacing_storage];
|
||||
System.arraycopy(granule_vals, 0, bar, 0, granule_vals.length);
|
||||
granule_vals = bar;
|
||||
}
|
||||
}
|
||||
|
||||
/* submit data to the internal buffer of the framing engine */
|
||||
public int packetin(Packet op) {
|
||||
int lacing_val = op.bytes / 255 + 1;
|
||||
|
||||
if (body_returned != 0) {
|
||||
/*
|
||||
* advance packet data according to the body_returned pointer. We had to keep it
|
||||
* around to return a pointer into the buffer last call
|
||||
*/
|
||||
|
||||
body_fill -= body_returned;
|
||||
if (body_fill != 0) {
|
||||
System.arraycopy(body_data, body_returned, body_data, 0, body_fill);
|
||||
}
|
||||
body_returned = 0;
|
||||
}
|
||||
|
||||
/* make sure we have the buffer storage */
|
||||
body_expand(op.bytes);
|
||||
lacing_expand(lacing_val);
|
||||
|
||||
/*
|
||||
* Copy in the submitted packet. Yes, the copy is a waste; this is the liability
|
||||
* of overly clean abstraction for the time being. It will actually be fairly
|
||||
* easy to eliminate the extra copy in the future
|
||||
*/
|
||||
|
||||
System.arraycopy(op.packet_base, op.packet, body_data, body_fill, op.bytes);
|
||||
body_fill += op.bytes;
|
||||
|
||||
/* Store lacing vals for this packet */
|
||||
int j;
|
||||
for (j = 0; j < lacing_val - 1; j++) {
|
||||
lacing_vals[lacing_fill + j] = 255;
|
||||
granule_vals[lacing_fill + j] = granulepos;
|
||||
}
|
||||
lacing_vals[lacing_fill + j] = (op.bytes) % 255;
|
||||
granulepos = granule_vals[lacing_fill + j] = op.granulepos;
|
||||
|
||||
/* flag the first segment as the beginning of the packet */
|
||||
lacing_vals[lacing_fill] |= 0x100;
|
||||
|
||||
lacing_fill += lacing_val;
|
||||
|
||||
/* for the sake of completeness */
|
||||
packetno++;
|
||||
|
||||
if (op.e_o_s != 0)
|
||||
e_o_s = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
public int packetout(Packet op) {
|
||||
|
||||
/*
|
||||
* The last part of decode. We have the stream broken into packet segments. Now
|
||||
* we need to group them into packets (or return the out of sync markers)
|
||||
*/
|
||||
|
||||
int ptr = lacing_returned;
|
||||
|
||||
if (lacing_packet <= ptr) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if ((lacing_vals[ptr] & 0x400) != 0) {
|
||||
/* We lost sync here; let the app know */
|
||||
lacing_returned++;
|
||||
|
||||
/*
|
||||
* we need to tell the codec there's a gap; it might need to handle previous
|
||||
* packet dependencies.
|
||||
*/
|
||||
packetno++;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Gather the whole packet. We'll have no holes or a partial packet */
|
||||
{
|
||||
int size = lacing_vals[ptr] & 0xff;
|
||||
int bytes = 0;
|
||||
|
||||
op.packet_base = body_data;
|
||||
op.packet = body_returned;
|
||||
op.e_o_s = lacing_vals[ptr] & 0x200; /* last packet of the stream? */
|
||||
op.b_o_s = lacing_vals[ptr] & 0x100; /* first packet of the stream? */
|
||||
bytes += size;
|
||||
|
||||
while (size == 255) {
|
||||
int val = lacing_vals[++ptr];
|
||||
size = val & 0xff;
|
||||
if ((val & 0x200) != 0)
|
||||
op.e_o_s = 0x200;
|
||||
bytes += size;
|
||||
}
|
||||
|
||||
op.packetno = packetno;
|
||||
op.granulepos = granule_vals[ptr];
|
||||
op.bytes = bytes;
|
||||
|
||||
body_returned += bytes;
|
||||
|
||||
lacing_returned = ptr + 1;
|
||||
}
|
||||
packetno++;
|
||||
return (1);
|
||||
}
|
||||
|
||||
// add the incoming page to the stream state; we decompose the page
|
||||
// into packet segments here as well.
|
||||
|
||||
public int pagein(Page og) {
|
||||
byte[] header_base = og.header_base;
|
||||
int header = og.header;
|
||||
byte[] body_base = og.body_base;
|
||||
int body = og.body;
|
||||
int bodysize = og.body_len;
|
||||
int segptr = 0;
|
||||
|
||||
int version = og.version();
|
||||
int continued = og.continued();
|
||||
int bos = og.bos();
|
||||
int eos = og.eos();
|
||||
long granulepos = og.granulepos();
|
||||
int _serialno = og.serialno();
|
||||
int _pageno = og.pageno();
|
||||
int segments = header_base[header + 26] & 0xff;
|
||||
|
||||
// clean up 'returned data'
|
||||
{
|
||||
int lr = lacing_returned;
|
||||
int br = body_returned;
|
||||
|
||||
// body data
|
||||
if (br != 0) {
|
||||
body_fill -= br;
|
||||
if (body_fill != 0) {
|
||||
System.arraycopy(body_data, br, body_data, 0, body_fill);
|
||||
}
|
||||
body_returned = 0;
|
||||
}
|
||||
|
||||
if (lr != 0) {
|
||||
// segment table
|
||||
if ((lacing_fill - lr) != 0) {
|
||||
System.arraycopy(lacing_vals, lr, lacing_vals, 0, lacing_fill - lr);
|
||||
System.arraycopy(granule_vals, lr, granule_vals, 0, lacing_fill - lr);
|
||||
}
|
||||
lacing_fill -= lr;
|
||||
lacing_packet -= lr;
|
||||
lacing_returned = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// check the serial number
|
||||
if (_serialno != serialno)
|
||||
return (-1);
|
||||
if (version > 0)
|
||||
return (-1);
|
||||
|
||||
lacing_expand(segments + 1);
|
||||
|
||||
// are we in sequence?
|
||||
if (_pageno != pageno) {
|
||||
int i;
|
||||
|
||||
// unroll previous partial packet (if any)
|
||||
for (i = lacing_packet; i < lacing_fill; i++) {
|
||||
body_fill -= lacing_vals[i] & 0xff;
|
||||
// System.out.println("??");
|
||||
}
|
||||
lacing_fill = lacing_packet;
|
||||
|
||||
// make a note of dropped data in segment table
|
||||
if (pageno != -1) {
|
||||
lacing_vals[lacing_fill++] = 0x400;
|
||||
lacing_packet++;
|
||||
}
|
||||
|
||||
// are we a 'continued packet' page? If so, we'll need to skip
|
||||
// some segments
|
||||
if (continued != 0) {
|
||||
bos = 0;
|
||||
for (; segptr < segments; segptr++) {
|
||||
int val = (header_base[header + 27 + segptr] & 0xff);
|
||||
body += val;
|
||||
bodysize -= val;
|
||||
if (val < 255) {
|
||||
segptr++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bodysize != 0) {
|
||||
body_expand(bodysize);
|
||||
System.arraycopy(body_base, body, body_data, body_fill, bodysize);
|
||||
body_fill += bodysize;
|
||||
}
|
||||
|
||||
{
|
||||
int saved = -1;
|
||||
while (segptr < segments) {
|
||||
int val = (header_base[header + 27 + segptr] & 0xff);
|
||||
lacing_vals[lacing_fill] = val;
|
||||
granule_vals[lacing_fill] = -1;
|
||||
|
||||
if (bos != 0) {
|
||||
lacing_vals[lacing_fill] |= 0x100;
|
||||
bos = 0;
|
||||
}
|
||||
|
||||
if (val < 255)
|
||||
saved = lacing_fill;
|
||||
|
||||
lacing_fill++;
|
||||
segptr++;
|
||||
|
||||
if (val < 255)
|
||||
lacing_packet = lacing_fill;
|
||||
}
|
||||
|
||||
/* set the granulepos on the last pcmval of the last full packet */
|
||||
if (saved != -1) {
|
||||
granule_vals[saved] = granulepos;
|
||||
}
|
||||
}
|
||||
|
||||
if (eos != 0) {
|
||||
e_o_s = 1;
|
||||
if (lacing_fill > 0)
|
||||
lacing_vals[lacing_fill - 1] |= 0x200;
|
||||
}
|
||||
|
||||
pageno = _pageno + 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This will flush remaining packets into a page (returning nonzero), even if
|
||||
* there is not enough data to trigger a flush normally (undersized page). If
|
||||
* there are no packets or partial packets to flush, ogg_stream_flush returns 0.
|
||||
* Note that ogg_stream_flush will try to flush a normal sized page like
|
||||
* ogg_stream_pageout; a call to ogg_stream_flush does not gurantee that all
|
||||
* packets have flushed. Only a return value of 0 from ogg_stream_flush
|
||||
* indicates all packet data is flushed into pages.
|
||||
*
|
||||
* ogg_stream_page will flush the last page in a stream even if it's undersized;
|
||||
* you almost certainly want to use ogg_stream_pageout (and *not*
|
||||
* ogg_stream_flush) unless you need to flush an undersized page in the middle
|
||||
* of a stream for some reason.
|
||||
*/
|
||||
|
||||
public int flush(Page og) {
|
||||
|
||||
int i;
|
||||
int vals = 0;
|
||||
int maxvals = (lacing_fill > 255 ? 255 : lacing_fill);
|
||||
int bytes = 0;
|
||||
int acc = 0;
|
||||
long granule_pos = granule_vals[0];
|
||||
|
||||
if (maxvals == 0)
|
||||
return (0);
|
||||
|
||||
/* construct a page */
|
||||
/* decide how many segments to include */
|
||||
|
||||
/*
|
||||
* If this is the initial header case, the first page must only include the
|
||||
* initial header packet
|
||||
*/
|
||||
if (b_o_s == 0) { /* 'initial header page' case */
|
||||
granule_pos = 0;
|
||||
for (vals = 0; vals < maxvals; vals++) {
|
||||
if ((lacing_vals[vals] & 0x0ff) < 255) {
|
||||
vals++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (vals = 0; vals < maxvals; vals++) {
|
||||
if (acc > 4096)
|
||||
break;
|
||||
acc += (lacing_vals[vals] & 0x0ff);
|
||||
granule_pos = granule_vals[vals];
|
||||
}
|
||||
}
|
||||
|
||||
/* construct the header in temp storage */
|
||||
System.arraycopy("OggS".getBytes(), 0, header, 0, 4);
|
||||
|
||||
/* stream structure version */
|
||||
header[4] = 0x00;
|
||||
|
||||
/* continued packet flag? */
|
||||
header[5] = 0x00;
|
||||
if ((lacing_vals[0] & 0x100) == 0)
|
||||
header[5] |= 0x01;
|
||||
/* first page flag? */
|
||||
if (b_o_s == 0)
|
||||
header[5] |= 0x02;
|
||||
/* last page flag? */
|
||||
if (e_o_s != 0 && lacing_fill == vals)
|
||||
header[5] |= 0x04;
|
||||
b_o_s = 1;
|
||||
|
||||
/* 64 bits of PCM position */
|
||||
for (i = 6; i < 14; i++) {
|
||||
header[i] = (byte) granule_pos;
|
||||
granule_pos >>>= 8;
|
||||
}
|
||||
|
||||
/* 32 bits of stream serial number */
|
||||
{
|
||||
int _serialno = serialno;
|
||||
for (i = 14; i < 18; i++) {
|
||||
header[i] = (byte) _serialno;
|
||||
_serialno >>>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 32 bits of page counter (we have both counter and page header because this
|
||||
* val can roll over)
|
||||
*/
|
||||
if (pageno == -1)
|
||||
pageno = 0; /*
|
||||
* because someone called stream_reset; this would be a strange thing to do in
|
||||
* an encode stream, but it has plausible uses
|
||||
*/
|
||||
{
|
||||
int _pageno = pageno++;
|
||||
for (i = 18; i < 22; i++) {
|
||||
header[i] = (byte) _pageno;
|
||||
_pageno >>>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* zero for computation; filled in later */
|
||||
header[22] = 0;
|
||||
header[23] = 0;
|
||||
header[24] = 0;
|
||||
header[25] = 0;
|
||||
|
||||
/* segment table */
|
||||
header[26] = (byte) vals;
|
||||
for (i = 0; i < vals; i++) {
|
||||
header[i + 27] = (byte) lacing_vals[i];
|
||||
bytes += (header[i + 27] & 0xff);
|
||||
}
|
||||
|
||||
/* set pointers in the ogg_page struct */
|
||||
og.header_base = header;
|
||||
og.header = 0;
|
||||
og.header_len = header_fill = vals + 27;
|
||||
og.body_base = body_data;
|
||||
og.body = body_returned;
|
||||
og.body_len = bytes;
|
||||
|
||||
/* advance the lacing data and set the body_returned pointer */
|
||||
|
||||
lacing_fill -= vals;
|
||||
System.arraycopy(lacing_vals, vals, lacing_vals, 0, lacing_fill * 4);
|
||||
System.arraycopy(granule_vals, vals, granule_vals, 0, lacing_fill * 8);
|
||||
body_returned += bytes;
|
||||
|
||||
/* calculate the checksum */
|
||||
|
||||
og.checksum();
|
||||
|
||||
/* done */
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* This constructs pages from buffered packet segments. The pointers returned
|
||||
* are to static buffers; do not free. The returned buffers are good only until
|
||||
* the next call (using the same ogg_stream_state)
|
||||
*/
|
||||
public int pageout(Page og) {
|
||||
if ((e_o_s != 0 && lacing_fill != 0) || /* 'were done, now flush' case */
|
||||
body_fill - body_returned > 4096 || /* 'page nominal size' case */
|
||||
lacing_fill >= 255 || /* 'segment table full' case */
|
||||
(lacing_fill != 0 && b_o_s == 0)) { /* 'initial header page' case */
|
||||
return flush(og);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int eof() {
|
||||
return e_o_s;
|
||||
}
|
||||
|
||||
public int reset() {
|
||||
body_fill = 0;
|
||||
body_returned = 0;
|
||||
|
||||
lacing_fill = 0;
|
||||
lacing_packet = 0;
|
||||
lacing_returned = 0;
|
||||
|
||||
header_fill = 0;
|
||||
|
||||
e_o_s = 0;
|
||||
b_o_s = 0;
|
||||
pageno = -1;
|
||||
packetno = 0;
|
||||
granulepos = 0;
|
||||
return (0);
|
||||
}
|
||||
}
|
273
sources/wasm-gc-teavm/java/com/jcraft/jogg/SyncState.java
Normal file
273
sources/wasm-gc-teavm/java/com/jcraft/jogg/SyncState.java
Normal file
@ -0,0 +1,273 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jogg;
|
||||
|
||||
// DECODING PRIMITIVES: packet streaming layer
|
||||
|
||||
// This has two layers to place more of the multi-serialno and paging
|
||||
// control in the application's hands. First, we expose a data buffer
|
||||
// using ogg_decode_buffer(). The app either copies into the
|
||||
// buffer, or passes it directly to read(), etc. We then call
|
||||
// ogg_decode_wrote() to tell how many bytes we just added.
|
||||
//
|
||||
// Pages are returned (pointers into the buffer in ogg_sync_state)
|
||||
// by ogg_decode_stream(). The page is then submitted to
|
||||
// ogg_decode_page() along with the appropriate
|
||||
// ogg_stream_state* (ie, matching serialno). We then get raw
|
||||
// packets out calling ogg_stream_packet() with a
|
||||
// ogg_stream_state. See the 'frame-prog.txt' docs for details and
|
||||
// example code.
|
||||
|
||||
public class SyncState {
|
||||
|
||||
public byte[] data;
|
||||
int storage;
|
||||
int fill;
|
||||
int returned;
|
||||
|
||||
int unsynced;
|
||||
int headerbytes;
|
||||
int bodybytes;
|
||||
|
||||
public int clear() {
|
||||
data = null;
|
||||
return (0);
|
||||
}
|
||||
|
||||
public int buffer(int size) {
|
||||
// first, clear out any space that has been previously returned
|
||||
if (returned != 0) {
|
||||
fill -= returned;
|
||||
if (fill > 0) {
|
||||
System.arraycopy(data, returned, data, 0, fill);
|
||||
}
|
||||
returned = 0;
|
||||
}
|
||||
|
||||
if (size > storage - fill) {
|
||||
// We need to extend the internal buffer
|
||||
int newsize = size + fill + 4096; // an extra page to be nice
|
||||
if (data != null) {
|
||||
byte[] foo = new byte[newsize];
|
||||
System.arraycopy(data, 0, foo, 0, data.length);
|
||||
data = foo;
|
||||
} else {
|
||||
data = new byte[newsize];
|
||||
}
|
||||
storage = newsize;
|
||||
}
|
||||
|
||||
return (fill);
|
||||
}
|
||||
|
||||
public int wrote(int bytes) {
|
||||
if (fill + bytes > storage)
|
||||
return (-1);
|
||||
fill += bytes;
|
||||
return (0);
|
||||
}
|
||||
|
||||
// sync the stream. This is meant to be useful for finding page
|
||||
// boundaries.
|
||||
//
|
||||
// return values for this:
|
||||
// -n) skipped n bytes
|
||||
// 0) page not ready; more data (no bytes skipped)
|
||||
// n) page synced at current location; page length n bytes
|
||||
private Page pageseek = new Page();
|
||||
private byte[] chksum = new byte[4];
|
||||
|
||||
public int pageseek(Page og) {
|
||||
int page = returned;
|
||||
int next;
|
||||
int bytes = fill - returned;
|
||||
|
||||
if (headerbytes == 0) {
|
||||
int _headerbytes, i;
|
||||
if (bytes < 27)
|
||||
return (0); // not enough for a header
|
||||
|
||||
/* verify capture pattern */
|
||||
if (data[page] != 'O' || data[page + 1] != 'g' || data[page + 2] != 'g' || data[page + 3] != 'S') {
|
||||
headerbytes = 0;
|
||||
bodybytes = 0;
|
||||
|
||||
// search for possible capture
|
||||
next = 0;
|
||||
for (int ii = 0; ii < bytes - 1; ii++) {
|
||||
if (data[page + 1 + ii] == 'O') {
|
||||
next = page + 1 + ii;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// next=memchr(page+1,'O',bytes-1);
|
||||
if (next == 0)
|
||||
next = fill;
|
||||
|
||||
returned = next;
|
||||
return (-(next - page));
|
||||
}
|
||||
_headerbytes = (data[page + 26] & 0xff) + 27;
|
||||
if (bytes < _headerbytes)
|
||||
return (0); // not enough for header + seg table
|
||||
|
||||
// count up body length in the segment table
|
||||
|
||||
for (i = 0; i < (data[page + 26] & 0xff); i++) {
|
||||
bodybytes += (data[page + 27 + i] & 0xff);
|
||||
}
|
||||
headerbytes = _headerbytes;
|
||||
}
|
||||
|
||||
if (bodybytes + headerbytes > bytes)
|
||||
return (0);
|
||||
|
||||
// The whole test page is buffered. Verify the checksum
|
||||
synchronized (chksum) {
|
||||
// Grab the checksum bytes, set the header field to zero
|
||||
|
||||
System.arraycopy(data, page + 22, chksum, 0, 4);
|
||||
data[page + 22] = 0;
|
||||
data[page + 23] = 0;
|
||||
data[page + 24] = 0;
|
||||
data[page + 25] = 0;
|
||||
|
||||
// set up a temp page struct and recompute the checksum
|
||||
Page log = pageseek;
|
||||
log.header_base = data;
|
||||
log.header = page;
|
||||
log.header_len = headerbytes;
|
||||
|
||||
log.body_base = data;
|
||||
log.body = page + headerbytes;
|
||||
log.body_len = bodybytes;
|
||||
log.checksum();
|
||||
|
||||
// Compare
|
||||
if (chksum[0] != data[page + 22] || chksum[1] != data[page + 23] || chksum[2] != data[page + 24]
|
||||
|| chksum[3] != data[page + 25]) {
|
||||
// D'oh. Mismatch! Corrupt page (or miscapture and not a page at all)
|
||||
// replace the computed checksum with the one actually read in
|
||||
System.arraycopy(chksum, 0, data, page + 22, 4);
|
||||
// Bad checksum. Lose sync */
|
||||
|
||||
headerbytes = 0;
|
||||
bodybytes = 0;
|
||||
// search for possible capture
|
||||
next = 0;
|
||||
for (int ii = 0; ii < bytes - 1; ii++) {
|
||||
if (data[page + 1 + ii] == 'O') {
|
||||
next = page + 1 + ii;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// next=memchr(page+1,'O',bytes-1);
|
||||
if (next == 0)
|
||||
next = fill;
|
||||
returned = next;
|
||||
return (-(next - page));
|
||||
}
|
||||
}
|
||||
|
||||
// yes, have a whole page all ready to go
|
||||
{
|
||||
page = returned;
|
||||
|
||||
if (og != null) {
|
||||
og.header_base = data;
|
||||
og.header = page;
|
||||
og.header_len = headerbytes;
|
||||
og.body_base = data;
|
||||
og.body = page + headerbytes;
|
||||
og.body_len = bodybytes;
|
||||
}
|
||||
|
||||
unsynced = 0;
|
||||
returned += (bytes = headerbytes + bodybytes);
|
||||
headerbytes = 0;
|
||||
bodybytes = 0;
|
||||
return (bytes);
|
||||
}
|
||||
}
|
||||
|
||||
// sync the stream and get a page. Keep trying until we find a page.
|
||||
// Supress 'sync errors' after reporting the first.
|
||||
//
|
||||
// return values:
|
||||
// -1) recapture (hole in data)
|
||||
// 0) need more data
|
||||
// 1) page returned
|
||||
//
|
||||
// Returns pointers into buffered data; invalidated by next call to
|
||||
// _stream, _clear, _init, or _buffer
|
||||
|
||||
public int pageout(Page og) {
|
||||
// all we need to do is verify a page at the head of the stream
|
||||
// buffer. If it doesn't verify, we look for the next potential
|
||||
// frame
|
||||
|
||||
while (true) {
|
||||
int ret = pageseek(og);
|
||||
if (ret > 0) {
|
||||
// have a page
|
||||
return (1);
|
||||
}
|
||||
if (ret == 0) {
|
||||
// need more data
|
||||
return (0);
|
||||
}
|
||||
|
||||
// head did not start a synced page... skipped some bytes
|
||||
if (unsynced == 0) {
|
||||
unsynced = 1;
|
||||
return (-1);
|
||||
}
|
||||
// loop. keep looking
|
||||
}
|
||||
}
|
||||
|
||||
// clear things to an initial state. Good to call, eg, before seeking
|
||||
public int reset() {
|
||||
fill = 0;
|
||||
returned = 0;
|
||||
unsynced = 0;
|
||||
headerbytes = 0;
|
||||
bodybytes = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
public int getDataOffset() {
|
||||
return returned;
|
||||
}
|
||||
|
||||
public int getBufferOffset() {
|
||||
return fill;
|
||||
}
|
||||
}
|
126
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Block.java
Normal file
126
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Block.java
Normal file
@ -0,0 +1,126 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
import com.jcraft.jogg.*;
|
||||
|
||||
public class Block {
|
||||
/// necessary stream state for linking to the framing abstraction
|
||||
float[][] pcm = new float[0][]; // this is a pointer into local storage
|
||||
Buffer opb = new Buffer();
|
||||
|
||||
int lW;
|
||||
int W;
|
||||
int nW;
|
||||
int pcmend;
|
||||
int mode;
|
||||
|
||||
int eofflag;
|
||||
long granulepos;
|
||||
long sequence;
|
||||
DspState vd; // For read-only access of configuration
|
||||
|
||||
// bitmetrics for the frame
|
||||
int glue_bits;
|
||||
int time_bits;
|
||||
int floor_bits;
|
||||
int res_bits;
|
||||
|
||||
public Block(DspState vd) {
|
||||
this.vd = vd;
|
||||
if (vd.analysisp != 0) {
|
||||
opb.writeinit();
|
||||
}
|
||||
}
|
||||
|
||||
public void init(DspState vd) {
|
||||
this.vd = vd;
|
||||
}
|
||||
|
||||
public int clear() {
|
||||
if (vd != null) {
|
||||
if (vd.analysisp != 0) {
|
||||
opb.writeclear();
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
public int synthesis(Packet op) {
|
||||
Info vi = vd.vi;
|
||||
|
||||
// first things first. Make sure decode is ready
|
||||
opb.readinit(op.packet_base, op.packet, op.bytes);
|
||||
|
||||
// Check the packet type
|
||||
if (opb.read(1) != 0) {
|
||||
// Oops. This is not an audio data packet
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// read our mode and pre/post windowsize
|
||||
int _mode = opb.read(vd.modebits);
|
||||
if (_mode == -1)
|
||||
return (-1);
|
||||
|
||||
mode = _mode;
|
||||
W = vi.mode_param[mode].blockflag;
|
||||
if (W != 0) {
|
||||
lW = opb.read(1);
|
||||
nW = opb.read(1);
|
||||
if (nW == -1)
|
||||
return (-1);
|
||||
} else {
|
||||
lW = 0;
|
||||
nW = 0;
|
||||
}
|
||||
|
||||
// more setup
|
||||
granulepos = op.granulepos;
|
||||
sequence = op.packetno - 3; // first block is third packet
|
||||
eofflag = op.e_o_s;
|
||||
|
||||
// alloc pcm passback storage
|
||||
pcmend = vi.blocksizes[W];
|
||||
if (pcm.length < vi.channels) {
|
||||
pcm = new float[vi.channels][];
|
||||
}
|
||||
for (int i = 0; i < vi.channels; i++) {
|
||||
if (pcm[i] == null || pcm[i].length < pcmend) {
|
||||
pcm[i] = new float[pcmend];
|
||||
} else {
|
||||
for (int j = 0; j < pcmend; j++) {
|
||||
pcm[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unpack_header enforces range checking
|
||||
int type = vi.map_type[vi.mode_param[mode].mapping];
|
||||
return (FuncMapping.mapping_P[type].inverse(this, vd.mode[mode]));
|
||||
}
|
||||
}
|
471
sources/wasm-gc-teavm/java/com/jcraft/jorbis/CodeBook.java
Normal file
471
sources/wasm-gc-teavm/java/com/jcraft/jorbis/CodeBook.java
Normal file
@ -0,0 +1,471 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
import com.jcraft.jogg.*;
|
||||
|
||||
class CodeBook {
|
||||
int dim; // codebook dimensions (elements per vector)
|
||||
int entries; // codebook entries
|
||||
StaticCodeBook c = new StaticCodeBook();
|
||||
|
||||
float[] valuelist; // list of dim*entries actual entry values
|
||||
int[] codelist; // list of bitstream codewords for each entry
|
||||
DecodeAux decode_tree;
|
||||
|
||||
// returns the number of bits
|
||||
int encode(int a, Buffer b) {
|
||||
b.write(codelist[a], c.lengthlist[a]);
|
||||
return (c.lengthlist[a]);
|
||||
}
|
||||
|
||||
// One the encode side, our vector writers are each designed for a
|
||||
// specific purpose, and the encoder is not flexible without modification:
|
||||
//
|
||||
// The LSP vector coder uses a single stage nearest-match with no
|
||||
// interleave, so no step and no error return. This is specced by floor0
|
||||
// and doesn't change.
|
||||
//
|
||||
// Residue0 encoding interleaves, uses multiple stages, and each stage
|
||||
// peels of a specific amount of resolution from a lattice (thus we want
|
||||
// to match by threshhold, not nearest match). Residue doesn't *have* to
|
||||
// be encoded that way, but to change it, one will need to add more
|
||||
// infrastructure on the encode side (decode side is specced and simpler)
|
||||
|
||||
// floor0 LSP (single stage, non interleaved, nearest match)
|
||||
// returns entry number and *modifies a* to the quantization value
|
||||
int errorv(float[] a) {
|
||||
int best = best(a, 1);
|
||||
for (int k = 0; k < dim; k++) {
|
||||
a[k] = valuelist[best * dim + k];
|
||||
}
|
||||
return (best);
|
||||
}
|
||||
|
||||
// returns the number of bits and *modifies a* to the quantization value
|
||||
int encodev(int best, float[] a, Buffer b) {
|
||||
for (int k = 0; k < dim; k++) {
|
||||
a[k] = valuelist[best * dim + k];
|
||||
}
|
||||
return (encode(best, b));
|
||||
}
|
||||
|
||||
// res0 (multistage, interleave, lattice)
|
||||
// returns the number of bits and *modifies a* to the remainder value
|
||||
int encodevs(float[] a, Buffer b, int step, int addmul) {
|
||||
int best = besterror(a, step, addmul);
|
||||
return (encode(best, b));
|
||||
}
|
||||
|
||||
private int[] t = new int[15]; // decodevs_add is synchronized for re-using t.
|
||||
|
||||
synchronized int decodevs_add(float[] a, int offset, Buffer b, int n) {
|
||||
int step = n / dim;
|
||||
int entry;
|
||||
int i, j, o;
|
||||
|
||||
if (t.length < step) {
|
||||
t = new int[step];
|
||||
}
|
||||
|
||||
for (i = 0; i < step; i++) {
|
||||
entry = decode(b);
|
||||
if (entry == -1)
|
||||
return (-1);
|
||||
t[i] = entry * dim;
|
||||
}
|
||||
for (i = 0, o = 0; i < dim; i++, o += step) {
|
||||
for (j = 0; j < step; j++) {
|
||||
a[offset + o + j] += valuelist[t[j] + i];
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int decodev_add(float[] a, int offset, Buffer b, int n) {
|
||||
int i, j, entry;
|
||||
int t;
|
||||
|
||||
if (dim > 8) {
|
||||
for (i = 0; i < n;) {
|
||||
entry = decode(b);
|
||||
if (entry == -1)
|
||||
return (-1);
|
||||
t = entry * dim;
|
||||
for (j = 0; j < dim;) {
|
||||
a[offset + (i++)] += valuelist[t + (j++)];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < n;) {
|
||||
entry = decode(b);
|
||||
if (entry == -1)
|
||||
return (-1);
|
||||
t = entry * dim;
|
||||
j = 0;
|
||||
switch (dim) {
|
||||
case 8:
|
||||
a[offset + (i++)] += valuelist[t + (j++)];
|
||||
case 7:
|
||||
a[offset + (i++)] += valuelist[t + (j++)];
|
||||
case 6:
|
||||
a[offset + (i++)] += valuelist[t + (j++)];
|
||||
case 5:
|
||||
a[offset + (i++)] += valuelist[t + (j++)];
|
||||
case 4:
|
||||
a[offset + (i++)] += valuelist[t + (j++)];
|
||||
case 3:
|
||||
a[offset + (i++)] += valuelist[t + (j++)];
|
||||
case 2:
|
||||
a[offset + (i++)] += valuelist[t + (j++)];
|
||||
case 1:
|
||||
a[offset + (i++)] += valuelist[t + (j++)];
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int decodev_set(float[] a, int offset, Buffer b, int n) {
|
||||
int i, j, entry;
|
||||
int t;
|
||||
|
||||
for (i = 0; i < n;) {
|
||||
entry = decode(b);
|
||||
if (entry == -1)
|
||||
return (-1);
|
||||
t = entry * dim;
|
||||
for (j = 0; j < dim;) {
|
||||
a[offset + i++] = valuelist[t + (j++)];
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int decodevv_add(float[][] a, int offset, int ch, Buffer b, int n) {
|
||||
int i, j, entry;
|
||||
int chptr = 0;
|
||||
|
||||
for (i = offset / ch; i < (offset + n) / ch;) {
|
||||
entry = decode(b);
|
||||
if (entry == -1)
|
||||
return (-1);
|
||||
|
||||
int t = entry * dim;
|
||||
for (j = 0; j < dim; j++) {
|
||||
a[chptr++][i] += valuelist[t + j];
|
||||
if (chptr == ch) {
|
||||
chptr = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
// Decode side is specced and easier, because we don't need to find
|
||||
// matches using different criteria; we simply read and map. There are
|
||||
// two things we need to do 'depending':
|
||||
//
|
||||
// We may need to support interleave. We don't really, but it's
|
||||
// convenient to do it here rather than rebuild the vector later.
|
||||
//
|
||||
// Cascades may be additive or multiplicitive; this is not inherent in
|
||||
// the codebook, but set in the code using the codebook. Like
|
||||
// interleaving, it's easiest to do it here.
|
||||
// stage==0 -> declarative (set the value)
|
||||
// stage==1 -> additive
|
||||
// stage==2 -> multiplicitive
|
||||
|
||||
// returns the entry number or -1 on eof
|
||||
int decode(Buffer b) {
|
||||
int ptr = 0;
|
||||
DecodeAux t = decode_tree;
|
||||
int lok = b.look(t.tabn);
|
||||
|
||||
if (lok >= 0) {
|
||||
ptr = t.tab[lok];
|
||||
b.adv(t.tabl[lok]);
|
||||
if (ptr <= 0) {
|
||||
return -ptr;
|
||||
}
|
||||
}
|
||||
do {
|
||||
switch (b.read1()) {
|
||||
case 0:
|
||||
ptr = t.ptr0[ptr];
|
||||
break;
|
||||
case 1:
|
||||
ptr = t.ptr1[ptr];
|
||||
break;
|
||||
case -1:
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
} while (ptr > 0);
|
||||
return (-ptr);
|
||||
}
|
||||
|
||||
// returns the entry number or -1 on eof
|
||||
int decodevs(float[] a, int index, Buffer b, int step, int addmul) {
|
||||
int entry = decode(b);
|
||||
if (entry == -1)
|
||||
return (-1);
|
||||
switch (addmul) {
|
||||
case -1:
|
||||
for (int i = 0, o = 0; i < dim; i++, o += step)
|
||||
a[index + o] = valuelist[entry * dim + i];
|
||||
break;
|
||||
case 0:
|
||||
for (int i = 0, o = 0; i < dim; i++, o += step)
|
||||
a[index + o] += valuelist[entry * dim + i];
|
||||
break;
|
||||
case 1:
|
||||
for (int i = 0, o = 0; i < dim; i++, o += step)
|
||||
a[index + o] *= valuelist[entry * dim + i];
|
||||
break;
|
||||
default:
|
||||
// System.err.println("CodeBook.decodeves: addmul="+addmul);
|
||||
}
|
||||
return (entry);
|
||||
}
|
||||
|
||||
int best(float[] a, int step) {
|
||||
// brute force it!
|
||||
{
|
||||
int besti = -1;
|
||||
float best = 0.f;
|
||||
int e = 0;
|
||||
for (int i = 0; i < entries; i++) {
|
||||
if (c.lengthlist[i] > 0) {
|
||||
float _this = dist(dim, valuelist, e, a, step);
|
||||
if (besti == -1 || _this < best) {
|
||||
best = _this;
|
||||
besti = i;
|
||||
}
|
||||
}
|
||||
e += dim;
|
||||
}
|
||||
return (besti);
|
||||
}
|
||||
}
|
||||
|
||||
// returns the entry number and *modifies a* to the remainder value
|
||||
int besterror(float[] a, int step, int addmul) {
|
||||
int best = best(a, step);
|
||||
switch (addmul) {
|
||||
case 0:
|
||||
for (int i = 0, o = 0; i < dim; i++, o += step)
|
||||
a[o] -= valuelist[best * dim + i];
|
||||
break;
|
||||
case 1:
|
||||
for (int i = 0, o = 0; i < dim; i++, o += step) {
|
||||
float val = valuelist[best * dim + i];
|
||||
if (val == 0) {
|
||||
a[o] = 0;
|
||||
} else {
|
||||
a[o] /= val;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (best);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
}
|
||||
|
||||
private static float dist(int el, float[] ref, int index, float[] b, int step) {
|
||||
float acc = (float) 0.;
|
||||
for (int i = 0; i < el; i++) {
|
||||
float val = (ref[index + i] - b[i * step]);
|
||||
acc += val * val;
|
||||
}
|
||||
return (acc);
|
||||
}
|
||||
|
||||
int init_decode(StaticCodeBook s) {
|
||||
c = s;
|
||||
entries = s.entries;
|
||||
dim = s.dim;
|
||||
valuelist = s.unquantize();
|
||||
|
||||
decode_tree = make_decode_tree();
|
||||
if (decode_tree == null) {
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
// given a list of word lengths, generate a list of codewords. Works
|
||||
// for length ordered or unordered, always assigns the lowest valued
|
||||
// codewords first. Extended to handle unused entries (length 0)
|
||||
static int[] make_words(int[] l, int n) {
|
||||
int[] marker = new int[33];
|
||||
int[] r = new int[n];
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
int length = l[i];
|
||||
if (length > 0) {
|
||||
int entry = marker[length];
|
||||
|
||||
// when we claim a node for an entry, we also claim the nodes
|
||||
// below it (pruning off the imagined tree that may have dangled
|
||||
// from it) as well as blocking the use of any nodes directly
|
||||
// above for leaves
|
||||
|
||||
// update ourself
|
||||
if (length < 32 && (entry >>> length) != 0) {
|
||||
// error condition; the lengths must specify an overpopulated tree
|
||||
// free(r);
|
||||
return (null);
|
||||
}
|
||||
r[i] = entry;
|
||||
|
||||
// Look to see if the next shorter marker points to the node
|
||||
// above. if so, update it and repeat.
|
||||
{
|
||||
for (int j = length; j > 0; j--) {
|
||||
if ((marker[j] & 1) != 0) {
|
||||
// have to jump branches
|
||||
if (j == 1)
|
||||
marker[1]++;
|
||||
else
|
||||
marker[j] = marker[j - 1] << 1;
|
||||
break; // invariant says next upper marker would already
|
||||
// have been moved if it was on the same path
|
||||
}
|
||||
marker[j]++;
|
||||
}
|
||||
}
|
||||
|
||||
// prune the tree; the implicit invariant says all the longer
|
||||
// markers were dangling from our just-taken node. Dangle them
|
||||
// from our *new* node.
|
||||
for (int j = length + 1; j < 33; j++) {
|
||||
if ((marker[j] >>> 1) == entry) {
|
||||
entry = marker[j];
|
||||
marker[j] = marker[j - 1] << 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bitreverse the words because our bitwise packer/unpacker is LSb
|
||||
// endian
|
||||
for (int i = 0; i < n; i++) {
|
||||
int temp = 0;
|
||||
for (int j = 0; j < l[i]; j++) {
|
||||
temp <<= 1;
|
||||
temp |= (r[i] >>> j) & 1;
|
||||
}
|
||||
r[i] = temp;
|
||||
}
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
// build the decode helper tree from the codewords
|
||||
DecodeAux make_decode_tree() {
|
||||
int top = 0;
|
||||
DecodeAux t = new DecodeAux();
|
||||
int[] ptr0 = t.ptr0 = new int[entries * 2];
|
||||
int[] ptr1 = t.ptr1 = new int[entries * 2];
|
||||
int[] codelist = make_words(c.lengthlist, c.entries);
|
||||
|
||||
if (codelist == null)
|
||||
return (null);
|
||||
t.aux = entries * 2;
|
||||
|
||||
for (int i = 0; i < entries; i++) {
|
||||
if (c.lengthlist[i] > 0) {
|
||||
int ptr = 0;
|
||||
int j;
|
||||
for (j = 0; j < c.lengthlist[i] - 1; j++) {
|
||||
int bit = (codelist[i] >>> j) & 1;
|
||||
if (bit == 0) {
|
||||
if (ptr0[ptr] == 0) {
|
||||
ptr0[ptr] = ++top;
|
||||
}
|
||||
ptr = ptr0[ptr];
|
||||
} else {
|
||||
if (ptr1[ptr] == 0) {
|
||||
ptr1[ptr] = ++top;
|
||||
}
|
||||
ptr = ptr1[ptr];
|
||||
}
|
||||
}
|
||||
|
||||
if (((codelist[i] >>> j) & 1) == 0) {
|
||||
ptr0[ptr] = -i;
|
||||
} else {
|
||||
ptr1[ptr] = -i;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
t.tabn = Util.ilog(entries) - 4;
|
||||
|
||||
if (t.tabn < 5)
|
||||
t.tabn = 5;
|
||||
int n = 1 << t.tabn;
|
||||
t.tab = new int[n];
|
||||
t.tabl = new int[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
int p = 0;
|
||||
int j = 0;
|
||||
for (j = 0; j < t.tabn && (p > 0 || j == 0); j++) {
|
||||
if ((i & (1 << j)) != 0) {
|
||||
p = ptr1[p];
|
||||
} else {
|
||||
p = ptr0[p];
|
||||
}
|
||||
}
|
||||
t.tab[i] = p; // -code
|
||||
t.tabl[i] = j; // length
|
||||
}
|
||||
|
||||
return (t);
|
||||
}
|
||||
|
||||
class DecodeAux {
|
||||
int[] tab;
|
||||
int[] tabl;
|
||||
int tabn;
|
||||
|
||||
int[] ptr0;
|
||||
int[] ptr1;
|
||||
int aux; // number of tree entries
|
||||
}
|
||||
}
|
240
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Comment.java
Normal file
240
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Comment.java
Normal file
@ -0,0 +1,240 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
import com.jcraft.jogg.*;
|
||||
|
||||
// the comments are not part of vorbis_info so that vorbis_info can be
|
||||
// static storage
|
||||
public class Comment {
|
||||
private static byte[] _vorbis = "vorbis".getBytes();
|
||||
private static byte[] _vendor = "Xiphophorus libVorbis I 20000508".getBytes();
|
||||
|
||||
private static final int OV_EIMPL = -130;
|
||||
|
||||
// unlimited user comment fields.
|
||||
public byte[][] user_comments;
|
||||
public int[] comment_lengths;
|
||||
public int comments;
|
||||
public byte[] vendor;
|
||||
|
||||
public void init() {
|
||||
user_comments = null;
|
||||
comments = 0;
|
||||
vendor = null;
|
||||
}
|
||||
|
||||
public void add(String comment) {
|
||||
add(comment.getBytes());
|
||||
}
|
||||
|
||||
private void add(byte[] comment) {
|
||||
byte[][] foo = new byte[comments + 2][];
|
||||
if (user_comments != null) {
|
||||
System.arraycopy(user_comments, 0, foo, 0, comments);
|
||||
}
|
||||
user_comments = foo;
|
||||
|
||||
int[] goo = new int[comments + 2];
|
||||
if (comment_lengths != null) {
|
||||
System.arraycopy(comment_lengths, 0, goo, 0, comments);
|
||||
}
|
||||
comment_lengths = goo;
|
||||
|
||||
byte[] bar = new byte[comment.length + 1];
|
||||
System.arraycopy(comment, 0, bar, 0, comment.length);
|
||||
user_comments[comments] = bar;
|
||||
comment_lengths[comments] = comment.length;
|
||||
comments++;
|
||||
user_comments[comments] = null;
|
||||
}
|
||||
|
||||
public void add_tag(String tag, String contents) {
|
||||
if (contents == null)
|
||||
contents = "";
|
||||
add(tag + "=" + contents);
|
||||
}
|
||||
|
||||
static boolean tagcompare(byte[] s1, byte[] s2, int n) {
|
||||
int c = 0;
|
||||
byte u1, u2;
|
||||
while (c < n) {
|
||||
u1 = s1[c];
|
||||
u2 = s2[c];
|
||||
if ('Z' >= u1 && u1 >= 'A')
|
||||
u1 = (byte) (u1 - 'A' + 'a');
|
||||
if ('Z' >= u2 && u2 >= 'A')
|
||||
u2 = (byte) (u2 - 'A' + 'a');
|
||||
if (u1 != u2) {
|
||||
return false;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public String query(String tag) {
|
||||
return query(tag, 0);
|
||||
}
|
||||
|
||||
public String query(String tag, int count) {
|
||||
int foo = query(tag.getBytes(), count);
|
||||
if (foo == -1)
|
||||
return null;
|
||||
byte[] comment = user_comments[foo];
|
||||
for (int i = 0; i < comment_lengths[foo]; i++) {
|
||||
if (comment[i] == '=') {
|
||||
return new String(comment, i + 1, comment_lengths[foo] - (i + 1));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int query(byte[] tag, int count) {
|
||||
int i = 0;
|
||||
int found = 0;
|
||||
int fulltaglen = tag.length + 1;
|
||||
byte[] fulltag = new byte[fulltaglen];
|
||||
System.arraycopy(tag, 0, fulltag, 0, tag.length);
|
||||
fulltag[tag.length] = (byte) '=';
|
||||
|
||||
for (i = 0; i < comments; i++) {
|
||||
if (tagcompare(user_comments[i], fulltag, fulltaglen)) {
|
||||
if (count == found) {
|
||||
// We return a pointer to the data, not a copy
|
||||
// return user_comments[i] + taglen + 1;
|
||||
return i;
|
||||
} else {
|
||||
found++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int unpack(Buffer opb) {
|
||||
int vendorlen = opb.read(32);
|
||||
if (vendorlen < 0) {
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
vendor = new byte[vendorlen + 1];
|
||||
opb.read(vendor, vendorlen);
|
||||
comments = opb.read(32);
|
||||
if (comments < 0) {
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
user_comments = new byte[comments + 1][];
|
||||
comment_lengths = new int[comments + 1];
|
||||
|
||||
for (int i = 0; i < comments; i++) {
|
||||
int len = opb.read(32);
|
||||
if (len < 0) {
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
comment_lengths[i] = len;
|
||||
user_comments[i] = new byte[len + 1];
|
||||
opb.read(user_comments[i], len);
|
||||
}
|
||||
if (opb.read(1) != 1) {
|
||||
clear();
|
||||
return (-1);
|
||||
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int pack(Buffer opb) {
|
||||
// preamble
|
||||
opb.write(0x03, 8);
|
||||
opb.write(_vorbis);
|
||||
|
||||
// vendor
|
||||
opb.write(_vendor.length, 32);
|
||||
opb.write(_vendor);
|
||||
|
||||
// comments
|
||||
opb.write(comments, 32);
|
||||
if (comments != 0) {
|
||||
for (int i = 0; i < comments; i++) {
|
||||
if (user_comments[i] != null) {
|
||||
opb.write(comment_lengths[i], 32);
|
||||
opb.write(user_comments[i]);
|
||||
} else {
|
||||
opb.write(0, 32);
|
||||
}
|
||||
}
|
||||
}
|
||||
opb.write(1, 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
public int header_out(Packet op) {
|
||||
Buffer opb = new Buffer();
|
||||
opb.writeinit();
|
||||
|
||||
if (pack(opb) != 0)
|
||||
return OV_EIMPL;
|
||||
|
||||
op.packet_base = new byte[opb.bytes()];
|
||||
op.packet = 0;
|
||||
op.bytes = opb.bytes();
|
||||
System.arraycopy(opb.buffer(), 0, op.packet_base, 0, op.bytes);
|
||||
op.b_o_s = 0;
|
||||
op.e_o_s = 0;
|
||||
op.granulepos = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
for (int i = 0; i < comments; i++)
|
||||
user_comments[i] = null;
|
||||
user_comments = null;
|
||||
vendor = null;
|
||||
}
|
||||
|
||||
public String getVendor() {
|
||||
return new String(vendor, 0, vendor.length - 1);
|
||||
}
|
||||
|
||||
public String getComment(int i) {
|
||||
if (comments <= i)
|
||||
return null;
|
||||
return new String(user_comments[i], 0, user_comments[i].length - 1);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String foo = "Vendor: " + new String(vendor, 0, vendor.length - 1);
|
||||
for (int i = 0; i < comments; i++) {
|
||||
foo = foo + "\nComment: " + new String(user_comments[i], 0, user_comments[i].length - 1);
|
||||
}
|
||||
foo = foo + "\n";
|
||||
return foo;
|
||||
}
|
||||
}
|
1319
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Drft.java
Normal file
1319
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Drft.java
Normal file
File diff suppressed because it is too large
Load Diff
369
sources/wasm-gc-teavm/java/com/jcraft/jorbis/DspState.java
Normal file
369
sources/wasm-gc-teavm/java/com/jcraft/jorbis/DspState.java
Normal file
@ -0,0 +1,369 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
public class DspState {
|
||||
static final float M_PI = 3.1415926539f;
|
||||
static final int VI_TRANSFORMB = 1;
|
||||
static final int VI_WINDOWB = 1;
|
||||
|
||||
int analysisp;
|
||||
Info vi;
|
||||
int modebits;
|
||||
|
||||
float[][] pcm;
|
||||
int pcm_storage;
|
||||
int pcm_current;
|
||||
int pcm_returned;
|
||||
|
||||
float[] multipliers;
|
||||
int envelope_storage;
|
||||
int envelope_current;
|
||||
|
||||
int eofflag;
|
||||
|
||||
int lW;
|
||||
int W;
|
||||
int nW;
|
||||
int centerW;
|
||||
|
||||
long granulepos;
|
||||
long sequence;
|
||||
|
||||
long glue_bits;
|
||||
long time_bits;
|
||||
long floor_bits;
|
||||
long res_bits;
|
||||
|
||||
// local lookup storage
|
||||
float[][][][][] window; // block, leadin, leadout, type
|
||||
Object[][] transform;
|
||||
CodeBook[] fullbooks;
|
||||
// backend lookups are tied to the mode, not the backend or naked mapping
|
||||
Object[] mode;
|
||||
|
||||
// local storage, only used on the encoding side. This way the
|
||||
// application does not need to worry about freeing some packets'
|
||||
// memory and not others'; packet storage is always tracked.
|
||||
// Cleared next call to a _dsp_ function
|
||||
byte[] header;
|
||||
byte[] header1;
|
||||
byte[] header2;
|
||||
|
||||
public DspState() {
|
||||
transform = new Object[2][];
|
||||
window = new float[2][][][][];
|
||||
window[0] = new float[2][][][];
|
||||
window[0][0] = new float[2][][];
|
||||
window[0][1] = new float[2][][];
|
||||
window[0][0][0] = new float[2][];
|
||||
window[0][0][1] = new float[2][];
|
||||
window[0][1][0] = new float[2][];
|
||||
window[0][1][1] = new float[2][];
|
||||
window[1] = new float[2][][][];
|
||||
window[1][0] = new float[2][][];
|
||||
window[1][1] = new float[2][][];
|
||||
window[1][0][0] = new float[2][];
|
||||
window[1][0][1] = new float[2][];
|
||||
window[1][1][0] = new float[2][];
|
||||
window[1][1][1] = new float[2][];
|
||||
}
|
||||
|
||||
static float[] window(int type, int window, int left, int right) {
|
||||
float[] ret = new float[window];
|
||||
switch (type) {
|
||||
case 0:
|
||||
// The 'vorbis window' (window 0) is sin(sin(x)*sin(x)*2pi)
|
||||
{
|
||||
int leftbegin = window / 4 - left / 2;
|
||||
int rightbegin = window - window / 4 - right / 2;
|
||||
|
||||
for (int i = 0; i < left; i++) {
|
||||
float x = (float) ((i + .5) / left * M_PI / 2.);
|
||||
x = (float) Math.sin(x);
|
||||
x *= x;
|
||||
x *= M_PI / 2.;
|
||||
x = (float) Math.sin(x);
|
||||
ret[i + leftbegin] = x;
|
||||
}
|
||||
|
||||
for (int i = leftbegin + left; i < rightbegin; i++) {
|
||||
ret[i] = 1.f;
|
||||
}
|
||||
|
||||
for (int i = 0; i < right; i++) {
|
||||
float x = (float) ((right - i - .5) / right * M_PI / 2.);
|
||||
x = (float) Math.sin(x);
|
||||
x *= x;
|
||||
x *= M_PI / 2.;
|
||||
x = (float) Math.sin(x);
|
||||
ret[i + rightbegin] = x;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// free(ret);
|
||||
return (null);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
// Analysis side code, but directly related to blocking. Thus it's
|
||||
// here and not in analysis.c (which is for analysis transforms only).
|
||||
// The init is here because some of it is shared
|
||||
|
||||
int init(Info vi, boolean encp) {
|
||||
this.vi = vi;
|
||||
modebits = Util.ilog2(vi.modes);
|
||||
|
||||
transform[0] = new Object[VI_TRANSFORMB];
|
||||
transform[1] = new Object[VI_TRANSFORMB];
|
||||
|
||||
// MDCT is tranform 0
|
||||
|
||||
transform[0][0] = new Mdct();
|
||||
transform[1][0] = new Mdct();
|
||||
((Mdct) transform[0][0]).init(vi.blocksizes[0]);
|
||||
((Mdct) transform[1][0]).init(vi.blocksizes[1]);
|
||||
|
||||
window[0][0][0] = new float[VI_WINDOWB][];
|
||||
window[0][0][1] = window[0][0][0];
|
||||
window[0][1][0] = window[0][0][0];
|
||||
window[0][1][1] = window[0][0][0];
|
||||
window[1][0][0] = new float[VI_WINDOWB][];
|
||||
window[1][0][1] = new float[VI_WINDOWB][];
|
||||
window[1][1][0] = new float[VI_WINDOWB][];
|
||||
window[1][1][1] = new float[VI_WINDOWB][];
|
||||
|
||||
for (int i = 0; i < VI_WINDOWB; i++) {
|
||||
window[0][0][0][i] = window(i, vi.blocksizes[0], vi.blocksizes[0] / 2, vi.blocksizes[0] / 2);
|
||||
window[1][0][0][i] = window(i, vi.blocksizes[1], vi.blocksizes[0] / 2, vi.blocksizes[0] / 2);
|
||||
window[1][0][1][i] = window(i, vi.blocksizes[1], vi.blocksizes[0] / 2, vi.blocksizes[1] / 2);
|
||||
window[1][1][0][i] = window(i, vi.blocksizes[1], vi.blocksizes[1] / 2, vi.blocksizes[0] / 2);
|
||||
window[1][1][1][i] = window(i, vi.blocksizes[1], vi.blocksizes[1] / 2, vi.blocksizes[1] / 2);
|
||||
}
|
||||
|
||||
fullbooks = new CodeBook[vi.books];
|
||||
for (int i = 0; i < vi.books; i++) {
|
||||
fullbooks[i] = new CodeBook();
|
||||
fullbooks[i].init_decode(vi.book_param[i]);
|
||||
}
|
||||
|
||||
// initialize the storage vectors to a decent size greater than the
|
||||
// minimum
|
||||
|
||||
pcm_storage = 8192; // we'll assume later that we have
|
||||
// a minimum of twice the blocksize of
|
||||
// accumulated samples in analysis
|
||||
pcm = new float[vi.channels][];
|
||||
{
|
||||
for (int i = 0; i < vi.channels; i++) {
|
||||
pcm[i] = new float[pcm_storage];
|
||||
}
|
||||
}
|
||||
|
||||
// all 1 (large block) or 0 (small block)
|
||||
// explicitly set for the sake of clarity
|
||||
lW = 0; // previous window size
|
||||
W = 0; // current window size
|
||||
|
||||
// all vector indexes; multiples of samples_per_envelope_step
|
||||
centerW = vi.blocksizes[1] / 2;
|
||||
|
||||
pcm_current = centerW;
|
||||
|
||||
// initialize all the mapping/backend lookups
|
||||
mode = new Object[vi.modes];
|
||||
for (int i = 0; i < vi.modes; i++) {
|
||||
int mapnum = vi.mode_param[i].mapping;
|
||||
int maptype = vi.map_type[mapnum];
|
||||
mode[i] = FuncMapping.mapping_P[maptype].look(this, vi.mode_param[i], vi.map_param[mapnum]);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
public int synthesis_init(Info vi) {
|
||||
init(vi, false);
|
||||
// Adjust centerW to allow an easier mechanism for determining output
|
||||
pcm_returned = centerW;
|
||||
centerW -= vi.blocksizes[W] / 4 + vi.blocksizes[lW] / 4;
|
||||
granulepos = -1;
|
||||
sequence = -1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
DspState(Info vi) {
|
||||
this();
|
||||
init(vi, false);
|
||||
// Adjust centerW to allow an easier mechanism for determining output
|
||||
pcm_returned = centerW;
|
||||
centerW -= vi.blocksizes[W] / 4 + vi.blocksizes[lW] / 4;
|
||||
granulepos = -1;
|
||||
sequence = -1;
|
||||
}
|
||||
|
||||
// Unike in analysis, the window is only partially applied for each
|
||||
// block. The time domain envelope is not yet handled at the point of
|
||||
// calling (as it relies on the previous block).
|
||||
|
||||
public int synthesis_blockin(Block vb) {
|
||||
// Shift out any PCM/multipliers that we returned previously
|
||||
// centerW is currently the center of the last block added
|
||||
if (centerW > vi.blocksizes[1] / 2 && pcm_returned > 8192) {
|
||||
// don't shift too much; we need to have a minimum PCM buffer of
|
||||
// 1/2 long block
|
||||
|
||||
int shiftPCM = centerW - vi.blocksizes[1] / 2;
|
||||
shiftPCM = (pcm_returned < shiftPCM ? pcm_returned : shiftPCM);
|
||||
|
||||
pcm_current -= shiftPCM;
|
||||
centerW -= shiftPCM;
|
||||
pcm_returned -= shiftPCM;
|
||||
if (shiftPCM != 0) {
|
||||
for (int i = 0; i < vi.channels; i++) {
|
||||
System.arraycopy(pcm[i], shiftPCM, pcm[i], 0, pcm_current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lW = W;
|
||||
W = vb.W;
|
||||
nW = -1;
|
||||
|
||||
glue_bits += vb.glue_bits;
|
||||
time_bits += vb.time_bits;
|
||||
floor_bits += vb.floor_bits;
|
||||
res_bits += vb.res_bits;
|
||||
|
||||
if (sequence + 1 != vb.sequence)
|
||||
granulepos = -1; // out of sequence; lose count
|
||||
|
||||
sequence = vb.sequence;
|
||||
|
||||
{
|
||||
int sizeW = vi.blocksizes[W];
|
||||
int _centerW = centerW + vi.blocksizes[lW] / 4 + sizeW / 4;
|
||||
int beginW = _centerW - sizeW / 2;
|
||||
int endW = beginW + sizeW;
|
||||
int beginSl = 0;
|
||||
int endSl = 0;
|
||||
|
||||
// Do we have enough PCM/mult storage for the block?
|
||||
if (endW > pcm_storage) {
|
||||
// expand the storage
|
||||
pcm_storage = endW + vi.blocksizes[1];
|
||||
for (int i = 0; i < vi.channels; i++) {
|
||||
float[] foo = new float[pcm_storage];
|
||||
System.arraycopy(pcm[i], 0, foo, 0, pcm[i].length);
|
||||
pcm[i] = foo;
|
||||
}
|
||||
}
|
||||
|
||||
// overlap/add PCM
|
||||
switch (W) {
|
||||
case 0:
|
||||
beginSl = 0;
|
||||
endSl = vi.blocksizes[0] / 2;
|
||||
break;
|
||||
case 1:
|
||||
beginSl = vi.blocksizes[1] / 4 - vi.blocksizes[lW] / 4;
|
||||
endSl = beginSl + vi.blocksizes[lW] / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int j = 0; j < vi.channels; j++) {
|
||||
int _pcm = beginW;
|
||||
// the overlap/add section
|
||||
int i = 0;
|
||||
for (i = beginSl; i < endSl; i++) {
|
||||
pcm[j][_pcm + i] += vb.pcm[j][i];
|
||||
}
|
||||
// the remaining section
|
||||
for (; i < sizeW; i++) {
|
||||
pcm[j][_pcm + i] = vb.pcm[j][i];
|
||||
}
|
||||
}
|
||||
|
||||
// track the frame number... This is for convenience, but also
|
||||
// making sure our last packet doesn't end with added padding. If
|
||||
// the last packet is partial, the number of samples we'll have to
|
||||
// return will be past the vb->granulepos.
|
||||
//
|
||||
// This is not foolproof! It will be confused if we begin
|
||||
// decoding at the last page after a seek or hole. In that case,
|
||||
// we don't have a starting point to judge where the last frame
|
||||
// is. For this reason, vorbisfile will always try to make sure
|
||||
// it reads the last two marked pages in proper sequence
|
||||
|
||||
if (granulepos == -1) {
|
||||
granulepos = vb.granulepos;
|
||||
} else {
|
||||
granulepos += (_centerW - centerW);
|
||||
if (vb.granulepos != -1 && granulepos != vb.granulepos) {
|
||||
if (granulepos > vb.granulepos && vb.eofflag != 0) {
|
||||
// partial last frame. Strip the padding off
|
||||
_centerW -= (granulepos - vb.granulepos);
|
||||
} // else{ Shouldn't happen *unless* the bitstream is out of
|
||||
// spec. Either way, believe the bitstream }
|
||||
granulepos = vb.granulepos;
|
||||
}
|
||||
}
|
||||
|
||||
// Update, cleanup
|
||||
|
||||
centerW = _centerW;
|
||||
pcm_current = endW;
|
||||
if (vb.eofflag != 0)
|
||||
eofflag = 1;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
// pcm==NULL indicates we just want the pending samples, no more
|
||||
public int synthesis_pcmout(float[][][] _pcm, int[] index) {
|
||||
if (pcm_returned < centerW) {
|
||||
if (_pcm != null) {
|
||||
for (int i = 0; i < vi.channels; i++) {
|
||||
index[i] = pcm_returned;
|
||||
}
|
||||
_pcm[0] = pcm;
|
||||
}
|
||||
return (centerW - pcm_returned);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
public int synthesis_read(int bytes) {
|
||||
if (bytes != 0 && pcm_returned + bytes > centerW)
|
||||
return (-1);
|
||||
pcm_returned += bytes;
|
||||
return (0);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
}
|
||||
}
|
332
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Floor0.java
Normal file
332
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Floor0.java
Normal file
@ -0,0 +1,332 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
import com.jcraft.jogg.*;
|
||||
|
||||
class Floor0 extends FuncFloor {
|
||||
|
||||
void pack(Object i, Buffer opb) {
|
||||
InfoFloor0 info = (InfoFloor0) i;
|
||||
opb.write(info.order, 8);
|
||||
opb.write(info.rate, 16);
|
||||
opb.write(info.barkmap, 16);
|
||||
opb.write(info.ampbits, 6);
|
||||
opb.write(info.ampdB, 8);
|
||||
opb.write(info.numbooks - 1, 4);
|
||||
for (int j = 0; j < info.numbooks; j++)
|
||||
opb.write(info.books[j], 8);
|
||||
}
|
||||
|
||||
Object unpack(Info vi, Buffer opb) {
|
||||
InfoFloor0 info = new InfoFloor0();
|
||||
info.order = opb.read(8);
|
||||
info.rate = opb.read(16);
|
||||
info.barkmap = opb.read(16);
|
||||
info.ampbits = opb.read(6);
|
||||
info.ampdB = opb.read(8);
|
||||
info.numbooks = opb.read(4) + 1;
|
||||
|
||||
if ((info.order < 1) || (info.rate < 1) || (info.barkmap < 1) || (info.numbooks < 1)) {
|
||||
return (null);
|
||||
}
|
||||
|
||||
for (int j = 0; j < info.numbooks; j++) {
|
||||
info.books[j] = opb.read(8);
|
||||
if (info.books[j] < 0 || info.books[j] >= vi.books) {
|
||||
return (null);
|
||||
}
|
||||
}
|
||||
return (info);
|
||||
}
|
||||
|
||||
Object look(DspState vd, InfoMode mi, Object i) {
|
||||
float scale;
|
||||
Info vi = vd.vi;
|
||||
InfoFloor0 info = (InfoFloor0) i;
|
||||
LookFloor0 look = new LookFloor0();
|
||||
look.m = info.order;
|
||||
look.n = vi.blocksizes[mi.blockflag] / 2;
|
||||
look.ln = info.barkmap;
|
||||
look.vi = info;
|
||||
look.lpclook.init(look.ln, look.m);
|
||||
|
||||
// we choose a scaling constant so that:
|
||||
scale = look.ln / toBARK((float) (info.rate / 2.));
|
||||
|
||||
// the mapping from a linear scale to a smaller bark scale is
|
||||
// straightforward. We do *not* make sure that the linear mapping
|
||||
// does not skip bark-scale bins; the decoder simply skips them and
|
||||
// the encoder may do what it wishes in filling them. They're
|
||||
// necessary in some mapping combinations to keep the scale spacing
|
||||
// accurate
|
||||
look.linearmap = new int[look.n];
|
||||
for (int j = 0; j < look.n; j++) {
|
||||
int val = (int) Math.floor(toBARK((float) ((info.rate / 2.) / look.n * j)) * scale); // bark numbers
|
||||
// represent band
|
||||
// edges
|
||||
if (val >= look.ln)
|
||||
val = look.ln; // guard against the approximation
|
||||
look.linearmap[j] = val;
|
||||
}
|
||||
return look;
|
||||
}
|
||||
|
||||
static float toBARK(float f) {
|
||||
return (float) (13.1 * Math.atan(.00074 * (f)) + 2.24 * Math.atan((f) * (f) * 1.85e-8) + 1e-4 * (f));
|
||||
}
|
||||
|
||||
Object state(Object i) {
|
||||
EchstateFloor0 state = new EchstateFloor0();
|
||||
InfoFloor0 info = (InfoFloor0) i;
|
||||
|
||||
// a safe size if usually too big (dim==1)
|
||||
state.codewords = new int[info.order];
|
||||
state.curve = new float[info.barkmap];
|
||||
state.frameno = -1;
|
||||
return (state);
|
||||
}
|
||||
|
||||
void free_info(Object i) {
|
||||
}
|
||||
|
||||
void free_look(Object i) {
|
||||
}
|
||||
|
||||
void free_state(Object vs) {
|
||||
}
|
||||
|
||||
int forward(Block vb, Object i, float[] in, float[] out, Object vs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
float[] lsp = null;
|
||||
|
||||
int inverse(Block vb, Object i, float[] out) {
|
||||
// System.err.println("Floor0.inverse "+i.getClass()+"]");
|
||||
LookFloor0 look = (LookFloor0) i;
|
||||
InfoFloor0 info = look.vi;
|
||||
int ampraw = vb.opb.read(info.ampbits);
|
||||
if (ampraw > 0) { // also handles the -1 out of data case
|
||||
int maxval = (1 << info.ampbits) - 1;
|
||||
float amp = (float) ampraw / maxval * info.ampdB;
|
||||
int booknum = vb.opb.read(Util.ilog(info.numbooks));
|
||||
|
||||
if (booknum != -1 && booknum < info.numbooks) {
|
||||
|
||||
synchronized (this) {
|
||||
if (lsp == null || lsp.length < look.m) {
|
||||
lsp = new float[look.m];
|
||||
} else {
|
||||
for (int j = 0; j < look.m; j++)
|
||||
lsp[j] = 0.f;
|
||||
}
|
||||
|
||||
CodeBook b = vb.vd.fullbooks[info.books[booknum]];
|
||||
float last = 0.f;
|
||||
|
||||
for (int j = 0; j < look.m; j++)
|
||||
out[j] = 0.0f;
|
||||
|
||||
for (int j = 0; j < look.m; j += b.dim) {
|
||||
if (b.decodevs(lsp, j, vb.opb, 1, -1) == -1) {
|
||||
for (int k = 0; k < look.n; k++)
|
||||
out[k] = 0.0f;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < look.m;) {
|
||||
for (int k = 0; k < b.dim; k++, j++)
|
||||
lsp[j] += last;
|
||||
last = lsp[j - 1];
|
||||
}
|
||||
// take the coefficients back to a spectral envelope curve
|
||||
Lsp.lsp_to_curve(out, look.linearmap, look.n, look.ln, lsp, look.m, amp, info.ampdB);
|
||||
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
Object inverse1(Block vb, Object i, Object memo) {
|
||||
LookFloor0 look = (LookFloor0) i;
|
||||
InfoFloor0 info = look.vi;
|
||||
float[] lsp = null;
|
||||
if (memo instanceof float[]) {
|
||||
lsp = (float[]) memo;
|
||||
}
|
||||
|
||||
int ampraw = vb.opb.read(info.ampbits);
|
||||
if (ampraw > 0) { // also handles the -1 out of data case
|
||||
int maxval = (1 << info.ampbits) - 1;
|
||||
float amp = (float) ampraw / maxval * info.ampdB;
|
||||
int booknum = vb.opb.read(Util.ilog(info.numbooks));
|
||||
|
||||
if (booknum != -1 && booknum < info.numbooks) {
|
||||
CodeBook b = vb.vd.fullbooks[info.books[booknum]];
|
||||
float last = 0.f;
|
||||
|
||||
if (lsp == null || lsp.length < look.m + 1) {
|
||||
lsp = new float[look.m + 1];
|
||||
} else {
|
||||
for (int j = 0; j < lsp.length; j++)
|
||||
lsp[j] = 0.f;
|
||||
}
|
||||
|
||||
for (int j = 0; j < look.m; j += b.dim) {
|
||||
if (b.decodev_set(lsp, j, vb.opb, b.dim) == -1) {
|
||||
return (null);
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < look.m;) {
|
||||
for (int k = 0; k < b.dim; k++, j++)
|
||||
lsp[j] += last;
|
||||
last = lsp[j - 1];
|
||||
}
|
||||
lsp[look.m] = amp;
|
||||
return (lsp);
|
||||
}
|
||||
}
|
||||
return (null);
|
||||
}
|
||||
|
||||
int inverse2(Block vb, Object i, Object memo, float[] out) {
|
||||
LookFloor0 look = (LookFloor0) i;
|
||||
InfoFloor0 info = look.vi;
|
||||
|
||||
if (memo != null) {
|
||||
float[] lsp = (float[]) memo;
|
||||
float amp = lsp[look.m];
|
||||
|
||||
Lsp.lsp_to_curve(out, look.linearmap, look.n, look.ln, lsp, look.m, amp, info.ampdB);
|
||||
return (1);
|
||||
}
|
||||
for (int j = 0; j < look.n; j++) {
|
||||
out[j] = 0.f;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static float fromdB(float x) {
|
||||
return (float) (Math.exp((x) * .11512925));
|
||||
}
|
||||
|
||||
static void lsp_to_lpc(float[] lsp, float[] lpc, int m) {
|
||||
int i, j, m2 = m / 2;
|
||||
float[] O = new float[m2];
|
||||
float[] E = new float[m2];
|
||||
float A;
|
||||
float[] Ae = new float[m2 + 1];
|
||||
float[] Ao = new float[m2 + 1];
|
||||
float B;
|
||||
float[] Be = new float[m2];
|
||||
float[] Bo = new float[m2];
|
||||
float temp;
|
||||
|
||||
// even/odd roots setup
|
||||
for (i = 0; i < m2; i++) {
|
||||
O[i] = (float) (-2. * Math.cos(lsp[i * 2]));
|
||||
E[i] = (float) (-2. * Math.cos(lsp[i * 2 + 1]));
|
||||
}
|
||||
|
||||
// set up impulse response
|
||||
for (j = 0; j < m2; j++) {
|
||||
Ae[j] = 0.f;
|
||||
Ao[j] = 1.f;
|
||||
Be[j] = 0.f;
|
||||
Bo[j] = 1.f;
|
||||
}
|
||||
Ao[j] = 1.f;
|
||||
Ae[j] = 1.f;
|
||||
|
||||
// run impulse response
|
||||
for (i = 1; i < m + 1; i++) {
|
||||
A = B = 0.f;
|
||||
for (j = 0; j < m2; j++) {
|
||||
temp = O[j] * Ao[j] + Ae[j];
|
||||
Ae[j] = Ao[j];
|
||||
Ao[j] = A;
|
||||
A += temp;
|
||||
|
||||
temp = E[j] * Bo[j] + Be[j];
|
||||
Be[j] = Bo[j];
|
||||
Bo[j] = B;
|
||||
B += temp;
|
||||
}
|
||||
lpc[i - 1] = (A + Ao[j] + B - Ae[j]) / 2;
|
||||
Ao[j] = A;
|
||||
Ae[j] = B;
|
||||
}
|
||||
}
|
||||
|
||||
static void lpc_to_curve(float[] curve, float[] lpc, float amp, LookFloor0 l, String name, int frameno) {
|
||||
// l->m+1 must be less than l->ln, but guard in case we get a bad stream
|
||||
float[] lcurve = new float[Math.max(l.ln * 2, l.m * 2 + 2)];
|
||||
|
||||
if (amp == 0) {
|
||||
for (int j = 0; j < l.n; j++)
|
||||
curve[j] = 0.0f;
|
||||
return;
|
||||
}
|
||||
l.lpclook.lpc_to_curve(lcurve, lpc, amp);
|
||||
|
||||
for (int i = 0; i < l.n; i++)
|
||||
curve[i] = lcurve[l.linearmap[i]];
|
||||
}
|
||||
|
||||
class InfoFloor0 {
|
||||
int order;
|
||||
int rate;
|
||||
int barkmap;
|
||||
|
||||
int ampbits;
|
||||
int ampdB;
|
||||
|
||||
int numbooks; // <= 16
|
||||
int[] books = new int[16];
|
||||
}
|
||||
|
||||
class LookFloor0 {
|
||||
int n;
|
||||
int ln;
|
||||
int m;
|
||||
int[] linearmap;
|
||||
|
||||
InfoFloor0 vi;
|
||||
Lpc lpclook = new Lpc();
|
||||
}
|
||||
|
||||
class EchstateFloor0 {
|
||||
int[] codewords;
|
||||
float[] curve;
|
||||
long frameno;
|
||||
long codes;
|
||||
}
|
||||
}
|
584
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Floor1.java
Normal file
584
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Floor1.java
Normal file
@ -0,0 +1,584 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
import com.jcraft.jogg.*;
|
||||
|
||||
class Floor1 extends FuncFloor {
|
||||
static final int floor1_rangedb = 140;
|
||||
static final int VIF_POSIT = 63;
|
||||
|
||||
void pack(Object i, Buffer opb) {
|
||||
InfoFloor1 info = (InfoFloor1) i;
|
||||
|
||||
int count = 0;
|
||||
int rangebits;
|
||||
int maxposit = info.postlist[1];
|
||||
int maxclass = -1;
|
||||
|
||||
/* save out partitions */
|
||||
opb.write(info.partitions, 5); /* only 0 to 31 legal */
|
||||
for (int j = 0; j < info.partitions; j++) {
|
||||
opb.write(info.partitionclass[j], 4); /* only 0 to 15 legal */
|
||||
if (maxclass < info.partitionclass[j])
|
||||
maxclass = info.partitionclass[j];
|
||||
}
|
||||
|
||||
/* save out partition classes */
|
||||
for (int j = 0; j < maxclass + 1; j++) {
|
||||
opb.write(info.class_dim[j] - 1, 3); /* 1 to 8 */
|
||||
opb.write(info.class_subs[j], 2); /* 0 to 3 */
|
||||
if (info.class_subs[j] != 0) {
|
||||
opb.write(info.class_book[j], 8);
|
||||
}
|
||||
for (int k = 0; k < (1 << info.class_subs[j]); k++) {
|
||||
opb.write(info.class_subbook[j][k] + 1, 8);
|
||||
}
|
||||
}
|
||||
|
||||
/* save out the post list */
|
||||
opb.write(info.mult - 1, 2); /* only 1,2,3,4 legal now */
|
||||
opb.write(Util.ilog2(maxposit), 4);
|
||||
rangebits = Util.ilog2(maxposit);
|
||||
|
||||
for (int j = 0, k = 0; j < info.partitions; j++) {
|
||||
count += info.class_dim[info.partitionclass[j]];
|
||||
for (; k < count; k++) {
|
||||
opb.write(info.postlist[k + 2], rangebits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object unpack(Info vi, Buffer opb) {
|
||||
int count = 0, maxclass = -1, rangebits;
|
||||
InfoFloor1 info = new InfoFloor1();
|
||||
|
||||
/* read partitions */
|
||||
info.partitions = opb.read(5); /* only 0 to 31 legal */
|
||||
for (int j = 0; j < info.partitions; j++) {
|
||||
info.partitionclass[j] = opb.read(4); /* only 0 to 15 legal */
|
||||
if (maxclass < info.partitionclass[j])
|
||||
maxclass = info.partitionclass[j];
|
||||
}
|
||||
|
||||
/* read partition classes */
|
||||
for (int j = 0; j < maxclass + 1; j++) {
|
||||
info.class_dim[j] = opb.read(3) + 1; /* 1 to 8 */
|
||||
info.class_subs[j] = opb.read(2); /* 0,1,2,3 bits */
|
||||
if (info.class_subs[j] < 0) {
|
||||
info.free();
|
||||
return (null);
|
||||
}
|
||||
if (info.class_subs[j] != 0) {
|
||||
info.class_book[j] = opb.read(8);
|
||||
}
|
||||
if (info.class_book[j] < 0 || info.class_book[j] >= vi.books) {
|
||||
info.free();
|
||||
return (null);
|
||||
}
|
||||
for (int k = 0; k < (1 << info.class_subs[j]); k++) {
|
||||
info.class_subbook[j][k] = opb.read(8) - 1;
|
||||
if (info.class_subbook[j][k] < -1 || info.class_subbook[j][k] >= vi.books) {
|
||||
info.free();
|
||||
return (null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* read the post list */
|
||||
info.mult = opb.read(2) + 1; /* only 1,2,3,4 legal now */
|
||||
rangebits = opb.read(4);
|
||||
|
||||
for (int j = 0, k = 0; j < info.partitions; j++) {
|
||||
count += info.class_dim[info.partitionclass[j]];
|
||||
for (; k < count; k++) {
|
||||
int t = info.postlist[k + 2] = opb.read(rangebits);
|
||||
if (t < 0 || t >= (1 << rangebits)) {
|
||||
info.free();
|
||||
return (null);
|
||||
}
|
||||
}
|
||||
}
|
||||
info.postlist[0] = 0;
|
||||
info.postlist[1] = 1 << rangebits;
|
||||
|
||||
return (info);
|
||||
}
|
||||
|
||||
Object look(DspState vd, InfoMode mi, Object i) {
|
||||
int _n = 0;
|
||||
|
||||
int[] sortpointer = new int[VIF_POSIT + 2];
|
||||
|
||||
// Info vi=vd.vi;
|
||||
|
||||
InfoFloor1 info = (InfoFloor1) i;
|
||||
LookFloor1 look = new LookFloor1();
|
||||
look.vi = info;
|
||||
look.n = info.postlist[1];
|
||||
|
||||
/*
|
||||
* we drop each position value in-between already decoded values, and use linear
|
||||
* interpolation to predict each new value past the edges. The positions are
|
||||
* read in the order of the position list... we precompute the bounding
|
||||
* positions in the lookup. Of course, the neighbors can change (if a position
|
||||
* is declined), but this is an initial mapping
|
||||
*/
|
||||
|
||||
for (int j = 0; j < info.partitions; j++) {
|
||||
_n += info.class_dim[info.partitionclass[j]];
|
||||
}
|
||||
_n += 2;
|
||||
look.posts = _n;
|
||||
|
||||
/* also store a sorted position index */
|
||||
for (int j = 0; j < _n; j++) {
|
||||
sortpointer[j] = j;
|
||||
}
|
||||
// qsort(sortpointer,n,sizeof(int),icomp); // !!
|
||||
|
||||
int foo;
|
||||
for (int j = 0; j < _n - 1; j++) {
|
||||
for (int k = j; k < _n; k++) {
|
||||
if (info.postlist[sortpointer[j]] > info.postlist[sortpointer[k]]) {
|
||||
foo = sortpointer[k];
|
||||
sortpointer[k] = sortpointer[j];
|
||||
sortpointer[j] = foo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* points from sort order back to range number */
|
||||
for (int j = 0; j < _n; j++) {
|
||||
look.forward_index[j] = sortpointer[j];
|
||||
}
|
||||
/* points from range order to sorted position */
|
||||
for (int j = 0; j < _n; j++) {
|
||||
look.reverse_index[look.forward_index[j]] = j;
|
||||
}
|
||||
/* we actually need the post values too */
|
||||
for (int j = 0; j < _n; j++) {
|
||||
look.sorted_index[j] = info.postlist[look.forward_index[j]];
|
||||
}
|
||||
|
||||
/* quantize values to multiplier spec */
|
||||
switch (info.mult) {
|
||||
case 1: /* 1024 -> 256 */
|
||||
look.quant_q = 256;
|
||||
break;
|
||||
case 2: /* 1024 -> 128 */
|
||||
look.quant_q = 128;
|
||||
break;
|
||||
case 3: /* 1024 -> 86 */
|
||||
look.quant_q = 86;
|
||||
break;
|
||||
case 4: /* 1024 -> 64 */
|
||||
look.quant_q = 64;
|
||||
break;
|
||||
default:
|
||||
look.quant_q = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* discover our neighbors for decode where we don't use fit flags (that would
|
||||
* push the neighbors outward)
|
||||
*/
|
||||
for (int j = 0; j < _n - 2; j++) {
|
||||
int lo = 0;
|
||||
int hi = 1;
|
||||
int lx = 0;
|
||||
int hx = look.n;
|
||||
int currentx = info.postlist[j + 2];
|
||||
for (int k = 0; k < j + 2; k++) {
|
||||
int x = info.postlist[k];
|
||||
if (x > lx && x < currentx) {
|
||||
lo = k;
|
||||
lx = x;
|
||||
}
|
||||
if (x < hx && x > currentx) {
|
||||
hi = k;
|
||||
hx = x;
|
||||
}
|
||||
}
|
||||
look.loneighbor[j] = lo;
|
||||
look.hineighbor[j] = hi;
|
||||
}
|
||||
|
||||
return look;
|
||||
}
|
||||
|
||||
void free_info(Object i) {
|
||||
}
|
||||
|
||||
void free_look(Object i) {
|
||||
}
|
||||
|
||||
void free_state(Object vs) {
|
||||
}
|
||||
|
||||
int forward(Block vb, Object i, float[] in, float[] out, Object vs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Object inverse1(Block vb, Object ii, Object memo) {
|
||||
LookFloor1 look = (LookFloor1) ii;
|
||||
InfoFloor1 info = look.vi;
|
||||
CodeBook[] books = vb.vd.fullbooks;
|
||||
|
||||
/* unpack wrapped/predicted values from stream */
|
||||
if (vb.opb.read(1) == 1) {
|
||||
int[] fit_value = null;
|
||||
if (memo instanceof int[]) {
|
||||
fit_value = (int[]) memo;
|
||||
}
|
||||
if (fit_value == null || fit_value.length < look.posts) {
|
||||
fit_value = new int[look.posts];
|
||||
} else {
|
||||
for (int i = 0; i < fit_value.length; i++)
|
||||
fit_value[i] = 0;
|
||||
}
|
||||
|
||||
fit_value[0] = vb.opb.read(Util.ilog(look.quant_q - 1));
|
||||
fit_value[1] = vb.opb.read(Util.ilog(look.quant_q - 1));
|
||||
|
||||
/* partition by partition */
|
||||
for (int i = 0, j = 2; i < info.partitions; i++) {
|
||||
int clss = info.partitionclass[i];
|
||||
int cdim = info.class_dim[clss];
|
||||
int csubbits = info.class_subs[clss];
|
||||
int csub = 1 << csubbits;
|
||||
int cval = 0;
|
||||
|
||||
/* decode the partition's first stage cascade value */
|
||||
if (csubbits != 0) {
|
||||
cval = books[info.class_book[clss]].decode(vb.opb);
|
||||
|
||||
if (cval == -1) {
|
||||
return (null);
|
||||
}
|
||||
}
|
||||
|
||||
for (int k = 0; k < cdim; k++) {
|
||||
int book = info.class_subbook[clss][cval & (csub - 1)];
|
||||
cval >>>= csubbits;
|
||||
if (book >= 0) {
|
||||
if ((fit_value[j + k] = books[book].decode(vb.opb)) == -1) {
|
||||
return (null);
|
||||
}
|
||||
} else {
|
||||
fit_value[j + k] = 0;
|
||||
}
|
||||
}
|
||||
j += cdim;
|
||||
}
|
||||
|
||||
/* unwrap positive values and reconsitute via linear interpolation */
|
||||
for (int i = 2; i < look.posts; i++) {
|
||||
int predicted = render_point(info.postlist[look.loneighbor[i - 2]],
|
||||
info.postlist[look.hineighbor[i - 2]], fit_value[look.loneighbor[i - 2]],
|
||||
fit_value[look.hineighbor[i - 2]], info.postlist[i]);
|
||||
int hiroom = look.quant_q - predicted;
|
||||
int loroom = predicted;
|
||||
int room = (hiroom < loroom ? hiroom : loroom) << 1;
|
||||
int val = fit_value[i];
|
||||
|
||||
if (val != 0) {
|
||||
if (val >= room) {
|
||||
if (hiroom > loroom) {
|
||||
val = val - loroom;
|
||||
} else {
|
||||
val = -1 - (val - hiroom);
|
||||
}
|
||||
} else {
|
||||
if ((val & 1) != 0) {
|
||||
val = -((val + 1) >>> 1);
|
||||
} else {
|
||||
val >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
fit_value[i] = val + predicted;
|
||||
fit_value[look.loneighbor[i - 2]] &= 0x7fff;
|
||||
fit_value[look.hineighbor[i - 2]] &= 0x7fff;
|
||||
} else {
|
||||
fit_value[i] = predicted | 0x8000;
|
||||
}
|
||||
}
|
||||
return (fit_value);
|
||||
}
|
||||
|
||||
return (null);
|
||||
}
|
||||
|
||||
private static int render_point(int x0, int x1, int y0, int y1, int x) {
|
||||
y0 &= 0x7fff; /* mask off flag */
|
||||
y1 &= 0x7fff;
|
||||
|
||||
{
|
||||
int dy = y1 - y0;
|
||||
int adx = x1 - x0;
|
||||
int ady = Math.abs(dy);
|
||||
int err = ady * (x - x0);
|
||||
|
||||
int off = (int) (err / adx);
|
||||
if (dy < 0)
|
||||
return (y0 - off);
|
||||
return (y0 + off);
|
||||
}
|
||||
}
|
||||
|
||||
int inverse2(Block vb, Object i, Object memo, float[] out) {
|
||||
LookFloor1 look = (LookFloor1) i;
|
||||
InfoFloor1 info = look.vi;
|
||||
int n = vb.vd.vi.blocksizes[vb.mode] / 2;
|
||||
|
||||
if (memo != null) {
|
||||
/* render the lines */
|
||||
int[] fit_value = (int[]) memo;
|
||||
int hx = 0;
|
||||
int lx = 0;
|
||||
int ly = fit_value[0] * info.mult;
|
||||
for (int j = 1; j < look.posts; j++) {
|
||||
int current = look.forward_index[j];
|
||||
int hy = fit_value[current] & 0x7fff;
|
||||
if (hy == fit_value[current]) {
|
||||
hy *= info.mult;
|
||||
hx = info.postlist[current];
|
||||
|
||||
render_line(lx, hx, ly, hy, out);
|
||||
|
||||
lx = hx;
|
||||
ly = hy;
|
||||
}
|
||||
}
|
||||
for (int j = hx; j < n; j++) {
|
||||
out[j] *= out[j - 1]; /* be certain */
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
for (int j = 0; j < n; j++) {
|
||||
out[j] = 0.f;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
private static float[] FLOOR_fromdB_LOOKUP = { 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
|
||||
1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F, 1.7623575e-07F, 1.8768855e-07F,
|
||||
1.9988561e-07F, 2.128753e-07F, 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
|
||||
2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F, 3.7516214e-07F, 3.9954229e-07F,
|
||||
4.2550680e-07F, 4.5315863e-07F, 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
|
||||
6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F, 7.9862701e-07F, 8.5052630e-07F,
|
||||
9.0579828e-07F, 9.6466216e-07F, 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
|
||||
1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F, 1.7000785e-06F, 1.8105592e-06F,
|
||||
1.9282195e-06F, 2.0535261e-06F, 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
|
||||
2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F, 3.6190449e-06F, 3.8542308e-06F,
|
||||
4.1047004e-06F, 4.3714470e-06F, 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
|
||||
5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F, 7.7040476e-06F, 8.2047000e-06F,
|
||||
8.7378876e-06F, 9.3057248e-06F, 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
|
||||
1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F, 1.6400004e-05F, 1.7465768e-05F,
|
||||
1.8600792e-05F, 1.9809576e-05F, 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
|
||||
2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F, 3.4911534e-05F, 3.7180282e-05F,
|
||||
3.9596466e-05F, 4.2169667e-05F, 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
|
||||
5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F, 7.4317983e-05F, 7.9147585e-05F,
|
||||
8.4291040e-05F, 8.9768747e-05F, 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
|
||||
0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F, 0.00015820453F, 0.00016848555F,
|
||||
0.00017943469F, 0.00019109536F, 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
|
||||
0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F, 0.00033677814F, 0.00035866388F,
|
||||
0.00038197188F, 0.00040679456F, 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
|
||||
0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F, 0.00071691700F, 0.00076350630F,
|
||||
0.00081312324F, 0.00086596457F, 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F, 0.0011863665F,
|
||||
0.0012634633F, 0.0013455702F, 0.0014330129F, 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
|
||||
0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F, 0.0025254795F, 0.0026895994F, 0.0028643847F,
|
||||
0.0030505286F, 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F, 0.0041792066F, 0.0044507950F,
|
||||
0.0047400328F, 0.0050480668F, 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F, 0.0069158225F,
|
||||
0.0073652516F, 0.0078438871F, 0.0083536271F, 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
|
||||
0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F, 0.014722068F, 0.015678791F, 0.016697687F,
|
||||
0.017782797F, 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F, 0.024362330F, 0.025945531F,
|
||||
0.027631618F, 0.029427276F, 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F, 0.040315199F,
|
||||
0.042935108F, 0.045725273F, 0.048696758F, 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
|
||||
0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F, 0.085821044F, 0.091398179F, 0.097337747F,
|
||||
0.10366330F, 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F, 0.14201813F, 0.15124727F, 0.16107617F,
|
||||
0.17154380F, 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F, 0.23501402F, 0.25028656F, 0.26655159F,
|
||||
0.28387361F, 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F, 0.38890521F, 0.41417847F, 0.44109412F,
|
||||
0.46975890F, 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F, 0.64356699F, 0.68538959F, 0.72993007F,
|
||||
0.77736504F, 0.82788260F, 0.88168307F, 0.9389798F, 1.F };
|
||||
|
||||
private static void render_line(int x0, int x1, int y0, int y1, float[] d) {
|
||||
int dy = y1 - y0;
|
||||
int adx = x1 - x0;
|
||||
int ady = Math.abs(dy);
|
||||
int base = dy / adx;
|
||||
int sy = (dy < 0 ? base - 1 : base + 1);
|
||||
int x = x0;
|
||||
int y = y0;
|
||||
int err = 0;
|
||||
|
||||
ady -= Math.abs(base * adx);
|
||||
|
||||
d[x] *= FLOOR_fromdB_LOOKUP[y];
|
||||
while (++x < x1) {
|
||||
err = err + ady;
|
||||
if (err >= adx) {
|
||||
err -= adx;
|
||||
y += sy;
|
||||
} else {
|
||||
y += base;
|
||||
}
|
||||
d[x] *= FLOOR_fromdB_LOOKUP[y];
|
||||
}
|
||||
}
|
||||
|
||||
class InfoFloor1 {
|
||||
static final int VIF_POSIT = 63;
|
||||
static final int VIF_CLASS = 16;
|
||||
static final int VIF_PARTS = 31;
|
||||
|
||||
int partitions; /* 0 to 31 */
|
||||
int[] partitionclass = new int[VIF_PARTS]; /* 0 to 15 */
|
||||
|
||||
int[] class_dim = new int[VIF_CLASS]; /* 1 to 8 */
|
||||
int[] class_subs = new int[VIF_CLASS]; /* 0,1,2,3 (bits: 1<<n poss) */
|
||||
int[] class_book = new int[VIF_CLASS]; /* subs ^ dim entries */
|
||||
int[][] class_subbook = new int[VIF_CLASS][]; /* [VIF_CLASS][subs] */
|
||||
|
||||
int mult; /* 1 2 3 or 4 */
|
||||
int[] postlist = new int[VIF_POSIT + 2]; /* first two implicit */
|
||||
|
||||
/* encode side analysis parameters */
|
||||
float maxover;
|
||||
float maxunder;
|
||||
float maxerr;
|
||||
|
||||
int twofitminsize;
|
||||
int twofitminused;
|
||||
int twofitweight;
|
||||
float twofitatten;
|
||||
int unusedminsize;
|
||||
int unusedmin_n;
|
||||
|
||||
int n;
|
||||
|
||||
InfoFloor1() {
|
||||
for (int i = 0; i < class_subbook.length; i++) {
|
||||
class_subbook[i] = new int[8];
|
||||
}
|
||||
}
|
||||
|
||||
void free() {
|
||||
partitionclass = null;
|
||||
class_dim = null;
|
||||
class_subs = null;
|
||||
class_book = null;
|
||||
class_subbook = null;
|
||||
postlist = null;
|
||||
}
|
||||
|
||||
Object copy_info() {
|
||||
InfoFloor1 info = this;
|
||||
InfoFloor1 ret = new InfoFloor1();
|
||||
|
||||
ret.partitions = info.partitions;
|
||||
System.arraycopy(info.partitionclass, 0, ret.partitionclass, 0, VIF_PARTS);
|
||||
System.arraycopy(info.class_dim, 0, ret.class_dim, 0, VIF_CLASS);
|
||||
System.arraycopy(info.class_subs, 0, ret.class_subs, 0, VIF_CLASS);
|
||||
System.arraycopy(info.class_book, 0, ret.class_book, 0, VIF_CLASS);
|
||||
|
||||
for (int j = 0; j < VIF_CLASS; j++) {
|
||||
System.arraycopy(info.class_subbook[j], 0, ret.class_subbook[j], 0, 8);
|
||||
}
|
||||
|
||||
ret.mult = info.mult;
|
||||
System.arraycopy(info.postlist, 0, ret.postlist, 0, VIF_POSIT + 2);
|
||||
|
||||
ret.maxover = info.maxover;
|
||||
ret.maxunder = info.maxunder;
|
||||
ret.maxerr = info.maxerr;
|
||||
|
||||
ret.twofitminsize = info.twofitminsize;
|
||||
ret.twofitminused = info.twofitminused;
|
||||
ret.twofitweight = info.twofitweight;
|
||||
ret.twofitatten = info.twofitatten;
|
||||
ret.unusedminsize = info.unusedminsize;
|
||||
ret.unusedmin_n = info.unusedmin_n;
|
||||
|
||||
ret.n = info.n;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class LookFloor1 {
|
||||
static final int VIF_POSIT = 63;
|
||||
|
||||
int[] sorted_index = new int[VIF_POSIT + 2];
|
||||
int[] forward_index = new int[VIF_POSIT + 2];
|
||||
int[] reverse_index = new int[VIF_POSIT + 2];
|
||||
int[] hineighbor = new int[VIF_POSIT];
|
||||
int[] loneighbor = new int[VIF_POSIT];
|
||||
int posts;
|
||||
|
||||
int n;
|
||||
int quant_q;
|
||||
InfoFloor1 vi;
|
||||
|
||||
int phrasebits;
|
||||
int postbits;
|
||||
int frames;
|
||||
|
||||
void free() {
|
||||
sorted_index = null;
|
||||
forward_index = null;
|
||||
reverse_index = null;
|
||||
hineighbor = null;
|
||||
loneighbor = null;
|
||||
}
|
||||
}
|
||||
|
||||
class Lsfit_acc {
|
||||
long x0;
|
||||
long x1;
|
||||
|
||||
long xa;
|
||||
long ya;
|
||||
long x2a;
|
||||
long y2a;
|
||||
long xya;
|
||||
long n;
|
||||
long an;
|
||||
long un;
|
||||
long edgey0;
|
||||
long edgey1;
|
||||
}
|
||||
|
||||
class EchstateFloor1 {
|
||||
int[] codewords;
|
||||
float[] curve;
|
||||
long frameno;
|
||||
long codes;
|
||||
}
|
||||
}
|
52
sources/wasm-gc-teavm/java/com/jcraft/jorbis/FuncFloor.java
Normal file
52
sources/wasm-gc-teavm/java/com/jcraft/jorbis/FuncFloor.java
Normal file
@ -0,0 +1,52 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
import com.jcraft.jogg.*;
|
||||
|
||||
abstract class FuncFloor {
|
||||
|
||||
public static FuncFloor[] floor_P = { new Floor0(), new Floor1() };
|
||||
|
||||
abstract void pack(Object i, Buffer opb);
|
||||
|
||||
abstract Object unpack(Info vi, Buffer opb);
|
||||
|
||||
abstract Object look(DspState vd, InfoMode mi, Object i);
|
||||
|
||||
abstract void free_info(Object i);
|
||||
|
||||
abstract void free_look(Object i);
|
||||
|
||||
abstract void free_state(Object vs);
|
||||
|
||||
abstract int forward(Block vb, Object i, float[] in, float[] out, Object vs);
|
||||
|
||||
abstract Object inverse1(Block vb, Object i, Object memo);
|
||||
|
||||
abstract int inverse2(Block vb, Object i, Object memo, float[] out);
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
import com.jcraft.jogg.*;
|
||||
|
||||
abstract class FuncMapping {
|
||||
public static FuncMapping[] mapping_P = { new Mapping0() };
|
||||
|
||||
abstract void pack(Info info, Object imap, Buffer buffer);
|
||||
|
||||
abstract Object unpack(Info info, Buffer buffer);
|
||||
|
||||
abstract Object look(DspState vd, InfoMode vm, Object m);
|
||||
|
||||
abstract void free_info(Object imap);
|
||||
|
||||
abstract void free_look(Object imap);
|
||||
|
||||
abstract int inverse(Block vd, Object lm);
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
import com.jcraft.jogg.*;
|
||||
|
||||
abstract class FuncResidue {
|
||||
public static FuncResidue[] residue_P = { new Residue0(), new Residue1(), new Residue2() };
|
||||
|
||||
abstract void pack(Object vr, Buffer opb);
|
||||
|
||||
abstract Object unpack(Info vi, Buffer opb);
|
||||
|
||||
abstract Object look(DspState vd, InfoMode vm, Object vr);
|
||||
|
||||
abstract void free_info(Object i);
|
||||
|
||||
abstract void free_look(Object i);
|
||||
|
||||
abstract int inverse(Block vb, Object vl, float[][] in, int[] nonzero, int ch);
|
||||
}
|
45
sources/wasm-gc-teavm/java/com/jcraft/jorbis/FuncTime.java
Normal file
45
sources/wasm-gc-teavm/java/com/jcraft/jorbis/FuncTime.java
Normal file
@ -0,0 +1,45 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
import com.jcraft.jogg.*;
|
||||
|
||||
abstract class FuncTime {
|
||||
public static FuncTime[] time_P = { new Time0() };
|
||||
|
||||
abstract void pack(Object i, Buffer opb);
|
||||
|
||||
abstract Object unpack(Info vi, Buffer opb);
|
||||
|
||||
abstract Object look(DspState vd, InfoMode vm, Object i);
|
||||
|
||||
abstract void free_info(Object i);
|
||||
|
||||
abstract void free_look(Object i);
|
||||
|
||||
abstract int inverse(Block vb, Object i, float[] in, float[] out);
|
||||
}
|
468
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Info.java
Normal file
468
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Info.java
Normal file
@ -0,0 +1,468 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
import com.jcraft.jogg.*;
|
||||
|
||||
public class Info {
|
||||
private static final int OV_EBADPACKET = -136;
|
||||
private static final int OV_ENOTAUDIO = -135;
|
||||
|
||||
private static byte[] _vorbis = "vorbis".getBytes();
|
||||
private static final int VI_TIMEB = 1;
|
||||
// private static final int VI_FLOORB=1;
|
||||
private static final int VI_FLOORB = 2;
|
||||
// private static final int VI_RESB=1;
|
||||
private static final int VI_RESB = 3;
|
||||
private static final int VI_MAPB = 1;
|
||||
private static final int VI_WINDOWB = 1;
|
||||
|
||||
public int version;
|
||||
public int channels;
|
||||
public int rate;
|
||||
|
||||
// The below bitrate declarations are *hints*.
|
||||
// Combinations of the three values carry the following implications:
|
||||
//
|
||||
// all three set to the same value:
|
||||
// implies a fixed rate bitstream
|
||||
// only nominal set:
|
||||
// implies a VBR stream that averages the nominal bitrate. No hard
|
||||
// upper/lower limit
|
||||
// upper and or lower set:
|
||||
// implies a VBR bitstream that obeys the bitrate limits. nominal
|
||||
// may also be set to give a nominal rate.
|
||||
// none set:
|
||||
// the coder does not care to speculate.
|
||||
|
||||
int bitrate_upper;
|
||||
int bitrate_nominal;
|
||||
int bitrate_lower;
|
||||
|
||||
// Vorbis supports only short and long blocks, but allows the
|
||||
// encoder to choose the sizes
|
||||
|
||||
int[] blocksizes = new int[2];
|
||||
|
||||
// modes are the primary means of supporting on-the-fly different
|
||||
// blocksizes, different channel mappings (LR or mid-side),
|
||||
// different residue backends, etc. Each mode consists of a
|
||||
// blocksize flag and a mapping (along with the mapping setup
|
||||
|
||||
int modes;
|
||||
int maps;
|
||||
int times;
|
||||
int floors;
|
||||
int residues;
|
||||
int books;
|
||||
int psys; // encode only
|
||||
|
||||
InfoMode[] mode_param = null;
|
||||
|
||||
int[] map_type = null;
|
||||
Object[] map_param = null;
|
||||
|
||||
int[] time_type = null;
|
||||
Object[] time_param = null;
|
||||
|
||||
int[] floor_type = null;
|
||||
Object[] floor_param = null;
|
||||
|
||||
int[] residue_type = null;
|
||||
Object[] residue_param = null;
|
||||
|
||||
StaticCodeBook[] book_param = null;
|
||||
|
||||
PsyInfo[] psy_param = new PsyInfo[64]; // encode only
|
||||
|
||||
// for block long/sort tuning; encode only
|
||||
int envelopesa;
|
||||
float preecho_thresh;
|
||||
float preecho_clamp;
|
||||
|
||||
// used by synthesis, which has a full, alloced vi
|
||||
public void init() {
|
||||
rate = 0;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
for (int i = 0; i < modes; i++) {
|
||||
mode_param[i] = null;
|
||||
}
|
||||
mode_param = null;
|
||||
|
||||
for (int i = 0; i < maps; i++) { // unpack does the range checking
|
||||
FuncMapping.mapping_P[map_type[i]].free_info(map_param[i]);
|
||||
}
|
||||
map_param = null;
|
||||
|
||||
for (int i = 0; i < times; i++) { // unpack does the range checking
|
||||
FuncTime.time_P[time_type[i]].free_info(time_param[i]);
|
||||
}
|
||||
time_param = null;
|
||||
|
||||
for (int i = 0; i < floors; i++) { // unpack does the range checking
|
||||
FuncFloor.floor_P[floor_type[i]].free_info(floor_param[i]);
|
||||
}
|
||||
floor_param = null;
|
||||
|
||||
for (int i = 0; i < residues; i++) { // unpack does the range checking
|
||||
FuncResidue.residue_P[residue_type[i]].free_info(residue_param[i]);
|
||||
}
|
||||
residue_param = null;
|
||||
|
||||
// the static codebooks *are* freed if you call info_clear, because
|
||||
// decode side does alloc a 'static' codebook. Calling clear on the
|
||||
// full codebook does not clear the static codebook (that's our
|
||||
// responsibility)
|
||||
for (int i = 0; i < books; i++) {
|
||||
// just in case the decoder pre-cleared to save space
|
||||
if (book_param[i] != null) {
|
||||
book_param[i].clear();
|
||||
book_param[i] = null;
|
||||
}
|
||||
}
|
||||
// if(vi->book_param)free(vi->book_param);
|
||||
book_param = null;
|
||||
|
||||
for (int i = 0; i < psys; i++) {
|
||||
psy_param[i].free();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Header packing/unpacking
|
||||
int unpack_info(Buffer opb) {
|
||||
version = opb.read(32);
|
||||
if (version != 0)
|
||||
return (-1);
|
||||
|
||||
channels = opb.read(8);
|
||||
rate = opb.read(32);
|
||||
|
||||
bitrate_upper = opb.read(32);
|
||||
bitrate_nominal = opb.read(32);
|
||||
bitrate_lower = opb.read(32);
|
||||
|
||||
blocksizes[0] = 1 << opb.read(4);
|
||||
blocksizes[1] = 1 << opb.read(4);
|
||||
|
||||
if ((rate < 1) || (channels < 1) || (blocksizes[0] < 8) || (blocksizes[1] < blocksizes[0])
|
||||
|| (opb.read(1) != 1)) {
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
// all of the real encoding details are here. The modes, books,
|
||||
// everything
|
||||
int unpack_books(Buffer opb) {
|
||||
|
||||
books = opb.read(8) + 1;
|
||||
|
||||
if (book_param == null || book_param.length != books)
|
||||
book_param = new StaticCodeBook[books];
|
||||
for (int i = 0; i < books; i++) {
|
||||
book_param[i] = new StaticCodeBook();
|
||||
if (book_param[i].unpack(opb) != 0) {
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
// time backend settings
|
||||
times = opb.read(6) + 1;
|
||||
if (time_type == null || time_type.length != times)
|
||||
time_type = new int[times];
|
||||
if (time_param == null || time_param.length != times)
|
||||
time_param = new Object[times];
|
||||
for (int i = 0; i < times; i++) {
|
||||
time_type[i] = opb.read(16);
|
||||
if (time_type[i] < 0 || time_type[i] >= VI_TIMEB) {
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
time_param[i] = FuncTime.time_P[time_type[i]].unpack(this, opb);
|
||||
if (time_param[i] == null) {
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
// floor backend settings
|
||||
floors = opb.read(6) + 1;
|
||||
if (floor_type == null || floor_type.length != floors)
|
||||
floor_type = new int[floors];
|
||||
if (floor_param == null || floor_param.length != floors)
|
||||
floor_param = new Object[floors];
|
||||
|
||||
for (int i = 0; i < floors; i++) {
|
||||
floor_type[i] = opb.read(16);
|
||||
if (floor_type[i] < 0 || floor_type[i] >= VI_FLOORB) {
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
|
||||
floor_param[i] = FuncFloor.floor_P[floor_type[i]].unpack(this, opb);
|
||||
if (floor_param[i] == null) {
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
// residue backend settings
|
||||
residues = opb.read(6) + 1;
|
||||
|
||||
if (residue_type == null || residue_type.length != residues)
|
||||
residue_type = new int[residues];
|
||||
|
||||
if (residue_param == null || residue_param.length != residues)
|
||||
residue_param = new Object[residues];
|
||||
|
||||
for (int i = 0; i < residues; i++) {
|
||||
residue_type[i] = opb.read(16);
|
||||
if (residue_type[i] < 0 || residue_type[i] >= VI_RESB) {
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
residue_param[i] = FuncResidue.residue_P[residue_type[i]].unpack(this, opb);
|
||||
if (residue_param[i] == null) {
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
// map backend settings
|
||||
maps = opb.read(6) + 1;
|
||||
if (map_type == null || map_type.length != maps)
|
||||
map_type = new int[maps];
|
||||
if (map_param == null || map_param.length != maps)
|
||||
map_param = new Object[maps];
|
||||
for (int i = 0; i < maps; i++) {
|
||||
map_type[i] = opb.read(16);
|
||||
if (map_type[i] < 0 || map_type[i] >= VI_MAPB) {
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
map_param[i] = FuncMapping.mapping_P[map_type[i]].unpack(this, opb);
|
||||
if (map_param[i] == null) {
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
// mode settings
|
||||
modes = opb.read(6) + 1;
|
||||
if (mode_param == null || mode_param.length != modes)
|
||||
mode_param = new InfoMode[modes];
|
||||
for (int i = 0; i < modes; i++) {
|
||||
mode_param[i] = new InfoMode();
|
||||
mode_param[i].blockflag = opb.read(1);
|
||||
mode_param[i].windowtype = opb.read(16);
|
||||
mode_param[i].transformtype = opb.read(16);
|
||||
mode_param[i].mapping = opb.read(8);
|
||||
|
||||
if ((mode_param[i].windowtype >= VI_WINDOWB) || (mode_param[i].transformtype >= VI_WINDOWB)
|
||||
|| (mode_param[i].mapping >= maps)) {
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (opb.read(1) != 1) {
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
// The Vorbis header is in three packets; the initial small packet in
|
||||
// the first page that identifies basic parameters, a second packet
|
||||
// with bitstream comments and a third packet that holds the
|
||||
// codebook.
|
||||
|
||||
public int synthesis_headerin(Comment vc, Packet op) {
|
||||
Buffer opb = new Buffer();
|
||||
|
||||
if (op != null) {
|
||||
opb.readinit(op.packet_base, op.packet, op.bytes);
|
||||
|
||||
// Which of the three types of header is this?
|
||||
// Also verify header-ness, vorbis
|
||||
{
|
||||
byte[] buffer = new byte[6];
|
||||
int packtype = opb.read(8);
|
||||
opb.read(buffer, 6);
|
||||
if (buffer[0] != 'v' || buffer[1] != 'o' || buffer[2] != 'r' || buffer[3] != 'b' || buffer[4] != 'i'
|
||||
|| buffer[5] != 's') {
|
||||
// not a vorbis header
|
||||
return (-1);
|
||||
}
|
||||
switch (packtype) {
|
||||
case 0x01: // least significant *bit* is read first
|
||||
if (op.b_o_s == 0) {
|
||||
// Not the initial packet
|
||||
return (-1);
|
||||
}
|
||||
if (rate != 0) {
|
||||
// previously initialized info header
|
||||
return (-1);
|
||||
}
|
||||
return (unpack_info(opb));
|
||||
case 0x03: // least significant *bit* is read first
|
||||
if (rate == 0) {
|
||||
// um... we didn't get the initial header
|
||||
return (-1);
|
||||
}
|
||||
return (vc.unpack(opb));
|
||||
case 0x05: // least significant *bit* is read first
|
||||
if (rate == 0 || vc.vendor == null) {
|
||||
// um... we didn;t get the initial header or comments yet
|
||||
return (-1);
|
||||
}
|
||||
return (unpack_books(opb));
|
||||
default:
|
||||
// Not a valid vorbis header type
|
||||
// return(-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// pack side
|
||||
int pack_info(Buffer opb) {
|
||||
// preamble
|
||||
opb.write(0x01, 8);
|
||||
opb.write(_vorbis);
|
||||
|
||||
// basic information about the stream
|
||||
opb.write(0x00, 32);
|
||||
opb.write(channels, 8);
|
||||
opb.write(rate, 32);
|
||||
|
||||
opb.write(bitrate_upper, 32);
|
||||
opb.write(bitrate_nominal, 32);
|
||||
opb.write(bitrate_lower, 32);
|
||||
|
||||
opb.write(Util.ilog2(blocksizes[0]), 4);
|
||||
opb.write(Util.ilog2(blocksizes[1]), 4);
|
||||
opb.write(1, 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int pack_books(Buffer opb) {
|
||||
opb.write(0x05, 8);
|
||||
opb.write(_vorbis);
|
||||
|
||||
// books
|
||||
opb.write(books - 1, 8);
|
||||
for (int i = 0; i < books; i++) {
|
||||
if (book_param[i].pack(opb) != 0) {
|
||||
// goto err_out;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
// times
|
||||
opb.write(times - 1, 6);
|
||||
for (int i = 0; i < times; i++) {
|
||||
opb.write(time_type[i], 16);
|
||||
FuncTime.time_P[time_type[i]].pack(this.time_param[i], opb);
|
||||
}
|
||||
|
||||
// floors
|
||||
opb.write(floors - 1, 6);
|
||||
for (int i = 0; i < floors; i++) {
|
||||
opb.write(floor_type[i], 16);
|
||||
FuncFloor.floor_P[floor_type[i]].pack(floor_param[i], opb);
|
||||
}
|
||||
|
||||
// residues
|
||||
opb.write(residues - 1, 6);
|
||||
for (int i = 0; i < residues; i++) {
|
||||
opb.write(residue_type[i], 16);
|
||||
FuncResidue.residue_P[residue_type[i]].pack(residue_param[i], opb);
|
||||
}
|
||||
|
||||
// maps
|
||||
opb.write(maps - 1, 6);
|
||||
for (int i = 0; i < maps; i++) {
|
||||
opb.write(map_type[i], 16);
|
||||
FuncMapping.mapping_P[map_type[i]].pack(this, map_param[i], opb);
|
||||
}
|
||||
|
||||
// modes
|
||||
opb.write(modes - 1, 6);
|
||||
for (int i = 0; i < modes; i++) {
|
||||
opb.write(mode_param[i].blockflag, 1);
|
||||
opb.write(mode_param[i].windowtype, 16);
|
||||
opb.write(mode_param[i].transformtype, 16);
|
||||
opb.write(mode_param[i].mapping, 8);
|
||||
}
|
||||
opb.write(1, 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
public int blocksize(Packet op) {
|
||||
// codec_setup_info
|
||||
Buffer opb = new Buffer();
|
||||
|
||||
int mode;
|
||||
|
||||
opb.readinit(op.packet_base, op.packet, op.bytes);
|
||||
|
||||
/* Check the packet type */
|
||||
if (opb.read(1) != 0) {
|
||||
/* Oops. This is not an audio data packet */
|
||||
return (OV_ENOTAUDIO);
|
||||
}
|
||||
{
|
||||
int modebits = 0;
|
||||
int v = modes;
|
||||
while (v > 1) {
|
||||
modebits++;
|
||||
v >>>= 1;
|
||||
}
|
||||
|
||||
/* read our mode and pre/post windowsize */
|
||||
mode = opb.read(modebits);
|
||||
}
|
||||
if (mode == -1)
|
||||
return (OV_EBADPACKET);
|
||||
return (blocksizes[mode_param[mode].blockflag]);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "version:" + version + ", channels:" + channels + ", rate:" + rate
|
||||
+ ", bitrate:" + bitrate_upper + "," + bitrate_nominal + ","
|
||||
+ bitrate_lower;
|
||||
}
|
||||
}
|
34
sources/wasm-gc-teavm/java/com/jcraft/jorbis/InfoMode.java
Normal file
34
sources/wasm-gc-teavm/java/com/jcraft/jorbis/InfoMode.java
Normal file
@ -0,0 +1,34 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
class InfoMode {
|
||||
int blockflag;
|
||||
int windowtype;
|
||||
int transformtype;
|
||||
int mapping;
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
public class JOrbisException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public JOrbisException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public JOrbisException(String s) {
|
||||
super("JOrbis: " + s);
|
||||
}
|
||||
}
|
122
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Lookup.java
Normal file
122
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Lookup.java
Normal file
@ -0,0 +1,122 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
class Lookup {
|
||||
static final int COS_LOOKUP_SZ = 128;
|
||||
static final float[] COS_LOOKUP = { +1.0000000000000f, +0.9996988186962f, +0.9987954562052f, +0.9972904566787f,
|
||||
+0.9951847266722f, +0.9924795345987f, +0.9891765099648f, +0.9852776423889f, +0.9807852804032f,
|
||||
+0.9757021300385f, +0.9700312531945f, +0.9637760657954f, +0.9569403357322f, +0.9495281805930f,
|
||||
+0.9415440651830f, +0.9329927988347f, +0.9238795325113f, +0.9142097557035f, +0.9039892931234f,
|
||||
+0.8932243011955f, +0.8819212643484f, +0.8700869911087f, +0.8577286100003f, +0.8448535652497f,
|
||||
+0.8314696123025f, +0.8175848131516f, +0.8032075314806f, +0.7883464276266f, +0.7730104533627f,
|
||||
+0.7572088465065f, +0.7409511253550f, +0.7242470829515f, +0.7071067811865f, +0.6895405447371f,
|
||||
+0.6715589548470f, +0.6531728429538f, +0.6343932841636f, +0.6152315905806f, +0.5956993044924f,
|
||||
+0.5758081914178f, +0.5555702330196f, +0.5349976198871f, +0.5141027441932f, +0.4928981922298f,
|
||||
+0.4713967368260f, +0.4496113296546f, +0.4275550934303f, +0.4052413140050f, +0.3826834323651f,
|
||||
+0.3598950365350f, +0.3368898533922f, +0.3136817403989f, +0.2902846772545f, +0.2667127574749f,
|
||||
+0.2429801799033f, +0.2191012401569f, +0.1950903220161f, +0.1709618887603f, +0.1467304744554f,
|
||||
+0.1224106751992f, +0.0980171403296f, +0.0735645635997f, +0.0490676743274f, +0.0245412285229f,
|
||||
+0.0000000000000f, -0.0245412285229f, -0.0490676743274f, -0.0735645635997f, -0.0980171403296f,
|
||||
-0.1224106751992f, -0.1467304744554f, -0.1709618887603f, -0.1950903220161f, -0.2191012401569f,
|
||||
-0.2429801799033f, -0.2667127574749f, -0.2902846772545f, -0.3136817403989f, -0.3368898533922f,
|
||||
-0.3598950365350f, -0.3826834323651f, -0.4052413140050f, -0.4275550934303f, -0.4496113296546f,
|
||||
-0.4713967368260f, -0.4928981922298f, -0.5141027441932f, -0.5349976198871f, -0.5555702330196f,
|
||||
-0.5758081914178f, -0.5956993044924f, -0.6152315905806f, -0.6343932841636f, -0.6531728429538f,
|
||||
-0.6715589548470f, -0.6895405447371f, -0.7071067811865f, -0.7242470829515f, -0.7409511253550f,
|
||||
-0.7572088465065f, -0.7730104533627f, -0.7883464276266f, -0.8032075314806f, -0.8175848131516f,
|
||||
-0.8314696123025f, -0.8448535652497f, -0.8577286100003f, -0.8700869911087f, -0.8819212643484f,
|
||||
-0.8932243011955f, -0.9039892931234f, -0.9142097557035f, -0.9238795325113f, -0.9329927988347f,
|
||||
-0.9415440651830f, -0.9495281805930f, -0.9569403357322f, -0.9637760657954f, -0.9700312531945f,
|
||||
-0.9757021300385f, -0.9807852804032f, -0.9852776423889f, -0.9891765099648f, -0.9924795345987f,
|
||||
-0.9951847266722f, -0.9972904566787f, -0.9987954562052f, -0.9996988186962f, -1.0000000000000f, };
|
||||
|
||||
/* interpolated lookup based cos function, domain 0 to PI only */
|
||||
static float coslook(float a) {
|
||||
double d = a * (.31830989 * (float) COS_LOOKUP_SZ);
|
||||
int i = (int) d;
|
||||
return COS_LOOKUP[i] + ((float) (d - i)) * (COS_LOOKUP[i + 1] - COS_LOOKUP[i]);
|
||||
}
|
||||
|
||||
static final int INVSQ_LOOKUP_SZ = 32;
|
||||
static final float[] INVSQ_LOOKUP = { 1.414213562373f, 1.392621247646f, 1.371988681140f, 1.352246807566f,
|
||||
1.333333333333f, 1.315191898443f, 1.297771369046f, 1.281025230441f, 1.264911064067f, 1.249390095109f,
|
||||
1.234426799697f, 1.219988562661f, 1.206045378311f, 1.192569588000f, 1.179535649239f, 1.166919931983f,
|
||||
1.154700538379f, 1.142857142857f, 1.131370849898f, 1.120224067222f, 1.109400392450f, 1.098884511590f,
|
||||
1.088662107904f, 1.078719779941f, 1.069044967650f, 1.059625885652f, 1.050451462878f, 1.041511287847f,
|
||||
1.032795558989f, 1.024295039463f, 1.016001016002f, 1.007905261358f, 1.000000000000f, };
|
||||
|
||||
/* interpolated 1./sqrt(p) where .5 <= p < 1. */
|
||||
static float invsqlook(float a) {
|
||||
double d = a * (2.f * (float) INVSQ_LOOKUP_SZ) - (float) INVSQ_LOOKUP_SZ;
|
||||
int i = (int) d;
|
||||
return INVSQ_LOOKUP[i] + ((float) (d - i)) * (INVSQ_LOOKUP[i + 1] - INVSQ_LOOKUP[i]);
|
||||
}
|
||||
|
||||
static final int INVSQ2EXP_LOOKUP_MIN = -32;
|
||||
static final int INVSQ2EXP_LOOKUP_MAX = 32;
|
||||
static final float[] INVSQ2EXP_LOOKUP = { 65536.f, 46340.95001f, 32768.f, 23170.47501f, 16384.f, 11585.2375f,
|
||||
8192.f, 5792.618751f, 4096.f, 2896.309376f, 2048.f, 1448.154688f, 1024.f, 724.0773439f, 512.f, 362.038672f,
|
||||
256.f, 181.019336f, 128.f, 90.50966799f, 64.f, 45.254834f, 32.f, 22.627417f, 16.f, 11.3137085f, 8.f,
|
||||
5.656854249f, 4.f, 2.828427125f, 2.f, 1.414213562f, 1.f, 0.7071067812f, 0.5f, 0.3535533906f, 0.25f,
|
||||
0.1767766953f, 0.125f, 0.08838834765f, 0.0625f, 0.04419417382f, 0.03125f, 0.02209708691f, 0.015625f,
|
||||
0.01104854346f, 0.0078125f, 0.005524271728f, 0.00390625f, 0.002762135864f, 0.001953125f, 0.001381067932f,
|
||||
0.0009765625f, 0.000690533966f, 0.00048828125f, 0.000345266983f, 0.000244140625f, 0.0001726334915f,
|
||||
0.0001220703125f, 8.631674575e-05f, 6.103515625e-05f, 4.315837288e-05f, 3.051757812e-05f, 2.157918644e-05f,
|
||||
1.525878906e-05f, };
|
||||
|
||||
/* interpolated 1./sqrt(p) where .5 <= p < 1. */
|
||||
static float invsq2explook(int a) {
|
||||
return INVSQ2EXP_LOOKUP[a - INVSQ2EXP_LOOKUP_MIN];
|
||||
}
|
||||
|
||||
static final int FROMdB_LOOKUP_SZ = 35;
|
||||
static final int FROMdB2_LOOKUP_SZ = 32;
|
||||
static final int FROMdB_SHIFT = 5;
|
||||
static final int FROMdB2_SHIFT = 3;
|
||||
static final int FROMdB2_MASK = 31;
|
||||
static final float[] FROMdB_LOOKUP = { 1.f, 0.6309573445f, 0.3981071706f, 0.2511886432f, 0.1584893192f, 0.1f,
|
||||
0.06309573445f, 0.03981071706f, 0.02511886432f, 0.01584893192f, 0.01f, 0.006309573445f, 0.003981071706f,
|
||||
0.002511886432f, 0.001584893192f, 0.001f, 0.0006309573445f, 0.0003981071706f, 0.0002511886432f,
|
||||
0.0001584893192f, 0.0001f, 6.309573445e-05f, 3.981071706e-05f, 2.511886432e-05f, 1.584893192e-05f, 1e-05f,
|
||||
6.309573445e-06f, 3.981071706e-06f, 2.511886432e-06f, 1.584893192e-06f, 1e-06f, 6.309573445e-07f,
|
||||
3.981071706e-07f, 2.511886432e-07f, 1.584893192e-07f, };
|
||||
static final float[] FROMdB2_LOOKUP = { 0.9928302478f, 0.9786445908f, 0.9646616199f, 0.9508784391f, 0.9372921937f,
|
||||
0.92390007f, 0.9106992942f, 0.8976871324f, 0.8848608897f, 0.8722179097f, 0.8597555737f, 0.8474713009f,
|
||||
0.835362547f, 0.8234268041f, 0.8116616003f, 0.8000644989f, 0.7886330981f, 0.7773650302f, 0.7662579617f,
|
||||
0.755309592f, 0.7445176537f, 0.7338799116f, 0.7233941627f, 0.7130582353f, 0.7028699885f, 0.6928273125f,
|
||||
0.6829281272f, 0.6731703824f, 0.6635520573f, 0.6540711597f, 0.6447257262f, 0.6355138211f, };
|
||||
|
||||
/* interpolated lookup based fromdB function, domain -140dB to 0dB only */
|
||||
static float fromdBlook(float a) {
|
||||
int i = (int) (a * ((float) (-(1 << FROMdB2_SHIFT))));
|
||||
return (i < 0) ? 1.f
|
||||
: ((i >= (FROMdB_LOOKUP_SZ << FROMdB_SHIFT)) ? 0.f
|
||||
: FROMdB_LOOKUP[i >>> FROMdB_SHIFT] * FROMdB2_LOOKUP[i & FROMdB2_MASK]);
|
||||
}
|
||||
|
||||
}
|
185
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Lpc.java
Normal file
185
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Lpc.java
Normal file
@ -0,0 +1,185 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
class Lpc {
|
||||
// en/decode lookups
|
||||
Drft fft = new Drft();;
|
||||
|
||||
int ln;
|
||||
int m;
|
||||
|
||||
// Autocorrelation LPC coeff generation algorithm invented by
|
||||
// N. Levinson in 1947, modified by J. Durbin in 1959.
|
||||
|
||||
// Input : n elements of time doamin data
|
||||
// Output: m lpc coefficients, excitation energy
|
||||
|
||||
static float lpc_from_data(float[] data, float[] lpc, int n, int m) {
|
||||
float[] aut = new float[m + 1];
|
||||
float error;
|
||||
int i, j;
|
||||
|
||||
// autocorrelation, p+1 lag coefficients
|
||||
|
||||
j = m + 1;
|
||||
while (j-- != 0) {
|
||||
float d = 0;
|
||||
for (i = j; i < n; i++)
|
||||
d += data[i] * data[i - j];
|
||||
aut[j] = d;
|
||||
}
|
||||
|
||||
// Generate lpc coefficients from autocorr values
|
||||
|
||||
error = aut[0];
|
||||
/*
|
||||
* if(error==0){ for(int k=0; k<m; k++) lpc[k]=0.0f; return 0; }
|
||||
*/
|
||||
|
||||
for (i = 0; i < m; i++) {
|
||||
float r = -aut[i + 1];
|
||||
|
||||
if (error == 0) {
|
||||
for (int k = 0; k < m; k++)
|
||||
lpc[k] = 0.0f;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Sum up this iteration's reflection coefficient; note that in
|
||||
// Vorbis we don't save it. If anyone wants to recycle this code
|
||||
// and needs reflection coefficients, save the results of 'r' from
|
||||
// each iteration.
|
||||
|
||||
for (j = 0; j < i; j++)
|
||||
r -= lpc[j] * aut[i - j];
|
||||
r /= error;
|
||||
|
||||
// Update LPC coefficients and total error
|
||||
|
||||
lpc[i] = r;
|
||||
for (j = 0; j < i / 2; j++) {
|
||||
float tmp = lpc[j];
|
||||
lpc[j] += r * lpc[i - 1 - j];
|
||||
lpc[i - 1 - j] += r * tmp;
|
||||
}
|
||||
if (i % 2 != 0)
|
||||
lpc[j] += lpc[j] * r;
|
||||
|
||||
error *= 1.0 - r * r;
|
||||
}
|
||||
|
||||
// we need the error value to know how big an impulse to hit the
|
||||
// filter with later
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
// Input : n element envelope spectral curve
|
||||
// Output: m lpc coefficients, excitation energy
|
||||
|
||||
float lpc_from_curve(float[] curve, float[] lpc) {
|
||||
int n = ln;
|
||||
float[] work = new float[n + n];
|
||||
float fscale = (float) (.5 / n);
|
||||
int i, j;
|
||||
|
||||
// input is a real curve. make it complex-real
|
||||
// This mixes phase, but the LPC generation doesn't care.
|
||||
for (i = 0; i < n; i++) {
|
||||
work[i * 2] = curve[i] * fscale;
|
||||
work[i * 2 + 1] = 0;
|
||||
}
|
||||
work[n * 2 - 1] = curve[n - 1] * fscale;
|
||||
|
||||
n *= 2;
|
||||
fft.backward(work);
|
||||
|
||||
// The autocorrelation will not be circular. Shift, else we lose
|
||||
// most of the power in the edges.
|
||||
|
||||
for (i = 0, j = n / 2; i < n / 2;) {
|
||||
float temp = work[i];
|
||||
work[i++] = work[j];
|
||||
work[j++] = temp;
|
||||
}
|
||||
|
||||
return (lpc_from_data(work, lpc, n, m));
|
||||
}
|
||||
|
||||
void init(int mapped, int m) {
|
||||
ln = mapped;
|
||||
this.m = m;
|
||||
|
||||
// we cheat decoding the LPC spectrum via FFTs
|
||||
fft.init(mapped * 2);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
fft.clear();
|
||||
}
|
||||
|
||||
static float FAST_HYPOT(float a, float b) {
|
||||
return (float) Math.sqrt((a) * (a) + (b) * (b));
|
||||
}
|
||||
|
||||
// One can do this the long way by generating the transfer function in
|
||||
// the time domain and taking the forward FFT of the result. The
|
||||
// results from direct calculation are cleaner and faster.
|
||||
//
|
||||
// This version does a linear curve generation and then later
|
||||
// interpolates the log curve from the linear curve.
|
||||
|
||||
void lpc_to_curve(float[] curve, float[] lpc, float amp) {
|
||||
|
||||
for (int i = 0; i < ln * 2; i++)
|
||||
curve[i] = 0.0f;
|
||||
|
||||
if (amp == 0)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < m; i++) {
|
||||
curve[i * 2 + 1] = lpc[i] / (4 * amp);
|
||||
curve[i * 2 + 2] = -lpc[i] / (4 * amp);
|
||||
}
|
||||
|
||||
fft.backward(curve);
|
||||
|
||||
{
|
||||
int l2 = ln * 2;
|
||||
float unit = (float) (1. / amp);
|
||||
curve[0] = (float) (1. / (curve[0] * 2 + unit));
|
||||
for (int i = 1; i < ln; i++) {
|
||||
float real = (curve[i] + curve[l2 - i]);
|
||||
float imag = (curve[i] - curve[l2 - i]);
|
||||
|
||||
float a = real + unit;
|
||||
curve[i] = (float) (1.0 / FAST_HYPOT(a, imag));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
102
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Lsp.java
Normal file
102
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Lsp.java
Normal file
@ -0,0 +1,102 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
/*
|
||||
function: LSP (also called LSF) conversion routines
|
||||
|
||||
The LSP generation code is taken (with minimal modification) from
|
||||
"On the Computation of the LSP Frequencies" by Joseph Rothweiler
|
||||
<rothwlr@altavista.net>, available at:
|
||||
|
||||
http://www2.xtdl.com/~rothwlr/lsfpaper/lsfpage.html
|
||||
********************************************************************/
|
||||
|
||||
class Lsp {
|
||||
|
||||
static final float M_PI = (float) (3.1415926539);
|
||||
|
||||
static void lsp_to_curve(float[] curve, int[] map, int n, int ln, float[] lsp, int m, float amp, float ampoffset) {
|
||||
int i;
|
||||
float wdel = M_PI / ln;
|
||||
for (i = 0; i < m; i++)
|
||||
lsp[i] = Lookup.coslook(lsp[i]);
|
||||
int m2 = (m / 2) * 2;
|
||||
|
||||
i = 0;
|
||||
while (i < n) {
|
||||
int k = map[i];
|
||||
float p = .7071067812f;
|
||||
float q = .7071067812f;
|
||||
float w = Lookup.coslook(wdel * k);
|
||||
|
||||
for (int j = 0; j < m2; j += 2) {
|
||||
q *= lsp[j] - w;
|
||||
p *= lsp[j + 1] - w;
|
||||
}
|
||||
|
||||
if ((m & 1) != 0) {
|
||||
/* odd order filter; slightly assymetric */
|
||||
/* the last coefficient */
|
||||
q *= lsp[m - 1] - w;
|
||||
q *= q;
|
||||
p *= p * (1.f - w * w);
|
||||
} else {
|
||||
/* even order filter; still symmetric */
|
||||
q *= q * (1.f + w);
|
||||
p *= p * (1.f - w);
|
||||
}
|
||||
|
||||
// q=frexp(p+q,&qexp);
|
||||
q = p + q;
|
||||
int hx = Float.floatToIntBits(q);
|
||||
int ix = 0x7fffffff & hx;
|
||||
int qexp = 0;
|
||||
|
||||
if (ix >= 0x7f800000 || (ix == 0)) {
|
||||
// 0,inf,nan
|
||||
} else {
|
||||
if (ix < 0x00800000) { // subnormal
|
||||
q *= 3.3554432000e+07; // 0x4c000000
|
||||
hx = Float.floatToIntBits(q);
|
||||
ix = 0x7fffffff & hx;
|
||||
qexp = -25;
|
||||
}
|
||||
qexp += ((ix >>> 23) - 126);
|
||||
hx = (hx & 0x807fffff) | 0x3f000000;
|
||||
q = Float.intBitsToFloat(hx);
|
||||
}
|
||||
|
||||
q = Lookup.fromdBlook(amp * Lookup.invsqlook(q) * Lookup.invsq2explook(qexp + m) - ampoffset);
|
||||
|
||||
do {
|
||||
curve[i++] *= q;
|
||||
} while (i < n && map[i] == k);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
361
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Mapping0.java
Normal file
361
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Mapping0.java
Normal file
@ -0,0 +1,361 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
import com.jcraft.jogg.*;
|
||||
|
||||
class Mapping0 extends FuncMapping {
|
||||
static int seq = 0;
|
||||
|
||||
void free_info(Object imap) {
|
||||
};
|
||||
|
||||
void free_look(Object imap) {
|
||||
}
|
||||
|
||||
Object look(DspState vd, InfoMode vm, Object m) {
|
||||
// System.err.println("Mapping0.look");
|
||||
Info vi = vd.vi;
|
||||
LookMapping0 look = new LookMapping0();
|
||||
InfoMapping0 info = look.map = (InfoMapping0) m;
|
||||
look.mode = vm;
|
||||
|
||||
look.time_look = new Object[info.submaps];
|
||||
look.floor_look = new Object[info.submaps];
|
||||
look.residue_look = new Object[info.submaps];
|
||||
|
||||
look.time_func = new FuncTime[info.submaps];
|
||||
look.floor_func = new FuncFloor[info.submaps];
|
||||
look.residue_func = new FuncResidue[info.submaps];
|
||||
|
||||
for (int i = 0; i < info.submaps; i++) {
|
||||
int timenum = info.timesubmap[i];
|
||||
int floornum = info.floorsubmap[i];
|
||||
int resnum = info.residuesubmap[i];
|
||||
|
||||
look.time_func[i] = FuncTime.time_P[vi.time_type[timenum]];
|
||||
look.time_look[i] = look.time_func[i].look(vd, vm, vi.time_param[timenum]);
|
||||
look.floor_func[i] = FuncFloor.floor_P[vi.floor_type[floornum]];
|
||||
look.floor_look[i] = look.floor_func[i].look(vd, vm, vi.floor_param[floornum]);
|
||||
look.residue_func[i] = FuncResidue.residue_P[vi.residue_type[resnum]];
|
||||
look.residue_look[i] = look.residue_func[i].look(vd, vm, vi.residue_param[resnum]);
|
||||
|
||||
}
|
||||
|
||||
if (vi.psys != 0 && vd.analysisp != 0) {
|
||||
// ??
|
||||
}
|
||||
|
||||
look.ch = vi.channels;
|
||||
|
||||
return (look);
|
||||
}
|
||||
|
||||
void pack(Info vi, Object imap, Buffer opb) {
|
||||
InfoMapping0 info = (InfoMapping0) imap;
|
||||
|
||||
/*
|
||||
* another 'we meant to do it this way' hack... up to beta 4, we packed 4 binary
|
||||
* zeros here to signify one submapping in use. We now redefine that to mean
|
||||
* four bitflags that indicate use of deeper features; bit0:submappings,
|
||||
* bit1:coupling, bit2,3:reserved. This is backward compatable with all actual
|
||||
* uses of the beta code.
|
||||
*/
|
||||
|
||||
if (info.submaps > 1) {
|
||||
opb.write(1, 1);
|
||||
opb.write(info.submaps - 1, 4);
|
||||
} else {
|
||||
opb.write(0, 1);
|
||||
}
|
||||
|
||||
if (info.coupling_steps > 0) {
|
||||
opb.write(1, 1);
|
||||
opb.write(info.coupling_steps - 1, 8);
|
||||
for (int i = 0; i < info.coupling_steps; i++) {
|
||||
opb.write(info.coupling_mag[i], Util.ilog2(vi.channels));
|
||||
opb.write(info.coupling_ang[i], Util.ilog2(vi.channels));
|
||||
}
|
||||
} else {
|
||||
opb.write(0, 1);
|
||||
}
|
||||
|
||||
opb.write(0, 2); /* 2,3:reserved */
|
||||
|
||||
/* we don't write the channel submappings if we only have one... */
|
||||
if (info.submaps > 1) {
|
||||
for (int i = 0; i < vi.channels; i++)
|
||||
opb.write(info.chmuxlist[i], 4);
|
||||
}
|
||||
for (int i = 0; i < info.submaps; i++) {
|
||||
opb.write(info.timesubmap[i], 8);
|
||||
opb.write(info.floorsubmap[i], 8);
|
||||
opb.write(info.residuesubmap[i], 8);
|
||||
}
|
||||
}
|
||||
|
||||
// also responsible for range checking
|
||||
Object unpack(Info vi, Buffer opb) {
|
||||
InfoMapping0 info = new InfoMapping0();
|
||||
|
||||
if (opb.read(1) != 0) {
|
||||
info.submaps = opb.read(4) + 1;
|
||||
} else {
|
||||
info.submaps = 1;
|
||||
}
|
||||
|
||||
if (opb.read(1) != 0) {
|
||||
info.coupling_steps = opb.read(8) + 1;
|
||||
|
||||
for (int i = 0; i < info.coupling_steps; i++) {
|
||||
int testM = info.coupling_mag[i] = opb.read(Util.ilog2(vi.channels));
|
||||
int testA = info.coupling_ang[i] = opb.read(Util.ilog2(vi.channels));
|
||||
|
||||
if (testM < 0 || testA < 0 || testM == testA || testM >= vi.channels || testA >= vi.channels) {
|
||||
// goto err_out;
|
||||
info.free();
|
||||
return (null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (opb.read(2) > 0) { /* 2,3:reserved */
|
||||
info.free();
|
||||
return (null);
|
||||
}
|
||||
|
||||
if (info.submaps > 1) {
|
||||
for (int i = 0; i < vi.channels; i++) {
|
||||
info.chmuxlist[i] = opb.read(4);
|
||||
if (info.chmuxlist[i] >= info.submaps) {
|
||||
info.free();
|
||||
return (null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < info.submaps; i++) {
|
||||
info.timesubmap[i] = opb.read(8);
|
||||
if (info.timesubmap[i] >= vi.times) {
|
||||
info.free();
|
||||
return (null);
|
||||
}
|
||||
info.floorsubmap[i] = opb.read(8);
|
||||
if (info.floorsubmap[i] >= vi.floors) {
|
||||
info.free();
|
||||
return (null);
|
||||
}
|
||||
info.residuesubmap[i] = opb.read(8);
|
||||
if (info.residuesubmap[i] >= vi.residues) {
|
||||
info.free();
|
||||
return (null);
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
float[][] pcmbundle = null;
|
||||
int[] zerobundle = null;
|
||||
int[] nonzero = null;
|
||||
Object[] floormemo = null;
|
||||
|
||||
synchronized int inverse(Block vb, Object l) {
|
||||
DspState vd = vb.vd;
|
||||
Info vi = vd.vi;
|
||||
LookMapping0 look = (LookMapping0) l;
|
||||
InfoMapping0 info = look.map;
|
||||
InfoMode mode = look.mode;
|
||||
int n = vb.pcmend = vi.blocksizes[vb.W];
|
||||
|
||||
float[] window = vd.window[vb.W][vb.lW][vb.nW][mode.windowtype];
|
||||
if (pcmbundle == null || pcmbundle.length < vi.channels) {
|
||||
pcmbundle = new float[vi.channels][];
|
||||
nonzero = new int[vi.channels];
|
||||
zerobundle = new int[vi.channels];
|
||||
floormemo = new Object[vi.channels];
|
||||
}
|
||||
|
||||
// time domain information decode (note that applying the
|
||||
// information would have to happen later; we'll probably add a
|
||||
// function entry to the harness for that later
|
||||
// NOT IMPLEMENTED
|
||||
|
||||
// recover the spectral envelope; store it in the PCM vector for now
|
||||
for (int i = 0; i < vi.channels; i++) {
|
||||
float[] pcm = vb.pcm[i];
|
||||
int submap = info.chmuxlist[i];
|
||||
|
||||
floormemo[i] = look.floor_func[submap].inverse1(vb, look.floor_look[submap], floormemo[i]);
|
||||
if (floormemo[i] != null) {
|
||||
nonzero[i] = 1;
|
||||
} else {
|
||||
nonzero[i] = 0;
|
||||
}
|
||||
for (int j = 0; j < n / 2; j++) {
|
||||
pcm[j] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < info.coupling_steps; i++) {
|
||||
if (nonzero[info.coupling_mag[i]] != 0 || nonzero[info.coupling_ang[i]] != 0) {
|
||||
nonzero[info.coupling_mag[i]] = 1;
|
||||
nonzero[info.coupling_ang[i]] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// recover the residue, apply directly to the spectral envelope
|
||||
|
||||
for (int i = 0; i < info.submaps; i++) {
|
||||
int ch_in_bundle = 0;
|
||||
for (int j = 0; j < vi.channels; j++) {
|
||||
if (info.chmuxlist[j] == i) {
|
||||
if (nonzero[j] != 0) {
|
||||
zerobundle[ch_in_bundle] = 1;
|
||||
} else {
|
||||
zerobundle[ch_in_bundle] = 0;
|
||||
}
|
||||
pcmbundle[ch_in_bundle++] = vb.pcm[j];
|
||||
}
|
||||
}
|
||||
|
||||
look.residue_func[i].inverse(vb, look.residue_look[i], pcmbundle, zerobundle, ch_in_bundle);
|
||||
}
|
||||
|
||||
for (int i = info.coupling_steps - 1; i >= 0; i--) {
|
||||
float[] pcmM = vb.pcm[info.coupling_mag[i]];
|
||||
float[] pcmA = vb.pcm[info.coupling_ang[i]];
|
||||
|
||||
for (int j = 0; j < n / 2; j++) {
|
||||
float mag = pcmM[j];
|
||||
float ang = pcmA[j];
|
||||
|
||||
if (mag > 0) {
|
||||
if (ang > 0) {
|
||||
pcmM[j] = mag;
|
||||
pcmA[j] = mag - ang;
|
||||
} else {
|
||||
pcmA[j] = mag;
|
||||
pcmM[j] = mag + ang;
|
||||
}
|
||||
} else {
|
||||
if (ang > 0) {
|
||||
pcmM[j] = mag;
|
||||
pcmA[j] = mag + ang;
|
||||
} else {
|
||||
pcmA[j] = mag;
|
||||
pcmM[j] = mag - ang;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// /* compute and apply spectral envelope */
|
||||
|
||||
for (int i = 0; i < vi.channels; i++) {
|
||||
float[] pcm = vb.pcm[i];
|
||||
int submap = info.chmuxlist[i];
|
||||
look.floor_func[submap].inverse2(vb, look.floor_look[submap], floormemo[i], pcm);
|
||||
}
|
||||
|
||||
// transform the PCM data; takes PCM vector, vb; modifies PCM vector
|
||||
// only MDCT right now....
|
||||
|
||||
for (int i = 0; i < vi.channels; i++) {
|
||||
float[] pcm = vb.pcm[i];
|
||||
// _analysis_output("out",seq+i,pcm,n/2,0,0);
|
||||
((Mdct) vd.transform[vb.W][0]).backward(pcm, pcm);
|
||||
}
|
||||
|
||||
// now apply the decoded pre-window time information
|
||||
// NOT IMPLEMENTED
|
||||
|
||||
// window the data
|
||||
for (int i = 0; i < vi.channels; i++) {
|
||||
float[] pcm = vb.pcm[i];
|
||||
if (nonzero[i] != 0) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
pcm[j] *= window[j];
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < n; j++) {
|
||||
pcm[j] = 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now apply the decoded post-window time information
|
||||
// NOT IMPLEMENTED
|
||||
// all done!
|
||||
return (0);
|
||||
}
|
||||
|
||||
class InfoMapping0 {
|
||||
int submaps; // <= 16
|
||||
int[] chmuxlist = new int[256]; // up to 256 channels in a Vorbis stream
|
||||
|
||||
int[] timesubmap = new int[16]; // [mux]
|
||||
int[] floorsubmap = new int[16]; // [mux] submap to floors
|
||||
int[] residuesubmap = new int[16];// [mux] submap to residue
|
||||
int[] psysubmap = new int[16]; // [mux]; encode only
|
||||
|
||||
int coupling_steps;
|
||||
int[] coupling_mag = new int[256];
|
||||
int[] coupling_ang = new int[256];
|
||||
|
||||
void free() {
|
||||
chmuxlist = null;
|
||||
timesubmap = null;
|
||||
floorsubmap = null;
|
||||
residuesubmap = null;
|
||||
psysubmap = null;
|
||||
|
||||
coupling_mag = null;
|
||||
coupling_ang = null;
|
||||
}
|
||||
}
|
||||
|
||||
class LookMapping0 {
|
||||
InfoMode mode;
|
||||
InfoMapping0 map;
|
||||
Object[] time_look;
|
||||
Object[] floor_look;
|
||||
Object[] floor_state;
|
||||
Object[] residue_look;
|
||||
PsyLook[] psy_look;
|
||||
|
||||
FuncTime[] time_func;
|
||||
FuncFloor[] floor_func;
|
||||
FuncResidue[] residue_func;
|
||||
|
||||
int ch;
|
||||
float[][] decay;
|
||||
int lastframe; // if a different mode is called, we need to
|
||||
// invalidate decay and floor state
|
||||
}
|
||||
|
||||
}
|
249
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Mdct.java
Normal file
249
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Mdct.java
Normal file
@ -0,0 +1,249 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
class Mdct {
|
||||
|
||||
int n;
|
||||
int log2n;
|
||||
|
||||
float[] trig;
|
||||
int[] bitrev;
|
||||
|
||||
float scale;
|
||||
|
||||
void init(int n) {
|
||||
bitrev = new int[n / 4];
|
||||
trig = new float[n + n / 4];
|
||||
|
||||
log2n = (int) Math.rint(Math.log(n) / Math.log(2));
|
||||
this.n = n;
|
||||
|
||||
int AE = 0;
|
||||
int AO = 1;
|
||||
int BE = AE + n / 2;
|
||||
int BO = BE + 1;
|
||||
int CE = BE + n / 2;
|
||||
int CO = CE + 1;
|
||||
// trig lookups...
|
||||
for (int i = 0; i < n / 4; i++) {
|
||||
trig[AE + i * 2] = (float) Math.cos((Math.PI / n) * (4 * i));
|
||||
trig[AO + i * 2] = (float) -Math.sin((Math.PI / n) * (4 * i));
|
||||
trig[BE + i * 2] = (float) Math.cos((Math.PI / (2 * n)) * (2 * i + 1));
|
||||
trig[BO + i * 2] = (float) Math.sin((Math.PI / (2 * n)) * (2 * i + 1));
|
||||
}
|
||||
for (int i = 0; i < n / 8; i++) {
|
||||
trig[CE + i * 2] = (float) Math.cos((Math.PI / n) * (4 * i + 2));
|
||||
trig[CO + i * 2] = (float) -Math.sin((Math.PI / n) * (4 * i + 2));
|
||||
}
|
||||
|
||||
{
|
||||
int mask = (1 << (log2n - 1)) - 1;
|
||||
int msb = 1 << (log2n - 2);
|
||||
for (int i = 0; i < n / 8; i++) {
|
||||
int acc = 0;
|
||||
for (int j = 0; msb >>> j != 0; j++)
|
||||
if (((msb >>> j) & i) != 0)
|
||||
acc |= 1 << j;
|
||||
bitrev[i * 2] = ((~acc) & mask);
|
||||
// bitrev[i*2]=((~acc)&mask)-1;
|
||||
bitrev[i * 2 + 1] = acc;
|
||||
}
|
||||
}
|
||||
scale = 4.f / n;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
}
|
||||
|
||||
void forward(float[] in, float[] out) {
|
||||
}
|
||||
|
||||
float[] _x = new float[1024];
|
||||
float[] _w = new float[1024];
|
||||
|
||||
synchronized void backward(float[] in, float[] out) {
|
||||
if (_x.length < n / 2) {
|
||||
_x = new float[n / 2];
|
||||
}
|
||||
if (_w.length < n / 2) {
|
||||
_w = new float[n / 2];
|
||||
}
|
||||
float[] x = _x;
|
||||
float[] w = _w;
|
||||
int n2 = n >>> 1;
|
||||
int n4 = n >>> 2;
|
||||
int n8 = n >>> 3;
|
||||
|
||||
// rotate + step 1
|
||||
{
|
||||
int inO = 1;
|
||||
int xO = 0;
|
||||
int A = n2;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < n8; i++) {
|
||||
A -= 2;
|
||||
x[xO++] = -in[inO + 2] * trig[A + 1] - in[inO] * trig[A];
|
||||
x[xO++] = in[inO] * trig[A + 1] - in[inO + 2] * trig[A];
|
||||
inO += 4;
|
||||
}
|
||||
|
||||
inO = n2 - 4;
|
||||
|
||||
for (i = 0; i < n8; i++) {
|
||||
A -= 2;
|
||||
x[xO++] = in[inO] * trig[A + 1] + in[inO + 2] * trig[A];
|
||||
x[xO++] = in[inO] * trig[A] - in[inO + 2] * trig[A + 1];
|
||||
inO -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
float[] xxx = mdct_kernel(x, w, n, n2, n4, n8);
|
||||
int xx = 0;
|
||||
|
||||
// step 8
|
||||
|
||||
{
|
||||
int B = n2;
|
||||
int o1 = n4, o2 = o1 - 1;
|
||||
int o3 = n4 + n2, o4 = o3 - 1;
|
||||
|
||||
for (int i = 0; i < n4; i++) {
|
||||
float temp1 = (xxx[xx] * trig[B + 1] - xxx[xx + 1] * trig[B]);
|
||||
float temp2 = -(xxx[xx] * trig[B] + xxx[xx + 1] * trig[B + 1]);
|
||||
|
||||
out[o1] = -temp1;
|
||||
out[o2] = temp1;
|
||||
out[o3] = temp2;
|
||||
out[o4] = temp2;
|
||||
|
||||
o1++;
|
||||
o2--;
|
||||
o3++;
|
||||
o4--;
|
||||
xx += 2;
|
||||
B += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float[] mdct_kernel(float[] x, float[] w, int n, int n2, int n4, int n8) {
|
||||
// step 2
|
||||
|
||||
int xA = n4;
|
||||
int xB = 0;
|
||||
int w2 = n4;
|
||||
int A = n2;
|
||||
|
||||
for (int i = 0; i < n4;) {
|
||||
float x0 = x[xA] - x[xB];
|
||||
float x1;
|
||||
w[w2 + i] = x[xA++] + x[xB++];
|
||||
|
||||
x1 = x[xA] - x[xB];
|
||||
A -= 4;
|
||||
|
||||
w[i++] = x0 * trig[A] + x1 * trig[A + 1];
|
||||
w[i] = x1 * trig[A] - x0 * trig[A + 1];
|
||||
|
||||
w[w2 + i] = x[xA++] + x[xB++];
|
||||
i++;
|
||||
}
|
||||
|
||||
// step 3
|
||||
|
||||
{
|
||||
for (int i = 0; i < log2n - 3; i++) {
|
||||
int k0 = n >>> (i + 2);
|
||||
int k1 = 1 << (i + 3);
|
||||
int wbase = n2 - 2;
|
||||
|
||||
A = 0;
|
||||
float[] temp;
|
||||
|
||||
for (int r = 0; r < (k0 >>> 2); r++) {
|
||||
int w1 = wbase;
|
||||
w2 = w1 - (k0 >> 1);
|
||||
float AEv = trig[A], wA;
|
||||
float AOv = trig[A + 1], wB;
|
||||
wbase -= 2;
|
||||
|
||||
k0++;
|
||||
for (int s = 0; s < (2 << i); s++) {
|
||||
wB = w[w1] - w[w2];
|
||||
x[w1] = w[w1] + w[w2];
|
||||
|
||||
wA = w[++w1] - w[++w2];
|
||||
x[w1] = w[w1] + w[w2];
|
||||
|
||||
x[w2] = wA * AEv - wB * AOv;
|
||||
x[w2 - 1] = wB * AEv + wA * AOv;
|
||||
|
||||
w1 -= k0;
|
||||
w2 -= k0;
|
||||
}
|
||||
k0--;
|
||||
A += k1;
|
||||
}
|
||||
|
||||
temp = w;
|
||||
w = x;
|
||||
x = temp;
|
||||
}
|
||||
}
|
||||
|
||||
// step 4, 5, 6, 7
|
||||
{
|
||||
int C = n;
|
||||
int bit = 0;
|
||||
int x1 = 0;
|
||||
int x2 = n2 - 1;
|
||||
|
||||
for (int i = 0; i < n8; i++) {
|
||||
int t1 = bitrev[bit++];
|
||||
int t2 = bitrev[bit++];
|
||||
|
||||
float wA = w[t1] - w[t2 + 1];
|
||||
float wB = w[t1 - 1] + w[t2];
|
||||
float wC = w[t1] + w[t2 + 1];
|
||||
float wD = w[t1 - 1] - w[t2];
|
||||
|
||||
float wACE = wA * trig[C];
|
||||
float wBCE = wB * trig[C++];
|
||||
float wACO = wA * trig[C];
|
||||
float wBCO = wB * trig[C++];
|
||||
|
||||
x[x1++] = (wC + wACO + wBCE) * .5f;
|
||||
x[x2--] = (-wD + wBCO - wACE) * .5f;
|
||||
x[x1++] = (wD + wBCO - wACE) * .5f;
|
||||
x[x2--] = (wC - wACO - wBCE) * .5f;
|
||||
}
|
||||
}
|
||||
return (x);
|
||||
}
|
||||
}
|
74
sources/wasm-gc-teavm/java/com/jcraft/jorbis/PsyInfo.java
Normal file
74
sources/wasm-gc-teavm/java/com/jcraft/jorbis/PsyInfo.java
Normal file
@ -0,0 +1,74 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
// psychoacoustic setup
|
||||
class PsyInfo {
|
||||
int athp;
|
||||
int decayp;
|
||||
int smoothp;
|
||||
int noisefitp;
|
||||
int noisefit_subblock;
|
||||
float noisefit_threshdB;
|
||||
|
||||
float ath_att;
|
||||
|
||||
int tonemaskp;
|
||||
float[] toneatt_125Hz = new float[5];
|
||||
float[] toneatt_250Hz = new float[5];
|
||||
float[] toneatt_500Hz = new float[5];
|
||||
float[] toneatt_1000Hz = new float[5];
|
||||
float[] toneatt_2000Hz = new float[5];
|
||||
float[] toneatt_4000Hz = new float[5];
|
||||
float[] toneatt_8000Hz = new float[5];
|
||||
|
||||
int peakattp;
|
||||
float[] peakatt_125Hz = new float[5];
|
||||
float[] peakatt_250Hz = new float[5];
|
||||
float[] peakatt_500Hz = new float[5];
|
||||
float[] peakatt_1000Hz = new float[5];
|
||||
float[] peakatt_2000Hz = new float[5];
|
||||
float[] peakatt_4000Hz = new float[5];
|
||||
float[] peakatt_8000Hz = new float[5];
|
||||
|
||||
int noisemaskp;
|
||||
float[] noiseatt_125Hz = new float[5];
|
||||
float[] noiseatt_250Hz = new float[5];
|
||||
float[] noiseatt_500Hz = new float[5];
|
||||
float[] noiseatt_1000Hz = new float[5];
|
||||
float[] noiseatt_2000Hz = new float[5];
|
||||
float[] noiseatt_4000Hz = new float[5];
|
||||
float[] noiseatt_8000Hz = new float[5];
|
||||
|
||||
float max_curve_dB;
|
||||
|
||||
float attack_coeff;
|
||||
float decay_coeff;
|
||||
|
||||
void free() {
|
||||
}
|
||||
}
|
42
sources/wasm-gc-teavm/java/com/jcraft/jorbis/PsyLook.java
Normal file
42
sources/wasm-gc-teavm/java/com/jcraft/jorbis/PsyLook.java
Normal file
@ -0,0 +1,42 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
class PsyLook {
|
||||
int n;
|
||||
PsyInfo vi;
|
||||
|
||||
float[][][] tonecurves;
|
||||
float[][] peakatt;
|
||||
float[][][] noisecurves;
|
||||
|
||||
float[] ath;
|
||||
int[] octave;
|
||||
|
||||
void init(PsyInfo vi, int n, int rate) {
|
||||
}
|
||||
}
|
326
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Residue0.java
Normal file
326
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Residue0.java
Normal file
@ -0,0 +1,326 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
import com.jcraft.jogg.*;
|
||||
|
||||
class Residue0 extends FuncResidue {
|
||||
void pack(Object vr, Buffer opb) {
|
||||
InfoResidue0 info = (InfoResidue0) vr;
|
||||
int acc = 0;
|
||||
opb.write(info.begin, 24);
|
||||
opb.write(info.end, 24);
|
||||
|
||||
opb.write(info.grouping - 1, 24); /*
|
||||
* residue vectors to group and code with a partitioned book
|
||||
*/
|
||||
opb.write(info.partitions - 1, 6); /* possible partition choices */
|
||||
opb.write(info.groupbook, 8); /* group huffman book */
|
||||
|
||||
/*
|
||||
* secondstages is a bitmask; as encoding progresses pass by pass, a bitmask of
|
||||
* one indicates this partition class has bits to write this pass
|
||||
*/
|
||||
for (int j = 0; j < info.partitions; j++) {
|
||||
int i = info.secondstages[j];
|
||||
if (Util.ilog(i) > 3) {
|
||||
/* yes, this is a minor hack due to not thinking ahead */
|
||||
opb.write(i, 3);
|
||||
opb.write(1, 1);
|
||||
opb.write(i >>> 3, 5);
|
||||
} else {
|
||||
opb.write(i, 4); /* trailing zero */
|
||||
}
|
||||
acc += Util.icount(i);
|
||||
}
|
||||
for (int j = 0; j < acc; j++) {
|
||||
opb.write(info.booklist[j], 8);
|
||||
}
|
||||
}
|
||||
|
||||
Object unpack(Info vi, Buffer opb) {
|
||||
int acc = 0;
|
||||
InfoResidue0 info = new InfoResidue0();
|
||||
info.begin = opb.read(24);
|
||||
info.end = opb.read(24);
|
||||
info.grouping = opb.read(24) + 1;
|
||||
info.partitions = opb.read(6) + 1;
|
||||
info.groupbook = opb.read(8);
|
||||
|
||||
for (int j = 0; j < info.partitions; j++) {
|
||||
int cascade = opb.read(3);
|
||||
if (opb.read(1) != 0) {
|
||||
cascade |= (opb.read(5) << 3);
|
||||
}
|
||||
info.secondstages[j] = cascade;
|
||||
acc += Util.icount(cascade);
|
||||
}
|
||||
|
||||
for (int j = 0; j < acc; j++) {
|
||||
info.booklist[j] = opb.read(8);
|
||||
}
|
||||
|
||||
if (info.groupbook >= vi.books) {
|
||||
free_info(info);
|
||||
return (null);
|
||||
}
|
||||
|
||||
for (int j = 0; j < acc; j++) {
|
||||
if (info.booklist[j] >= vi.books) {
|
||||
free_info(info);
|
||||
return (null);
|
||||
}
|
||||
}
|
||||
return (info);
|
||||
}
|
||||
|
||||
Object look(DspState vd, InfoMode vm, Object vr) {
|
||||
InfoResidue0 info = (InfoResidue0) vr;
|
||||
LookResidue0 look = new LookResidue0();
|
||||
int acc = 0;
|
||||
int dim;
|
||||
int maxstage = 0;
|
||||
look.info = info;
|
||||
look.map = vm.mapping;
|
||||
|
||||
look.parts = info.partitions;
|
||||
look.fullbooks = vd.fullbooks;
|
||||
look.phrasebook = vd.fullbooks[info.groupbook];
|
||||
|
||||
dim = look.phrasebook.dim;
|
||||
|
||||
look.partbooks = new int[look.parts][];
|
||||
|
||||
for (int j = 0; j < look.parts; j++) {
|
||||
int i = info.secondstages[j];
|
||||
int stages = Util.ilog(i);
|
||||
if (stages != 0) {
|
||||
if (stages > maxstage)
|
||||
maxstage = stages;
|
||||
look.partbooks[j] = new int[stages];
|
||||
for (int k = 0; k < stages; k++) {
|
||||
if ((i & (1 << k)) != 0) {
|
||||
look.partbooks[j][k] = info.booklist[acc++];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
look.partvals = (int) Math.rint(Math.pow(look.parts, dim));
|
||||
look.stages = maxstage;
|
||||
look.decodemap = new int[look.partvals][];
|
||||
for (int j = 0; j < look.partvals; j++) {
|
||||
int val = j;
|
||||
int mult = look.partvals / look.parts;
|
||||
look.decodemap[j] = new int[dim];
|
||||
|
||||
for (int k = 0; k < dim; k++) {
|
||||
int deco = val / mult;
|
||||
val -= deco * mult;
|
||||
mult /= look.parts;
|
||||
look.decodemap[j][k] = deco;
|
||||
}
|
||||
}
|
||||
return (look);
|
||||
}
|
||||
|
||||
void free_info(Object i) {
|
||||
}
|
||||
|
||||
void free_look(Object i) {
|
||||
}
|
||||
|
||||
private static int[][][] _01inverse_partword = new int[2][][]; // _01inverse is synchronized for
|
||||
|
||||
// re-using partword
|
||||
synchronized static int _01inverse(Block vb, Object vl, float[][] in, int ch, int decodepart) {
|
||||
int i, j, k, l, s;
|
||||
LookResidue0 look = (LookResidue0) vl;
|
||||
InfoResidue0 info = look.info;
|
||||
|
||||
// move all this setup out later
|
||||
int samples_per_partition = info.grouping;
|
||||
int partitions_per_word = look.phrasebook.dim;
|
||||
int n = info.end - info.begin;
|
||||
|
||||
int partvals = n / samples_per_partition;
|
||||
int partwords = (partvals + partitions_per_word - 1) / partitions_per_word;
|
||||
|
||||
if (_01inverse_partword.length < ch) {
|
||||
_01inverse_partword = new int[ch][][];
|
||||
}
|
||||
|
||||
for (j = 0; j < ch; j++) {
|
||||
if (_01inverse_partword[j] == null || _01inverse_partword[j].length < partwords) {
|
||||
_01inverse_partword[j] = new int[partwords][];
|
||||
}
|
||||
}
|
||||
|
||||
for (s = 0; s < look.stages; s++) {
|
||||
// each loop decodes on partition codeword containing
|
||||
// partitions_pre_word partitions
|
||||
for (i = 0, l = 0; i < partvals; l++) {
|
||||
if (s == 0) {
|
||||
// fetch the partition word for each channel
|
||||
for (j = 0; j < ch; j++) {
|
||||
int temp = look.phrasebook.decode(vb.opb);
|
||||
if (temp == -1) {
|
||||
return (0);
|
||||
}
|
||||
_01inverse_partword[j][l] = look.decodemap[temp];
|
||||
if (_01inverse_partword[j][l] == null) {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now we decode residual values for the partitions
|
||||
for (k = 0; k < partitions_per_word && i < partvals; k++, i++)
|
||||
for (j = 0; j < ch; j++) {
|
||||
int offset = info.begin + i * samples_per_partition;
|
||||
int index = _01inverse_partword[j][l][k];
|
||||
if ((info.secondstages[index] & (1 << s)) != 0) {
|
||||
CodeBook stagebook = look.fullbooks[look.partbooks[index][s]];
|
||||
if (stagebook != null) {
|
||||
if (decodepart == 0) {
|
||||
if (stagebook.decodevs_add(in[j], offset, vb.opb, samples_per_partition) == -1) {
|
||||
return (0);
|
||||
}
|
||||
} else if (decodepart == 1) {
|
||||
if (stagebook.decodev_add(in[j], offset, vb.opb, samples_per_partition) == -1) {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int[][] _2inverse_partword = null;
|
||||
|
||||
synchronized static int _2inverse(Block vb, Object vl, float[][] in, int ch) {
|
||||
int i, k, l, s;
|
||||
LookResidue0 look = (LookResidue0) vl;
|
||||
InfoResidue0 info = look.info;
|
||||
|
||||
// move all this setup out later
|
||||
int samples_per_partition = info.grouping;
|
||||
int partitions_per_word = look.phrasebook.dim;
|
||||
int n = info.end - info.begin;
|
||||
|
||||
int partvals = n / samples_per_partition;
|
||||
int partwords = (partvals + partitions_per_word - 1) / partitions_per_word;
|
||||
|
||||
if (_2inverse_partword == null || _2inverse_partword.length < partwords) {
|
||||
_2inverse_partword = new int[partwords][];
|
||||
}
|
||||
for (s = 0; s < look.stages; s++) {
|
||||
for (i = 0, l = 0; i < partvals; l++) {
|
||||
if (s == 0) {
|
||||
// fetch the partition word for each channel
|
||||
int temp = look.phrasebook.decode(vb.opb);
|
||||
if (temp == -1) {
|
||||
return (0);
|
||||
}
|
||||
_2inverse_partword[l] = look.decodemap[temp];
|
||||
if (_2inverse_partword[l] == null) {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
// now we decode residual values for the partitions
|
||||
for (k = 0; k < partitions_per_word && i < partvals; k++, i++) {
|
||||
int offset = info.begin + i * samples_per_partition;
|
||||
int index = _2inverse_partword[l][k];
|
||||
if ((info.secondstages[index] & (1 << s)) != 0) {
|
||||
CodeBook stagebook = look.fullbooks[look.partbooks[index][s]];
|
||||
if (stagebook != null) {
|
||||
if (stagebook.decodevv_add(in, offset, ch, vb.opb, samples_per_partition) == -1) {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int inverse(Block vb, Object vl, float[][] in, int[] nonzero, int ch) {
|
||||
int used = 0;
|
||||
for (int i = 0; i < ch; i++) {
|
||||
if (nonzero[i] != 0) {
|
||||
in[used++] = in[i];
|
||||
}
|
||||
}
|
||||
if (used != 0)
|
||||
return (_01inverse(vb, vl, in, used, 0));
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
class LookResidue0 {
|
||||
InfoResidue0 info;
|
||||
int map;
|
||||
|
||||
int parts;
|
||||
int stages;
|
||||
CodeBook[] fullbooks;
|
||||
CodeBook phrasebook;
|
||||
int[][] partbooks;
|
||||
|
||||
int partvals;
|
||||
int[][] decodemap;
|
||||
|
||||
int postbits;
|
||||
int phrasebits;
|
||||
int frames;
|
||||
}
|
||||
|
||||
class InfoResidue0 {
|
||||
// block-partitioned VQ coded straight residue
|
||||
int begin;
|
||||
int end;
|
||||
|
||||
// first stage (lossless partitioning)
|
||||
int grouping; // group n vectors per partition
|
||||
int partitions; // possible codebooks for a partition
|
||||
int groupbook; // huffbook for partitioning
|
||||
int[] secondstages = new int[64]; // expanded out to pointers in lookup
|
||||
int[] booklist = new int[256]; // list of second stage books
|
||||
|
||||
// encode-only heuristic settings
|
||||
float[] entmax = new float[64]; // book entropy threshholds
|
||||
float[] ampmax = new float[64]; // book amp threshholds
|
||||
int[] subgrp = new int[64]; // book heuristic subgroup size
|
||||
int[] blimit = new int[64]; // subgroup position limits
|
||||
}
|
||||
|
||||
}
|
44
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Residue1.java
Normal file
44
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Residue1.java
Normal file
@ -0,0 +1,44 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
class Residue1 extends Residue0 {
|
||||
|
||||
int inverse(Block vb, Object vl, float[][] in, int[] nonzero, int ch) {
|
||||
int used = 0;
|
||||
for (int i = 0; i < ch; i++) {
|
||||
if (nonzero[i] != 0) {
|
||||
in[used++] = in[i];
|
||||
}
|
||||
}
|
||||
if (used != 0) {
|
||||
return (_01inverse(vb, vl, in, used, 1));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
41
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Residue2.java
Normal file
41
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Residue2.java
Normal file
@ -0,0 +1,41 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
class Residue2 extends Residue0 {
|
||||
|
||||
int inverse(Block vb, Object vl, float[][] in, int[] nonzero, int ch) {
|
||||
int i = 0;
|
||||
for (i = 0; i < ch; i++)
|
||||
if (nonzero[i] != 0)
|
||||
break;
|
||||
if (i == ch)
|
||||
return (0); /* no nonzero vectors */
|
||||
|
||||
return (_2inverse(vb, vl, in, ch));
|
||||
}
|
||||
}
|
436
sources/wasm-gc-teavm/java/com/jcraft/jorbis/StaticCodeBook.java
Normal file
436
sources/wasm-gc-teavm/java/com/jcraft/jorbis/StaticCodeBook.java
Normal file
@ -0,0 +1,436 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
import com.jcraft.jogg.*;
|
||||
|
||||
class StaticCodeBook {
|
||||
int dim; // codebook dimensions (elements per vector)
|
||||
int entries; // codebook entries
|
||||
int[] lengthlist; // codeword lengths in bits
|
||||
|
||||
// mapping
|
||||
int maptype; // 0=none
|
||||
// 1=implicitly populated values from map column
|
||||
// 2=listed arbitrary values
|
||||
|
||||
// The below does a linear, single monotonic sequence mapping.
|
||||
int q_min; // packed 32 bit float; quant value 0 maps to minval
|
||||
int q_delta; // packed 32 bit float; val 1 - val 0 == delta
|
||||
int q_quant; // bits: 0 < quant <= 16
|
||||
int q_sequencep; // bitflag
|
||||
|
||||
// additional information for log (dB) mapping; the linear mapping
|
||||
// is assumed to actually be values in dB. encodebias is used to
|
||||
// assign an error weight to 0 dB. We have two additional flags:
|
||||
// zeroflag indicates if entry zero is to represent -Inf dB; negflag
|
||||
// indicates if we're to represent negative linear values in a
|
||||
// mirror of the positive mapping.
|
||||
|
||||
int[] quantlist; // map == 1: (int)(entries/dim) element column map
|
||||
// map == 2: list of dim*entries quantized entry vals
|
||||
|
||||
StaticCodeBook() {
|
||||
}
|
||||
|
||||
int pack(Buffer opb) {
|
||||
int i;
|
||||
boolean ordered = false;
|
||||
|
||||
opb.write(0x564342, 24);
|
||||
opb.write(dim, 16);
|
||||
opb.write(entries, 24);
|
||||
|
||||
// pack the codewords. There are two packings; length ordered and
|
||||
// length random. Decide between the two now.
|
||||
|
||||
for (i = 1; i < entries; i++) {
|
||||
if (lengthlist[i] < lengthlist[i - 1])
|
||||
break;
|
||||
}
|
||||
if (i == entries)
|
||||
ordered = true;
|
||||
|
||||
if (ordered) {
|
||||
// length ordered. We only need to say how many codewords of
|
||||
// each length. The actual codewords are generated
|
||||
// deterministically
|
||||
|
||||
int count = 0;
|
||||
opb.write(1, 1); // ordered
|
||||
opb.write(lengthlist[0] - 1, 5); // 1 to 32
|
||||
|
||||
for (i = 1; i < entries; i++) {
|
||||
int _this = lengthlist[i];
|
||||
int _last = lengthlist[i - 1];
|
||||
if (_this > _last) {
|
||||
for (int j = _last; j < _this; j++) {
|
||||
opb.write(i - count, Util.ilog(entries - count));
|
||||
count = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
opb.write(i - count, Util.ilog(entries - count));
|
||||
} else {
|
||||
// length random. Again, we don't code the codeword itself, just
|
||||
// the length. This time, though, we have to encode each length
|
||||
opb.write(0, 1); // unordered
|
||||
|
||||
// algortihmic mapping has use for 'unused entries', which we tag
|
||||
// here. The algorithmic mapping happens as usual, but the unused
|
||||
// entry has no codeword.
|
||||
for (i = 0; i < entries; i++) {
|
||||
if (lengthlist[i] == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == entries) {
|
||||
opb.write(0, 1); // no unused entries
|
||||
for (i = 0; i < entries; i++) {
|
||||
opb.write(lengthlist[i] - 1, 5);
|
||||
}
|
||||
} else {
|
||||
opb.write(1, 1); // we have unused entries; thus we tag
|
||||
for (i = 0; i < entries; i++) {
|
||||
if (lengthlist[i] == 0) {
|
||||
opb.write(0, 1);
|
||||
} else {
|
||||
opb.write(1, 1);
|
||||
opb.write(lengthlist[i] - 1, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// is the entry number the desired return value, or do we have a
|
||||
// mapping? If we have a mapping, what type?
|
||||
opb.write(maptype, 4);
|
||||
switch (maptype) {
|
||||
case 0:
|
||||
// no mapping
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
// implicitly populated value mapping
|
||||
// explicitly populated value mapping
|
||||
if (quantlist == null) {
|
||||
// no quantlist? error
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// values that define the dequantization
|
||||
opb.write(q_min, 32);
|
||||
opb.write(q_delta, 32);
|
||||
opb.write(q_quant - 1, 4);
|
||||
opb.write(q_sequencep, 1);
|
||||
|
||||
{
|
||||
int quantvals = 0;
|
||||
switch (maptype) {
|
||||
case 1:
|
||||
// a single column of (c->entries/c->dim) quantized values for
|
||||
// building a full value list algorithmically (square lattice)
|
||||
quantvals = maptype1_quantvals();
|
||||
break;
|
||||
case 2:
|
||||
// every value (c->entries*c->dim total) specified explicitly
|
||||
quantvals = entries * dim;
|
||||
break;
|
||||
}
|
||||
|
||||
// quantized values
|
||||
for (i = 0; i < quantvals; i++) {
|
||||
opb.write(Math.abs(quantlist[i]), q_quant);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// error case; we don't have any other map types now
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
// unpacks a codebook from the packet buffer into the codebook struct,
|
||||
// readies the codebook auxiliary structures for decode
|
||||
int unpack(Buffer opb) {
|
||||
int i;
|
||||
// memset(s,0,sizeof(static_codebook));
|
||||
|
||||
// make sure alignment is correct
|
||||
if (opb.read(24) != 0x564342) {
|
||||
// goto _eofout;
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// first the basic parameters
|
||||
dim = opb.read(16);
|
||||
entries = opb.read(24);
|
||||
if (entries == -1) {
|
||||
// goto _eofout;
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// codeword ordering.... length ordered or unordered?
|
||||
switch (opb.read(1)) {
|
||||
case 0:
|
||||
// unordered
|
||||
lengthlist = new int[entries];
|
||||
|
||||
// allocated but unused entries?
|
||||
if (opb.read(1) != 0) {
|
||||
// yes, unused entries
|
||||
|
||||
for (i = 0; i < entries; i++) {
|
||||
if (opb.read(1) != 0) {
|
||||
int num = opb.read(5);
|
||||
if (num == -1) {
|
||||
// goto _eofout;
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
lengthlist[i] = num + 1;
|
||||
} else {
|
||||
lengthlist[i] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// all entries used; no tagging
|
||||
for (i = 0; i < entries; i++) {
|
||||
int num = opb.read(5);
|
||||
if (num == -1) {
|
||||
// goto _eofout;
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
lengthlist[i] = num + 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// ordered
|
||||
{
|
||||
int length = opb.read(5) + 1;
|
||||
lengthlist = new int[entries];
|
||||
|
||||
for (i = 0; i < entries;) {
|
||||
int num = opb.read(Util.ilog(entries - i));
|
||||
if (num == -1) {
|
||||
// goto _eofout;
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
for (int j = 0; j < num; j++, i++) {
|
||||
lengthlist[i] = length;
|
||||
}
|
||||
length++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// EOF
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// Do we have a mapping to unpack?
|
||||
switch ((maptype = opb.read(4))) {
|
||||
case 0:
|
||||
// no mapping
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
// implicitly populated value mapping
|
||||
// explicitly populated value mapping
|
||||
q_min = opb.read(32);
|
||||
q_delta = opb.read(32);
|
||||
q_quant = opb.read(4) + 1;
|
||||
q_sequencep = opb.read(1);
|
||||
|
||||
{
|
||||
int quantvals = 0;
|
||||
switch (maptype) {
|
||||
case 1:
|
||||
quantvals = maptype1_quantvals();
|
||||
break;
|
||||
case 2:
|
||||
quantvals = entries * dim;
|
||||
break;
|
||||
}
|
||||
|
||||
// quantized values
|
||||
quantlist = new int[quantvals];
|
||||
for (i = 0; i < quantvals; i++) {
|
||||
quantlist[i] = opb.read(q_quant);
|
||||
}
|
||||
if (quantlist[quantvals - 1] == -1) {
|
||||
// goto _eofout;
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// goto _eofout;
|
||||
clear();
|
||||
return (-1);
|
||||
}
|
||||
// all set
|
||||
return (0);
|
||||
// _errout:
|
||||
// _eofout:
|
||||
// vorbis_staticbook_clear(s);
|
||||
// return(-1);
|
||||
}
|
||||
|
||||
// there might be a straightforward one-line way to do the below
|
||||
// that's portable and totally safe against roundoff, but I haven't
|
||||
// thought of it. Therefore, we opt on the side of caution
|
||||
private int maptype1_quantvals() {
|
||||
int vals = (int) (Math.floor(Math.pow(entries, 1. / dim)));
|
||||
|
||||
// the above *should* be reliable, but we'll not assume that FP is
|
||||
// ever reliable when bitstream sync is at stake; verify via integer
|
||||
// means that vals really is the greatest value of dim for which
|
||||
// vals^b->bim <= b->entries
|
||||
// treat the above as an initial guess
|
||||
while (true) {
|
||||
int acc = 1;
|
||||
int acc1 = 1;
|
||||
for (int i = 0; i < dim; i++) {
|
||||
acc *= vals;
|
||||
acc1 *= vals + 1;
|
||||
}
|
||||
if (acc <= entries && acc1 > entries) {
|
||||
return (vals);
|
||||
} else {
|
||||
if (acc > entries) {
|
||||
vals--;
|
||||
} else {
|
||||
vals++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
}
|
||||
|
||||
// unpack the quantized list of values for encode/decode
|
||||
// we need to deal with two map types: in map type 1, the values are
|
||||
// generated algorithmically (each column of the vector counts through
|
||||
// the values in the quant vector). in map type 2, all the values came
|
||||
// in in an explicit list. Both value lists must be unpacked
|
||||
float[] unquantize() {
|
||||
|
||||
if (maptype == 1 || maptype == 2) {
|
||||
int quantvals;
|
||||
float mindel = float32_unpack(q_min);
|
||||
float delta = float32_unpack(q_delta);
|
||||
float[] r = new float[entries * dim];
|
||||
|
||||
// maptype 1 and 2 both use a quantized value vector, but
|
||||
// different sizes
|
||||
switch (maptype) {
|
||||
case 1:
|
||||
// most of the time, entries%dimensions == 0, but we need to be
|
||||
// well defined. We define that the possible vales at each
|
||||
// scalar is values == entries/dim. If entries%dim != 0, we'll
|
||||
// have 'too few' values (values*dim<entries), which means that
|
||||
// we'll have 'left over' entries; left over entries use zeroed
|
||||
// values (and are wasted). So don't generate codebooks like that
|
||||
quantvals = maptype1_quantvals();
|
||||
for (int j = 0; j < entries; j++) {
|
||||
float last = 0.f;
|
||||
int indexdiv = 1;
|
||||
for (int k = 0; k < dim; k++) {
|
||||
int index = (j / indexdiv) % quantvals;
|
||||
float val = quantlist[index];
|
||||
val = Math.abs(val) * delta + mindel + last;
|
||||
if (q_sequencep != 0)
|
||||
last = val;
|
||||
r[j * dim + k] = val;
|
||||
indexdiv *= quantvals;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (int j = 0; j < entries; j++) {
|
||||
float last = 0.f;
|
||||
for (int k = 0; k < dim; k++) {
|
||||
float val = quantlist[j * dim + k];
|
||||
// if((j*dim+k)==0){System.err.println(" | 0 -> "+val+" | ");}
|
||||
val = Math.abs(val) * delta + mindel + last;
|
||||
if (q_sequencep != 0)
|
||||
last = val;
|
||||
r[j * dim + k] = val;
|
||||
// if((j*dim+k)==0){System.err.println(" $ r[0] -> "+r[0]+" | ");}
|
||||
}
|
||||
}
|
||||
// System.err.println("\nr[0]="+r[0]);
|
||||
}
|
||||
return (r);
|
||||
}
|
||||
return (null);
|
||||
}
|
||||
|
||||
// 32 bit float (not IEEE; nonnormalized mantissa +
|
||||
// biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm
|
||||
// Why not IEEE? It's just not that important here.
|
||||
|
||||
static final int VQ_FEXP = 10;
|
||||
static final int VQ_FMAN = 21;
|
||||
static final int VQ_FEXP_BIAS = 768; // bias toward values smaller than 1.
|
||||
|
||||
// doesn't currently guard under/overflow
|
||||
static long float32_pack(float val) {
|
||||
int sign = 0;
|
||||
int exp;
|
||||
int mant;
|
||||
if (val < 0) {
|
||||
sign = 0x80000000;
|
||||
val = -val;
|
||||
}
|
||||
exp = (int) Math.floor(Math.log(val) / Math.log(2));
|
||||
mant = (int) Math.rint(Math.pow(val, (VQ_FMAN - 1) - exp));
|
||||
exp = (exp + VQ_FEXP_BIAS) << VQ_FMAN;
|
||||
return (sign | exp | mant);
|
||||
}
|
||||
|
||||
static float float32_unpack(int val) {
|
||||
float mant = val & 0x1fffff;
|
||||
float exp = (val & 0x7fe00000) >>> VQ_FMAN;
|
||||
if ((val & 0x80000000) != 0)
|
||||
mant = -mant;
|
||||
return (ldexp(mant, ((int) exp) - (VQ_FMAN - 1) - VQ_FEXP_BIAS));
|
||||
}
|
||||
|
||||
static float ldexp(float foo, int e) {
|
||||
return (float) (foo * Math.pow(2, e));
|
||||
}
|
||||
}
|
52
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Time0.java
Normal file
52
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Time0.java
Normal file
@ -0,0 +1,52 @@
|
||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
|
||||
/* JOrbis
|
||||
* Copyright (C) 2000 ymnk, JCraft,Inc.
|
||||
*
|
||||
* Written by: 2000 ymnk<ymnk@jcraft.com>
|
||||
*
|
||||
* Many thanks to
|
||||
* Monty <monty@xiph.org> and
|
||||
* The XIPHOPHORUS Company http://www.xiph.org/ .
|
||||
* JOrbis has been based on their awesome works, Vorbis codec.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
import com.jcraft.jogg.*;
|
||||
|
||||
class Time0 extends FuncTime {
|
||||
void pack(Object i, Buffer opb) {
|
||||
}
|
||||
|
||||
Object unpack(Info vi, Buffer opb) {
|
||||
return "";
|
||||
}
|
||||
|
||||
Object look(DspState vd, InfoMode mi, Object i) {
|
||||
return "";
|
||||
}
|
||||
|
||||
void free_info(Object i) {
|
||||
}
|
||||
|
||||
void free_look(Object i) {
|
||||
}
|
||||
|
||||
int inverse(Block vb, Object i, float[] in, float[] out) {
|
||||
return 0;
|
||||
}
|
||||
}
|
30
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Util.java
Normal file
30
sources/wasm-gc-teavm/java/com/jcraft/jorbis/Util.java
Normal file
@ -0,0 +1,30 @@
|
||||
package com.jcraft.jorbis;
|
||||
|
||||
class Util {
|
||||
static int ilog(int v) {
|
||||
int ret = 0;
|
||||
while (v != 0) {
|
||||
ret++;
|
||||
v >>>= 1;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int ilog2(int v) {
|
||||
int ret = 0;
|
||||
while (v > 1) {
|
||||
ret++;
|
||||
v >>>= 1;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int icount(int v) {
|
||||
int ret = 0;
|
||||
while (v != 0) {
|
||||
ret += (v & 1);
|
||||
v >>>= 1;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
}
|
1348
sources/wasm-gc-teavm/java/com/jcraft/jorbis/VorbisFile.java
Normal file
1348
sources/wasm-gc-teavm/java/com/jcraft/jorbis/VorbisFile.java
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user