www in docker support

This commit is contained in:
MaddoScientisto 2026-04-22 18:41:37 +02:00
commit c227fce036
2145 changed files with 399596 additions and 58 deletions

View file

@ -0,0 +1,39 @@
package org.jcodec.codecs.mpa;
class ChannelSynthesizer {
private float[][] v;
private int pos;
private float scalefactor;
private int current;
public ChannelSynthesizer(int channelnumber, float factor) {
this.v = new float[2][512];
this.scalefactor = factor;
this.pos = 15;
}
private static void distributeSamples(int pos, float[] dest, float[] next, float[] s) {
for (int m = 0; m < 16; m++)
dest[(m << 4) + pos] = s[m];
for (int k = 1; k < 17; k++)
next[(k << 4) + pos] = s[15 + k];
dest[256 + pos] = 0.0F;
next[0 + pos] = -s[0];
for (int j = 0; j < 15; j++)
dest[272 + (j << 4) + pos] = -s[15 - j];
for (int i = 0; i < 15; i++)
next[272 + (i << 4) + pos] = s[30 - i];
}
public void synthesize(float[] coeffs, short[] out, int off) {
MpaPqmf.computeButterfly(this.pos, coeffs);
int next = (this.current ^ 0xFFFFFFFF) & 0x1;
distributeSamples(this.pos, this.v[this.current], this.v[next], coeffs);
MpaPqmf.computeFilter(this.pos, this.v[this.current], out, off, this.scalefactor);
this.pos = this.pos + 1 & 0xF;
this.current = next;
}
}

View file

