public void run() { runInit(); // superclass // Haupt-Variablen fuer den Prozess int ch, i, j, k, m; double d1, d2; SpectStreamSlot[] runInSlot = new SpectStreamSlot[2]; SpectStreamSlot runOutSlot; SpectStream[] runInStream = new SpectStream[2]; SpectStream runOutStream; SpectFrame[] runInFr = new SpectFrame[2]; SpectFrame runOutFr; // Ziel-Frame Berechnung int[] srcBands = new int[2]; int fftSize, fullFFTsize, complexFFTsize; float[] convBuf1, convBuf2; float[][] fftBuf; float[] win; int readDone, oldReadDone; int[] phase = new int[2]; topLevel: try { // ------------------------------ Input-Slot ------------------------------ for (i = 0; i < 2; i++) { runInSlot[i] = slots.elementAt(SLOT_INPUT1 + i); if (runInSlot[i].getLinked() == null) { runStop(); // threadDead = true -> folgendes for() wird uebersprungen } // diese while Schleife ist noetig, da beim initReader ein Pause eingelegt werden kann // und die InterruptException ausgeloest wird; danach versuchen wir es erneut for (boolean initDone = false; !initDone && !threadDead; ) { try { runInStream[i] = runInSlot[i].getDescr(); // throws InterruptedException initDone = true; srcBands[i] = runInStream[i].bands; } catch (InterruptedException ignored) { } runCheckPause(); } } if (threadDead) break topLevel; // ------------------------------ Output-Slot ------------------------------ runOutSlot = slots.elementAt(SLOT_OUTPUT); runOutStream = new SpectStream(runInStream[0]); runOutSlot.initWriter(runOutStream); // ------------------------------ Vorberechnungen ------------------------------ fftSize = srcBands[0] - 1; fullFFTsize = fftSize << 1; complexFFTsize = fullFFTsize << 1; fftBuf = new float[2][complexFFTsize]; win = new float[fullFFTsize]; d1 = 1.0 / (double) fullFFTsize * Math.PI; for (i = 0; i < fullFFTsize; i++) { d2 = Math.cos(i * d1); win[i] = (float) (d2 * d2); } phase[0] = (int) (pr.para[PR_ANGLE].value / 100.0 * fullFFTsize + 0.5) % fullFFTsize; phase[1] = (phase[0] + fftSize) % fullFFTsize; // convBuf2 = fftBuf[0]; // Util.clear( convBuf2 ); // for( k = 0; k < 2; k++ ) { // m = k * fftSize; // for( i = 0; m < fullFFTsize; ) { // convBuf2[ i++ ] += win[ m ]; // convBuf2[ i++ ] += win[ m++ ]; // } // for( m = 0; i < complexFFTsize; ) { // convBuf2[ i++ ] += win[ m ]; // convBuf2[ i++ ] += win[ m++ ]; // } // } // Debug.view( convBuf2, "win overlap" ); // ------------------------------ Hauptschleife ------------------------------ runSlotsReady(); mainLoop: while (!threadDead) { // ---------- Frame einlesen ---------- for (readDone = 0; (readDone < 2) && !threadDead; ) { oldReadDone = readDone; for (i = 0; i < 2; i++) { try { if (runInStream[i].framesReadable() > 0) { runInFr[i] = runInSlot[i].readFrame(); readDone++; } } catch (InterruptedException ignored) { } catch (EOFException e) { break mainLoop; } runCheckPause(); } if (oldReadDone == readDone) { // konnte nix gelesen werden try { Thread.sleep(500); // ...deshalb kurze Pause } catch (InterruptedException ignored) { } // mainLoop wird gleich automatisch verlassen runCheckPause(); } } if (threadDead) break mainLoop; runOutFr = runOutStream.allocFrame(); // ---------- Process: Ziel-Frame berechnen ---------- for (ch = 0; ch < runOutStream.chanNum; ch++) { for (k = 0; k < 2; k++) { convBuf1 = runInFr[k].data[ch]; convBuf2 = fftBuf[k]; // calculate complex log spectrum : // Re( target ) = Log( Mag( source )) // Im( target ) = Phase( source ) // convBuf1 is already in polar style // -> fftBuf will be in rect style for (i = 0; i <= fullFFTsize; ) { convBuf2[i] = (float) Math.log(Math.max(1.0e-24, convBuf1[i])); // Re( target ) i++; convBuf2[i] = convBuf1[i]; // Im( target ) i++; } // make full spectrum (negative frequencies = conjugate positive frequencies) for (i = fullFFTsize + 2, j = fullFFTsize - 2; i < complexFFTsize; j -= 2) { // bug but nice? - 1 convBuf2[i++] = convBuf2[j]; convBuf2[i++] = -convBuf2[j + 1]; } // cepstrum domain Fourier.complexTransform(convBuf2, fullFFTsize, Fourier.INVERSE); // window m = phase[k]; for (i = 0; m < fullFFTsize; ) { convBuf2[i++] *= win[m]; convBuf2[i++] *= win[m++]; } for (m = 0; i < complexFFTsize; ) { convBuf2[i++] *= win[m]; convBuf2[i++] *= win[m++]; } } // mix cepstra convBuf1 = fftBuf[0]; convBuf2 = runOutFr.data[ch]; Util.add(fftBuf[1], 0, convBuf1, 0, complexFFTsize); // back to frequency domain Fourier.complexTransform(convBuf1, fullFFTsize, Fourier.FORWARD); // calculate real exponential spectrum : // Mag( target ) = Exp( Re( source )) // Phase( target ) = Im( source ) // ->convBuf2 shall be polar style, that makes things easy for (i = 0; i <= fullFFTsize; ) { convBuf2[i] = (float) Math.exp(convBuf1[i]); i++; convBuf2[i] = convBuf1[i]; i++; } } // calculation done runInSlot[0].freeFrame(runInFr[0]); runInSlot[1].freeFrame(runInFr[1]); for (boolean writeDone = false; (!writeDone) && !threadDead; ) { try { // Unterbrechung runOutSlot.writeFrame(runOutFr); // throws InterruptedException writeDone = true; runFrameDone(runOutSlot, runOutFr); runOutStream.freeFrame(runOutFr); } catch (InterruptedException ignored) { } // mainLoop wird eh gleich verlassen runCheckPause(); } } // end of main loop runInStream[0].closeReader(); runInStream[1].closeReader(); runOutStream.closeWriter(); } // break topLevel catch (IOException e) { runQuit(e); return; } catch (SlotAlreadyConnectedException e) { runQuit(e); return; } // catch( OutOfMemoryError e ) { // abort( e ); // return; // } runQuit(null); }
public void run() { runInit(); // superclass // Haupt-Variablen fuer den Prozess int ch, i; float f1, f2, maxGain; double exp; Param ampRef = new Param(1.0, Param.ABS_AMP); // transform-Referenz SpectStreamSlot runInSlot; SpectStreamSlot runOutSlot; SpectStream runInStream = null; SpectStream runOutStream; SpectFrame runInFr = null; SpectFrame runOutFr = null; // Ziel-Frame Berechnung int srcBands, fftSize, fullFFTsize, winSize, winHalf; float[] fftBuf, convBuf1, convBuf2, win; topLevel: try { // ------------------------------ Input-Slot ------------------------------ runInSlot = slots.elementAt(SLOT_INPUT); if (runInSlot.getLinked() == null) { runStop(); // threadDead = true -> folgendes for() wird uebersprungen } // diese while Schleife ist noetig, da beim initReader ein Pause eingelegt werden kann // und die InterruptException ausgeloest wird; danach versuchen wir es erneut for (boolean initDone = false; !initDone && !threadDead; ) { try { runInStream = runInSlot.getDescr(); // throws InterruptedException initDone = true; } catch (InterruptedException ignored) { } runCheckPause(); } if (threadDead) break topLevel; // ------------------------------ Output-Slot ------------------------------ runOutSlot = slots.elementAt(SLOT_OUTPUT); runOutStream = new SpectStream(runInStream); runOutSlot.initWriter(runOutStream); // ------------------------------ Vorberechnungen ------------------------------ srcBands = runInStream.bands; winSize = srcBands - 1; winHalf = winSize >> 1; win = Filter.createFullWindow(winSize, Filter.WIN_BLACKMAN); // pr.intg[ PR_WINDOW ]); fftSize = srcBands - 1; fullFFTsize = fftSize << 1; fftBuf = new float[fullFFTsize + 2]; exp = (Param.transform(pr.para[PR_CONTRAST], Param.ABS_AMP, ampRef, null)).value - 1.0; maxGain = (float) (Param.transform(pr.para[PR_MAXBOOST], Param.ABS_AMP, ampRef, null)).value; // System.out.println( "srcBands "+srcBands+"; fftSize "+fftSize+"; exp "+exp+"; maxGain // "+maxGain ); // ------------------------------ Hauptschleife ------------------------------ runSlotsReady(); mainLoop: while (!threadDead) { // ---------- Frame einlesen ---------- for (boolean readDone = false; (!readDone) && !threadDead; ) { try { runInFr = runInSlot.readFrame(); // throws InterruptedException readDone = true; runOutFr = runOutStream.allocFrame(); } catch (InterruptedException ignored) { } catch (EOFException e) { break mainLoop; } runCheckPause(); } if (threadDead) break mainLoop; // ---------- Process: Ziel-Frame berechnen ---------- for (ch = 0; ch < runOutStream.chanNum; ch++) { convBuf1 = runInFr.data[ch]; convBuf2 = runOutFr.data[ch]; fftBuf[0] = 1.0f; fftBuf[1] = 0.0f; for (i = 2; i < fullFFTsize; ) { f2 = (convBuf1[i - 2] + convBuf1[i + 2]); if (f2 > 0.0f) { f1 = (float) Math.min(maxGain, Math.pow(2.0f * convBuf1[i] / f2, exp)); } else { if (convBuf1[i] == 0.0f) { f1 = 1.0f; } else { f1 = maxGain; } } // System.out.println( f1 ); fftBuf[i++] = f1; fftBuf[i++] = 0.0f; } fftBuf[i++] = 1.0f; fftBuf[i++] = 0.0f; Fourier.realTransform(fftBuf, fullFFTsize, Fourier.INVERSE); Util.mult(win, winHalf, fftBuf, 0, winHalf); for (i = winHalf; i < fullFFTsize - winHalf; ) { fftBuf[i++] = 0.0f; } Util.mult(win, 0, fftBuf, i, winHalf); // if( (runOutStream.framesWritten < 2) && (ch == 0) ) Debug.view( fftBuf, "time" ); Fourier.realTransform(fftBuf, fullFFTsize, Fourier.FORWARD); // if( (runOutStream.framesWritten < 2) && (ch == 0) ) Debug.view( fftBuf, "freq" ); for (i = 0; i <= fullFFTsize; ) { convBuf2[i] = convBuf1[i] * fftBuf[i]; i++; convBuf2[i] = convBuf1[i]; i++; } } // calculation done // if( (runOutStream.framesWritten < 2) ) { // Debug.view( fftBuf, "flt "+runOutStream.framesWritten ); // Debug.view( runInFr.data[0], "in "+runOutStream.framesWritten ); // Debug.view( runOutFr.data[0], "out "+runOutStream.framesWritten ); // } runInSlot.freeFrame(runInFr); for (boolean writeDone = false; (!writeDone) && !threadDead; ) { try { // Unterbrechung runOutSlot.writeFrame(runOutFr); // throws InterruptedException writeDone = true; runFrameDone(runOutSlot, runOutFr); runOutStream.freeFrame(runOutFr); } catch (InterruptedException ignored) { } // mainLoop wird eh gleich verlassen runCheckPause(); } } // end of main loop runInStream.closeReader(); runOutStream.closeWriter(); } // break topLevel catch (IOException e) { runQuit(e); return; } catch (SlotAlreadyConnectedException e) { runQuit(e); return; } // catch( OutOfMemoryError e ) { // abort( e ); // return; // } runQuit(null); }