|
From: aperion <was...@us...> - 2009-07-22 14:32:17
|
Module: performous
Branch: ultraed
Commit: aec573babadcfa067bbf9dfa77526a61fe9bafde
Author: Christian Wasserthal <ap...@gm...>
Date: Wed Jul 22 16:31:19 2009 +0200
added two functions to the editor, to automatically adjust the #GAP
---
README.txt | 1 -
src/org/aperion/sound/FFTProject.java | 63 +++++++++++++++++++++++++++-
src/org/aperion/sound/swingui/MainGUI.java | 21 +++++++++
3 files changed, 83 insertions(+), 2 deletions(-)
diff --git a/README.txt b/README.txt
index b421a0e..f9d300a 100644
--- a/README.txt
+++ b/README.txt
@@ -22,7 +22,6 @@ What is not yet supported?
""""""""""""""""""""""""""
- take into account multiple channels
- use the harmonics to create a better contrast
- - changing notes
Dependencies.
diff --git a/src/org/aperion/sound/FFTProject.java b/src/org/aperion/sound/FFTProject.java
index 1bdde35..2066370 100644
--- a/src/org/aperion/sound/FFTProject.java
+++ b/src/org/aperion/sound/FFTProject.java
@@ -31,6 +31,8 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
+import javax.swing.JProgressBar;
+
import org.aperion.sound.TxtFile.NoteBar;
import org.aperion.util.AMath;
@@ -123,7 +125,7 @@ public class FFTProject{
}
}
catch(final ClassNotFoundException e){
- throw new IOException(e.toString());
+ throw new IOException(e.getMessage());
}
finally{
ois.close();
@@ -391,6 +393,65 @@ public class FFTProject{
}
}
+ public double linearGapSearch(final double stepInSeconds, final JProgressBar bar, final double[] harmonicWeights){
+ final double originalGap = txt.getGAP();
+ final int iMax = (int)((getLength()-txt.getNotes().last().getEndSecond()+originalGap)/stepInSeconds);
+ bar.setMinimum(0);
+ bar.setMaximum(iMax);
+ double bestGap = originalGap;
+ double bestScore = gapHelper(originalGap,harmonicWeights);
+ for(int i=0;i<iMax;i++){
+ bar.setValue(i);
+ final double score = gapHelper(i*stepInSeconds,harmonicWeights);
+ if(score>bestScore){
+ bestGap = i*stepInSeconds;
+ bestScore = score;
+ }
+ }
+ txt.setGAP(originalGap);
+ return bestGap;
+ }
+
+ public double optimizeGapLocally(final JProgressBar bar, final double[] harmonicWeights){
+ final double originalGap = txt.getGAP();
+ final double[] step = new double[]{0.1,0.01,0.001}; // seconds
+ double currentGap = originalGap;
+ double currentScore = gapHelper(originalGap,harmonicWeights);
+ bar.setMinimum(0);
+ bar.setMaximum(21*step.length);
+ for(int i=0;i<step.length;i++){
+ double bestGap = currentGap;
+ double bestScore = currentScore;
+ for(int j=-10;j<=10;j++){
+ bar.setValue(21*i+j+10);
+ final double score = gapHelper(currentGap+j*step[i],harmonicWeights);
+ if(score>bestScore){
+ bestGap = currentGap+j*step[i];
+ bestScore = score;
+ }
+ }
+ currentGap = bestGap;
+ currentScore = bestScore;
+ }
+ txt.setGAP(originalGap);
+ return currentGap;
+ }
+
+ /**
+ * Accumulates the note magnitudes with a different gap.
+ * @param newGap the #GAP to test
+ * @param harmonicWeights the harmonic weighting to use
+ * @return the sum of all note magnitudes
+ */
+ private double gapHelper(final double newGap, final double[] harmonicWeights){
+ txt.setGAP(newGap);
+ double score = 0d;
+ for(final NoteBar n:txt.getNotes()){
+ score += getHarmonicNoteMag(n,harmonicWeights);
+ }
+ return score;
+ }
+
/////////////////////////////////////////////////////////////////////////////////////////////////
public interface RepaintListener{
diff --git a/src/org/aperion/sound/swingui/MainGUI.java b/src/org/aperion/sound/swingui/MainGUI.java
index 30e7a5f..9ade467 100644
--- a/src/org/aperion/sound/swingui/MainGUI.java
+++ b/src/org/aperion/sound/swingui/MainGUI.java
@@ -61,6 +61,7 @@ import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
+import javax.swing.JProgressBar;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
@@ -151,6 +152,8 @@ public class MainGUI extends ClassLoader implements WindowListener, ActionListen
private final JMenuItem menuNotesAlign;
private final JMenuItem menuNotesTimer;
private final JMenuItem menuNotesClear;
+ private final JMenuItem menuNotesLinearGapSearch;
+ private final JMenuItem menuNotesOptimizeGap;
private final JButton playButton;
private final JButton stopButton;
@@ -286,6 +289,14 @@ public class MainGUI extends ClassLoader implements WindowListener, ActionListen
menuNotesClear.setMnemonic('c');
menuNotesClear.addActionListener(this);
menuNotes.add(menuNotesClear);
+ menuNotesLinearGapSearch = new JMenuItem("linear gap search");
+ menuNotesLinearGapSearch.setMnemonic('l');
+ menuNotesLinearGapSearch.addActionListener(this);
+ menuNotes.add(menuNotesLinearGapSearch);
+ menuNotesOptimizeGap = new JMenuItem("optimize gap locally");
+ menuNotesOptimizeGap.setMnemonic('o');
+ menuNotesOptimizeGap.addActionListener(this);
+ menuNotes.add(menuNotesOptimizeGap);
final JToolBar bar = new JToolBar();
bar.setFloatable(true);
@@ -844,6 +855,16 @@ public class MainGUI extends ClassLoader implements WindowListener, ActionListen
}
matchFreqBarToView();
}
+ else if(e.getSource()==menuNotesLinearGapSearch){
+ final JProgressBar bar = new JProgressBar(); // TODO there should be a progressbar somewhere to use
+ prj.getTextFile().setGAP(prj.linearGapSearch(0.5,bar,DEFAULT_HARMONIC_WEIGHTS));
+ cont.forceRepaint();
+ }
+ else if(e.getSource()==menuNotesOptimizeGap){
+ final JProgressBar bar = new JProgressBar(); // TODO there should be a progressbar somewhere to use
+ prj.getTextFile().setGAP(prj.optimizeGapLocally(bar,DEFAULT_HARMONIC_WEIGHTS));
+ cont.forceRepaint();
+ }
else{
throw new AssertionError();
}
|