/*
* Created on Apr 11, 2007
*
* Copyright (c) 2006-2007 P.J.Leonard
*
* http://www.frinika.com
*
* This file is part of Frinika.
*
* Frinika is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* Frinika is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Frinika; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// Attempt
package com.frinika.audio.analysis.constantq;
// ATTEMPT INVERSE CONSTANT Q (not much good)
import java.awt.Dimension;
import java.util.Observable;
import java.util.Observer;
import java.util.TreeSet;
import com.frinika.audio.analysis.Oscillator;
import com.frinika.audio.analysis.OscillatorNode;
import com.frinika.audio.analysis.SpectrogramDataListener;
public class SpectrogramToWave implements SpectrogramDataListener, Observer {
public ConstantQSpectrogramDataBuilder data;
int dataPtr = 0;
private int nChunk;
private int nBin;
Thread buildThread;
int renderCount;
boolean rebuild = false;
TreeSet<Oscillator> activeOscillator = new TreeSet<Oscillator>();
public SpectrogramToWave(ConstantQSpectrogramDataBuilder data) {
this.data = data;
data.addSizeObserver(this);
}
int peaks[];
void doWork() {
int ptr = 0;
synchronized (data) {
int end = data.getChunkRenderedCount();
for (; renderCount < end; renderCount++) {
getPeaks(renderCount);
}
}
}
final TreeSet<OscillatorNode> vertCache = new TreeSet<OscillatorNode>(); //new AmpComparator());
//public Object oscillators;
public TreeSet<? extends Oscillator> getPeaks(long chunkPtr) {
vertCache.clear();
if (!data.validAt(chunkPtr)) {
System.out.println(" Data not ready at " + chunkPtr);
return vertCache;
}
float freqs[] = data.getFreqArray();
peaks = new int[freqs.length];
float magn[] = data.getMagnitudeAt(chunkPtr);
float pfreq[] = data.getPhaseFreqAt(chunkPtr);
float phase[] = data.getPhaseAt(chunkPtr);
long sampleTime=data.chunkStartInSamples(chunkPtr);
int cnt = getPeaks(magn, peaks, 0.1f);
for (int i = 0; i < cnt; i++) {
int ifreq = peaks[i];
//vertCache.add(new OscillatorNode(sampleTime,ifreq, freqs[ifreq], magn[ifreq],
// pfreq[ifreq], phase[ifreq]));
}
return vertCache;
}
private int getPeaks(float a[], int peaks[], float threshold) {
float max = 0.0f;
int imax = -1;
int cnt = 0;
for (int i = 1; i < a.length - 1; i++) {
if (a[i] < threshold)
continue;
if (a[i] >= a[i - 1] && a[i] > a[i + 1]) {
peaks[cnt++] = i;
}
}
return cnt;
}
public void update(Observable arg0, Object arg) {
dataPtr = (Integer) arg;
}
public void notifySizeChange(Dimension d) {
nChunk = d.width;
nBin = d.height;
rebuild = true;
}
public void notifyMoreDataReady() {
doWork();
}
// class OscillatorNode implements Oscillator{
//
// long sampleTime;
// int index;
// double freq;
// double amp;
// double pfreq;
// double phaseRef;
//
// double phase;
// double dphase;
//
// OscillatorNode(long sampleTime,int index, double freq, double amp, double pfreq,
// double phaseRef) {
// this.sampleTime=sampleTime;
// this.index = index;
// this.freq = freq;
// this.amp = amp;
// this.pfreq = pfreq;
// this.phaseRef = phaseRef;
// this.dphase = 2.0*Math.PI*freq/FrinikaConfig.sampleRate;
// }
//
// public String toString() {
// return "" + freq + " " + amp + "" + pfreq;
// }
//
// public void close() {
// // TODO Auto-generated method stub
//
// }
//
// public void open() {
// // TODO Auto-generated method stub
//
// }
//
// public int processAudio(AudioBuffer buffer) {
// float buff[]=buffer.getChannel(0);
// int n=buffer.getSampleCount();
// for (int i=0;i<n;i++) {
// buff[i] += amp*Math.sin(phase+=dphase); // TODO
// }
// return AUDIO_OK;
// }
//
// }
// class AmpComparator implements Comparator<OscillatorNode> {
//
// public int compare(OscillatorNode arg0, OscillatorNode arg1) {
// int i = Double.compare(arg0.amp, arg1.amp);
// if (i != 0)
// return i;
// System.out.println(" magnitudes are the same ");
// if (arg0.hashCode() > arg1.hashCode())
// return 1;
// return -1;
// }
//
// }
public TreeSet<? extends Oscillator> getPeaksAtFrame(long framePtr) {
int chunkPtr=data.getChunkAtFrame(framePtr);
return getPeaks(chunkPtr);
}
}