This commit is contained in:
Gianpaolo Coro 2013-04-30 14:14:18 +00:00
parent d2fec70777
commit 61290b4c45
3 changed files with 611 additions and 0 deletions

View File

@ -0,0 +1,38 @@
package org.gcube.dataanalysis.ecoengine.signals;
public class Delta {
public static void calcDelta(double A[][], int numCoeff) throws Exception {
int delta;
for (int j = 0; j < numCoeff; j++) {
delta = j + numCoeff;
completeDelta(A, j, delta);
}
}
public static void calcDoubleDelta(double A[][], int numCoeff) throws Exception {
int fine = numCoeff * 2;
for (int delta = numCoeff; delta < fine; delta++) {
int doppioDelta = delta + numCoeff;
completeDelta(A, delta, doppioDelta);
}
}
private static void completeDelta(double A[][], int j, int d) throws Exception {
if (A.length < 4) {
throw new Exception();
}
if (A.length > 2) {
A[0][d] = A[1][j] - A[0][j];
A[1][d] = (A[2][j] - A[0][j]) - (A[0][j] - A[1][j]) / 4;
}
for (int i = 2; i < A.length - 2; i++)
A[i][d] = ((2 * (A[i + 2][j] - A[i - 2][j])) + (A[i + 1][j] - A[i - 1][j])) / 8;
if (A.length > 3) {
A[A.length - 2][d] = (A[A.length - 1][j] - A[A.length - 3][j]) - (A[A.length - 1][j] - A[A.length - 2][j]);
A[A.length - 1][d] = A[A.length - 2][j] - A[A.length - 1][j];
}
}
}

View File