@ -0,0 +1,400 @@
package org.jcodec.codecs.mpa;
import java.nio.ByteBuffer;
import org.jcodec.common.Vector2Int;
import org.jcodec.common.Vector4Int;
import org.jcodec.common.io.BitReader;
import org.jcodec.common.tools.MathUtil;
public class Mp3Bitstream {
static class MP3SideInfo {
int mainDataBegin;
int privateBits;
boolean[][] scfsi = new boolean[2][4];
Mp3Bitstream.Granule[][] granule = new Mp3Bitstream.Granule[][] { new Mp3Bitstream.Granule[] { new Mp3Bitstream.Granule(), new Mp3Bitstream.Granule() }, new Mp3Bitstream.Granule[] { new Mp3Bitstream.Granule(), new Mp3Bitstream.Granule() } };
}
static class Granule {
int part23Length;
int bigValues;
int globalGain;
int scalefacCompress;
boolean windowSwitchingFlag;
int blockType;
boolean mixedBlockFlag;
int[] tableSelect = new int[3];
int[] subblockGain = new int[3];
int region0Count;
int region1Count;
boolean preflag;
int scalefacScale;
int count1tableSelect;
}
static class ScaleFactors {
int[] large = new int[23];
int[][] small = new int[3][13];
}
static MP3SideInfo readSideInfo(MpaHeader header, ByteBuffer src, int channels) {
MP3SideInfo si = new MP3SideInfo();
BitReader stream = BitReader.createBitReader(src);
if (header.version == 1) {
si.mainDataBegin = stream.readNBit(9);
if (channels == 1) {
si.privateBits = stream.readNBit(5);
} else {
si.privateBits = stream.readNBit(3);
}
for (int ch = 0; ch < channels; ch++) {
si.scfsi[ch][0] = (stream.read1Bit() == 0);
si.scfsi[ch][1] = (stream.read1Bit() == 0);
si.scfsi[ch][2] = (stream.read1Bit() == 0);
si.scfsi[ch][3] = (stream.read1Bit() == 0);
}
for (int gr = 0; gr < 2; gr++) {
for (int i = 0; i < channels; i++) {
Granule granule = si.granule[i][gr];
granule.part23Length = stream.readNBit(12);
granule.bigValues = stream.readNBit(9);
granule.globalGain = stream.readNBit(8);
granule.scalefacCompress = stream.readNBit(4);
granule.windowSwitchingFlag = (stream.readNBit(1) != 0);
if (granule.windowSwitchingFlag) {
granule.blockType = stream.readNBit(2);
granule.mixedBlockFlag = (stream.readNBit(1) != 0);
granule.tableSelect[0] = stream.readNBit(5);
granule.tableSelect[1] = stream.readNBit(5);
granule.subblockGain[0] = stream.readNBit(3);
granule.subblockGain[1] = stream.readNBit(3);
granule.subblockGain[2] = stream.readNBit(3);
if (granule.blockType == 0)
return null;
if (granule.blockType == 2 && !granule.mixedBlockFlag) {
granule.region0Count = 8;
} else {
granule.region0Count = 7;
}
granule.region1Count = 20 - granule.region0Count;
} else {
granule.tableSelect[0] = stream.readNBit(5);
granule.tableSelect[1] = stream.readNBit(5);
granule.tableSelect[2] = stream.readNBit(5);
granule.region0Count = stream.readNBit(4);
granule.region1Count = stream.readNBit(3);
granule.blockType = 0;
}
granule.preflag = (stream.readNBit(1) != 0);
granule.scalefacScale = stream.readNBit(1);
granule.count1tableSelect = stream.readNBit(1);
}
}
} else {
si.mainDataBegin = stream.readNBit(8);
if (channels == 1) {
si.privateBits = stream.readNBit(1);
} else {
si.privateBits = stream.readNBit(2);
}
for (int ch = 0; ch < channels; ch++) {
Granule granule = si.granule[ch][0];
granule.part23Length = stream.readNBit(12);
granule.bigValues = stream.readNBit(9);
granule.globalGain = stream.readNBit(8);
granule.scalefacCompress = stream.readNBit(9);
granule.windowSwitchingFlag = (stream.readNBit(1) != 0);
if (granule.windowSwitchingFlag) {
granule.blockType = stream.readNBit(2);
granule.mixedBlockFlag = (stream.readNBit(1) != 0);
granule.tableSelect[0] = stream.readNBit(5);
granule.tableSelect[1] = stream.readNBit(5);
granule.subblockGain[0] = stream.readNBit(3);
granule.subblockGain[1] = stream.readNBit(3);
granule.subblockGain[2] = stream.readNBit(3);
if (granule.blockType == 0)
return null;
if (granule.blockType == 2 && !granule.mixedBlockFlag) {
granule.region0Count = 8;
} else {
granule.region0Count = 7;
granule.region1Count = 20 - granule.region0Count;
}
} else {
granule.tableSelect[0] = stream.readNBit(5);
granule.tableSelect[1] = stream.readNBit(5);
granule.tableSelect[2] = stream.readNBit(5);
granule.region0Count = stream.readNBit(4);
granule.region1Count = stream.readNBit(3);
granule.blockType = 0;
}
granule.scalefacScale = stream.readNBit(1);
granule.count1tableSelect = stream.readNBit(1);
}
}
stream.terminate();
return si;
}
static ScaleFactors readScaleFactors(BitReader br, Granule granule, boolean[] b) {
if (granule.windowSwitchingFlag && granule.blockType == 2) {
if (granule.mixedBlockFlag)
return readScaleFacMixed(br, granule);
return readScaleFacShort(br, granule);
}
return readScaleFacNonSwitch(br, granule, b);
}
private static ScaleFactors readScaleFacMixed(BitReader br, Granule granule) {
ScaleFactors sf = new ScaleFactors();
for (int k = 0; k < 8; k++)
sf.large[k] = br.readNBit(MpaConst.scaleFactorLen[0][granule.scalefacCompress]);
for (int j = 3; j < 6; j++) {
for (int m = 0; m < 3; m++)
sf.small[m][j] = br.readNBit(MpaConst.scaleFactorLen[0][granule.scalefacCompress]);
}
for (int i = 6; i < 12; i++) {
for (int m = 0; m < 3; m++)
sf.small[m][i] = br.readNBit(MpaConst.scaleFactorLen[1][granule.scalefacCompress]);
}
for (int sfb = 12, window = 0; window < 3; window++)
sf.small[window][sfb] = 0;
return sf;
}
private static ScaleFactors readScaleFacNonSwitch(BitReader br, Granule granule, boolean[] b) {
ScaleFactors sf = new ScaleFactors();
int length0 = MpaConst.scaleFactorLen[0][granule.scalefacCompress];
int length1 = MpaConst.scaleFactorLen[1][granule.scalefacCompress];
if (b[0])
for (int i = 0; i < 6; i++)
sf.large[i] = br.readNBit(length0);
if (b[1])
for (int i = 6; i < 11; i++)
sf.large[i] = br.readNBit(length0);
if (b[2])
for (int i = 11; i < 16; i++)
sf.large[i] = br.readNBit(length1);
if (b[3])
for (int i = 16; i < 21; i++)
sf.large[i] = br.readNBit(length1);
sf.large[21] = 0;
sf.large[22] = 0;
return sf;
}
private static ScaleFactors readScaleFacShort(BitReader br, Granule granule) {
ScaleFactors sf = new ScaleFactors();
int length0 = MpaConst.scaleFactorLen[0][granule.scalefacCompress];
int length1 = MpaConst.scaleFactorLen[1][granule.scalefacCompress];
for (int j = 0; j < 6; j++) {
for (int k = 0; k < 3; k++)
sf.small[k][j] = br.readNBit(length0);
}
for (int i = 6; i < 12; i++) {
for (int k = 0; k < 3; k++)
sf.small[k][i] = br.readNBit(length1);
}
sf.small[0][12] = 0;
sf.small[1][12] = 0;
sf.small[2][12] = 0;
return sf;
}
static ScaleFactors readLSFScaleFactors(BitReader br, MpaHeader header, Granule granule, int ch) {
ScaleFactors scalefac = new ScaleFactors();
int[] scalefacBuffer = readLSFScaleData(br, header, granule, ch);
int m = 0;
if (granule.windowSwitchingFlag && granule.blockType == 2) {
if (granule.mixedBlockFlag) {
for (int i = 0; i < 8; i++) {
scalefac.large[i] = scalefacBuffer[m];
m++;
}
for (int sfb = 3; sfb < 12; sfb++) {
for (int j = 0; j < 3; j++) {
scalefac.small[j][sfb] = scalefacBuffer[m];
m++;
}
}
for (int window = 0; window < 3; window++)
scalefac.small[window][12] = 0;
} else {
for (int sfb = 0; sfb < 12; sfb++) {
for (int i = 0; i < 3; i++) {
scalefac.small[i][sfb] = scalefacBuffer[m];
m++;
}
}
for (int window = 0; window < 3; window++)
scalefac.small[window][12] = 0;
}
} else {
for (int sfb = 0; sfb < 21; sfb++) {
scalefac.large[sfb] = scalefacBuffer[m];
m++;
}
scalefac.large[21] = 0;
scalefac.large[22] = 0;
}
return scalefac;
}
private static int[] readLSFScaleData(BitReader br, MpaHeader header, Granule granule, int ch) {
int[] result = new int[54];
int[] scaleFacLen = new int[4];
int comp = granule.scalefacCompress;
int blockType = (granule.blockType == 2) ? (granule.mixedBlockFlag ? 2 : 1) : 0;
boolean ch1 = ((header.modeExtension == 1 || header.modeExtension == 3) && ch == 1);
int lenType = 0;
if (!ch1) {
if (comp < 400) {
scaleFacLen[0] = (comp >>> 4) / 5;
scaleFacLen[1] = (comp >>> 4) % 5;
scaleFacLen[2] = (comp & 0xF) >>> 2;
scaleFacLen[3] = comp & 0x3;
granule.preflag = false;
lenType = 0;
} else if (comp < 500) {
scaleFacLen[0] = (comp - 400 >>> 2) / 5;
scaleFacLen[1] = (comp - 400 >>> 2) % 5;
scaleFacLen[2] = comp - 400 & 0x3;
scaleFacLen[3] = 0;
granule.preflag = false;
lenType = 1;
} else if (comp < 512) {
scaleFacLen[0] = (comp - 500) / 3;
scaleFacLen[1] = (comp - 500) % 3;
scaleFacLen[2] = 0;
scaleFacLen[3] = 0;
granule.preflag = true;
lenType = 2;
}
} else {
int halfComp = comp >>> 1;
if (halfComp < 180) {
scaleFacLen[0] = halfComp / 36;
scaleFacLen[1] = halfComp % 36 / 6;
scaleFacLen[2] = halfComp % 36 % 6;
scaleFacLen[3] = 0;
granule.preflag = false;
lenType = 3;
} else if (halfComp < 244) {
scaleFacLen[0] = (halfComp - 180 & 0x3F) >>> 4;
scaleFacLen[1] = (halfComp - 180 & 0xF) >>> 2;
scaleFacLen[2] = halfComp - 180 & 0x3;
scaleFacLen[3] = 0;
granule.preflag = false;
lenType = 4;
} else if (halfComp < 255) {
scaleFacLen[0] = (halfComp - 244) / 3;
scaleFacLen[1] = (halfComp - 244) % 3;
scaleFacLen[2] = 0;
scaleFacLen[3] = 0;
granule.preflag = false;
lenType = 5;
}
}
for (int i = 0, m = 0; i < 4; i++) {
for (int j = 0; j < MpaConst.numberOfScaleFactors[lenType][blockType][i]; j++, m++)
result[m] = (scaleFacLen[i] == 0) ? 0 : br.readNBit(scaleFacLen[i]);
}
return result;
}
static int readCoeffs(BitReader br, Granule granule, int ch, int part2_start, int sfreq, int[] out) {
int part23End = part2_start + granule.part23Length;
int region1Start = (sfreq == 8) ? 72 : 36;
int region2Start = 576;
if (!granule.windowSwitchingFlag || granule.blockType != 2) {
int region1StartIdx = MathUtil.clip(granule.region0Count + granule.region1Count + 2, 0, (MpaConst.sfbLong[sfreq]).length - 1);
region1Start = MpaConst.sfbLong[sfreq][granule.region0Count + 1];
region2Start = MpaConst.sfbLong[sfreq][region1StartIdx];
}
int index = 0;
for (int i = 0; i < granule.bigValues << 1; i += 2) {
int tab = 0;
if (i < region1Start) {
tab = granule.tableSelect[0];
} else if (i < region2Start) {
tab = granule.tableSelect[1];
} else {
tab = granule.tableSelect[2];
}
if (tab == 0 || tab == 4 || tab == 14) {
out[index++] = 0;
out[index++] = 0;
} else {
int packed = readBigVal(tab, br);
out[index++] = Vector2Int.el16_0(packed);
out[index++] = Vector2Int.el16_1(packed);
}
}
while (br.position() < part23End && index < 576) {
int packed = readCount1(granule.count1tableSelect, br);
out[index++] = Vector4Int.el8_0(packed);
out[index++] = Vector4Int.el8_1(packed);
out[index++] = Vector4Int.el8_2(packed);
out[index++] = Vector4Int.el8_3(packed);
}
if (br.position() < part23End)
br.readNBit(part23End - br.position());
return MathUtil.clip(index, 0, 576);
}
static int readBigVal(int tab, BitReader br) {
int res = MpaConst.bigValVlc[tab].readVLC(br);
int x = res >>> 4;
int y = res & 0xF;
if (MpaConst.bigValEscBits[tab] != 0 &&
MpaConst.bigValMaxval[tab] - 1 == x)
x += br.readNBit(MpaConst.bigValEscBits[tab]);
if (x != 0 &&
br.read1Bit() != 0)
x = -x;
if (MpaConst.bigValEscBits[tab] != 0 &&
MpaConst.bigValMaxval[tab] - 1 == y)
y += br.readNBit(MpaConst.bigValEscBits[tab]);
if (y != 0 &&
br.read1Bit() != 0)
y = -y;
return Vector2Int.pack16(x, y);
}
static int readCount1(int tab, BitReader br) {
int res = ((tab == 0) ? MpaConst.cnt1A : MpaConst.cnt1B).readVLC(br);
int v = res >> 3 & 0x1;
int w = res >> 2 & 0x1;
int x = res >> 1 & 0x1;
int y = res & 0x1;
if (v != 0 &&
br.read1Bit() != 0)
v = -v;
if (w != 0 &&
br.read1Bit() != 0)
w = -w;
if (x != 0 &&
br.read1Bit() != 0)
x = -x;
if (y != 0 &&
br.read1Bit() != 0)
y = -y;
return Vector4Int.pack8(v, w, x, y);
}
}

