diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/SoundExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/SoundExporter.java index 7aa8cefcf..75fc54dd4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/SoundExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/SoundExporter.java @@ -20,8 +20,6 @@ import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler; import com.jpexs.decompiler.flash.EventListener; import com.jpexs.decompiler.flash.ReadOnlyTagList; import com.jpexs.decompiler.flash.RetryTask; -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.exporters.modes.SoundExportMode; import com.jpexs.decompiler.flash.exporters.settings.SoundExportSettings; import com.jpexs.decompiler.flash.flv.AUDIODATA; @@ -159,14 +157,7 @@ public class SoundExporter { } } else { List soundData = st.getRawSoundData(); - SWF swf = ((Tag) st).getSwf(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - for (ByteArrayRange data : soundData) { - baos.write(data.getArray(), data.getPos(), data.getLength()); - } - - SWFInputStream sis = new SWFInputStream(swf, baos.toByteArray()); - fmt.createWav(sis, fos); + fmt.createWav(soundData, fos); } } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/sound/MP3Decoder.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/sound/MP3Decoder.java index 5c4fbbae0..0bcdbe688 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/sound/MP3Decoder.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/sound/MP3Decoder.java @@ -17,8 +17,8 @@ package com.jpexs.decompiler.flash.types.sound; import com.jpexs.decompiler.flash.SWFInputStream; -import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import javazoom.jl.decoder.Bitstream; import javazoom.jl.decoder.BitstreamException; @@ -33,16 +33,74 @@ import javazoom.jl.decoder.SampleBuffer; */ public class MP3Decoder extends SoundDecoder { + private final Decoder decoder = new Decoder(); + + private final MyInputStream inputStream = new MyInputStream(); + + private final Bitstream bitStream = new Bitstream(inputStream); + + class MyInputStream extends InputStream { + + byte[] buf = new byte[4096]; + + int pos = 0; + + int remaining = 0; + + public void add(byte[] data) { + if (data == null || data.length == 0) { + return; + } + + int remaining = this.remaining; + int requiredSize = data.length + remaining; + byte[] oldBuf = this.buf; + byte[] buf = oldBuf; + int pos = this.pos; + if (requiredSize > buf.length) { + int newSize = buf.length; + while (requiredSize > newSize) { + newSize *= 2; + } + + buf = new byte[newSize]; + this.buf = buf; + } + + if (remaining > 0) { + System.arraycopy(oldBuf, pos, buf, 0, remaining); + } + + this.pos = 0; + + System.arraycopy(data, 0, buf, remaining, data.length); + this.remaining = remaining + data.length; + } + + @Override + public int read() throws IOException { + if (remaining > 0) { + int result = buf[pos] & 0xff; + remaining--; + pos++; + return result; + } + + return -1; + } + } + public MP3Decoder(SoundFormat soundFormat) { super(soundFormat); } @Override public void decode(SWFInputStream sis, OutputStream os) throws IOException { - Decoder decoder = new Decoder(); - Bitstream bitstream = new Bitstream(new ByteArrayInputStream(sis.readBytesEx(sis.available(), "soundStream"))); + byte[] data = sis.readBytesEx(sis.available(), "soundStream"); + inputStream.add(data); + SampleBuffer buf; - while ((buf = readFrame(decoder, bitstream)) != null) { + while ((buf = readFrame(decoder, bitStream)) != null) { short[] audio = buf.getBuffer(); byte[] d = new byte[buf.getBufferLength() * 2]; for (int i = 0; i < buf.getBufferLength(); i++) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/sound/SoundFormat.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/sound/SoundFormat.java index d5e6e19d5..4293d6c69 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/sound/SoundFormat.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/sound/SoundFormat.java @@ -17,10 +17,12 @@ package com.jpexs.decompiler.flash.types.sound; import com.jpexs.decompiler.flash.SWFInputStream; +import com.jpexs.helpers.ByteArrayRange; import com.jpexs.helpers.utf8.Utf8Helper; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.List; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; @@ -197,10 +199,16 @@ public class SoundFormat { } } - public boolean createWav(SWFInputStream sis, OutputStream os) { + public boolean createWav(List dataRanges, OutputStream os) throws IOException { ensureFormat(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); - decode(sis, baos); + SoundDecoder decoder = getDecoder(); + for (ByteArrayRange dataRange : dataRanges) { + SWFInputStream sis = new SWFInputStream(null, dataRange.getArray(), 0, dataRange.getPos() + dataRange.getLength()); + sis.seek(dataRange.getPos()); + decoder.decode(sis, baos); + } + try { createWavFromPcmData(os, samplingRate, true, stereo, baos.toByteArray()); return true; diff --git a/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java b/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java index e03068a0b..eacda0efe 100644 --- a/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java +++ b/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java @@ -17,7 +17,6 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.gui.player.MediaDisplay; import com.jpexs.decompiler.flash.gui.player.MediaDisplayListener; import com.jpexs.decompiler.flash.gui.player.Zoom; @@ -160,15 +159,9 @@ public class SoundTagPlayer implements MediaDisplay { SWF swf = ((Tag) tag).getSwf(); byte[] wavData = swf.getFromCache(tag); if (wavData == null) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); List soundData = tag.getRawSoundData(); - for (ByteArrayRange data : soundData) { - baos.write(data.getArray(), data.getPos(), data.getLength()); - } - - SWFInputStream sis = new SWFInputStream(swf, baos.toByteArray()); - baos = new ByteArrayOutputStream(); - tag.getSoundFormat().createWav(sis, baos); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + tag.getSoundFormat().createWav(soundData, baos); wavData = baos.toByteArray(); swf.putToCache(tag, wavData); }