Added release version checker

This commit is contained in:
2020-02-03 20:27:15 +00:00
parent c67e6d6abc
commit 746f47a5fa
10 changed files with 231 additions and 176 deletions

BIN
deps/json-20190722.jar LFS vendored Normal file

Binary file not shown.

View File

@@ -1 +1 @@
version=0.3.8
version=0.3.9

View File

@@ -149,7 +149,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
JPanel statusBar;
JLabel statusLabel;
NoiseFloor noiseFloorLabel;
JScrollPane mainScroll;
@@ -767,11 +767,13 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
centralPanel.add(sampleControl, BorderLayout.SOUTH);
statusBar = new JPanel();
statusBar.setLayout(new FlowLayout(FlowLayout.CENTER));
statusBar.setLayout(new FlowLayout(FlowLayout.RIGHT));
add(statusBar, BorderLayout.SOUTH);
statusLabel = new JLabel("Noise floor: " + getNoiseFloorDB() + "dB");
statusBar.add(statusLabel);
noiseFloorLabel = new NoiseFloor();
statusBar.add(noiseFloorLabel);
// statusBar.add(Box.createHorizontalStrut(2));
statusBar.add(queueMonitor);
buildToolbar(centralPanel);
@@ -1010,6 +1012,8 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
Options.savePreferences();
}
queueJob(new VersionChecker());
}
void bindKeys(JComponent component) {
@@ -2328,7 +2332,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
bookTree.expandPath(new TreePath(book.getPath()));
statusLabel.setText("Noise floor: " + getNoiseFloorDB() + "dB");
noiseFloorLabel.setNoiseFloor(getNoiseFloorDB());
} catch (Exception ex) {
ex.printStackTrace();
@@ -2586,7 +2590,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
bookTree.expandPath(new TreePath(book.getPath()));
statusLabel.setText("Noise floor: " + getNoiseFloorDB() + "dB");
noiseFloorLabel.setNoiseFloor(getNoiseFloorDB());
book.setIcon(Icons.book);
}
@@ -2659,7 +2663,7 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
Debug.trace();
roomNoise.stopRecording();
centralPanel.setFlash(false);
statusLabel.setText("Noise floor: " + getNoiseFloorDB() + "dB");
noiseFloorLabel.setNoiseFloor(getNoiseFloorDB());
}
}, 5000); // 5 seconds of recording
}
@@ -4194,7 +4198,10 @@ public class AudiobookRecorder extends JFrame implements DocumentListener {
}
}
if (orphans.getChildCount() == 0) {
bookTreeModel.removeNodeFromParent(orphans);
try {
bookTreeModel.removeNodeFromParent(orphans);
} catch (Exception ignored) {
}
}
}

View File

@@ -1,23 +1,5 @@
package uk.co.majenko.audiobookrecorder;
// Biquad.java
//
// Created by Nigel Redmon on 11/24/12
// EarLevel Engineering: earlevel.com
// Copyright 2012 Nigel Redmon
// Translated to Java 2019 Majenko Technologies
//
// For a complete explanation of the Biquad code:
// http://www.earlevel.com/main/2012/11/26/biquad-c-source-code/
//
// License:
//
// This source code is provided as is, without warranty.
// You may copy and distribute verbatim copies of this document.
// You may modify and use this source code to create binary code
// for your own purposes, free or commercial.
//
import java.util.ArrayList;
public class Biquad implements Effect {

View File

@@ -450,7 +450,10 @@ public class Book extends BookTreeNode {
public void run() {
if (AudiobookRecorder.window == null) return;
if (AudiobookRecorder.window.bookTreeModel == null) return;
AudiobookRecorder.window.bookTreeModel.reload(Book.this);
try {
AudiobookRecorder.window.bookTreeModel.reload(Book.this);
} catch (Exception ignored) {
}
}
});
}

View File