View file

@ -0,0 +1,271 @@
package org.jcodec.codecs.mpa;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import org.jcodec.common.AudioCodecMeta;
import org.jcodec.common.AudioDecoder;
import org.jcodec.common.AudioFormat;
import org.jcodec.common.io.BitReader;
import org.jcodec.common.io.NIOUtils;
import org.jcodec.common.model.AudioBuffer;
import org.jcodec.common.tools.MathUtil;
public class Mp3Decoder implements AudioDecoder {
private static final boolean[] ALL_TRUE = new boolean[] { true, true, true, true };
private static final int SAMPLES_PER_BAND = 18;
private static final int NUM_BANDS = 32;
private ChannelSynthesizer[] filter = new ChannelSynthesizer[] { null, null };
private boolean initialized;
private static final double fourByThree = 1.3333333333333333D;
private float[][] prevBlk;
private ByteBuffer frameData = ByteBuffer.allocate(4096);
private int channels;
private int sfreq;
private float[] samples = new float[32];
private float[] mdctIn = new float[18];
private float[] mdctOut = new float[36];
private float[][] dequant = new float[2][576];
private short[][] tmpOut = new short[2][576];
private void init(MpaHeader header) {
float scalefactor = 32700.0F;
this.channels = (header.mode == 3) ? 1 : 2;
this.filter[0] = new ChannelSynthesizer(0, scalefactor);
if (this.channels == 2)
this.filter[1] = new ChannelSynthesizer(1, scalefactor);
this.prevBlk = new float[2][576];
this.sfreq = header.sampleFreq + ((header.version == 1) ? 3 : ((header.version == 2) ? 6 : 0));
for (int ch = 0; ch < 2; ch++)
Arrays.fill(this.prevBlk[ch], 0.0F);
this.initialized = true;
}
private void decodeGranule(MpaHeader header, ByteBuffer output, Mp3Bitstream.MP3SideInfo si, BitReader br, Mp3Bitstream.ScaleFactors[] scalefac, int grInd) {
Arrays.fill(this.dequant[0], 0.0F);
Arrays.fill(this.dequant[1], 0.0F);
for (int ch = 0; ch < this.channels; ch++) {
int part2Start = br.position();
Mp3Bitstream.Granule granule = si.granule[ch][grInd];
if (header.version == 1) {
Mp3Bitstream.ScaleFactors old = scalefac[ch];
boolean[] scfi = (grInd == 0) ? ALL_TRUE : si.scfsi[ch];
scalefac[ch] = Mp3Bitstream.readScaleFactors(br, si.granule[ch][grInd], scfi);
mergeScaleFac(scalefac[ch], old, scfi);
} else {
scalefac[ch] = Mp3Bitstream.readLSFScaleFactors(br, header, granule, ch);
}
int[] coeffs = new int[580];
int nonzero = Mp3Bitstream.readCoeffs(br, granule, ch, part2Start, this.sfreq, coeffs);
dequantizeCoeffs(coeffs, nonzero, granule, scalefac[ch], this.dequant[ch]);
}
boolean msStereo = (header.mode == 1 && (header.modeExtension & 0x2) != 0);
if (msStereo && this.channels == 2)
decodeMsStereo(header, si.granule[0][grInd], scalefac, this.dequant);
for (int i = 0; i < this.channels; i++) {
float[] out = this.dequant[i];
Mp3Bitstream.Granule granule = si.granule[i][grInd];
antialias(granule, out);
mdctDecode(i, granule, out);
for (int sb18 = 18; sb18 < 576; sb18 += 36) {
for (int j = 1; j < 18; j += 2)
out[sb18 + j] = -out[sb18 + j];
}
for (int ss = 0, off = 0; ss < 18; ss++, off += 32) {
for (int j = 0, sb = 0; j < 576; j += 18, sb++)
this.samples[sb] = out[j + ss];
this.filter[i].synthesize(this.samples, this.tmpOut[i], off);
}
}
if (this.channels == 2) {
appendSamplesInterleave(output, this.tmpOut[0], this.tmpOut[1], 576);
} else {
appendSamples(output, this.tmpOut[0], 576);
}
}
public static void appendSamples(ByteBuffer buf, short[] f, int n) {
for (int i = 0; i < n; i++)
buf.putShort(f[i]);
}
public static void appendSamplesInterleave(ByteBuffer buf, short[] f0, short[] f1, int n) {
for (int i = 0; i < n; i++) {
buf.putShort(f0[i]);
buf.putShort(f1[i]);
}
}
private void mergeScaleFac(Mp3Bitstream.ScaleFactors sf, Mp3Bitstream.ScaleFactors old, boolean[] scfsi) {
if (!scfsi[0])
for (int i = 0; i < 6; i++)
sf.large[i] = old.large[i];
if (!scfsi[1])
for (int i = 6; i < 11; i++)
sf.large[i] = old.large[i];
if (!scfsi[2])
for (int i = 11; i < 16; i++)
sf.large[i] = old.large[i];
if (!scfsi[3])
for (int i = 16; i < 21; i++)
sf.large[i] = old.large[i];
}
private void dequantizeCoeffs(int[] input, int nonzero, Mp3Bitstream.Granule granule, Mp3Bitstream.ScaleFactors scalefac, float[] out) {
float globalGain = (float)Math.pow(2.0D, 0.25D * ((double)granule.globalGain - 210.0D));
if (granule.windowSwitchingFlag && granule.blockType == 2) {
if (granule.mixedBlockFlag) {
dequantMixed(input, nonzero, granule, scalefac, globalGain, out);
} else {
dequantShort(input, nonzero, granule, scalefac, globalGain, out);
}
} else {
dequantLong(input, nonzero, granule, scalefac, globalGain, out);
}
}
private void dequantMixed(int[] input, int nonzero, Mp3Bitstream.Granule granule, Mp3Bitstream.ScaleFactors scalefac, float globalGain, float[] out) {
int i = 0;
for (int j = 0; j < 8 && i < nonzero; j++) {
for (; i < MpaConst.sfbLong[this.sfreq][j + 1] && i < nonzero; i++) {
int idx = scalefac.large[j] + (granule.preflag ? MpaConst.pretab[j] : 0) << granule.scalefacScale;
out[i] = globalGain * pow43(input[i]) * MpaConst.quantizerTab[idx];
}
}
for (int sfb = 3; sfb < 12 && i < nonzero; sfb++) {
int sfbSz = MpaConst.sfbShort[this.sfreq][sfb + 1] - MpaConst.sfbShort[this.sfreq][sfb];
int sfbStart = i;
for (int wnd = 0; wnd < 3; wnd++) {
for (int k = 0; k < sfbSz && i < nonzero; k++, i++) {
int idx = (scalefac.small[wnd][sfb] << granule.scalefacScale) + (granule.subblockGain[wnd] << 2);
out[sfbStart + k * 3 + wnd] = globalGain * pow43(input[i]) * MpaConst.quantizerTab[idx];
}
}
}
}
private void dequantShort(int[] input, int nonzero, Mp3Bitstream.Granule granule, Mp3Bitstream.ScaleFactors scalefac, float globalGain, float[] out) {
for (int sfb = 0, i = 0; i < nonzero; sfb++) {
int sfbSz = MpaConst.sfbShort[this.sfreq][sfb + 1] - MpaConst.sfbShort[this.sfreq][sfb];
int sfbStart = i;
for (int wnd = 0; wnd < 3; wnd++) {
for (int j = 0; j < sfbSz && i < nonzero; j++, i++) {
int idx = (scalefac.small[wnd][sfb] << granule.scalefacScale) + (granule.subblockGain[wnd] << 2);
out[sfbStart + j * 3 + wnd] = globalGain * pow43(input[i]) * MpaConst.quantizerTab[idx];
}
}
}
}
private void dequantLong(int[] input, int nonzero, Mp3Bitstream.Granule granule, Mp3Bitstream.ScaleFactors scalefac, float globalGain, float[] out) {
for (int i = 0, sfb = 0; i < nonzero; i++) {
if (i == MpaConst.sfbLong[this.sfreq][sfb + 1])
sfb++;
int idx = scalefac.large[sfb] + (granule.preflag ? MpaConst.pretab[sfb] : 0) << granule.scalefacScale;
out[i] = globalGain * pow43(input[i]) * MpaConst.quantizerTab[idx];
}
}
private float pow43(int val) {
if (val == 0)
return 0.0F;
int sign = 1 - (val >>> 31 << 1);
int abs = MathUtil.abs(val);
if (abs < MpaConst.power43Tab.length)
return (float)sign * MpaConst.power43Tab[abs];
return (float)sign * (float)Math.pow((double)abs, 1.3333333333333333D);
}
private void decodeMsStereo(MpaHeader header, Mp3Bitstream.Granule granule, Mp3Bitstream.ScaleFactors[] scalefac, float[][] ro) {
for (int i = 0; i < 576; i++) {
float a = ro[0][i];
float b = ro[1][i];
ro[0][i] = (a + b) * 0.70710677F;
ro[1][i] = (a - b) * 0.70710677F;
}
}
private void antialias(Mp3Bitstream.Granule granule, float[] out) {
if (granule.windowSwitchingFlag && granule.blockType == 2 && !granule.mixedBlockFlag)
return;
int bands = (granule.windowSwitchingFlag && granule.mixedBlockFlag && granule.blockType == 2) ? 1 : 31;
for (int band = 0, bandStart = 0; band < bands; band++, bandStart += 18) {
for (int sample = 0; sample < 8; sample++) {
int src_idx1 = bandStart + 17 - sample;
int src_idx2 = bandStart + 18 + sample;
float bu = out[src_idx1];
float bd = out[src_idx2];
out[src_idx1] = bu * MpaConst.cs[sample] - bd * MpaConst.ca[sample];
out[src_idx2] = bd * MpaConst.cs[sample] + bu * MpaConst.ca[sample];
}
}
}
private void mdctDecode(int ch, Mp3Bitstream.Granule granule, float[] out) {
for (int sb18 = 0; sb18 < 576; sb18 += 18) {
int blockType = (granule.windowSwitchingFlag && granule.mixedBlockFlag && sb18 < 36) ? 0 :
granule.blockType;
for (int cc = 0; cc < 18; cc++)
this.mdctIn[cc] = out[cc + sb18];
if (blockType == 2) {
Mp3Mdct.threeShort(this.mdctIn, this.mdctOut);
} else {
Mp3Mdct.oneLong(this.mdctIn, this.mdctOut);
for (int j = 0; j < 36; j++)
this.mdctOut[j] = this.mdctOut[j] * MpaConst.win[blockType][j];
}
for (int i = 0; i < 18; i++) {
out[i + sb18] = this.mdctOut[i] + this.prevBlk[ch][sb18 + i];
this.prevBlk[ch][sb18 + i] = this.mdctOut[18 + i];
}
}
}
public AudioBuffer decodeFrame(ByteBuffer frame, ByteBuffer dst) throws IOException {
MpaHeader header = MpaHeader.read_header(frame);
if (!this.initialized)
init(header);
boolean intensityStereo = (header.mode == 1 && (header.modeExtension & 0x1) != 0);
if (intensityStereo)
throw new RuntimeException("Intensity stereo is not supported.");
dst.order(ByteOrder.LITTLE_ENDIAN);
Mp3Bitstream.MP3SideInfo si = Mp3Bitstream.readSideInfo(header, frame, this.channels);
int reserve = this.frameData.position();
this.frameData.put(NIOUtils.read(frame, header.frameBytes));
this.frameData.flip();
if (header.protectionBit == 0)
frame.getShort();
NIOUtils.skip(this.frameData, reserve - si.mainDataBegin);
BitReader br = BitReader.createBitReader(this.frameData);
Mp3Bitstream.ScaleFactors[] scalefac = new Mp3Bitstream.ScaleFactors[2];
decodeGranule(header, dst, si, br, scalefac, 0);
if (header.version == 1)
decodeGranule(header, dst, si, br, scalefac, 1);
br.terminate();
NIOUtils.relocateLeftover(this.frameData);
dst.flip();
return new AudioBuffer(dst, null, 1);
}
public AudioCodecMeta getCodecMeta(ByteBuffer data) throws IOException {
MpaHeader header = MpaHeader.read_header(data.duplicate());
AudioFormat format = new AudioFormat(MpaConst.frequencies[header.version][header.sampleFreq], 16,
(header.mode == 3) ? 1 : 2, true, false);
return AudioCodecMeta.fromAudioFormat(format);
}
}

