mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-22 01:17:03 +00:00
Replacing SoundStreamHeads with MP3
This commit is contained in:
Binary file not shown.
@@ -163,12 +163,13 @@ public abstract class SoundStreamHeadTypeTag extends Tag implements CharacterIdT
|
||||
|
||||
newSoundSize = true;
|
||||
newSoundType = fr.isStereo();
|
||||
int len = snd.sampleCount();
|
||||
/*int len = snd.sampleCount();
|
||||
if (fr.isStereo()) {
|
||||
len = len / 2;
|
||||
}
|
||||
}*/
|
||||
|
||||
newSoundSampleCount = len;
|
||||
newSoundSampleCount = (int) Math.ceil(soundRateHz / swf.frameRate);
|
||||
//newSoundSampleCount = len;
|
||||
}
|
||||
|
||||
mp3Frames = snd.frames;
|
||||
@@ -237,7 +238,7 @@ public abstract class SoundStreamHeadTypeTag extends Tag implements CharacterIdT
|
||||
}
|
||||
if (mp3Frames != null) {
|
||||
|
||||
/*int frame = 0;
|
||||
int frame = 0;
|
||||
|
||||
int mp3FrameNum = 0;
|
||||
long lastNumSamplesLong = 0;
|
||||
@@ -252,21 +253,28 @@ public abstract class SoundStreamHeadTypeTag extends Tag implements CharacterIdT
|
||||
|
||||
List<MP3FRAME> blockMp3Frames = new ArrayList<>();
|
||||
int blockSamples = 0;
|
||||
while(lastNumSamplesLong < numSamplesAfterFrame) {
|
||||
while(lastNumSamplesLong < numSamplesAfterFrame && mp3FrameNum < mp3Frames.size()) {
|
||||
MP3FRAME mp3Frame = mp3Frames.get(mp3FrameNum);
|
||||
lastNumSamplesLong += mp3Frame.getSampleCount();
|
||||
blockSamples += mp3Frame.getSampleCount();
|
||||
blockMp3Frames.add(mp3Frame);
|
||||
mp3FrameNum++;
|
||||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, SWF.DEFAULT_VERSION, null);
|
||||
try {
|
||||
sos.writeUI16(blockSamples);
|
||||
sos.writeSI16(seekSamples);
|
||||
for (MP3FRAME mp3Frame:blockMp3Frames) {
|
||||
sos.write(mp3Frame.getBytes());
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SoundStreamHeadTypeTag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
} */
|
||||
block.streamSoundData = new ByteArrayRange(baos.toByteArray());
|
||||
blocks.add(block);
|
||||
frame++;
|
||||
}
|
||||
}
|
||||
|
||||
ReadOnlyTagList tags = timelined.getTags();
|
||||
|
||||
@@ -35,11 +35,22 @@ public class MP3FRAME {
|
||||
private Header h;
|
||||
|
||||
private SampleBuffer samples;
|
||||
|
||||
private byte[] fullData;
|
||||
|
||||
private MP3FRAME() {
|
||||
|
||||
}
|
||||
|
||||
public void setFullData(byte[] fullData) {
|
||||
this.fullData = fullData;
|
||||
}
|
||||
|
||||
public byte[] getBytes() {
|
||||
return fullData;
|
||||
}
|
||||
|
||||
|
||||
public static MP3FRAME readFrame(Bitstream bitstream, Decoder decoder) throws IOException {
|
||||
MP3FRAME ret = new MP3FRAME();
|
||||
try {
|
||||
@@ -60,24 +71,24 @@ public class MP3FRAME {
|
||||
}
|
||||
|
||||
public int getSampleCount() {
|
||||
if (h.version() == 3) {
|
||||
if (h.version() == Header.MPEG1) {
|
||||
switch(h.layer()) {
|
||||
case 1:
|
||||
return 1152;
|
||||
return 384;
|
||||
case 2:
|
||||
return 1152;
|
||||
case 3:
|
||||
return 384;
|
||||
return 1152;
|
||||
}
|
||||
}
|
||||
if (h.version() == 2 || h.version() == 0) {
|
||||
if (h.version() == Header.MPEG2_LSF || h.version() == Header.MPEG25_LSF) {
|
||||
switch(h.layer()) {
|
||||
case 1:
|
||||
return 576;
|
||||
return 384;
|
||||
case 2:
|
||||
return 1152;
|
||||
case 3:
|
||||
return 384;
|
||||
return 576;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -20,9 +20,12 @@ import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javazoom.jl.decoder.Bitstream;
|
||||
import javazoom.jl.decoder.Decoder;
|
||||
import javazoom.jl.decoder.MarkingBufferedInputStream;
|
||||
import javazoom.jl.decoder.MarkingPushbackInputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -41,10 +44,23 @@ public class MP3SOUNDDATA {
|
||||
frames = new ArrayList<>();
|
||||
MP3FRAME f;
|
||||
Decoder decoder = new Decoder();
|
||||
Bitstream bitstream = new Bitstream(new ByteArrayInputStream(sis.readBytesEx(sis.available(), "soundStream")));
|
||||
while ((f = MP3FRAME.readFrame(bitstream, decoder)) != null) {
|
||||
frames.add(f);
|
||||
}
|
||||
|
||||
byte data[] = sis.readBytesEx(sis.available(), "soundStream");
|
||||
MarkingBufferedInputStream mis = new MarkingBufferedInputStream(new ByteArrayInputStream(data));
|
||||
Bitstream bitstream = new Bitstream(mis); //new ByteArrayInputStream(data)
|
||||
long initLen = mis.getPosition();
|
||||
MarkingPushbackInputStream mpis = bitstream.getSource();
|
||||
while (true) {
|
||||
//System.err.println("initLen = "+initLen);
|
||||
long posBefore = initLen+mpis.getPosition();
|
||||
MP3FRAME frame = MP3FRAME.readFrame(bitstream, decoder);
|
||||
if (frame == null) {
|
||||
break;
|
||||
}
|
||||
long posAfter = initLen+mpis.getPosition();
|
||||
frame.setFullData(Arrays.copyOfRange(data, (int)posBefore, (int)posAfter));
|
||||
frames.add(frame);
|
||||
}
|
||||
}
|
||||
|
||||
public int sampleCount() {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2022 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.types.sound;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MarkingInputStream extends InputStream {
|
||||
|
||||
private InputStream is;
|
||||
|
||||
private long pos = 0;
|
||||
|
||||
public MarkingInputStream(InputStream is) {
|
||||
this.is = is;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
pos++;
|
||||
return is.read();
|
||||
}
|
||||
|
||||
public long getPos() {
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
@@ -146,7 +146,24 @@ public final class Bitstream implements BitstreamErrors {
|
||||
|
||||
closeFrame();
|
||||
}
|
||||
|
||||
//JPEXS
|
||||
public Bitstream(MarkingBufferedInputStream in) {
|
||||
if (in == null)
|
||||
throw new NullPointerException("in");
|
||||
loadID3v2(in);
|
||||
in.setFixed(true);
|
||||
firstframe = true;
|
||||
source = new MarkingPushbackInputStream(in, BUFFER_INT_SIZE * 4);
|
||||
|
||||
closeFrame();
|
||||
}
|
||||
|
||||
//JPEXS
|
||||
public MarkingPushbackInputStream getSource() {
|
||||
return (MarkingPushbackInputStream) source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return position of the first audio header.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
package javazoom.jl.decoder;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MarkingBufferedInputStream extends BufferedInputStream {
|
||||
|
||||
private BufferedInputStream is;
|
||||
|
||||
private long pos = 0;
|
||||
|
||||
private long markedPos = -1;
|
||||
|
||||
private boolean fixed = false;
|
||||
|
||||
public long getPosition() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public void setFixed(boolean fixed) {
|
||||
this.fixed = fixed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public MarkingBufferedInputStream(InputStream in) {
|
||||
super(in);
|
||||
this.is = new BufferedInputStream(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int read() throws IOException {
|
||||
if (!fixed) pos++;
|
||||
return is.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException {
|
||||
int ret = is.read(b);
|
||||
if (!fixed) pos += ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int read(byte[] b, int off, int len) throws IOException {
|
||||
int ret = is.read(b, off, len);
|
||||
if (!fixed) pos += ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void reset() throws IOException {
|
||||
if (markedPos > -1) {
|
||||
if (!fixed) pos = markedPos;
|
||||
markedPos = -1;
|
||||
}
|
||||
is.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void mark(int readlimit) {
|
||||
markedPos = pos;
|
||||
is.mark(readlimit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int available() throws IOException {
|
||||
return is.available();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized long skip(long n) throws IOException {
|
||||
long ret = is.skip(n);
|
||||
if (!fixed) pos+=ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skipNBytes(long n) throws IOException {
|
||||
if (!fixed) pos+=n;
|
||||
is.skipNBytes(n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
is.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return is.markSupported();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package javazoom.jl.decoder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PushbackInputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MarkingPushbackInputStream extends PushbackInputStream {
|
||||
|
||||
private PushbackInputStream is;
|
||||
|
||||
private long pos = 0;
|
||||
|
||||
public long getPosition() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public MarkingPushbackInputStream(InputStream in, int size) {
|
||||
super(in, size);
|
||||
is = new PushbackInputStream(in, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return is.available();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() throws IOException {
|
||||
is.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void mark(int readlimit) {
|
||||
is.mark(readlimit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return is.markSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
pos++;
|
||||
return is.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
|
||||
int ret = is.read(b, off, len);
|
||||
pos += ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException {
|
||||
int ret = is.read(b);
|
||||
pos += ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void reset() throws IOException {
|
||||
is.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unread(byte[] b) throws IOException {
|
||||
pos -= b.length;
|
||||
is.unread(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unread(int b) throws IOException {
|
||||
pos--;
|
||||
is.unread(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unread(byte[] b, int off, int len) throws IOException {
|
||||
pos -= len;
|
||||
is.unread(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long n) throws IOException {
|
||||
long ret = is.skip(n);
|
||||
pos += ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skipNBytes(long n) throws IOException {
|
||||
pos += n;
|
||||
is.skipNBytes(n);
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.OpenableSourceInfo;
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.RenameType;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
@@ -156,6 +157,7 @@ import com.jpexs.decompiler.flash.tags.PlaceObjectTag;
|
||||
import com.jpexs.decompiler.flash.tags.ProductInfoTag;
|
||||
import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
|
||||
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
|
||||
import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.TagInfo;
|
||||
import com.jpexs.decompiler.flash.tags.UnknownTag;
|
||||
@@ -4752,7 +4754,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
previewPanel.closeTag();
|
||||
}
|
||||
|
||||
public static void showPreview(TreeItem treeItem, PreviewPanel previewPanel, int frame, Timelined timelinedContainer) {
|
||||
public static void showPreview(TreeItem treeItem, PreviewPanel previewPanel, int frame, Timelined timelinedContainer) {
|
||||
previewPanel.clear();
|
||||
if (treeItem == null) {
|
||||
previewPanel.showEmpty();
|
||||
@@ -5034,6 +5036,20 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
showDetail(DETAILCARDEMPTYPANEL);
|
||||
}
|
||||
|
||||
if (treeItem instanceof SoundStreamBlockTag) {
|
||||
SoundStreamBlockTag block = (SoundStreamBlockTag)treeItem;
|
||||
byte[] data = block.streamSoundData.getRangeData();
|
||||
try{
|
||||
SWFInputStream sis = new SWFInputStream(block.getSwf(), data);
|
||||
int sampleCount = sis.readUI16("sampleCount");
|
||||
int seekSamples = sis.readSI16("seekSamples");
|
||||
System.out.println("sampleCount = "+sampleCount);
|
||||
System.out.println("seekSamples = "+seekSamples);
|
||||
System.out.println("============");
|
||||
}catch(Exception ex){
|
||||
|
||||
}
|
||||
}
|
||||
if (treeItem instanceof HeaderItem) {
|
||||
headerPanel.load((SWF) ((HeaderItem) treeItem).getOpenable());
|
||||
showCard(CARDHEADER);
|
||||
|
||||
Reference in New Issue
Block a user