@ -0,0 +1,273 @@
package org.gcube.dataanalysis.ecoengine.signals;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import javax.swing.JPanel;
import marytts.signalproc.display.SpectrogramCustom;
import marytts.signalproc.window.Window;
import com.rapidminer.example.Attribute;
import com.rapidminer.example.Example;
import com.rapidminer.example.ExampleSet;
import com.rapidminer.example.table.MemoryExampleTable;
/**
* includes tools for basic signal transformations:
* delta + double delta
* center frequency
* cepstral coefficients calculation
* spectrum frequency cut
* transformation to and from Rapid Miner Example Set
* filterbanks
* fequency to mel
* frequency to index in fft
* sinusoid signal generation
* inverse mel
* log10
* mel filterbanks
* sample to time and time to sample
* signal timeline generation
* index to time in spectrogram
* spectrogram calculation and display
* time to index in spectrogram
*
* @author coro
*
*/
public class SignalConversions {
public static double[][] addDeltaDouble(double[][] features) throws Exception{
int vectorL = features[0].length;
double[][] delta = new double[features.length][features[0].length*3];
for (int k=0;k<features.length;k++){
for (int g=0;g<vectorL;g++){
delta[k][g] = features[k][g];
}
}
Delta.calcDelta(delta, vectorL);
Delta.calcDoubleDelta(delta, vectorL);
return delta;
}
public static double centerFreq(int i, double samplingRate, double lowerFilterFreq, int numMelFilters) {
double mel[] = new double[2];
mel[0] = freqToMel(lowerFilterFreq);
mel[1] = freqToMel(samplingRate / 2);
// take inverse mel of:
double temp = mel[0] + ((mel[1] - mel[0]) / (numMelFilters + 1)) * i;
return inverseMel(temp);
}
public static double[] cepCoefficients(double f[], int numCepstra, int numFilters) {
double cepc[] = new double[numCepstra];
for (int i = 0; i < cepc.length; i++) {
for (int j = 1; j <= numFilters; j++) {
cepc[i] += f[j - 1] * Math.cos(Math.PI * i / numFilters * (j - 0.5));
}
}
return cepc;
}
public static BufferedImage createImage(JPanel panel) {
int w = panel.getWidth();
int h = panel.getHeight();
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
panel.paint(g);
return bi;
}
public static double[][] cutSpectrum(double[][] spectrum, float minFreq, float maxfreq, int fftWindowSize, int samplingRate) {
int minFrequencyIndex = frequencyIndex(minFreq, fftWindowSize, samplingRate);
int maxFrequencyIndex = frequencyIndex(maxfreq, fftWindowSize, samplingRate);
double[][] cutSpectrum = new double[spectrum.length][maxFrequencyIndex - minFrequencyIndex + 1];
for (int i = 0; i < spectrum.length; i++) {
cutSpectrum[i] = Arrays.copyOfRange(spectrum[i], minFrequencyIndex, maxFrequencyIndex);
}
return cutSpectrum;
}
public static void exampleSet2Signal(double[] rebuiltSignal, ExampleSet es) {
MemoryExampleTable met = (MemoryExampleTable) es.getExampleTable();
int numCol = met.getAttributeCount();
int numRows = met.size();
Attribute labelAtt = met.getAttribute(numCol - 1);
for (int i = 0; i < numRows; i++) {
int index = (int) met.getDataRow(i).get(labelAtt);
String label = labelAtt.getMapping().mapIndex(index);
int id = Integer.parseInt(label);
Example e = es.getExample(i);
// System.out.println(es.getExample(i)+"->"+signal[i]);
for (Attribute a : e.getAttributes()) {
rebuiltSignal[id] = e.getValue(a);
}
}
}
public static int[] fftBinIndices(double samplingRate, int frameSize, int numMelFilters, int numFequencies, float lowerFilterFreq, float upperFilterFreq) {
int cbin[] = new int[numFequencies+2];
System.out.println("New Filter banks: "+numFequencies);
cbin[0] = (int) Math.round(lowerFilterFreq / samplingRate * frameSize);
cbin[cbin.length - 1] = frequencyIndex(upperFilterFreq, frameSize, (float)samplingRate);
System.out.println("F0: "+lowerFilterFreq);
for (int i = 1; i <= numFequencies; i++) {
double fc = centerFreq(i, samplingRate, lowerFilterFreq, numMelFilters);
System.out.println("F"+(i)+": "+fc);
cbin[i] = (int) Math.round(fc / samplingRate * frameSize);
}
System.out.println("F"+(cbin.length - 1)+": "+upperFilterFreq);
return cbin;
}
public static int[] fftBinIndices(double samplingRate, int frameSize, int numMelFilters, float lowerFilterFreq) {
int cbin[] = new int[numMelFilters + 2];
cbin[0] = (int) Math.round(lowerFilterFreq / samplingRate * frameSize);
cbin[cbin.length - 1] = (int) (frameSize / 2);
for (int i = 1; i <= numMelFilters; i++) {
double fc = centerFreq(i, samplingRate, lowerFilterFreq, numMelFilters);
cbin[i] = (int) Math.round(fc / samplingRate * frameSize);
}
return cbin;
}
public static double freqToMel(double freq) {
return 2595 * log10(1 + freq / 700);
}
public static int frequencyIndex(float frequency, int fftSize, float samplingRate) {
return Math.round(frequency * fftSize / samplingRate);
}
static double[] generateSinSignal(int signalLength, float timeShift, float frequency) {
//final float frequency = 0.3f;// 1f;
double samples[] = new double[signalLength];
float time = 0;
for (int i = 0; i < samples.length; i++) {
samples[i] = (float) Math.sin(2f * Math.PI * frequency * time);
// time += 1f / (float) samplingRate;
time += timeShift;
}
return samples;
}
private static double inverseMel(double x) {
double temp = Math.pow(10, x / 2595) - 1;
return 700 * (temp);
}
public static double log10(double value) {
return Math.log(value) / Math.log(10);
}
public static double[] melFilter(double bin[], int cbin[], int numMelFilters) {
double temp[] = new double[numMelFilters + 2];
for (int k = 1; k <= numMelFilters; k++) {
double num1 = 0, num2 = 0;
for (int i = cbin[k - 1]; i <= cbin[k]; i++) {
num1 += ((i - cbin[k - 1] + 1) / (cbin[k] - cbin[k - 1] + 1)) * bin[i];
}
for (int i = cbin[k] + 1; i <= cbin[k + 1]; i++) {
num2 += (1 - ((i - cbin[k]) / (cbin[k + 1] - cbin[k] + 1))) * bin[i];
}
temp[k] = num1 + num2;
}
double fbank[] = new double[numMelFilters];
for (int i = 0; i < numMelFilters; i++) {
fbank[i] = temp[i + 1];
}
return fbank;
}
public static int recalculateMaxMelFilters(double samplingRate, int numMelFilters, float lowerFilterFreq, float maxFilterFreq){
int bestIndex=1;
for (int i = 1; i <= numMelFilters; i++) {
double fc = centerFreq(i, samplingRate, lowerFilterFreq, numMelFilters);
System.out.println("fc "+fc);
if (fc>maxFilterFreq){
bestIndex=i;
break;
}
}
return bestIndex-1;
}
public static double sample2Time(int sample, int sampleRate) {
return (double) sample / (double) sampleRate;
}
public static double[] signalTimeLine(int signalLength, double samplingRate) {
double time[] = new double[signalLength];
Arrays.fill(time, Double.NaN);
for (int i = 0; i < signalLength; i++) {
time[i] = (double) i / (double) samplingRate;
}
System.out.println("time " + time[signalLength - 1] * samplingRate + " vs " + signalLength);
return time;
}
public static float spectrumTime(float linearTime, float windowShiftTime) {
return linearTime / windowShiftTime;
}
public static double[][] spectrogram(String name, double[] signal, int samplingRate, int windowshift, int frameslength, boolean display) throws Exception {
SpectrogramCustom spec = new SpectrogramCustom(signal, samplingRate, Window.get(Window.HAMMING, frameslength), windowshift, frameslength, 640, 480);
double[][] spectrum = spec.spectra.toArray(new double[spec.spectra.size()][]);
if (display) {
spec.showInJFrame(name, true, true);
/*
* save spectrograms to files BufferedImage image =
* createImage(spec);
* ImageIO.write(ImageTools.toBufferedImage(image), "png", new
* File(name+".png"));
*/
// Thread.sleep(2000);
}
return spectrum;
}
public static float spectrumTimeFromIndex(int index, float windowShiftTime) {
return index * windowShiftTime;
}
public static int spectrumIndex(float linearTime, float windowShiftTime) {
return (int) (linearTime / windowShiftTime);
}
public static int time2Sample(double time, int sampleRate) {
return (int) (time * sampleRate);
}
}

