Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0cfd066f4f | |||
| 217ccb915a | |||
| 1dd3e9d86f | |||
| d3d81d71fe | |||
| 80c110afa9 | |||
| 1c08b9a51d | |||
| 4ad30106b6 | |||
| 9100d0e35a | |||
| b8dea19c30 | |||
| 671f2b9270 | |||
| d619fb2f4d | |||
| 3eb6704f2f | |||
| cd24beb8a6 | |||
| fa287305eb | |||
| 3fb656b693 | |||
| f514993525 | |||
| 81787260c9 | |||
| f9ad396228 | |||
| 8976f2e359 | |||
| 187c3edaf6 | |||
| 02e85fb354 | |||
| 289834021f | |||
| 04fea4acb2 | |||
| 54739b0a75 | |||
| ea5520a729 | |||
| 0a19d8d308 | |||
| 4dbe3e23b7 | |||
| c43cfc3b69 | |||
| babd3d2052 | |||
| 9464839b4d | |||
| bcf7875414 | |||
| 732894a0fb | |||
| 146bf5a3c2 | |||
| b05bfde094 | |||
| 37d372b8f5 | |||
| c01fee3b73 | |||
| c907e735c6 | |||
| 7545e33d2f | |||
| ebf961449a | |||
| 45d6882527 | |||
| 2ec370ad61 |
BIN
deps/sphinx4-core-5prealpha-SNAPSHOT.jar
LFS
vendored
Normal file
BIN
deps/sphinx4-core-5prealpha-SNAPSHOT.jar
LFS
vendored
Normal file
Binary file not shown.
BIN
deps/sphinx4-data-5prealpha-SNAPSHOT.jar
LFS
vendored
Normal file
BIN
deps/sphinx4-data-5prealpha-SNAPSHOT.jar
LFS
vendored
Normal file
Binary file not shown.
@@ -1 +1 @@
|
|||||||
version=0.1.6
|
version=0.2.1
|
||||||
|
|||||||
BIN
resources/uk/co/majenko/audiobookrecorder/icons/cut.png
Normal file
BIN
resources/uk/co/majenko/audiobookrecorder/icons/cut.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 674 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/uk/co/majenko/audiobookrecorder/icons/do-cut.png
Normal file
BIN
resources/uk/co/majenko/audiobookrecorder/icons/do-cut.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 576 B |
BIN
resources/uk/co/majenko/audiobookrecorder/icons/play-to.png
Normal file
BIN
resources/uk/co/majenko/audiobookrecorder/icons/play-to.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 752 B |
BIN
resources/uk/co/majenko/audiobookrecorder/icons/split.png
Normal file
BIN
resources/uk/co/majenko/audiobookrecorder/icons/split.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 409 B |
@@ -795,7 +795,7 @@ public abstract class AbstractTheme extends MetalTheme {
|
|||||||
public FontUIResource getControlTextFont() {
|
public FontUIResource getControlTextFont() {
|
||||||
if (controlFont == null) {
|
if (controlFont == null) {
|
||||||
if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) {
|
if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) {
|
||||||
controlFont = new FontUIResource(DIALOG, Font.BOLD, 14);
|
controlFont = new FontUIResource(DIALOG, Font.PLAIN, 14); // bold
|
||||||
} else {
|
} else {
|
||||||
controlFont = new FontUIResource(DIALOG, Font.PLAIN, 12);
|
controlFont = new FontUIResource(DIALOG, Font.PLAIN, 12);
|
||||||
}
|
}
|
||||||
@@ -806,7 +806,7 @@ public abstract class AbstractTheme extends MetalTheme {
|
|||||||
public FontUIResource getSystemTextFont() {
|
public FontUIResource getSystemTextFont() {
|
||||||
if (systemFont == null) {
|
if (systemFont == null) {
|
||||||
if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) {
|
if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) {
|
||||||
systemFont = new FontUIResource(DIALOG, Font.BOLD, 14);
|
systemFont = new FontUIResource(DIALOG, Font.PLAIN, 14); // bold
|
||||||
} else {
|
} else {
|
||||||
systemFont = new FontUIResource(DIALOG, Font.PLAIN, 12);
|
systemFont = new FontUIResource(DIALOG, Font.PLAIN, 12);
|
||||||
}
|
}
|
||||||
@@ -817,7 +817,7 @@ public abstract class AbstractTheme extends MetalTheme {
|
|||||||
public FontUIResource getUserTextFont() {
|
public FontUIResource getUserTextFont() {
|
||||||
if (userFont == null) {
|
if (userFont == null) {
|
||||||
if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) {
|
if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) {
|
||||||
userFont = new FontUIResource(DIALOG, Font.BOLD, 14);
|
userFont = new FontUIResource(DIALOG, Font.PLAIN, 14); // bold
|
||||||
} else {
|
} else {
|
||||||
userFont = new FontUIResource(DIALOG, Font.PLAIN, 12);
|
userFont = new FontUIResource(DIALOG, Font.PLAIN, 12);
|
||||||
}
|
}
|
||||||
@@ -828,7 +828,7 @@ public abstract class AbstractTheme extends MetalTheme {
|
|||||||
public FontUIResource getMenuTextFont() {
|
public FontUIResource getMenuTextFont() {
|
||||||
if (menuFont == null) {
|
if (menuFont == null) {
|
||||||
if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) {
|
if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) {
|
||||||
menuFont = new FontUIResource(DIALOG, Font.BOLD, 14);
|
menuFont = new FontUIResource(DIALOG, Font.PLAIN, 14); // bold
|
||||||
} else {
|
} else {
|
||||||
menuFont = new FontUIResource(DIALOG, Font.PLAIN, 12);
|
menuFont = new FontUIResource(DIALOG, Font.PLAIN, 12);
|
||||||
}
|
}
|
||||||
@@ -839,9 +839,9 @@ public abstract class AbstractTheme extends MetalTheme {
|
|||||||
public FontUIResource getWindowTitleFont() {
|
public FontUIResource getWindowTitleFont() {
|
||||||
if (windowTitleFont == null) {
|
if (windowTitleFont == null) {
|
||||||
if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) {
|
if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) {
|
||||||
windowTitleFont = new FontUIResource(DIALOG, Font.BOLD, 14);
|
windowTitleFont = new FontUIResource(DIALOG, Font.PLAIN, 14); // bold
|
||||||
} else {
|
} else {
|
||||||
windowTitleFont = new FontUIResource(DIALOG, Font.BOLD, 12);
|
windowTitleFont = new FontUIResource(DIALOG, Font.PLAIN, 12); // bold
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return windowTitleFont;
|
return windowTitleFont;
|
||||||
@@ -850,7 +850,7 @@ public abstract class AbstractTheme extends MetalTheme {
|
|||||||
public FontUIResource getSubTextFont() {
|
public FontUIResource getSubTextFont() {
|
||||||
if (smallFont == null) {
|
if (smallFont == null) {
|
||||||
if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) {
|
if (JTattooUtilities.isLinux() && JTattooUtilities.isHiresScreen()) {
|
||||||
smallFont = new FontUIResource(DIALOG, Font.BOLD, 12);
|
smallFont = new FontUIResource(DIALOG, Font.PLAIN, 12); // bold
|
||||||
} else {
|
} else {
|
||||||
smallFont = new FontUIResource(DIALOG, Font.PLAIN, 10);
|
smallFont = new FontUIResource(DIALOG, Font.PLAIN, 10);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,11 +125,11 @@ public class HiFiDefaultTheme extends AbstractTheme {
|
|||||||
tooltipForegroundColor = white;
|
tooltipForegroundColor = white;
|
||||||
tooltipBackgroundColor = new ColorUIResource(24, 24, 24);
|
tooltipBackgroundColor = new ColorUIResource(24, 24, 24);
|
||||||
|
|
||||||
controlFont = new FontUIResource("Dialog", Font.BOLD, 12);
|
controlFont = new FontUIResource("Dialog", Font.PLAIN, 12); // bold
|
||||||
systemFont = new FontUIResource("Dialog", Font.BOLD, 12);
|
systemFont = new FontUIResource("Dialog", Font.PLAIN, 12); // bold
|
||||||
userFont = new FontUIResource("Dialog", Font.BOLD, 12);
|
userFont = new FontUIResource("Dialog", Font.PLAIN, 12); // bold
|
||||||
menuFont = new FontUIResource("Dialog", Font.BOLD, 12);
|
menuFont = new FontUIResource("Dialog", Font.PLAIN, 12); // bold
|
||||||
windowTitleFont = new FontUIResource("Dialog", Font.BOLD, 12);
|
windowTitleFont = new FontUIResource("Dialog", Font.PLAIN, 12); // bold
|
||||||
smallFont = new FontUIResource("Dialog", Font.PLAIN, 10);
|
smallFont = new FontUIResource("Dialog", Font.PLAIN, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,18 +42,18 @@ public class HiFiLookAndFeel extends AbstractLookAndFeel {
|
|||||||
private static final Properties giantFontProps = new Properties();
|
private static final Properties giantFontProps = new Properties();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
smallFontProps.setProperty("controlTextFont", "Dialog bold 10");
|
smallFontProps.setProperty("controlTextFont", "Dialog 10"); // bold
|
||||||
smallFontProps.setProperty("systemTextFont", "Dialog bold 10");
|
smallFontProps.setProperty("systemTextFont", "Dialog 10"); // bold
|
||||||
smallFontProps.setProperty("userTextFont", "Dialog 10");
|
smallFontProps.setProperty("userTextFont", "Dialog 10");
|
||||||
smallFontProps.setProperty("menuTextFont", "Dialog bold 10");
|
smallFontProps.setProperty("menuTextFont", "Dialog 10"); // bold
|
||||||
smallFontProps.setProperty("windowTitleFont", "Dialog bold 10");
|
smallFontProps.setProperty("windowTitleFont", "Dialog 10"); // bold
|
||||||
smallFontProps.setProperty("subTextFont", "Dialog 8");
|
smallFontProps.setProperty("subTextFont", "Dialog 8");
|
||||||
|
|
||||||
largeFontProps.setProperty("controlTextFont", "Dialog bold 14");
|
largeFontProps.setProperty("controlTextFont", "Dialog 14"); // bold
|
||||||
largeFontProps.setProperty("systemTextFont", "Dialog bold 14");
|
largeFontProps.setProperty("systemTextFont", "Dialog 14"); // bold
|
||||||
largeFontProps.setProperty("userTextFont", "Dialog bold 14");
|
largeFontProps.setProperty("userTextFont", "Dialog 14"); // bold
|
||||||
largeFontProps.setProperty("menuTextFont", "Dialog bold 14");
|
largeFontProps.setProperty("menuTextFont", "Dialog 14"); // bold
|
||||||
largeFontProps.setProperty("windowTitleFont", "Dialog bold 14");
|
largeFontProps.setProperty("windowTitleFont", "Dialog 14"); // bold
|
||||||
largeFontProps.setProperty("subTextFont", "Dialog 12");
|
largeFontProps.setProperty("subTextFont", "Dialog 12");
|
||||||
|
|
||||||
giantFontProps.setProperty("controlTextFont", "Dialog 18");
|
giantFontProps.setProperty("controlTextFont", "Dialog 18");
|
||||||
|
|||||||
@@ -25,27 +25,37 @@ public class AGC implements Effect {
|
|||||||
return getName();
|
return getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public double process(double sample) {
|
public void process(double[][] samples) {
|
||||||
double absSample = Math.abs(sample) * gain;
|
gain = 1d;
|
||||||
|
for (int i = 0; i < samples.length; i++) {
|
||||||
|
double absSampleLeft = Math.abs(samples[i][Sentence.LEFT]) * gain;
|
||||||
|
double absSampleRight = Math.abs(samples[i][Sentence.RIGHT]) * gain;
|
||||||
|
|
||||||
if (absSample > ceiling) {
|
double factor = 0.0d;
|
||||||
gain -= attack;
|
|
||||||
if (gain < 0) gain = 0;
|
if (absSampleLeft > ceiling) {
|
||||||
}
|
factor = -attack;
|
||||||
|
|
||||||
if (absSample < ceiling) {
|
|
||||||
gain += decay;
|
|
||||||
if (gain > limit) {
|
|
||||||
gain = limit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (absSampleRight > ceiling) {
|
||||||
|
factor = -attack;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((absSampleLeft < ceiling) && (absSampleRight < ceiling)) {
|
||||||
|
factor = decay;
|
||||||
|
}
|
||||||
|
|
||||||
|
gain += factor;
|
||||||
|
if (gain > limit) gain = limit;
|
||||||
|
if (gain < 0) gain = 0;
|
||||||
|
|
||||||
|
samples[i][Sentence.LEFT] *= gain;
|
||||||
|
samples[i][Sentence.RIGHT] *= gain;
|
||||||
}
|
}
|
||||||
|
|
||||||
sample *= gain;
|
|
||||||
|
|
||||||
return sample;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(double sr) {
|
public void init(double sr) {
|
||||||
|
gain = 1d;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dump() {
|
public void dump() {
|
||||||
|
|||||||
@@ -19,8 +19,11 @@ public class Amplifier implements Effect {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double process(double sample) {
|
public void process(double[][] samples) {
|
||||||
return sample * gain;
|
for (int i = 0; i < samples.length; i++) {
|
||||||
|
samples[i][Sentence.LEFT] *= gain;
|
||||||
|
samples[i][Sentence.RIGHT] *= gain;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getGain() {
|
public double getGain() {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -32,7 +32,8 @@ public class Biquad implements Effect {
|
|||||||
int type;
|
int type;
|
||||||
double a0, a1, a2, b1, b2;
|
double a0, a1, a2, b1, b2;
|
||||||
double Fc, Q, peakGain;
|
double Fc, Q, peakGain;
|
||||||
double z1, z2;
|
double lz1, lz2;
|
||||||
|
double rz1, rz2;
|
||||||
double sampleFrequency;
|
double sampleFrequency;
|
||||||
|
|
||||||
public Biquad() {
|
public Biquad() {
|
||||||
@@ -45,15 +46,19 @@ public class Biquad implements Effect {
|
|||||||
Fc = 440d;
|
Fc = 440d;
|
||||||
Q = 0.707d;
|
Q = 0.707d;
|
||||||
peakGain = 0.0d;
|
peakGain = 0.0d;
|
||||||
z1 = 0.0d;
|
lz1 = 0.0d;
|
||||||
z2 = 0.0d;
|
lz2 = 0.0d;
|
||||||
|
rz1 = 0.0d;
|
||||||
|
rz2 = 0.0d;
|
||||||
sampleFrequency = 44100d;
|
sampleFrequency = 44100d;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Biquad(int type, double Fc, double Q, double peakGainDB) {
|
public Biquad(int type, double Fc, double Q, double peakGainDB) {
|
||||||
setBiquad(type, Fc, Q, peakGainDB);
|
setBiquad(type, Fc, Q, peakGainDB);
|
||||||
z1 = 0.0;
|
lz1 = 0.0;
|
||||||
z2 = 0.0;
|
lz2 = 0.0;
|
||||||
|
rz1 = 0.0;
|
||||||
|
rz2 = 0.0;
|
||||||
sampleFrequency = 44100d;
|
sampleFrequency = 44100d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,17 +89,33 @@ public class Biquad implements Effect {
|
|||||||
setPeakGain(peakGainDB);
|
setPeakGain(peakGainDB);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double process(double in) {
|
public void process(double[][] samples) {
|
||||||
double out = in * a0 + z1;
|
lz1 = 0d;
|
||||||
z1 = in * a1 + z2 - b1 * out;
|
lz2 = 0d;
|
||||||
z2 = in * a2 - b2 * out;
|
rz1 = 0d;
|
||||||
return out;
|
rz2 = 0d;
|
||||||
|
for (double[] in : samples) {
|
||||||
|
double lout = in[Sentence.LEFT] * a0 + lz1;
|
||||||
|
|
||||||
|
lz1 = in[Sentence.LEFT] * a1 + lz2 - b1 * lout;
|
||||||
|
lz2 = in[Sentence.LEFT] * a2 - b2 * lout;
|
||||||
|
|
||||||
|
double rout = in[Sentence.RIGHT] * a0 + rz1;
|
||||||
|
|
||||||
|
rz1 = in[Sentence.RIGHT] * a1 + rz2 - b1 * rout;
|
||||||
|
rz2 = in[Sentence.RIGHT] * a2 - b2 * rout;
|
||||||
|
|
||||||
|
in[Sentence.LEFT] = lout;
|
||||||
|
in[Sentence.RIGHT] = rout;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(double sf) {
|
public void init(double sf) {
|
||||||
sampleFrequency = sf;
|
sampleFrequency = sf;
|
||||||
z1 = 0d;
|
lz1 = 0d;
|
||||||
z2 = 0d;
|
lz2 = 0d;
|
||||||
|
rz1 = 0d;
|
||||||
|
rz2 = 0d;
|
||||||
calcBiquad();
|
calcBiquad();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -206,4 +206,14 @@ public class Book extends DefaultMutableTreeNode {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void purgeBackups() {
|
||||||
|
for (Enumeration o = children(); o.hasMoreElements();) {
|
||||||
|
Object ob = (Object)o.nextElement();
|
||||||
|
if (ob instanceof Chapter) {
|
||||||
|
Chapter c = (Chapter)ob;
|
||||||
|
c.purgeBackups();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,14 @@ package uk.co.majenko.audiobookrecorder;
|
|||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.tree.*;
|
import javax.swing.tree.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import javax.swing.border.*;
|
||||||
|
|
||||||
public class BookTreeRenderer extends DefaultTreeCellRenderer {
|
public class BookTreeRenderer extends DefaultTreeCellRenderer {
|
||||||
|
|
||||||
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
|
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
|
||||||
JLabel ret = (JLabel) super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
|
JLabel ret = (JLabel) super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
|
||||||
|
ret.setIconTextGap(0);
|
||||||
|
ret.setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||||
if (value instanceof Sentence) {
|
if (value instanceof Sentence) {
|
||||||
Sentence s = (Sentence)value;
|
Sentence s = (Sentence)value;
|
||||||
|
|
||||||
@@ -31,8 +34,36 @@ public class BookTreeRenderer extends DefaultTreeCellRenderer {
|
|||||||
icn.add(Overlays.important, OverlayIcon.TOP_RIGHT);
|
icn.add(Overlays.important, OverlayIcon.TOP_RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s.getEffectChain() != null) {
|
||||||
|
if (!s.getEffectChain().equals("none")) {
|
||||||
|
icn.add(Overlays.filter, OverlayIcon.BOTTOM_RIGHT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret.setIcon(icn);
|
ret.setIcon(icn);
|
||||||
|
|
||||||
|
String gaptype = s.getPostGapType();
|
||||||
|
DefaultMutableTreeNode prev = s.getPreviousSibling();
|
||||||
|
String prevtype = "sentence";
|
||||||
|
if (prev instanceof Sentence) {
|
||||||
|
Sentence s2 = (Sentence)prev;
|
||||||
|
prevtype = s2.getPostGapType();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prevtype.equals("continuation")) {
|
||||||
|
ret.setIconTextGap(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gaptype.equals("sentence")) {
|
||||||
|
ret.setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||||
|
} else if (gaptype.equals("continuation")) {
|
||||||
|
ret.setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||||
|
} else if (gaptype.equals("paragraph")) {
|
||||||
|
ret.setBorder(new EmptyBorder(0, 0, 7, 0));
|
||||||
|
} else if (gaptype.equals("section")) {
|
||||||
|
ret.setBorder(new EmptyBorder(0, 0, 15, 0));
|
||||||
|
}
|
||||||
|
|
||||||
} else if (value instanceof Chapter) {
|
} else if (value instanceof Chapter) {
|
||||||
ret.setIcon(Icons.chapter);
|
ret.setIcon(Icons.chapter);
|
||||||
} else if (value instanceof Book) {
|
} else if (value instanceof Book) {
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ public class CacheManager {
|
|||||||
if (ob.lockedInCache()) {
|
if (ob.lockedInCache()) {
|
||||||
cache.add(ob);
|
cache.add(ob);
|
||||||
} else {
|
} else {
|
||||||
|
if (ob instanceof Sentence) {
|
||||||
|
Sentence s = (Sentence)ob;
|
||||||
|
}
|
||||||
ob.clearCache();
|
ob.clearCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,4 +26,19 @@ public class CacheManager {
|
|||||||
public static void setCacheSize(int c) {
|
public static void setCacheSize(int c) {
|
||||||
cacheSize = c;
|
cacheSize = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void removeFromCache(Cacheable c) {
|
||||||
|
if (c instanceof Sentence) {
|
||||||
|
Sentence s = (Sentence)c;
|
||||||
|
}
|
||||||
|
cache.remove(c);
|
||||||
|
c.clearCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void purgeCache() {
|
||||||
|
for (Cacheable c : cache) {
|
||||||
|
c.clearCache();
|
||||||
|
}
|
||||||
|
cache.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
58
src/uk/co/majenko/audiobookrecorder/Chain.java
Normal file
58
src/uk/co/majenko/audiobookrecorder/Chain.java
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package uk.co.majenko.audiobookrecorder;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class Chain implements Effect {
|
||||||
|
String target;
|
||||||
|
|
||||||
|
public Chain(String t) {
|
||||||
|
target = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chain() {
|
||||||
|
target = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void process(double[][] samples) {
|
||||||
|
if (target != null) {
|
||||||
|
Effect t = AudiobookRecorder.window.effects.get(target);
|
||||||
|
if (t != null) {
|
||||||
|
t.process(samples);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTarget(String t) {
|
||||||
|
target = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTarget() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "Chain to " + target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dump() {
|
||||||
|
System.out.println(toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(double sf) {
|
||||||
|
if (target != null) {
|
||||||
|
Effect t = AudiobookRecorder.window.effects.get(target);
|
||||||
|
if (t != null) {
|
||||||
|
t.init(sf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Effect> getChildEffects() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -116,13 +116,13 @@ public class Chapter extends DefaultMutableTreeNode {
|
|||||||
audioAttributes.setCodec("libmp3lame");
|
audioAttributes.setCodec("libmp3lame");
|
||||||
audioAttributes.setBitRate(Options.getInteger("audio.export.bitrate"));
|
audioAttributes.setBitRate(Options.getInteger("audio.export.bitrate"));
|
||||||
audioAttributes.setSamplingRate(Options.getInteger("audio.export.samplerate"));
|
audioAttributes.setSamplingRate(Options.getInteger("audio.export.samplerate"));
|
||||||
audioAttributes.setChannels(2); //new Integer(2));
|
audioAttributes.setChannels(Options.getInteger("audio.export.channels")); //new Integer(2));
|
||||||
attributes.setFormat("mp3");
|
attributes.setFormat("mp3");
|
||||||
attributes.setAudioAttributes(audioAttributes);
|
attributes.setAudioAttributes(audioAttributes);
|
||||||
|
|
||||||
|
|
||||||
AudioFormat sampleformat = AudiobookRecorder.window.roomNoise.getAudioFormat();
|
AudioFormat sampleformat = AudiobookRecorder.window.roomNoise.getAudioFormat();
|
||||||
AudioFormat format = new AudioFormat(sampleformat.getSampleRate(), 16, 1, true, false);
|
AudioFormat format = new AudioFormat(sampleformat.getSampleRate(), 16, 2, true, false);
|
||||||
byte[] data;
|
byte[] data;
|
||||||
|
|
||||||
int fullLength = 0;
|
int fullLength = 0;
|
||||||
@@ -232,5 +232,21 @@ public class Chapter extends DefaultMutableTreeNode {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void resetPostGaps() {
|
||||||
|
for (Enumeration s = children(); s.hasMoreElements();) {
|
||||||
|
Sentence snt = (Sentence)s.nextElement();
|
||||||
|
snt.resetPostGap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void purgeBackups() {
|
||||||
|
for (Enumeration o = children(); o.hasMoreElements();) {
|
||||||
|
Object ob = (Object)o.nextElement();
|
||||||
|
if (ob instanceof Sentence) {
|
||||||
|
Sentence s = (Sentence)ob;
|
||||||
|
s.purgeBackups();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,13 @@ public class Clipping implements Effect {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double process(double sample) {
|
public void process(double[][] samples) {
|
||||||
if (sample > clip) return clip;
|
for (double[] sample : samples) {
|
||||||
if (sample < -clip) return -clip;
|
if (sample[Sentence.LEFT] > clip) sample[Sentence.LEFT] = clip;
|
||||||
return sample;
|
if (sample[Sentence.LEFT] < -clip) sample[Sentence.LEFT] = -clip;
|
||||||
|
if (sample[Sentence.RIGHT] > clip) sample[Sentence.RIGHT] = clip;
|
||||||
|
if (sample[Sentence.RIGHT] < -clip) sample[Sentence.RIGHT] = -clip;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getClip() {
|
public double getClip() {
|
||||||
|
|||||||
12
src/uk/co/majenko/audiobookrecorder/Debug.java
Normal file
12
src/uk/co/majenko/audiobookrecorder/Debug.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package uk.co.majenko.audiobookrecorder;
|
||||||
|
|
||||||
|
public class Debug {
|
||||||
|
static long timestamp;
|
||||||
|
|
||||||
|
static void debug(String msg) {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
long diff = now - timestamp;
|
||||||
|
timestamp = now;
|
||||||
|
System.err.println(String.format("%8d - %s", diff, msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,8 @@ public class DelayLine implements Effect {
|
|||||||
|
|
||||||
ArrayList<DelayLineStore> delayLines;
|
ArrayList<DelayLineStore> delayLines;
|
||||||
|
|
||||||
|
boolean wetOnly = false;
|
||||||
|
|
||||||
public DelayLine() {
|
public DelayLine() {
|
||||||
delayLines = new ArrayList<DelayLineStore>();
|
delayLines = new ArrayList<DelayLineStore>();
|
||||||
}
|
}
|
||||||
@@ -14,23 +16,70 @@ public class DelayLine implements Effect {
|
|||||||
return "Delay Line (" + delayLines.size() + " lines)";
|
return "Delay Line (" + delayLines.size() + " lines)";
|
||||||
}
|
}
|
||||||
|
|
||||||
public double process(double sample) {
|
public void process(double[][] samples) {
|
||||||
double s = sample;
|
double[][] savedSamples = new double[samples.length][2];
|
||||||
for (DelayLineStore d : delayLines) {
|
for (int i = 0; i < samples.length; i++) {
|
||||||
double echo = d.pass(sample);
|
savedSamples[i][Sentence.LEFT] = samples[i][Sentence.LEFT];
|
||||||
s = mix(s, echo);
|
savedSamples[i][Sentence.RIGHT] = samples[i][Sentence.RIGHT];
|
||||||
|
}
|
||||||
|
if (wetOnly) {
|
||||||
|
for (int i = 0; i < samples.length; i++) {
|
||||||
|
samples[i][Sentence.LEFT] = 0d;
|
||||||
|
samples[i][Sentence.RIGHT] = 0d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double[][] subSamples = new double[samples.length][2];
|
||||||
|
for (int i = 0; i < samples.length; i++) {
|
||||||
|
subSamples[i][Sentence.LEFT] = savedSamples[i][Sentence.LEFT];
|
||||||
|
subSamples[i][Sentence.RIGHT] = savedSamples[i][Sentence.RIGHT];
|
||||||
|
}
|
||||||
|
for (DelayLineStore d : delayLines) {
|
||||||
|
for (int i = 0; i < samples.length; i++) {
|
||||||
|
subSamples[i][Sentence.LEFT] = savedSamples[i][Sentence.LEFT];
|
||||||
|
subSamples[i][Sentence.RIGHT] = savedSamples[i][Sentence.RIGHT];
|
||||||
|
}
|
||||||
|
|
||||||
|
d.process(subSamples);
|
||||||
|
|
||||||
|
for (int i = 0; i < subSamples.length; i++) {
|
||||||
|
int off = i + d.getSamples();
|
||||||
|
if ((off < samples.length) && (off > 0)) {
|
||||||
|
|
||||||
|
double[] ns = mix(samples[off], subSamples[i]);
|
||||||
|
samples[off][Sentence.LEFT] = ns[Sentence.LEFT];
|
||||||
|
samples[off][Sentence.RIGHT] = ns[Sentence.RIGHT];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double mix(double a, double b) {
|
double[] mix(double[] a, double[] b) {
|
||||||
if ((a < 0) && (b < 0)) {
|
double[] out = new double[2];
|
||||||
return (a + b) - (a * b);
|
|
||||||
}
|
if ((a[Sentence.LEFT] < 0) && (b[Sentence.LEFT] < 0)) {
|
||||||
if ((a > 0) && (b > 0)) {
|
out[Sentence.LEFT] = (a[Sentence.LEFT] + b[Sentence.LEFT]) - (a[Sentence.LEFT] * b[Sentence.LEFT]);
|
||||||
return (a + b) - (a * b);
|
} else if ((a[Sentence.LEFT] > 0) && (b[Sentence.LEFT] > 0)) {
|
||||||
|
out[Sentence.LEFT] = (a[Sentence.LEFT] + b[Sentence.LEFT]) - (a[Sentence.LEFT] * b[Sentence.LEFT]);
|
||||||
|
} else {
|
||||||
|
out[Sentence.LEFT] = a[Sentence.LEFT] + b[Sentence.LEFT];
|
||||||
}
|
}
|
||||||
return a + b;
|
|
||||||
|
if ((a[Sentence.RIGHT] < 0) && (b[Sentence.RIGHT] < 0)) {
|
||||||
|
out[Sentence.RIGHT] = (a[Sentence.RIGHT] + b[Sentence.RIGHT]) - (a[Sentence.RIGHT] * b[Sentence.RIGHT]);
|
||||||
|
} else if ((a[Sentence.RIGHT] > 0) && (b[Sentence.RIGHT] > 0)) {
|
||||||
|
out[Sentence.RIGHT] = (a[Sentence.RIGHT] + b[Sentence.RIGHT]) - (a[Sentence.RIGHT] * b[Sentence.RIGHT]);
|
||||||
|
} else {
|
||||||
|
out[Sentence.RIGHT] = a[Sentence.RIGHT] + b[Sentence.RIGHT];
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DelayLineStore addDelayLine(int samples, double gain, double pan) {
|
||||||
|
DelayLineStore s = new DelayLineStore(samples, gain, pan);
|
||||||
|
delayLines.add(s);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DelayLineStore addDelayLine(int samples, double gain) {
|
public DelayLineStore addDelayLine(int samples, double gain) {
|
||||||
@@ -60,5 +109,7 @@ public class DelayLine implements Effect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setWetOnly(boolean b) {
|
||||||
|
wetOnly = b;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,42 +4,46 @@ import java.util.concurrent.ArrayBlockingQueue;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class DelayLineStore {
|
public class DelayLineStore {
|
||||||
ArrayBlockingQueue<Double> fifo;
|
|
||||||
double gain;
|
double gain;
|
||||||
int numSamples;
|
int numSamples;
|
||||||
|
double pan;
|
||||||
|
|
||||||
ArrayList<Effect> effects;
|
ArrayList<Effect> effects;
|
||||||
|
|
||||||
public DelayLineStore(int s, double g) {
|
public DelayLineStore(int s, double g, double p) {
|
||||||
fifo = new ArrayBlockingQueue<Double>(s);
|
|
||||||
for (int i = 0; i < s; i++) {
|
|
||||||
fifo.add(0d);
|
|
||||||
}
|
|
||||||
numSamples = s;
|
numSamples = s;
|
||||||
gain = g;
|
gain = g;
|
||||||
|
pan = p;
|
||||||
effects = new ArrayList<Effect>();
|
effects = new ArrayList<Effect>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public double pass(double s) {
|
public DelayLineStore(int s, double g) {
|
||||||
try {
|
numSamples = s;
|
||||||
for (Effect e : effects) {
|
gain = g;
|
||||||
s = e.process(s);
|
pan = 0d;
|
||||||
}
|
effects = new ArrayList<Effect>();
|
||||||
double v = s * gain;
|
}
|
||||||
double t = fifo.poll();
|
|
||||||
fifo.add(v);
|
public void process(double[][] samples) {
|
||||||
return t;
|
for (Effect e : effects) {
|
||||||
} catch (Exception e) {
|
e.process(samples);
|
||||||
e.printStackTrace();
|
}
|
||||||
|
|
||||||
|
for (double[] sample : samples) {
|
||||||
|
sample[Sentence.LEFT] *= gain;
|
||||||
|
sample[Sentence.RIGHT] *= gain;
|
||||||
|
|
||||||
|
if (pan < 0) {
|
||||||
|
double p = 1 + pan;
|
||||||
|
sample[Sentence.RIGHT] *= p;
|
||||||
|
} else {
|
||||||
|
double p = 1 - pan;
|
||||||
|
sample[Sentence.LEFT] *= p;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSamples(int s) {
|
public void setSamples(int s) {
|
||||||
fifo = new ArrayBlockingQueue<Double>(s);
|
|
||||||
for (int i = 0; i < s; i++) {
|
|
||||||
fifo.add(0d);
|
|
||||||
}
|
|
||||||
numSamples = s;
|
numSamples = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,13 +59,6 @@ public class DelayLineStore {
|
|||||||
return gain;
|
return gain;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void purge() {
|
|
||||||
fifo.clear();
|
|
||||||
for (int i = 0; i < numSamples; i++) {
|
|
||||||
fifo.add(0d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addEffect(Effect e) {
|
public void addEffect(Effect e) {
|
||||||
effects.add(e);
|
effects.add(e);
|
||||||
}
|
}
|
||||||
@@ -70,7 +67,6 @@ public class DelayLineStore {
|
|||||||
for (Effect e : effects) {
|
for (Effect e : effects) {
|
||||||
e.init(sf);
|
e.init(sf);
|
||||||
}
|
}
|
||||||
purge();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dump() {
|
public void dump() {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package uk.co.majenko.audiobookrecorder;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public interface Effect {
|
public interface Effect {
|
||||||
public double process(double sample);
|
public void process(double[][] samples);
|
||||||
public String getName();
|
public String getName();
|
||||||
public ArrayList<Effect> getChildEffects();
|
public ArrayList<Effect> getChildEffects();
|
||||||
public void dump();
|
public void dump();
|
||||||
|
|||||||
@@ -16,12 +16,10 @@ public class EffectGroup implements Effect {
|
|||||||
effects = new ArrayList<Effect>();
|
effects = new ArrayList<Effect>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public double process(double sample) {
|
public void process(double[][] samples) {
|
||||||
double out = sample;
|
|
||||||
for (Effect e : effects) {
|
for (Effect e : effects) {
|
||||||
out = e.process(out);
|
e.process(samples);
|
||||||
}
|
}
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String n) {
|
public void setName(String n) {
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ public class FlashPanel extends JPanel {
|
|||||||
public void setFlash(boolean f) {
|
public void setFlash(boolean f) {
|
||||||
flash = f;
|
flash = f;
|
||||||
|
|
||||||
|
col = true;
|
||||||
|
|
||||||
for (Component o : getComponents()) {
|
for (Component o : getComponents()) {
|
||||||
((JComponent)o).setVisible(!f);
|
((JComponent)o).setVisible(!f);
|
||||||
}
|
}
|
||||||
@@ -42,7 +44,7 @@ public class FlashPanel extends JPanel {
|
|||||||
if (col) {
|
if (col) {
|
||||||
g.setColor(Color.RED);
|
g.setColor(Color.RED);
|
||||||
} else {
|
} else {
|
||||||
g.setColor(Color.BLACK);
|
g.setColor(Color.GREEN);
|
||||||
}
|
}
|
||||||
Dimension d = getSize();
|
Dimension d = getSize();
|
||||||
g.fillRect(0, 0, d.width, d.height);
|
g.fillRect(0, 0, d.width, d.height);
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
package uk.co.majenko.audiobookrecorder;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.*;
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.util.Timer;
|
|
||||||
|
|
||||||
public class HavenQueue extends JPanel {
|
|
||||||
ConcurrentLinkedQueue<Sentence> sentenceList = new ConcurrentLinkedQueue<Sentence>();
|
|
||||||
|
|
||||||
Timer timer = new Timer();
|
|
||||||
|
|
||||||
Sentence currentSentence = null;
|
|
||||||
|
|
||||||
JLabel count;
|
|
||||||
|
|
||||||
public HavenQueue() {
|
|
||||||
timer.schedule(new TimerTask() { public void run() { processQueue(); }}, 30000);
|
|
||||||
count = new JLabel("Haven queue: 0");
|
|
||||||
setLayout(new BorderLayout());
|
|
||||||
add(count, BorderLayout.CENTER);
|
|
||||||
|
|
||||||
count.setOpaque(false);
|
|
||||||
setOpaque(false);
|
|
||||||
count.setForeground(Color.WHITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void processQueue() {
|
|
||||||
|
|
||||||
count.setText("Haven queue: " + sentenceList.size());
|
|
||||||
|
|
||||||
if (currentSentence == null) {
|
|
||||||
// Grab a new sentence to process.
|
|
||||||
currentSentence = sentenceList.poll();
|
|
||||||
|
|
||||||
if (currentSentence != null) {
|
|
||||||
if (!currentSentence.postHavenData()) { // Failed. Add to the end of the queue and wait a bit
|
|
||||||
submit(currentSentence);
|
|
||||||
currentSentence = null;
|
|
||||||
timer.schedule(new TimerTask() { public void run() { processQueue(); }}, 30000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
timer.schedule(new TimerTask() { public void run() { processQueue(); }}, 5000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
timer.schedule(new TimerTask() { public void run() { processQueue(); }}, 5000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentSentence != null) {
|
|
||||||
currentSentence.processPendingHaven();
|
|
||||||
int status = currentSentence.getHavenStatus();
|
|
||||||
switch (status) {
|
|
||||||
case 0: // Um... not running...?
|
|
||||||
currentSentence = null;
|
|
||||||
timer.schedule(new TimerTask() { public void run() { processQueue(); }}, 30000);
|
|
||||||
return;
|
|
||||||
case 1: // Still processing...
|
|
||||||
timer.schedule(new TimerTask() { public void run() { processQueue(); }}, 5000);
|
|
||||||
return;
|
|
||||||
case 2: // Finished
|
|
||||||
currentSentence = null;
|
|
||||||
timer.schedule(new TimerTask() { public void run() { processQueue(); }}, 30000);
|
|
||||||
return;
|
|
||||||
case 3: // Failed
|
|
||||||
currentSentence = null;
|
|
||||||
timer.schedule(new TimerTask() { public void run() { processQueue(); }}, 30000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
timer.schedule(new TimerTask() { public void run() { processQueue(); }}, 30000);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void submit(Sentence s) {
|
|
||||||
s.setOverrideText("[queued...]");
|
|
||||||
AudiobookRecorder.window.bookTreeModel.reload(s);
|
|
||||||
sentenceList.add(s);
|
|
||||||
count.setText("Haven queue: " + sentenceList.size());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -33,4 +33,9 @@ public class Icons {
|
|||||||
static public final ImageIcon dollar = new ImageIcon(Icons.class.getResource("icons/dollar.png"));
|
static public final ImageIcon dollar = new ImageIcon(Icons.class.getResource("icons/dollar.png"));
|
||||||
static public final ImageIcon attention = new ImageIcon(Icons.class.getResource("icons/attention.png"));
|
static public final ImageIcon attention = new ImageIcon(Icons.class.getResource("icons/attention.png"));
|
||||||
static public final ImageIcon normalize = new ImageIcon(Icons.class.getResource("icons/normalize.png"));
|
static public final ImageIcon normalize = new ImageIcon(Icons.class.getResource("icons/normalize.png"));
|
||||||
|
static public final ImageIcon split = new ImageIcon(Icons.class.getResource("icons/split.png"));
|
||||||
|
static public final ImageIcon cut = new ImageIcon(Icons.class.getResource("icons/cut.png"));
|
||||||
|
static public final ImageIcon docut = new ImageIcon(Icons.class.getResource("icons/do-cut.png"));
|
||||||
|
static public final ImageIcon playto = new ImageIcon(Icons.class.getResource("icons/play-to.png"));
|
||||||
|
static public final ImageIcon disable = new ImageIcon(Icons.class.getResource("icons/disable-effects.png"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,24 +22,25 @@ public class LFO implements Effect {
|
|||||||
phase = p;
|
phase = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double process(double sample) {
|
public void process(double[][] samples) {
|
||||||
double v = Math.sin(phase);
|
for (double[] sample : samples) {
|
||||||
phase += sampleStep;
|
double v = Math.sin(phase);
|
||||||
if (phase > (Math.PI * 2d)) {
|
phase += sampleStep;
|
||||||
phase -= (Math.PI * 2d);
|
if (phase > (Math.PI * 2d)) {
|
||||||
}
|
phase -= (Math.PI * 2d);
|
||||||
|
}
|
||||||
|
|
||||||
// // Make it between 0 and 1.
|
// // Make it between 0 and 1.
|
||||||
// v = 1d + v;
|
// v = 1d + v;
|
||||||
// v /= 2d;
|
// v /= 2d;
|
||||||
|
|
||||||
// Multiply it by the gain factor
|
// Multiply it by the gain factor
|
||||||
v *= depth;
|
v *= depth;
|
||||||
|
|
||||||
// Apply it to the sample
|
// Apply it to the sample
|
||||||
sample += (sample * v);
|
sample[Sentence.LEFT] += (sample[Sentence.LEFT] * v);
|
||||||
|
sample[Sentence.RIGHT] += (sample[Sentence.RIGHT] * v);
|
||||||
return sample;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() { return "Low Frequency Oscillator (" + frequency + " Hz, " + (depth * 100d) + "%)"; }
|
public String getName() { return "Low Frequency Oscillator (" + frequency + " Hz, " + (depth * 100d) + "%)"; }
|
||||||
|
|||||||
@@ -14,9 +14,14 @@ public class MainToolBar extends JToolBar {
|
|||||||
JButtonSpacePlay recordRoomNoise;
|
JButtonSpacePlay recordRoomNoise;
|
||||||
JButtonSpacePlay playSentence;
|
JButtonSpacePlay playSentence;
|
||||||
JButtonSpacePlay playonSentence;
|
JButtonSpacePlay playonSentence;
|
||||||
|
JButtonSpacePlay playtoSentence;
|
||||||
JButtonSpacePlay stopPlaying;
|
JButtonSpacePlay stopPlaying;
|
||||||
JButtonSpacePlay eq;
|
JButtonSpacePlay eq;
|
||||||
JToggleButton mic;
|
JToggleButtonSpacePlay mic;
|
||||||
|
|
||||||
|
JComboBox<String> playbackSpeed;
|
||||||
|
|
||||||
|
JToggleButtonSpacePlay disableEffects;
|
||||||
|
|
||||||
AudiobookRecorder root;
|
AudiobookRecorder root;
|
||||||
|
|
||||||
@@ -78,6 +83,14 @@ public class MainToolBar extends JToolBar {
|
|||||||
});
|
});
|
||||||
add(playonSentence);
|
add(playonSentence);
|
||||||
|
|
||||||
|
playtoSentence = new JButtonSpacePlay(Icons.playto, "Play sentence to cut", new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
root.playToSelectedSentence();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
add(playtoSentence);
|
||||||
|
playtoSentence.setEnabled(false);
|
||||||
|
|
||||||
stopPlaying = new JButtonSpacePlay(Icons.stop, "Stop playing", new ActionListener() {
|
stopPlaying = new JButtonSpacePlay(Icons.stop, "Stop playing", new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
root.stopPlaying();
|
root.stopPlaying();
|
||||||
@@ -89,6 +102,7 @@ public class MainToolBar extends JToolBar {
|
|||||||
eq = new JButtonSpacePlay(Icons.eq, "Reload Effects", new ActionListener() {
|
eq = new JButtonSpacePlay(Icons.eq, "Reload Effects", new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
root.loadEffects();
|
root.loadEffects();
|
||||||
|
CacheManager.purgeCache();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -117,11 +131,56 @@ public class MainToolBar extends JToolBar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
add(mic);
|
add(mic);
|
||||||
|
|
||||||
|
addSeparator();
|
||||||
|
|
||||||
|
disableEffects = new JToggleButtonSpacePlay(Icons.disable, "Disable effects", new ActionListener() {
|
||||||
|
Color bgCol = null;
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
JToggleButton b = (JToggleButton)e.getSource();
|
||||||
|
if (b.isSelected()) {
|
||||||
|
root.setEffectsEnabled(false);
|
||||||
|
bgCol = b.getBackground();
|
||||||
|
b.setBackground(Color.RED);
|
||||||
|
} else {
|
||||||
|
root.setEffectsEnabled(true);
|
||||||
|
if (bgCol != null) {
|
||||||
|
b.setBackground(bgCol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
add(disableEffects);
|
||||||
|
|
||||||
|
addSeparator();
|
||||||
|
|
||||||
|
add(new JLabel("Playback speed: "));
|
||||||
|
playbackSpeed = new JComboBox<String>(new String[] {
|
||||||
|
"0.75x",
|
||||||
|
"1.00x",
|
||||||
|
"1.25x",
|
||||||
|
"1.50x",
|
||||||
|
"1.75x"
|
||||||
|
});
|
||||||
|
playbackSpeed.setFocusable(false);
|
||||||
|
|
||||||
|
playbackSpeed.setSelectedIndex(1);
|
||||||
|
add(playbackSpeed);
|
||||||
|
|
||||||
setFloatable(false);
|
setFloatable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void enablePlayTo(boolean b) {
|
||||||
|
playtoSentence.setEnabled(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getPlaybackSpeed() {
|
||||||
|
int v = playbackSpeed.getSelectedIndex();
|
||||||
|
return 0.75f + (0.25f * v);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ public class Options extends JDialog {
|
|||||||
JComboBox<KVPair> rateList;
|
JComboBox<KVPair> rateList;
|
||||||
JComboBox<KVPair> bitDepth;
|
JComboBox<KVPair> bitDepth;
|
||||||
JComboBox<KVPair> trimMethod;
|
JComboBox<KVPair> trimMethod;
|
||||||
|
JComboBox<KVPair> fftBlockSize;
|
||||||
|
JComboBox<KVPair> playbackBlockSize;
|
||||||
JTextField storageFolder;
|
JTextField storageFolder;
|
||||||
JTextField archiveFolder;
|
JTextField archiveFolder;
|
||||||
JSpinner preChapterGap;
|
JSpinner preChapterGap;
|
||||||
@@ -34,6 +36,7 @@ public class Options extends JDialog {
|
|||||||
JSpinner postSectionGap;
|
JSpinner postSectionGap;
|
||||||
JTextField ffmpegLocation;
|
JTextField ffmpegLocation;
|
||||||
JComboBox<KVPair> bitRate;
|
JComboBox<KVPair> bitRate;
|
||||||
|
JComboBox<KVPair> channels;
|
||||||
JComboBox<KVPair> exportRate;
|
JComboBox<KVPair> exportRate;
|
||||||
JCheckBox enableParsing;
|
JCheckBox enableParsing;
|
||||||
JSpinner cacheSize;
|
JSpinner cacheSize;
|
||||||
@@ -44,8 +47,6 @@ public class Options extends JDialog {
|
|||||||
JSpinner etherealAttenuation;
|
JSpinner etherealAttenuation;
|
||||||
JSpinner etherealOffset;
|
JSpinner etherealOffset;
|
||||||
|
|
||||||
JTextField havenApiKey;
|
|
||||||
|
|
||||||
JTextField externalEditor;
|
JTextField externalEditor;
|
||||||
|
|
||||||
JTextArea startupScript;
|
JTextArea startupScript;
|
||||||
@@ -299,10 +300,12 @@ public class Options extends JDialog {
|
|||||||
bitDepth = addDropdown(optionsPanel, "Sample resolution:", getResolutionList(), get("audio.recording.resolution"));
|
bitDepth = addDropdown(optionsPanel, "Sample resolution:", getResolutionList(), get("audio.recording.resolution"));
|
||||||
trimMethod = addDropdown(optionsPanel, "Auto-trim method:", getTrimMethods(), get("audio.recording.trim"));
|
trimMethod = addDropdown(optionsPanel, "Auto-trim method:", getTrimMethods(), get("audio.recording.trim"));
|
||||||
fftThreshold = addSpinner(optionsPanel, "FFT threshold:", 0, 100, 1, getInteger("audio.recording.trim.fft"), "");
|
fftThreshold = addSpinner(optionsPanel, "FFT threshold:", 0, 100, 1, getInteger("audio.recording.trim.fft"), "");
|
||||||
|
fftBlockSize = addDropdown(optionsPanel, "FFT Block size:", getFFTBlockSizes(), get("audio.recording.trim.blocksize"));
|
||||||
|
|
||||||
addSeparator(optionsPanel);
|
addSeparator(optionsPanel);
|
||||||
|
|
||||||
playbackList = addDropdown(optionsPanel, "Playback device:", getPlaybackMixerList(), get("audio.playback.device"));
|
playbackList = addDropdown(optionsPanel, "Playback device:", getPlaybackMixerList(), get("audio.playback.device"));
|
||||||
|
playbackBlockSize = addDropdown(optionsPanel, "Playback Block size:", getPlaybackBlockSizes(), get("audio.playback.blocksize"));
|
||||||
addSeparator(optionsPanel);
|
addSeparator(optionsPanel);
|
||||||
storageFolder = addFilePath(optionsPanel, "Storage folder:", get("path.storage"), true);
|
storageFolder = addFilePath(optionsPanel, "Storage folder:", get("path.storage"), true);
|
||||||
archiveFolder = addFilePath(optionsPanel, "Archive folder:", get("path.archive"), true);
|
archiveFolder = addFilePath(optionsPanel, "Archive folder:", get("path.archive"), true);
|
||||||
@@ -320,21 +323,21 @@ public class Options extends JDialog {
|
|||||||
|
|
||||||
ffmpegLocation = addFilePath(optionsPanel, "FFMPEG location:", get("path.ffmpeg"), false);
|
ffmpegLocation = addFilePath(optionsPanel, "FFMPEG location:", get("path.ffmpeg"), false);
|
||||||
bitRate = addDropdown(optionsPanel, "Export bitrate:", getBitrates(), get("audio.export.bitrate"));
|
bitRate = addDropdown(optionsPanel, "Export bitrate:", getBitrates(), get("audio.export.bitrate"));
|
||||||
|
channels = addDropdown(optionsPanel, "Export channels:", getChannelCountList(), get("audio.export.channels"));
|
||||||
exportRate = addDropdown(optionsPanel, "Export sample rate:", getSampleRateList(), get("audio.export.samplerate"));
|
exportRate = addDropdown(optionsPanel, "Export sample rate:", getSampleRateList(), get("audio.export.samplerate"));
|
||||||
|
|
||||||
|
|
||||||
addSeparator(optionsPanel);
|
addSeparator(optionsPanel);
|
||||||
|
|
||||||
enableParsing = addCheckBox(optionsPanel, "Enable automatic speech-to-text submission", getBoolean("process.haven.auto"));
|
enableParsing = addCheckBox(optionsPanel, "Enable automatic sphinx speech-to-text (**SLOW**)", getBoolean("process.sphinx"));
|
||||||
havenApiKey = addTextField(optionsPanel, "Haven OnDemand API Key", get("process.haven.apikey"));
|
|
||||||
|
|
||||||
addSeparator(optionsPanel);
|
addSeparator(optionsPanel);
|
||||||
|
|
||||||
externalEditor = addTextField(optionsPanel, "External Editor Command", get("editor.external"));
|
externalEditor = addTextField(optionsPanel, "External Editor Command", get("editor.external"));
|
||||||
|
|
||||||
addSeparator(optionsPanel);
|
addSeparator(optionsPanel);
|
||||||
|
|
||||||
cacheSize = addSpinner(optionsPanel, "Cache size:", 0, 5000, 1, getInteger("cache.size"), "");
|
cacheSize = addSpinner(optionsPanel, "Cache size:", 2, 100, 1, getInteger("cache.size"), "");
|
||||||
|
|
||||||
addSeparator(optionsPanel);
|
addSeparator(optionsPanel);
|
||||||
tabs.add("Options", new JScrollPane(optionsPanel));
|
tabs.add("Options", new JScrollPane(optionsPanel));
|
||||||
@@ -568,6 +571,8 @@ public class Options extends JDialog {
|
|||||||
} else {
|
} else {
|
||||||
defaultPrefs.put("audio.playback.device", "");
|
defaultPrefs.put("audio.playback.device", "");
|
||||||
}
|
}
|
||||||
|
defaultPrefs.put("audio.recording.trim.blocksize", "4096");
|
||||||
|
defaultPrefs.put("audio.playback.blocksize", "4096");
|
||||||
|
|
||||||
defaultPrefs.put("catenation.pre-chapter", "1000");
|
defaultPrefs.put("catenation.pre-chapter", "1000");
|
||||||
defaultPrefs.put("catenation.post-chapter", "1500");
|
defaultPrefs.put("catenation.post-chapter", "1500");
|
||||||
@@ -583,10 +588,9 @@ public class Options extends JDialog {
|
|||||||
defaultPrefs.put("path.ffmpeg", "");
|
defaultPrefs.put("path.ffmpeg", "");
|
||||||
|
|
||||||
defaultPrefs.put("audio.export.bitrate", "256000");
|
defaultPrefs.put("audio.export.bitrate", "256000");
|
||||||
|
defaultPrefs.put("audio.export.channels", "2");
|
||||||
defaultPrefs.put("audio.export.samplerate", "44100");
|
defaultPrefs.put("audio.export.samplerate", "44100");
|
||||||
|
|
||||||
defaultPrefs.put("process.sphinx", "false");
|
defaultPrefs.put("process.sphinx", "false");
|
||||||
defaultPrefs.put("process.haven.apikey", "");
|
|
||||||
|
|
||||||
defaultPrefs.put("editor.external", "");
|
defaultPrefs.put("editor.external", "");
|
||||||
|
|
||||||
@@ -708,12 +712,14 @@ public class Options extends JDialog {
|
|||||||
set("catenation.post-paragraph", postParagraphGap.getValue());
|
set("catenation.post-paragraph", postParagraphGap.getValue());
|
||||||
set("catenation.post-section", postSectionGap.getValue());
|
set("catenation.post-section", postSectionGap.getValue());
|
||||||
set("audio.export.bitrate", ((KVPair)bitRate.getSelectedItem()).key);
|
set("audio.export.bitrate", ((KVPair)bitRate.getSelectedItem()).key);
|
||||||
|
set("audio.export.channels", ((KVPair)channels.getSelectedItem()).key);
|
||||||
set("audio.export.samplerate", ((KVPair)exportRate.getSelectedItem()).key);
|
set("audio.export.samplerate", ((KVPair)exportRate.getSelectedItem()).key);
|
||||||
set("process.sphinx", enableParsing.isSelected());
|
set("process.sphinx", enableParsing.isSelected());
|
||||||
set("process.haven.apikey", havenApiKey.getText());
|
|
||||||
set("editor.external", externalEditor.getText());
|
set("editor.external", externalEditor.getText());
|
||||||
set("cache.size", cacheSize.getValue());
|
set("cache.size", cacheSize.getValue());
|
||||||
set("audio.recording.trim.fft", fftThreshold.getValue());
|
set("audio.recording.trim.fft", fftThreshold.getValue());
|
||||||
|
set("audio.recording.trim.blocksize", ((KVPair)fftBlockSize.getSelectedItem()).key);
|
||||||
|
set("audio.playback.blocksize", ((KVPair)playbackBlockSize.getSelectedItem()).key);
|
||||||
|
|
||||||
set("effects.ethereal.offset", etherealOffset.getValue());
|
set("effects.ethereal.offset", etherealOffset.getValue());
|
||||||
set("effects.ethereal.iterations", etherealIterations.getValue());
|
set("effects.ethereal.iterations", etherealIterations.getValue());
|
||||||
@@ -781,12 +787,38 @@ public class Options extends JDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static KVPair[] getTrimMethods() {
|
public static KVPair[] getTrimMethods() {
|
||||||
KVPair[] pairs = new KVPair[2];
|
KVPair[] pairs = new KVPair[3];
|
||||||
pairs[0] = new KVPair<String, String>("peak", "Peak Amplitude");
|
pairs[0] = new KVPair<String, String>("none", "None");
|
||||||
pairs[1] = new KVPair<String, String>("fft", "FFT Analysis");
|
pairs[1] = new KVPair<String, String>("peak", "Peak Amplitude");
|
||||||
|
pairs[2] = new KVPair<String, String>("fft", "FFT Analysis");
|
||||||
return pairs;
|
return pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static KVPair[] getFFTBlockSizes() {
|
||||||
|
KVPair[] pairs = new KVPair[8];
|
||||||
|
pairs[0] = new KVPair<String, String>("1024", "1024");
|
||||||
|
pairs[1] = new KVPair<String, String>("2048", "2048");
|
||||||
|
pairs[2] = new KVPair<String, String>("4096", "4096");
|
||||||
|
pairs[3] = new KVPair<String, String>("8192", "8192");
|
||||||
|
pairs[4] = new KVPair<String, String>("16384", "16384");
|
||||||
|
pairs[5] = new KVPair<String, String>("32768", "32768");
|
||||||
|
pairs[6] = new KVPair<String, String>("65536", "65537");
|
||||||
|
pairs[7] = new KVPair<String, String>("131072", "131072");
|
||||||
|
return pairs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static KVPair[] getPlaybackBlockSizes() {
|
||||||
|
KVPair[] pairs = new KVPair[8];
|
||||||
|
pairs[0] = new KVPair<String, String>("1024", "1024");
|
||||||
|
pairs[1] = new KVPair<String, String>("2048", "2048");
|
||||||
|
pairs[2] = new KVPair<String, String>("4096", "4096");
|
||||||
|
pairs[3] = new KVPair<String, String>("8192", "8192");
|
||||||
|
pairs[4] = new KVPair<String, String>("16384", "16384");
|
||||||
|
pairs[5] = new KVPair<String, String>("32768", "32768");
|
||||||
|
pairs[6] = new KVPair<String, String>("65536", "65537");
|
||||||
|
pairs[7] = new KVPair<String, String>("131072", "131072");
|
||||||
|
return pairs;
|
||||||
|
}
|
||||||
|
|
||||||
public static void createEffectChains() {
|
public static void createEffectChains() {
|
||||||
effectChains = new ArrayList<EffectGroup>();
|
effectChains = new ArrayList<EffectGroup>();
|
||||||
|
|||||||
52
src/uk/co/majenko/audiobookrecorder/Pan.java
Normal file
52
src/uk/co/majenko/audiobookrecorder/Pan.java
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package uk.co.majenko.audiobookrecorder;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class Pan implements Effect {
|
||||||
|
double pan;
|
||||||
|
public Pan() {
|
||||||
|
pan = 0.0d;
|
||||||
|
}
|
||||||
|
public Pan(double p) {
|
||||||
|
pan = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return "Pan (" + pan + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Effect> getChildEffects() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void process(double[][] samples) {
|
||||||
|
for (double[] sample : samples) {
|
||||||
|
if (pan < 0) {
|
||||||
|
double p = 1 + pan;
|
||||||
|
sample[Sentence.RIGHT] *= p;
|
||||||
|
} else {
|
||||||
|
double p = 1 - pan;
|
||||||
|
sample[Sentence.LEFT] *= p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPan() {
|
||||||
|
return pan;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPan(double p) {
|
||||||
|
pan = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dump() {
|
||||||
|
System.out.println(toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(double sf) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
package uk.co.majenko.audiobookrecorder;
|
|
||||||
|
|
||||||
public class Sample {
|
|
||||||
double left;
|
|
||||||
double right;
|
|
||||||
|
|
||||||
public Sample(double m) {
|
|
||||||
left = m;
|
|
||||||
right = m;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Sample(double l, double r) {
|
|
||||||
left = l;
|
|
||||||
right = r;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getLeft() {
|
|
||||||
return left;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getRight() {
|
|
||||||
return right;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getMono() {
|
|
||||||
return (left + right) / 2.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -63,4 +63,17 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long millis = System.currentTimeMillis();
|
||||||
|
|
||||||
|
public static void report(String tag) {
|
||||||
|
long t = System.currentTimeMillis();
|
||||||
|
long d = t - millis;
|
||||||
|
millis = t;
|
||||||
|
System.err.println(String.format("%10d - %10s : %8d | %8d | %8d", d, tag,
|
||||||
|
Runtime.getRuntime().totalMemory(),
|
||||||
|
Runtime.getRuntime().maxMemory(),
|
||||||
|
Runtime.getRuntime().freeMemory()
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import javax.sound.sampled.*;
|
|||||||
|
|
||||||
public class Waveform extends JPanel implements MouseListener, MouseMotionListener {
|
public class Waveform extends JPanel implements MouseListener, MouseMotionListener {
|
||||||
|
|
||||||
double[] samples = null;
|
double[][] samples = null;
|
||||||
|
|
||||||
int leftMarker = 0;
|
int leftMarker = 0;
|
||||||
int rightMarker = 0;
|
int rightMarker = 0;
|
||||||
@@ -21,6 +21,11 @@ public class Waveform extends JPanel implements MouseListener, MouseMotionListen
|
|||||||
int leftAltMarker = 0;
|
int leftAltMarker = 0;
|
||||||
int rightAltMarker = 0;
|
int rightAltMarker = 0;
|
||||||
|
|
||||||
|
int cutEntry = 0;
|
||||||
|
int cutExit = 0;
|
||||||
|
boolean displayCut = false;
|
||||||
|
boolean displaySplit = false;
|
||||||
|
|
||||||
int dragging = 0;
|
int dragging = 0;
|
||||||
|
|
||||||
int step = 1;
|
int step = 1;
|
||||||
@@ -92,7 +97,7 @@ public class Waveform extends JPanel implements MouseListener, MouseMotionListen
|
|||||||
double lmax = 0;
|
double lmax = 0;
|
||||||
|
|
||||||
for (int o = 0; o < step; o++) {
|
for (int o = 0; o < step; o++) {
|
||||||
double sample = samples[offset + (n * step) + o];
|
double sample = (samples[offset + (n * step) + o][Sentence.LEFT] + samples[offset + (n * step) + o][Sentence.RIGHT]) / 2d;
|
||||||
if (sample >= 0) {
|
if (sample >= 0) {
|
||||||
have += sample;
|
have += sample;
|
||||||
hcnt++;
|
hcnt++;
|
||||||
@@ -133,7 +138,7 @@ public class Waveform extends JPanel implements MouseListener, MouseMotionListen
|
|||||||
g.drawLine(n, (int)(h/2 + lave), n, (int)(h/2 - have));
|
g.drawLine(n, (int)(h/2 + lave), n, (int)(h/2 - have));
|
||||||
}
|
}
|
||||||
|
|
||||||
g.setColor(new Color(255, 0, 0, 32));
|
g.setColor(new Color(255, 0, 0, 64));
|
||||||
g.fillRect(0, 0, (leftAltMarker - offset)/step, h);
|
g.fillRect(0, 0, (leftAltMarker - offset)/step, h);
|
||||||
g.fillRect((rightAltMarker - offset)/step, 0, (num - rightAltMarker) / step , h);
|
g.fillRect((rightAltMarker - offset)/step, 0, (num - rightAltMarker) / step , h);
|
||||||
|
|
||||||
@@ -145,6 +150,19 @@ public class Waveform extends JPanel implements MouseListener, MouseMotionListen
|
|||||||
g.drawLine((leftMarker - offset)/step, 0, (leftMarker - offset)/step, h);
|
g.drawLine((leftMarker - offset)/step, 0, (leftMarker - offset)/step, h);
|
||||||
g.drawLine((rightMarker - offset)/step, 0, (rightMarker - offset)/step, h);
|
g.drawLine((rightMarker - offset)/step, 0, (rightMarker - offset)/step, h);
|
||||||
|
|
||||||
|
if (displayCut || displaySplit) {
|
||||||
|
g.setColor(new Color(0, 255, 255));
|
||||||
|
g.drawLine((cutEntry - offset)/step, 0, (cutEntry - offset)/step, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (displayCut) {
|
||||||
|
g.setColor(new Color(0, 255, 255));
|
||||||
|
g.drawLine((cutExit - offset)/step, 0, (cutExit - offset)/step, h);
|
||||||
|
|
||||||
|
g.setColor(new Color(0, 255, 255, 80));
|
||||||
|
g.fillRect((cutEntry - offset)/step, 0, ((cutExit - offset) - (cutEntry - offset))/step , h);
|
||||||
|
}
|
||||||
|
|
||||||
g.setColor(new Color(0, 255, 255));
|
g.setColor(new Color(0, 255, 255));
|
||||||
for (int i = 0; i < h; i += 2) {
|
for (int i = 0; i < h; i += 2) {
|
||||||
g.drawLine((playMarker - offset) / step, i, (playMarker - offset) / step, i);
|
g.drawLine((playMarker - offset) / step, i, (playMarker - offset) / step, i);
|
||||||
@@ -189,9 +207,11 @@ public class Waveform extends JPanel implements MouseListener, MouseMotionListen
|
|||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setData(double[] s) {
|
public void setData(double[][] s) {
|
||||||
samples = s;
|
samples = s;
|
||||||
playMarker = 0;
|
playMarker = 0;
|
||||||
|
displayCut = false;
|
||||||
|
displaySplit = false;
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,6 +241,19 @@ public class Waveform extends JPanel implements MouseListener, MouseMotionListen
|
|||||||
dragging = 2;
|
dragging = 2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (displayCut || displaySplit) {
|
||||||
|
if ((x >= ((cutEntry - offset)/step) - 10) && (x <= ((cutEntry - offset)/step) + 10)) {
|
||||||
|
dragging = 3;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (displayCut) {
|
||||||
|
if ((x >= ((cutExit - offset)/step) - 10) && (x <= ((cutExit - offset)/step) + 10)) {
|
||||||
|
dragging = 4;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void mouseReleased(MouseEvent e) {
|
public void mouseReleased(MouseEvent e) {
|
||||||
@@ -251,6 +284,19 @@ public class Waveform extends JPanel implements MouseListener, MouseMotionListen
|
|||||||
setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
|
setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (displayCut || displaySplit) {
|
||||||
|
if ((x >= ((cutEntry - offset)/step) - 10) && (x <= ((cutEntry - offset)/step) + 10)) {
|
||||||
|
setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (displayCut) {
|
||||||
|
if ((x >= ((cutExit - offset)/step) - 10) && (x <= ((cutExit - offset)/step) + 10)) {
|
||||||
|
setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
|
|
||||||
@@ -270,6 +316,18 @@ public class Waveform extends JPanel implements MouseListener, MouseMotionListen
|
|||||||
if (rightMarker < leftMarker) {
|
if (rightMarker < leftMarker) {
|
||||||
rightMarker = leftMarker;
|
rightMarker = leftMarker;
|
||||||
}
|
}
|
||||||
|
} else if (dragging == 3) {
|
||||||
|
cutEntry = (x * step) + offset;
|
||||||
|
if (displayCut) {
|
||||||
|
if (cutEntry > cutExit) {
|
||||||
|
cutEntry = cutExit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (dragging == 4) {
|
||||||
|
cutExit = (x * step) + offset;
|
||||||
|
if (cutExit < cutEntry) {
|
||||||
|
cutExit = cutEntry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
repaint();
|
repaint();
|
||||||
@@ -299,4 +357,33 @@ public class Waveform extends JPanel implements MouseListener, MouseMotionListen
|
|||||||
playMarker = leftAltMarker + m;
|
playMarker = leftAltMarker + m;
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDisplayCut(boolean c) {
|
||||||
|
displayCut = c;
|
||||||
|
displaySplit = false;
|
||||||
|
if (displayCut) {
|
||||||
|
int d = rightMarker - leftMarker;
|
||||||
|
cutEntry = leftMarker + (d / 3);
|
||||||
|
cutExit = leftMarker + (d / 3 * 2);
|
||||||
|
}
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplaySplit(boolean c) {
|
||||||
|
displayCut = false;
|
||||||
|
displaySplit = c;
|
||||||
|
if (displaySplit) {
|
||||||
|
int d = rightMarker - leftMarker;
|
||||||
|
cutEntry = leftMarker + (d / 2);
|
||||||
|
}
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCutStart() {
|
||||||
|
return cutEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCutEnd() {
|
||||||
|
return cutExit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user