internal sound playing refactoring

diplay sound icon
ffdec:format code, organize imports
This commit is contained in:
Jindra Petk
2014-03-14 20:30:45 +01:00
parent c528228104
commit c0a8e3f6be
13 changed files with 208 additions and 396 deletions

View File

@@ -117,7 +117,6 @@ import com.jpexs.decompiler.flash.types.MATRIX;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.filters.BlendComposite;
import com.jpexs.decompiler.flash.types.filters.FILTER;
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
import com.jpexs.decompiler.flash.xfl.FLAVersion;
import com.jpexs.decompiler.flash.xfl.XFLConverter;
@@ -133,9 +132,7 @@ import com.jpexs.helpers.ProgressListener;
import com.jpexs.helpers.SerializableImage;
import com.jpexs.helpers.utf8.Utf8Helper;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
@@ -2352,12 +2349,12 @@ public final class SWF implements TreeItem, Timelined {
drawable.toImage(dframe, layer.ratio, stateUnderCursor, mouseButton, img, m, clrTrans);
//if(stateUnderCursor == layer){
/* if(true){
Graphics2D gg = (Graphics2D)img.getGraphics();
gg.setStroke(new BasicStroke(3));
gg.setPaint(Color.red);
gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
gg.draw(SHAPERECORD.twipToPixelShape(drawable.getOutline(frame, layer.ratio, stateUnderCursor, mouseButton, m)));
}*/
Graphics2D gg = (Graphics2D)img.getGraphics();
gg.setStroke(new BasicStroke(3));
gg.setPaint(Color.red);
gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
gg.draw(SHAPERECORD.twipToPixelShape(drawable.getOutline(frame, layer.ratio, stateUnderCursor, mouseButton, m)));
}*/
} else if (drawable instanceof FontTag) {
// only DefineFont tags
FontTag fontTag = (FontTag) drawable;
@@ -2470,9 +2467,7 @@ public final class SWF implements TreeItem, Timelined {
g.setComposite(AlphaComposite.Dst);
}
}
g.setTransform(AffineTransform.getScaleInstance(1, 1));
}

View File