View File

@ -0,0 +1,300 @@
package org.gcube.dataanalysis.ecoengine.signals;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.gcube.contentmanagement.graphtools.data.BigSamplesTable;
import org.gcube.contentmanagement.graphtools.plotting.graphs.NumericSeriesGraph;
import org.gcube.contentmanagement.graphtools.plotting.graphs.TimeSeriesGraph;
import org.gcube.contentmanagement.lexicalmatcher.utils.MathFunctions;
import org.jfree.data.time.FixedMillisecond;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYSeriesCollection;
import com.rapidminer.RapidMiner;
import com.rapidminer.example.ExampleSet;
import com.rapidminer.operator.preprocessing.sampling.AbsoluteSampling;
import com.rapidminer.operator.preprocessing.series.filter.SeriesMissingValueReplenishment;
import com.rapidminer.tools.OperatorService;
public class SignalProcessing {
public static double[][] applyFilterBank(double[][] feature, int numCepstra, int numMelFilters, int samplingRate, int frameLength, float minCutFequency, float maxCutFrequency) throws Exception {
// recalculate Mel filters on the basis of the maxFrequency
int recalcMelFilters = SignalConversions.recalculateMaxMelFilters(samplingRate, numMelFilters, minCutFequency, maxCutFrequency);
double[][] mels = new double[feature.length][numCepstra];
int i = 0;
for (double[] bin : feature) {
int cbin[] = SignalConversions.fftBinIndices(samplingRate, frameLength, numMelFilters, recalcMelFilters, minCutFequency, maxCutFrequency);
double f[] = SignalConversions.melFilter(bin, cbin, recalcMelFilters);
double cepstra[] = SignalConversions.cepCoefficients(f, numCepstra, recalcMelFilters);
mels[i] = cepstra;
i++;
}
double[][] deltamels = new double[feature.length][numCepstra * 3];
for (int k = 0; k < feature.length; k++) {
for (int g = 0; g < mels[0].length; g++) {
deltamels[k][g] = mels[k][g];
}
}
Delta.calcDelta(deltamels, numCepstra);
Delta.calcDoubleDelta(deltamels, numCepstra);
return deltamels;
}
public static double[][] calculateSumSpectrum(List<double[]> signals, int windowShiftSamples, int frameLength, int samplingRate) throws Exception {
int signalLenght = signals.get(0).length;
System.out.println("TRIALS LENGHT " + signalLenght);
List<double[][]> spectrograms = new ArrayList<double[][]>();
System.out.println("Getting Spectra");
int j = 0;
// get all spectrograms
for (double[] signal : signals) {
double[][] spectro = SignalConversions.spectrogram("Spectrogram", signal, samplingRate, windowShiftSamples, frameLength, false);
System.out.println("Signal Number " + (j + 1) + " spectrum lenght " + ((spectro.length * windowShiftSamples) / samplingRate));
spectrograms.add(spectro);
j++;
}
System.out.println("Summing Spectra");
// sum all spectrograms
double[][] sumSpectro = SignalProcessing.sumSpectra(spectrograms);
spectrograms = null;
return sumSpectro;
}
// concatenates several spectra
public static double[][] concatenateSpectra(List<double[][]> spectra) {
double[][] firstSpectrum = spectra.get(0);
int mi = firstSpectrum.length;
int mj = firstSpectrum[0].length;
int nSpectra = spectra.size();
double[][] concatenatedSpectrum = new double[mi][mj * nSpectra];
int k = 0;
for (double[][] spectrum : spectra) {
for (int i = 0; i < mi; i++) {
for (int j = 0; j < mj; j++)
concatenatedSpectrum[i][j + (k * mj)] = spectrum[i][j];
}
k++;
}
return concatenatedSpectrum;
}
public static void displaySignalWithGenericTime(double[] signal, float t0, float timeshift, String name) {
org.jfree.data.xy.XYSeries xyseries = new org.jfree.data.xy.XYSeries(name);
float time = t0;
for (int i = 0; i < signal.length; i++) {
xyseries.add(time, signal[i]);
time = time + timeshift;
}
XYSeriesCollection collection = new XYSeriesCollection(xyseries);
NumericSeriesGraph nsg = new NumericSeriesGraph(name);
nsg.render(collection);
}
public static void displaySignalWithTime(double[] signal, Date[] dates, String name, String format) {
org.jfree.data.time.TimeSeries series = new org.jfree.data.time.TimeSeries(name);
for (int i = 0; i < signal.length; i++)
series.add(new FixedMillisecond(dates[i]), signal[i]);
TimeSeriesCollection dataset = new TimeSeriesCollection();
dataset.addSeries(series);
TimeSeriesGraph tsg = new TimeSeriesGraph(name);
tsg.timeseriesformat = format;
tsg.render(dataset);
}
public static double[] downSample(double[] signal, int numElements) throws Exception {
System.setProperty("rapidminer.init.operators", "operators.xml");
RapidMiner.init();
double[] rebuiltSignal = new double[signal.length];
Arrays.fill(rebuiltSignal, Double.NaN);
BigSamplesTable samples = new BigSamplesTable();
for (int k = 0; k < signal.length; k++) {
samples.addSampleRow("" + k, signal[k]);
}
ExampleSet es = samples.generateExampleSet();
System.out.println("Example Set Created");
AbsoluteSampling sampler = (AbsoluteSampling) OperatorService.createOperator("AbsoluteSampling");
sampler.setParameter("sample_size", "" + numElements);
sampler.setParameter("local_random_seed", "-1");
es = sampler.apply(es);
System.out.println("Finished");
SignalConversions.exampleSet2Signal(rebuiltSignal, es);
return rebuiltSignal;
}
public static double[][] extractSumSpectrum(String file, int windowShiftSamples, int frameLength, int samplingRate) throws Exception {
List<double[]> signals = SignalProcessing.readSignalsFromCSV(file, ",");
// int numSignals = signals.size();
int signalLenght = signals.get(0).length;
List<double[][]> sumspectrograms = new ArrayList<double[][]>();
List<double[][]> spectrograms = new ArrayList<double[][]>();
System.out.println("Getting Spectra");
int j = 0;
// get all spectrograms
for (double[] signal : signals) {
System.out.println("Signal Number " + (j + 1));
double[][] spectro = SignalConversions.spectrogram("Spectrogram", signal, samplingRate, windowShiftSamples, frameLength, false);
spectrograms.add(spectro);
j++;
}
System.out.println("Summing Spectra");
// sum all spectrograms
double[][] sumSpectro = SignalProcessing.sumSpectra(spectrograms);
spectrograms = null;
return sumSpectro;
}
public static Date[] fillTimeLine(double[] timeseconds, double samplingRate) throws Exception {
double[] values = new double[timeseconds.length];
for (int i = 0; i < timeseconds.length; i++)
values[i] = timeseconds[i] * 1000d;
double[] milliseconds = fillTimeSeries(values, timeseconds, samplingRate);
Date[] dates = new Date[milliseconds.length];
for (int i = 0; i < milliseconds.length; i++)
dates[i] = new Date((long) milliseconds[i]);
return dates;
}
public static double[] fillTimeSeries(double[] values, double[] timeseconds, double samplingRate) throws Exception {
System.setProperty("rapidminer.init.operators", "operators.xml");
RapidMiner.init();
double t0 = timeseconds[0];
double t1 = timeseconds[timeseconds.length - 1];
int signalength = (int) ((t1 - t0) * samplingRate) + 1;
double signal[] = new double[signalength];
Arrays.fill(signal, Double.NaN);
for (int i = 0; i < values.length; i++) {
if (values[i] != Double.NaN) {
int index = (int) ((timeseconds[i] - t0) * samplingRate);
signal[index] = values[i];
}
}
double[] rebuiltSignal = new double[signal.length];
BigSamplesTable samples = new BigSamplesTable();
for (int k = 0; k < signal.length; k++) {
samples.addSampleRow("" + k, signal[k]);
}
ExampleSet es = samples.generateExampleSet();
System.out.println("Example Set Created");
SeriesMissingValueReplenishment sampler = (SeriesMissingValueReplenishment) OperatorService.createOperator("SeriesMissingValueReplenishment");
sampler.setParameter("attribute_name", "att0");
sampler.setParameter("replacement", "3");
es = sampler.apply(es);
System.out.println("Finished");
SignalConversions.exampleSet2Signal(rebuiltSignal, es);
return rebuiltSignal;
}
public static double[][] multiSignalAnalysis(List<double[]> signals, int samplingRate, int windowshift, int frameslength, boolean display) throws Exception {
List<double[][]> spectra = new ArrayList<double[][]>();
for (double[] signal : signals)
spectra.add(SignalConversions.spectrogram("Spectrogram", signal, samplingRate, windowshift, frameslength, display));
double[][] sumSpec = sumSpectra(spectra);
return sumSpec;
}
public static List<double[]> readSignalsFromCSV(String file, String delimiter) throws Exception {
BufferedReader br = new BufferedReader(new FileReader(new File(file)));
String line = br.readLine();
List<double[]> signals = new ArrayList<double[]>();
while (line != null) {
double[] signal = readSignalFromCSVLine(line, delimiter);
signals.add(signal);
line = br.readLine();
}
br.close();
return signals;
}
public static double[] readSignalFromCSVLine(String line, String delimiter) throws Exception {
String[] splitted = line.split(delimiter);
double[] signal = new double[splitted.length];
for (int i = 0; i < splitted.length; i++)
signal[i] = Double.parseDouble(splitted[i]);
return signal;
}
// sums several spectra of the same length
public static double[][] sumSpectra(List<double[][]> spectra) {
double[][] firstSpectrum = spectra.get(0);
int mi = firstSpectrum.length;
int mj = firstSpectrum[0].length;
double[][] sumSpectrum = new double[mi][mj];
int k = 0;
for (double[][] spectrum : spectra) {
for (int i = 0; i < mi; i++) {
for (int j = 0; j < mj; j++)
sumSpectrum[i][j] = MathFunctions.incrementAvg(sumSpectrum[i][j], spectrum[i][j], k);
}
k++;
}
return sumSpectrum;
}
public static double[][] takeCentralSpectrum(double[][] spectrum, float numOfCentralSeconds, float windowShiftTime, int sampleRate) {
float maxTime = ((float) spectrum.length * (float) windowShiftTime);
float centralTime = (maxTime / (2f * numOfCentralSeconds));
System.out.println("Max Time in the Spectrum " + maxTime + " Central time " + centralTime);
int startIndex = (int) (centralTime / windowShiftTime);
int endIndex = (int) ((centralTime + numOfCentralSeconds) / windowShiftTime);
System.out.println("Recalculated lenght " + maxTime + " sec");
System.out.println("Lenght " + spectrum.length);
System.out.println("Start " + startIndex + " End " + endIndex + " max " + spectrum.length + " Cut lenght " + (endIndex - startIndex + 1) * windowShiftTime);
double[][] cutSpectrum = new double[endIndex - startIndex + 1][spectrum[0].length];
for (int i = startIndex; i <= endIndex; i++) {
cutSpectrum[i - startIndex] = spectrum[i];
}
return cutSpectrum;
}
}