From 073f29c3b0968a2f4d00413be9f99bce022016b8 Mon Sep 17 00:00:00 2001 From: Alex Iadicicco Date: Thu, 8 Dec 2022 03:18:26 -0800 Subject: [PATCH] Significant Vorbis decoder progress --- src/main/java/funorb/audio/SoundLoader.java | 8 +- src/main/java/funorb/audio/Synth.java | 16 +- .../audio/{FmtSynth.java => SynthFormat.java} | 8 +- src/main/java/funorb/audio/SynthMystery.java | 56 +-- .../java/funorb/audio/VorbisCodebook.java | 224 ++++++++++ src/main/java/funorb/audio/VorbisFloor1.java | 364 ++++++++++++++++ .../{FmtVorbis.java => VorbisFormat.java} | 409 ++++++++---------- src/main/java/funorb/audio/VorbisMapping.java | 35 ++ .../java/funorb/audio/VorbisResidues.java | 112 +++++ src/main/java/funorb/audio/fq_.java | 31 -- src/main/java/funorb/audio/kn_.java | 357 --------------- src/main/java/funorb/audio/to_.java | 113 ----- src/main/java/funorb/audio/vb_.java | 232 ---------- .../client/intro/JagexLogoIntroAnimation.java | 6 +- 14 files changed, 973 insertions(+), 998 deletions(-) rename src/main/java/funorb/audio/{FmtSynth.java => SynthFormat.java} (89%) create mode 100644 src/main/java/funorb/audio/VorbisCodebook.java create mode 100644 src/main/java/funorb/audio/VorbisFloor1.java rename src/main/java/funorb/audio/{FmtVorbis.java => VorbisFormat.java} (53%) create mode 100644 src/main/java/funorb/audio/VorbisMapping.java create mode 100644 src/main/java/funorb/audio/VorbisResidues.java delete mode 100644 src/main/java/funorb/audio/fq_.java delete mode 100644 src/main/java/funorb/audio/kn_.java delete mode 100644 src/main/java/funorb/audio/to_.java delete mode 100644 src/main/java/funorb/audio/vb_.java diff --git a/src/main/java/funorb/audio/SoundLoader.java b/src/main/java/funorb/audio/SoundLoader.java index 5262088..c53a3f6 100644 --- a/src/main/java/funorb/audio/SoundLoader.java +++ b/src/main/java/funorb/audio/SoundLoader.java @@ -7,7 +7,7 @@ import java.util.Map; public final class SoundLoader { public static SoundLoader globalLoader; - private final Map cache2 = new HashMap<>(); + private final Map cache2 = new HashMap<>(); private final Map cache1 = new HashMap<>(); private final ResourceLoader loader1; private final ResourceLoader loader2; @@ -21,7 +21,7 @@ public final class SoundLoader { final int cacheKey = (itemId ^ (((groupId << 4) & 0xfff3) | (groupId >>> 12))) | (groupId << 16); final RawSampleS8 cachedRaw = this.cache1.get((long) cacheKey); if (cachedRaw == null) { - final FmtSynth file = FmtSynth.load(this.loader1, groupId, itemId); + final SynthFormat file = SynthFormat.load(this.loader1, groupId, itemId); if (file == null) { return null; } else { @@ -59,9 +59,9 @@ public final class SoundLoader { final long cacheKey = 0x100000000L ^ (long) var5; RawSampleS8 raw = this.cache1.get(cacheKey); if (raw == null) { - FmtVorbis file = this.cache2.get(cacheKey); + VorbisFormat file = this.cache2.get(cacheKey); if (file == null) { - file = FmtVorbis.load(this.loader2, groupId, itemId); + file = VorbisFormat.load(this.loader2, groupId, itemId); if (file == null) { return null; } diff --git a/src/main/java/funorb/audio/Synth.java b/src/main/java/funorb/audio/Synth.java index b86dd8d..d48981a 100644 --- a/src/main/java/funorb/audio/Synth.java +++ b/src/main/java/funorb/audio/Synth.java @@ -173,14 +173,14 @@ public final class Synth { final int var15 = Math.min(var13, len - var12); while (var14 < var15) { - int var16 = (int) ((long) buf[var14 + var12] * (long) SynthMystery._g >> 16); + int var16 = (int) ((long) buf[var14 + var12] * (long) SynthMystery.someAmp >> 16); for (int var17 = 0; var17 < var12; ++var17) { - var16 += (int) ((long) buf[var14 + var12 - 1 - var17] * (long) SynthMystery._e[0][var17] >> 16); + var16 += (int) ((long) buf[var14 + var12 - 1 - var17] * (long) SynthMystery.someAmps[0][var17] >> 16); } for (int var17 = 0; var17 < var14; ++var17) { - var16 -= (int) ((long) buf[var14 - 1 - var17] * (long) SynthMystery._e[1][var17] >> 16); + var16 -= (int) ((long) buf[var14 - 1 - var17] * (long) SynthMystery.someAmps[1][var17] >> 16); } buf[var14] = var16; @@ -195,14 +195,14 @@ public final class Synth { } while (var14 < var15a) { - int var16 = (int) ((long) buf[var14 + var12] * (long) SynthMystery._g >> 16); + int var16 = (int) ((long) buf[var14 + var12] * (long) SynthMystery.someAmp >> 16); for (int var17 = 0; var17 < var12; ++var17) { - var16 += (int) ((long) buf[var14 + var12 - 1 - var17] * (long) SynthMystery._e[0][var17] >> 16); + var16 += (int) ((long) buf[var14 + var12 - 1 - var17] * (long) SynthMystery.someAmps[0][var17] >> 16); } for (int var17 = 0; var17 < var13; ++var17) { - var16 -= (int) ((long) buf[var14 - 1 - var17] * (long) SynthMystery._e[1][var17] >> 16); + var16 -= (int) ((long) buf[var14 - 1 - var17] * (long) SynthMystery.someAmps[1][var17] >> 16); } buf[var14] = var16; @@ -215,11 +215,11 @@ public final class Synth { int var16 = 0; for (int var17 = var14 + var12 - len; var17 < var12; ++var17) { - var16 += (int) ((long) buf[var14 + var12 - 1 - var17] * (long) SynthMystery._e[0][var17] >> 16); + var16 += (int) ((long) buf[var14 + var12 - 1 - var17] * (long) SynthMystery.someAmps[0][var17] >> 16); } for (int var17 = 0; var17 < var13; ++var17) { - var16 -= (int) ((long) buf[var14 - 1 - var17] * (long) SynthMystery._e[1][var17] >> 16); + var16 -= (int) ((long) buf[var14 - 1 - var17] * (long) SynthMystery.someAmps[1][var17] >> 16); } buf[var14] = var16; diff --git a/src/main/java/funorb/audio/FmtSynth.java b/src/main/java/funorb/audio/SynthFormat.java similarity index 89% rename from src/main/java/funorb/audio/FmtSynth.java rename to src/main/java/funorb/audio/SynthFormat.java index a34de4f..5423bfb 100644 --- a/src/main/java/funorb/audio/FmtSynth.java +++ b/src/main/java/funorb/audio/SynthFormat.java @@ -3,12 +3,12 @@ package funorb.audio; import funorb.cache.ResourceLoader; import funorb.io.Buffer; -public final class FmtSynth { +public final class SynthFormat { private final Synth[] oscs = new Synth[10]; private final int loopStartMs; private final int loopEndMs; - private FmtSynth(final Buffer data) { + private SynthFormat(final Buffer data) { for (int i = 0; i < 10; ++i) { final int peekByte = data.readUByte(); if (peekByte != 0) { @@ -22,9 +22,9 @@ public final class FmtSynth { this.loopEndMs = data.readUShort(); } - public static FmtSynth load(final ResourceLoader loader, final int groupId, final int itemId) { + public static SynthFormat load(final ResourceLoader loader, final int groupId, final int itemId) { final byte[] data = loader.getResource(groupId, itemId); - return data == null ? null : new FmtSynth(new Buffer(data)); + return data == null ? null : new SynthFormat(new Buffer(data)); } private byte[] toSampleDataS8() { diff --git a/src/main/java/funorb/audio/SynthMystery.java b/src/main/java/funorb/audio/SynthMystery.java index 1b1d85c..f97f7bb 100644 --- a/src/main/java/funorb/audio/SynthMystery.java +++ b/src/main/java/funorb/audio/SynthMystery.java @@ -3,17 +3,17 @@ package funorb.audio; import funorb.io.Buffer; public final class SynthMystery { - public static final int[][] _e = new int[2][8]; + public static final int[][] someAmps = new int[2][8]; private static final float[][] _f = new float[2][8]; - public static int _g; + public static int someAmp; private static float _h; public final int[] _d = new int[2]; private final int[] _b = new int[2]; private final int[][][] _a = new int[2][2][4]; private final int[][][] _c = new int[2][2][4]; - private static float a251(final float var0) { - final float var1 = 32.703197F * (float) Math.pow(2.0D, var0); + private static float a251(final float octave) { + final float var1 = 32.703197F * (float) Math.pow(2.0D, octave); return var1 * 3.1415927F / 11025.0F; } @@ -59,64 +59,64 @@ public final class SynthMystery { } } - public int a197(final int var1, final float var2) { + public int a197(final int idx, final float var2) { float var3; - if (var1 == 0) { + if (idx == 0) { var3 = (float) this._b[0] + (float) (this._b[1] - this._b[0]) * var2; var3 *= 0.0030517578F; _h = (float) Math.pow(0.1D, var3 / 20.0F); - _g = (int) (_h * 65536.0F); + someAmp = (int) (_h * 65536.0F); } - if (this._d[var1] == 0) { + if (this._d[idx] == 0) { return 0; } else { - var3 = this.b427(var1, 0, var2); - _f[var1][0] = -2.0f * var3 * (float) Math.cos(this.a427(var1, 0, var2)); - _f[var1][1] = var3 * var3; + var3 = this.b427(idx, 0, var2); + _f[idx][0] = -2.0f * var3 * (float) Math.cos(this.a427(idx, 0, var2)); + _f[idx][1] = var3 * var3; int var4; - for (var4 = 1; var4 < this._d[var1]; ++var4) { - var3 = this.b427(var1, var4, var2); - final float var5 = -2.0f * var3 * (float) Math.cos(this.a427(var1, var4, var2)); + for (var4 = 1; var4 < this._d[idx]; ++var4) { + var3 = this.b427(idx, var4, var2); + final float var5 = -2.0f * var3 * (float) Math.cos(this.a427(idx, var4, var2)); final float var6 = var3 * var3; - _f[var1][var4 * 2 + 1] = _f[var1][var4 * 2 - 1] * var6; - _f[var1][var4 * 2] = _f[var1][var4 * 2 - 1] * var5 + _f[var1][var4 * 2 - 2] * var6; + _f[idx][var4 * 2 + 1] = _f[idx][var4 * 2 - 1] * var6; + _f[idx][var4 * 2] = _f[idx][var4 * 2 - 1] * var5 + _f[idx][var4 * 2 - 2] * var6; for (int var7 = var4 * 2 - 1; var7 >= 2; --var7) { - final float[] var10000 = _f[var1]; - var10000[var7] += _f[var1][var7 - 1] * var5 + _f[var1][var7 - 2] * var6; + final float[] var10000 = _f[idx]; + var10000[var7] += _f[idx][var7 - 1] * var5 + _f[idx][var7 - 2] * var6; } - final float[] var10000 = _f[var1]; - var10000[1] += _f[var1][0] * var5 + var6; + final float[] var10000 = _f[idx]; + var10000[1] += _f[idx][0] * var5 + var6; var10000[0] += var5; } - if (var1 == 0) { + if (idx == 0) { for (var4 = 0; var4 < this._d[0] * 2; ++var4) { final float[] var10000 = _f[0]; var10000[var4] *= _h; } } - for (var4 = 0; var4 < this._d[var1] * 2; ++var4) { - _e[var1][var4] = (int) (_f[var1][var4] * 65536.0F); + for (var4 = 0; var4 < this._d[idx] * 2; ++var4) { + someAmps[idx][var4] = (int) (_f[idx][var4] * 65536.0F); } - return this._d[var1] * 2; + return this._d[idx] * 2; } } private float a427(final int var1, final int var2, final float var3) { - float var4 = (float) this._a[var1][0][var2] + var3 * (float) (this._a[var1][1][var2] - this._a[var1][0][var2]); - var4 *= 1.2207031E-4F; - return a251(var4); + float octave = (float) this._a[var1][0][var2] + var3 * (float) (this._a[var1][1][var2] - this._a[var1][0][var2]); + octave *= 1.2207031E-4F; // 1/8192 + return a251(octave); } private float b427(final int var1, final int var2, final float var3) { float var4 = (float) this._c[var1][0][var2] + var3 * (float) (this._c[var1][1][var2] - this._c[var1][0][var2]); - var4 *= 0.0015258789F; + var4 *= 0.0015258789F; // 1/655.36 return 1.0F - (float) Math.pow(10.0D, -var4 / 20.0F); } } diff --git a/src/main/java/funorb/audio/VorbisCodebook.java b/src/main/java/funorb/audio/VorbisCodebook.java new file mode 100644 index 0000000..90ce09e --- /dev/null +++ b/src/main/java/funorb/audio/VorbisCodebook.java @@ -0,0 +1,224 @@ +package funorb.audio; + +import funorb.util.BitMath; + +public final class VorbisCodebook { + public final int cbDim; + private final int cbSize; + private final int[] cwLengths; + private float[][] vectors; + private int[] _f; + + public VorbisCodebook() { + VorbisFormat.readBits(24); + this.cbDim = VorbisFormat.readBits(16); + this.cbSize = VorbisFormat.readBits(24); + this.cwLengths = new int[this.cbSize]; + + final boolean ordered = VorbisFormat.readBit() != 0; + if (ordered) { + int curEntry = 0; + int curLength = VorbisFormat.readBits(5) + 1; + while (curEntry < this.cbSize) { + final int number = VorbisFormat.readBits(BitMath.lastSet(this.cbSize - curEntry)); + for (int i = 0; i < number; ++i) { + this.cwLengths[curEntry++] = curLength; + } + curLength++; + } + } else { + final boolean sparse = VorbisFormat.readBit() != 0; + for (int i = 0; i < this.cbSize; ++i) { + if (sparse && VorbisFormat.readBit() == 0) { + this.cwLengths[i] = 0; + } else { + this.cwLengths[i] = VorbisFormat.readBits(5) + 1; + } + } + } + + this.b797(); + + int lookupTableType = VorbisFormat.readBits(4); + if (lookupTableType > 0) { + final float cbMinValue = VorbisFormat.float32Unpack(VorbisFormat.readBits(32)); + final float cbDeltaValue = VorbisFormat.float32Unpack(VorbisFormat.readBits(32)); + int cbValueBits = VorbisFormat.readBits(4) + 1; + final boolean cbSequenceP = VorbisFormat.readBit() != 0; + + final int lookupValues; + if (lookupTableType == 1) { + lookupValues = lookup1Values(this.cbSize, this.cbDim); + } else { + lookupValues = this.cbSize * this.cbDim; + } + + final int[] cbMultiplicands = new int[lookupValues]; + for (int i = 0; i < lookupValues; ++i) { + cbMultiplicands[i] = VorbisFormat.readBits(cbValueBits); + } + + this.vectors = new float[this.cbSize][this.cbDim]; + float last; + int indexDiv; + + if (lookupTableType == 1) { + for (int i = 0; i < this.cbSize; ++i) { + last = 0.0F; + indexDiv = 1; + for (int j = 0; j < this.cbDim; ++j) { + final int offset = i / indexDiv % lookupValues; + final float value = (float) cbMultiplicands[offset] * cbDeltaValue + cbMinValue + last; + this.vectors[i][j] = value; + if (cbSequenceP) { + last = value; + } + indexDiv *= lookupValues; + } + } + } else { + for (int i = 0; i < this.cbSize; ++i) { + last = 0.0F; + indexDiv = i * this.cbDim; + for (int j = 0; j < this.cbDim; ++j) { + final float value = (float) cbMultiplicands[indexDiv] * cbDeltaValue + cbMinValue + last; + this.vectors[i][j] = value; + if (cbSequenceP) { + last = value; + } + ++indexDiv; + } + } + } + } + + } + + private static int lookup1Values(final int cbSize, final int cbDim) { + int res = (int) Math.pow(cbSize, 1.0D / (double) cbDim) + 1; + while (pow(res, cbDim) > cbSize) { + --res; + } + return res; + } + + private static int pow(int base, int exp) { + int res; + + for (res = 1; exp > 1; base *= base) { + if ((exp & 1) != 0) { + res *= base; + } + exp >>= 1; + } + + if (exp == 1) { + return res * base; + } else { + return res; + } + } + + public float[] c932() { + return this.vectors[this.a784()]; + } + + public int a784() { + int var1 = 0; + while (this._f[var1] >= 0) { + var1 = VorbisFormat.readBit() != 0 ? this._f[var1] : var1 + 1; + } + return ~this._f[var1]; + } + + private void b797() { + final int[] var1 = new int[this.cbSize]; + final int[] var2 = new int[33]; + + int var4; + int var5; + int var6; + int var7; + int var10; + + for (int i = 0; i < this.cbSize; ++i) { + var4 = this.cwLengths[i]; + if (var4 != 0) { + var5 = 1 << 32 - var4; + var6 = var2[var4]; + var1[i] = var6; + int var9; + if ((var6 & var5) == 0) { + var7 = var6 | var5; + + for (int j = var4 - 1; j >= 1; --j) { + var9 = var2[j]; + if (var9 != var6) { + break; + } + + var10 = 1 << 32 - j; + if ((var9 & var10) != 0) { + var2[j] = var2[j - 1]; + break; + } + + var2[j] = var9 | var10; + } + } else { + var7 = var2[var4 - 1]; + } + + var2[var4] = var7; + + for (int j = var4 + 1; j <= 32; ++j) { + var9 = var2[j]; + if (var9 == var6) { + var2[j] = var7; + } + } + } + } + + this._f = new int[8]; + int var11 = 0; + + for (int i = 0; i < this.cbSize; ++i) { + var4 = this.cwLengths[i]; + if (var4 != 0) { + var5 = var1[i]; + var6 = 0; + + for (var7 = 0; var7 < var4; ++var7) { + int var8 = Integer.MIN_VALUE >>> var7; + if ((var5 & var8) == 0) { + ++var6; + } else { + if (this._f[var6] == 0) { + this._f[var6] = var11; + } + + var6 = this._f[var6]; + } + + if (var6 >= this._f.length) { + final int[] var12 = new int[this._f.length * 2]; + + for (var10 = 0; var10 < this._f.length; ++var10) { + var12[var10] = this._f[var10]; + } + + this._f = var12; + } + + } + + this._f[var6] = ~i; + if (var6 >= var11) { + var11 = var6 + 1; + } + } + } + + } +} diff --git a/src/main/java/funorb/audio/VorbisFloor1.java b/src/main/java/funorb/audio/VorbisFloor1.java new file mode 100644 index 0000000..f4600b4 --- /dev/null +++ b/src/main/java/funorb/audio/VorbisFloor1.java @@ -0,0 +1,364 @@ +package funorb.audio; + +import funorb.util.BitMath; + +public final class VorbisFloor1 { + private static final float[] INVERSE_DB_TABLE = new float[]{ + 1.0649863E-7F, 1.1341951E-7F, 1.2079015E-7F, 1.2863978E-7F, + 1.369995E-7F, 1.459025E-7F, 1.5538409E-7F, 1.6548181E-7F, + 1.7623574E-7F, 1.8768856E-7F, 1.998856E-7F, 2.128753E-7F, + 2.2670913E-7F, 2.4144197E-7F, 2.5713223E-7F, 2.7384212E-7F, + 2.9163792E-7F, 3.1059022E-7F, 3.307741E-7F, 3.5226967E-7F, + 3.7516213E-7F, 3.995423E-7F, 4.255068E-7F, 4.5315863E-7F, + 4.8260745E-7F, 5.1397E-7F, 5.4737063E-7F, 5.829419E-7F, + 6.208247E-7F, 6.611694E-7F, 7.041359E-7F, 7.4989464E-7F, + + 7.98627E-7F, 8.505263E-7F, 9.057983E-7F, 9.646621E-7F, + 1.0273513E-6F, 1.0941144E-6F, 1.1652161E-6F, 1.2409384E-6F, + 1.3215816E-6F, 1.4074654E-6F, 1.4989305E-6F, 1.5963394E-6F, + 1.7000785E-6F, 1.8105592E-6F, 1.9282195E-6F, 2.053526E-6F, + 2.1869757E-6F, 2.3290977E-6F, 2.4804558E-6F, 2.6416496E-6F, + 2.813319E-6F, 2.9961443E-6F, 3.1908505E-6F, 3.39821E-6F, + 3.619045E-6F, 3.8542307E-6F, 4.1047006E-6F, 4.371447E-6F, + 4.6555283E-6F, 4.958071E-6F, 5.280274E-6F, 5.623416E-6F, + + 5.988857E-6F, 6.3780467E-6F, 6.7925284E-6F, 7.2339453E-6F, + 7.704048E-6F, 8.2047E-6F, 8.737888E-6F, 9.305725E-6F, + 9.910464E-6F, 1.0554501E-5F, 1.1240392E-5F, 1.1970856E-5F, + 1.2748789E-5F, 1.3577278E-5F, 1.4459606E-5F, 1.5399271E-5F, + 1.6400005E-5F, 1.7465769E-5F, 1.8600793E-5F, 1.9809577E-5F, + 2.1096914E-5F, 2.2467912E-5F, 2.3928002E-5F, 2.5482977E-5F, + 2.7139005E-5F, 2.890265E-5F, 3.078091E-5F, 3.2781227E-5F, + 3.4911533E-5F, 3.718028E-5F, 3.9596467E-5F, 4.2169668E-5F, + + 4.491009E-5F, 4.7828602E-5F, 5.0936775E-5F, 5.424693E-5F, + 5.7772202E-5F, 6.152657E-5F, 6.552491E-5F, 6.9783084E-5F, + 7.4317984E-5F, 7.914758E-5F, 8.429104E-5F, 8.976875E-5F, + 9.560242E-5F, 1.0181521E-4F, 1.0843174E-4F, 1.1547824E-4F, + 1.2298267E-4F, 1.3097477E-4F, 1.3948625E-4F, 1.4855085E-4F, + 1.5820454E-4F, 1.6848555E-4F, 1.7943469E-4F, 1.9109536E-4F, + 2.0351382E-4F, 2.167393E-4F, 2.3082423E-4F, 2.4582449E-4F, + 2.6179955E-4F, 2.7881275E-4F, 2.9693157E-4F, 3.1622787E-4F, + + 3.3677815E-4F, 3.5866388E-4F, 3.8197188E-4F, 4.0679457E-4F, + 4.3323037E-4F, 4.613841E-4F, 4.913675E-4F, 5.2329927E-4F, + 5.573062E-4F, 5.935231E-4F, 6.320936E-4F, 6.731706E-4F, + 7.16917E-4F, 7.635063E-4F, 8.1312325E-4F, 8.6596457E-4F, + 9.2223985E-4F, 9.821722E-4F, 0.0010459992F, 0.0011139743F, + 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F, + 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F, + 0.0019632196F, 0.0020908006F, 0.0022266726F, 0.0023713743F, + + 0.0025254795F, 0.0026895993F, 0.0028643848F, 0.0030505287F, + 0.003248769F, 0.0034598925F, 0.0036847359F, 0.0039241905F, + 0.0041792067F, 0.004450795F, 0.004740033F, 0.005048067F, + 0.0053761187F, 0.005725489F, 0.0060975635F, 0.0064938175F, + 0.0069158226F, 0.0073652514F, 0.007843887F, 0.008353627F, + 0.008896492F, 0.009474637F, 0.010090352F, 0.01074608F, + 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F, + 0.014722068F, 0.015678791F, 0.016697686F, 0.017782796F, + + 0.018938422F, 0.020169148F, 0.021479854F, 0.022875736F, + 0.02436233F, 0.025945531F, 0.027631618F, 0.029427277F, + 0.031339627F, 0.03337625F, 0.035545226F, 0.037855156F, + 0.0403152F, 0.042935107F, 0.045725275F, 0.048696756F, + 0.05186135F, 0.05523159F, 0.05882085F, 0.062643364F, + 0.06671428F, 0.07104975F, 0.075666964F, 0.08058423F, + 0.08582105F, 0.09139818F, 0.097337745F, 0.1036633F, + 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F, + + 0.14201812F, 0.15124726F, 0.16107617F, 0.1715438F, + 0.18269168F, 0.19456401F, 0.20720787F, 0.22067343F, + 0.23501402F, 0.25028655F, 0.26655158F, 0.28387362F, + 0.3023213F, 0.32196787F, 0.34289113F, 0.36517414F, + 0.3889052F, 0.41417846F, 0.44109413F, 0.4697589F, + 0.50028646F, 0.53279793F, 0.5674221F, 0.6042964F, + 0.64356697F, 0.6853896F, 0.72993004F, 0.777365F, + 0.8278826F, 0.88168305F, 0.9389798F, 1.0F}; + private static final int[] FLOOR_MULTIPLIER_LOOKUP = new int[]{256, 128, 86, 64}; + private static boolean[] step2Flag; + private static int[] floorY; + private static int[] floorX; + private final int[] xList; + private final int[] classSubclasses; + private final int[][] subclassBooks; + private final int[] partitionClasses; + private final int[] classMasterbooks; + private final int multiplier; + private final int[] classDims; + + public VorbisFloor1() { + final int floorType = VorbisFormat.readBits(16); + if (floorType != 1) { + throw new RuntimeException(); + } + + final int numPartitions = VorbisFormat.readBits(5); + this.partitionClasses = new int[numPartitions]; + + int maxClassPlusOne = 0; + for (int i = 0; i < numPartitions; ++i) { + int cls = VorbisFormat.readBits(4); + this.partitionClasses[i] = cls; + if (cls >= maxClassPlusOne) { + maxClassPlusOne = cls + 1; + } + } + + this.classDims = new int[maxClassPlusOne]; + this.classSubclasses = new int[maxClassPlusOne]; + this.classMasterbooks = new int[maxClassPlusOne]; + this.subclassBooks = new int[maxClassPlusOne][]; + + for (int i = 0; i < maxClassPlusOne; ++i) { + this.classDims[i] = VorbisFormat.readBits(3) + 1; + int subclasses = this.classSubclasses[i] = VorbisFormat.readBits(2); + if (subclasses != 0) { + this.classMasterbooks[i] = VorbisFormat.readBits(8); + } + + subclasses = 1 << subclasses; + final int[] book = new int[subclasses]; + this.subclassBooks[i] = book; + + for (int j = 0; j < subclasses; ++j) { + book[j] = VorbisFormat.readBits(8) - 1; + } + } + + this.multiplier = VorbisFormat.readBits(2) + 1; + int rangeBits = VorbisFormat.readBits(4); + + int xListSize = 2; + for (int i = 0; i < numPartitions; ++i) { + xListSize += this.classDims[this.partitionClasses[i]]; + } + + this.xList = new int[xListSize]; + this.xList[0] = 0; + this.xList[1] = 1 << rangeBits; + + int values = 2; + for (int i = 0; i < numPartitions; ++i) { + int cls = this.partitionClasses[i]; + for (int j = 0; j < this.classDims[cls]; ++j) { + this.xList[values++] = VorbisFormat.readBits(rangeBits); + } + } + if (floorX == null || floorX.length < values) { + floorX = new int[values]; + floorY = new int[values]; + step2Flag = new boolean[values]; + } + } + + private static int highNeighbor(final int[] vec, final int x) { + final int target = vec[x]; + int minIndex = -1; + int minValue = Integer.MAX_VALUE; + + for (int i = 0; i < x; ++i) { + final int value = vec[i]; + if (target < value && value < minValue) { + minIndex = i; + minValue = value; + } + } + + return minIndex; + } + + private static int lowNeighbor(final int[] vec, final int x) { + final int target = vec[x]; + int maxIndex = -1; + int maxValue = Integer.MIN_VALUE; + + for (int i = 0; i < x; ++i) { + final int value = vec[i]; + if (value < target && maxValue < value) { + maxIndex = i; + maxValue = value; + } + } + + return maxIndex; + } + + public boolean decode() { + final boolean nonzero = VorbisFormat.readBit() != 0; + if (!nonzero) { + return false; + } + + for (int i = 0; i < this.xList.length; ++i) { + floorX[i] = this.xList[i]; + } + + int range = FLOOR_MULTIPLIER_LOOKUP[this.multiplier - 1]; + final int yBits = BitMath.lastSet(range - 1); + floorY[0] = VorbisFormat.readBits(yBits); + floorY[1] = VorbisFormat.readBits(yBits); + + int offset = 2; + for (final int cls : this.partitionClasses) { + final int cDim = this.classDims[cls]; + final int cBits = this.classSubclasses[cls]; + final int cSub = (1 << cBits) - 1; + int cVal = 0; + if (cBits > 0) { + cVal = VorbisFormat.codebooks[this.classMasterbooks[cls]].a784(); + } + for (int i = 0; i < cDim; ++i) { + final int book = this.subclassBooks[cls][cVal & cSub]; + cVal >>>= cBits; + floorY[offset++] = book >= 0 ? VorbisFormat.codebooks[book].a784() : 0; + } + } + + return true; + } + + private void sortFloor(final int a, final int b) { + if (a >= b) { + return; + } + + int split = a; + final int pivotX = floorX[a]; + final int pivotY = floorY[a]; + final boolean pivotStep2 = step2Flag[a]; + + for (int i = a + 1; i <= b; ++i) { + final int value = floorX[i]; + if (value >= pivotX) { + continue; + } + + floorX[split] = value; + floorY[split] = floorY[i]; + step2Flag[split] = step2Flag[i]; + ++split; + floorX[i] = floorX[split]; + floorY[i] = floorY[split]; + step2Flag[i] = step2Flag[split]; + } + + floorX[split] = pivotX; + floorY[split] = pivotY; + step2Flag[split] = pivotStep2; + + this.sortFloor(a, split - 1); + this.sortFloor(split + 1, b); + } + + private int renderPoint( + final int x0, + final int y0, + final int x1, + final int y1, + final int x + ) { + final int dy = y1 - y0; + final int adx = x1 - x0; + final int ady = dy < 0 ? -dy : dy; + final int err = ady * (x - x0); + final int off = err / adx; + return dy < 0 ? y0 - off : y0 + off; + } + + private void renderLinePremultiplied( + final int lx, + final int ly, + int hx, + final int hy, + final float[] floor, + final int n + ) { + final int dy = hy - ly; + final int adx = hx - lx; + int ady = dy < 0 ? -dy : dy; + final int base = dy / adx; + int x = lx; + int y = ly; + int err = 0; + final int sy = dy < 0 ? base - 1 : base + 1; + + ady -= (base < 0 ? -base : base) * adx; + floor[lx] *= INVERSE_DB_TABLE[ly]; + if (hx > n) { + hx = n; + } + + for (x = lx + 1; x < hx; ++x) { + err += ady; + if (err >= adx) { + err -= adx; + y += sy; + } else { + y += base; + } + floor[x] *= INVERSE_DB_TABLE[y]; + } + } + + public void computeCurve(final float[] floor, final int n) { + final int numValues = this.xList.length; + final int range = FLOOR_MULTIPLIER_LOOKUP[this.multiplier - 1]; + + final boolean[] step2Flag = VorbisFloor1.step2Flag; + step2Flag[0] = true; + step2Flag[1] = true; + + for (int i = 2; i < numValues; ++i) { + int lowOffset = lowNeighbor(floorX, i); + int highOffset = highNeighbor(floorX, i); + int predicted = this.renderPoint( + floorX[lowOffset], + floorY[lowOffset], + floorX[highOffset], + floorY[highOffset], + floorX[i] + ); + int val = floorY[i]; + final int highroom = range - predicted; + final int room = (Math.min(highroom, predicted)) << 1; + if (val != 0) { + final boolean[] var14 = VorbisFloor1.step2Flag; + VorbisFloor1.step2Flag[highOffset] = true; + var14[lowOffset] = true; + VorbisFloor1.step2Flag[i] = true; + if (val >= room) { + floorY[i] = highroom > predicted ? val - predicted + predicted : predicted - val + highroom - 1; + } else { + floorY[i] = (val & 1) != 0 ? predicted - (val + 1) / 2 : predicted + val / 2; + } + } else { + VorbisFloor1.step2Flag[i] = false; + floorY[i] = predicted; + } + } + + this.sortFloor(0, numValues - 1); + + int lx = 0; + int ly = floorY[0] * this.multiplier; + for (int i = 1; i < numValues; ++i) { + if (!VorbisFloor1.step2Flag[i]) { + continue; + } + int hx = floorX[i]; + int hy = floorY[i] * this.multiplier; + this.renderLinePremultiplied(lx, ly, hx, hy, floor, n); + if (hx >= n) { + return; + } + lx = hx; + ly = hy; + } + + final float coeff = INVERSE_DB_TABLE[ly]; + for (int i = lx; i < n; ++i) { + floor[i] *= coeff; + } + } +} diff --git a/src/main/java/funorb/audio/FmtVorbis.java b/src/main/java/funorb/audio/VorbisFormat.java similarity index 53% rename from src/main/java/funorb/audio/FmtVorbis.java rename to src/main/java/funorb/audio/VorbisFormat.java index d2a1739..bea18fa 100644 --- a/src/main/java/funorb/audio/FmtVorbis.java +++ b/src/main/java/funorb/audio/VorbisFormat.java @@ -7,47 +7,47 @@ import funorb.util.BitMath; import java.io.IOException; import java.util.stream.IntStream; -public final class FmtVorbis { - public static vb_[] _L; +public final class VorbisFormat { + public static VorbisCodebook[] codebooks; private static float[] _k; - private static to_[] _o; - private static int[] _J; + private static VorbisResidues[] residues; + private static int[] modeMapping; private static int[] _D; - private static fq_[] _O; + private static VorbisMapping[] mappings; private static float[] _u; private static float[] _C; - private static boolean _x = false; + private static boolean setupFinished_idk = false; private static byte[] buffer; private static float[] _z; - private static boolean[] _t; + private static boolean[] modeBlockFlag; private static float[] _y; private static float[] _j; - private static int _r; + private static int blocksize1; private static float[] _l; private static int curBit; private static int[] _F; - private static int _E; - private static kn_[] _h; + private static int blocksize0; + private static VorbisFloor1[] floors; private static int curByte; private int sampleLength; private int loopEnd; private boolean isLooped; private int loopStart; private int _i; - private int _s; + private int outputOffset; private boolean _A; - private byte[][] sections; + private byte[][] packets; private int _M; private int sampleRate; private byte[] sampleData; - private float[] _n; - private int sectionIndex; + private float[] prevWindow; + private int packet; - private FmtVorbis(final byte[] data) throws IOException { + private VorbisFormat(final byte[] data) throws IOException { this.load(data); } - public static float parseAsFloat(final int value) { + public static float float32Unpack(final int value) { int significand = value & 0x1fffff; final int sign = value & Integer.MIN_VALUE; final int exponent = (value & 0x7fe00000) >> 21; @@ -65,22 +65,17 @@ public final class FmtVorbis { return bit; } - public static void b604(final byte[] section) { - setBuffer(section); - _E = 1 << readBits(4); - _r = 1 << readBits(4); - _k = new float[_r]; + public static void readIdentificationAndSetup(final byte[] section) { + setCurrentPacket(section); + blocksize0 = 1 << readBits(4); + blocksize1 = 1 << readBits(4); + _k = new float[blocksize1]; - int var1; - int var2; - int var3; - int var4; - int var5; - for (var1 = 0; var1 < 2; ++var1) { - var2 = var1 != 0 ? _r : _E; - var3 = var2 >> 1; - var4 = var2 >> 2; - var5 = var2 >> 3; + for (int i = 0; i < 2; ++i) { + int var2 = i != 0 ? blocksize1 : blocksize0; + int var3 = var2 >> 1; + int var4 = var2 >> 2; + int var5 = var2 >> 3; final float[] var6 = new float[var3]; for (int var7 = 0; var7 < var4; ++var7) { @@ -105,7 +100,7 @@ public final class FmtVorbis { final int var10 = BitMath.lastSet(var5 - 1); final int[] var15 = IntStream.range(0, var5).map(var11 -> reverseBits(var11, var10)).toArray(); - if (var1 == 0) { + if (i == 0) { _l = var6; _z = var13; _C = var14; @@ -118,70 +113,63 @@ public final class FmtVorbis { } } - var1 = readBits(8) + 1; - _L = new vb_[var1]; - - for (var2 = 0; var2 < var1; ++var2) { - _L[var2] = new vb_(); + int numCodebooks = readBits(8) + 1; + codebooks = new VorbisCodebook[numCodebooks]; + for (int i = 0; i < numCodebooks; ++i) { + codebooks[i] = new VorbisCodebook(); } - var2 = readBits(6) + 1; - - for (var3 = 0; var3 < var2; ++var3) { + int numVorbisTimes = readBits(6) + 1; + for (int i = 0; i < numVorbisTimes; ++i) { readBits(16); } - var2 = readBits(6) + 1; - _h = new kn_[var2]; - - for (var3 = 0; var3 < var2; ++var3) { - _h[var3] = new kn_(); + int numFloors = readBits(6) + 1; + floors = new VorbisFloor1[numFloors]; + for (int i = 0; i < numFloors; ++i) { + floors[i] = new VorbisFloor1(); } - var3 = readBits(6) + 1; - _o = new to_[var3]; - - for (var4 = 0; var4 < var3; ++var4) { - _o[var4] = new to_(); + int numResidues = readBits(6) + 1; + residues = new VorbisResidues[numResidues]; + for (int i = 0; i < numResidues; ++i) { + residues[i] = new VorbisResidues(); } - var4 = readBits(6) + 1; - _O = new fq_[var4]; - - for (var5 = 0; var5 < var4; ++var5) { - _O[var5] = new fq_(); + int numMappings = readBits(6) + 1; + mappings = new VorbisMapping[numMappings]; + for (int i = 0; i < numMappings; ++i) { + mappings[i] = new VorbisMapping(); } - var5 = readBits(6) + 1; - _t = new boolean[var5]; - _J = new int[var5]; + int numModes = readBits(6) + 1; + modeBlockFlag = new boolean[numModes]; + modeMapping = new int[numModes]; - for (int var12 = 0; var12 < var5; ++var12) { - _t[var12] = readBit() != 0; - readBits(16); - readBits(16); - _J[var12] = readBits(8); + for (int i = 0; i < numModes; ++i) { + modeBlockFlag[i] = readBit() != 0; + readBits(16); // window type + readBits(16); // transform type + modeMapping[i] = readBits(8); } - _x = true; + setupFinished_idk = true; } @SuppressWarnings("SameParameterValue") - public static FmtVorbis a968(final ResourceLoader loader, final String group, final String item) { - if (a521(loader)) { - final byte[] var3 = loader.getResource(group, item); - if (var3 == null) { + public static VorbisFormat loadAudio(final ResourceLoader loader, final String group, final String item) { + if (loadSetup(loader)) { + final byte[] data = loader.getResource(group, item); + if (data == null) { return null; } else { - FmtVorbis var4 = null; - + VorbisFormat vorbis = null; try { - var4 = new FmtVorbis(var3); - } catch (final IOException var6) { - var6.printStackTrace(); + vorbis = new VorbisFormat(data); + } catch (final IOException e) { + e.printStackTrace(); } - - return var4; + return vorbis; } } else { loader.loadGroupDataForItem(group, item); @@ -189,21 +177,19 @@ public final class FmtVorbis { } } - private static boolean a521(final ResourceLoader loader) { - if (!_x) { + private static boolean loadSetup(final ResourceLoader loader) { + if (!setupFinished_idk) { final byte[] data = loader.getResource(0, 0); if (data == null) { return false; } - - b604(data); + readIdentificationAndSetup(data); } - return true; } - private static void setBuffer(final byte[] section) { - buffer = section; + private static void setCurrentPacket(final byte[] packet) { + buffer = packet; curByte = 0; curBit = 0; } @@ -231,21 +217,19 @@ public final class FmtVorbis { return result; } - public static FmtVorbis load(final ResourceLoader loader, final int groupId, final int itemId) { - if (a521(loader)) { - final byte[] var3 = loader.getResource(groupId, itemId); - if (var3 == null) { + public static VorbisFormat load(final ResourceLoader loader, final int groupId, final int itemId) { + if (loadSetup(loader)) { + final byte[] data = loader.getResource(groupId, itemId); + if (data == null) { return null; } else { - FmtVorbis var4 = null; - + VorbisFormat vorbis = null; try { - var4 = new FmtVorbis(var3); - } catch (final IOException var6) { - var6.printStackTrace(); + vorbis = new VorbisFormat(data); + } catch (final IOException e) { + e.printStackTrace(); } - - return var4; + return vorbis; } } else { loader.loadGroupDataForItem(groupId, itemId); @@ -265,108 +249,102 @@ public final class FmtVorbis { public RawSampleS8 toRawSample() { if (this.sampleData == null) { this._M = 0; - this._n = new float[_r]; + this.prevWindow = new float[blocksize1]; this.sampleData = new byte[this.sampleLength]; - this._s = 0; - this.sectionIndex = 0; + this.outputOffset = 0; + this.packet = 0; } - for (; this.sectionIndex < this.sections.length; ++this.sectionIndex) { - - final float[] var2 = this.e875(this.sectionIndex); - if (var2 != null) { - int var3 = this._s; - int var4 = var2.length; - if (var4 > this.sampleLength - var3) { - var4 = this.sampleLength - var3; + for (; this.packet < this.packets.length; ++this.packet) { + final float[] frame = this.decodeAudioPacket(this.packet); + if (frame != null) { + int offset = this.outputOffset; + int len = frame.length; + if (len > this.sampleLength - offset) { + len = this.sampleLength - offset; } - - for (int var5 = 0; var5 < var4; ++var5) { - int var6 = (int) (128.0F + var2[var5] * 128.0F); - if ((var6 & -256) != 0) { - var6 = ~var6 >> 31; + for (int i = 0; i < len; ++i) { + int sample = (int) (128.0F + frame[i] * 128.0F); + if ((sample & -256) != 0) { + sample = ~sample >> 31; } - - this.sampleData[var3++] = (byte) (var6 - 128); + this.sampleData[offset++] = (byte) (sample - 128); } - - this._s = var3; + this.outputOffset = offset; } } - this._n = null; + this.prevWindow = null; final byte[] sampleData = this.sampleData; this.sampleData = null; return new RawSampleS8(this.sampleRate, sampleData, this.loopStart, this.loopEnd, this.isLooped); } - private float[] e875(final int sectionIndex) { - setBuffer(this.sections[sectionIndex]); - readBit(); - final int var2 = readBits(BitMath.lastSet(_J.length - 1)); - final boolean var3 = _t[var2]; - final int var4 = var3 ? _r : _E; - boolean var5 = false; - boolean var6 = false; - if (var3) { - var5 = readBit() != 0; - var6 = readBit() != 0; + private float[] decodeAudioPacket(final int packet) { + setCurrentPacket(this.packets[packet]); + readBit(); // packet type (assumed audio) + + final int modeNumber = readBits(BitMath.lastSet(modeMapping.length - 1)); + final boolean isLongWindow = VorbisFormat.modeBlockFlag[modeNumber]; + final int n = isLongWindow ? blocksize1 : blocksize0; + + boolean prevWindowFlag = false; + boolean nextWindowFlag = false; + if (isLongWindow) { + prevWindowFlag = readBit() != 0; + nextWindowFlag = readBit() != 0; } - final int var7 = var4 >> 1; - final int var8; - final int var9; - final int var10; - if (var3 && !var5) { - var8 = (var4 >> 2) - (_E >> 2); - var9 = (var4 >> 2) + (_E >> 2); - var10 = _E >> 1; + final int windowCenter = n >> 1; + + final int leftWindowStart; + final int leftWindowEnd; + final int leftN; + if (isLongWindow && !prevWindowFlag) { + leftWindowStart = (n >> 2) - (blocksize0 >> 2); + leftWindowEnd = (n >> 2) + (blocksize0 >> 2); + leftN = blocksize0 >> 1; } else { - var8 = 0; - var9 = var7; - var10 = var4 >> 1; + leftWindowStart = 0; + leftWindowEnd = windowCenter; + leftN = n >> 1; } - final int var11; - final int var12; - final int var13; - if (var3 && !var6) { - var11 = var4 - (var4 >> 2) - (_E >> 2); - var12 = var4 - (var4 >> 2) + (_E >> 2); - var13 = _E >> 1; + final int rightWindowStart; + final int rightWindowEnd; + final int rightN; + if (isLongWindow && !nextWindowFlag) { + rightWindowStart = n - (n >> 2) - (blocksize0 >> 2); + rightWindowEnd = n - (n >> 2) + (blocksize0 >> 2); + rightN = blocksize0 >> 1; } else { - var11 = var7; - var12 = var4; - var13 = var4 >> 1; + rightWindowStart = windowCenter; + rightWindowEnd = n; + rightN = n >> 1; } - final fq_ var14 = _O[_J[var2]]; - final int var16 = var14._d; - int var17 = var14._b[var16]; - final boolean var15 = !_h[var17].b801(); + final VorbisMapping mapping = mappings[modeMapping[modeNumber]]; + final boolean var15 = !floors[mapping.floor[mapping.mux]].decode(); - for (var17 = 0; var17 < var14._c; ++var17) { - final to_ var18 = _o[var14._a[var17]]; + for (int i = 0; i < mapping.submaps; ++i) { + final VorbisResidues residue = residues[mapping.residues[i]]; final float[] var19 = _k; - var18.a623(var19, var4 >> 1, var15); + residue.a623(var19, n >> 1, var15); } - int var41; if (!var15) { - var17 = var14._d; - var41 = var14._b[var17]; - _h[var41].a331(_k, var4 >> 1); + floors[mapping.floor[mapping.mux]].computeCurve(_k, n >> 1); } int var42; if (var15) { - for (var17 = var4 >> 1; var17 < var4; ++var17) { + for (int var17 = n >> 1; var17 < n; ++var17) { _k[var17] = 0.0F; } } else { - final int i = var4 >> 1; - var41 = var4 >> 2; - var42 = var4 >> 3; + final int i = n >> 1; + int var41 = n >> 2; + var42 = n >> 3; final float[] var20 = _k; int var21; @@ -374,14 +352,14 @@ public final class FmtVorbis { var20[var21] *= 0.5F; } - for (var21 = i; var21 < var4; ++var21) { - var20[var21] = -var20[var4 - var21 - 1]; + for (var21 = i; var21 < n; ++var21) { + var20[var21] = -var20[n - var21 - 1]; } - final float[] var46 = var3 ? _j : _l; - final float[] var22 = var3 ? _y : _z; - final float[] var23 = var3 ? _u : _C; - final int[] var24 = var3 ? _F : _D; + final float[] var46 = isLongWindow ? _j : _l; + final float[] var22 = isLongWindow ? _y : _z; + final float[] var23 = isLongWindow ? _u : _C; + final int[] var24 = isLongWindow ? _F : _D; int var25; float var26; @@ -389,12 +367,12 @@ public final class FmtVorbis { float var28; float var29; for (var25 = 0; var25 < var41; ++var25) { - var26 = var20[4 * var25] - var20[var4 - 4 * var25 - 1]; - var27 = var20[4 * var25 + 2] - var20[var4 - 4 * var25 - 3]; + var26 = var20[4 * var25] - var20[n - 4 * var25 - 1]; + var27 = var20[4 * var25 + 2] - var20[n - 4 * var25 - 3]; var28 = var46[2 * var25]; var29 = var46[2 * var25 + 1]; - var20[var4 - 4 * var25 - 1] = var26 * var28 - var27 * var29; - var20[var4 - 4 * var25 - 3] = var26 * var29 + var27 * var28; + var20[n - 4 * var25 - 1] = var26 * var28 - var27 * var29; + var20[n - 4 * var25 - 3] = var26 * var29 + var27 * var28; } float var30; @@ -412,21 +390,21 @@ public final class FmtVorbis { var20[4 * var25 + 1] = (var27 - var29) * var30 + (var26 - var28) * var31; } - var25 = BitMath.lastSet(var4 - 1); + var25 = BitMath.lastSet(n - 1); int var47; int var48; int var49; int var50; for (var47 = 0; var47 < var25 - 3; ++var47) { - var48 = var4 >> var47 + 2; + var48 = n >> var47 + 2; var49 = 8 << var47; for (var50 = 0; var50 < 2 << var47; ++var50) { - final int var51 = var4 - var48 * 2 * var50; - final int var52 = var4 - var48 * (2 * var50 + 1); + final int var51 = n - var48 * 2 * var50; + final int var52 = n - var48 * (2 * var50 + 1); - for (int var32 = 0; var32 < var4 >> var47 + 4; ++var32) { + for (int var32 = 0; var32 < n >> var47 + 4; ++var32) { final int var33 = 4 * var32; final float var34 = var20[var51 - 1 - var33]; final float var35 = var20[var51 - 3 - var33]; @@ -467,10 +445,10 @@ public final class FmtVorbis { } for (var47 = 0; var47 < var42; ++var47) { - var20[var4 - 1 - 2 * var47] = var20[4 * var47]; - var20[var4 - 2 - 2 * var47] = var20[4 * var47 + 1]; - var20[var4 - var41 - 1 - 2 * var47] = var20[4 * var47 + 2]; - var20[var4 - var41 - 2 - 2 * var47] = var20[4 * var47 + 3]; + var20[n - 1 - 2 * var47] = var20[4 * var47]; + var20[n - 2 - 2 * var47] = var20[4 * var47 + 1]; + var20[n - var41 - 1 - 2 * var47] = var20[4 * var47 + 2]; + var20[n - var41 - 2 - 2 * var47] = var20[4 * var47 + 3]; } for (var47 = 0; var47 < var42; ++var47) { @@ -478,14 +456,14 @@ public final class FmtVorbis { var28 = var23[2 * var47 + 1]; var29 = var20[i + 2 * var47]; var30 = var20[i + 2 * var47 + 1]; - var31 = var20[var4 - 2 - 2 * var47]; - final float var53 = var20[var4 - 1 - 2 * var47]; + var31 = var20[n - 2 - 2 * var47]; + final float var53 = var20[n - 1 - 2 * var47]; final float var54 = var28 * (var29 - var31) + var27 * (var30 + var53); var20[i + 2 * var47] = (var29 + var31 + var54) * 0.5F; - var20[var4 - 2 - 2 * var47] = (var29 + var31 - var54) * 0.5F; + var20[n - 2 - 2 * var47] = (var29 + var31 - var54) * 0.5F; final float v = var28 * (var30 + var53) - var27 * (var29 - var31); var20[i + 2 * var47 + 1] = (var30 - var53 + v) * 0.5F; - var20[var4 - 1 - 2 * var47] = (-var30 + var53 + v) * 0.5F; + var20[n - 1 - 2 * var47] = (-var30 + var53 + v) * 0.5F; } for (var47 = 0; var47 < var41; ++var47) { @@ -494,7 +472,7 @@ public final class FmtVorbis { } for (var47 = 0; var47 < var41; ++var47) { - var20[var4 - var41 + var47] = -var20[var47]; + var20[n - var41 + var47] = -var20[var47]; } for (var47 = 0; var47 < var41; ++var47) { @@ -506,18 +484,18 @@ public final class FmtVorbis { } for (var47 = 0; var47 < var41; ++var47) { - var20[i + var47] = var20[var4 - var47 - 1]; + var20[i + var47] = var20[n - var47 - 1]; } float[] var10000; - for (var47 = var8; var47 < var9; ++var47) { - var27 = (float) Math.sin(((double) (var47 - var8) + 0.5D) / (double) var10 * 0.5D * Math.PI); + for (var47 = leftWindowStart; var47 < leftWindowEnd; ++var47) { + var27 = (float) Math.sin(((double) (var47 - leftWindowStart) + 0.5D) / (double) leftN * 0.5D * Math.PI); var10000 = _k; var10000[var47] *= (float) Math.sin(1.5707963267948966D * (double) var27 * (double) var27); } - for (var47 = var11; var47 < var12; ++var47) { - var27 = (float) Math.sin(((double) (var47 - var11) + 0.5D) / (double) var13 * 0.5D * Math.PI + (Math.PI / 2)); + for (var47 = rightWindowStart; var47 < rightWindowEnd; ++var47) { + var27 = (float) Math.sin(((double) (var47 - rightWindowStart) + 0.5D) / (double) rightN * 0.5D * Math.PI + (Math.PI / 2)); var10000 = _k; var10000[var47] *= (float) Math.sin(1.5707963267948966D * (double) var27 * (double) var27); } @@ -525,29 +503,28 @@ public final class FmtVorbis { float[] var43 = null; if (this._M > 0) { - var41 = this._M + var4 >> 2; - var43 = new float[var41]; + var43 = new float[this._M + n >> 2]; int var45; if (!this._A) { for (var42 = 0; var42 < this._i; ++var42) { var45 = (this._M >> 1) + var42; - var43[var42] += this._n[var45]; + var43[var42] += this.prevWindow[var45]; } } if (!var15) { - for (var42 = var8; var42 < var4 >> 1; ++var42) { - var45 = var43.length - (var4 >> 1) + var42; + for (var42 = leftWindowStart; var42 < n >> 1; ++var42) { + var45 = var43.length - (n >> 1) + var42; var43[var45] += _k[var42]; } } } - final float[] var44 = this._n; - this._n = _k; + final float[] var44 = this.prevWindow; + this.prevWindow = _k; _k = var44; - this._M = var4; - this._i = var12 - (var4 >> 1); + this._M = n; + this._i = rightWindowEnd - (n >> 1); this._A = var15; return var43; } @@ -566,31 +543,27 @@ public final class FmtVorbis { final int count = buf.readInt(); if (count < 0) { throw new IOException(); - } else { - this.sections = new byte[count][]; - - for (int i = 0; i < count; ++i) { - int total = 0; - - int x; - do { - x = buf.readUByte(); - total += x; - } while (x >= 255); - - final byte[] section = new byte[total]; - buf.readBytes(section, total); - this.sections[i] = section; - } + } + this.packets = new byte[count][]; + for (int i = 0; i < count; ++i) { + int total = 0; + int x; + do { + x = buf.readUByte(); + total += x; + } while (x >= 255); + final byte[] packet = new byte[total]; + buf.readBytes(packet, total); + this.packets[i] = packet; } } public void b720() { this._M = 0; - this._n = new float[_r]; - for (int i = 0; i < this.sections.length; ++i) { - this.e875(i); + this.prevWindow = new float[blocksize1]; + for (int i = 0; i < this.packets.length; ++i) { + this.decodeAudioPacket(i); } } } diff --git a/src/main/java/funorb/audio/VorbisMapping.java b/src/main/java/funorb/audio/VorbisMapping.java new file mode 100644 index 0000000..1e32a2a --- /dev/null +++ b/src/main/java/funorb/audio/VorbisMapping.java @@ -0,0 +1,35 @@ +package funorb.audio; + +public final class VorbisMapping { + public final int[] floor; + public final int[] residues; + public final int submaps; + public int mux; + + public VorbisMapping() { + VorbisFormat.readBits(16); // map type (unused) + + this.submaps = VorbisFormat.readBit() != 0 ? VorbisFormat.readBits(4) + 1 : 1; + + // vorbis mapping coupling steps (unused by this decoder) + if (VorbisFormat.readBit() != 0) { + VorbisFormat.readBits(8); + } + + VorbisFormat.readBits(2); // reserved + + if (this.submaps > 1) { + this.mux = VorbisFormat.readBits(4); + } + + this.floor = new int[this.submaps]; + this.residues = new int[this.submaps]; + + for (int i = 0; i < this.submaps; ++i) { + VorbisFormat.readBits(8); + this.floor[i] = VorbisFormat.readBits(8); + this.residues[i] = VorbisFormat.readBits(8); + } + + } +} diff --git a/src/main/java/funorb/audio/VorbisResidues.java b/src/main/java/funorb/audio/VorbisResidues.java new file mode 100644 index 0000000..6923013 --- /dev/null +++ b/src/main/java/funorb/audio/VorbisResidues.java @@ -0,0 +1,112 @@ +package funorb.audio; + +public final class VorbisResidues { + // vorbis spec uses a [resClassifications][8] array of ints, but resBook + // is a flattened array containing [resClassifications*8] entries + private final int[] resBooks; + private final int _c; + private final int resBegin; + private final int resEnd; + private final int resPartitionSize; + private final int resClassifications; + private final int resClassbook; + + public VorbisResidues() { + this._c = VorbisFormat.readBits(16); + this.resBegin = VorbisFormat.readBits(24); + this.resEnd = VorbisFormat.readBits(24); + this.resPartitionSize = VorbisFormat.readBits(24) + 1; + this.resClassifications = VorbisFormat.readBits(6) + 1; + this.resClassbook = VorbisFormat.readBits(8); + + final int[] resCascade = new int[this.resClassifications]; + for (int i = 0; i < this.resClassifications; ++i) { + int highBits = 0; + final int lowBits = VorbisFormat.readBits(3); + final boolean bitflag = VorbisFormat.readBit() != 0; + if (bitflag) { + highBits = VorbisFormat.readBits(5); + } + resCascade[i] = highBits << 3 | lowBits; + } + + this.resBooks = new int[this.resClassifications * 8]; + for (int i = 0; i < this.resClassifications * 8; ++i) { + this.resBooks[i] = (resCascade[i >> 3] & 1 << (i & 7)) != 0 + ? VorbisFormat.readBits(8) + : -1; + } + } + + public void a623(final float[] var1, final int var2, final boolean var3) { + int var4; + for (var4 = 0; var4 < var2; ++var4) { + var1[var4] = 0.0F; + } + + if (!var3) { + var4 = VorbisFormat.codebooks[this.resClassbook].cbDim; + final int var5 = this.resEnd - this.resBegin; + final int var6 = var5 / this.resPartitionSize; + final int[] var7 = new int[var6]; + + for (int var8 = 0; var8 < 8; ++var8) { + int var9 = 0; + + while (var9 < var6) { + int var10; + int var11; + if (var8 == 0) { + var10 = VorbisFormat.codebooks[this.resClassbook].a784(); + + for (var11 = var4 - 1; var11 >= 0; --var11) { + if (var9 + var11 < var6) { + var7[var9 + var11] = var10 % this.resClassifications; + } + + var10 /= this.resClassifications; + } + } + + for (var10 = 0; var10 < var4; ++var10) { + var11 = var7[var9]; + final int var12 = this.resBooks[var11 * 8 + var8]; + if (var12 >= 0) { + final int var13 = this.resBegin + var9 * this.resPartitionSize; + final VorbisCodebook var14 = VorbisFormat.codebooks[var12]; + int var15; + if (this._c == 0) { + var15 = this.resPartitionSize / var14.cbDim; + + for (int var19 = 0; var19 < var15; ++var19) { + final float[] var20 = var14.c932(); + + for (int var18 = 0; var18 < var14.cbDim; ++var18) { + var1[var13 + var19 + var18 * var15] += var20[var18]; + } + } + } else { + var15 = 0; + + while (var15 < this.resPartitionSize) { + final float[] var16 = var14.c932(); + + for (int var17 = 0; var17 < var14.cbDim; ++var17) { + var1[var13 + var15] += var16[var17]; + ++var15; + } + } + } + } + + ++var9; + if (var9 >= var6) { + break; + } + } + } + } + + } + } +} diff --git a/src/main/java/funorb/audio/fq_.java b/src/main/java/funorb/audio/fq_.java deleted file mode 100644 index 605f63c..0000000 --- a/src/main/java/funorb/audio/fq_.java +++ /dev/null @@ -1,31 +0,0 @@ -package funorb.audio; - -public final class fq_ { - public final int[] _b; - public final int[] _a; - public final int _c; - public int _d; - - public fq_() { - FmtVorbis.readBits(16); - this._c = FmtVorbis.readBit() != 0 ? FmtVorbis.readBits(4) + 1 : 1; - if (FmtVorbis.readBit() != 0) { - FmtVorbis.readBits(8); - } - - FmtVorbis.readBits(2); - if (this._c > 1) { - this._d = FmtVorbis.readBits(4); - } - - this._b = new int[this._c]; - this._a = new int[this._c]; - - for (int var1 = 0; var1 < this._c; ++var1) { - FmtVorbis.readBits(8); - this._b[var1] = FmtVorbis.readBits(8); - this._a[var1] = FmtVorbis.readBits(8); - } - - } -} diff --git a/src/main/java/funorb/audio/kn_.java b/src/main/java/funorb/audio/kn_.java deleted file mode 100644 index b7f50c0..0000000 --- a/src/main/java/funorb/audio/kn_.java +++ /dev/null @@ -1,357 +0,0 @@ -package funorb.audio; - -import funorb.util.BitMath; - -public final class kn_ { - private static final float[] EXP_LUT_16_1024 = new float[]{ - 1.0649863E-7F, 1.1341951E-7F, 1.2079015E-7F, 1.2863978E-7F, - 1.369995E-7F, 1.459025E-7F, 1.5538409E-7F, 1.6548181E-7F, - 1.7623574E-7F, 1.8768856E-7F, 1.998856E-7F, 2.128753E-7F, - 2.2670913E-7F, 2.4144197E-7F, 2.5713223E-7F, 2.7384212E-7F, - 2.9163792E-7F, 3.1059022E-7F, 3.307741E-7F, 3.5226967E-7F, - 3.7516213E-7F, 3.995423E-7F, 4.255068E-7F, 4.5315863E-7F, - 4.8260745E-7F, 5.1397E-7F, 5.4737063E-7F, 5.829419E-7F, - 6.208247E-7F, 6.611694E-7F, 7.041359E-7F, 7.4989464E-7F, - - 7.98627E-7F, 8.505263E-7F, 9.057983E-7F, 9.646621E-7F, - 1.0273513E-6F, 1.0941144E-6F, 1.1652161E-6F, 1.2409384E-6F, - 1.3215816E-6F, 1.4074654E-6F, 1.4989305E-6F, 1.5963394E-6F, - 1.7000785E-6F, 1.8105592E-6F, 1.9282195E-6F, 2.053526E-6F, - 2.1869757E-6F, 2.3290977E-6F, 2.4804558E-6F, 2.6416496E-6F, - 2.813319E-6F, 2.9961443E-6F, 3.1908505E-6F, 3.39821E-6F, - 3.619045E-6F, 3.8542307E-6F, 4.1047006E-6F, 4.371447E-6F, - 4.6555283E-6F, 4.958071E-6F, 5.280274E-6F, 5.623416E-6F, - - 5.988857E-6F, 6.3780467E-6F, 6.7925284E-6F, 7.2339453E-6F, - 7.704048E-6F, 8.2047E-6F, 8.737888E-6F, 9.305725E-6F, - 9.910464E-6F, 1.0554501E-5F, 1.1240392E-5F, 1.1970856E-5F, - 1.2748789E-5F, 1.3577278E-5F, 1.4459606E-5F, 1.5399271E-5F, - 1.6400005E-5F, 1.7465769E-5F, 1.8600793E-5F, 1.9809577E-5F, - 2.1096914E-5F, 2.2467912E-5F, 2.3928002E-5F, 2.5482977E-5F, - 2.7139005E-5F, 2.890265E-5F, 3.078091E-5F, 3.2781227E-5F, - 3.4911533E-5F, 3.718028E-5F, 3.9596467E-5F, 4.2169668E-5F, - - 4.491009E-5F, 4.7828602E-5F, 5.0936775E-5F, 5.424693E-5F, - 5.7772202E-5F, 6.152657E-5F, 6.552491E-5F, 6.9783084E-5F, - 7.4317984E-5F, 7.914758E-5F, 8.429104E-5F, 8.976875E-5F, - 9.560242E-5F, 1.0181521E-4F, 1.0843174E-4F, 1.1547824E-4F, - 1.2298267E-4F, 1.3097477E-4F, 1.3948625E-4F, 1.4855085E-4F, - 1.5820454E-4F, 1.6848555E-4F, 1.7943469E-4F, 1.9109536E-4F, - 2.0351382E-4F, 2.167393E-4F, 2.3082423E-4F, 2.4582449E-4F, - 2.6179955E-4F, 2.7881275E-4F, 2.9693157E-4F, 3.1622787E-4F, - - 3.3677815E-4F, 3.5866388E-4F, 3.8197188E-4F, 4.0679457E-4F, - 4.3323037E-4F, 4.613841E-4F, 4.913675E-4F, 5.2329927E-4F, - 5.573062E-4F, 5.935231E-4F, 6.320936E-4F, 6.731706E-4F, - 7.16917E-4F, 7.635063E-4F, 8.1312325E-4F, 8.6596457E-4F, - 9.2223985E-4F, 9.821722E-4F, 0.0010459992F, 0.0011139743F, - 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F, - 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F, - 0.0019632196F, 0.0020908006F, 0.0022266726F, 0.0023713743F, - - 0.0025254795F, 0.0026895993F, 0.0028643848F, 0.0030505287F, - 0.003248769F, 0.0034598925F, 0.0036847359F, 0.0039241905F, - 0.0041792067F, 0.004450795F, 0.004740033F, 0.005048067F, - 0.0053761187F, 0.005725489F, 0.0060975635F, 0.0064938175F, - 0.0069158226F, 0.0073652514F, 0.007843887F, 0.008353627F, - 0.008896492F, 0.009474637F, 0.010090352F, 0.01074608F, - 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F, - 0.014722068F, 0.015678791F, 0.016697686F, 0.017782796F, - - 0.018938422F, 0.020169148F, 0.021479854F, 0.022875736F, - 0.02436233F, 0.025945531F, 0.027631618F, 0.029427277F, - 0.031339627F, 0.03337625F, 0.035545226F, 0.037855156F, - 0.0403152F, 0.042935107F, 0.045725275F, 0.048696756F, - 0.05186135F, 0.05523159F, 0.05882085F, 0.062643364F, - 0.06671428F, 0.07104975F, 0.075666964F, 0.08058423F, - 0.08582105F, 0.09139818F, 0.097337745F, 0.1036633F, - 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F, - - 0.14201812F, 0.15124726F, 0.16107617F, 0.1715438F, - 0.18269168F, 0.19456401F, 0.20720787F, 0.22067343F, - 0.23501402F, 0.25028655F, 0.26655158F, 0.28387362F, - 0.3023213F, 0.32196787F, 0.34289113F, 0.36517414F, - 0.3889052F, 0.41417846F, 0.44109413F, 0.4697589F, - 0.50028646F, 0.53279793F, 0.5674221F, 0.6042964F, - 0.64356697F, 0.6853896F, 0.72993004F, 0.777365F, - 0.8278826F, 0.88168305F, 0.9389798F, 1.0F}; - private static final int[] _a = new int[]{256, 128, 86, 64}; - private static boolean[] _g; - private static int[] _i; - private static int[] _d; - private final int[] _f; - private final int[] _c; - private final int[][] _k; - private final int[] _l; - private final int[] _h; - private final int _b; - private final int[] _e; - - public kn_() { - final int var1 = FmtVorbis.readBits(16); - if (var1 == 1) { - final int var2 = FmtVorbis.readBits(5); - int var3 = 0; - this._l = new int[var2]; - - int var4; - int var5; - for (var4 = 0; var4 < var2; ++var4) { - var5 = FmtVorbis.readBits(4); - this._l[var4] = var5; - if (var5 >= var3) { - var3 = var5 + 1; - } - } - - this._e = new int[var3]; - this._c = new int[var3]; - this._h = new int[var3]; - this._k = new int[var3][]; - - int var7; - for (var4 = 0; var4 < var3; ++var4) { - this._e[var4] = FmtVorbis.readBits(3) + 1; - var5 = this._c[var4] = FmtVorbis.readBits(2); - if (var5 != 0) { - this._h[var4] = FmtVorbis.readBits(8); - } - - var5 = 1 << var5; - final int[] var6 = new int[var5]; - this._k[var4] = var6; - - for (var7 = 0; var7 < var5; ++var7) { - var6[var7] = FmtVorbis.readBits(8) - 1; - } - } - - this._b = FmtVorbis.readBits(2) + 1; - var4 = FmtVorbis.readBits(4); - var5 = 2; - - int var9; - for (var9 = 0; var9 < var2; ++var9) { - var5 += this._e[this._l[var9]]; - } - - this._f = new int[var5]; - this._f[0] = 0; - this._f[1] = 1 << var4; - var5 = 2; - - for (var9 = 0; var9 < var2; ++var9) { - var7 = this._l[var9]; - - for (int var8 = 0; var8 < this._e[var7]; ++var8) { - this._f[var5++] = FmtVorbis.readBits(var4); - } - } - - if (_d == null || _d.length < var5) { - _d = new int[var5]; - _i = new int[var5]; - _g = new boolean[var5]; - } - - } else { - throw new RuntimeException(); - } - } - - private static int b691(final int[] var0, final int var1) { - final int var2 = var0[var1]; - int var3 = -1; - int var4 = Integer.MAX_VALUE; - - for (int var5 = 0; var5 < var1; ++var5) { - final int var6 = var0[var5]; - if (var6 > var2 && var6 < var4) { - var3 = var5; - var4 = var6; - } - } - - return var3; - } - - private static int a691(final int[] var0, final int var1) { - final int var2 = var0[var1]; - int var3 = -1; - int var4 = Integer.MIN_VALUE; - - for (int var5 = 0; var5 < var1; ++var5) { - final int var6 = var0[var5]; - if (var6 < var2 && var6 > var4) { - var3 = var5; - var4 = var6; - } - } - - return var3; - } - - public boolean b801() { - final boolean var1 = FmtVorbis.readBit() != 0; - if (var1) { - final int var2 = this._f.length; - - int var3; - for (var3 = 0; var3 < var2; ++var3) { - _d[var3] = this._f[var3]; - } - - var3 = _a[this._b - 1]; - final int var4 = BitMath.lastSet(var3 - 1); - _i[0] = FmtVorbis.readBits(var4); - _i[1] = FmtVorbis.readBits(var4); - int var5 = 2; - - for (final int var7 : this._l) { - final int var8 = this._e[var7]; - final int var9 = this._c[var7]; - final int var10 = (1 << var9) - 1; - int var11 = 0; - if (var9 > 0) { - var11 = FmtVorbis._L[this._h[var7]].a784(); - } - - for (int var12 = 0; var12 < var8; ++var12) { - final int var13 = this._k[var7][var11 & var10]; - var11 >>>= var9; - _i[var5++] = var13 >= 0 ? FmtVorbis._L[var13].a784() : 0; - } - } - - return true; - } else { - return false; - } - } - - private void a093(final int var1, final int var2) { - if (var1 < var2) { - int var3 = var1; - final int var4 = _d[var1]; - final int var5 = _i[var1]; - final boolean var6 = _g[var1]; - - for (int var7 = var1 + 1; var7 <= var2; ++var7) { - final int var8 = _d[var7]; - if (var8 < var4) { - _d[var3] = var8; - _i[var3] = _i[var7]; - _g[var3] = _g[var7]; - ++var3; - _d[var7] = _d[var3]; - _i[var7] = _i[var3]; - _g[var7] = _g[var3]; - } - } - - _d[var3] = var4; - _i[var3] = var5; - _g[var3] = var6; - this.a093(var1, var3 - 1); - this.a093(var3 + 1, var2); - } - } - - private int a063(final int var1, final int var2, final int var3, final int var4, final int var5) { - final int var6 = var4 - var2; - final int var7 = var3 - var1; - final int var8 = var6 < 0 ? -var6 : var6; - final int var9 = var8 * (var5 - var1); - final int var10 = var9 / var7; - return var6 < 0 ? var2 - var10 : var2 + var10; - } - - private void a365(final int var1, final int var2, int var3, final int var4, final float[] var5, final int var6) { - final int var7 = var4 - var2; - final int var8 = var3 - var1; - int var9 = var7 < 0 ? -var7 : var7; - final int var10 = var7 / var8; - int var11 = var2; - int var12 = 0; - final int var13 = var7 < 0 ? var10 - 1 : var10 + 1; - var9 -= (var10 < 0 ? -var10 : var10) * var8; - var5[var1] *= EXP_LUT_16_1024[var2]; - if (var3 > var6) { - var3 = var6; - } - - for (int var14 = var1 + 1; var14 < var3; ++var14) { - var12 += var9; - if (var12 >= var8) { - var12 -= var8; - var11 += var13; - } else { - var11 += var10; - } - - var5[var14] *= EXP_LUT_16_1024[var11]; - } - - } - - public void a331(final float[] var1, final int var2) { - final int var3 = this._f.length; - final int var4 = _a[this._b - 1]; - final boolean[] var5 = _g; - _g[1] = true; - var5[0] = true; - - int var6; - int var7; - int var8; - int var9; - int var10; - for (var6 = 2; var6 < var3; ++var6) { - var7 = a691(_d, var6); - var8 = b691(_d, var6); - var9 = this.a063(_d[var7], _i[var7], _d[var8], _i[var8], _d[var6]); - var10 = _i[var6]; - final int var11 = var4 - var9; - final int var13 = (Math.min(var11, var9)) << 1; - if (var10 == 0) { - _g[var6] = false; - _i[var6] = var9; - } else { - final boolean[] var14 = _g; - _g[var8] = true; - var14[var7] = true; - _g[var6] = true; - if (var10 >= var13) { - _i[var6] = var11 > var9 ? var10 - var9 + var9 : var9 - var10 + var11 - 1; - } else { - _i[var6] = (var10 & 1) != 0 ? var9 - (var10 + 1) / 2 : var9 + var10 / 2; - } - } - } - - this.a093(0, var3 - 1); - var6 = 0; - var7 = _i[0] * this._b; - - for (var8 = 1; var8 < var3; ++var8) { - if (_g[var8]) { - var9 = _d[var8]; - var10 = _i[var8] * this._b; - this.a365(var6, var7, var9, var10, var1, var2); - if (var9 >= var2) { - return; - } - - var6 = var9; - var7 = var10; - } - } - - final float var16 = EXP_LUT_16_1024[var7]; - - for (var9 = var6; var9 < var2; ++var9) { - var1[var9] *= var16; - } - - } -} diff --git a/src/main/java/funorb/audio/to_.java b/src/main/java/funorb/audio/to_.java deleted file mode 100644 index 58b947b..0000000 --- a/src/main/java/funorb/audio/to_.java +++ /dev/null @@ -1,113 +0,0 @@ -package funorb.audio; - -public final class to_ { - private final int[] _e; - private final int _c; - private final int _g; - private final int _d; - private final int _b; - private final int _a; - private final int _f; - - public to_() { - this._c = FmtVorbis.readBits(16); - this._g = FmtVorbis.readBits(24); - this._d = FmtVorbis.readBits(24); - this._b = FmtVorbis.readBits(24) + 1; - this._a = FmtVorbis.readBits(6) + 1; - this._f = FmtVorbis.readBits(8); - - final int[] var1 = new int[this._a]; - - int var2; - for (var2 = 0; var2 < this._a; ++var2) { - int var3 = 0; - final int var4 = FmtVorbis.readBits(3); - final boolean var5 = FmtVorbis.readBit() != 0; - if (var5) { - var3 = FmtVorbis.readBits(5); - } - - var1[var2] = var3 << 3 | var4; - } - - this._e = new int[this._a * 8]; - - for (var2 = 0; var2 < this._a * 8; ++var2) { - this._e[var2] = (var1[var2 >> 3] & 1 << (var2 & 7)) != 0 ? FmtVorbis.readBits(8) : -1; - } - - } - - public void a623(final float[] var1, final int var2, final boolean var3) { - int var4; - for (var4 = 0; var4 < var2; ++var4) { - var1[var4] = 0.0F; - } - - if (!var3) { - var4 = FmtVorbis._L[this._f]._a; - final int var5 = this._d - this._g; - final int var6 = var5 / this._b; - final int[] var7 = new int[var6]; - - for (int var8 = 0; var8 < 8; ++var8) { - int var9 = 0; - - while (var9 < var6) { - int var10; - int var11; - if (var8 == 0) { - var10 = FmtVorbis._L[this._f].a784(); - - for (var11 = var4 - 1; var11 >= 0; --var11) { - if (var9 + var11 < var6) { - var7[var9 + var11] = var10 % this._a; - } - - var10 /= this._a; - } - } - - for (var10 = 0; var10 < var4; ++var10) { - var11 = var7[var9]; - final int var12 = this._e[var11 * 8 + var8]; - if (var12 >= 0) { - final int var13 = this._g + var9 * this._b; - final vb_ var14 = FmtVorbis._L[var12]; - int var15; - if (this._c == 0) { - var15 = this._b / var14._a; - - for (int var19 = 0; var19 < var15; ++var19) { - final float[] var20 = var14.c932(); - - for (int var18 = 0; var18 < var14._a; ++var18) { - var1[var13 + var19 + var18 * var15] += var20[var18]; - } - } - } else { - var15 = 0; - - while (var15 < this._b) { - final float[] var16 = var14.c932(); - - for (int var17 = 0; var17 < var14._a; ++var17) { - var1[var13 + var15] += var16[var17]; - ++var15; - } - } - } - } - - ++var9; - if (var9 >= var6) { - break; - } - } - } - } - - } - } -} diff --git a/src/main/java/funorb/audio/vb_.java b/src/main/java/funorb/audio/vb_.java deleted file mode 100644 index 668fed3..0000000 --- a/src/main/java/funorb/audio/vb_.java +++ /dev/null @@ -1,232 +0,0 @@ -package funorb.audio; - -import funorb.util.BitMath; - -public final class vb_ { - public final int _a; - private final int _c; - private final int[] _b; - private float[][] _d; - private int[] _f; - - public vb_() { - FmtVorbis.readBits(24); - this._a = FmtVorbis.readBits(16); - this._c = FmtVorbis.readBits(24); - this._b = new int[this._c]; - final boolean var1 = FmtVorbis.readBit() != 0; - int var2; - int var3; - int var5; - if (var1) { - var2 = 0; - - for (var3 = FmtVorbis.readBits(5) + 1; var2 < this._c; ++var3) { - final int var4 = FmtVorbis.readBits(BitMath.lastSet(this._c - var2)); - - for (var5 = 0; var5 < var4; ++var5) { - this._b[var2++] = var3; - } - } - } else { - final boolean var14 = FmtVorbis.readBit() != 0; - - for (var3 = 0; var3 < this._c; ++var3) { - if (var14 && FmtVorbis.readBit() == 0) { - this._b[var3] = 0; - } else { - this._b[var3] = FmtVorbis.readBits(5) + 1; - } - } - } - - this.b797(); - var2 = FmtVorbis.readBits(4); - if (var2 > 0) { - final float var15 = FmtVorbis.parseAsFloat(FmtVorbis.readBits(32)); - final float var16 = FmtVorbis.parseAsFloat(FmtVorbis.readBits(32)); - var5 = FmtVorbis.readBits(4) + 1; - final boolean var6 = FmtVorbis.readBit() != 0; - final int var7; - if (var2 == 1) { - var7 = a080(this._c, this._a); - } else { - var7 = this._c * this._a; - } - - final int[] _e = new int[var7]; - - int var8; - for (var8 = 0; var8 < var7; ++var8) { - _e[var8] = FmtVorbis.readBits(var5); - } - - this._d = new float[this._c][this._a]; - float var9; - int var10; - int var11; - if (var2 == 1) { - for (var8 = 0; var8 < this._c; ++var8) { - var9 = 0.0F; - var10 = 1; - - for (var11 = 0; var11 < this._a; ++var11) { - final int var12 = var8 / var10 % var7; - final float var13 = (float) _e[var12] * var16 + var15 + var9; - this._d[var8][var11] = var13; - if (var6) { - var9 = var13; - } - - var10 *= var7; - } - } - } else { - for (var8 = 0; var8 < this._c; ++var8) { - var9 = 0.0F; - var10 = var8 * this._a; - - for (var11 = 0; var11 < this._a; ++var11) { - final float var17 = (float) _e[var10] * var16 + var15 + var9; - this._d[var8][var11] = var17; - if (var6) { - var9 = var17; - } - - ++var10; - } - } - } - } - - } - - private static int a080(final int var0, final int var1) { - int var2 = (int) Math.pow(var0, 1.0D / (double) var1) + 1; - while (a776em(var2, var1) > var0) { - --var2; - } - return var2; - } - - private static int a776em(int var0, int var1) { - int var2; - for (var2 = 1; var1 > 1; var0 *= var0) { - if ((var1 & 1) != 0) { - var2 *= var0; - } - - var1 >>= 1; - } - - if (var1 == 1) { - return var2 * var0; - } else { - return var2; - } - } - - public float[] c932() { - return this._d[this.a784()]; - } - - public int a784() { - int var1 = 0; - while (this._f[var1] >= 0) { - var1 = FmtVorbis.readBit() != 0 ? this._f[var1] : var1 + 1; - } - return ~this._f[var1]; - } - - private void b797() { - final int[] var1 = new int[this._c]; - final int[] var2 = new int[33]; - - int var3; - int var4; - int var5; - int var6; - int var7; - int var8; - int var10; - for (var3 = 0; var3 < this._c; ++var3) { - var4 = this._b[var3]; - if (var4 != 0) { - var5 = 1 << 32 - var4; - var6 = var2[var4]; - var1[var3] = var6; - int var9; - if ((var6 & var5) == 0) { - var7 = var6 | var5; - - for (var8 = var4 - 1; var8 >= 1; --var8) { - var9 = var2[var8]; - if (var9 != var6) { - break; - } - - var10 = 1 << 32 - var8; - if ((var9 & var10) != 0) { - var2[var8] = var2[var8 - 1]; - break; - } - - var2[var8] = var9 | var10; - } - } else { - var7 = var2[var4 - 1]; - } - - var2[var4] = var7; - - for (var8 = var4 + 1; var8 <= 32; ++var8) { - var9 = var2[var8]; - if (var9 == var6) { - var2[var8] = var7; - } - } - } - } - - this._f = new int[8]; - int var11 = 0; - - for (var3 = 0; var3 < this._c; ++var3) { - var4 = this._b[var3]; - if (var4 != 0) { - var5 = var1[var3]; - var6 = 0; - - for (var7 = 0; var7 < var4; ++var7) { - var8 = Integer.MIN_VALUE >>> var7; - if ((var5 & var8) == 0) { - ++var6; - } else { - if (this._f[var6] == 0) { - this._f[var6] = var11; - } - - var6 = this._f[var6]; - } - - if (var6 >= this._f.length) { - final int[] var12 = new int[this._f.length * 2]; - - for (var10 = 0; var10 < this._f.length; ++var10) { - var12[var10] = this._f[var10]; - } - - this._f = var12; - } - - } - - this._f[var6] = ~var3; - if (var6 >= var11) { - var11 = var6 + 1; - } - } - } - - } -} diff --git a/src/main/java/funorb/client/intro/JagexLogoIntroAnimation.java b/src/main/java/funorb/client/intro/JagexLogoIntroAnimation.java index 8ad3220..16ea077 100644 --- a/src/main/java/funorb/client/intro/JagexLogoIntroAnimation.java +++ b/src/main/java/funorb/client/intro/JagexLogoIntroAnimation.java @@ -1,6 +1,6 @@ package funorb.client.intro; -import funorb.audio.FmtVorbis; +import funorb.audio.VorbisFormat; import funorb.cache.ResourceLoader; import funorb.client.JagexBaseApplet; import funorb.graphics.Drawing; @@ -57,8 +57,8 @@ public final class JagexLogoIntroAnimation { } private static void load1(final ResourceLoader loader) { - FmtVorbis.b604(loader.getResource("headers.packvorbis", "")); - final FmtVorbis var2 = FmtVorbis.a968(loader, "jagex logo2.packvorbis", ""); + VorbisFormat.readIdentificationAndSetup(loader.getResource("headers.packvorbis", "")); + final VorbisFormat var2 = VorbisFormat.loadAudio(loader, "jagex logo2.packvorbis", ""); assert var2 != null; var2.b720(); }