/**
* Created : Jun 27, 2012
*
* @author pquiring
*/
import javaforce.*;
public class FxAmplify extends javax.swing.JDialog {
/**
* Creates new form FxAmplify
*/
public FxAmplify(java.awt.Frame parent, boolean modal, TrackPanel track) {
super(parent, modal);
initComponents();
JF.centerWindow(this);
this.track = track;
maxSample = 0;
if (track.selectStop < track.selectStart) {
sStart = track.selectStop;
sStop = track.selectStart;
} else {
sStart = track.selectStart;
sStop = track.selectStop;
}
length = (sStop - sStart + 1);
offset = sStart;
long len = length;
long off = offset;
while (len > 0) {
int read = track.maxChunkSize;
if (read > len) read = (int)len;
for(int ch=0;ch<track.channels;ch++) {
byte samples[] = track.getSamples(off, read, ch);
switch (track.bits) {
case 16:
short samples16[] = LE.byteArray2shortArray(samples, null);
for(int a=0;a<samples16.length;a++) {
int value = Math.abs(samples16[a]) << 16;
if (value > maxSample) maxSample = value;
}
break;
case 32:
int samples32[] = LE.byteArray2intArray(samples, null);
for(int a=0;a<samples32.length;a++) {
int value = Math.abs(samples32[a]);
if (value > maxSample) maxSample = value;
}
break;
}
}
off += read;
len -= read;
}
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
apply = new javax.swing.JButton();
cancel = new javax.swing.JButton();
jLabel1 = new javax.swing.JLabel();
valueField = new javax.swing.JTextField();
valueSlider = new javax.swing.JSlider();
allowClipping = new javax.swing.JCheckBox();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle("Amplify");
setResizable(false);
apply.setText("Apply");
apply.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
applyActionPerformed(evt);
}
});
cancel.setText("Cancel");
cancel.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cancelActionPerformed(evt);
}
});
jLabel1.setText("Amplification (dB)");
valueField.setText("0.0");
valueField.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseReleased(java.awt.event.MouseEvent evt) {
valueFieldMouseReleased(evt);
}
});
valueField.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent evt) {
valueFieldKeyReleased(evt);
}
});
valueSlider.setMaximum(500);
valueSlider.setMinimum(-500);
valueSlider.setToolTipText("Amplification");
valueSlider.setValue(0);
valueSlider.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
valueSliderStateChanged(evt);
}
});
allowClipping.setText("Allow clipping");
allowClipping.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
allowClippingActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(allowClipping)
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(valueSlider, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(cancel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(apply))
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(valueField)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(valueField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(valueSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(allowClipping)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(apply)
.addComponent(cancel))
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void valueSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_valueSliderStateChanged
sliderChanged();
}//GEN-LAST:event_valueSliderStateChanged
private void cancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelActionPerformed
dispose();
}//GEN-LAST:event_cancelActionPerformed
private void applyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyActionPerformed
apply();
}//GEN-LAST:event_applyActionPerformed
private void allowClippingActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allowClippingActionPerformed
checkClipping();
}//GEN-LAST:event_allowClippingActionPerformed
private void valueFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_valueFieldKeyReleased
textChanged();
}//GEN-LAST:event_valueFieldKeyReleased
private void valueFieldMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_valueFieldMouseReleased
textChanged();
}//GEN-LAST:event_valueFieldMouseReleased
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JCheckBox allowClipping;
private javax.swing.JButton apply;
private javax.swing.JButton cancel;
private javax.swing.JLabel jLabel1;
private javax.swing.JTextField valueField;
private javax.swing.JSlider valueSlider;
// End of variables declaration//GEN-END:variables
private TrackPanel track;
private double maxSample;
private long length, sStart, sStop, offset;
private boolean changing = false;
private void checkClipping() {
boolean ok = true;
double value = ((double)valueSlider.getValue()) * 0.1;
double factor = (int)(value / 10.0); //convert DB to multiply/divide factor (10dB = 2x)
if (factor >= 0.0) {
if (maxSample * factor > Integer.MAX_VALUE) ok = false;
}
if (ok || allowClipping.isSelected()) {
apply.setEnabled(true);
} else {
apply.setEnabled(false);
}
}
private void apply() {
double dbValue = ((double)valueSlider.getValue()) * 0.1;
double dbFactor = dbValue / 10.0; //convert DB to multiply/divide factor (10dB = 2x)
// JFLog.log("dbFactor=" + dbFactor);
track.createModifyUndo();
if (dbFactor >= 0.0) {
dbFactor += 1.0;
//multiply factor
long len = length;
long off = offset;
while (len > 0) {
int read = track.maxChunkSize;
if (read > len) read = (int)len;
for(int ch=0;ch<track.channels;ch++) {
byte samples[] = track.getSamples(off, read, ch);
//JFLog.log("samples.8=" + samples[0] + "," + samples[1] + "," + samples[2] + "," + samples[3]);
switch (track.bits) {
case 16:
short samples16[] = LE.byteArray2shortArray(samples, null);
//JFLog.log("samples.16=" + samples16[0] + "," + samples16[1] + "," + samples16[2] + "," + samples16[3]);
for(int a=0;a<samples16.length;a++) {
samples16[a] = (short)(samples16[a] * dbFactor);
}
//JFLog.log("samples.16=" + samples16[0] + "," + samples16[1] + "," + samples16[2] + "," + samples16[3]);
samples = LE.shortArray2byteArray(samples16, null);
break;
case 32:
int samples32[] = LE.byteArray2intArray(samples, null);
for(int a=0;a<samples32.length;a++) {
samples32[a] = (int)(samples32[a] * dbFactor);
}
samples = LE.intArray2byteArray(samples32, null);
break;
}
//JFLog.log("samples.8=" + samples[0] + "," + samples[1] + "," + samples[2] + "," + samples[3]);
track.setSamples(off, samples, ch);
}
off += read;
len -= read;
}
} else {
//divide factor
dbFactor *= -1.0;
dbFactor += 1.0;
long len = length;
long off = offset;
while (len > 0) {
int read = track.maxChunkSize;
if (read > len) read = (int)len;
for(int ch=0;ch<track.channels;ch++) {
byte samples[] = track.getSamples(off, read, ch);
switch (track.bits) {
case 16:
short samples16[] = LE.byteArray2shortArray(samples, null);
for(int a=0;a<samples16.length;a++) {
samples16[a] = (short)(samples16[a] / dbFactor);
}
samples = LE.shortArray2byteArray(samples16, null);
break;
case 32:
int samples32[] = LE.byteArray2intArray(samples, null);
for(int a=0;a<samples32.length;a++) {
samples32[a] = (int)(samples32[a] / dbFactor);
}
samples = LE.intArray2byteArray(samples32, null);
break;
}
track.setSamples(off, samples, ch);
}
off += read;
len -= read;
}
}
dispose();
}
private void textChanged() {
if (changing) return;
changing = true;
try {
Double value = Double.valueOf(valueField.getText());
if (value < -50.0) value = -50.0;
if (value > 50.0) value = 50.0;
valueSlider.setValue((int)(value * 10.0));
} catch (Exception e) {
JFLog.log(e);
}
changing = false;
checkClipping();
}
private void sliderChanged() {
if (changing) return;
changing = true;
try {
valueField.setText(String.format("%.2f", ((double)valueSlider.getValue()) * 0.1));
} catch (Exception e) {
JFLog.log(e);
}
changing = false;
checkClipping();
}
}