#752 Sound is not stopped when you change the selectin in he tag tree from SWF to e.g any shape fixed

This commit is contained in:
2014-12-15 22:33:13 +01:00
parent 9ea4f6c6b7
commit 5f4214dffd
5 changed files with 228 additions and 318 deletions
@@ -61,6 +61,8 @@ public class FolderPreviewPanel extends JPanel {
private List<TreeItem> items;
private int selectedIndex = -1;
private boolean repaintQueued;
private int lastWidth;
private int lastHeight;
public Map<Integer, TreeItem> selectedItems = new HashMap<>();
@@ -217,8 +219,9 @@ public class FolderPreviewPanel extends JPanel {
}
}
Dimension size = getSize();
if (size.width != width || size.height != height) {
if (lastWidth != width || lastHeight != height) {
lastWidth = width;
lastHeight = height;
setSize(new Dimension(width, height));
}
}
+130 -105
View File
@@ -214,71 +214,66 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
if (e == null) {
return;
}
boolean draw2 = false;
synchronized (ImagePanel.class) {
lastMouseEvent = e;
boolean handCursor = false;
DepthState newStateUnderCursor = null;
if (timelined != null) {
Timeline tim = ((Timelined) timelined).getTimeline();
BoundedTag bounded = (BoundedTag) timelined;
RECT rect = bounded.getRect(new HashSet<BoundedTag>());
int width = rect.getWidth();
double scale = 1.0;
/*if (width > swf.displayRect.getWidth()) {
scale = (double) swf.displayRect.getWidth() / (double) width;
}*/
Matrix m = new Matrix();
m.translate(-rect.Xmin, -rect.Ymin);
m.scale(scale);
Point p = e.getPoint();
p = iconPanel.toImagePoint(p);
List<DepthState> objs = new ArrayList<>();
String ret = "";
if (p != null) {
int x = p.x;
int y = p.y;
objs = iconPanel.getObjectsUnderPoint(p);
lastMouseEvent = e;
boolean handCursor = false;
DepthState newStateUnderCursor = null;
if (timelined != null) {
ret += " [" + x + "," + y + "] : ";
}
Timeline tim = ((Timelined) timelined).getTimeline();
BoundedTag bounded = (BoundedTag) timelined;
RECT rect = bounded.getRect(new HashSet<BoundedTag>());
int width = rect.getWidth();
double scale = 1.0;
/*if (width > swf.displayRect.getWidth()) {
scale = (double) swf.displayRect.getWidth() / (double) width;
}*/
Matrix m = new Matrix();
m.translate(-rect.Xmin, -rect.Ymin);
m.scale(scale);
Point p = e.getPoint();
p = iconPanel.toImagePoint(p);
List<DepthState> objs = new ArrayList<>();
String ret = "";
if (p != null) {
int x = p.x;
int y = p.y;
objs = iconPanel.getObjectsUnderPoint(p);
boolean first = true;
for (int i = 0; i < objs.size(); i++) {
DepthState ds = objs.get(i);
if (!first) {
ret += ", ";
}
first = false;
CharacterTag c = tim.swf.characters.get(ds.characterId);
if (c instanceof ButtonTag) {
newStateUnderCursor = ds;
handCursor = true;
}
ret += c.toString();
if (timelined instanceof ButtonTag) {
handCursor = true;
}
}
if (first) {
ret += " - ";
}
debugLabel.setText(ret);
ret += " [" + x + "," + y + "] : ";
}
if (handCursor) {
iconPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
} else {
iconPanel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
boolean first = true;
for (int i = 0; i < objs.size(); i++) {
DepthState ds = objs.get(i);
if (!first) {
ret += ", ";
}
if (newStateUnderCursor != stateUnderCursor) {
stateUnderCursor = newStateUnderCursor;
draw2 = true;
first = false;
CharacterTag c = tim.swf.characters.get(ds.characterId);
if (c instanceof ButtonTag) {
newStateUnderCursor = ds;
handCursor = true;
}
ret += c.toString();
if (timelined instanceof ButtonTag) {
handCursor = true;
}
}
}
if (draw2) {
drawFrame();
if (first) {
ret += " - ";
}
debugLabel.setText(ret);
if (handCursor) {
iconPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
} else {
iconPanel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
if (newStateUnderCursor != stateUnderCursor) {
stateUnderCursor = newStateUnderCursor;
drawFrame();
}
}
}
@@ -316,27 +311,33 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
@Override
public void mouseEntered(MouseEvent e) {
drawFrame();
synchronized (ImagePanel.class) {
drawFrame();
}
}
@Override
public void mouseExited(MouseEvent e) {
stateUnderCursor = null;
lastMouseEvent = null;
drawFrame();
synchronized (ImagePanel.class) {
drawFrame();
}
hideMouseSelection();
}
@Override
public void mousePressed(MouseEvent e) {
mouseButton = e.getButton();
updatePos(e, true);
drawFrame();
if (stateUnderCursor != null) {
ButtonTag b = (ButtonTag) swf.characters.get(stateUnderCursor.characterId);
DefineButtonSoundTag sounds = b.getSounds();
if (sounds != null && sounds.buttonSoundChar2 != 0) { //OverUpToOverDown
playSound((SoundTag) swf.characters.get(sounds.buttonSoundChar2));
synchronized (ImagePanel.class) {
updatePos(e, true);
drawFrame();
if (stateUnderCursor != null) {
ButtonTag b = (ButtonTag) swf.characters.get(stateUnderCursor.characterId);
DefineButtonSoundTag sounds = b.getSounds();
if (sounds != null && sounds.buttonSoundChar2 != 0) { //OverUpToOverDown
playSound((SoundTag) swf.characters.get(sounds.buttonSoundChar2));
}
}
}
}
@@ -344,13 +345,15 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
@Override
public void mouseReleased(MouseEvent e) {
mouseButton = 0;
updatePos(e, true);
drawFrame();
if (stateUnderCursor != null) {
ButtonTag b = (ButtonTag) swf.characters.get(stateUnderCursor.characterId);
DefineButtonSoundTag sounds = b.getSounds();
if (sounds != null && sounds.buttonSoundChar3 != 0) { //OverDownToOverUp
playSound((SoundTag) swf.characters.get(sounds.buttonSoundChar3));
synchronized (ImagePanel.class) {
updatePos(e, true);
drawFrame();
if (stateUnderCursor != null) {
ButtonTag b = (ButtonTag) swf.characters.get(stateUnderCursor.characterId);
DefineButtonSoundTag sounds = b.getSounds();
if (sounds != null && sounds.buttonSoundChar3 != 0) { //OverDownToOverUp
playSound((SoundTag) swf.characters.get(sounds.buttonSoundChar3));
}
}
}
}
@@ -360,24 +363,26 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
@Override
public void mouseMoved(MouseEvent e) {
DepthState lastUnderCur = stateUnderCursor;
updatePos(e, true);
if (stateUnderCursor != null) {
if (lastUnderCur == null || lastUnderCur.instanceId != stateUnderCursor.instanceId) {
//New mouse entered
ButtonTag b = (ButtonTag) swf.characters.get(stateUnderCursor.characterId);
DefineButtonSoundTag sounds = b.getSounds();
if (sounds != null && sounds.buttonSoundChar1 != 0) { //IddleToOverUp
playSound((SoundTag) swf.characters.get(sounds.buttonSoundChar1));
synchronized (ImagePanel.class) {
updatePos(e, true);
if (stateUnderCursor != null) {
if (lastUnderCur == null || lastUnderCur.instanceId != stateUnderCursor.instanceId) {
//New mouse entered
ButtonTag b = (ButtonTag) swf.characters.get(stateUnderCursor.characterId);
DefineButtonSoundTag sounds = b.getSounds();
if (sounds != null && sounds.buttonSoundChar1 != 0) { //IddleToOverUp
playSound((SoundTag) swf.characters.get(sounds.buttonSoundChar1));
}
}
}
}
if (lastUnderCur != null) {
if (stateUnderCursor == null || stateUnderCursor.instanceId != lastUnderCur.instanceId) {
//Old mouse leave
ButtonTag b = (ButtonTag) swf.characters.get(lastUnderCur.characterId);
DefineButtonSoundTag sounds = b.getSounds();
if (sounds != null && sounds.buttonSoundChar0 != 0) { //OverUpToIddle
playSound((SoundTag) swf.characters.get(sounds.buttonSoundChar0));
if (lastUnderCur != null) {
if (stateUnderCursor == null || stateUnderCursor.instanceId != lastUnderCur.instanceId) {
//Old mouse leave
ButtonTag b = (ButtonTag) swf.characters.get(lastUnderCur.characterId);
DefineButtonSoundTag sounds = b.getSounds();
if (sounds != null && sounds.buttonSoundChar0 != 0) { //OverUpToIddle
playSound((SoundTag) swf.characters.get(sounds.buttonSoundChar0));
}
}
}
}
@@ -385,7 +390,9 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
@Override
public void mouseDragged(MouseEvent e) {
updatePos(e, true);
synchronized (ImagePanel.class) {
updatePos(e, true);
}
}
});
@@ -394,7 +401,9 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
@Override
public void zoom(double zoom) {
this.zoom = zoom;
drawFrame();
synchronized (ImagePanel.class) {
drawFrame();
}
}
@Override
@@ -510,7 +519,10 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
timer.cancel();
timer = null;
}
stopAllSounds();
synchronized (ImagePanel.class) {
stopAllSounds();
}
}
private void stopAllSounds() {
@@ -601,7 +613,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
return img;
}
private synchronized void drawFrame() {
private void drawFrame() {
if (timelined == null) {
return;
}
@@ -627,6 +639,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
}
}
}
for (int sndId : sounds) {
CharacterTag c = swf.characters.get(sndId);
if (c instanceof SoundTag) {
@@ -681,6 +694,10 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
timer.cancel();
timer = null;
}
synchronized (ImagePanel.class) {
stopAllSounds();
}
}
@Override
@@ -694,26 +711,32 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
@Override
public void run() {
Timeline timeline = timelined.getTimeline();
if (timeline.getFrameCount() <= 1 && timeline.isSingleFrame()) {
if (first) {
drawFrame();
first = false;
synchronized (ImagePanel.class) {
if (timer == null) {
return;
}
Timeline timeline = timelined.getTimeline();
if (timeline.getFrameCount() <= 1 && timeline.isSingleFrame()) {
if (first) {
drawFrame();
first = false;
}
} else {
nextFrame();
}
} else {
nextFrame();
}
}
}, 0, frameRate == 0 ? Integer.MAX_VALUE : frameRate);
} else {
drawFrame();
}
}
@Override
public void rewind() {
frame = 0;
drawFrame();
synchronized (ImagePanel.class) {
drawFrame();
}
}
@Override
@@ -740,7 +763,9 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
return;
}
this.frame = frame;
drawFrame();
synchronized (ImagePanel.class) {
drawFrame();
}
}
@Override
@@ -21,7 +21,6 @@ import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.gui.player.MediaDisplay;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.SoundTag;
import com.jpexs.helpers.SoundPlayer;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
@@ -29,8 +28,11 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
@@ -40,10 +42,11 @@ import javax.sound.sampled.UnsupportedAudioFileException;
*/
public class SoundTagPlayer implements MediaDisplay {
private final SoundPlayer player;
private final Clip clip;
private Thread thr;
private int actualPos = 0;
private int loopCount;
private boolean paused = true;
private final Object playLock = new Object();
private final SoundTag tag;
private final List<PlayerListener> listeners = new ArrayList<>();
@@ -63,13 +66,9 @@ public class SoundTagPlayer implements MediaDisplay {
private static final int FRAME_DIVISOR = 8000;
private int loops;
private boolean paused = true;
private final Object playLock = new Object();
public SoundTagPlayer(SoundTag tag, int loops) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
this.tag = tag;
this.loops = loops;
this.loopCount = loops;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
List<byte[]> soundData = tag.getRawSoundData();
SWF swf = ((Tag) tag).getSwf();
@@ -78,107 +77,70 @@ public class SoundTagPlayer implements MediaDisplay {
siss.add(new SWFInputStream(swf, data));
}
tag.getSoundFormat().createWav(siss, baos);
player = new SoundPlayer(new ByteArrayInputStream(baos.toByteArray()));
}
clip = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
clip.open(AudioSystem.getAudioInputStream(new ByteArrayInputStream(baos.toByteArray())));
@Override
public synchronized int getCurrentFrame() {
synchronized (playLock) {
if (isPlaying()) {
actualPos = (int) (player.getSamplePosition() / FRAME_DIVISOR);
}
return actualPos;
}
}
@Override
public synchronized int getTotalFrames() {
int ret = (int) (player.samplesCount() / FRAME_DIVISOR);
return ret;
}
@Override
public synchronized void pause() {
if (!isPlaying()) {
paused = true;
return;
}
synchronized (playLock) {
actualPos = (int) (player.getSamplePosition() / FRAME_DIVISOR);
}
waitStop();
}
private void waitStop() {
synchronized (playLock) {
if (!paused) {
paused = true;
player.stop();
try {
playLock.wait();
} catch (InterruptedException ex) {
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public void play(boolean async) {
waitStop();
Runnable r = new Runnable() {
clip.addLineListener(new LineListener() {
@Override
public void run() {
boolean playAgain = true;
while (playAgain) {
int startPos;
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP) {
//clip.close();
synchronized (playLock) {
startPos = actualPos * FRAME_DIVISOR;
}
player.setPosition(startPos);
player.play();
synchronized (playLock) {
playAgain = !paused && loops > 0;
if (!paused) {
if (loops == 0) {
paused = true;
} else if (loops != Integer.MAX_VALUE) {
loops--;
decreaseLoopCount();
if (loopCount > 0) {
clip.setFramePosition(0);
clip.start();
} else {
fireFinished();
}
}
if (playAgain) {
actualPos = 0;
}
}
}
fireFinished();
synchronized (playLock) {
playLock.notifyAll();
}
}
};
synchronized (playLock) {
paused = false;
}
if (async) {
thr = new Thread(r);
thr.start();
} else {
r.run();
}
});
}
@Override
public synchronized void play() {
play(true);
public int getCurrentFrame() {
synchronized (playLock) {
return (int) (clip.getMicrosecondPosition() / FRAME_DIVISOR);
}
}
@Override
public int getTotalFrames() {
synchronized (playLock) {
return (int) (clip.getMicrosecondLength() / FRAME_DIVISOR);
}
}
@Override
public void pause() {
synchronized (playLock) {
paused = true;
clip.stop();
}
}
@Override
public void play() {
synchronized (playLock) {
paused = false;
if (!clip.isActive()) {
if (clip.getMicrosecondLength() == clip.getMicrosecondPosition()) {
decreaseLoopCount();
clip.setFramePosition(0);
}
clip.start();
}
}
}
@Override
@@ -188,7 +150,7 @@ public class SoundTagPlayer implements MediaDisplay {
@Override
public boolean isPlaying() {
return player.isPlaying();
return clip.isActive();
}
@Override
@@ -217,10 +179,17 @@ public class SoundTagPlayer implements MediaDisplay {
}
@Override
public synchronized void gotoFrame(int frame) {
pause();
public void gotoFrame(int frame) {
synchronized (playLock) {
actualPos = frame;
boolean active = clip.isActive();
if (active) {
clip.stop();
}
clip.setMicrosecondPosition(frame * FRAME_DIVISOR);
if (active) {
clip.start();
}
}
}
@@ -231,10 +200,7 @@ public class SoundTagPlayer implements MediaDisplay {
@Override
public int getFrameRate() {
if (player == null) {
return 1;
}
return (int) (player.getFrameRate() / FRAME_DIVISOR);
return (int) (1000000L / FRAME_DIVISOR);
}
@Override
@@ -247,4 +213,21 @@ public class SoundTagPlayer implements MediaDisplay {
return null;
}
@Override
protected void finalize() throws Throwable {
try {
if (clip != null) {
clip.close();
}
} finally {
super.finalize();
}
}
private void decreaseLoopCount() {
// this method should be called from synchronized (playLock) block
if (loopCount > 0 && loopCount != Integer.MAX_VALUE) {
loopCount--;
}
}
}
@@ -334,6 +334,9 @@ public class PlayerControls extends JPanel implements ActionListener {
frameControls.setVisible(display.screenAvailable());
int totalFrames = display.getTotalFrames();
int currentFrame = display.getCurrentFrame();
if (currentFrame >= totalFrames) {
currentFrame = totalFrames - 1;
}
int frameRate = display.getFrameRate();
if (totalFrames == 0) {
progress.setIndeterminate(true);