예제 #1
0
  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);
  }
예제 #2
0
  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);
  }