import davaguine.jeq.core.IIR; import edu.uci.ics.jung.graph.DirectedSparseGraph; import java.util.Collection; import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; public class Processor<T extends Double> implements Runnable { /* Properties set from RendererConfig */ public static float SR = HypertronVelodyne.getRendererConfig().getSampleRate(); private int samplesToProcess = HypertronVelodyne.getRendererConfig().getSamplesToProcess(); private Model<T> model; private boolean initialized = false; private Object lock = new Object(); int numThreads = 8; public Processor(Model<T> model) { this.model = model; for (Node n : this.model.getGraph().getVertices()) { if (n.type == Node.NodeType.wall) { n.eq = createEqualizer(); } } } CyclicBarrier barrierEnd = new CyclicBarrier(numThreads + 1); CyclicBarrier barrierStart = new CyclicBarrier(numThreads + 1); CyclicBarrier barrierDistribute = new CyclicBarrier(numThreads + 1); LinkedList<Computation> comps = new LinkedList<Computation>(); public class Computation implements Runnable { public Collection<Node> nodes; public Model.GraphModelData md; public boolean running = true; @Override public void run() { while (running) { try { barrierStart.await(); } catch (Exception e) { e.printStackTrace(); } for (Node node : nodes) { calcSample(node, md); } try { barrierEnd.await(); } catch (Exception e) { e.printStackTrace(); } } } } private IIR createEqualizer() { return new IIR(10, SR, 1); } // parallelize?! geht evtl weil ja intern nur Sum auf delay lines @Override public void run() { long startTime = System.currentTimeMillis(); if (!initialized) { for (Edge<T> edge : this.model.getModelData().graph.getEdges()) { edge.createDelayLine(); } int i = 0; String usrDir = System.getProperty("user.dir"); /* for (Node node : this.model.getModelData().sourceNodes) { switch (i) { case 0: node.wavFileReader = new WavFileReader("/usr/lib/pd-extended/extra/ekext/examples/stink.wav"); break; case 1: node.wavFileReader = new WavFileReader("/home/lodsb/rorgan.wav"); break; default: node.wavFileReader = new WavFileReader("/home/lodsb/aero_talk.wav"); } i = (i +1)%3; } */ /* for(Node node: this.model.getModelData().listenerNodes) { // get headpositions here... int numInEdges = this.model.getModelData().graph.getInEdges(node).size(); node.createInputChannels(numInEdges); } */ initialized = true; LinkedList<Node>[] a = new LinkedList[numThreads]; for (int kk = 0; kk < a.length; kk++) { a[kk] = new LinkedList<Node>(); } System.err.println("**** "+this.model.getGraph().getVertices().size()); int mod = 0; for (Node node : this.model.getGraph().getVertices()) { a[mod].add(node); mod = (mod + 1) % (a.length - 1); } int sizeLists = 0; for (int k = 0; k < numThreads; k++) { Computation c = new Computation(); c.md = this.model.getModelData(); c.nodes = a[k]; sizeLists = sizeLists + c.nodes.size(); Thread t = new Thread(c); this.comps.add(c); threads.add(t); t.start(); } System.err.println("????????? "+sizeLists); } for (int sampleNr = 0; sampleNr < samplesToProcess; sampleNr++) { if (sampleNr % 100 == 0) { System.out.print("Processing sample #" + sampleNr + " ..."); } processGraph(this.model.getModelData()); t++; if (sampleNr % 100 == 0) { System.out.println("done!"); } } for(Computation c: comps) { c.running = false; } System.out.println("Processed " + samplesToProcess + " in " + (System.currentTimeMillis() - startTime) + "ms"); int i = 0; for (Node node : this.model.getModelData().listenerNodes) { new HRTFRenderer(node, i + "" + node.name + ".wav", true).render(); i++; } } private void calcSample(Node node, Model.GraphModelData md) { double sample = 0; if(node.type != Node.NodeType.volume) { for (Edge edge : (Collection<Edge>) md.graph.getInEdges(node)) { synchronized(edge) { sample = sample + edge.getDelayLine().getCurrentSample(); edge.visited = true; } } distributeSample(md.graph, node, sample); }else { int i = 0; for (Edge edge : (Collection<Edge>) md.graph.getInEdges(node)) { synchronized(edge) { sample = edge.getDelayLine().getCurrentSample(); } distributeSampleVolume(md.graph,node,sample,i); i++; edge.visited = true; } } } int t = 0; LinkedList<Thread> threads = new LinkedList<Thread>(); AtomicBoolean startB = new AtomicBoolean(); // process SINGLE SAMPLE from sources private void processGraph(Model.GraphModelData md) { for (Node node : (LinkedList<Node>) md.sourceNodes) { float inputSample = node.wavFileReader.getNextSample(); /* if(t < 10) { inputSample = 1.0f; } else { inputSample = 0.0f; } */ distributeSample(md.graph, node, (double) inputSample); //traverseGraph(md.graph, node, inputSample); } /* for (Node node : this.model.getGraph().getVertices()) { calcSample(node, md); } */ try { barrierStart.await(); barrierStart.reset(); //System.err.println("waiting"); barrierEnd.await(); barrierEnd.reset(); } catch (InterruptedException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (BrokenBarrierException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } double outSample = 0; for (Node node : (LinkedList<Node>) md.listenerNodes) { int channel = 0; for (Edge edge : (Collection<Edge>) md.graph.getInEdges(node)) { double c = 1.0; /*if (((Node) md.graph.getSource(edge)).type == Node.NodeType.source) c = 0.1; */ // why sum outsample?? //outSample = c * edge.getDelayLine().getCurrentSample(); outSample = c * edge.getDelayLine().getCurrentSample(); //if(outSample != 0) System.out.println(outSample+ " chan "+channel+" node " // + md.graph.getPredecessorCount(node) ); node.appendSample(channel, (float) outSample); channel++; } } for (Edge edge : (Collection<Edge>) md.graph.getEdges()) { edge.visited = false; edge.getDelayLine().incrementIndex(); } } Random rnd = new Random(); private void distributeSample(DirectedSparseGraph<Node, Edge> graph, Node node, double sample) { // distribute energy equally int numOutputs = graph.getOutEdges(node).size(); sample = sample / numOutputs; /*double c = 1.0; if(node.type == Node.NodeType.wall) { c = -1.0; } */ //if(node.type == Node.NodeType.wall) sample=-1.0*sample; if(node.type == Node.NodeType.wall) sample = (0.91*sample); for (Edge edge : graph.getOutEdges(node)) { edge.visited = true; synchronized (edge) { edge.getDelayLine().addSample(sample); } } } private void distributeSampleVolume(DirectedSparseGraph<Node, Edge> graph, Node node, double sample, int edgeIndex) { // distribute energy equally int numOutputs = graph.getOutEdges(node).size(); sample = sample / numOutputs; /*double c = 1.0; if(node.type == Node.NodeType.wall) { c = -1.0; } */ //if(node.type == Node.NodeType.wall) sample=-1.0*sample; if(node.type == Node.NodeType.wall){ sample = (0.91*sample); } int i = 0; for (Edge edge : graph.getOutEdges(node)) { if(node.type == Node.NodeType.volume) { sample = sample*( node.edgeGainMap.get((Object) edge)[edgeIndex] ); } edge.visited = true; synchronized (edge) { edge.getDelayLine().addSample(sample); } i++; } } }