/**
* Music editor
*
* @author pquiring
*
* Created : Jan 14, 2014
*/
import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.filechooser.*;
import javax.sound.midi.*;
import javaforce.*;
import javaforce.media.*;
import javaforce.jni.*;
public class SongPanel extends javax.swing.JPanel implements Music.Listener, Receiver, MediaIO {
/**
* Creates new form MainPanel
*/
public SongPanel() {
initComponents();
tableView.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
tableView.setTableHeader(null);
tableView.setRowHeight(20);
colModel = (DefaultTableColumnModel)tableView.getColumnModel();
samples = new Samples(this);
samplesPane.setViewportView(samples);
loadLibrary();
reset();
}
/**
* 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() {
noteTypes = new javax.swing.ButtonGroup();
tabs = new javax.swing.JTabbedPane();
generalTab = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
name = new javax.swing.JTextField();
jLabel8 = new javax.swing.JLabel();
jScrollPane3 = new javax.swing.JScrollPane();
comment = new javax.swing.JTextArea();
patternsTab = new javax.swing.JPanel();
jToolBar2 = new javax.swing.JToolBar();
jLabel11 = new javax.swing.JLabel();
pattern = new javax.swing.JComboBox();
addPattern = new javax.swing.JButton();
removePattern = new javax.swing.JButton();
jButton10 = new javax.swing.JButton();
filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767));
jButton11 = new javax.swing.JButton();
jButton12 = new javax.swing.JButton();
filler5 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767));
jButton2 = new javax.swing.JButton();
jButton3 = new javax.swing.JButton();
jButton1 = new javax.swing.JButton();
jToolBar4 = new javax.swing.JToolBar();
jLabel2 = new javax.swing.JLabel();
bpm = new javax.swing.JSpinner();
filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767));
jLabel3 = new javax.swing.JLabel();
jButton7 = new javax.swing.JButton();
jButton8 = new javax.swing.JButton();
filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767));
jScrollPane1 = new javax.swing.JScrollPane();
tableView = new javax.swing.JTable() {
public TableCellEditor getCellEditor(int row, int column) {
if (row == 0) return _getCellEditor(row, column);
return super.getCellEditor(row, column);
}
};
seqTab = new javax.swing.JPanel();
jScrollPane4 = new javax.swing.JScrollPane();
sequence = new javax.swing.JList();
seqUp = new javax.swing.JButton();
seqDown = new javax.swing.JButton();
jToolBar1 = new javax.swing.JToolBar();
jLabel13 = new javax.swing.JLabel();
seqPattern = new javax.swing.JComboBox();
seqAdd = new javax.swing.JButton();
seqRemove = new javax.swing.JButton();
instrTab = new javax.swing.JPanel();
jToolBar5 = new javax.swing.JToolBar();
jLabel14 = new javax.swing.JLabel();
instrument = new javax.swing.JComboBox();
iRemove = new javax.swing.JButton();
jButton9 = new javax.swing.JButton();
filler9 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767));
jLabel5 = new javax.swing.JLabel();
library = new javax.swing.JComboBox();
iAddLibrary = new javax.swing.JButton();
filler10 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767));
jLabel7 = new javax.swing.JLabel();
iAddFile = new javax.swing.JButton();
filler6 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
jToolBar7 = new javax.swing.JToolBar();
jLabel6 = new javax.swing.JLabel();
regions = new javax.swing.JComboBox();
jButton14 = new javax.swing.JButton();
jButton15 = new javax.swing.JButton();
jButton13 = new javax.swing.JButton();
filler11 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
samplesTab = new javax.swing.JPanel();
jToolBar3 = new javax.swing.JToolBar();
jLabel9 = new javax.swing.JLabel();
sample = new javax.swing.JComboBox();
jButton17 = new javax.swing.JButton();
jButton18 = new javax.swing.JButton();
jButton16 = new javax.swing.JButton();
filler8 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
jToolBar6 = new javax.swing.JToolBar();
sustain = new javax.swing.JCheckBox();
loop = new javax.swing.JCheckBox();
attenuation = new javax.swing.JCheckBox();
filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767));
jLabel4 = new javax.swing.JLabel();
zoom = new javax.swing.JComboBox();
jButton4 = new javax.swing.JButton();
jButton5 = new javax.swing.JButton();
jButton6 = new javax.swing.JButton();
filler7 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
samplesPane = new javax.swing.JScrollPane();
tabs.setPreferredSize(new java.awt.Dimension(418, 580));
generalTab.setPreferredSize(new java.awt.Dimension(418, 580));
jLabel1.setText("Name:");
jLabel8.setText("Comments:");
comment.setColumns(20);
comment.setRows(5);
jScrollPane3.setViewportView(comment);
javax.swing.GroupLayout generalTabLayout = new javax.swing.GroupLayout(generalTab);
generalTab.setLayout(generalTabLayout);
generalTabLayout.setHorizontalGroup(
generalTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(generalTabLayout.createSequentialGroup()
.addContainerGap()
.addGroup(generalTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(generalTabLayout.createSequentialGroup()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(name))
.addGroup(generalTabLayout.createSequentialGroup()
.addComponent(jLabel8)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 550, Short.MAX_VALUE)))
.addContainerGap())
);
generalTabLayout.setVerticalGroup(
generalTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(generalTabLayout.createSequentialGroup()
.addContainerGap()
.addGroup(generalTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(name, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(generalTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel8)
.addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(449, Short.MAX_VALUE))
);
tabs.addTab("General", generalTab);
patternsTab.setPreferredSize(new java.awt.Dimension(418, 580));
jToolBar2.setFloatable(false);
jToolBar2.setRollover(true);
jLabel11.setText("Pattern:");
jToolBar2.add(jLabel11);
pattern.setMaximumSize(new java.awt.Dimension(128, 20));
pattern.setMinimumSize(new java.awt.Dimension(128, 20));
pattern.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
patternItemStateChanged(evt);
}
});
jToolBar2.add(pattern);
addPattern.setIcon(new javax.swing.ImageIcon(getClass().getResource("/plus.png"))); // NOI18N
addPattern.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
addPatternActionPerformed(evt);
}
});
jToolBar2.add(addPattern);
removePattern.setIcon(new javax.swing.ImageIcon(getClass().getResource("/minus.png"))); // NOI18N
removePattern.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
removePatternActionPerformed(evt);
}
});
jToolBar2.add(removePattern);
jButton10.setIcon(new javax.swing.ImageIcon(getClass().getResource("/edit.png"))); // NOI18N
jButton10.setFocusable(false);
jButton10.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jButton10.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jButton10.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton10ActionPerformed(evt);
}
});
jToolBar2.add(jButton10);
jToolBar2.add(filler2);
jButton11.setIcon(new javax.swing.ImageIcon(getClass().getResource("/up.png"))); // NOI18N
jButton11.setFocusable(false);
jButton11.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jButton11.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jButton11.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton11ActionPerformed(evt);
}
});
jToolBar2.add(jButton11);
jButton12.setIcon(new javax.swing.ImageIcon(getClass().getResource("/down.png"))); // NOI18N
jButton12.setFocusable(false);
jButton12.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jButton12.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jButton12.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton12ActionPerformed(evt);
}
});
jToolBar2.add(jButton12);
jToolBar2.add(filler5);
jButton2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/play.png"))); // NOI18N
jButton2.setFocusable(false);
jButton2.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jButton2.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});
jToolBar2.add(jButton2);
jButton3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/stop.png"))); // NOI18N
jButton3.setFocusable(false);
jButton3.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jButton3.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jButton3.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton3ActionPerformed(evt);
}
});
jToolBar2.add(jButton3);
jButton1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/record.png"))); // NOI18N
jButton1.setFocusable(false);
jButton1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jButton1.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
jToolBar2.add(jButton1);
jToolBar4.setFloatable(false);
jLabel2.setText("BPM:");
jToolBar4.add(jLabel2);
bpm.setModel(new javax.swing.SpinnerNumberModel(80, 1, 65536, 1));
bpm.setMaximumSize(new java.awt.Dimension(60, 20));
bpm.setMinimumSize(new java.awt.Dimension(20, 20));
bpm.setPreferredSize(new java.awt.Dimension(20, 20));
bpm.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
bpmStateChanged(evt);
}
});
bpm.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent evt) {
bpmKeyTyped(evt);
}
});
jToolBar4.add(bpm);
jToolBar4.add(filler3);
jLabel3.setText("Track:");
jToolBar4.add(jLabel3);
jButton7.setIcon(new javax.swing.ImageIcon(getClass().getResource("/plus.png"))); // NOI18N
jButton7.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton7ActionPerformed(evt);
}
});
jToolBar4.add(jButton7);
jButton8.setIcon(new javax.swing.ImageIcon(getClass().getResource("/minus.png"))); // NOI18N
jButton8.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton8ActionPerformed(evt);
}
});
jToolBar4.add(jButton8);
jToolBar4.add(filler1);
tableView.setFont(JF.getMonospacedFont(0, 12));
tableView.setModel(tableModel);
tableView.setCellSelectionEnabled(true);
tableView.getTableHeader().setReorderingAllowed(false);
tableView.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
tableViewMouseClicked(evt);
}
});
tableView.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyPressed(java.awt.event.KeyEvent evt) {
tableViewKeyPressed(evt);
}
public void keyReleased(java.awt.event.KeyEvent evt) {
tableViewKeyReleased(evt);
}
public void keyTyped(java.awt.event.KeyEvent evt) {
tableViewKeyTyped(evt);
}
});
jScrollPane1.setViewportView(tableView);
tableView.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
javax.swing.GroupLayout patternsTabLayout = new javax.swing.GroupLayout(patternsTab);
patternsTab.setLayout(patternsTabLayout);
patternsTabLayout.setHorizontalGroup(
patternsTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jToolBar2, javax.swing.GroupLayout.DEFAULT_SIZE, 628, Short.MAX_VALUE)
.addComponent(jToolBar4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 628, Short.MAX_VALUE)
);
patternsTabLayout.setVerticalGroup(
patternsTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(patternsTabLayout.createSequentialGroup()
.addComponent(jToolBar2, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jToolBar4, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 520, Short.MAX_VALUE))
);
tabs.addTab("Patterns", patternsTab);
seqTab.setPreferredSize(new java.awt.Dimension(418, 580));
sequence.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
sequenceValueChanged(evt);
}
});
jScrollPane4.setViewportView(sequence);
seqUp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/up.png"))); // NOI18N
seqUp.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
seqUpActionPerformed(evt);
}
});
seqDown.setIcon(new javax.swing.ImageIcon(getClass().getResource("/down.png"))); // NOI18N
seqDown.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
seqDownActionPerformed(evt);
}
});
jToolBar1.setFloatable(false);
jToolBar1.setRollover(true);
jLabel13.setText("Pattern:");
jToolBar1.add(jLabel13);
seqPattern.setMaximumSize(new java.awt.Dimension(128, 20));
seqPattern.setMinimumSize(new java.awt.Dimension(128, 20));
jToolBar1.add(seqPattern);
seqAdd.setIcon(new javax.swing.ImageIcon(getClass().getResource("/plus.png"))); // NOI18N
seqAdd.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
seqAddActionPerformed(evt);
}
});
jToolBar1.add(seqAdd);
seqRemove.setIcon(new javax.swing.ImageIcon(getClass().getResource("/minus.png"))); // NOI18N
seqRemove.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
seqRemoveActionPerformed(evt);
}
});
javax.swing.GroupLayout seqTabLayout = new javax.swing.GroupLayout(seqTab);
seqTab.setLayout(seqTabLayout);
seqTabLayout.setHorizontalGroup(
seqTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(seqTabLayout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 172, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(seqTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(seqUp)
.addComponent(seqDown)
.addComponent(seqRemove))
.addContainerGap(391, Short.MAX_VALUE))
.addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
seqTabLayout.setVerticalGroup(
seqTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(seqTabLayout.createSequentialGroup()
.addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(seqTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(seqTabLayout.createSequentialGroup()
.addComponent(seqUp)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(seqDown)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(seqRemove)
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 556, Short.MAX_VALUE)))
);
tabs.addTab("Sequence", seqTab);
instrTab.setPreferredSize(new java.awt.Dimension(418, 580));
jToolBar5.setFloatable(false);
jToolBar5.setRollover(true);
jToolBar5.setMinimumSize(new java.awt.Dimension(1, 1));
jToolBar5.setPreferredSize(new java.awt.Dimension(1, 25));
jLabel14.setText("Instrument:");
jToolBar5.add(jLabel14);
instrument.setMaximumSize(new java.awt.Dimension(256, 32767));
instrument.setMinimumSize(new java.awt.Dimension(256, 20));
instrument.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
instrumentItemStateChanged(evt);
}
});
jToolBar5.add(instrument);
iRemove.setIcon(new javax.swing.ImageIcon(getClass().getResource("/minus.png"))); // NOI18N
iRemove.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
iRemoveActionPerformed(evt);
}
});
jToolBar5.add(iRemove);
jButton9.setIcon(new javax.swing.ImageIcon(getClass().getResource("/edit.png"))); // NOI18N
jButton9.setFocusable(false);
jButton9.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jButton9.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jButton9.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton9ActionPerformed(evt);
}
});
jToolBar5.add(jButton9);
jToolBar5.add(filler9);
jLabel5.setText("Library:");
jToolBar5.add(jLabel5);
library.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Piano", "etc" }));
library.setMaximumSize(new java.awt.Dimension(256, 32767));
library.setMinimumSize(new java.awt.Dimension(256, 20));
jToolBar5.add(library);
iAddLibrary.setIcon(new javax.swing.ImageIcon(getClass().getResource("/plus.png"))); // NOI18N
iAddLibrary.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
iAddLibraryActionPerformed(evt);
}
});
jToolBar5.add(iAddLibrary);
jToolBar5.add(filler10);
jLabel7.setText("Import:");
jToolBar5.add(jLabel7);
iAddFile.setIcon(new javax.swing.ImageIcon(getClass().getResource("/plus.png"))); // NOI18N
iAddFile.setToolTipText("");
iAddFile.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
iAddFileActionPerformed(evt);
}
});
jToolBar5.add(iAddFile);
jToolBar5.add(filler6);
jToolBar7.setFloatable(false);
jToolBar7.setRollover(true);
jLabel6.setText("Regions:");
jToolBar7.add(jLabel6);
regions.setMaximumSize(new java.awt.Dimension(256, 32767));
regions.setMinimumSize(new java.awt.Dimension(256, 20));
regions.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
regionsItemStateChanged(evt);
}
});
jToolBar7.add(regions);
jButton14.setIcon(new javax.swing.ImageIcon(getClass().getResource("/plus.png"))); // NOI18N
jButton14.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton14ActionPerformed(evt);
}
});
jToolBar7.add(jButton14);
jButton15.setIcon(new javax.swing.ImageIcon(getClass().getResource("/minus.png"))); // NOI18N
jButton15.setToolTipText("");
jButton15.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton15ActionPerformed(evt);
}
});
jToolBar7.add(jButton15);
jButton13.setIcon(new javax.swing.ImageIcon(getClass().getResource("/edit.png"))); // NOI18N
jButton13.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton13ActionPerformed(evt);
}
});
jToolBar7.add(jButton13);
jToolBar7.add(filler11);
javax.swing.GroupLayout instrTabLayout = new javax.swing.GroupLayout(instrTab);
instrTab.setLayout(instrTabLayout);
instrTabLayout.setHorizontalGroup(
instrTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jToolBar5, javax.swing.GroupLayout.DEFAULT_SIZE, 628, Short.MAX_VALUE)
.addComponent(jToolBar7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
instrTabLayout.setVerticalGroup(
instrTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(instrTabLayout.createSequentialGroup()
.addComponent(jToolBar5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jToolBar7, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(531, Short.MAX_VALUE))
);
tabs.addTab("Instruments", instrTab);
jToolBar3.setFloatable(false);
jToolBar3.setRollover(true);
jLabel9.setText("Sample:");
jToolBar3.add(jLabel9);
sample.setMaximumSize(new java.awt.Dimension(256, 32767));
sample.setMinimumSize(new java.awt.Dimension(256, 20));
sample.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
sampleItemStateChanged(evt);
}
});
jToolBar3.add(sample);
jButton17.setIcon(new javax.swing.ImageIcon(getClass().getResource("/plus.png"))); // NOI18N
jButton17.setToolTipText("");
jButton17.setFocusable(false);
jButton17.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jButton17.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jButton17.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton17ActionPerformed(evt);
}
});
jToolBar3.add(jButton17);
jButton18.setIcon(new javax.swing.ImageIcon(getClass().getResource("/minus.png"))); // NOI18N
jButton18.setFocusable(false);
jButton18.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jButton18.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jButton18.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton18ActionPerformed(evt);
}
});
jToolBar3.add(jButton18);
jButton16.setIcon(new javax.swing.ImageIcon(getClass().getResource("/edit.png"))); // NOI18N
jButton16.setFocusable(false);
jButton16.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jButton16.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jButton16.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton16ActionPerformed(evt);
}
});
jToolBar3.add(jButton16);
jToolBar3.add(filler8);
jToolBar6.setFloatable(false);
jToolBar6.setRollover(true);
jToolBar6.setMinimumSize(new java.awt.Dimension(1, 1));
jToolBar6.setPreferredSize(new java.awt.Dimension(1, 25));
sustain.setText("Sustain");
sustain.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
sustainItemStateChanged(evt);
}
});
jToolBar6.add(sustain);
loop.setText("Loop");
loop.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
loopItemStateChanged(evt);
}
});
jToolBar6.add(loop);
attenuation.setText("Attenuation");
attenuation.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
attenuationItemStateChanged(evt);
}
});
jToolBar6.add(attenuation);
jToolBar6.add(filler4);
jLabel4.setText("Zoom:");
jToolBar6.add(jLabel4);
zoom.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "1:1", "1:2", "1:4", "1:8", "1:16", "1:32", "1:64", "1:128" }));
zoom.setMaximumSize(new java.awt.Dimension(128, 32767));
zoom.setMinimumSize(new java.awt.Dimension(128, 20));
zoom.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
zoomItemStateChanged(evt);
}
});
jToolBar6.add(zoom);
jButton4.setIcon(new javax.swing.ImageIcon(getClass().getResource("/play.png"))); // NOI18N
jButton4.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton4ActionPerformed(evt);
}
});
jToolBar6.add(jButton4);
jButton5.setIcon(new javax.swing.ImageIcon(getClass().getResource("/stop.png"))); // NOI18N
jButton5.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton5ActionPerformed(evt);
}
});
jToolBar6.add(jButton5);
jButton6.setIcon(new javax.swing.ImageIcon(getClass().getResource("/keyup.png"))); // NOI18N
jButton6.setToolTipText("Key up");
jButton6.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton6ActionPerformed(evt);
}
});
jToolBar6.add(jButton6);
jToolBar6.add(filler7);
javax.swing.GroupLayout samplesTabLayout = new javax.swing.GroupLayout(samplesTab);
samplesTab.setLayout(samplesTabLayout);
samplesTabLayout.setHorizontalGroup(
samplesTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jToolBar3, javax.swing.GroupLayout.DEFAULT_SIZE, 628, Short.MAX_VALUE)
.addComponent(jToolBar6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, samplesTabLayout.createSequentialGroup()
.addContainerGap()
.addComponent(samplesPane)
.addContainerGap())
);
samplesTabLayout.setVerticalGroup(
samplesTabLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(samplesTabLayout.createSequentialGroup()
.addComponent(jToolBar3, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jToolBar6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(samplesPane, javax.swing.GroupLayout.DEFAULT_SIZE, 514, Short.MAX_VALUE)
.addContainerGap())
);
tabs.addTab("Samples", samplesTab);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tabs, javax.swing.GroupLayout.DEFAULT_SIZE, 633, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tabs, javax.swing.GroupLayout.DEFAULT_SIZE, 615, Short.MAX_VALUE)
);
}// </editor-fold>//GEN-END:initComponents
private void addPatternActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addPatternActionPerformed
music.addPattern(4);
int size = music.song.patterns.size();
String name = "Verse " + size;
int idx = size - 1;
music.song.patterns.get(idx).name = name;
pattern.addItem(name);
pattern.setSelectedIndex(idx);
updatePattern();
}//GEN-LAST:event_addPatternActionPerformed
private void patternItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_patternItemStateChanged
currentPatternIdx = pattern.getSelectedIndex();
updatePattern();
}//GEN-LAST:event_patternItemStateChanged
private void tableViewMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tableViewMouseClicked
evt.consume();
if (evt.getClickCount() == 2) {
editNote();
}
}//GEN-LAST:event_tableViewMouseClicked
private void tableViewKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_tableViewKeyTyped
evt.consume();
enterNote(evt.getKeyChar());
}//GEN-LAST:event_tableViewKeyTyped
private void removePatternActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removePatternActionPerformed
if (!JF.showConfirm("Delete Pattern?", "Are you sure?")) return;
music.removePattern(currentPatternIdx);
if (music.song.patterns.size() == 0) {
music.addPattern(4);
}
updatePattern();
}//GEN-LAST:event_removePatternActionPerformed
private void jButton7ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton7ActionPerformed
music.addTrack(currentPatternIdx);
updatePattern();
}//GEN-LAST:event_jButton7ActionPerformed
private void jButton8ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton8ActionPerformed
int col = tableView.getSelectedColumn();
if (col == -1) {
JF.showError("Notice", "Select a track to delete");
return;
}
if (col == 0) return;
if (!JF.showConfirm("Delete Track?", "Are you sure?")) return;
music.removeTrack(currentPatternIdx, col - 1);
updatePattern();
}//GEN-LAST:event_jButton8ActionPerformed
private void seqAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_seqAddActionPerformed
int idx = seqPattern.getSelectedIndex();
if (idx == -1) return;
music.song.sequence.add(idx);
updateSequenceList();
}//GEN-LAST:event_seqAddActionPerformed
private void seqRemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_seqRemoveActionPerformed
int idx = sequence.getSelectedIndex();
if (idx == -1) {
JF.showError("Notice", "Select a sequence to delete");
return;
}
// if (!JF.showConfirm("Delete Sequence?", "Are you sure?")) return;
music.song.sequence.remove(idx);
updateSequenceList();
}//GEN-LAST:event_seqRemoveActionPerformed
private void seqUpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_seqUpActionPerformed
int idx = sequence.getSelectedIndex();
if (idx <= 0) return;
Integer top = music.song.sequence.get(idx-1);
Integer bot = music.song.sequence.get(idx);
music.song.sequence.set(idx-1, bot);
music.song.sequence.set(idx, top);
updateSequenceList();
sequence.setSelectedIndex(idx-1);
}//GEN-LAST:event_seqUpActionPerformed
private void seqDownActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_seqDownActionPerformed
int idx = sequence.getSelectedIndex();
if (idx == -1) return;
if (idx == music.song.sequence.size() - 1) return;
Integer top = music.song.sequence.get(idx);
Integer bot = music.song.sequence.get(idx+1);
music.song.sequence.set(idx, bot);
music.song.sequence.set(idx+1, top);
updateSequenceList();
sequence.setSelectedIndex(idx+1);
}//GEN-LAST:event_seqDownActionPerformed
private void tableViewKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_tableViewKeyPressed
evt.consume();
int row = tableView.getSelectedRow();
int col = tableView.getSelectedColumn();
if (row == -1 || col == -1) return;
if (row == 0) return;
TableCell cell = null;
if (col > 0) cell = (TableCell)tableView.getValueAt(row, col);
int cnt = -1, sel = -1;
if (evt.getModifiers() == 0) {
switch(evt.getKeyCode()) {
case KeyEvent.VK_ESCAPE:
if (recording) recordStop();
break;
case KeyEvent.VK_DELETE:
enterNote(' ');
break;
case KeyEvent.VK_ENTER:
editNote();
break;
case KeyEvent.VK_UP:
if (row == 1) break;
if (col > 0) sel = cell.getSelection();
row--;
if (col > 0) ((TableCell)tableView.getValueAt(row, col)).setSelection(sel);
break;
case KeyEvent.VK_DOWN:
if (row == tableView.getRowCount() - 1) break;
if (col > 0) sel = cell.getSelection();
row++;
if (col > 0) ((TableCell)tableView.getValueAt(row, col)).setSelection(sel);
break;
case KeyEvent.VK_LEFT:
if (col == 0) break;
if (cell == null) break; //should not happen
sel = cell.getSelection();
if (sel == 0) {
col--;
if (col > 0) {
cell = (TableCell)tableView.getValueAt(row, col);
cell.setSelection(2);
}
} else {
cell.setSelection(sel-1);
}
break;
case KeyEvent.VK_RIGHT:
cnt = tableView.getColumnCount();
if (cell == null) {
if (col == cnt-1) break;
col++;
break;
}
sel = cell.getSelection();
if (sel == 2) {
if (col == cnt-1) break;
col++;
cell = (TableCell)tableView.getValueAt(row, col);
cell.setSelection(0);
} else {
cell.setSelection(sel+1);
}
break;
}
}
if (col > 1 && evt.getModifiers() == KeyEvent.CTRL_MASK) {
Music.Track track = music.song.patterns.get(currentPatternIdx).tracks.get(col-1);
switch(evt.getKeyCode()) {
case KeyEvent.VK_C:
//copy note/vol/fx
cbNote = track.notes[row-1];
cbVolCmd = track.volcmds[row-1];
cbVolParam = track.volparams[row-1];
cbFXCmd = track.fxcmds[row-1];
cbFXParam = track.fxparams[row-1];
break;
case KeyEvent.VK_V:
//paste note/vol/fx
track.notes[row-1] = cbNote;
track.volcmds[row-1] = cbVolCmd;
track.volparams[row-1] = cbVolParam;
track.fxcmds[row-1] = cbFXCmd;
track.fxparams[row-1] = cbFXParam;
updatePattern();
break;
}
}
tableView.changeSelection(row, col, false, false);
// tableView.scrollRectToVisible(tableView.getCellRect(row, col, true));
tableView.repaint();
}//GEN-LAST:event_tableViewKeyPressed
private void tableViewKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_tableViewKeyReleased
evt.consume();
}//GEN-LAST:event_tableViewKeyReleased
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
musicStart();
music.playPattern(currentPatternIdx);
}//GEN-LAST:event_jButton2ActionPerformed
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
if (recording)
recordStop();
else
music.stopMusic();
if (exporting) {
musicEnded();
}
}//GEN-LAST:event_jButton3ActionPerformed
private void bpmStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_bpmStateChanged
if (currentPatternIdx == -1) return;
music.song.patterns.get(currentPatternIdx).bpm = (Integer)bpm.getValue();
}//GEN-LAST:event_bpmStateChanged
private void jButton6ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton6ActionPerformed
if (soundIdx != -1) {
music.channelKeyUp(soundIdx);
// soundIdx = -1; //may still have a loop
}
}//GEN-LAST:event_jButton6ActionPerformed
private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton5ActionPerformed
if (soundIdx != -1) {
music.channelStop(soundIdx);
soundIdx = -1;
}
}//GEN-LAST:event_jButton5ActionPerformed
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton4ActionPerformed
if (currentSampleIdx == -1) return;
musicStart();
if (soundIdx != -1) {
music.channelStop(soundIdx);
soundIdx = -1;
}
soundIdx = music.samplePlay(currentSampleIdx, 1.0f, 1.0f);
}//GEN-LAST:event_jButton4ActionPerformed
private void zoomItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_zoomItemStateChanged
samples.revalidate();
samples.repaint();
}//GEN-LAST:event_zoomItemStateChanged
private void iAddFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_iAddFileActionPerformed
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.addChoosableFileFilter(new FileNameExtensionFilter("WAV", "wav"));
chooser.setFileFilter(chooser.getChoosableFileFilters()[1]); //use first added filefilter added
chooser.setMultiSelectionEnabled(false);
chooser.setCurrentDirectory(new File(MainPanel.currentPath));
if (chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) return;
int iidx = music.song.instruments.size();
int sidx = music.song.samples.size();
String name = "Instrument " + (iidx+1);
music.addInstrument(name);
music.addRegion(iidx, 0, 0x7f, 0x3c, sidx);
if (!music.addSamples(name + "_" + 0, chooser.getSelectedFile().getAbsolutePath(), -1, -1, -1, -1, 0.0f)) {
JF.showError("Error", "Failed to load wav file");
return;
}
updateSamples();
sample.setSelectedIndex(sidx);
updateSample();
updateInstruments();
instrument.setSelectedIndex(iidx);
updateInstrument();
}//GEN-LAST:event_iAddFileActionPerformed
private void iAddLibraryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_iAddLibraryActionPerformed
String name = (String)library.getSelectedItem();
if (name == null) return;
int libidx = library.getSelectedIndex();
if (libidx == -1) return;
Library.Entry entry = Library.get(libidx);
int iidx = music.song.instruments.size();
int sidx = music.song.samples.size();
switch (entry.type) {
case WAV:
music.addInstrument(name);
music.addRegion(iidx, 0, 0x7f, 0x3c, sidx);
if (!music.addSamples(name + "_" + 0, entry.fullPath, -1, -1, -1, -1, 0.0f)) {
JF.showError("Error", "Failed to load wav file");
break;
}
break;
case DLS:
DLS dls = Library.getDLS(entry.dls_idx);
music.addInstrument(name);
int cnt = dls.getRegionsCount(name);
for(int a=0;a<cnt;a++) {
DLS.Instrument i = dls.getInstrument(name, a);
if (i == null) return;
int susStart = -1, susEnd = -1;
if (i.loopStart != -1) {
susStart = i.loopStart;
susEnd = i.loopStart + i.loopLength;
}
DLS.Region region = dls.getRegion(name, a);
music.addRegion(iidx, region.keyMin, region.keyMax, region.unityNote, sidx + a);
float attenuation = 0.0f; //region.attenuation; //TODO???
if (!music.addSamples(name + " " + (sidx+a), i.samples, -1, -1, susStart, susEnd, attenuation)) {
JF.showError("Error", "Failed to load wav file");
break;
}
}
break;
}
updateSamples();
sample.setSelectedIndex(sidx);
updateSample();
updateInstruments();
instrument.setSelectedIndex(iidx);
updatePattern();
}//GEN-LAST:event_iAddLibraryActionPerformed
private void iRemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_iRemoveActionPerformed
if (currentInstrumentIdx == -1) return;
if (!JF.showConfirm("Delete Instrument?", "Are you sure?")) return;
music.removeInstrument(currentInstrumentIdx);
currentInstrumentIdx = -1;
updateInstruments();
updatePattern();
}//GEN-LAST:event_iRemoveActionPerformed
private void instrumentItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_instrumentItemStateChanged
if (currentInstrumentIdx != -1) {
saveInstrument();
}
currentInstrumentIdx = instrument.getSelectedIndex();
updateInstrument();
}//GEN-LAST:event_instrumentItemStateChanged
private void loopItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_loopItemStateChanged
if (loop.isSelected()) {
if (samples.sample == null) {
loop.setSelected(false);
return;
}
if (samples.loopStart == -1) {
int length = samples.sample.samples.length-1;
samples.loopStart = (int)(length * 0.10f);
samples.loopEnd = (int)(length * 0.90f);
}
} else {
if (samples.sample == null) return;
// samples.loopStart = -1;
// samples.loopEnd = -1;
}
samples.showLoop = loop.isSelected();
samples.repaint();
}//GEN-LAST:event_loopItemStateChanged
private void sustainItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_sustainItemStateChanged
if (sustain.isSelected()) {
if (samples.sample == null) {
sustain.setSelected(false);
return;
}
if (samples.sustainStart == -1) {
int length = samples.sample.samples.length-1;
samples.sustainStart = (int)(length * 0.05f);
samples.sustainEnd = (int)(length * 0.95f);
}
} else {
if (samples.sample == null) return;
// samples.sustainStart = -1;
// samples.sustainEnd = -1;
}
samples.showSustain = sustain.isSelected();
samples.repaint();
}//GEN-LAST:event_sustainItemStateChanged
private void attenuationItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_attenuationItemStateChanged
samples.showAttenuation = attenuation.isSelected();
samples.repaint();
}//GEN-LAST:event_attenuationItemStateChanged
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
if (recording)
recordStop();
else
recordStart();
}//GEN-LAST:event_jButton1ActionPerformed
private void bpmKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_bpmKeyTyped
if (currentPatternIdx == -1) return;
music.song.patterns.get(currentPatternIdx).bpm = (Integer)bpm.getValue();
}//GEN-LAST:event_bpmKeyTyped
private void jButton10ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton10ActionPerformed
if (currentPatternIdx == -1) return;
String newName = JF.getString("Edit Name", (String)pattern.getSelectedItem());
if (newName == null) return;
music.song.patterns.get(currentPatternIdx).name = newName;
int idx = currentPatternIdx;
updatePatterns();
pattern.setSelectedIndex(idx);
updateSequence();
updateSequenceList();
}//GEN-LAST:event_jButton10ActionPerformed
private void jButton9ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton9ActionPerformed
if (currentInstrumentIdx == -1) return;
String newName = JF.getString("Edit Name", (String)instrument.getSelectedItem());
if (newName == null) return;
music.song.instruments.get(currentInstrumentIdx).name = newName;
int idx = currentInstrumentIdx;
updateInstruments();
instrument.setSelectedIndex(idx);
updatePattern();
}//GEN-LAST:event_jButton9ActionPerformed
private void sequenceValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_sequenceValueChanged
currentSequenceIdx = sequence.getSelectedIndex();
}//GEN-LAST:event_sequenceValueChanged
private void jButton11ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton11ActionPerformed
//move pattern up
if (currentPatternIdx <= 0) return;
if (music.song.patterns.size() < 2) return;
Music.Pattern pat = music.song.patterns.remove(currentPatternIdx);
music.song.patterns.add(currentPatternIdx - 1, pat);
//update sequence
for(int a=0;a<music.song.sequence.size();a++) {
int idx = music.song.sequence.get(a);
if (idx == currentPatternIdx) {
music.song.sequence.set(a, idx - 1);
} else if (idx == currentPatternIdx - 1) {
music.song.sequence.set(a, idx + 1);
}
}
int idx = currentPatternIdx - 1;
updatePatterns();
pattern.setSelectedIndex(idx);
updatePattern();
updateSequenceList();
updateSequence();
}//GEN-LAST:event_jButton11ActionPerformed
private void jButton12ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton12ActionPerformed
//move pattern down
if (currentPatternIdx == -1) return;
int patSize = music.song.patterns.size();
if (patSize < 2) return;
if (currentPatternIdx == patSize-1) return;
Music.Pattern pat = music.song.patterns.remove(currentPatternIdx);
music.song.patterns.add(currentPatternIdx + 1, pat);
//update sequence
for(int a=0;a<music.song.sequence.size();a++) {
int idx = music.song.sequence.get(a);
if (idx == currentPatternIdx) {
music.song.sequence.set(a, idx + 1);
} else if (idx == currentPatternIdx + 1) {
music.song.sequence.set(a, idx - 1);
}
}
int idx = currentPatternIdx + 1;
updatePatterns();
pattern.setSelectedIndex(idx);
updatePattern();
updateSequenceList();
updateSequence();
}//GEN-LAST:event_jButton12ActionPerformed
private void sampleItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_sampleItemStateChanged
if (currentSampleIdx != -1) {
saveSample();
}
currentSampleIdx = sample.getSelectedIndex();
updateSample();
}//GEN-LAST:event_sampleItemStateChanged
private void jButton13ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton13ActionPerformed
if (currentInstrumentIdx == -1) return;
EditRegion dialog = new EditRegion(null, true, music.song.instruments.get(currentInstrumentIdx).regions.get(currentRegionIdx), music, true);
dialog.setVisible(true);
updateInstrument();
}//GEN-LAST:event_jButton13ActionPerformed
private void regionsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_regionsItemStateChanged
currentRegionIdx = regions.getSelectedIndex();
}//GEN-LAST:event_regionsItemStateChanged
private void jButton14ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton14ActionPerformed
if (currentInstrumentIdx == -1) return;
Music.Region region = new Music.Region();
EditRegion dialog = new EditRegion(null, true, region, music, false);
dialog.setVisible(true);
if (!dialog.accepted) return;
music.song.instruments.get(currentInstrumentIdx).regions.add(region);
updateInstrument();
}//GEN-LAST:event_jButton14ActionPerformed
private void jButton15ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton15ActionPerformed
if (currentInstrumentIdx == -1) return;
if (currentRegionIdx == -1) return;
if (!JF.showConfirm("Delete Region?", "Are you sure?")) return;
music.song.instruments.get(currentInstrumentIdx).regions.remove(currentRegionIdx);
updateInstrument();
}//GEN-LAST:event_jButton15ActionPerformed
private void jButton16ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton16ActionPerformed
if (currentSampleIdx == -1) return;
String newName = JF.getString("Edit Name", music.song.samples.get(currentSampleIdx).name);
if (newName == null) return;
music.song.samples.get(currentSampleIdx).name = newName;
updateSamples();
updateSample();
}//GEN-LAST:event_jButton16ActionPerformed
private void jButton18ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton18ActionPerformed
if (currentSampleIdx == -1) return;
if (!JF.showConfirm("Delete Sample?", "Are you sure?")) return;
music.removeSamples(currentSampleIdx);
updateSamples();
updateSample();
}//GEN-LAST:event_jButton18ActionPerformed
private void jButton17ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton17ActionPerformed
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.addChoosableFileFilter(new FileNameExtensionFilter("WAV", "wav"));
chooser.setFileFilter(chooser.getChoosableFileFilters()[1]); //use first added filefilter added
chooser.setMultiSelectionEnabled(false);
chooser.setCurrentDirectory(new File(MainPanel.currentPath));
if (chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) return;
int sidx = music.song.samples.size();
File file = chooser.getSelectedFile();
String name = file.getName();
if (name.toLowerCase().endsWith(".wav")) {
name = name.substring(0, name.length() - 4);
}
if (!music.addSamples(name, file.getAbsolutePath(), -1, -1, -1, -1, 0.0f)) {
JF.showError("Error", "Failed to load wav file");
return;
}
updateSamples();
sample.setSelectedIndex(sidx);
updateSample();
}//GEN-LAST:event_jButton17ActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton addPattern;
private javax.swing.JCheckBox attenuation;
private javax.swing.JSpinner bpm;
private javax.swing.JTextArea comment;
private javax.swing.Box.Filler filler1;
private javax.swing.Box.Filler filler10;
private javax.swing.Box.Filler filler11;
private javax.swing.Box.Filler filler2;
private javax.swing.Box.Filler filler3;
private javax.swing.Box.Filler filler4;
private javax.swing.Box.Filler filler5;
private javax.swing.Box.Filler filler6;
private javax.swing.Box.Filler filler7;
private javax.swing.Box.Filler filler8;
private javax.swing.Box.Filler filler9;
private javax.swing.JPanel generalTab;
private javax.swing.JButton iAddFile;
private javax.swing.JButton iAddLibrary;
private javax.swing.JButton iRemove;
private javax.swing.JPanel instrTab;
private javax.swing.JComboBox instrument;
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton10;
private javax.swing.JButton jButton11;
private javax.swing.JButton jButton12;
private javax.swing.JButton jButton13;
private javax.swing.JButton jButton14;
private javax.swing.JButton jButton15;
private javax.swing.JButton jButton16;
private javax.swing.JButton jButton17;
private javax.swing.JButton jButton18;
private javax.swing.JButton jButton2;
private javax.swing.JButton jButton3;
private javax.swing.JButton jButton4;
private javax.swing.JButton jButton5;
private javax.swing.JButton jButton6;
private javax.swing.JButton jButton7;
private javax.swing.JButton jButton8;
private javax.swing.JButton jButton9;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel11;
private javax.swing.JLabel jLabel13;
private javax.swing.JLabel jLabel14;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JLabel jLabel6;
private javax.swing.JLabel jLabel7;
private javax.swing.JLabel jLabel8;
private javax.swing.JLabel jLabel9;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane3;
private javax.swing.JScrollPane jScrollPane4;
private javax.swing.JToolBar jToolBar1;
private javax.swing.JToolBar jToolBar2;
private javax.swing.JToolBar jToolBar3;
private javax.swing.JToolBar jToolBar4;
private javax.swing.JToolBar jToolBar5;
private javax.swing.JToolBar jToolBar6;
private javax.swing.JToolBar jToolBar7;
private javax.swing.JComboBox library;
private javax.swing.JCheckBox loop;
private javax.swing.JTextField name;
private javax.swing.ButtonGroup noteTypes;
private javax.swing.JComboBox pattern;
private javax.swing.JPanel patternsTab;
private javax.swing.JComboBox regions;
private javax.swing.JButton removePattern;
private javax.swing.JComboBox sample;
private javax.swing.JScrollPane samplesPane;
private javax.swing.JPanel samplesTab;
private javax.swing.JButton seqAdd;
private javax.swing.JButton seqDown;
private javax.swing.JComboBox seqPattern;
private javax.swing.JButton seqRemove;
private javax.swing.JPanel seqTab;
private javax.swing.JButton seqUp;
private javax.swing.JList sequence;
private javax.swing.JCheckBox sustain;
private javax.swing.JTable tableView;
private javax.swing.JTabbedPane tabs;
private javax.swing.JComboBox zoom;
// End of variables declaration//GEN-END:variables
private DefaultTableModel tableModel = new DefaultTableModel() {
public boolean isCellEditable(int row,int col) {
if (row == 0 && col > 0) return true;
return false;
}
public void setValueAt(Object value,int row,int col) {
if (value == null) return;
if (row == 0) {
//DefaultCellEditor assumes entry was a string, so instead of a combobox
JComboBox cb = (JComboBox)tableView.getValueAt(row, col);
String str = (String)value;
int idx = JF.atox(str.substring(0, 2));
cb.setSelectedIndex(idx);
music.song.patterns.get(currentPatternIdx).tracks.get(col-1).startInstrument = (byte)idx;
} else {
super.setValueAt(value, row, col);
}
}
};
private DefaultTableColumnModel colModel; // = new DefaultTableColumnModel();
private Music music;
private int currentPatternIdx = -1;
private int currentSequenceIdx = -1;
private int currentInstrumentIdx = -1;
private int currentRegionIdx = -1;
private int currentSampleIdx = -1;
private Samples samples;
private String filename;
private int soundIdx = -1;
private byte cbNote = -1, cbVolCmd, cbFXCmd;
private int cbVolParam, cbFXParam;
private MidiDevice midi;
private Transmitter trans;
private java.util.Timer timer;
private boolean recording;
private boolean recordingStarted;
private boolean exporting;
private MediaEncoder ffmpeg;
private RandomAccessFile exportFile;
private void reset() {
music = new Music();
music.reset();
repaint();
updatePatterns();
updatePattern();
}
private void updatePatterns() {
currentPatternIdx = -1;
pattern.removeAllItems();
int size = music.song.patterns.size();
for(int a=0;a<size;a++) {
pattern.addItem(music.song.patterns.get(a).name);
}
}
private void updateSequence() {
int idx = seqPattern.getSelectedIndex();
seqPattern.removeAllItems();
int cnt = pattern.getItemCount();
if (idx >= cnt) idx = cnt - 1;
for(int a=0;a<cnt;a++) {
seqPattern.addItem(music.song.patterns.get(a).name);
}
seqPattern.setSelectedIndex(idx);
}
private void updatePattern() {
updateSequence();
tableModel.setRowCount(0);
tableModel.setColumnCount(0);
tableView.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
if (currentPatternIdx >= music.song.patterns.size()) {
currentPatternIdx = music.song.patterns.size() - 1;
pattern.setSelectedIndex(currentPatternIdx);
}
if (currentPatternIdx == -1) {
bpm.setValue(80);
return;
}
Music.Pattern pattern = music.song.patterns.get(currentPatternIdx);
bpm.setValue(pattern.bpm);
int cnt = pattern.tracks.size();
tableModel.setColumnCount(1 + cnt);
ArrayList<Object> row = new ArrayList<Object>();
row.clear();
TableColumn col;
col = colModel.getColumn(0);
// col.setCellRenderer(new SimpleTableCellRenderer());
// col.setHeaderRenderer(new SimpleTableCellRenderer());
// col.setHeaderValue(null);
row.add("");
for(int t=0;t<cnt;t++) {
Music.Track track = pattern.tracks.get(t);
col = colModel.getColumn(t+1);
col.setCellRenderer(new SimpleTableCellRenderer());
// col.setHeaderRenderer(new SimpleTableCellRenderer());
// col.setHeaderValue(new JComboBox());
row.add(getTrackInstruments(track));
}
tableModel.addRow(row.toArray());
for(int r=0;r<64;r++) {
row.clear();
row.add(String.format("%02d", r));
for(int t=0;t<cnt;t++) {
Music.Track track = pattern.tracks.get(t);
row.add(new TableCell(getNoteVolFX(track, r)));
}
tableModel.addRow(row.toArray());
}
setTableWidths();
tableView.repaint();
}
private void updateCell() {
int col = tableView.getSelectedColumn();
int row = tableView.getSelectedRow();
if (col <= 0) return;
if (row <= 0) return;
if (currentPatternIdx == -1) return;
Music.Track track = music.song.patterns.get(currentPatternIdx).tracks.get(col-1);
Object obj = new TableCell(getNoteVolFX(track, row-1));
tableView.setValueAt(obj, row, col);
tableView.repaint();
}
private String getNoteVolFX(Music.Track track, int row) {
return getNote(track.notes[row]) + " "
+ getVolCmd(track.volcmds[row]) //+ getHexParam(track.volparams[r])
+ " "
+ getFXCmd(track.fxcmds[row]); //+ getHexParam(track.fxparams[r])
}
private String keys[] = {"C-", "C#", "D-", "D#", "E-", "F-", "F#", "G-", "G#", "A-", "A#", "B-"};
private String getNote(byte note) {
if (note == -1) {
return "...";
}
int octave = note / 12;
int key = note % 12;
return keys[key] + octave;
}
private String getVolCmd(int value) {
switch (value) {
case Music.VOLCMD_NONE: return "..";
case Music.VOLCMD_SET_VOLUME: return "sv";
case Music.VOLCMD_SET_VOL_VIBRATE_SPEED: return "vv";
case Music.VOLCMD_SET_PAN_VIBRATE_SPEED: return "vp";
case Music.VOLCMD_TREMOLO: return "tr";
case Music.VOLCMD_PANBRELLO: return "pa";
case Music.VOLCMD_SET_PANNING: return "sp";
case Music.VOLCMD_SLIDE: return "vs";
case Music.VOLCMD_PAN_SLIDE: return "ps";
}
return "??";
}
private String getFXCmd(int value) {
switch (value) {
case Music.FXCMD_NONE: return "..";
case Music.FXCMD_PORTAMENTO_TO_NOTE: return "pn";
case Music.FXCMD_SET_VIBRATE_SPEED: return "vs";
case Music.FXCMD_VIBRATO: return "vb";
case Music.FXCMD_PORTAMENTO: return "po";
case Music.FXCMD_TREMOR: return "tr";
case Music.FXCMD_SET_INSTRUMENT: return "si";
case Music.FXCMD_DELAY_START: return "ds";
case Music.FXCMD_SAMPLE_OFFSET: return "so";
case Music.FXCMD_SET_BPM: return "sm";
case Music.FXCMD_KEY_OFF: return "ko";
case Music.FXCMD_PATTERN_BREAK: return "pb";
}
return "??";
}
private String getHexParam(int value) {
//or float ???
if (value == 0) return "........";
return String.format("%08x", value);
}
private void setTableWidths() {
int cnt = colModel.getColumnCount();
for(int a=0;a<cnt;a++) {
TableColumn col = colModel.getColumn(a);
int width = 25;
if (a > 0) width = 100;
col.setResizable(false);
col.setMinWidth(width);
col.setMaxWidth(width);
col.setPreferredWidth(width);
}
}
private void editNote() {
int col = tableView.getSelectedColumn();
if (col <= 0) return;
int row = tableView.getSelectedRow();
if (row <= 0) return;
row--; col--;
if (currentPatternIdx == -1) return;
Music.Pattern pattern = music.song.patterns.get(currentPatternIdx);
Music.Track track = pattern.tracks.get(col);
EditNote dialog = new EditNote(null, true, track.notes[row]
,track.volcmds[row], track.volparams[row]
,track.fxcmds[row], track.fxparams[row], music);
dialog.setVisible(true);
if (dialog.accepted) {
track.notes[row] = dialog.note;
track.volcmds[row] = dialog.volcmd;
track.volparams[row] = dialog.volparam;
track.fxcmds[row] = dialog.fxcmd;
track.fxparams[row] = dialog.fxparam;
updatePattern();
tableView.repaint();
}
}
private void updateSequenceList() {
ArrayList<String> list = new ArrayList<String>();
int cnt = music.song.sequence.size();
for(int a=0;a<cnt;a++) {
int idx = music.song.sequence.get(a);
list.add("" + a + music.song.patterns.get(idx).name);
}
sequence.setListData(list.toArray(new String[0]));
}
private void updateInstruments() {
saveInstrument();
int idx = currentInstrumentIdx;
currentInstrumentIdx = -1;
instrument.removeAllItems();
int cnt = music.song.instruments.size();
if (cnt == 0) {
return;
}
for(int a=0;a<cnt;a++) {
instrument.addItem(music.song.instruments.get(a).name);
}
if (idx != -1) instrument.setSelectedIndex(idx);
}
private char row1[] = {'q' ,'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']'};
private char row2[] = {'a' ,'s', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '\r'};
private char row3[] = {'z' ,'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', '?', '?'};
private void enterNote(char ch) {
int row = tableView.getSelectedRow();
int col = tableView.getSelectedColumn();
if (row <= 0) return;
if (col <= 0) return;
if (currentPatternIdx == -1) return;
TableCell cell = (TableCell)tableView.getValueAt(row, col);
int sel = cell.getSelection();
Music.Track track = music.song.patterns.get(currentPatternIdx).tracks.get(col-1);
switch (sel) {
case 0: //note
byte newnote = -2;
if (ch == ' ') {
newnote = -1;
} else if (ch >= '0' && ch <= '9') {
//change octave (if there is a note)
if (track.notes[row-1] == -1) break;
int octave = (ch - '0') * 12;
int key = track.notes[row-1] % 12;
track.notes[row-1] = (byte)(octave + key);
} else {
for(int a=0;a<12;a++) {
if (row1[a] == ch) {
newnote = (byte)((3 * 12) + a);
break;
}
else if (row2[a] == ch) {
newnote = (byte)((4 * 12) + a);
break;
}
else if (row3[a] == ch) {
newnote = (byte)((5 * 12) + a);
break;
}
}
}
if (newnote != -2) track.notes[row-1] = newnote;
break;
case 1: //volcmd
if (ch == ' ') {
track.volcmds[row-1] = 0;
track.volparams[row-1] = 0;
}
/* if (ch >= '0' && ch <= '9') {
track.volcmds[row-1] <<= 4;
track.volcmds[row-1] |= (ch - '0');
}
else if (ch >= 'a' && ch <= 'f') {
track.volcmds[row-1] <<= 4;
track.volcmds[row-1] |= (ch - 'a' + 10);
}
*/
break;
/*
case 2: //volparam
if (ch >= '0' && ch <= '9') {
track.volparams[row-1] <<= 4;
track.volparams[row-1] |= (ch - '0');
}
else if (ch >= 'a' && ch <= 'f') {
track.volparams[row-1] <<= 4;
track.volparams[row-1] |= (ch - 'a' + 10);
}
break;
*/
case 2: //fxcmd
if (ch == ' ') {
track.fxcmds[row-1] = 0;
track.fxparams[row-1] = 0;
}
/*
if (ch >= '0' && ch <= '9') {
track.fxcmds[row-1] <<= 4;
track.fxcmds[row-1] |= (ch - '0');
}
else if (ch >= 'a' && ch <= 'f') {
track.fxcmds[row-1] <<= 4;
track.fxcmds[row-1] |= (ch - 'a' + 10);
}
*/
break;
/*
case 4: //fxparam
if (ch >= '0' && ch <= '9') {
track.fxparams[row-1] <<= 4;
track.fxparams[row-1] |= (ch - '0');
}
else if (ch >= 'a' && ch <= 'f') {
track.fxparams[row-1] <<= 4;
track.fxparams[row-1] |= (ch - 'a' + 10);
}
break;
*/
}
updateCell();
cell = (TableCell)tableView.getValueAt(row, col);
cell.setSelection(sel);
}
public void selectTab(int idx) {
tabs.setSelectedIndex(idx);
}
private void updateInstrument() {
updateRegions();
}
private void saveInstrument() {
}
private void updateRegions() {
regions.removeAllItems();
if (currentInstrumentIdx == -1) return;
Music.Instrument i = music.song.instruments.get(currentInstrumentIdx);
if (i.regions == null) return; //beta file
for(int a=0;a<i.regions.size();a++) {
Music.Region r = i.regions.get(a);
regions.addItem("" + DLS.getKeyName(r.low) + " thru " + DLS.getKeyName(r.high));
}
}
private void updateSample() {
if (currentSampleIdx == -1) {
loop.setSelected(false);
sustain.setSelected(false);
attenuation.setSelected(false);
samples.setSample(null);
samplesPane.repaint();
return;
}
Music.Sample i = music.song.samples.get(currentSampleIdx);
samples.setSample(i);
samples.loopStart = i.loopStart;
samples.loopEnd = i.loopEnd;
loop.setSelected(i.loopStart != -1);
samples.sustainStart = i.sustainStart;
samples.sustainEnd = i.sustainEnd;
sustain.setSelected(i.sustainStart != -1);
samples.attenuation = i.attenuation;
attenuation.setSelected(i.attenuation > 0.0f);
samples.revalidate();
samples.repaint();
}
public void saveSample() {
if (currentSampleIdx == -1) return;
Music.Sample s = music.song.samples.get(currentSampleIdx);
if (loop.isSelected()) {
s.loopStart = samples.loopStart;
s.loopEnd = samples.loopEnd;
} else {
s.loopStart = -1;
s.loopEnd = -1;
}
if (sustain.isSelected()) {
s.sustainStart = samples.sustainStart;
s.sustainEnd = samples.sustainEnd;
} else {
s.sustainStart = -1;
s.sustainEnd = -1;
}
if (attenuation.isSelected())
s.attenuation = samples.attenuation;
else
s.attenuation = 0.0f;
}
public void updateSamples() {
saveSample();
int idx = currentSampleIdx;
currentSampleIdx = -1;
sample.removeAllItems();
int cnt = music.song.samples.size();
if (cnt == 0) {
return;
}
for(int a=0;a<cnt;a++) {
sample.addItem(music.song.samples.get(a).name);
}
if (idx != -1) sample.setSelectedIndex(idx);
}
public int getZoom() {
int idx = zoom.getSelectedIndex();
switch (idx) {
case 0: return 1;
case 1: return 2;
case 2: return 4;
case 3: return 8;
case 4: return 16;
case 5: return 32;
case 6: return 64;
case 7: return 128;
}
return -1;
}
public JComboBox getTrackInstruments(final Music.Track track) {
final JComboBox cb = new JComboBox();
int cnt = music.song.instruments.size();
if (cnt == 0) return cb;
for(int a=0;a<cnt;a++) {
cb.addItem(String.format("%02x", a) + ":" + music.song.instruments.get(a).name);
}
cb.setSelectedIndex(track.startInstrument);
cb.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e) {
track.startInstrument = (byte)cb.getSelectedIndex();
}
});
return cb;
}
private void loadLibrary() {
library.removeAllItems();
ArrayList<Library.Entry> list = Library.getList();
for(int a=0;a<list.size();a++) {
library.addItem(list.get(a).name);
}
}
public void playSong() {
musicStart();
music.playSong(false);
}
public void playPattern() {
musicStart();
music.setListener(this);
music.playSong(false);
}
public void stopSong() {
music.stopMusic();
if (exporting) {
musicEnded();
}
}
public void musicEnded() {
JFLog.log("musicEnded");
music.stop();
if (exporting) {
ffmpeg.stop();
try {
exportFile.close();
} catch (Exception e) {
JFLog.log(e);
}
exporting = false;
}
}
public void musicSamples(short samples[]) {
if (exporting) {
ffmpeg.addAudio(samples);
}
}
public void musicRow(int seq,int pat,int row) {
final int _seq = seq;
final int _pat = pat;
final int _row = row;
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
if (_seq != -1) {
if (currentSequenceIdx != _seq) {
sequence.setSelectedIndex(_seq);
}
}
if (_pat != -1) {
if (currentPatternIdx != _pat) {
pattern.setSelectedIndex(_pat);
}
}
tableView.changeSelection(_row+1, 0, false, false);
}
});
}
private DefaultCellEditor editor;
public TableCellEditor _getCellEditor(int row, int column) {
int col = tableView.convertColumnIndexToModel(column); //order of cols can change (not in this app though)
JComboBox cb = (JComboBox)tableView.getValueAt(row, col);
editor = new DefaultCellEditor(cb);
editor.setClickCountToStart(1);
return editor;
}
public Dimension getSamplesPaneSize() {
return new Dimension(samplesPane.getWidth(), samplesPane.getHeight());
}
public void updateGeneral() {
name.setText(music.song.name);
comment.setText(music.song.comment);
}
public boolean load(String fn) {
music = new Music();
filename = fn;
if (!music.load(fn)) return false;
updatePatterns();
updatePattern();
updateSequence();
updateSequenceList();
updateInstruments();
updateInstrument();
updateSamples();
updateSample();
updateGeneral();
return true;
}
public boolean save() {
if (filename == null) {
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.addChoosableFileFilter(new FileNameExtensionFilter("Music Projects (*.mproj)", "mproj"));
chooser.setFileFilter(chooser.getChoosableFileFilters()[1]); //use first added filefilter added
chooser.setMultiSelectionEnabled(false);
chooser.setCurrentDirectory(new File(MainPanel.currentPath));
if (chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) return false;
File file = chooser.getSelectedFile();
MainPanel.currentPath = file.getParent();
if (MainPanel.currentPath == null) MainPanel.currentPath = JF.getUserPath() + "/Music";
filename = file.getAbsolutePath();
if (!filename.toLowerCase().endsWith(".mproj")) filename += ".mproj";
}
String title;
title = filename;
int idx = title.indexOf(".mproj");
if (idx != -1) title = title.substring(0, idx);
idx = title.lastIndexOf("/");
if (idx != -1) title = title.substring(idx+1);
idx = title.lastIndexOf("\\");
if (idx != -1) title = title.substring(idx+1);
music.song.name = name.getText();
music.song.comment = comment.getText();
MainPanel.This.setTitle(this, title);
return music.save(filename);
}
public void closeSong() {
music.close();
}
private void musicStart() {
if (music.isRunning()) return;
music.start(20, 1);
music.setListener(this);
}
private void recordStart() {
notes.clear();
if (currentPatternIdx == -1) return;
pattern.setEnabled(false);
recordingStarted = false;
recording = true;
if (Settings.current.midiDevice.length() > 0) {
//open midi device for recording
loadMIDI(Settings.current.midiDevice);
}
int delay = (1000 * 60) / (Integer)bpm.getValue();
timer = new java.util.Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
recordBeat();
}
});
}
}, delay, delay);
}
private void recordStop() {
pattern.setEnabled(true);
recording = false;
if (timer != null) {
timer.cancel();
timer = null;
}
if (midi != null) {
midi.close();
midi = null;
}
}
private class Note {
int note;
boolean down;
int velocity;
}
private ArrayList<Note> notes = new ArrayList<Note>();
private Object notesLock = new Object();
private int noteTrack[] = new int[128]; //keep track of which track(col) note was played on
private void recordBeat() {
if (!recordingStarted) return;
int col = tableView.getSelectedColumn();
int row = tableView.getSelectedRow();
int colMax = tableModel.getColumnCount();
Note note;
int rcol = col;
while (!notes.isEmpty()) {
synchronized(notesLock) {
note = notes.remove(0);
}
if (note.down) {
Music.Track track = music.song.patterns.get(currentPatternIdx).tracks.get(rcol-1);
track.notes[row-1] = (byte)note.note;
track.fxcmds[row-1] = 0; //remove key off if set
noteTrack[note.note] = rcol;
} else {
Music.Track track = music.song.patterns.get(currentPatternIdx).tracks.get(noteTrack[note.note]-1);
track.fxcmds[row-1] = Music.FXCMD_KEY_OFF;
}
tableView.changeSelection(row, rcol, false, false);
updateCell();
if (note.down) rcol++;
if (rcol == colMax) break;
}
row++;
if (row == 64) {
//end recording
recordStop();
return;
}
tableView.changeSelection(row, col, false, false);
}
private void loadMIDI(String midiName) {
if (midi != null) {
midi.close();
midi = null;
}
MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
try {
if (infos == null) throw new Exception("no devices found");
for(int a=0;a<infos.length;a++) {
MidiDevice midiDevice = MidiSystem.getMidiDevice(infos[a]);
if (midiDevice.getMaxTransmitters() == 0) continue;
String name = infos[a].getName();
if (name.equals(midiName)) {
midi = midiDevice;
trans = midi.getTransmitter();
trans.setReceiver(this);
midi.open();
JFLog.log("selected device:" + midi + "," + trans);
return;
}
}
if (midi == null) return;
} catch (Exception e) {
JFLog.log(e);
return;
}
}
//Receiver.close() - do nothing
public void close() {}
//Receiver.send() - receive MIDI message
public void send(MidiMessage message, long timeStamp) {
if (!(message instanceof ShortMessage)) return;
//decode message
ShortMessage sm = (ShortMessage)message;
int cmd = sm.getCommand() & 0xff;
int d1 = sm.getData1() & 0x7f;
int d2 = sm.getData2() & 0x7f;
String cmdstr = null;
Note note = new Note();
switch (cmd) {
case 0x80: //note off
// note / velocity (zero)
cmdstr = "keyUp";
//d1 = key
note.note = d1;
note.down = false;
synchronized(notesLock) {
notes.add(note);
}
break;
case 0x90: //note on
// note / velocity (0-127)
cmdstr = "keyDn";
//d1 = note
//d2 = velocity
note.note = d1;
note.velocity = d2;
note.down = true;
synchronized(notesLock) {
notes.add(note);
}
if (!recordingStarted) recordingStarted = true;
// if (!velocity.isSelected()) d2 = 0x7f;
break;
case 0xb0: //control change
// control / value (0-127)
// controls : 1 = modulation : 7 = volume : 4a = ch1 : 47 = ch2 : 49 = ch3 : 48 = ch4
cmdstr = " ctrl";
break;
case 0xe0: //pitch wheel
cmdstr = "pitch";
// zero / value (0-127)
break;
}
JFLog.log(String.format("%s:%02x:%02x:%02x", cmdstr, cmd, d1, d2));
}
public void insertRow() {
int row = tableView.getSelectedRow();
int col = tableView.getSelectedColumn();
if (row <= 0) return;
if (col <= 0) return;
if (currentPatternIdx == -1) return;
row--;
col--;
Music.Pattern pat = music.song.patterns.get(currentPatternIdx);
int nTracks = pat.tracks.size();
for(int t=0;t<nTracks;t++) {
Music.Track track = pat.tracks.get(t);
for(int r=63;r>row;r--) {
track.notes[r] = track.notes[r-1];
track.volcmds[r] = track.volcmds[r-1];
track.volparams[r] = track.volparams[r-1];
track.fxcmds[r] = track.fxcmds[r-1];
track.fxparams[r] = track.fxparams[r-1];
}
track.notes[row] = -1;
track.volcmds[row] = 0;
track.volparams[row] = 0;
track.fxcmds[row] = 0;
track.fxparams[row] = 0;
}
updatePattern();
}
public void deleteRow() {
int row = tableView.getSelectedRow();
int col = tableView.getSelectedColumn();
if (row <= 0) return;
if (col <= 0) return;
row--;
col--;
if (currentPatternIdx == -1) return;
Music.Pattern pat = music.song.patterns.get(currentPatternIdx);
int nTracks = pat.tracks.size();
for(int t=0;t<nTracks;t++) {
Music.Track track = pat.tracks.get(t);
for(int r=row;r<64;r++) {
track.notes[r] = track.notes[r+1];
track.volcmds[r] = track.volcmds[r+1];
track.volparams[r] = track.volparams[r+1];
track.fxcmds[r] = track.fxcmds[r+1];
track.fxparams[r] = track.fxparams[r+1];
}
track.notes[63] = -1;
track.volcmds[63] = 0;
track.volparams[63] = 0;
track.fxcmds[63] = 0;
track.fxparams[63] = 0;
}
updatePattern();
}
public void dupPattern() {
if (currentPatternIdx == -1) return;
Music.Pattern oldpat = music.song.patterns.get(currentPatternIdx);
music.addPattern(oldpat.tracks.size());
int size = music.song.patterns.size();
String name = "Verse " + size;
int idx = size - 1;
Music.Pattern newpat = music.song.patterns.get(idx);
newpat.name = name;
newpat.bpm = oldpat.bpm;
int nTracks = oldpat.tracks.size();
for(int t=0;t<nTracks;t++) {
Music.Track oldtrack = oldpat.tracks.get(t);
Music.Track newtrack = newpat.tracks.get(t);
for(int r=0;r<64;r++) {
newtrack.notes[r] = oldtrack.notes[r];
newtrack.volcmds[r] = oldtrack.volcmds[r];
newtrack.volparams[r] = oldtrack.volparams[r];
newtrack.fxcmds[r] = oldtrack.fxcmds[r];
newtrack.fxparams[r] = oldtrack.fxparams[r];
}
}
pattern.addItem(name);
pattern.setSelectedIndex(idx);
updatePattern();
}
public void export() {
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
FileNameExtensionFilter wav = new FileNameExtensionFilter("WAV (*.wav)", "wav");
JFLog.log("wav=" + wav);
chooser.addChoosableFileFilter(wav);
FileNameExtensionFilter mp3 = new FileNameExtensionFilter("MP3 (*.mp3)", "mp3");
JFLog.log("mp3=" + mp3);
chooser.addChoosableFileFilter(mp3);
chooser.setFileFilter(chooser.getChoosableFileFilters()[1]); //use first added filefilter added
chooser.setMultiSelectionEnabled(false);
chooser.setCurrentDirectory(new File(MainPanel.currentPath));
if (chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) return;
String file = chooser.getSelectedFile().getAbsolutePath();
String ext;
int idx = file.lastIndexOf('.');
if (idx == -1) {
JFLog.log("fileFilter=" + chooser.getFileFilter());
if (chooser.getFileFilter() == wav) {
file += ".wav";
ext = "wav";
} else if (chooser.getFileFilter() == mp3) {
ext = "mp3";
file += ".mp3";
} else {
//assume wav
file += ".wav";
ext = "wav";
}
} else {
ext = file.substring(idx+1).toLowerCase();
if (!ext.equals("wav") && !ext.equals("mp3")) {
//add ext
JFLog.log("fileFilter=" + chooser.getFileFilter());
if (chooser.getFileFilter() == wav) {
ext = "wav";
file += ".wav";
} else if (chooser.getFileFilter() == mp3) {
ext = "mp3";
file += ".mp3";
} else {
//assume wav
file += ".wav";
ext = "wav";
}
}
}
try {
exportFile = new RandomAccessFile(file, "rw");
} catch (Exception e) {
JFLog.log(e);
JF.showError("Error", "Failed to create export file");
return;
}
exporting = true;
ffmpeg = new MediaEncoder();
if (ext.equals("mp3")) {
String bitRate = JF.getString("Enter bitrate (32-512)", "128");
if (bitRate == null) bitRate = "128";
int bits = JF.atoi(bitRate);
if (bits < 32) bits = 32;
if (bits > 512) bits = 512;
ffmpeg.setAudioBitRate(bits * 1024);
}
ffmpeg.start(this, -1, -1, -1, 2, 44100, ext, false, true);
playSong();
}
//MediaCoderIO interface
public int read(MediaCoder coder, byte[] bytes) {
return 0;
}
public int write(MediaCoder coder, byte[] bytes) {
try {
exportFile.write(bytes);
} catch (Exception e) {
JFLog.log(e);
}
return bytes.length;
}
public long seek(MediaCoder coder, long pos, int how) {
try {
switch (how) {
case MediaCoder.SEEK_SET:
exportFile.seek(pos);
break;
case MediaCoder.SEEK_CUR:
exportFile.seek(exportFile.getFilePointer() + pos);
break;
case MediaCoder.SEEK_END:
exportFile.seek(exportFile.length() + pos);
break;
}
} catch (Exception e) {
JFLog.log(e);
}
return pos;
}
}