Removed resampling from CLI and all source code

Frames with streamed sound are not taken as same.
This commit is contained in:
Jindra Petřík
2025-11-16 22:37:09 +01:00
parent 396cd97801
commit 714dd8761c
24 changed files with 67 additions and 145 deletions
+3
View File
@@ -30,6 +30,9 @@ All notable changes to this project will be documented in this file.
### Changed ### Changed
- Simple editor uses percent as units for filter strength - Simple editor uses percent as units for filter strength
### Removed
- Removed resampling from CLI and all source code
## [24.1.0] - 2025-09-28 ## [24.1.0] - 2025-09-28
### Added ### Added
- [#2477] Option to disable AS2 detection of uninitialized class fields - [#2477] Option to disable AS2 detection of uninitialized class fields
@@ -4493,11 +4493,10 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
* *
* @param soundInfo Sound info * @param soundInfo Sound info
* @param soundTag Sound tag * @param soundTag Sound tag
* @param resample Resample to 44kHz?
* @param data Byte data * @param data Byte data
*/ */
public void putToCache(SOUNDINFO soundInfo, SoundTag soundTag, boolean resample, byte[] data) { public void putToCache(SOUNDINFO soundInfo, SoundTag soundTag, byte[] data) {
SoundInfoSoundCacheEntry key = new SoundInfoSoundCacheEntry(soundInfo, soundTag, resample); SoundInfoSoundCacheEntry key = new SoundInfoSoundCacheEntry(soundInfo, soundTag);
soundCache.put(key, data); soundCache.put(key, data);
} }
@@ -4720,11 +4719,10 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
* *
* @param soundInfo Sound info * @param soundInfo Sound info
* @param soundTag Sound tag * @param soundTag Sound tag
* @param resample Resample to 44kHz
* @return Byte data * @return Byte data
*/ */
public byte[] getFromCache(SOUNDINFO soundInfo, SoundTag soundTag, boolean resample) { public byte[] getFromCache(SOUNDINFO soundInfo, SoundTag soundTag) {
SoundInfoSoundCacheEntry key = new SoundInfoSoundCacheEntry(soundInfo, soundTag, resample); SoundInfoSoundCacheEntry key = new SoundInfoSoundCacheEntry(soundInfo, soundTag);
if (soundCache.contains(key)) { if (soundCache.contains(key)) {
return soundCache.get(key); return soundCache.get(key);
} }
@@ -48,6 +48,7 @@ import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import jdk.jfr.internal.RemoveFields;
/** /**
* Configuration of FFDec. * Configuration of FFDec.
@@ -1003,10 +1004,12 @@ public final class Configuration {
@ConfigurationDefaultBoolean(false) @ConfigurationDefaultBoolean(false)
@ConfigurationCategory("export") @ConfigurationCategory("export")
@ConfigurationRemoved
public static ConfigurationItem<Boolean> lastExportResampleWav = null; public static ConfigurationItem<Boolean> lastExportResampleWav = null;
@ConfigurationDefaultBoolean(true) @ConfigurationDefaultBoolean(true)
@ConfigurationCategory("display") @ConfigurationCategory("display")
@ConfigurationRemoved
public static ConfigurationItem<Boolean> previewResampleSound = null; public static ConfigurationItem<Boolean> previewResampleSound = null;
@ConfigurationDefaultBoolean(false) @ConfigurationDefaultBoolean(false)
@@ -118,7 +118,7 @@ public class SoundExporter {
final File file = new File(outdir + File.separator + Helper.makeFileName(st.getCharacterExportFileName()) + ext); final File file = new File(outdir + File.separator + Helper.makeFileName(st.getCharacterExportFileName()) + ext);
new RetryTask(() -> { new RetryTask(() -> {
try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) { try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file))) {
exportSound(os, st, settings.mode, settings.resampleWav); exportSound(os, st, settings.mode);
} }
}, handler).run(); }, handler).run();
@@ -152,13 +152,13 @@ public class SoundExporter {
return ret; return ret;
} }
public byte[] exportSound(SoundTag t, SoundExportMode mode, boolean resampleWav) throws IOException { public byte[] exportSound(SoundTag t, SoundExportMode mode) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
exportSound(baos, t, mode, resampleWav); exportSound(baos, t, mode);
return baos.toByteArray(); return baos.toByteArray();
} }
public void exportSound(OutputStream fos, SoundTag st, SoundExportMode mode, boolean resampleWav) throws IOException { public void exportSound(OutputStream fos, SoundTag st, SoundExportMode mode) throws IOException {
SoundFormat fmt = st.getSoundFormat(); SoundFormat fmt = st.getSoundFormat();
SoundExportFormat nativeFormat = fmt.getNativeExportFormat(); SoundExportFormat nativeFormat = fmt.getNativeExportFormat();
@@ -202,7 +202,7 @@ public class SoundExporter {
} }
} else { } else {
List<ByteArrayRange> soundData = st.getRawSoundData(); List<ByteArrayRange> soundData = st.getRawSoundData();
fmt.createWav(null, soundData, fos, st.getInitialLatency(), resampleWav); fmt.createWav(null, soundData, fos, st.getInitialLatency());
} }
} }
} }
@@ -651,7 +651,7 @@ public class AS3ScriptExporter {
return ret; return ret;
} }
SoundExporter se = new SoundExporter(); SoundExporter se = new SoundExporter();
se.exportSounds(handler, ASSETS_DIR, rttl, new SoundExportSettings(SoundExportMode.MP3_WAV, exportSettings.resampleWav), evl); se.exportSounds(handler, ASSETS_DIR, rttl, new SoundExportSettings(SoundExportMode.MP3_WAV), evl);
if (CancellableWorker.isInterrupted()) { if (CancellableWorker.isInterrupted()) {
return ret; return ret;
} }
@@ -95,10 +95,9 @@ public class ScriptExportSettings implements Cloneable {
boolean singleFile, boolean singleFile,
boolean ignoreFrameScripts, boolean ignoreFrameScripts,
boolean exportEmbed, boolean exportEmbed,
boolean exportEmbedFlaMode, boolean exportEmbedFlaMode
boolean resampleWav
) { ) {
this(mode, singleFile, ignoreFrameScripts, exportEmbed, exportEmbedFlaMode, resampleWav, "/_assets/", false, false); this(mode, singleFile, ignoreFrameScripts, exportEmbed, exportEmbedFlaMode, "/_assets/", false, false);
} }
public ScriptExportSettings( public ScriptExportSettings(
@@ -107,7 +106,6 @@ public class ScriptExportSettings implements Cloneable {
boolean ignoreFrameScripts, boolean ignoreFrameScripts,
boolean exportEmbed, boolean exportEmbed,
boolean exportEmbedFlaMode, boolean exportEmbedFlaMode,
boolean resampleWav,
String assetsDir, String assetsDir,
boolean includeAllClasses, boolean includeAllClasses,
boolean ignoreAccessibility boolean ignoreAccessibility
@@ -117,7 +115,6 @@ public class ScriptExportSettings implements Cloneable {
this.ignoreFrameScripts = ignoreFrameScripts; this.ignoreFrameScripts = ignoreFrameScripts;
this.exportEmbed = exportEmbed; this.exportEmbed = exportEmbed;
this.exportEmbedFlaMode = exportEmbedFlaMode; this.exportEmbedFlaMode = exportEmbedFlaMode;
this.resampleWav = resampleWav;
this.assetsDir = assetsDir; this.assetsDir = assetsDir;
this.includeAllClasses = includeAllClasses; this.includeAllClasses = includeAllClasses;
this.ignoreAccessibility = ignoreAccessibility; this.ignoreAccessibility = ignoreAccessibility;
@@ -35,18 +35,13 @@ public class SoundExportSettings {
*/ */
public SoundExportMode mode; public SoundExportMode mode;
/**
* Resample WAV
*/
public boolean resampleWav;
/** /**
* Constructor. * Constructor.
* @param mode Mode * @param mode Mode
* @param resampleWav Resample WAV * @param resampleWav Resample WAV
*/ */
public SoundExportSettings(SoundExportMode mode, boolean resampleWav) { public SoundExportSettings(SoundExportMode mode) {
this.mode = mode; this.mode = mode;
this.resampleWav = resampleWav;
} }
} }
@@ -343,7 +343,7 @@ public class SwfFlashDevelopExporter {
} }
boolean parallel = Configuration.parallelSpeedUp.get(); boolean parallel = Configuration.parallelSpeedUp.get();
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(ScriptExportMode.AS, false, false, true, false, false, "/_assets/", Configuration.linkAllClasses.get(), false); ScriptExportSettings scriptExportSettings = new ScriptExportSettings(ScriptExportMode.AS, false, false, true, false, "/_assets/", Configuration.linkAllClasses.get(), false);
swf.exportActionScript(handler, outFile.toPath().getParent().resolve(srcPath).toFile().getAbsolutePath(), scriptExportSettings, parallel, eventListener); swf.exportActionScript(handler, outFile.toPath().getParent().resolve(srcPath).toFile().getAbsolutePath(), scriptExportSettings, parallel, eventListener);
} }
} }
@@ -315,7 +315,7 @@ public class SwfIntelliJIdeaExporter {
} }
boolean parallel = Configuration.parallelSpeedUp.get(); boolean parallel = Configuration.parallelSpeedUp.get();
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(ScriptExportMode.AS, false, false, true, false, false, "/_assets/", Configuration.linkAllClasses.get(), false); ScriptExportSettings scriptExportSettings = new ScriptExportSettings(ScriptExportMode.AS, false, false, true, false, "/_assets/", Configuration.linkAllClasses.get(), false);
swf.exportActionScript(handler, new File(outDir, "src").getAbsolutePath(), scriptExportSettings, parallel, eventListener); swf.exportActionScript(handler, new File(outDir, "src").getAbsolutePath(), scriptExportSettings, parallel, eventListener);
} }
} }
@@ -411,7 +411,7 @@ public class SwfVsCodeExporter {
libsDir.mkdirs(); libsDir.mkdirs();
boolean parallel = Configuration.parallelSpeedUp.get(); boolean parallel = Configuration.parallelSpeedUp.get();
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(ScriptExportMode.AS, false, false, true, false, false, "/_assets/", Configuration.linkAllClasses.get(), false); ScriptExportSettings scriptExportSettings = new ScriptExportSettings(ScriptExportMode.AS, false, false, true, false, "/_assets/", Configuration.linkAllClasses.get(), false);
swf.exportActionScript(handler, srcDir.getAbsolutePath(), scriptExportSettings, parallel, eventListener); swf.exportActionScript(handler, srcDir.getAbsolutePath(), scriptExportSettings, parallel, eventListener);
} }
} }
@@ -328,7 +328,7 @@ public class MxmlcAs3ScriptReplacer extends MxmlcRunner implements As3ScriptRepl
//This compiled code won't be used at all in original SWF, //This compiled code won't be used at all in original SWF,
//it is used only by Flex to properly compile current script //it is used only by Flex to properly compile current script
AS3ScriptExporter ex = new AS3ScriptExporter(); AS3ScriptExporter ex = new AS3ScriptExporter();
ex.exportActionScript3(swfCopy, null, tempDir.getAbsolutePath(), removedPacks, new ScriptExportSettings(ScriptExportMode.AS_METHOD_STUBS, false, false, false /* ??? FIXME */, false, true), false, null); ex.exportActionScript3(swfCopy, null, tempDir.getAbsolutePath(), removedPacks, new ScriptExportSettings(ScriptExportMode.AS_METHOD_STUBS, false, false, false /* ??? FIXME */, false), false, null);
//now really remove the classes from SWF copy //now really remove the classes from SWF copy
for (ABC a : modAbcs) { for (ABC a : modAbcs) {
@@ -83,7 +83,7 @@ public class AS3ScriptImporter {
continue; continue;
} }
try { try {
File file = pack.getExportFile(scriptsFolder, new ScriptExportSettings(ScriptExportMode.AS, false, false, false, false, true)); File file = pack.getExportFile(scriptsFolder, new ScriptExportSettings(ScriptExportMode.AS, false, false, false, false));
if (file.exists()) { if (file.exists()) {
Openable openable = pack.getOpenable(); Openable openable = pack.getOpenable();
SWF swf = (openable instanceof SWF) ? (SWF) openable : ((ABC) openable).getSwf(); SWF swf = (openable instanceof SWF) ? (SWF) openable : ((ABC) openable).getSwf();
@@ -2197,6 +2197,11 @@ public class Timeline {
*/ */
public boolean isSingleFrame(int frame) { public boolean isSingleFrame(int frame) {
Frame frameObj = getFrame(frame); Frame frameObj = getFrame(frame);
for (int i = 0; i < frameObj.innerTags.size(); i++) {
if (frameObj.innerTags.get(i) instanceof SoundStreamBlockTag) {
return false;
}
}
for (int i = 0; i <= maxDepth; i++) { for (int i = 0; i <= maxDepth; i++) {
if (!frameObj.layers.containsKey(i)) { if (!frameObj.layers.containsKey(i)) {
continue; continue;
@@ -296,7 +296,7 @@ public class SoundFormat {
return baosResampled.toByteArray(); return baosResampled.toByteArray();
} }
public boolean createWav(SOUNDINFO soundInfo, List<ByteArrayRange> dataRanges, OutputStream os, int skipSamples, boolean resample) throws IOException { public boolean createWav(SOUNDINFO soundInfo, List<ByteArrayRange> dataRanges, OutputStream os, int skipSamples) throws IOException {
byte[] decodedData = decode(soundInfo, dataRanges, skipSamples); byte[] decodedData = decode(soundInfo, dataRanges, skipSamples);
boolean convertedStereo = stereo; boolean convertedStereo = stereo;
@@ -351,10 +351,9 @@ public class SoundFormat {
convertedStereo = true; convertedStereo = true;
} }
byte[] resampled = resample ? resample(baosFiltered.toByteArray()) : baosFiltered.toByteArray();
try { try {
createWavFromPcmData(os, resample ? 44100 : samplingRate, true, convertedStereo, resampled); createWavFromPcmData(os, samplingRate, true, convertedStereo, baosFiltered.toByteArray());
return true; return true;
} catch (IOException ex) { } catch (IOException ex) {
return false; return false;
@@ -29,12 +29,10 @@ public class SoundInfoSoundCacheEntry {
public SOUNDINFO soundInfo; public SOUNDINFO soundInfo;
public SoundTag soundTag; public SoundTag soundTag;
public boolean resample;
public SoundInfoSoundCacheEntry(SOUNDINFO soundInfo, SoundTag soundTag, boolean resample) { public SoundInfoSoundCacheEntry(SOUNDINFO soundInfo, SoundTag soundTag) {
this.soundInfo = soundInfo; this.soundInfo = soundInfo;
this.soundTag = soundTag; this.soundTag = soundTag;
this.resample = resample;
} }
@Override @Override
@@ -42,7 +40,6 @@ public class SoundInfoSoundCacheEntry {
int hash = 7; int hash = 7;
hash = 97 * hash + Objects.hashCode(this.soundInfo); hash = 97 * hash + Objects.hashCode(this.soundInfo);
hash = 97 * hash + Objects.hashCode(this.soundTag); hash = 97 * hash + Objects.hashCode(this.soundTag);
hash = 97 * hash + (this.resample ? 1 : 0);
return hash; return hash;
} }
@@ -58,9 +55,6 @@ public class SoundInfoSoundCacheEntry {
return false; return false;
} }
final SoundInfoSoundCacheEntry other = (SoundInfoSoundCacheEntry) obj; final SoundInfoSoundCacheEntry other = (SoundInfoSoundCacheEntry) obj;
if (this.resample != other.resample) {
return false;
}
if (!Objects.equals(this.soundInfo, other.soundInfo)) { if (!Objects.equals(this.soundInfo, other.soundInfo)) {
return false; return false;
} }
@@ -2031,7 +2031,7 @@ public class XFLConverter {
SoundTag st = (SoundTag) symbol; SoundTag st = (SoundTag) symbol;
byte[] data = SWFInputStream.BYTE_ARRAY_EMPTY; byte[] data = SWFInputStream.BYTE_ARRAY_EMPTY;
try { try {
data = new SoundExporter().exportSound(st, convertMp3ToWav ? SoundExportMode.WAV : SoundExportMode.MP3_WAV, false); data = new SoundExporter().exportSound(st, convertMp3ToWav ? SoundExportMode.WAV : SoundExportMode.MP3_WAV);
} catch (IOException ex) { } catch (IOException ex) {
logger.log(Level.SEVERE, null, ex); logger.log(Level.SEVERE, null, ex);
} }
@@ -6157,7 +6157,7 @@ public class XFLConverter {
} }
if (useAS3 && settings.exportScript) { if (useAS3 && settings.exportScript) {
try { try {
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(ScriptExportMode.AS, false, true, false, true, true, "/_assets/", Configuration.linkAllClasses.get(), true); ScriptExportSettings scriptExportSettings = new ScriptExportSettings(ScriptExportMode.AS, false, true, false, true, "/_assets/", Configuration.linkAllClasses.get(), true);
swf.exportActionScript(handler, scriptsDir.getAbsolutePath(), scriptExportSettings, parallel, null); swf.exportActionScript(handler, scriptsDir.getAbsolutePath(), scriptExportSettings, parallel, null);
} catch (Exception ex) { } catch (Exception ex) {
logger.log(Level.SEVERE, "Error during ActionScript3 export", ex); logger.log(Level.SEVERE, "Error during ActionScript3 export", ex);
@@ -108,7 +108,7 @@ public class ExportTest extends FileTestBase {
return this; return this;
} }
}, fdir.getAbsolutePath(), new ScriptExportSettings(exportMode, false, false, false, false, true), false, null); }, fdir.getAbsolutePath(), new ScriptExportSettings(exportMode, false, false, false, false), false, null);
} catch (Exception ex) { } catch (Exception ex) {
fail("Exception during decompilation: " + filePath + " " + ex.getMessage()); fail("Exception during decompilation: " + filePath + " " + ex.getMessage());
} }
@@ -510,7 +510,6 @@ public class CommandLineArgumentParser {
boolean cliMode = false; boolean cliMode = false;
boolean air = false; boolean air = false;
boolean exportEmbed = false; boolean exportEmbed = false;
boolean resampleWav = false;
boolean transparentBackground = false; boolean transparentBackground = false;
Selection selection = new Selection(); Selection selection = new Selection();
Selection selectionIds = new Selection(); Selection selectionIds = new Selection();
@@ -549,9 +548,6 @@ public class CommandLineArgumentParser {
case "-exportembed": case "-exportembed":
exportEmbed = true; exportEmbed = true;
break; break;
case "-resamplewav":
resampleWav = true;
break;
case "-ignorebackground": case "-ignorebackground":
transparentBackground = true; transparentBackground = true;
break; break;
@@ -681,7 +677,7 @@ public class CommandLineArgumentParser {
} else if (command.equals("proxy")) { } else if (command.equals("proxy")) {
parseProxy(args); parseProxy(args);
} else if (command.equals("export")) { } else if (command.equals("export")) {
parseExport(selectionClasses, selection, selectionIds, args, handler, traceLevel, format, zoom, charset, exportEmbed, resampleWav, transparentBackground, urlResolver, subLength); parseExport(selectionClasses, selection, selectionIds, args, handler, traceLevel, format, zoom, charset, exportEmbed, transparentBackground, urlResolver, subLength);
System.exit(0); System.exit(0);
} else if (command.equals("compress")) { } else if (command.equals("compress")) {
parseCompress(args); parseCompress(args);
@@ -2121,7 +2117,6 @@ public class CommandLineArgumentParser {
double zoom, double zoom,
String charset, String charset,
boolean exportEmbed, boolean exportEmbed,
boolean resampleWav,
boolean transparentBackground, boolean transparentBackground,
UrlResolver urlResolver, UrlResolver urlResolver,
int subFrameLength) { int subFrameLength) {
@@ -2321,7 +2316,7 @@ public class CommandLineArgumentParser {
if (exportAll || exportFormats.contains("sound")) { if (exportAll || exportFormats.contains("sound")) {
System.out.println("Exporting sounds..."); System.out.println("Exporting sounds...");
new SoundExporter().exportSounds(handler, outDir + (multipleExportTypes ? File.separator + SoundExportSettings.EXPORT_FOLDER_NAME : ""), new ReadOnlyTagList(extags), new SoundExportSettings(enumFromStr(formats.get("sound"), SoundExportMode.class), resampleWav), evl); new SoundExporter().exportSounds(handler, outDir + (multipleExportTypes ? File.separator + SoundExportSettings.EXPORT_FOLDER_NAME : ""), new ReadOnlyTagList(extags), new SoundExportSettings(enumFromStr(formats.get("sound"), SoundExportMode.class)), evl);
} }
if (exportAll || exportFormats.contains("binarydata")) { if (exportAll || exportFormats.contains("binarydata")) {
@@ -2395,7 +2390,7 @@ public class CommandLineArgumentParser {
singleScriptFile = false; singleScriptFile = false;
} }
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(enumFromStr(formats.get("script"), ScriptExportMode.class), singleScriptFile, false, exportEmbed, false, resampleWav); ScriptExportSettings scriptExportSettings = new ScriptExportSettings(enumFromStr(formats.get("script"), ScriptExportMode.class), singleScriptFile, false, exportEmbed, false);
boolean exportAllScript = exportAll || exportFormats.contains("script"); boolean exportAllScript = exportAll || exportFormats.contains("script");
boolean exportAs2Script = exportAllScript || exportFormats.contains("script_as2"); boolean exportAs2Script = exportAllScript || exportFormats.contains("script_as2");
boolean exportAs3Script = exportAllScript || exportFormats.contains("script_as3"); boolean exportAs3Script = exportAllScript || exportFormats.contains("script_as3");
@@ -155,8 +155,6 @@ public class ExportDialog extends AppDialog {
private JCheckBox embedCheckBox; private JCheckBox embedCheckBox;
private JCheckBox resampleWavCheckBox;
private JCheckBox transparentFrameBackgroundCheckBox; private JCheckBox transparentFrameBackgroundCheckBox;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -184,10 +182,6 @@ public class ExportDialog extends AppDialog {
return embedCheckBox.isSelected(); return embedCheckBox.isSelected();
} }
public boolean isResampleWavEnabled() {
return resampleWavCheckBox.isSelected();
}
public boolean isTransparentFrameBackgroundEnabled() { public boolean isTransparentFrameBackgroundEnabled() {
return transparentFrameBackgroundCheckBox.isSelected(); return transparentFrameBackgroundCheckBox.isSelected();
} }
@@ -217,9 +211,6 @@ public class ExportDialog extends AppDialog {
if (embedCheckBox.isVisible()) { if (embedCheckBox.isVisible()) {
Configuration.lastExportEnableEmbed.set(embedCheckBox.isSelected()); Configuration.lastExportEnableEmbed.set(embedCheckBox.isSelected());
} }
if (resampleWavCheckBox.isVisible()) {
Configuration.lastExportResampleWav.set(resampleWavCheckBox.isSelected());
}
if (transparentFrameBackgroundCheckBox.isVisible()) { if (transparentFrameBackgroundCheckBox.isVisible()) {
Configuration.lastExportTransparentBackground.set(transparentFrameBackgroundCheckBox.isSelected()); Configuration.lastExportTransparentBackground.set(transparentFrameBackgroundCheckBox.isSelected());
} }
@@ -412,19 +403,6 @@ public class ExportDialog extends AppDialog {
} }
} }
resampleWavCheckBox = new JCheckBox(translate("resampleWav"));
resampleWavCheckBox.setVisible(false);
if (embedCheckBox.isVisible() || visibleOptionClasses.contains(SoundExportMode.class)) {
/*gbc.gridy++;
resampleWavCheckBox.setVisible(true);
comboPanel.add(resampleWavCheckBox, gbc);
if (Configuration.lastExportResampleWav.get()) {
resampleWavCheckBox.setSelected(true);
}*/
resampleWavCheckBox.setSelected(false);
}
transparentFrameBackgroundCheckBox = new JCheckBox(translate("transparentFrameBackground")); transparentFrameBackgroundCheckBox = new JCheckBox(translate("transparentFrameBackground"));
transparentFrameBackgroundCheckBox.setVisible(false); transparentFrameBackgroundCheckBox.setVisible(false);
if (visibleOptionClasses.contains(FrameExportMode.class)) { if (visibleOptionClasses.contains(FrameExportMode.class)) {
@@ -290,8 +290,6 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
private boolean muted = false; private boolean muted = false;
private boolean resample = false;
private boolean mutable = false; private boolean mutable = false;
private boolean alwaysDisplay = false; private boolean alwaysDisplay = false;
@@ -1026,11 +1024,6 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
} }
} }
@Override
public void setResample(boolean resample) {
this.resample = resample;
}
private static void drawGridSwf(Graphics2D g, Rectangle realRect, double zoom) { private static void drawGridSwf(Graphics2D g, Rectangle realRect, double zoom) {
g.setColor(Configuration.gridColor.get()); g.setColor(Configuration.gridColor.get());
double x; double x;
@@ -4788,7 +4781,6 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
this.frozen = frozen; this.frozen = frozen;
this.frozenButtons = frozenButtons; this.frozenButtons = frozenButtons;
this.muted = muted; this.muted = muted;
this.resample = false; //Configuration.previewResampleSound.get();
this.mutable = mutable; this.mutable = mutable;
depthStateUnderCursor = null; depthStateUnderCursor = null;
hilightedEdge = null; hilightedEdge = null;
@@ -5986,7 +5978,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
loopCount = Math.max(1, soundInfo.loopCount); loopCount = Math.max(1, soundInfo.loopCount);
} }
sp = new SoundTagPlayer(soundInfo, st, loopCount, false, resample); sp = new SoundTagPlayer(soundInfo, st, loopCount, false);
sp.addEventListener(new MediaDisplayListener() { sp.addEventListener(new MediaDisplayListener() {
@Override @Override
public void mediaDisplayStateChanged(MediaDisplay source) { public void mediaDisplayStateChanged(MediaDisplay source) {
@@ -2298,7 +2298,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
if (export.isOptionEnabled(SoundExportMode.class)) { if (export.isOptionEnabled(SoundExportMode.class)) {
ret.addAll(new SoundExporter().exportSounds(handler, selFile2 + File.separator + SoundExportSettings.EXPORT_FOLDER_NAME, sounds, ret.addAll(new SoundExporter().exportSounds(handler, selFile2 + File.separator + SoundExportSettings.EXPORT_FOLDER_NAME, sounds,
new SoundExportSettings(export.getValue(SoundExportMode.class), export.isResampleWavEnabled()), evl)); new SoundExportSettings(export.getValue(SoundExportMode.class)), evl));
} }
if (export.isOptionEnabled(BinaryDataExportMode.class)) { if (export.isOptionEnabled(BinaryDataExportMode.class)) {
@@ -2362,7 +2362,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
singleScriptFile = false; singleScriptFile = false;
} }
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(export.getValue(ScriptExportMode.class), singleScriptFile, false, export.isEmbedEnabled(), false, export.isResampleWavEnabled()); ScriptExportSettings scriptExportSettings = new ScriptExportSettings(export.getValue(ScriptExportMode.class), singleScriptFile, false, export.isEmbedEnabled(), false);
String singleFileName = Path.combine(scriptsFolder, openable.getShortFileName() + scriptExportSettings.getFileExtension()); String singleFileName = Path.combine(scriptsFolder, openable.getShortFileName() + scriptExportSettings.getFileExtension());
try (FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) { try (FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) {
scriptExportSettings.singleFileWriter = writer; scriptExportSettings.singleFileWriter = writer;
@@ -2416,7 +2416,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
if (export.isOptionEnabled(SoundExportMode.class)) { if (export.isOptionEnabled(SoundExportMode.class)) {
new SoundExporter().exportSounds(handler, Path.combine(selFile, SoundExportSettings.EXPORT_FOLDER_NAME), swf.getTags(), new SoundExporter().exportSounds(handler, Path.combine(selFile, SoundExportSettings.EXPORT_FOLDER_NAME), swf.getTags(),
new SoundExportSettings(export.getValue(SoundExportMode.class), export.isResampleWavEnabled()), evl); new SoundExportSettings(export.getValue(SoundExportMode.class)), evl);
} }
if (export.isOptionEnabled(BinaryDataExportMode.class)) { if (export.isOptionEnabled(BinaryDataExportMode.class)) {
@@ -2469,7 +2469,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
singleScriptFile = false; singleScriptFile = false;
} }
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(export.getValue(ScriptExportMode.class), singleScriptFile, false, export.isEmbedEnabled(), false, export.isResampleWavEnabled()); ScriptExportSettings scriptExportSettings = new ScriptExportSettings(export.getValue(ScriptExportMode.class), singleScriptFile, false, export.isEmbedEnabled(), false);
String singleFileName = Path.combine(scriptsFolder, swf.getShortFileName() + scriptExportSettings.getFileExtension()); String singleFileName = Path.combine(scriptsFolder, swf.getShortFileName() + scriptExportSettings.getFileExtension());
try (FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) { try (FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) {
scriptExportSettings.singleFileWriter = writer; scriptExportSettings.singleFileWriter = writer;
@@ -2519,7 +2519,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
if (export.isOptionEnabled(SoundExportMode.class)) { if (export.isOptionEnabled(SoundExportMode.class)) {
for (SoundExportMode exportMode : SoundExportMode.values()) { for (SoundExportMode exportMode : SoundExportMode.values()) {
new SoundExporter().exportSounds(handler, Path.combine(selFile, SoundExportSettings.EXPORT_FOLDER_NAME, exportMode.name()), swf.getTags(), new SoundExporter().exportSounds(handler, Path.combine(selFile, SoundExportSettings.EXPORT_FOLDER_NAME, exportMode.name()), swf.getTags(),
new SoundExportSettings(exportMode, export.isResampleWavEnabled()), evl); new SoundExportSettings(exportMode), evl);
} }
} }
@@ -2586,7 +2586,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
singleScriptFile = false; singleScriptFile = false;
} }
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(exportMode, singleScriptFile, false, export.isEmbedEnabled(), false, export.isResampleWavEnabled()); ScriptExportSettings scriptExportSettings = new ScriptExportSettings(exportMode, singleScriptFile, false, export.isEmbedEnabled(), false);
String singleFileName = Path.combine(scriptsFolder, swf.getShortFileName() + scriptExportSettings.getFileExtension()); String singleFileName = Path.combine(scriptsFolder, swf.getShortFileName() + scriptExportSettings.getFileExtension());
try (FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) { try (FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) {
scriptExportSettings.singleFileWriter = writer; scriptExportSettings.singleFileWriter = writer;
@@ -6187,7 +6187,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
previewPanel.setImageReplaceButtonVisible(false, false, false, !((SoundTag) treeItem).isReadOnly() && ((SoundTag) treeItem).importSupported(), false, false, false); previewPanel.setImageReplaceButtonVisible(false, false, false, !((SoundTag) treeItem).isReadOnly() && ((SoundTag) treeItem).importSupported(), false, false, false);
if (!(treeItem instanceof SoundStreamHeadTypeTag)) { if (!(treeItem instanceof SoundStreamHeadTypeTag)) {
try { try {
SoundTagPlayer soundThread = new SoundTagPlayer(null, (SoundTag) treeItem, Configuration.loopMedia.get() ? Integer.MAX_VALUE : 1, true, false); // Configuration.previewResampleSound.get()); SoundTagPlayer soundThread = new SoundTagPlayer(null, (SoundTag) treeItem, Configuration.loopMedia.get() ? Integer.MAX_VALUE : 1, true);
if (!Configuration.autoPlaySounds.get()) { if (!Configuration.autoPlaySounds.get()) {
soundThread.pause(); soundThread.pause();
} }
@@ -54,8 +54,6 @@ public class SoundTagPlayer implements MediaDisplay {
private boolean closed = false; private boolean closed = false;
private boolean resample = false;
private final Object playLock = new Object(); private final Object playLock = new Object();
private final SoundTag tag; private final SoundTag tag;
@@ -76,16 +74,12 @@ public class SoundTagPlayer implements MediaDisplay {
private double microsecPerByte = 0; private double microsecPerByte = 0;
private double microsecPerByteResampled = 0;
private double positionMicrosec = 0; private double positionMicrosec = 0;
private Long newPositionMicrosec = null; private Long newPositionMicrosec = null;
private byte[] wavData = null; private byte[] wavData = null;
private byte[] wavDataResampled = null;
private boolean active = false; private boolean active = false;
private static int totalInstances = 0; private static int totalInstances = 0;
@@ -166,7 +160,7 @@ public class SoundTagPlayer implements MediaDisplay {
private static final int FRAME_DIVISOR = 8000; private static final int FRAME_DIVISOR = 8000;
public SoundTagPlayer(final SOUNDINFO soundInfo, final SoundTag tag, int loops, boolean async, boolean resample) throws LineUnavailableException, IOException, UnsupportedAudioFileException { public SoundTagPlayer(final SOUNDINFO soundInfo, final SoundTag tag, int loops, boolean async) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
this.tag = tag; this.tag = tag;
this.loopCount = loops; this.loopCount = loops;
@@ -188,13 +182,11 @@ public class SoundTagPlayer implements MediaDisplay {
setPausedFlag(true); setPausedFlag(true);
} }
this.resample = resample;
thread = new Thread("Sound tag player") { thread = new Thread("Sound tag player") {
@Override @Override
public void run() { public void run() {
try { try {
openSound(soundInfo, tag, resample); openSound(soundInfo, tag);
} catch (IOException | LineUnavailableException | UnsupportedAudioFileException ex) { } catch (IOException | LineUnavailableException | UnsupportedAudioFileException ex) {
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex); Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
} }
@@ -216,20 +208,16 @@ public class SoundTagPlayer implements MediaDisplay {
thread.start(); thread.start();
} }
private void openSound(SOUNDINFO soundInfo, SoundTag tag, boolean resample) throws IOException, LineUnavailableException, UnsupportedAudioFileException { private void openSound(SOUNDINFO soundInfo, SoundTag tag) throws IOException, LineUnavailableException, UnsupportedAudioFileException {
SWF swf = (SWF) tag.getOpenable(); SWF swf = (SWF) tag.getOpenable();
wavData = swf.getFromCache(soundInfo, tag, false); wavData = swf.getFromCache(soundInfo, tag);
wavDataResampled = swf.getFromCache(soundInfo, tag, true); if (wavData == null) {
if (wavData == null || wavDataResampled == null) {
List<ByteArrayRange> soundData = tag.getRawSoundData(); List<ByteArrayRange> soundData = tag.getRawSoundData();
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
tag.getSoundFormat().createWav(soundInfo, soundData, baos, tag.getInitialLatency(), false); tag.getSoundFormat().createWav(soundInfo, soundData, baos, tag.getInitialLatency());
wavData = baos.toByteArray(); wavData = baos.toByteArray();
swf.putToCache(soundInfo, tag, false, wavData); swf.putToCache(soundInfo, tag, wavData);
baos = new ByteArrayOutputStream(); baos = new ByteArrayOutputStream();
tag.getSoundFormat().createWav(soundInfo, soundData, baos, tag.getInitialLatency(), true);
wavDataResampled = baos.toByteArray();
swf.putToCache(soundInfo, tag, true, wavDataResampled);
} }
long soundLength44 = 0; long soundLength44 = 0;
@@ -255,7 +243,6 @@ public class SoundTagPlayer implements MediaDisplay {
break; break;
} }
microsecPerByteResampled = 1000000d / (44100d * sampleLen);
lengthInMicroSec = soundLength44 * 1000000 / 44100; lengthInMicroSec = soundLength44 * 1000000 / 44100;
synchronized (playLock) { synchronized (playLock) {
@@ -300,7 +287,7 @@ public class SoundTagPlayer implements MediaDisplay {
} }
private void reloadAudioStream() throws IOException, UnsupportedAudioFileException, LineUnavailableException { private void reloadAudioStream() throws IOException, UnsupportedAudioFileException, LineUnavailableException {
audioStream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(resample ? wavDataResampled : wavData)); audioStream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(wavData));
if (sourceLine != null) { if (sourceLine != null) {
sourceLine.drain(); sourceLine.drain();
@@ -330,7 +317,7 @@ public class SoundTagPlayer implements MediaDisplay {
} }
if (!getPausedFlag()) { if (!getPausedFlag()) {
if (newPositionMicrosec != null) { if (newPositionMicrosec != null) {
long newPosBytes = (long) (newPositionMicrosec / (resample ? microsecPerByteResampled : microsecPerByte)); long newPosBytes = (long) (newPositionMicrosec / microsecPerByte);
audioStream.close(); audioStream.close();
reloadAudioStream(); reloadAudioStream();
audioStream.skip(newPosBytes); audioStream.skip(newPosBytes);
@@ -346,7 +333,7 @@ public class SoundTagPlayer implements MediaDisplay {
} }
sourceLine.write(data, 0, numReadBytes); sourceLine.write(data, 0, numReadBytes);
synchronized (playLock) { synchronized (playLock) {
positionMicrosec = (resample ? microsecPerByteResampled : microsecPerByte) * posBytes; positionMicrosec = microsecPerByte * posBytes;
} }
} }
} }
@@ -491,11 +478,6 @@ public class SoundTagPlayer implements MediaDisplay {
} }
} }
public void setResample(boolean resample) {
this.resample = resample;
rewind();
}
@Override @Override
public void gotoFrame(int frame) { public void gotoFrame(int frame) {
synchronized (playLock) { synchronized (playLock) {
@@ -43,8 +43,6 @@ public interface MediaDisplay extends Closeable {
public void setLoop(boolean loop); public void setLoop(boolean loop);
public void setResample(boolean resample);
public void gotoFrame(int frame); public void gotoFrame(int frame);
public void setBackground(Color color); public void setBackground(Color color);
@@ -69,8 +69,6 @@ public class PlayerControls extends JPanel implements MediaDisplayListener {
private final JButton loopButton; private final JButton loopButton;
private final JToggleButton resampleButton;
private MediaDisplay display; private MediaDisplay display;
private JProgressBar progress; private JProgressBar progress;
@@ -91,8 +89,6 @@ public class PlayerControls extends JPanel implements MediaDisplayListener {
private static final Icon noLoopIcon = View.getIcon("loopoff16"); private static final Icon noLoopIcon = View.getIcon("loopoff16");
private static final Icon resampleIcon = View.getIcon("resample16");
//private final JLabel percentLabel = new JLabel("100%"); //private final JLabel percentLabel = new JLabel("100%");
private final ZoomPanel zoomPanel; private final ZoomPanel zoomPanel;
@@ -293,16 +289,9 @@ public class PlayerControls extends JPanel implements MediaDisplayListener {
boolean loop = Configuration.loopMedia.get(); boolean loop = Configuration.loopMedia.get();
loopButton.setIcon(loop ? loopIcon : noLoopIcon); loopButton.setIcon(loop ? loopIcon : noLoopIcon);
resampleButton = new JToggleButton(resampleIcon);
resampleButton.setToolTipText(AppStrings.translate("preview.resample"));
resampleButton.setMargin(new Insets(4, 2, 2, 2));
resampleButton.addActionListener(this::resampleButtonActionPerformed);
resampleButton.setSelected(false); //Configuration.previewResampleSound.get());
buttonsPanel.add(pauseButton); buttonsPanel.add(pauseButton);
buttonsPanel.add(stopButton); buttonsPanel.add(stopButton);
buttonsPanel.add(loopButton); buttonsPanel.add(loopButton);
//buttonsPanel.add(resampleButton);
controlPanel.add(buttonsPanel, BorderLayout.CENTER); controlPanel.add(buttonsPanel, BorderLayout.CENTER);
progress = new JProgressBar(); progress = new JProgressBar();
@@ -444,12 +433,6 @@ public class PlayerControls extends JPanel implements MediaDisplayListener {
display.setLoop(loop); display.setLoop(loop);
} }
private void resampleButtonActionPerformed(ActionEvent evt) {
boolean resample = resampleButton.isSelected();
Configuration.previewResampleSound.set(resample);
display.setResample(resample);
}
private void gotoFrameButtonActionPerformed(ActionEvent evt) { private void gotoFrameButtonActionPerformed(ActionEvent evt) {
final JPanel gotoPanel = new JPanel(new BorderLayout()); final JPanel gotoPanel = new JPanel(new BorderLayout());
final JTextField frameField = new JTextField("" + display.getCurrentFrame()); final JTextField frameField = new JTextField("" + display.getCurrentFrame());