diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/SoundImporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/SoundImporter.java index 73bc87363..5d9911e12 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/SoundImporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/SoundImporter.java @@ -27,7 +27,6 @@ import com.jpexs.decompiler.flash.tags.SoundStreamBlockTag; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.SoundImportException; -import com.jpexs.decompiler.flash.tags.base.SoundParametersMismatchException; import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag; import com.jpexs.decompiler.flash.tags.base.SoundTag; import com.jpexs.decompiler.flash.tags.base.UnsupportedSamplingRateException; @@ -245,7 +244,7 @@ public class SoundImporter { * @return True if sound stream was imported successfully * @throws UnsupportedSamplingRateException On unsupported sampling rate */ - public boolean importSoundStream(SoundStreamHeadTypeTag streamHead, InputStream is, int newSoundFormat) throws UnsupportedSamplingRateException, SoundParametersMismatchException { + public boolean importSoundStream(SoundStreamHeadTypeTag streamHead, InputStream is, int newSoundFormat) throws UnsupportedSamplingRateException { return importSoundStreamAtFrame(streamHead, is, newSoundFormat, null); } @@ -260,30 +259,50 @@ public class SoundImporter { * @return True if sound stream was imported successfully * @throws UnsupportedSamplingRateException On unsupported sampling rate */ - public boolean importSoundStreamAtFrame(SoundStreamHeadTypeTag streamHead, InputStream is, int newSoundFormat, Integer startFrame) throws UnsupportedSamplingRateException, SoundParametersMismatchException { + public boolean importSoundStreamAtFrame(SoundStreamHeadTypeTag streamHead, InputStream is, int newSoundFormat, Integer startFrame) throws UnsupportedSamplingRateException { List mp3Frames = null; int newSoundRate = -1; boolean newSoundSize = false; boolean newSoundType = false; long newSoundSampleCount = -1; byte[] uncompressedSoundData = null; - int bytesPerSwfFrame = -1; + byte[] mp3data = null; SWF swf = streamHead.getSwf(); int sampleLen = 0; int soundRateHz = 0; + + int bitRateOriginal = -1; + int newBitRate = -1; + if (streamHead.getSoundFormatId() == SoundFormat.FORMAT_MP3) { + List ranges = streamHead.getRanges(); + if (!ranges.isEmpty()) { + SWFInputStream sis; + try { + sis = new SWFInputStream(swf, ranges.get(0).blocks.get(0).streamSoundData.getRangeData()); + MP3SOUNDDATA s = new MP3SOUNDDATA(sis, false); + if (!s.frames.isEmpty()) { + bitRateOriginal = s.frames.get(0).getBitRate(); + } + } catch (IOException ex) { + //ignore + } + } + } + switch (newSoundFormat) { case SoundFormat.FORMAT_UNCOMPRESSED_LITTLE_ENDIAN: try (AudioInputStream audioIs = AudioSystem.getAudioInputStream(new BufferedInputStream(is))) { AudioFormat fmt = audioIs.getFormat(); newSoundType = fmt.getChannels() == 2; newSoundSize = fmt.getSampleSizeInBits() == 16; + bitRateOriginal = -1; //newSoundSampleCount = audioIs.getFrameLength(); uncompressedSoundData = Helper.readStream(audioIs); sampleLen = (newSoundType ? 2 : 1) * (newSoundSize ? 2 : 1); soundRateHz = (int) Math.round(fmt.getSampleRate()); newSoundSampleCount = (int) Math.ceil(soundRateHz / swf.frameRate); - bytesPerSwfFrame = (int) Math.ceil(soundRateHz / swf.frameRate) * sampleLen; + //bytesPerSwfFrame = (int) Math.ceil(soundRateHz / swf.frameRate) * sampleLen; switch (soundRateHz) { case 5512: newSoundRate = 0; @@ -308,7 +327,7 @@ public class SoundImporter { case SoundFormat.FORMAT_MP3: BufferedInputStream bis = new BufferedInputStream(is); loadID3v2(bis); - byte[] mp3data = Helper.readStream(bis); + mp3data = Helper.readStream(bis); final int ID3_V1_LENTGH = 128; final int ID3_V1_EXT_LENGTH = 227; @@ -330,6 +349,7 @@ public class SoundImporter { if (!snd.frames.isEmpty()) { MP3FRAME fr = snd.frames.get(0); soundRateHz = fr.getSamplingRate(); + newBitRate = fr.getBitRate(); switch (soundRateHz) { case 11025: newSoundRate = 1; @@ -368,20 +388,85 @@ public class SoundImporter { if (newSoundFormat != streamHead.getSoundFormatId() || newSoundSize != streamHead.getSoundSize() || newSoundType != streamHead.getSoundType() - || newSoundRate != streamHead.getSoundRate()) { - throw new SoundParametersMismatchException( - streamHead.getSoundType(), - streamHead.getSoundSize(), - streamHead.getSoundRate(), - streamHead.getSoundFormatId(), - newSoundType, - newSoundSize, - newSoundRate, - newSoundFormat - ); + || newSoundRate != streamHead.getSoundRate() + || newBitRate != bitRateOriginal) { + List data = streamHead.getRawSoundData(); + byte[] wholeStreamUncompressedData; + try { + wholeStreamUncompressedData = streamHead.getSoundFormat().decode(null, data, 0); + } catch (IOException ex) { + return false; + } + if (mp3data != null) { + final int[] rateMap = {5512, 11025, 22050, 44100}; + SoundFormat mp3SoundFormat = new SoundFormat(SoundFormat.FORMAT_MP3, rateMap[newSoundRate], newSoundType); + try { + uncompressedSoundData = mp3SoundFormat.decode(null, Arrays.asList(new ByteArrayRange(mp3data)), 0); + } catch (IOException ex) { + return false; + } + mp3Frames = null; + } + + newSoundFormat = SoundFormat.FORMAT_UNCOMPRESSED_LITTLE_ENDIAN; + + //16bit<>8bit does not match, convert to 16bit + if (newSoundSize && !streamHead.getSoundSize()) { + wholeStreamUncompressedData = to16bit(wholeStreamUncompressedData); + } else if (streamHead.getSoundSize() && !newSoundSize) { + uncompressedSoundData = to16bit(uncompressedSoundData);; + newSoundSize = true; + } + + //stereo<>mono does not match, convert to stereo + if (newSoundType && !streamHead.getSoundType()) { + wholeStreamUncompressedData = toStereo(wholeStreamUncompressedData, newSoundSize); + } else if (streamHead.getSoundType() && !newSoundType) { + uncompressedSoundData = toStereo(uncompressedSoundData, newSoundSize); + newSoundType = true; + } + + //sound rate does not match, convert to the higher one + if (newSoundRate > streamHead.getSoundRate()) { + for (int i = streamHead.getSoundRate(); i < newSoundRate; i++) { + wholeStreamUncompressedData = toHigherRate(wholeStreamUncompressedData, newSoundSize, newSoundType); + } + } else if (streamHead.getSoundRate() > newSoundRate) { + for (int i = newSoundRate; i < streamHead.getSoundRate(); i++) { + uncompressedSoundData = toHigherRate(uncompressedSoundData, newSoundSize, newSoundType); + } + newSoundRate = streamHead.getSoundRate(); + } + + sampleLen = (newSoundType ? 2 : 1) * (newSoundSize ? 2 : 1); + final int[] rateMap = {5512, 11025, 22050, 44100}; + addStream(streamHead, wholeStreamUncompressedData, swf, rateMap[newSoundRate], sampleLen, null, null, true); } } + addStream(streamHead, uncompressedSoundData, swf, soundRateHz, sampleLen, mp3Frames, startFrame, false); + streamHead.setSoundCompression(newSoundFormat); + streamHead.setSoundSampleCount((int) newSoundSampleCount); + streamHead.setSoundSize(newSoundSize); + streamHead.setSoundType(newSoundType); + streamHead.setSoundRate(newSoundRate); + + streamHead.setModified(true); + streamHead.getTimelined().resetTimeline(); + swf.resetTimeline(); //to reload blocks + return true; + } + + private void addStream( + SoundStreamHeadTypeTag streamHead, + byte[] uncompressedSoundData, + SWF swf, + int soundRateHz, + int sampleLen, + List mp3Frames, + Integer startFrame, + boolean matchRanges + ) { ByteArrayInputStream bais = uncompressedSoundData == null ? null : new ByteArrayInputStream(uncompressedSoundData); List ranges = streamHead.getRanges(); @@ -418,7 +503,6 @@ public class SoundImporter { for (SoundStreamBlockTag block : existingBlocks) { timelined.removeTag(block); } - List blocks = new ArrayList<>(); if (bais != null) { //Uncompressed DataInputStream dais = new DataInputStream(bais); @@ -512,7 +596,18 @@ public class SoundImporter { } if (t instanceof ShowFrameTag) { frame++; - if (frame >= startFrame && !blocks.isEmpty()) { + boolean match = false; + if (matchRanges) { + for (SoundStreamFrameRange range : ranges) { + if (frame >= range.startFrame && frame <= range.endFrame) { + match = true; + break; + } + } + } else if (frame >= startFrame) { + match = true; + } + if (match && !blocks.isEmpty()) { SoundStreamBlockTag block = blocks.remove(0); block.setTimelined(timelined); timelined.addTag(i, block); @@ -534,16 +629,107 @@ public class SoundImporter { framesBefore++; } timelined.setFrameCount(framesBefore); - streamHead.setSoundCompression(newSoundFormat); - streamHead.setSoundSampleCount((int) newSoundSampleCount); - streamHead.setSoundSize(newSoundSize); - streamHead.setSoundType(newSoundType); - streamHead.setSoundRate(newSoundRate); - - streamHead.setModified(true); timelined.resetTimeline(); - swf.resetTimeline(); //to reload blocks - return true; + } + + private byte[] toStereo(byte[] data, boolean soundSize) { + byte[] ret = new byte[data.length * 2]; + for (int i = 0; i < data.length; i += (soundSize ? 2 : 1)) { + if (soundSize) { + ret[i * 2] = data[i]; + ret[i * 2 + 1] = data[i + 1]; + ret[i * 2 + 2] = data[i]; + ret[i * 2 + 3] = data[i + 1]; + } else { + ret[i * 2] = data[i]; + ret[i * 2 + 1] = data[i]; + } + } + return ret; + } + + private byte[] to16bit(byte[] data) { + byte[] ret = new byte[data.length * 2]; + for (int i = 0; i < data.length; i++) { + int val = data[i] & 0xFF; + val = val * 65535 / 255; + ret[i * 2] = (byte) (val & 0xFF); + ret[i * 2 + 1] = (byte) ((val >> 8) & 0xFF); + } + return ret; + } + + /** + * Resamples sound data to higher sound rate (doubles sound rate) 5512, + * 11025, 22050, 44100 + * + * @param data Input data + * @param soundSize True = 2 bytes little endian per channel, False = 1 byte + * per channel + * @param soundType True = Stereo = two channels, False = mono = single + * channel + * @return Resampled data + */ + private byte[] toHigherRate(byte[] data, boolean soundSize, boolean soundType) { + int sampleLen = (soundType ? 2 : 1) * (soundSize ? 2 : 1); + byte[] ret = new byte[data.length * 2 - sampleLen]; + int prevLeft = 0; + int prevRight = 0; + int retPos = 0; + for (int i = 0; i < data.length; i += sampleLen) { + int left; + int right; + if (soundSize) { + left = (short) ((data[i] & 0xFF) + ((data[i + 1] & 0xFF) << 8)); + if (soundType) { + right = (short) ((data[i + 2] & 0xFF) + ((data[i + 3] & 0xFF) << 8)); + } else { + right = left; + } + } else { + left = data[i]; + if (soundType) { + right = data[i + 1]; + } else { + right = left; + } + } + if (i > 0) { + int midLeft = (prevLeft + left) / 2; + int midRight = (prevRight + right) / 2; + if (soundSize) { + ret[retPos] = (byte) (midLeft & 0xFF); + ret[retPos + 1] = (byte) ((midLeft >> 8) & 0xFF); + if (soundType) { + ret[retPos + 2] = (byte) (midRight & 0xFF); + ret[retPos + 3] = (byte) ((midRight >> 8) & 0xFF); + } + } else { + ret[retPos] = (byte) (midLeft & 0xFF); + if (soundType) { + ret[retPos + 1] = (byte) (midRight & 0xFF); + } + } + retPos += sampleLen; + } + if (soundSize) { + ret[retPos] = (byte) (left & 0xFF); + ret[retPos + 1] = (byte) ((left >> 8) & 0xFF); + if (soundType) { + ret[retPos + 2] = (byte) (right & 0xFF); + ret[retPos + 3] = (byte) ((right >> 8) & 0xFF); + } + } else { + ret[retPos] = (byte) (left & 0xFF); + if (soundType) { + ret[retPos + 1] = (byte) (right & 0xFF); + } + } + prevLeft = left; + prevRight = right; + retPos += sampleLen; + } + return ret; } /** @@ -624,7 +810,8 @@ public class SoundImporter { } int pos = -1; - loopChars: for (SoundTag tag : soundTags) { + loopChars: + for (SoundTag tag : soundTags) { pos++; int characterId = tag.getCharacterId(); List existingFilesForSoundTag = new ArrayList<>(); @@ -670,7 +857,7 @@ public class SoundImporter { for (SoundStreamFrameRange r : ranges.get(pos)) { for (File sourceFile : existingFilesForSoundTag) { if (sourceFile.getName().startsWith("" + characterId + "_" + (r.startFrame + 1) + "-")) { - + try { if (printOut) { System.out.println("Importing character " + characterId + ", start frame " + r.startFrame + " from file " + sourceFile.getName()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/AppResources.properties b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/AppResources.properties index 43393f9fc..f736fb975 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/AppResources.properties +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/AppResources.properties @@ -61,5 +61,3 @@ configurationFile.meta.showComments = Show configuration comments - set to true configurationFile.meta.modifiedOnly = Store modified items only in this file - set to false (and exit app again to resave) to show all. configurationFile.configuration = Section - Actual configuration configuration.removed = WARNING: This configuration was REMOVED. It is unused. - -exception.soundFormat.expected = Required format for import to this sound stream: %expected%\nFormat of selected file:%actual%\nPlease convert the file to the required format and try again. diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/AppResources_cs.properties b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/AppResources_cs.properties index a8f42ce71..fa6774568 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/AppResources_cs.properties +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/AppResources_cs.properties @@ -62,5 +62,3 @@ configurationFile.meta.showComments = Zobrazit koment\u00e1\u0159e ke konfigurac configurationFile.meta.modifiedOnly = Ukl\u00e1dat do tohoto souboru pouze zm\u011bn\u011bn\u00e9 hodnoty - nastavte na false (a ukon\u010dete aplikaci pro nov\u00e9 ulo\u017een\u00ed) pro zobrazen\u00ed v\u0161eho. configurationFile.configuration = Sekce - Vlastn\u00ed konfigurace configuration.removed = VAROV\u00c1N\u00cd: Tato konfigurace byla ODSTRAN\u011aNA. Nepou\u017e\u00edv\u00e1 se. - -exception.soundFormat.expected = Vy\u017eadovan\u00fd form\u00e1t pro import do tohoto zvukov\u00e9ho streamu: %expected%\nForm\u00e1t vybran\u00e9ho souboru: %actual%\nPros\u00edm zkonvertujte soubor do vy\u017eadovan\u00e9ho form\u00e1tu a zkuste to znovu. diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/SoundParametersMismatchException.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/SoundParametersMismatchException.java deleted file mode 100644 index 9801d9700..000000000 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/SoundParametersMismatchException.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2010-2025 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.tags.base; - -import com.jpexs.decompiler.flash.AppResources; - -/** - * - * @author JPEXS - */ -public class SoundParametersMismatchException extends SoundImportException { - - /** - * - * @param expectedSoundType - * @param expectedSoundSize - * @param expectedSoundRate - * @param expectedSoundFormat - */ - public SoundParametersMismatchException( - boolean expectedSoundType, - boolean expectedSoundSize, - int expectedSoundRate, - int expectedSoundFormat, - boolean actualSoundType, - boolean actualSoundSize, - int actualSoundRate, - int actualSoundFormat) { - super(AppResources.translate("exception.soundFormat.expected").replace("%expected%", - (expectedSoundType ? "stereo" : "mono") + " " - + (expectedSoundSize ? "16bit" : "8bit") + " " - + new int[]{5512, 11025, 22050, 44100}[expectedSoundRate] + " Hz" - + " " + new String[]{ - "uncompressed native endian", - "adpcm", - "mp3", - "uncompressed little endian", - "nellymoser 16 kHz", - "nellymoser 8 kHz", - "nellymoser", - "", - "", - "", - "", - "speex" - }[expectedSoundFormat]).replace("%actual%", - (actualSoundType ? "stereo" : "mono") + " " - + (actualSoundSize ? "16bit" : "8bit") + " " - + new int[]{5512, 11025, 22050, 44100}[actualSoundRate] + " Hz" - + " " + new String[]{ - "uncompressed native endian", - "adpcm", - "mp3", - "uncompressed little endian", - "nellymoser 16 kHz", - "nellymoser 8 kHz", - "nellymoser", - "", - "", - "", - "", - "speex" - }[actualSoundFormat])); - } -} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/sound/MP3SOUNDDATA.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/sound/MP3SOUNDDATA.java index ba6283430..fb7d6a73f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/sound/MP3SOUNDDATA.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/sound/MP3SOUNDDATA.java @@ -52,7 +52,6 @@ public class MP3SOUNDDATA { 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) { @@ -60,7 +59,7 @@ public class MP3SOUNDDATA { } long posAfter = initLen + mpis.getPosition(); frame.setFullData(Arrays.copyOfRange(data, (int) posBefore, (int) posAfter)); - frames.add(frame); + frames.add(frame); } } diff --git a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java index 258c94abc..76d1d1e63 100644 --- a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java +++ b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java @@ -163,7 +163,6 @@ import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; import com.jpexs.decompiler.flash.tags.base.RenderContext; import com.jpexs.decompiler.flash.tags.base.ShapeTag; import com.jpexs.decompiler.flash.tags.base.SoundImportException; -import com.jpexs.decompiler.flash.tags.base.SoundParametersMismatchException; import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag; import com.jpexs.decompiler.flash.tags.base.SoundTag; import com.jpexs.decompiler.flash.tags.base.TextImportErrorHandler; @@ -3056,8 +3055,6 @@ public class CommandLineArgumentParser { } System.err.println("Import FAILED. Input file has unsupported sampling rate (" + usre.getSoundRate() + "). Supported rates for this sound format: " + String.join(", ", supportedRatesStr) + "."); System.exit(2); - } catch (SoundParametersMismatchException ex) { - System.err.println("Import FAILED. Input file has different format that target stream. Target stream format: " + ex.getMessage()); } if (!ok) { System.err.println("Import FAILED. Maybe unsupported media type? Only MP3 and uncompressed WAV are available."); @@ -3124,9 +3121,6 @@ public class CommandLineArgumentParser { SoundImporter soundImporter = new SoundImporter(); try { ok = soundImporter.importSound(st, new ByteArrayInputStream(data), soundFormat, startFrame); - } catch (SoundParametersMismatchException spm) { - System.err.println("Import FAILED. " + spm.getMessage()); - System.exit(3); } catch (UnsupportedSamplingRateException usre) { List supportedRatesStr = new ArrayList<>(); for (int i : usre.getSupportedRates()) { diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 6aa52b306..5a78dd5b0 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -172,7 +172,6 @@ import com.jpexs.decompiler.flash.tags.base.MorphShapeTag; import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; import com.jpexs.decompiler.flash.tags.base.ShapeTag; import com.jpexs.decompiler.flash.tags.base.SoundImportException; -import com.jpexs.decompiler.flash.tags.base.SoundParametersMismatchException; import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag; import com.jpexs.decompiler.flash.tags.base.SoundTag; import com.jpexs.decompiler.flash.tags.base.SymbolClassTypeTag; @@ -5121,16 +5120,16 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se TreeItem ti0 = items.get(0); File file = null; if (ti0 instanceof SoundTag) { - if (ti0 instanceof SoundStreamFrameRange) { + /*if (ti0 instanceof SoundStreamFrameRange) { SoundStreamFrameRange r = (SoundStreamFrameRange) ti0; if (r.getSoundFormatId() == SoundFormat.FORMAT_MP3) { file = showImportFileChooser("filter.sounds.mp3|*.mp3", false, "importsound"); } else { file = showImportFileChooser("filter.sounds.wav|*.wav", false, "importsound"); } - } else { - file = showImportFileChooser("filter.sounds|*.mp3;*.wav|filter.sounds.mp3|*.mp3|filter.sounds.wav|*.wav", false, "importsound"); - } + } else {*/ + file = showImportFileChooser("filter.sounds|*.mp3;*.wav|filter.sounds.mp3|*.mp3|filter.sounds.wav|*.wav", false, "importsound"); + //} } if (ti0 instanceof ImageTag) { file = showImportFileChooser("filter.images|*.jpg;*.jpeg;*.gif;*.png;*.bmp", true, "importimage"); @@ -5187,9 +5186,6 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } ViewMessages.showMessageDialog(this, translate("error.sound.rate").replace("%saplingRate%", samplingRateKhz).replace("%supportedRates%", String.join(", ", supportedRatesKhz)), translate("error"), JOptionPane.ERROR_MESSAGE); return; - } catch (SoundParametersMismatchException ex) { - ViewMessages.showMessageDialog(this, ex.getMessage(), translate("error"), JOptionPane.ERROR_MESSAGE); - return; } catch (SoundImportException ex) { //ignore }