@@ -102,12 +102,11 @@ public class Matrix {
public Point transform(Point point) {
return transform(point.x, point.y);
}
public java.awt.Point transform(java.awt.Point point) {
Point p= transform(point.x, point.y);
return new java.awt.Point((int)p.x,(int)p.y);
Point p = transform(point.x, point.y);
return new java.awt.Point((int) p.x, (int) p.y);
}
public ExportRectangle transform(ExportRectangle rect) {
double minX = Double.MAX_VALUE;

View File

@@ -40,8 +40,6 @@ import java.awt.Cursor;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
@@ -63,8 +61,8 @@ import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
@@ -95,9 +93,8 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
private Rectangle rect = null;
private List<DepthState> dss;
private List<Shape> outlines;
public void setImg(SerializableImage img,List<DepthState> dss, List<Shape> outlines) {
public void setImg(SerializableImage img, List<DepthState> dss, List<Shape> outlines) {
this.img = img;
this.dss = dss;
this.outlines = outlines;
@@ -105,22 +102,22 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
repaint();
}
public List<DepthState> getObjectsUnderPoint(Point p){
List<DepthState> ret=new ArrayList<>();
for(int i=0;i<outlines.size();i++){
if(outlines.get(i).contains(p)){
public List<DepthState> getObjectsUnderPoint(Point p) {
List<DepthState> ret = new ArrayList<>();
for (int i = 0; i < outlines.size(); i++) {
if (outlines.get(i).contains(p)) {
ret.add(dss.get(i));
}
}
return ret;
}
public Rectangle getRect() {
return rect;
}
public Point toImagePoint(Point p){
return new Point((p.x-rect.x)*img.getWidth()/rect.width,(p.y-rect.y)*img.getHeight()/rect.height);
public Point toImagePoint(Point p) {
return new Point((p.x - rect.x) * img.getWidth() / rect.width, (p.y - rect.y) * img.getHeight() / rect.height);
}
private void calcRect() {
@@ -162,7 +159,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
if (img != null) {
calcRect();
g2d.setComposite(AlphaComposite.SrcOver);
g2d.drawImage(img.getBufferedImage(), rect.x, rect.y, rect.x+rect.width, rect.y+rect.height, 0, 0, img.getWidth(), img.getHeight(), null);
g2d.drawImage(img.getBufferedImage(), rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, 0, 0, img.getWidth(), img.getHeight(), null);
}
}
@@ -210,24 +207,24 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
int width = rect.getWidth();
double scale = 1.0;
/*if (width > swf.displayRect.getWidth()) {
scale = (double) swf.displayRect.getWidth() / (double) width;
}*/
scale = (double) swf.displayRect.getWidth() / (double) width;
}*/
Matrix m = new Matrix();
m.translate(-rect.Xmin, -rect.Ymin);
m.scale(scale);
Point p=e.getPoint();
Point p = e.getPoint();
p = iconPanel.toImagePoint(p);
int x = p.x;
int x = p.x;
int y = p.y;
List<DepthState> objs = new ArrayList<>();
objs=iconPanel.getObjectsUnderPoint(p);
objs = iconPanel.getObjectsUnderPoint(p);
String ret = "";
ret += " [" + x + "," + y + "] : ";
boolean first = true;
for (int i=0;i<objs.size();i++) {
DepthState ds=objs.get(i);
for (int i = 0; i < objs.size(); i++) {
DepthState ds = objs.get(i);
if (!first) {
ret += ", ";
}
@@ -349,7 +346,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
timelined = null;
loaded = true;
try {
iconPanel.setImg(new SerializableImage(ImageIO.read(new ByteArrayInputStream(data))),new ArrayList<DepthState>(),new ArrayList<Shape>());
iconPanel.setImg(new SerializableImage(ImageIO.read(new ByteArrayInputStream(data))), new ArrayList<DepthState>(), new ArrayList<Shape>());
} catch (IOException ex) {
Logger.getLogger(ImagePanel.class.getName()).log(Level.SEVERE, null, ex);
}
@@ -372,7 +369,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
loaded = true;
if (drawable.getTimeline().frames.isEmpty()) {
iconPanel.setImg(null, new ArrayList<DepthState>(),new ArrayList<Shape>());
iconPanel.setImg(null, new ArrayList<DepthState>(), new ArrayList<Shape>());
return;
}
frame = 0;
@@ -387,7 +384,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
timelined = null;
loaded = true;
stillFrame = true;
iconPanel.setImg(image,new ArrayList<DepthState>(),new ArrayList<Shape>());
iconPanel.setImg(image, new ArrayList<DepthState>(), new ArrayList<Shape>());
}
@Override
@@ -449,50 +446,50 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
int height = rect.getHeight();
double scale = 1.0;
/*if (width > swf.displayRect.getWidth() || height > swf.displayRect.getHeight()) {
//scale = (double) swf.displayRect.getWidth() / (double) width;
//width = swf.displayRect.getWidth();
//scale = (double) swf.displayRect.getWidth() / (double) width;
//width = swf.displayRect.getWidth();
int w1 = width;
int h1 = height;
int w2 = swf.displayRect.getWidth();
int h2 = swf.displayRect.getHeight();
int w1 = width;
int h1 = height;
int w2 = swf.displayRect.getWidth();
int h2 = swf.displayRect.getHeight();
int w;
int h = h1 * w2 / w1;
if (h > h2) {
w = w1 * h2 / h1;
h = h2;
} else {
w = w2;
}
scale = (double) w / (double) width;
int w;
int h = h1 * w2 / w1;
if (h > h2) {
w = w1 * h2 / h1;
h = h2;
} else {
w = w2;
}
scale = (double) w / (double) width;
width = w;
height = h;
}*/
width = w;
height = h;
}*/
SerializableImage image = new SerializableImage((int) (width / SWF.unitDivisor) + 1,
(int) (height / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB);
image.fillTransparent();
Matrix m = new Matrix();
m.translate(-rect.Xmin, -rect.Ymin);
/*m.translate(-rect.getWidth(), -rect.getHeight());
m.scale(scale);
m.translate(rect.getWidth()*scale, rect.getHeight()*scale);*/
m.scale(scale);
m.translate(rect.getWidth()*scale, rect.getHeight()*scale);*/
drawable.getTimeline().toImage(frame, frame, stateUnderCursor, mouseButton, image, m, new ColorTransform());
Graphics2D gg = (Graphics2D)image.getGraphics();
gg.setStroke(new BasicStroke(3));
gg.setPaint(Color.green);
gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
List<DepthState> dss=new ArrayList<>();
List<Shape> os=new ArrayList<>();
/*drawable.getTimeline().getObjectsOutlines(frame, frame, stateUnderCursor, mouseButton, m, dss, os);
Graphics2D gg = (Graphics2D) image.getGraphics();
gg.setStroke(new BasicStroke(3));
gg.setPaint(Color.green);
gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
List<DepthState> dss = new ArrayList<>();
List<Shape> os = new ArrayList<>();
/*drawable.getTimeline().getObjectsOutlines(frame, frame, stateUnderCursor, mouseButton, m, dss, os);
//gg.setTransform(AffineTransform.getTranslateInstance(0, 0));
for(Shape s:os){
gg.draw(SHAPERECORD.twipToPixelShape(s));
gg.draw(SHAPERECORD.twipToPixelShape(s));
}*/
img = image;
} else if (drawable instanceof FontTag) {
// only DefineFont tags
@@ -517,34 +514,40 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis
CharacterTag c = swf.characters.get(sndId);
if (c instanceof SoundTag) {
SoundTag st = (SoundTag) c;
final SoundTagPlayer sp = new SoundTagPlayer(st, 1);
synchronized (ImagePanel.class) {
soundPlayers.add(sp);
}
sp.addListener(new PlayerListener() {
final SoundTagPlayer sp;
try {
sp = new SoundTagPlayer(st, 1);
@Override
public void playingFinished() {
synchronized (ImagePanel.class) {
soundPlayers.remove(sp);
}
synchronized (ImagePanel.class) {
soundPlayers.add(sp);
}
});
sp.play();
sp.addListener(new PlayerListener() {
@Override
public void playingFinished() {
synchronized (ImagePanel.class) {
soundPlayers.remove(sp);
}
}
});
sp.play();
} catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) {
Logger.getLogger(ImagePanel.class.getName()).log(Level.SEVERE, "Error during playing sound", ex);
}
}
}
Matrix m = new Matrix();
RECT rect= timelined.getTimeline().displayRect;
m.translate(-rect.Xmin, -rect.Ymin);
m.scale(1);
List<DepthState> objs = new ArrayList<>();
List<Shape> outlines=new ArrayList<>();
timelined.getTimeline().getObjectsOutlines(frame, frame, stateUnderCursor, mouseButton, m, objs, outlines);
for(int i=0;i<outlines.size();i++){
outlines.set(i, SHAPERECORD.twipToPixelShape(outlines.get(i)));
}
iconPanel.setImg(new SerializableImage(img),objs,outlines);
RECT rect = timelined.getTimeline().displayRect;
m.translate(-rect.Xmin, -rect.Ymin);
m.scale(1);
List<DepthState> objs = new ArrayList<>();
List<Shape> outlines = new ArrayList<>();
timelined.getTimeline().getObjectsOutlines(frame, frame, stateUnderCursor, mouseButton, m, objs, outlines);
for (int i = 0; i < outlines.size(); i++) {
outlines.set(i, SHAPERECORD.twipToPixelShape(outlines.get(i)));
}
iconPanel.setImg(new SerializableImage(img), objs, outlines);
}
public void stop() {

View File

@@ -154,7 +154,6 @@ import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedOutputStream;
@@ -176,6 +175,8 @@ import java.util.concurrent.CancellationException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
@@ -2705,11 +2706,14 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
previewImagePanel.setTimelined(timelined, swf, fn.getFrame() - 1);
} else if (((tagObj instanceof SoundTag) && mainMenu.isInternalFlashViewerSelected() && (Arrays.asList("mp3", "wav").contains(((SoundTag) tagObj).getExportFormat())))) {
showCard(CARDDRAWPREVIEWPANEL);
previewImagePanel.setImage(new SerializableImage(1, 1, BufferedImage.TYPE_INT_ARGB));
soundThread = new SoundTagPlayer((SoundTag) tagObj, Integer.MAX_VALUE);
imagePlayControls.setMedia(soundThread);
soundThread.play();
previewImagePanel.setImage(new SerializableImage(View.loadImage("sound32")));
try {
soundThread = new SoundTagPlayer((SoundTag) tagObj, Integer.MAX_VALUE);
imagePlayControls.setMedia(soundThread);
soundThread.play();
} catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) {
Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
}
} else if (((tagObj instanceof FrameNodeItem) && ((FrameNodeItem) tagObj).isDisplayed()) || ((tagObj instanceof CharacterTag) || (tagObj instanceof FontTag)) && (tagObj instanceof Tag) || (tagObj instanceof SoundStreamHeadTypeTag)) {
((CardLayout) viewerCards.getLayout()).show(viewerCards, FLASH_VIEWER_CARD);

View File

@@ -18,13 +18,17 @@ package com.jpexs.decompiler.flash.gui;
import com.jpexs.decompiler.flash.gui.player.MediaDisplay;
import com.jpexs.decompiler.flash.tags.base.SoundTag;
import com.jpexs.helpers.sound.SoundPlayer;
import com.jpexs.helpers.sound.WavPlayer;
import com.jpexs.helpers.SoundPlayer;
import java.awt.Color;
import java.io.ByteArrayInputStream;
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.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
/**
*
@@ -36,9 +40,7 @@ public class SoundTagPlayer implements MediaDisplay {
private Thread thr;
private int actualPos = 0;
private boolean playing = false;
private SoundTag tag;
private byte data[];
private List<PlayerListener> listeners = new ArrayList<>();
public void addListener(PlayerListener l) {
@@ -55,39 +57,39 @@ public class SoundTagPlayer implements MediaDisplay {
}
}
private static final int FRAME_DIVISOR = 1024;
private static final int FRAME_DIVISOR = 8000;
private int loops;
private boolean paused = true;
private Object myLock = new Object();
private final Object playLock = new Object();
public SoundTagPlayer(SoundTag tag, int loops) {
public SoundTagPlayer(SoundTag tag, int loops) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
this.tag = tag;
this.loops = loops;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ByteArrayInputStream bais = new ByteArrayInputStream(tag.getRawSoundData());
tag.getSoundFormat().createWav(bais, baos);
this.data = baos.toByteArray();
player = new SoundPlayer(new ByteArrayInputStream(baos.toByteArray()));
}
@Override
public synchronized int getCurrentFrame() {
if (player == null) {
return 0;
}
if (!playing) {
if (!isPlaying()) {
return actualPos;
}
actualPos = (int) (player.getSamplePosition() / FRAME_DIVISOR);
synchronized (playLock) {
actualPos = (int) (player.getSamplePosition() / FRAME_DIVISOR);
}
return actualPos;
}
@Override
public synchronized int getTotalFrames() {
//System.out.println("getTotalFrames");
if (player == null) {
return 0;
}
int ret = (int) (player.samplesCount() / FRAME_DIVISOR);
//System.out.println("/getTotalFrames");
@@ -96,39 +98,70 @@ public class SoundTagPlayer implements MediaDisplay {
@Override
public synchronized void pause() {
if (!playing) {
if (!isPlaying()) {
paused = true;
return;
}
playing = false;
actualPos = (int) (player.getSamplePosition() / FRAME_DIVISOR);
player.stop();
synchronized (playLock) {
actualPos = (int) (player.getSamplePosition() / FRAME_DIVISOR);
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) {
if (player != null) {
player.stop();
}
player = new WavPlayer(new ByteArrayInputStream(data));
final int startPos = actualPos * FRAME_DIVISOR;
synchronized (playLock) {
if (!paused) {
paused = true;
player.stop();
try {
playLock.wait();
} catch (InterruptedException ex) {
Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
;
Runnable r = new Runnable() {
@Override
public void run() {
player.skip(startPos);
player.play();
fireFinished();
if (loops > 0) {
loops--;
int startPos = 0;
synchronized (playLock) {
startPos = actualPos * FRAME_DIVISOR;
paused = false;
}
if (playing && loops > 0) {
player.setPosition(startPos);
player.play();
boolean playAgain = false;
synchronized (playLock) {
playAgain = !paused;
paused = true;
if (loops > 0) {
loops--;
}
}
if (playAgain && loops > 0) {
gotoFrame(0);
play();
run();
return;
} else {
fireFinished();
}
synchronized (playLock) {
playLock.notifyAll();
}
}
};
playing = true;
if (async) {
thr = new Thread(r);
thr.start();
@@ -145,21 +178,20 @@ public class SoundTagPlayer implements MediaDisplay {
@Override
public void rewind() {
actualPos = 0;
gotoFrame(0);
}
@Override
public boolean isPlaying() {
return playing;
return player.isPlaying();
}
@Override
public synchronized void gotoFrame(int frame) {
if (playing) {
playing = false;
player.stop();
pause();
synchronized (playLock) {
actualPos = frame;
}
actualPos = frame;
}
@Override

View File

@@ -26,7 +26,6 @@ import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.TexturePaint;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
@@ -222,9 +221,13 @@ public class View {
* @param name Name of the image
* @return loaded Image
*/
public static Image loadImage(String name) {
public static BufferedImage loadImage(String name) {
java.net.URL imageURL = View.class.getResource("/com/jpexs/decompiler/flash/gui/graphics/" + name + ".png");
return Toolkit.getDefaultToolkit().createImage(imageURL);
try {
return ImageIO.read(imageURL);
} catch (IOException ex) {
return null;
}
}
/**

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -86,9 +86,9 @@ public class PlayerControls extends JPanel implements ActionListener {
@Override
public void mousePressed(MouseEvent e) {
int frame = (int) Math.floor(e.getX() * t.display.getTotalFrames() / (double) progress.getWidth());
boolean p = paused;
boolean p = t.display.isPlaying();
t.display.gotoFrame(frame);
if (!p) {
if (p) {
t.display.play();
}
}

View File

@@ -16,20 +16,12 @@
*/
package com.jpexs.decompiler.flash.timeline;
import com.jpexs.decompiler.flash.exporters.Matrix;
import com.jpexs.decompiler.flash.tags.DoActionTag;
import com.jpexs.decompiler.flash.tags.base.ButtonTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
import com.jpexs.decompiler.flash.types.RGB;
import com.jpexs.decompiler.flash.types.RGBA;
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
import java.awt.Point;
import java.awt.Shape;
import java.awt.geom.Area;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.TreeMap;
/**

View File

@@ -206,8 +206,8 @@ public class Timeline {
}
return ret;
}
public void getObjectsOutlines(int frame, int ratio,DepthState stateUnderCursor, int mouseButton, Matrix transformation,List<DepthState> objs,List<Shape> outlines){
public void getObjectsOutlines(int frame, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation, List<DepthState> objs, List<Shape> outlines) {
Frame fr = this.frames.get(frame);
Stack<Clip> clips = new Stack<>();
for (int d = this.getMaxDepth(); d >= 0; d--) {
@@ -234,8 +234,8 @@ public class Timeline {
m = m.preConcatenate(transformation);
int dframe = 0;
if(c instanceof Timelined){
dframe = ds.time % ((Timelined) c).getTimeline().frames.size();
if (c instanceof Timelined) {
dframe = ds.time % ((Timelined) c).getTimeline().frames.size();
if (c instanceof ButtonTag) {
ButtonTag bt = (ButtonTag) c;
dframe = ButtonTag.FRAME_UP;
@@ -249,7 +249,7 @@ public class Timeline {
}
}
Shape cshape = ((DrawableTag) c).getOutline(dframe, ds.ratio, stateUnderCursor, mouseButton, m);
Area addArea = new Area(cshape);
if (currentClip != null) {
Area a = new Area(new Rectangle(displayRect.Xmin, displayRect.Ymin, displayRect.getWidth(), displayRect.getHeight()));
@@ -261,10 +261,10 @@ public class Timeline {
clips.push(clip);
} else {
objs.add(ds);
outlines.add(addArea);
outlines.add(addArea);
}
if(c instanceof Timelined){
((Timelined)c).getTimeline().getObjectsOutlines(dframe, ds.ratio, stateUnderCursor, mouseButton, m, objs, outlines);
if (c instanceof Timelined) {
((Timelined) c).getTimeline().getObjectsOutlines(dframe, ds.ratio, stateUnderCursor, mouseButton, m, objs, outlines);
}
}
}
@@ -298,8 +298,8 @@ public class Timeline {
m = m.preConcatenate(transformation);
int dframe = 0;
if(c instanceof Timelined){
dframe = ds.time % ((Timelined) c).getTimeline().frames.size();
if (c instanceof Timelined) {
dframe = ds.time % ((Timelined) c).getTimeline().frames.size();
if (c instanceof ButtonTag) {
ButtonTag bt = (ButtonTag) c;
dframe = ButtonTag.FRAME_UP;
@@ -313,7 +313,7 @@ public class Timeline {
}
}
Shape cshape = ((DrawableTag) c).getOutline(dframe, ds.ratio, stateUnderCursor, mouseButton, m);
Area addArea = new Area(cshape);
if (currentClip != null) {
Area a = new Area(new Rectangle(displayRect.Xmin, displayRect.Ymin, displayRect.getWidth(), displayRect.getHeight()));

View File

@@ -14,13 +14,11 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.helpers.sound;
package com.jpexs.helpers;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
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;
@@ -33,51 +31,29 @@ import javax.sound.sampled.UnsupportedAudioFileException;
*
* @author JPEXS
*/
public class WavPlayer extends SoundPlayer {
public class SoundPlayer {
private Clip clip;
private boolean complete = false;
private long startPos = 0;
public WavPlayer(InputStream is) {
super(is);
try {
clip = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
} catch (LineUnavailableException ex) {
Logger.getLogger(WavPlayer.class.getName()).log(Level.SEVERE, null, ex);
}
if (clip == null) {
return;
}
try {
clip.open(AudioSystem.getAudioInputStream(new BufferedInputStream(is)));
} catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) {
Logger.getLogger(WavPlayer.class.getName()).log(Level.SEVERE, "Error opening", ex);
clip = null;
}
public SoundPlayer(InputStream is) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
clip = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
clip.open(AudioSystem.getAudioInputStream(new BufferedInputStream(is)));
}
@Override
public long samplesCount() {
return clip.getMicrosecondLength();
}
@Override
public void play() {
if (clip == null) {
return;
}
clip.setMicrosecondPosition(startPos);//startPos);
final WavPlayer t = this;
final SoundPlayer t = this;
clip.addLineListener(new LineListener() {
@Override
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP) {
complete = true;
startPos = 0;
clip.close();
//clip.close();
synchronized (t) {
t.notifyAll();
}
@@ -94,29 +70,31 @@ public class WavPlayer extends SoundPlayer {
}
}
@Override
public long getSamplePosition() {
return clip.getMicrosecondPosition();
}
@Override
public void skip(long frames) {
startPos = getSamplePosition() + frames;
public void setPosition(long frames) {
clip.setMicrosecondPosition(frames);
}
@Override
public void stop() {
clip.stop();
}
@Override
public boolean isPlaying() {
return !complete;
return clip.isActive();
}
@Override
public long getFrameRate() {
return 1000000L;
}
@Override
protected void finalize() throws Throwable {
if (clip != null) {
clip.close();
}
}
}

View File

@@ -1,194 +0,0 @@
/*
* Copyright (C) 2010-2014 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.helpers.sound;
/**
*
* @author JPEXS
*/
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javazoom.jl.decoder.Bitstream;
import javazoom.jl.decoder.Decoder;
import javazoom.jl.decoder.Header;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.decoder.SampleBuffer;
import javazoom.jl.player.AudioDevice;
import javazoom.jl.player.FactoryRegistry;
public class MP3Player extends SoundPlayer {
private Bitstream bitstream;
private Decoder decoder;
private AudioDevice audio;
private boolean closed = false;
private boolean complete = false;
private int positionSamples = 0;
private long sampleCount;
private int frameRate;
private int positionFrames = 0;
public MP3Player(InputStream stream, long sampleCount, int frameRate) throws JavaLayerException {
this(stream, null);
this.sampleCount = sampleCount;
this.frameRate = frameRate;
}
private MP3Player(InputStream stream, AudioDevice device) throws JavaLayerException {
super(stream);
bitstream = new Bitstream(stream);
decoder = new Decoder();
if (device != null) {
audio = device;
} else {
FactoryRegistry r = FactoryRegistry.systemRegistry();
audio = r.createAudioDevice();
}
audio.open(decoder);
}
@Override
public void play() {
try {
play(Integer.MAX_VALUE);
} catch (JavaLayerException ex) {
Logger.getLogger(MP3Player.class.getName()).log(Level.SEVERE, null, ex);
}
}
private boolean play(int frames) throws JavaLayerException {
if (complete) {
return false;
}
boolean ret = true;
while (frames-- > 0 && ret) {
ret = decodeFrame();
}
if (!ret) {
// last frame, ensure all data flushed to the audio device.
AudioDevice out = audio;
if (out != null) {
out.flush();
synchronized (this) {
complete = (!closed);
stop();
}
}
}
return ret;
}
@Override
public synchronized void skip(long samples) {
if (complete) {
return;
}
long endPosition = positionSamples + samples;
if (samples == 0) {
return;
}
try {
while (true) {
Header h = bitstream.readFrame();
if (h == null) {
complete = true;
return;
}
SampleBuffer output = (SampleBuffer) decoder.decodeFrame(h, bitstream);
positionSamples += output.getBufferLength();
positionFrames++;
bitstream.closeFrame();
if (positionSamples >= endPosition) {
break;
}
}
} catch (Exception ex) {
//ingore
}
}
@Override
public synchronized void stop() {
AudioDevice out = audio;
if (out != null) {
closed = true;
audio = null;
out.close();
}
}
@Override
public synchronized boolean isPlaying() {
return !complete;
}
@Override
public long getSamplePosition() {
return positionSamples;
}
private boolean decodeFrame() throws JavaLayerException {
try {
AudioDevice out = audio;
if (out == null) {
return false;
}
Header h = bitstream.readFrame();
if (h == null) {
return false;
}
SampleBuffer output = (SampleBuffer) decoder.decodeFrame(h, bitstream);
positionSamples += output.getBufferLength();
positionFrames++;
synchronized (this) {
out = audio;
if (out != null) {
out.write(output.getBuffer(), 0, output.getBufferLength());
}
}
bitstream.closeFrame();
} catch (RuntimeException ex) {
return true;
}
return true;
}
@Override
public long samplesCount() {
return sampleCount;
}
@Override
public long getFrameRate() {
return frameRate;
}
}

View File

@@ -20,10 +20,10 @@ import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.parser.ParseException;
import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.CodeFormatting;
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
import com.jpexs.decompiler.flash.tags.DoActionTag;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;