/*
* Created on Feb 8, 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
*/
package com.frinika.tootX;
import com.frinika.project.FrinikaAudioSystem;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JFrame;
import com.frinika.priority.Priority;
import uk.org.toot.audio.core.AudioBuffer;
import uk.org.toot.audio.core.AudioProcess;
import uk.org.toot.audio.server.AudioClient;
import uk.org.toot.audio.server.AudioServer;
import uk.org.toot.audio.server.IOAudioProcess;
public class LatencyTester extends Observable {
AudioBuffer outbuf;
AudioBuffer inbuf;
AudioServer server;
IOAudioProcess out;
IOAudioProcess in;
AudioProcess pulse;
Analysis analysis;
int NOSIGNAL = -1;
int period;
int latency = 0;
boolean first=false;
boolean reset=true;
AudioClient client=new AudioClient() {
public void work(int bufSize) {
if (first) {
Priority.setPriorityRR(90);
first=false;
}
in.processAudio(inbuf);
analysis.processAudio(inbuf);
pulse.processAudio(outbuf);
out.processAudio(outbuf);
if (latency != analysis.latency || reset ) {
latency=analysis.latency;
LatencyTester.this.setChanged();
notifyObservers();
reset= false;
}
}
public void setEnabled(boolean b) {
// TODO ????
}
};
protected int getLatency() {
return latency;
}
public void reset() { reset=true; }
public void start(JFrame frame) {
server = FrinikaAudioSystem.getAudioServer();
try {
out = FrinikaAudioSystem.audioOutputDialog(frame,"Select output for latency test");
in = FrinikaAudioSystem.audioInputDialog(frame,"Select input for latency test");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
period = (int) (FrinikaAudioSystem.getSampleRate())/2;
pulse = new Pulse();
analysis = new Analysis();
// Send one pulse out on the output that we will look for in the input
outbuf = server.createAudioBuffer("latenyOut");
inbuf = server.createAudioBuffer("latencyIn");
System.out.println(" bffer size = " + outbuf.getSampleCount() + " "
+ inbuf.getSampleCount());
assert(false);
// FrinikaAudioSystem.stealAudioServer(this,client);
server.start();
}
public void stop() {
assert(false);
// FrinikaAudioSystem.returnAudioServer(this);
}
class Pulse implements AudioProcess {
long count = 0;
public int processAudio(AudioBuffer buf) {
int n = buf.getSampleCount();
float buff[] = buf.getChannel(0);
for (int i = 0; i < n; i++, count++) {
if (count % period == 0)
buff[i] = 0.2f;
else
buff[i] = 0.0f;
}
return AUDIO_OK;
}
public void open() {
// TODO Auto-generated method stub
}
public void close() {
// TODO Auto-generated method stub
}
};
class Analysis implements AudioProcess {
long count = 0;
int latency = NOSIGNAL;
int latch;
float threshold;
Analysis() {
latch = 0;
threshold = 0.2f;
}
public int processAudio(AudioBuffer buf) {
int n = buf.getSampleCount();
float buff[] = buf.getChannel(0);
for (int i = 0; i < n; i++, count++) {
if (latch-- < 0) {
if (buff[i] > threshold) {
latency = (int) (count % period);
latch = 100;
}
if (latch < -period)
latency = NOSIGNAL;
}
}
return AUDIO_OK;
}
public void open() {
// TODO Auto-generated method stub
}
public void close() {
// TODO Auto-generated method stub
}
}
public float getLatencyInMillis() {
// TODO Auto-generated method stub
return (float) (latency/server.getSampleRate()*1000.0);
}
public static void main(String args[]) throws Exception {
final LatencyTester l = new LatencyTester();
l.addObserver(new Observer() {
public void update(Observable o, Object arg) {
System.out.println(" latency is "+l.getLatencyInMillis() +"mS");
}
});
l.start(null);
Thread.sleep(100000);
}
public int getLatencyInSamples() {
return latency;
}
}