@@ -1,130 +1,93 @@
package uk.co.majenko.audiobookrecorder;
/**
* @author Orlando Selenu
*
*/
public class FFT {
/**
* The Fast Fourier Transform (generic version, with NO optimizations).
*
* @param inputReal
* an array of length n, the real part
* @param inputImag
* an array of length n, the imaginary part
* @param DIRECT
* TRUE = direct transform, FALSE = inverse transform
* @return a new array of length 2n
*/
public static double[] fft(final double[] inputReal, double[] inputImag,
boolean DIRECT) {
// - n is the dimension of the problem
// - nu is its logarithm in base e
int n = inputReal.length;
public static double[] fft(final double[] inputReal, double[] inputImag, boolean DIRECT) {
int n = inputReal.length;
// If n is a power of 2, then ld is an integer (_without_ decimals)
double ld = Math.log(n) / Math.log(2.0);
double ld = Math.log(n) / Math.log(2.0);
// Here I check if n is a power of 2. If exist decimals in ld, I quit
// from the function returning null.
if (((int) ld) - ld != 0) {
System.out.println("The number of elements is not a power of 2.");
return null;
}
if (((int) ld) - ld != 0) {
System.out.println("The number of elements is not a power of 2.");
return null;
}
// Declaration and initialization of the variables
// ld should be an integer, actually, so I don't lose any information in
// the cast
int nu = (int) ld;
int n2 = n / 2;
int nu1 = nu - 1;
double[] xReal = new double[n];
double[] xImag = new double[n];
double tReal, tImag, p, arg, c, s;
int nu = (int) ld;
int n2 = n / 2;
int nu1 = nu - 1;
double[] xReal = new double[n];
double[] xImag = new double[n];
double tReal, tImag, p, arg, c, s;
double constant;
if (DIRECT) {
constant = -2 * Math.PI;
} else {
constant = 2 * Math.PI;
}
// Here I check if I'm going to do the direct transform or the inverse
// transform.
double constant;
if (DIRECT)
constant = -2 * Math.PI;
else
constant = 2 * Math.PI;
for (int i = 0; i < n; i++) {
xReal[i] = inputReal[i];
xImag[i] = inputImag[i];
}
// I don't want to overwrite the input arrays, so here I copy them. This
// choice adds \Theta(2n) to the complexity.
for (int i = 0; i < n; i++) {
xReal[i] = inputReal[i];
xImag[i] = inputImag[i];
}
// First phase - calculation
int k = 0;
for (int l = 1; l <= nu; l++) {
while (k < n) {
for (int i = 1; i <= n2; i++) {
p = bitreverseReference(k >> nu1, nu);
// direct FFT or inverse FFT
arg = constant * p / n;
c = Math.cos(arg);
s = Math.sin(arg);
tReal = xReal[k + n2] * c + xImag[k + n2] * s;
tImag = xImag[k + n2] * c - xReal[k + n2] * s;
xReal[k + n2] = xReal[k] - tReal;
xImag[k + n2] = xImag[k] - tImag;
xReal[k] += tReal;
xImag[k] += tImag;
k++;
int k = 0;
for (int l = 1; l <= nu; l++) {
while (k < n) {
for (int i = 1; i <= n2; i++) {
p = bitreverseReference(k >> nu1, nu);
// direct FFT or inverse FFT
arg = constant * p / n;
c = Math.cos(arg);
s = Math.sin(arg);
tReal = xReal[k + n2] * c + xImag[k + n2] * s;
tImag = xImag[k + n2] * c - xReal[k + n2] * s;
xReal[k + n2] = xReal[k] - tReal;
xImag[k + n2] = xImag[k] - tImag;
xReal[k] += tReal;
xImag[k] += tImag;
k++;
}
k += n2;
}
k += n2;
k = 0;
nu1--;
n2 /= 2;
}
k = 0;
nu1--;
n2 /= 2;
}
// Second phase - recombination
k = 0;
int r;
while (k < n) {
r = bitreverseReference(k, nu);
if (r > k) {
tReal = xReal[k];
tImag = xImag[k];
xReal[k] = xReal[r];
xImag[k] = xImag[r];
xReal[r] = tReal;
xImag[r] = tImag;
int r;
while (k < n) {
r = bitreverseReference(k, nu);
if (r > k) {
tReal = xReal[k];
tImag = xImag[k];
xReal[k] = xReal[r];
xImag[k] = xImag[r];
xReal[r] = tReal;
xImag[r] = tImag;
}
k++;
}
k++;
double[] newArray = new double[xReal.length * 2];
double radice = 1 / Math.sqrt(n);
for (int i = 0; i < newArray.length; i += 2) {
int i2 = i / 2;
newArray[i] = xReal[i2] * radice;
newArray[i + 1] = xImag[i2] * radice;
}
return newArray;
}
// Here I have to mix xReal and xImag to have an array (yes, it should
// be possible to do this stuff in the earlier parts of the code, but
// it's here to readibility).
double[] newArray = new double[xReal.length * 2];
double radice = 1 / Math.sqrt(n);
for (int i = 0; i < newArray.length; i += 2) {
int i2 = i / 2;
// I used Stephen Wolfram's Mathematica as a reference so I'm going
// to normalize the output while I'm copying the elements.
newArray[i] = xReal[i2] * radice;
newArray[i + 1] = xImag[i2] * radice;
private static int bitreverseReference(int j, int nu) {
int j2;
int j1 = j;
int k = 0;
for (int i = 1; i <= nu; i++) {
j2 = j1 / 2;
k = 2 * k + j1 - 2 * j2;
j1 = j2;
}
return k;
}
return newArray;
}
/**
* The reference bitreverse function.
*/
private static int bitreverseReference(int j, int nu) {
int j2;
int j1 = j;
int k = 0;
for (int i = 1; i <= nu; i++) {
j2 = j1 / 2;
k = 2 * k + j1 - 2 * j2;
j1 = j2;
}
return k;
}
}

View File

@@ -14,10 +14,6 @@ public class KVPair<K,V> implements Comparable {
}
public int compareTo(Object o) {
// if (o instanceof KVPair) {
// KVPair ko = (KVPair)o;
// return key.compareTo(ko.key);
// }
return 0;
}

View File

@@ -0,0 +1,51 @@
package uk.co.majenko.audiobookrecorder;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Dimension;
import java.awt.Color;
public class NoiseFloor extends JPanel {
int noiseFloor = 0;
public NoiseFloor() {
super();
noiseFloor = 0;
}
public void setNoiseFloor(int n) {
noiseFloor = n;
repaint();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(128, 24);
}
@Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
@Override
public Dimension getMaximumSize() {
return getPreferredSize();
}
@Override
public void paintComponent(Graphics g) {
Rectangle size = g.getClipBounds();
g.setColor(getBackground());
g.fillRect(0, 0, size.width - 1, size.height - 1);
g.setColor(new Color(10, 10, 10));
g.drawRect(0, 0, size.width - 1, size.height - 1);
g.setFont(getFont());
g.setColor(getForeground());
g.drawString("Noise Floor: " + noiseFloor + "dB", 6, 16);
}
}

View File

@@ -1,33 +1,3 @@
/*
* Copyright (c) 2015, Majenko Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* * Neither the name of Majenko Technologies nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package uk.co.majenko.audiobookrecorder;
import javax.swing.ImageIcon;

View File

@@ -0,0 +1,80 @@
package uk.co.majenko.audiobookrecorder;
import java.lang.Runnable;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import org.json.JSONObject;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class VersionChecker implements Runnable {
public VersionChecker() {
}
public void run() {
try {
URL url = new URL("https://api.github.com/repos/MajenkoProjects/AudiobookRecorder/releases/latest");
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
InputStream is = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String inputLine;
StringBuilder jsonData = new StringBuilder();
while ((inputLine = br.readLine()) != null) {
jsonData.append(inputLine);
}
br.close();
JSONObject job = new JSONObject(jsonData.toString());
String installed = AudiobookRecorder.config.getProperty("version");
String available = job.getString("tag_name");
if (available.startsWith("v")) {
available = available.substring(1);
}
String website = job.getString("html_url");
String[] installedParts = installed.split("\\.");
String[] availableParts = available.split("\\.");
// Must be x.y.z
System.err.println(installedParts.length);
System.err.println(availableParts.length);
if (installedParts.length != 3) return;
if (availableParts.length != 3) return;
// Convert to xxxyyyzzz
String installedVersion = String.format("%03d%03d%03d", Utils.s2i(installedParts[0]), Utils.s2i(installedParts[1]), Utils.s2i(installedParts[2]));
String availableVersion = String.format("%03d%03d%03d", Utils.s2i(availableParts[0]), Utils.s2i(availableParts[1]), Utils.s2i(availableParts[2]));
if (Utils.s2i(installedVersion) >= Utils.s2i(availableVersion)) return;
System.err.println("Version installed: " + installed);
System.err.println("Version available: " + available);
System.err.println("URL: " + website);
JButton upgrade = new JButton("A new version is available.");
upgrade.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
Utils.browse(website);
}
});
AudiobookRecorder.window.statusBar.add(upgrade);
AudiobookRecorder.window.statusBar.revalidate();
} catch (Exception ignored) {
ignored.printStackTrace();
}
}
}