/**
*
* @author pquiring
*
* Created : Jan 19, 2014
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javaforce.*;
import javaforce.media.*;
public class Samples extends JComponent implements MouseListener, MouseMotionListener{
private SongPanel panel;
private JFImage img;
private Stroke normal, dashed;
public Music.Sample sample;
public int loopStart, loopEnd;
public int sustainStart, sustainEnd;
public float attenuation;
public boolean showAttenuation, showLoop, showSustain;
private int loopStartPos, loopEndPos;
private int sustainStartPos, sustainEndPos;
private int samplesPerPixel;
// private float maxAttenuation;
private int attenuationX, attenuationY;
public Samples(SongPanel panel) {
this.panel = panel;
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
public void paint(Graphics g) {
try {
int width = getWidth();
int height = getHeight();
if (img == null) {
img = new JFImage(width, height);
normal = img.getGraphics2D().getStroke();
dashed = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f
, new float[] {10.0f}, 0.0f);
}
if (img.getWidth() != width || img.getHeight() != height) {
img.setImageSize(width, height);
}
img.fill(0, 0, width, height, 0);
if (sample == null) return;
short samples[] = sample.samples;
samplesPerPixel = panel.getZoom();
int pos = 0;
int cnt = samples.length / samplesPerPixel;
if (samples.length % samplesPerPixel != 0) cnt++;
int hScale = 32768 / height;
int height2 = height / 2;
int last = height2;
for(int a=0;a<cnt;a++) {
if (a >= width) break;
boolean drawLine = false;
boolean dashedLine = false;
int val = 0;
for(int s=0;s<samplesPerPixel;s++) {
int poss = pos + s;
if (poss == samples.length) break;
val += samples[poss];
if (showLoop) {
if (poss == loopStart) {drawLine = true; loopStartPos = a; dashedLine = false;}
if (poss == loopEnd) {drawLine = true; loopEndPos = a; dashedLine = false;}
}
if (showSustain) {
if (poss == sustainStart) {drawLine = true; sustainStartPos = a; dashedLine = true;}
if (poss == sustainEnd) {drawLine = true; sustainEndPos = a; dashedLine = true;}
}
}
val /= samplesPerPixel;
val /= hScale;
val += height2;
if (val < 0) val = 0;
if (val >= height) val = height-1;
pos += samplesPerPixel;
img.line(a-1,last,a,val,Color.red.getRGB());
if (drawLine) {
if (dashedLine) img.getGraphics2D().setStroke(dashed);
img.line(a, 0, a, height-1, Color.white.getRGB());
if (dashedLine) img.getGraphics2D().setStroke(normal);
}
last = val;
}
if (showAttenuation) {
attenuationX = sample.samples.length / samplesPerPixel;
attenuationY = (int)(attenuation * sample.samples.length * height);
if (attenuationY >= height) attenuationY = height;
img.line(0,0,attenuationX,attenuationY,Color.blue.getRGB());
img.box(attenuationX-5,attenuationY-5,11,11,Color.blue.getRGB());
}
g.drawImage(img.getImage(), 0, 0, null);
} catch (Exception e) {
JFLog.log(e);
}
}
public void setSample(Music.Sample i) {
sample = i;
// maxAttenuation = 1.0f / ((float)instrument.samples.samples.length);
}
public Dimension getPreferredSize() {
Dimension size = panel.getSamplesPaneSize();
if (sample == null) return size;
size.width = sample.samples.length / panel.getZoom();
return size;
}
public void mouseClicked(MouseEvent e) {
}
private int drag = -1;
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
int tx, ty;
drag = -1;
if (showAttenuation) {
tx = x - attenuationX;
ty = y - attenuationY;
if (tx > -5 && tx < 5 && ty > -5 && ty < 5) {
drag = 5;
return;
}
}
if (loopStart != -1) {
tx = x - loopStartPos;
if (tx > -5 && tx < 5) {
drag = 1;
return;
}
tx = x - loopEndPos;
if (tx > -5 && tx < 5) {
drag = 2;
return;
}
}
if (sustainStart != -1) {
tx = x - sustainStartPos;
if (tx > -5 && tx < 5) {
drag = 3;
return;
}
tx = x - sustainEndPos;
if (tx > -5 && tx < 5) {
drag = 4;
return;
}
}
}
public void mouseReleased(MouseEvent e) {
if (drag != -1) {
panel.saveSample();
}
drag = -1;
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
if (drag == -1) return;
int x = e.getX() * samplesPerPixel;
if (x < 0) x = 0;
if (x >= sample.samples.length) x = sample.samples.length - 1;
int y = e.getY();
int height = getHeight();
if (y < 0) y = 0;
if (y >= height) y = height - 1;
switch (drag) {
case 1: loopStart = x; break;
case 2: loopEnd = x; break;
case 3: sustainStart = x; break;
case 4: sustainEnd = x; break;
case 5:
attenuation = (float)y;
attenuation /= (float)height;
attenuation /= (float)sample.samples.length;
break;
}
repaint();
}
public void mouseMoved(MouseEvent e) {
}
}