View file

@ -0,0 +1,147 @@
package org.jcodec.codecs.mpa;
import java.util.Arrays;
public class Mp3Mdct {
private static final float factor36pt0 = 0.34729636F;
private static final float factor36pt1 = 1.5320889F;
private static final float factor36pt2 = 1.8793852F;
private static final float factor36pt3 = 1.7320508F;
private static final float factor36pt4 = 1.9696155F;
private static final float factor36pt5 = 1.2855753F;
private static final float factor36pt6 = 0.6840403F;
private static final float[] factor36 = new float[] { 0.5019099F, 0.5176381F, 0.55168897F, 0.61038727F, 0.8717234F, 1.1831008F, 1.9318516F, 5.7368565F };
private static final float cos075 = 0.9914449F;
private static final float cos225 = 0.9238795F;
private static final float cos300 = 0.8660254F;
private static final float cos375 = 0.7933533F;
private static final float cos450 = 0.70710677F;
private static final float cos525 = 0.6087614F;
private static final float cos600 = 0.5F;
private static final float cos675 = 0.38268343F;
private static final float cos825 = 0.13052619F;
private static final float factor12pt0 = 1.9318516F;
private static final float factor12pt1 = 0.5176381F;
private static final float[] factor12 = new float[] { 0.5043145F, 0.5411961F, 0.6302362F, 0.8213398F, 1.306563F, 3.830649F };
private static float[] tmp = new float[16];
static void oneLong(float[] src, float[] dst) {
for (int i3 = 17; i3 > 0; i3--)
src[i3] = src[i3] + src[i3 - 1];
for (int i2 = 17; i2 > 2; i2 -= 2)
src[i2] = src[i2] + src[i2 - 2];
for (int i1 = 0, k = 0; i1 < 2; i1++, k += 8) {
float f1 = src[i1] + src[i1];
float f2 = f1 + src[12 + i1];
float tmp2 = src[6 + i1] * 1.7320508F;
tmp[k + 0] = f2 + src[4 + i1] * 1.8793852F + src[8 + i1] * 1.5320889F + src[16 + i1] * 0.34729636F;
tmp[k + 1] = f1 + src[4 + i1] - src[8 + i1] - src[12 + i1] - src[12 + i1] - src[16 + i1];
tmp[k + 2] = f2 - src[4 + i1] * 0.34729636F - src[8 + i1] * 1.8793852F + src[16 + i1] * 1.5320889F;
tmp[k + 3] = f2 - src[4 + i1] * 1.5320889F + src[8 + i1] * 0.34729636F - src[16 + i1] * 1.8793852F;
tmp[k + 4] = src[2 + i1] * 1.9696155F + tmp2 + src[10 + i1] * 1.2855753F + src[14 + i1] * 0.6840403F;
tmp[k + 5] = (src[2 + i1] - src[10 + i1] - src[14 + i1]) * 1.7320508F;
tmp[k + 6] = src[2 + i1] * 1.2855753F - tmp2 - src[10 + i1] * 0.6840403F + src[14 + i1] * 1.9696155F;
tmp[k + 7] = src[2 + i1] * 0.6840403F - tmp2 + src[10 + i1] * 1.9696155F - src[14 + i1] * 1.2855753F;
}
for (int n = 0, j = 4, i4 = 8, l = 12; n < 4; n++, j++, i4++, l++) {
float q1 = tmp[n];
float q2 = tmp[i4];
tmp[n] = tmp[n] + tmp[j];
tmp[j] = q1 - tmp[j];
tmp[i4] = (tmp[i4] + tmp[l]) * factor36[n];
tmp[l] = (q2 - tmp[l]) * factor36[7 - n];
}
for (int m = 0; m < 4; m++) {
dst[26 - m] = tmp[m] + tmp[8 + m];
dst[8 - m] = tmp[8 + m] - tmp[m];
dst[27 + m] = dst[26 - m];
dst[9 + m] = -dst[8 - m];
}
for (int i = 0; i < 4; i++) {
dst[21 - i] = tmp[7 - i] + tmp[15 - i];
dst[3 - i] = tmp[15 - i] - tmp[7 - i];
dst[32 + i] = dst[21 - i];
dst[14 + i] = -dst[3 - i];
}
float tmp0 = src[0] - src[4] + src[8] - src[12] + src[16];
float tmp1 = (src[1] - src[5] + src[9] - src[13] + src[17]) * 0.70710677F;
dst[4] = tmp1 - tmp0;
dst[13] = -dst[4];
dst[22] = tmp0 + tmp1;
dst[31] = tmp0 + tmp1;
}
static void threeShort(float[] src, float[] dst) {
Arrays.fill(dst, 0.0F);
for (int i = 0, outOff = 0; i < 3; i++, outOff += 6)
imdct12(src, dst, outOff, i);
}
private static void imdct12(float[] src, float[] dst, int outOff, int wndIdx) {
for (int j = 15 + wndIdx, k = 12 + wndIdx; j >= 3 + wndIdx; j -= 3, k -= 3)
src[j] = src[j] + src[k];
src[15 + wndIdx] = src[15 + wndIdx] + src[9 + wndIdx];
src[9 + wndIdx] = src[9 + wndIdx] + src[3 + wndIdx];
float pp2 = src[12 + wndIdx] * 0.5F;
float pp1 = src[6 + wndIdx] * 0.8660254F;
float sum = src[0 + wndIdx] + pp2;
tmp[1] = src[wndIdx] - src[12 + wndIdx];
tmp[0] = sum + pp1;
tmp[2] = sum - pp1;
pp2 = src[15 + wndIdx] * 0.5F;
pp1 = src[9 + wndIdx] * 0.8660254F;
sum = src[3 + wndIdx] + pp2;
tmp[4] = src[3 + wndIdx] - src[15 + wndIdx];
tmp[5] = sum + pp1;
tmp[3] = sum - pp1;
tmp[3] = tmp[3] * 1.9318516F;
tmp[4] = tmp[4] * 0.70710677F;
tmp[5] = tmp[5] * 0.5176381F;
float t = tmp[0];
tmp[0] = tmp[0] + tmp[5];
tmp[5] = t - tmp[5];
t = tmp[1];
tmp[1] = tmp[1] + tmp[4];
tmp[4] = t - tmp[4];
t = tmp[2];
tmp[2] = tmp[2] + tmp[3];
tmp[3] = t - tmp[3];
for (int m = 0; m < 6; m++)
tmp[m] = tmp[m] * factor12[m];
tmp[8] = -tmp[0] * 0.7933533F;
tmp[9] = -tmp[0] * 0.6087614F;
tmp[7] = -tmp[1] * 0.9238795F;
tmp[10] = -tmp[1] * 0.38268343F;
tmp[6] = -tmp[2] * 0.9914449F;
tmp[11] = -tmp[2] * 0.13052619F;
tmp[0] = tmp[3];
tmp[1] = tmp[4] * 0.38268343F;
tmp[2] = tmp[5] * 0.6087614F;
tmp[3] = -tmp[5] * 0.7933533F;
tmp[4] = -tmp[4] * 0.9238795F;
tmp[5] = -tmp[0] * 0.9914449F;
tmp[0] = tmp[0] * 0.13052619F;
for (int i = 0, n = outOff + 6; i < 12; i++, n++)
dst[n] = dst[n] + tmp[i];
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,116 @@
package org.jcodec.codecs.mpa;
import java.nio.ByteBuffer;
class MpaHeader {
int layer;
int protectionBit;
int bitrateIndex;
int paddingBit;
int modeExtension;
int version;
int mode;
int sampleFreq;
int numSubbands;
int intensityStereoBound;
boolean copyright;
boolean original;
int framesize;
int frameBytes;
static MpaHeader read_header(ByteBuffer bb) {
MpaHeader ret = new MpaHeader();
int headerstring = bb.getInt();
ret.version = headerstring >>> 19 & 0x1;
if ((headerstring >>> 20 & 0x1) == 0)
if (ret.version == 0) {
ret.version = 2;
} else {
throw new RuntimeException("UNKNOWN_ERROR");
}
if ((ret.sampleFreq = headerstring >>> 10 & 0x3) == 3)
throw new RuntimeException("UNKNOWN_ERROR");
ret.layer = 4 - (headerstring >>> 17) & 0x3;
ret.protectionBit = headerstring >>> 16 & 0x1;
ret.bitrateIndex = headerstring >>> 12 & 0xF;
ret.paddingBit = headerstring >>> 9 & 0x1;
ret.mode = headerstring >>> 6 & 0x3;
ret.modeExtension = headerstring >>> 4 & 0x3;
if (ret.mode == 1) {
ret.intensityStereoBound = (ret.modeExtension << 2) + 4;
} else {
ret.intensityStereoBound = 0;
}
if ((headerstring >>> 3 & 0x1) == 1)
ret.copyright = true;
if ((headerstring >>> 2 & 0x1) == 1)
ret.original = true;
if (ret.layer == 1) {
ret.numSubbands = 32;
} else {
int channel_bitrate = ret.bitrateIndex;
if (ret.mode != 3)
if (channel_bitrate == 4) {
channel_bitrate = 1;
} else {
channel_bitrate -= 4;
}
if (channel_bitrate == 1 || channel_bitrate == 2) {
if (ret.sampleFreq == 2) {
ret.numSubbands = 12;
} else {
ret.numSubbands = 8;
}
} else if (ret.sampleFreq == 1 || (channel_bitrate >= 3 && channel_bitrate <= 5)) {
ret.numSubbands = 27;
} else {
ret.numSubbands = 30;
}
}
if (ret.intensityStereoBound > ret.numSubbands)
ret.intensityStereoBound = ret.numSubbands;
calculateFramesize(ret);
return ret;
}
public static void calculateFramesize(MpaHeader ret) {
if (ret.layer == 1) {
ret.framesize = 12 * MpaConst.bitrates[ret.version][0][ret.bitrateIndex] / MpaConst.frequencies[ret.version][ret.sampleFreq];
if (ret.paddingBit != 0)
ret.framesize++;
ret.framesize <<= 2;
ret.frameBytes = 0;
} else {
ret.framesize = 144 * MpaConst.bitrates[ret.version][ret.layer - 1][ret.bitrateIndex] / MpaConst.frequencies[ret.version][ret.sampleFreq];
if (ret.version == 0 || ret.version == 2)
ret.framesize >>= 1;
if (ret.paddingBit != 0)
ret.framesize++;
if (ret.layer == 3) {
if (ret.version == 1) {
ret
.frameBytes = ret.framesize - ((ret.mode == 3) ? 17 : 32) - ((ret.protectionBit != 0) ? 0 : 2) - 4;
} else {
ret
.frameBytes = ret.framesize - ((ret.mode == 3) ? 9 : 17) - ((ret.protectionBit != 0) ? 0 : 2) - 4;
}
} else {
ret.frameBytes = 0;
}
}
ret.framesize -= 4;
}
}

View file

@ -0,0 +1,254 @@
package org.jcodec.codecs.mpa;
import org.jcodec.common.tools.MathUtil;
public class MpaPqmf {
private static final double MY_PI = 3.141592653589793D;
private static final float cos1_64 = (float)(1.0D / (2.0D * Math.cos(0.04908738521234052D)));
private static final float cos3_64 = (float)(1.0D / (2.0D * Math.cos(0.14726215563702155D)));
private static final float cos5_64 = (float)(1.0D / (2.0D * Math.cos(0.2454369260617026D)));
private static final float cos7_64 = (float)(1.0D / (2.0D * Math.cos(0.3436116964863836D)));
private static final float cos9_64 = (float)(1.0D / (2.0D * Math.cos(0.44178646691106466D)));
private static final float cos11_64 = (float)(1.0D / (2.0D * Math.cos(0.5399612373357456D)));
private static final float cos13_64 = (float)(1.0D / (2.0D * Math.cos(0.6381360077604268D)));
private static final float cos15_64 = (float)(1.0D / (2.0D * Math.cos(0.7363107781851077D)));
private static final float cos17_64 = (float)(1.0D / (2.0D * Math.cos(0.8344855486097889D)));
private static final float cos19_64 = (float)(1.0D / (2.0D * Math.cos(0.9326603190344698D)));
private static final float cos21_64 = (float)(1.0D / (2.0D * Math.cos(1.030835089459151D)));
private static final float cos23_64 = (float)(1.0D / (2.0D * Math.cos(1.1290098598838318D)));
private static final float cos25_64 = (float)(1.0D / (2.0D * Math.cos(1.227184630308513D)));
private static final float cos27_64 = (float)(1.0D / (2.0D * Math.cos(1.325359400733194D)));
private static final float cos29_64 = (float)(1.0D / (2.0D * Math.cos(1.423534171157875D)));
private static final float cos31_64 = (float)(1.0D / (2.0D * Math.cos(1.521708941582556D)));
private static final float cos1_32 = (float)(1.0D / (2.0D * Math.cos(0.09817477042468103D)));
private static final float cos3_32 = (float)(1.0D / (2.0D * Math.cos(0.2945243112740431D)));
private static final float cos5_32 = (float)(1.0D / (2.0D * Math.cos(0.4908738521234052D)));
private static final float cos7_32 = (float)(1.0D / (2.0D * Math.cos(0.6872233929727672D)));
private static final float cos9_32 = (float)(1.0D / (2.0D * Math.cos(0.8835729338221293D)));
private static final float cos11_32 = (float)(1.0D / (2.0D * Math.cos(1.0799224746714913D)));
private static final float cos13_32 = (float)(1.0D / (2.0D * Math.cos(1.2762720155208536D)));
private static final float cos15_32 = (float)(1.0D / (2.0D * Math.cos(1.4726215563702154D)));
private static final float cos1_16 = (float)(1.0D / (2.0D * Math.cos(0.19634954084936207D)));
private static final float cos3_16 = (float)(1.0D / (2.0D * Math.cos(0.5890486225480862D)));
private static final float cos5_16 = (float)(1.0D / (2.0D * Math.cos(0.9817477042468103D)));
private static final float cos7_16 = (float)(1.0D / (2.0D * Math.cos(1.3744467859455345D)));
private static final float cos1_8 = (float)(1.0D / (2.0D * Math.cos(0.39269908169872414D)));
private static final float cos3_8 = (float)(1.0D / (2.0D * Math.cos(1.1780972450961724D)));
private static final float cos1_4 = (float)(1.0D / (2.0D * Math.cos(0.7853981633974483D)));
private static final float[] bf32 = new float[] {
cos1_64, cos3_64, cos5_64, cos7_64, cos9_64, cos11_64, cos13_64, cos15_64, cos17_64, cos19_64,
cos21_64, cos23_64, cos25_64, cos27_64, cos29_64, cos31_64 };
private static final float[] bf16 = new float[] { cos1_32, cos3_32, cos5_32, cos7_32, cos9_32, cos11_32, cos13_32, cos15_32 };
private static final float[] bf8 = new float[] { cos1_16, cos3_16, cos5_16, cos7_16 };
static void computeFilter(int sampleOff, float[] samples, short[] out, int outOff, float scalefactor) {
int dvp = 0;
for (int i = 0; i < 32; i++) {
int b = i << 4;
float pcm_sample = (samples[(16 + sampleOff & 0xF) + dvp] * MpaConst.dp[b + 0] + samples[(15 + sampleOff & 0xF) + dvp] * MpaConst.dp[b + 1] + samples[(14 + sampleOff & 0xF) + dvp] * MpaConst.dp[b + 2] + samples[(13 + sampleOff & 0xF) + dvp] * MpaConst.dp[b + 3] + samples[(12 + sampleOff & 0xF) + dvp] * MpaConst.dp[b + 4] + samples[(11 + sampleOff & 0xF) + dvp] * MpaConst.dp[b + 5] + samples[(10 + sampleOff & 0xF) + dvp] * MpaConst.dp[b + 6] + samples[(9 + sampleOff & 0xF) + dvp] * MpaConst.dp[b + 7] + samples[(8 + sampleOff & 0xF) + dvp] * MpaConst.dp[b + 8] + samples[(7 + sampleOff & 0xF) + dvp] * MpaConst.dp[b + 9] + samples[(6 + sampleOff & 0xF) + dvp] * MpaConst.dp[b + 10] + samples[(5 + sampleOff & 0xF) + dvp] * MpaConst.dp[b + 11] + samples[(4 + sampleOff & 0xF) + dvp] * MpaConst.dp[b + 12] + samples[(3 + sampleOff & 0xF) + dvp] * MpaConst.dp[b + 13] + samples[(2 + sampleOff & 0xF) + dvp] * MpaConst.dp[b + 14] + samples[(1 + sampleOff & 0xF) + dvp] * MpaConst.dp[b + 15]) * scalefactor;
out[outOff + i] = (short)MathUtil.clip((int)pcm_sample, -32768, 32767);
dvp += 16;
}
}
static void computeButterfly(int pos, float[] s) {
butterfly32(s);
butterfly16L(s);
butterfly16H(s);
butterfly8L(s, 0);
butterfly8H(s, 0);
butterfly8L(s, 16);
butterfly8H(s, 16);
for (int j = 0; j < 32; j += 8) {
butterfly4L(s, j);
butterfly4H(s, j);
}
for (int i = 0; i < 32; i += 4) {
butterfly2L(s, i);
butterfly2H(s, i);
}
float k0 = -s[14] - s[15] - s[10] - s[11];
float k1 = s[29] + s[31] + s[25];
float k2 = k1 + s[17];
float k3 = k1 + s[21] + s[23];
float k4 = s[15] + s[11];
float k5 = s[15] + s[13] + s[9];
float k6 = s[7] + s[5];
float k7 = s[31] + s[23];
float k8 = k7 + s[27];
float k9 = s[31] + s[27] + s[19];
float k10 = -s[26] - s[27] - s[30] - s[31];
float k11 = -s[24] - s[28] - s[30] - s[31];
float k12 = s[20] + s[22] + s[23];
float k13 = s[21] + s[29];
float s0 = s[0];
float s1 = s[1];
float s2 = s[2];
float s3 = s[3];
float s4 = s[4];
float s6 = s[6];
float s7 = s[7];
float s8 = s[8];
float s12 = s[12];
float s13 = s[13];
float s14 = s[14];
float s15 = s[15];
float s16 = s[16];
float s18 = s[18];
float s19 = s[19];
float s21 = s[21];
float s22 = s[22];
float s23 = s[23];
float s28 = s[28];
float s29 = s[29];
float s30 = s[30];
float s31 = s[31];
s[0] = s1;
s[1] = k2;
s[2] = k5;
s[3] = k3;
s[4] = k6;
s[5] = k8 + k13;
s[6] = k4 + s13;
s[7] = k9 + s29;
s[8] = s3;
s[9] = k9;
s[10] = k4;
s[11] = k8;
s[12] = s7;
s[13] = k7;
s[14] = s15;
s[15] = s31;
s[16] = -k2 - s30;
s[17] = -k5 - s14;
s[18] = -k3 - s22 - s30;
s[19] = -k6 - s6;
s[20] = k10 - s29 - s21 - s22 - s23;
s[21] = k0 - s13;
s[22] = k10 - s29 - s18 - s19;
s[23] = -s3 - s2;
s[24] = k10 - s28 - s18 - s19;
s[25] = k0 - s12;
s[26] = k10 - s28 - k12;
s[27] = -s6 - s7 - s4;
s[28] = k11 - k12;
s[29] = -s14 - s15 - s12 - s8;
s[30] = k11 - s16;
s[31] = -s0;
}
private static void butterfly16H(float[] s) {
for (int i = 0; i < 8; i++) {
float tmp0 = s[16 + i];
float tmp1 = s[31 - i];
s[16 + i] = tmp0 + tmp1;
s[31 - i] = -(tmp0 - tmp1) * bf16[i];
}
}
private static void butterfly16L(float[] s) {
for (int i = 0; i < 8; i++) {
float tmp0 = s[i];
float tmp1 = s[15 - i];
s[i] = tmp0 + tmp1;
s[15 - i] = (tmp0 - tmp1) * bf16[i];
}
}
private static void butterfly8H(float[] s, int o) {
for (int i = 0; i < 4; i++) {
float tmp0 = s[o + 8 + i];
float tmp1 = s[o + 15 - i];
s[o + 8 + i] = tmp0 + tmp1;
s[o + 15 - i] = -(tmp0 - tmp1) * bf8[i];
}
}
private static void butterfly8L(float[] s, int o) {
for (int i = 0; i < 4; i++) {
float tmp0 = s[o + i];
float tmp1 = s[o + 7 - i];
s[o + i] = tmp0 + tmp1;
s[o + 7 - i] = (tmp0 - tmp1) * bf8[i];
}
}
private static void butterfly4H(float[] s, int o) {
float tmp0 = s[o + 4];
float tmp1 = s[o + 7];
s[o + 4] = tmp0 + tmp1;
s[o + 7] = -(tmp0 - tmp1) * cos1_8;
float tmp2 = s[o + 5];
float tmp3 = s[o + 6];
s[o + 5] = tmp2 + tmp3;
s[o + 6] = -(tmp2 - tmp3) * cos3_8;
}
private static void butterfly4L(float[] s, int o) {
float tmp0 = s[o];
float tmp1 = s[o + 3];
s[o + 0] = tmp0 + tmp1;
s[o + 3] = (tmp0 - tmp1) * cos1_8;
float tmp2 = s[o + 1];
float tmp3 = s[o + 2];
s[o + 1] = tmp2 + tmp3;
s[o + 2] = (tmp2 - tmp3) * cos3_8;
}
private static void butterfly2H(float[] s, int o) {
float tmp0 = s[o + 2];
float tmp1 = s[o + 3];
s[o + 2] = tmp0 + tmp1;
s[o + 3] = -(tmp0 - tmp1) * cos1_4;
}
private static void butterfly2L(float[] s, int o) {
float tmp0 = s[o];
float tmp1 = s[o + 1];
s[o + 0] = tmp0 + tmp1;
s[o + 1] = (tmp0 - tmp1) * cos1_4;
}
private static void butterfly32(float[] s) {
for (int i = 0; i < 16; i++) {
float tmp0 = s[i];
float tmp1 = s[31 - i];
s[i] = tmp0 + tmp1;
s[31 - i] = (tmp0 - tmp1) * bf32[i];
}
}
}