Fixed: Flash viewer - Sound envelope handling

This commit is contained in:
Jindra Petřík
2021-03-23 22:41:19 +01:00
parent efdcb27963
commit 9a45708ebb
17 changed files with 313 additions and 52 deletions

View File

@@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file.
- Folder preview of frames with time increasing
- Flash viewer - Do not play StartSoundTag all over again on single frame
- Flash viewer - StartSoundTag loops
- Flash viewer - Sound envelope handling
### Changed
- [#1661] Slow rendering warning is optional with default to not display

View File

@@ -144,8 +144,11 @@ import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.MATRIX;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.SHAPE;
import com.jpexs.decompiler.flash.types.SOUNDENVELOPE;
import com.jpexs.decompiler.flash.types.SOUNDINFO;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.flash.types.annotations.SWFField;
import com.jpexs.decompiler.flash.types.sound.SoundInfoSoundCacheEntry;
import com.jpexs.decompiler.flash.xfl.FLAVersion;
import com.jpexs.decompiler.flash.xfl.XFLConverter;
import com.jpexs.decompiler.flash.xfl.XFLExportSettings;
@@ -341,7 +344,7 @@ public final class SWF implements SWFContainerItem, Timelined {
private final Cache<SHAPE, ShapeExportData> shapeExportDataCache = Cache.getInstance(true, true, "shapeExportData");
@Internal
private final Cache<SoundTag, byte[]> soundCache = Cache.getInstance(false, false, "sound");
private final Cache<SoundInfoSoundCacheEntry, byte[]> soundCache = Cache.getInstance(false, false, "sound");
@Internal
public final AS2Cache as2Cache = new AS2Cache();
@@ -2577,9 +2580,10 @@ public final class SWF implements SWFContainerItem, Timelined {
return null;
}
public byte[] getFromCache(SoundTag soundTag) {
if (soundCache.contains(soundTag)) {
return soundCache.get(soundTag);
public byte[] getFromCache(SOUNDINFO soundInfo, SoundTag soundTag) {
SoundInfoSoundCacheEntry key = new SoundInfoSoundCacheEntry(soundInfo, soundTag);
if (soundCache.contains(key)) {
return soundCache.get(key);
}
return null;
}
@@ -2590,8 +2594,9 @@ public final class SWF implements SWFContainerItem, Timelined {
}
}
public void putToCache(SoundTag soundTag, byte[] data) {
soundCache.put(soundTag, data);
public void putToCache(SOUNDINFO soundInfo, SoundTag soundTag, byte[] data) {
SoundInfoSoundCacheEntry key = new SoundInfoSoundCacheEntry(soundInfo, soundTag);
soundCache.put(key, data);
}
public void clearImageCache() {

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.exporters;
import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
@@ -156,7 +157,7 @@ public class SoundExporter {
}
} else {
List<ByteArrayRange> soundData = st.getRawSoundData();
List<ByteArrayRange> soundData = st.getRawSoundData();
fmt.createWav(null, soundData, fos);
}
}
}

View File

@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.types;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
@@ -32,4 +33,38 @@ public class SOUNDENVELOPE implements Serializable {
@SWFType(BasicType.UI16)
public int rightLevel;
@Override
public int hashCode() {
int hash = 7;
hash = 29 * hash + (int) (this.pos44 ^ (this.pos44 >>> 32));
hash = 29 * hash + this.leftLevel;
hash = 29 * hash + this.rightLevel;
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final SOUNDENVELOPE other = (SOUNDENVELOPE) obj;
if (this.pos44 != other.pos44) {
return false;
}
if (this.leftLevel != other.leftLevel) {
return false;
}
if (this.rightLevel != other.rightLevel) {
return false;
}
return true;
}
}

View File

@@ -12,13 +12,15 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.types;
import com.jpexs.decompiler.flash.types.annotations.Conditional;
import com.jpexs.decompiler.flash.types.annotations.Reserved;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import java.io.Serializable;
import java.util.Arrays;
/**
*
@@ -56,4 +58,70 @@ public class SOUNDINFO implements Serializable {
@Conditional("hasEnvelope")
public SOUNDENVELOPE[] envelopeRecords = new SOUNDENVELOPE[0];
@Override
public int hashCode() {
int hash = 3;
hash = 17 * hash + this.reserved;
hash = 17 * hash + (this.syncStop ? 1 : 0);
hash = 17 * hash + (this.syncNoMultiple ? 1 : 0);
hash = 17 * hash + (this.hasEnvelope ? 1 : 0);
hash = 17 * hash + (this.hasLoops ? 1 : 0);
hash = 17 * hash + (this.hasOutPoint ? 1 : 0);
hash = 17 * hash + (this.hasInPoint ? 1 : 0);
hash = 17 * hash + (int) (this.inPoint ^ (this.inPoint >>> 32));
hash = 17 * hash + (int) (this.outPoint ^ (this.outPoint >>> 32));
hash = 17 * hash + this.loopCount;
hash = 17 * hash + Arrays.deepHashCode(this.envelopeRecords);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final SOUNDINFO other = (SOUNDINFO) obj;
if (this.reserved != other.reserved) {
return false;
}
if (this.syncStop != other.syncStop) {
return false;
}
if (this.syncNoMultiple != other.syncNoMultiple) {
return false;
}
if (this.hasEnvelope != other.hasEnvelope) {
return false;
}
if (this.hasLoops != other.hasLoops) {
return false;
}
if (this.hasOutPoint != other.hasOutPoint) {
return false;
}
if (this.hasInPoint != other.hasInPoint) {
return false;
}
if (this.inPoint != other.inPoint) {
return false;
}
if (this.outPoint != other.outPoint) {
return false;
}
if (this.loopCount != other.loopCount) {
return false;
}
if (!Arrays.deepEquals(this.envelopeRecords, other.envelopeRecords)) {
return false;
}
return true;
}
}

View File

@@ -12,10 +12,12 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.types.sound;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.types.SOUNDINFO;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.utf8.Utf8Helper;
import java.io.ByteArrayOutputStream;
@@ -198,7 +200,7 @@ public class SoundFormat {
}
}
public boolean createWav(SOUNDINFO soundInfo, List<ByteArrayRange> dataRanges, OutputStream os) throws IOException {
ensureFormat();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SoundDecoder decoder = getDecoder();
@@ -208,8 +210,56 @@ public class SoundFormat {
decoder.decode(sis, baos);
}
/*
System.err.println("sampling rate:" + samplingRate);
System.err.println("len:" + baos.toByteArray().length);
*/
boolean convertedStereo = stereo;
ByteArrayOutputStream baosFiltered;
if (soundInfo == null) {
baosFiltered = baos;
} else {
int inPoint = (soundInfo.hasInPoint ? (int) Math.round(soundInfo.inPoint * samplingRate / 44100.0) : 0);
int outPoint = (soundInfo.hasOutPoint ? (int) Math.round(soundInfo.outPoint * samplingRate / 44100.0) : Integer.MAX_VALUE);
byte data[] = baos.toByteArray();
baosFiltered = new ByteArrayOutputStream();
int inPointBytes = inPoint * 2 /*16bit*/ * (stereo ? 2 : 1);
int outPointBytes = soundInfo.hasOutPoint ? outPoint * 2 /*16bit*/ * (stereo ? 2 : 1) : data.length;
for (int i = inPointBytes; i < outPointBytes; i += (stereo ? 4 : 2)) {
int left = ((data[i] & 0xff) + ((data[i + 1] & 0xff) << 8)) << 16 >> 16;
int right = left;
if (stereo) {
right = ((data[i + 2] & 0xff) + ((data[i + 3] & 0xff) << 8)) << 16 >> 16;
}
if (soundInfo.hasEnvelope) {
for (int e = 0; e < soundInfo.envelopeRecords.length - 1; e++) {
int envPosBytes = inPointBytes + (int) (soundInfo.envelopeRecords[e].pos44 * samplingRate / 44100.0 * 2 * (stereo ? 2 : 1));
int envNextPosBytes = inPointBytes + (int) (soundInfo.envelopeRecords[e + 1].pos44 * samplingRate / 44100.0 * 2 * (stereo ? 2 : 1));
if (i >= envPosBytes && i <= envNextPosBytes) {
double pos = (i - envPosBytes) / (double) (envNextPosBytes - envPosBytes);
int leftLevel = (int) (soundInfo.envelopeRecords[e].leftLevel + (soundInfo.envelopeRecords[e + 1].leftLevel - soundInfo.envelopeRecords[e].leftLevel) * pos);
int rightLevel = (int) (soundInfo.envelopeRecords[e].rightLevel + (soundInfo.envelopeRecords[e + 1].rightLevel - soundInfo.envelopeRecords[e].rightLevel) * pos);
double leftMultiplier = leftLevel / 32768.0;
double rightMultiplier = rightLevel / 32768.0;
left = (int) Math.round(left * leftMultiplier);
right = (int) Math.round(right * rightMultiplier);
break;
}
}
}
writeLE(baosFiltered, left, 2);
writeLE(baosFiltered, right, 2);
}
convertedStereo = true;
}
try {
try {
createWavFromPcmData(os, samplingRate, true, convertedStereo, baosFiltered.toByteArray());
return true;
} catch (IOException ex) {
return false;

View File

@@ -0,0 +1,49 @@
package com.jpexs.decompiler.flash.types.sound;
import com.jpexs.decompiler.flash.tags.base.SoundTag;
import com.jpexs.decompiler.flash.types.SOUNDINFO;
import java.util.Objects;
/**
*
* @author JPEXS
*/
public class SoundInfoSoundCacheEntry {
public SOUNDINFO soundInfo;
public SoundTag soundTag;
public SoundInfoSoundCacheEntry(SOUNDINFO soundInfo, SoundTag soundTag) {
this.soundInfo = soundInfo;
this.soundTag = soundTag;
}
@Override
public int hashCode() {
int hash = 7;
hash = 47 * hash + Objects.hashCode(this.soundInfo);
hash = 47 * hash + Objects.hashCode(this.soundTag);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final SoundInfoSoundCacheEntry other = (SoundInfoSoundCacheEntry) obj;
if (!Objects.equals(this.soundInfo, other.soundInfo)) {
return false;
}
if (!Objects.equals(this.soundTag, other.soundTag)) {
return false;
}
return true;
}
}

Binary file not shown.

View File

@@ -1,12 +1,13 @@
<DOMDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ns.adobe.com/xfl/2008/" width="500" currentTimeline="1" xflVersion="2.2" creatorInfo="Adobe Flash Professional CS6" platform="Windows" versionInfo="Saved by Adobe Flash Windows 12.0 build 481" majorVersion="12" buildNumber="481" viewAngle3D="50.6510299754819" nextSceneIdentifier="25" playOptionsPlayLoop="false" playOptionsPlayPages="false" playOptionsPlayFrameActions="false">
<fonts>
<DOMFontItem name="Font 1" itemID="604e2b4c-00000400" font="TimesNewRomanPSMT" size="0" id="1" sourceLastImported="1615735628" embedRanges="1|2"/>
<DOMFontItem name="Font 2" itemID="604e7a9e-00000444" font="TimesNewRomanPS-BoldMT" size="30" id="2" sourceLastImported="1615755934" embedRanges="1|2"/>
<DOMFontItem name="Font 1" itemID="604e2b4c-00000400" font="TimesNewRomanPSMT" size="0" id="1" sourceLastImported="1615735628" embedRanges="1|2"/>
</fonts>
<media>
<DOMBitmapItem name="bitmapfill.png" itemID="604dcb84-00000229" sourceLastImported="1615711005" externalFileSize="1931" useImportedJPEGData="false" compressionType="lossless" originalCompressionType="lossless" quality="50" href="bitmapfill.png" bitmapDataHRef="M 2 1615711026.dat" frameRight="640" frameBottom="1280"/>
<DOMBitmapItem name="pony.jpg" itemID="604de7c7-000002d8" sourceLastImported="1615718230" externalFileSize="222138" quality="50" href="pony.jpg" bitmapDataHRef="M 4 1615718240.dat" frameRight="16000" frameBottom="10680" isJPEG="true"/>
<DOMSoundItem name="POOL-Pool_Shot-709343898.wav" itemID="605a2676-00000203" sourceExternalFilepath="./LIBRARY/POOL-Pool_Shot-709343898.wav" sourceLastImported="1515341955" externalFileSize="207370" href="POOL-Pool_Shot-709343898.wav" soundDataHRef="M 5 1616520759.dat" format="44kHz 16bit Stereo" sampleCount="51311"/>
<DOMSoundItem name="Yung Raf - Nothing To Lose.mp3" itemID="605a5e7d-00000258" sourceExternalFilepath="./LIBRARY/Yung Raf - Nothing To Lose.mp3" sourceLastImported="1616534842" externalFileSize="2233572" href="Yung Raf - Nothing To Lose.mp3" soundDataHRef="M 6 1616534947.dat" format="44kHz 16bit Stereo" sampleCount="6156288" exportFormat="1" exportBits="7" dataLength="2233572" exportNative="true" cacheFormat="5kHz 8bit Stereo" cachedSampleCount="769536"/>
</media>
<symbols>
<Include href="BlueSquare.xml" itemIcon="1" loadImmediate="false" itemID="604e0a22-000002e1" lastModified="1615730090"/>
@@ -31,7 +32,7 @@
<Include href="Tween 2.xml" itemIcon="1" loadImmediate="false" itemID="604dcf92-00000243" lastModified="1615712146"/>
</symbols>
<timelines>
<DOMTimeline name="Scene 1" currentFrame="57">
<DOMTimeline name="Scene 1" currentFrame="59">
<layers>
<DOMLayer name="Scripts layer" color="#9933CC" autoNamed="false">
<frames>
@@ -45,7 +46,7 @@
</DOMLayer>
<DOMLayer name="Prev next buttons" color="#4FFF4F" locked="true" autoNamed="false">
<frames>
<DOMFrame index="0" duration="58" keyMode="9728">
<DOMFrame index="0" duration="60" keyMode="9728">
<elements>
<DOMSymbolInstance libraryItemName="btnNext" symbolType="button">
<matrix>
@@ -114,7 +115,7 @@
</DOMFrame>
</frames>
</DOMLayer>
<DOMLayer name="Mask layer" color="#9933CC" locked="true" autoNamed="false" layerType="mask">
<DOMLayer name="Mask layer" color="#9933CC" locked="true" current="true" isSelected="true" autoNamed="false" layerType="mask">
<frames>
<DOMFrame index="0" duration="51" keyMode="9728">
<elements/>
@@ -161,7 +162,7 @@
</DOMFrame>
</frames>
</DOMLayer>
<DOMLayer name="Graphics layer" color="#4FFF4F" current="true" isSelected="true" autoNamed="false">
<DOMLayer name="Graphics layer" color="#4FFF4F" autoNamed="false">
<frames>
<DOMFrame index="0" keyMode="9728">
<elements>
@@ -773,10 +774,10 @@
!3980 1990|2980 1990!2980 1990|2980 990!2980 990|3980 990!3980 990|3980 1990"/>
<Edge strokeStyle="5" edges="
!1960 990|1960 1990!1960 1990|960 1990!960 1990|960 990!960 990|1960 990"/>
<Edge strokeStyle="7" edges="
!1980 4990|980 4990!980 4990|980 3990!980 3990|1980 3990!1980 3990|1980 4990"/>
<Edge strokeStyle="6" edges="
!2980 3990|3980 3990!3980 3990|3980 4990!3980 4990|2980 4990!2980 4990|2980 3990"/>
<Edge strokeStyle="7" edges="
!1980 4990|980 4990!980 4990|980 3990!980 3990|1980 3990!1980 3990|1980 4990"/>
<Edge strokeStyle="8" edges="
!5980 3990|5980 4990!5980 4990|4980 4990!4980 4990|4980 3990!4980 3990|5980 3990"/>
<Edge cubics="!1960 990(;1960,990 1960,1990 1960,1990q1960 990 1960 1990);"/>
@@ -1375,18 +1376,18 @@
</StrokeStyle>
</strokes>
<edges>
<Edge strokeStyle="2" edges="
!3500 1000|3500 2000!3500 2000|2500 2000!2500 2000|2500 1000"/>
<Edge strokeStyle="5" edges="
!5000 1000|5000 2000!5000 2000|4000 2000!4000 2000|4000 1000"/>
<Edge strokeStyle="2" edges="
!3500 1000|3500 2000!3500 2000|2500 2000!2500 2000|2500 1000"/>
<Edge strokeStyle="1" edges="
!2000 1000|2000 2000!2000 2000|1000 2000!1000 2000|1000 1000"/>
<Edge strokeStyle="6" edges="
!4647 3660/4942 4670!4942 4670/5019 3660"/>
<Edge strokeStyle="3" edges="
!2553 3660/2848 4670!2848 4670/2925 3660"/>
<Edge strokeStyle="4" edges="
!1000 3660/1295 4670!1295 4670/1372 3660"/>
<Edge strokeStyle="3" edges="
!2553 3660/2848 4670!2848 4670/2925 3660"/>
<Edge strokeStyle="6" edges="
!4647 3660/4942 4670!4942 4670/5019 3660"/>
<Edge cubics="!5000 2000(;5000,2000 4000,2000 4000,2000q5000 2000 4000 2000);"/>
<Edge cubics="!4000 2000(4000,2000;4000,2000 4000,1000 4000,1000q4000 2000 4000 1000);"/>
<Edge cubics="!5000 1000(;5000,1000 5000,2000 5000,2000q5000 1000 5000 2000);"/>
@@ -2108,12 +2109,22 @@
</SoundEnvelope>
<elements/>
</DOMFrame>
<DOMFrame index="57" keyMode="9728" soundEffect="custom" soundName="POOL-Pool_Shot-709343898.wav" inPoint44="11100" outPoint44="51311" soundZoomLevel="2">
<DOMFrame index="57" keyMode="9728" soundName="Yung Raf - Nothing To Lose.mp3" inPoint44="268780" outPoint44="358136" soundZoomLevel="5">
<SoundEnvelope>
<SoundEnvelopePoint level0="32768" level1="32768"/>
</SoundEnvelope>
<elements/>
</DOMFrame>
<DOMFrame index="58" keyMode="9728" soundEffect="custom" soundName="Yung Raf - Nothing To Lose.mp3" inPoint44="274640" outPoint44="494975" soundZoomLevel="5">
<SoundEnvelope>
<SoundEnvelopePoint/>
<SoundEnvelopePoint mark44="12800" level0="16632" level1="17129"/>
<SoundEnvelopePoint mark44="13300" level0="32768" level1="32768"/>
<SoundEnvelopePoint mark44="37400" level0="32768" level1="32768"/>
<SoundEnvelopePoint mark44="221341" level0="32768" level1="32768"/>
</SoundEnvelope>
<elements/>
</DOMFrame>
<DOMFrame index="59" keyMode="9728" soundName="Yung Raf - Nothing To Lose.mp3">
<SoundEnvelope>
<SoundEnvelopePoint level0="32768" level1="32768"/>
</SoundEnvelope>
<elements/>
</DOMFrame>
@@ -3417,7 +3428,41 @@
</matrix>
<textRuns>
<DOMTextRun>
<characters>058 Sound envelope</characters>
<characters>058 Sound in/outpoint</characters>
<textAttrs>
<DOMTextAttrs aliasText="false" size="30" face="TimesNewRomanPSMT"/>
</textAttrs>
</DOMTextRun>
</textRuns>
</DOMStaticText>
</elements>
</DOMFrame>
<DOMFrame index="58" keyMode="9728">
<elements>
<DOMStaticText width="446" height="33.25" includeOutlines="true" isSelectable="false">
<matrix>
<Matrix tx="22" ty="342"/>
</matrix>
<textRuns>
<DOMTextRun>
<characters>059 Sound envelope</characters>
<textAttrs>
<DOMTextAttrs aliasText="false" size="30" face="TimesNewRomanPSMT"/>
</textAttrs>
</DOMTextRun>
</textRuns>
</DOMStaticText>
</elements>
</DOMFrame>
<DOMFrame index="59" keyMode="9728">
<elements>
<DOMStaticText width="446" height="33.25" includeOutlines="true" isSelectable="false">
<matrix>
<Matrix tx="22" ty="342"/>
</matrix>
<textRuns>
<DOMTextRun>
<characters>060 Full song</characters>
<textAttrs>
<DOMTextAttrs aliasText="false" size="30" face="TimesNewRomanPSMT"/>
</textAttrs>
@@ -3433,6 +3478,15 @@
</timelines>
<PrinterSettings/>
<publishHistory>
<PublishItem publishSize="2335518" publishTime="1616535468"/>
<PublishItem publishSize="2335516" publishTime="1616535450"/>
<PublishItem publishSize="2335518" publishTime="1616535289"/>
<PublishItem publishSize="2335451" publishTime="1616535167"/>
<PublishItem publishSize="519155" publishTime="1616534572"/>
<PublishItem publishSize="519132" publishTime="1616532644"/>
<PublishItem publishSize="519144" publishTime="1616532498"/>
<PublishItem publishSize="519040" publishTime="1616531882"/>
<PublishItem publishSize="519034" publishTime="1616531715"/>
<PublishItem publishSize="108381" publishTime="1615971629"/>
<PublishItem publishSize="1483" publishTime="1615971614"/>
<PublishItem publishSize="1483" publishTime="1615971614"/>
@@ -3444,14 +3498,5 @@
<PublishItem publishSize="108339" publishTime="1615967290"/>
<PublishItem publishSize="108324" publishTime="1615966926"/>
<PublishItem publishSize="108418" publishTime="1615756125"/>
<PublishItem publishSize="108418" publishTime="1615756115"/>
<PublishItem publishSize="100326" publishTime="1615755435"/>
<PublishItem publishSize="100331" publishTime="1615755207"/>
<PublishItem publishSize="100395" publishTime="1615755150"/>
<PublishItem publishSize="100329" publishTime="1615755064"/>
<PublishItem publishSize="100331" publishTime="1615755045"/>
<PublishItem publishSize="100331" publishTime="1615755001"/>
<PublishItem publishSize="100352" publishTime="1615753742"/>
<PublishItem publishSize="100333" publishTime="1615752295"/>
</publishHistory>
</DOMDocument>

View File

@@ -5,8 +5,8 @@
xmlns:xmp="http://ns.adobe.com/xap/1.0/">
<xmp:CreatorTool>Adobe Flash Professional CS6 - build 481</xmp:CreatorTool>
<xmp:CreateDate>2021-03-14T08:29:20+01:00</xmp:CreateDate>
<xmp:MetadataDate>2021-03-23T18:33:42+01:00</xmp:MetadataDate>
<xmp:ModifyDate>2021-03-23T18:33:42+01:00</xmp:ModifyDate>
<xmp:MetadataDate>2021-03-23T21:35:13+01:00</xmp:MetadataDate>
<xmp:ModifyDate>2021-03-23T21:35:13+01:00</xmp:ModifyDate>
</rdf:Description>
<rdf:Description rdf:about=""
xmlns:dc="http://purl.org/dc/elements/1.1/">
@@ -15,7 +15,7 @@
<rdf:Description rdf:about=""
xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#">
<xmpMM:InstanceID>xmp.iid:875CB1E9FD8BEB11AEBE9CDB97D5B601</xmpMM:InstanceID>
<xmpMM:InstanceID>xmp.iid:8C5CB1E9FD8BEB11AEBE9CDB97D5B601</xmpMM:InstanceID>
<xmpMM:DocumentID>xmp.did:D6D3FE199784EB1187FEAE6972EC5115</xmpMM:DocumentID>
<xmpMM:OriginalDocumentID>xmp.did:D6D3FE199784EB1187FEAE6972EC5115</xmpMM:OriginalDocumentID>
<xmpMM:History>
@@ -80,6 +80,12 @@
<stEvt:when>2021-03-14T08:29:20+01:00</stEvt:when>
<stEvt:softwareAgent>Adobe Flash Professional CS6 - build 481</stEvt:softwareAgent>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<stEvt:action>created</stEvt:action>
<stEvt:instanceID>xmp.iid:8C5CB1E9FD8BEB11AEBE9CDB97D5B601</stEvt:instanceID>
<stEvt:when>2021-03-14T08:29:20+01:00</stEvt:when>
<stEvt:softwareAgent>Adobe Flash Professional CS6 - build 481</stEvt:softwareAgent>
</rdf:li>
</rdf:Seq>
</xmpMM:History>
</rdf:Description>

Binary file not shown.

View File

@@ -2039,7 +2039,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
loopCount = Math.max(1, soundInfo.loopCount);
}
sp = new SoundTagPlayer(st, loopCount, false);
sp = new SoundTagPlayer(soundInfo, st, loopCount, false);
sp.addEventListener(new MediaDisplayListener() {
@Override
public void mediaDisplayStateChanged(MediaDisplay source) {

View File

@@ -3606,7 +3606,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
previewPanel.showImagePanel(new SerializableImage(View.loadImage("sound32")));
previewPanel.setImageReplaceButtonVisible(((Tag) treeItem).isReadOnly() && (treeItem instanceof DefineSoundTag), false);
try {
SoundTagPlayer soundThread = new SoundTagPlayer((SoundTag) treeItem, Configuration.loopMedia.get() ? Integer.MAX_VALUE : 1, true);
SoundTagPlayer soundThread = new SoundTagPlayer(null, (SoundTag) treeItem, Configuration.loopMedia.get() ? Integer.MAX_VALUE : 1, true);
previewPanel.setMedia(soundThread);
} catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) {
logger.log(Level.SEVERE, null, ex);

View File

@@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.gui.player.MediaDisplayListener;
import com.jpexs.decompiler.flash.gui.player.Zoom;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.SoundTag;
import com.jpexs.decompiler.flash.types.SOUNDINFO;
import com.jpexs.helpers.ByteArrayRange;
import java.awt.Color;
import java.awt.image.BufferedImage;
@@ -88,7 +89,7 @@ public class SoundTagPlayer implements MediaDisplay {
private static final int FRAME_DIVISOR = 8000;
public SoundTagPlayer(final SoundTag tag, int loops, boolean async) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
public SoundTagPlayer(final SOUNDINFO soundInfo, final SoundTag tag, int loops, boolean async) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
this.tag = tag;
this.loopCount = loops;
clip = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
@@ -135,13 +136,13 @@ public class SoundTagPlayer implements MediaDisplay {
if (!async) {
paused = true;
openSound(tag);
openSound(soundInfo, tag);
} else {
new Thread() {
@Override
public void run() {
try {
openSound(tag);
openSound(soundInfo, tag);
} catch (IOException | LineUnavailableException | UnsupportedAudioFileException ex) {
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
}
@@ -155,15 +156,15 @@ public class SoundTagPlayer implements MediaDisplay {
}
}
private void openSound(SoundTag tag) throws IOException, LineUnavailableException, UnsupportedAudioFileException {
private void openSound(SOUNDINFO soundInfo, SoundTag tag) throws IOException, LineUnavailableException, UnsupportedAudioFileException {
SWF swf = ((Tag) tag).getSwf();
byte[] wavData = swf.getFromCache(tag);
byte[] wavData = swf.getFromCache(soundInfo, tag);
if (wavData == null) {
List<ByteArrayRange> soundData = tag.getRawSoundData();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
tag.getSoundFormat().createWav(soundData, baos);
tag.getSoundFormat().createWav(soundInfo, soundData, baos);
wavData = baos.toByteArray();
swf.putToCache(tag, wavData);
swf.putToCache(soundInfo, tag, wavData);
}
synchronized (playLock) {