/** Generate Tone * * Created : July 8, 2014 * * @author pquiring */ import java.io.*; import javaforce.*; public class GenTone extends javax.swing.JDialog { /** * Creates new form GenTone */ public GenTone(java.awt.Frame parent, boolean modal, TrackPanel track) { super(parent, modal); initComponents(); JF.centerWindow(this); this.track = track; if (track.selectStart != track.selectStop) { timeField.setEnabled(false); double time = track.selectStop - track.selectStart; time /= track.rate; timeField.setText("" + time ); } } /** * 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(); jLabel2 = new javax.swing.JLabel(); jLabel1 = new javax.swing.JLabel(); freqField = new javax.swing.JTextField(); ampField = new javax.swing.JTextField(); jLabel3 = new javax.swing.JLabel(); timeField = new javax.swing.JTextField(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setTitle("Resample"); 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); } }); jLabel2.setText("Frequency:"); jLabel1.setText("Amplitude:"); freqField.setText("440"); ampField.setText("0.5"); jLabel3.setText("Length:"); timeField.setText("5.0"); 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() .addGap(0, 132, Short.MAX_VALUE) .addComponent(cancel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(apply)) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jLabel1) .addComponent(jLabel2) .addComponent(jLabel3)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(freqField) .addComponent(ampField) .addComponent(timeField)))) .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(jLabel2) .addComponent(freqField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel1) .addComponent(ampField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel3) .addComponent(timeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .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 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(); dispose(); }//GEN-LAST:event_applyActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JTextField ampField; private javax.swing.JButton apply; private javax.swing.JButton cancel; private javax.swing.JTextField freqField; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JTextField timeField; // End of variables declaration//GEN-END:variables private TrackPanel track; private void apply() { int rate = track.rate; int freq = JF.atoi(freqField.getText()); double amp = Double.parseDouble(ampField.getText()); if (amp > 1.0) amp = 1.0; if (amp < 0.0) amp = 0.0; boolean replace = false; long length; if (track.selectStart != track.selectStop) { replace = true; track.createModifyUndo(); length = track.selectStop - track.selectStart; } else { length = (long)(Double.parseDouble(timeField.getText()) * rate); } // JFLog.log("length=" + length); String toPath = track.project.path + "/temp"; new File(toPath).mkdir(); FileOutputStream fos; long totalLength = length; switch (track.bits) { case 16: amp *= Short.MAX_VALUE; break; case 32: amp *= Integer.MAX_VALUE; break; } try { int cid[] = new int[track.channels]; ByteArrayOutputStream baos[] = new ByteArrayOutputStream[track.channels]; for(int ch=0;ch<track.channels;ch++) { baos[ch] = new ByteArrayOutputStream(); } int size[] = new int[track.channels]; double dSample = 0; double pos = 0, chpos = 0; double theta = 2.0 * Math.PI * freq / rate; while (length > 0) { int todo = track.maxChunkSize; if (todo > length) todo = (int)length; for(int ch=0;ch<track.channels;ch++) { chpos = pos; for(int a=0;a<todo;a++) { dSample = Math.sin(chpos) * amp; chpos += theta; switch (track.bits) { case 16: { short sample = (short) dSample; baos[ch].write(sample & 0xff); sample >>= 8; baos[ch].write(sample & 0xff); break; } case 32: { int sample = (int) dSample; baos[ch].write(sample & 0xff); sample >>= 8; baos[ch].write(sample & 0xff); sample >>= 8; baos[ch].write(sample & 0xff); sample >>= 8; baos[ch].write(sample & 0xff); break; } } size[ch]++; if (size[ch] == track.maxChunkSize) { fos = new FileOutputStream(toPath + "/c" + cid[ch] + "-" + ch + ".dat"); TrackPanel.ChunkHeader chunk = new TrackPanel.ChunkHeader(); chunk.cid = cid[ch]++; chunk.length = size[ch]; chunk.next_cid = cid[ch]; chunk.write(fos); fos.write(baos[ch].toByteArray()); fos.close(); size[ch] = 0; baos[ch].reset(); } } } length -= todo; pos += theta * todo; int w = (int)pos; pos -= w; } for(int ch=0;ch<track.channels;ch++) { if (size[ch] > 0) { fos = new FileOutputStream(toPath + "/c" + cid[ch] + "-" + ch + ".dat"); TrackPanel.ChunkHeader chunk = new TrackPanel.ChunkHeader(); chunk.cid = cid[ch]++; chunk.length = size[ch]; chunk.next_cid = 0; chunk.write(fos); fos.write(baos[ch].toByteArray()); fos.close(); size[ch] = 0; baos[ch].reset(); } else { //need to patch last chunk (clear next_cid) RandomAccessFile raf = new RandomAccessFile(toPath + "/c" + (cid[ch]-1) + "-" + ch + ".dat", "rw"); raf.seek(4); //skip length raf.write(new byte[4]); //write zero next_cid raf.close(); } } //write clip header fos = new FileOutputStream(toPath + "/clip.dat"); TrackPanel.ClipHeader clip = new TrackPanel.ClipHeader(); clip.offset = 0; clip.length = totalLength; clip.tid = track.tid; clip.channels = track.channels; clip.bits = track.bits; clip.bytes = track.bytes; clip.rate = rate; clip.write(fos); fos.close(); } catch (Exception e) { JFLog.log(e); dispose(); return; } track.paste(toPath, replace); track.writeMainHeader(); //now delete /temp contents File files[] = new File(toPath).listFiles(); for(int a=0;a<files.length;a++) { files[a].delete(); } } }