예제 #1
0
  protected void process() {
    int i, j, len, ch, chunkLength;
    long progOff, progLen;
    float f1;

    // io
    AudioFile inF = null;
    AudioFile outF = null;
    AudioFileDescr inStream;
    AudioFileDescr outStream;
    FloatFile[] floatF = null;
    File tempFile[] = null;

    // buffers
    float[][] inBuf, outBuf;
    float[] win;
    float[] convBuf1, convBuf2;
    float[] tempFlt;

    int inChanNum, inLength, inputStep, outputStep, winSize;
    int transLen, skip, inputLen, outputLen, fltLen;
    int framesRead, framesWritten;
    float warp, a1, b0, b1, x0, x1, y0, y1, b0init;

    Param ampRef = new Param(1.0, Param.ABS_AMP); // transform-Referenz
    Param peakGain;
    float gain = 1.0f; // gain abs amp
    float maxAmp = 0.0f;

    PathField ggOutput;

    topLevel:
    try {

      // ---- open input, output ----

      // input
      inF = AudioFile.openAsRead(new File(pr.text[PR_INPUTFILE]));
      inStream = inF.getDescr();
      inChanNum = inStream.channels;
      inLength = (int) inStream.length;
      // this helps to prevent errors from empty files!
      if ((inLength * inChanNum) < 1) throw new EOFException(ERR_EMPTY);
      // .... check running ....
      if (!threadRunning) break topLevel;

      // output
      ggOutput = (PathField) gui.getItemObj(GG_OUTPUTFILE);
      if (ggOutput == null) throw new IOException(ERR_MISSINGPROP);
      outStream = new AudioFileDescr(inStream);
      ggOutput.fillStream(outStream);
      outF = AudioFile.openAsWrite(outStream);
      // .... check running ....
      if (!threadRunning) break topLevel;

      // ---- parameter inits ----

      warp =
          Math.max(-0.98f, Math.min(0.98f, (float) (pr.para[PR_WARP].val / 100))); // DAFx2000 'b'
      f1 = (1.0f - warp) / (1.0f + warp); // DAFx2000 (25)
      winSize = 32 << pr.intg[PR_FRAMESIZE]; // DAFx2000 'N'
      j = winSize >> 1;
      transLen = (int) (f1 * winSize + 0.5f); // DAFx2000 'P' (26)
      i = pr.intg[PR_OVERLAP] + 1;
      while (((float) transLen / (float) i) > j) i++;
      inputStep = (int) (((float) transLen / (float) i) + 0.5f); // DAFx2000 'L'
      fltLen = Math.max(winSize, transLen);
      // System.out.println( "inputStep "+inputStep+"; winSize "+winSize+"; transLen "+transLen+";
      // fltLen "+fltLen+"; warp "+warp+"; � "+f1 );
      win = Filter.createFullWindow(winSize, Filter.WIN_HANNING); // DAFx2000 (27)
      outputStep = inputStep;

      b0init = (float) Math.sqrt(1.0f - warp * warp);

      progOff = 0;
      progLen = (long) inLength * (2 + inChanNum); // + winSize;

      tempFlt = new float[fltLen];
      inputLen = winSize + inputStep;
      inBuf = new float[inChanNum][inputLen];
      outputLen = transLen + outputStep;
      outBuf = new float[inChanNum][outputLen];

      // normalization requires temp files
      if (pr.intg[PR_GAINTYPE] == GAIN_UNITY) {
        tempFile = new File[inChanNum];
        floatF = new FloatFile[inChanNum];
        for (ch = 0; ch < inChanNum; ch++) { // first zero them because an exception might be thrown
          tempFile[ch] = null;
          floatF[ch] = null;
        }
        for (ch = 0; ch < inChanNum; ch++) {
          tempFile[ch] = IOUtil.createTempFile();
          floatF[ch] = new FloatFile(tempFile[ch], GenericFile.MODE_OUTPUT);
        }
        progLen += (long) inLength;
      } else {
        gain = (float) ((Param.transform(pr.para[PR_GAIN], Param.ABS_AMP, ampRef, null)).val);
      }
      // .... check running ....
      if (!threadRunning) break topLevel;

      // ----==================== the real stuff ====================----

      framesRead = 0;
      framesWritten = 0;
      skip = 0;

      while (threadRunning && (framesWritten < inLength)) {

        chunkLength = Math.min(inputLen, inLength - framesRead + skip);
        // ---- read input chunk ----
        len = Math.max(0, chunkLength - skip);
        inF.readFrames(inBuf, skip, len);
        framesRead += len;
        progOff += len;
        //				off			+= len;
        // .... progress ....
        setProgression((float) progOff / (float) progLen);
        // .... check running ....
        if (!threadRunning) break topLevel;

        // zero padding
        if (chunkLength < inputLen) {
          for (ch = 0; ch < inChanNum; ch++) {
            convBuf1 = inBuf[ch];
            for (i = chunkLength; i < convBuf1.length; i++) {
              convBuf1[i] = 0.0f;
            }
          }
        }

        for (ch = 0; threadRunning && (ch < inChanNum); ch++) {
          convBuf1 = inBuf[ch];
          convBuf2 = outBuf[ch];

          for (i = 0, j = fltLen; i < winSize; i++) {
            tempFlt[--j] = convBuf1[i] * win[i];
          }
          while (j > 0) {
            tempFlt[--j] = 0.0f;
          }

          a1 = -warp; // inital allpass
          b0 = b0init;
          b1 = 0.0f;
          for (j = 0; j < transLen; j++) {
            x1 = 0.0f;
            y1 = 0.0f;

            //						for( i = 0; i < transLen; i++ ) {		// DAFx2000 (2 resp. 3)
            for (i = 0; i < fltLen; i++) { // DAFx2000 (2 resp. 3)
              x0 = tempFlt[i];
              y0 = b0 * x0 + b1 * x1 - a1 * y1;
              tempFlt[i] = y0; // (work with double precision while computing cascades)
              y1 = y0;
              x1 = x0;
            }

            a1 = -warp; // cascaded allpasses
            b0 = -warp;
            b1 = 1.0f;

            convBuf2[j] += (float) y1;
          }
          // .... progress ....
          progOff += chunkLength - skip;
          setProgression((float) progOff / (float) progLen);
        } // for channels
        // .... check running ....
        if (!threadRunning) break topLevel;

        chunkLength = Math.min(outputStep, inLength - framesWritten);
        // ---- write output chunk ----
        if (floatF != null) {
          for (ch = 0; ch < inChanNum; ch++) {
            floatF[ch].writeFloats(outBuf[ch], 0, chunkLength);
          }
          progOff += chunkLength;
          //					off			  += len;
          framesWritten += chunkLength;
          // .... progress ....
          setProgression((float) progOff / (float) progLen);

        } else {
          for (ch = 0; ch < inChanNum; ch++) {
            Util.mult(outBuf[ch], 0, chunkLength, gain);
          }
          outF.writeFrames(outBuf, 0, chunkLength);
          progOff += chunkLength;
          //					off			  += len;
          framesWritten += chunkLength;
          // .... progress ....
          setProgression((float) progOff / (float) progLen);
        }
        // .... check running ....
        if (!threadRunning) break topLevel;

        // check max amp
        for (ch = 0; ch < inChanNum; ch++) {
          convBuf1 = outBuf[ch];
          for (i = 0; i < chunkLength; i++) {
            f1 = Math.abs(convBuf1[i]);
            if (f1 > maxAmp) {
              maxAmp = f1;
            }
          }
        }

        // overlaps
        skip = winSize;
        for (ch = 0; ch < inChanNum; ch++) {
          System.arraycopy(inBuf[ch], inputStep, inBuf[ch], 0, winSize);
          convBuf1 = outBuf[ch];
          System.arraycopy(convBuf1, outputStep, convBuf1, 0, transLen);
          for (i = transLen; i < outputLen; ) {
            convBuf1[i++] = 0.0f;
          }
        }
      } // until framesWritten == outLength
      // .... check running ....
      if (!threadRunning) break topLevel;

      // ----==================== normalize output ====================----

      if (pr.intg[PR_GAINTYPE] == GAIN_UNITY) {
        peakGain = new Param((double) maxAmp, Param.ABS_AMP);
        gain =
            (float)
                (Param.transform(
                        pr.para[PR_GAIN],
                        Param.ABS_AMP,
                        new Param(1.0 / peakGain.val, peakGain.unit),
                        null))
                    .val;
        normalizeAudioFile(floatF, outF, inBuf, gain, 1.0f);
        maxAmp *= gain;

        for (ch = 0; ch < inChanNum; ch++) {
          floatF[ch].cleanUp();
          floatF[ch] = null;
          tempFile[ch].delete();
          tempFile[ch] = null;
        }
      }
      // .... check running ....
      if (!threadRunning) break topLevel;

      // ---- Finish ----

      outF.close();
      outF = null;
      outStream = null;
      inF.close();
      inF = null;
      inStream = null;
      inBuf = null;

      // inform about clipping/ low level
      handleClipping(maxAmp);
    } catch (IOException e1) {
      setError(e1);
    } catch (OutOfMemoryError e2) {
      inStream = null;
      outStream = null;
      inBuf = null;
      convBuf1 = null;
      convBuf2 = null;
      System.gc();

      setError(new Exception(ERR_MEMORY));
      ;
    }

    // ---- cleanup (topLevel) ----
    if (inF != null) {
      inF.cleanUp();
      inF = null;
    }
    if (outF != null) {
      outF.cleanUp();
      outF = null;
    }
    if (floatF != null) {
      for (ch = 0; ch < floatF.length; ch++) {
        if (floatF[ch] != null) {
          floatF[ch].cleanUp();
          floatF[ch] = null;
        }
        if (tempFile[ch] != null) {
          tempFile[ch].delete();
          tempFile[ch] = null;
        }
      }
    }
  } // process()
예제 #2
0
  protected void process() {
    int i, j, ch, len, off, chunkLength;
    long progOff, progLen;
    float f1, f2;
    double d1;
    boolean extraAudioFile;

    // io
    AudioFile inF = null;
    AudioFile outF = null;
    AudioFile envInF = null;
    AudioFile envOutF = null;
    AudioFileDescr inStream = null;
    AudioFileDescr outStream = null;
    AudioFileDescr envInStream = null;
    AudioFileDescr envOutStream = null;
    FloatFile[] outFloatF = null;
    FloatFile[] envFloatF = null;
    File outTempFile[] = null;
    File envTempFile[] = null;
    int inChanNum, outChanNum, envInChanNum, envOutChanNum, shapeChanNum;

    int[][] shapeChan = null;
    int[][] inChan = null;
    float[][] shapeChanWeight = null;
    float[][] inChanWeight = null;

    // buffers
    float[][] inBuf = null; // Sound-In
    float[][] outBuf = null; // Sound-Out
    float[][] inEnvBuf = null; // Envelope of Input
    float[][] shapeEnvBuf = null; // Envelope of Shaper
    float[][] envInBuf = null; // Direct-In of Shaper-File
    float[] convBuf1, convBuf2;

    int inLength, outLength, envInLength, envOutLength;
    int framesRead, framesWritten; // re sound-files
    int framesRead2, framesWritten2; // re env-files

    Param ampRef = new Param(1.0, Param.ABS_AMP); // transform-Referenz
    Param peakGain;
    float gain = 1.0f; // gain abs amp
    float envGain = 1.0f; // gain abs amp
    float maxAmp = 0.0f;
    float envMaxAmp = 0.0f;

    float maxChange;
    int average, avrOff;

    double[] inEnergy, envInEnergy;

    PathField ggOutput;

    topLevel:
    try {

      // ---- open input, output; init ----

      // input
      inF = AudioFile.openAsRead(new File(pr.text[PR_INPUTFILE]));
      inStream = inF.getDescr();
      inChanNum = inStream.channels;
      inLength = (int) inStream.length;
      // this helps to prevent errors from empty files!
      if ((inLength < 1) || (inChanNum < 1)) throw new EOFException(ERR_EMPTY);
      // .... check running ....
      if (!threadRunning) break topLevel;

      envInLength = 0;
      envInChanNum = inChanNum;
      shapeChanNum = 0;

      // shape input
      switch (pr.intg[PR_ENVSOURCE]) {
        case SRC_SOUNDFILE:
        case SRC_ENVFILE:
          envInF = AudioFile.openAsRead(new File(pr.text[PR_ENVINFILE]));
          envInStream = envInF.getDescr();
          envInChanNum = envInStream.channels;
          shapeChanNum = envInChanNum;
          envInLength = (int) envInStream.length;
          // this helps to prevent errors from empty files!
          if ((envInLength < 1) || (envInChanNum < 1)) throw new EOFException(ERR_EMPTY);

          i = Math.min(inLength, envInLength);
          inLength = i;
          envInLength = i;
          break;

        case SRC_ENV:
          if (pr.bool[PR_RIGHTCHAN]) {
            shapeChanNum = 2;
            envInChanNum = Math.max(envInChanNum, shapeChanNum); // ggf. mono => stereo
          } else {
            shapeChanNum = 1;
          }
          break;

        case SRC_INPUT:
          shapeChanNum = inChanNum;
          break;
      }
      // .... check running ....
      if (!threadRunning) break topLevel;

      outChanNum = Math.max(inChanNum, envInChanNum);
      outLength = inLength;

      shapeChan = new int[outChanNum][2];
      shapeChanWeight = new float[outChanNum][2];
      inChan = new int[outChanNum][2];
      inChanWeight = new float[outChanNum][2];
      extraAudioFile =
          (envInF != null) && (pr.intg[PR_ENVSOURCE] == SRC_SOUNDFILE); // not if SRC_ENVFILE!!!

      // calc weights
      for (ch = 0; ch < outChanNum; ch++) {
        if (shapeChanNum == 1) {
          shapeChan[ch][0] = 0;
          shapeChan[ch][1] = 0;
          shapeChanWeight[ch][0] = 1.0f;
          shapeChanWeight[ch][1] = 0.0f;
        } else {
          f1 = ((float) ch / (float) (outChanNum - 1)) * (float) (shapeChanNum - 1);
          shapeChan[ch][0] = (int) f1; // Math.max verhindert ArrayIndex-Fehler
          shapeChan[ch][1] = Math.min((int) f1 + 1, shapeChanNum - 1); // (Weight ist dabei eh Null)
          f1 %= 1.0f;
          shapeChanWeight[ch][0] = 1.0f - f1;
          shapeChanWeight[ch][1] = f1;
        }
        if (inChanNum == 1) {
          inChan[ch][0] = 0;
          inChan[ch][1] = 0;
          inChanWeight[ch][0] = 1.0f;
          inChanWeight[ch][1] = 0.0f;
        } else {
          f1 = ((float) ch / (float) (outChanNum - 1)) * (float) (inChanNum - 1);
          inChan[ch][0] = (int) f1;
          inChan[ch][1] = Math.min((int) f1 + 1, inChanNum - 1);
          f1 %= 1.0f;
          inChanWeight[ch][0] = 1.0f - f1;
          inChanWeight[ch][1] = f1;
        }
        /*
        for( i = 0; i < 2; i++ ) {
        	System.out.println( "shapeChan["+ch+"]["+i+"] = "+shapeChan[ch][i] );
        	System.out.println( "shapeWeig["+ch+"]["+i+"] = "+shapeChanWeight[ch][i] );
        	System.out.println( "inputChan["+ch+"]["+i+"] = "+inChan[ch][i] );
        	System.out.println( "inputWeig["+ch+"]["+i+"] = "+inChanWeight[ch][i] );
        }
        */
      }

      // output
      ggOutput = (PathField) gui.getItemObj(GG_OUTPUTFILE);
      if (ggOutput == null) throw new IOException(ERR_MISSINGPROP);
      outStream = new AudioFileDescr(inStream);
      ggOutput.fillStream(outStream);
      outStream.channels = outChanNum;
      outF = AudioFile.openAsWrite(outStream);
      // .... check running ....
      if (!threadRunning) break topLevel;

      envOutLength = 0;
      envOutChanNum = 0;

      // envelope output
      if (pr.bool[PR_ENVOUTPUT]) {
        ggOutput = (PathField) gui.getItemObj(GG_ENVOUTFILE);
        if (ggOutput == null) throw new IOException(ERR_MISSINGPROP);
        envOutStream = new AudioFileDescr(inStream);
        ggOutput.fillStream(envOutStream);
        envOutStream.file = new File(pr.text[PR_ENVOUTFILE]);
        envOutF = AudioFile.openAsWrite(envOutStream);
        envOutLength = inLength;
        envOutChanNum = inChanNum;
      }
      // .... check running ....
      if (!threadRunning) break topLevel;

      // average buffer size
      d1 =
          Param.transform(
                  pr.para[PR_AVERAGE],
                  Param.ABS_MS,
                  new Param(AudioFileDescr.samplesToMillis(inStream, inLength), Param.ABS_MS),
                  null)
              .val; // average in millis
      average = ((int) (AudioFileDescr.millisToSamples(inStream, d1) + 0.5) & ~1) + 1; // always odd
      avrOff = (average >> 1) + 1; // first element needed for subtraction (see calcEnv())

      progOff = 0;
      progLen =
          (long) Math.max(average - avrOff, inLength)
              + (long) (extraAudioFile ? Math.max(average - avrOff, envInLength) : envInLength)
              + (long) outLength
              + (long) envOutLength;

      // normalization requires temp files
      if (pr.intg[PR_GAINTYPE] == GAIN_UNITY) {
        outTempFile = new File[outChanNum];
        outFloatF = new FloatFile[outChanNum];
        for (ch = 0;
            ch < outChanNum;
            ch++) { // first zero them because an exception might be thrown
          outTempFile[ch] = null;
          outFloatF[ch] = null;
        }
        for (ch = 0; ch < outChanNum; ch++) {
          outTempFile[ch] = IOUtil.createTempFile();
          outFloatF[ch] = new FloatFile(outTempFile[ch], GenericFile.MODE_OUTPUT);
        }
        progLen += (long) outLength;
      } else {
        gain = (float) (Param.transform(pr.para[PR_GAIN], Param.ABS_AMP, ampRef, null)).val;
      }
      // .... check running ....
      if (!threadRunning) break topLevel;

      // normalization requires temp files
      if (pr.intg[PR_ENVGAINTYPE] == GAIN_UNITY) {
        envTempFile = new File[envOutChanNum];
        envFloatF = new FloatFile[envOutChanNum];
        for (ch = 0;
            ch < envOutChanNum;
            ch++) { // first zero them because an exception might be thrown
          envTempFile[ch] = null;
          envFloatF[ch] = null;
        }
        for (ch = 0; ch < envOutChanNum; ch++) {
          envTempFile[ch] = IOUtil.createTempFile();
          envFloatF[ch] = new FloatFile(envTempFile[ch], GenericFile.MODE_OUTPUT);
        }
        progLen += (long) envOutLength;
      } else {
        envGain = (float) (Param.transform(pr.para[PR_ENVGAIN], Param.ABS_AMP, ampRef, null)).val;
      }
      // .... check running ....
      if (!threadRunning) break topLevel;

      // ---- further inits ----
      maxChange = (float) (Param.transform(pr.para[PR_MAXCHANGE], Param.ABS_AMP, ampRef, null)).val;

      inBuf = new float[inChanNum][8192 + average];
      Util.clear(inBuf);
      outBuf = new float[outChanNum][8192];
      Util.clear(outBuf);
      if (extraAudioFile) {
        envInBuf = new float[envInChanNum][8192 + average];
        Util.clear(envInBuf);
      }
      inEnvBuf = new float[inChanNum][8192]; // = envOutBuf
      Util.clear(inEnvBuf);
      shapeEnvBuf = new float[envInChanNum][8192];
      Util.clear(shapeEnvBuf);

      inEnergy = new double[inChanNum];
      for (ch = 0; ch < inChanNum; ch++) {
        inEnergy[ch] = 0.0;
      }
      envInEnergy = new double[envInChanNum];
      for (ch = 0; ch < envInChanNum; ch++) {
        envInEnergy[ch] = 0.0;
      }

      // System.out.println( "inLength "+inLength+"; envInLength "+envInLength+"; envOutLength
      // "+envOutLength+"; outLength "+outLength );
      // System.out.println( "average "+average+"; avrOff "+avrOff );

      // ----==================== buffer init ====================----

      framesRead = 0; // re inF
      framesRead2 = 0; // re envInF

      // ---- init buffers ----
      for (off = avrOff; threadRunning && (off < average); ) {
        len = Math.min(inLength - framesRead, Math.min(8192, average - off));
        if (len == 0) break;

        inF.readFrames(inBuf, off, len);
        // calc initial energy per channel (see calcEnv())
        for (ch = 0; ch < inChanNum; ch++) {
          convBuf1 = inBuf[ch];
          d1 = 0.0;
          for (i = 0, j = off; i < len; i++) {
            f1 = convBuf1[j++];
            d1 += f1 * f1;
          }
          inEnergy[ch] += d1;
        }
        framesRead += len;
        off += len;
        progOff += len;
        // .... progress ....
        setProgression((float) progOff / (float) progLen);
      }
      // zero padding bereits durch initialisierung mit Util.clear() passiert!

      if (extraAudioFile) {
        for (off = avrOff; threadRunning && (off < average); ) {
          len = Math.min(envInLength - framesRead2, Math.min(8192, average - off));
          if (len == 0) break;

          envInF.readFrames(envInBuf, off, len);
          // calc initial energy per channel (see calcEnv())
          for (ch = 0; ch < envInChanNum; ch++) {
            convBuf1 = envInBuf[ch];
            d1 = 0.0;
            for (i = 0, j = off; i < len; i++) {
              f1 = convBuf1[j++];
              d1 += f1 * f1;
            }
            envInEnergy[ch] += d1;
          }
          framesRead2 += len;
          off += len;
          progOff += len;
          // .... progress ....
          setProgression((float) progOff / (float) progLen);
        }
        // zero padding bereits durch initialisierung mit Util.clear() passiert!
      }
      // .... check running ....
      if (!threadRunning) break topLevel;

      // ----==================== the real stuff ====================----

      framesWritten = 0; // re OutF
      framesWritten2 = 0; // re envOutF

      while (threadRunning && (framesWritten < outLength)) {

        chunkLength = Math.min(8192, outLength - framesWritten);
        // ---- read input chunk ----
        len = Math.min(inLength - framesRead, chunkLength);
        inF.readFrames(inBuf, average, len);
        // zero padding
        for (ch = 0; ch < inChanNum; ch++) {
          convBuf1 = inBuf[ch];
          for (i = len, j = len + average; i < chunkLength; i++) {
            convBuf1[j++] = 0.0f;
          }
        }
        framesRead += len;
        progOff += len;
        // .... progress ....
        setProgression((float) progOff / (float) progLen);
        // .... check running ....
        if (!threadRunning) break topLevel;

        // ---- read input env chunk ----
        if (envInF != null) {
          len = Math.min(envInLength - framesRead2, chunkLength);
          if (extraAudioFile) { // ........ needs averaging ........
            envInF.readFrames(envInBuf, average, len);
            // zero padding
            for (ch = 0; ch < envInChanNum; ch++) {
              convBuf1 = envInBuf[ch];
              for (i = len, j = len + average; i < chunkLength; i++) {
                convBuf1[j++] = 0.0f;
              }
            }
          } else { // ........ is already env ........
            envInF.readFrames(shapeEnvBuf, 0, len);
            // zero padding
            for (ch = 0; ch < envInChanNum; ch++) {
              convBuf1 = shapeEnvBuf[ch];
              for (i = len; i < chunkLength; i++) {
                convBuf1[i] = 0.0f;
              }
            }
          }
          framesRead2 += len;
          progOff += len;
          // .... progress ....
          setProgression((float) progOff / (float) progLen);
        }
        // .... check running ....
        if (!threadRunning) break topLevel;

        // ---- calc input envelope ----
        for (ch = 0; ch < inChanNum; ch++) {
          inEnergy[ch] = calcEnv(inBuf[ch], inEnvBuf[ch], average, chunkLength, inEnergy[ch]);
        }

        // ---- write output env file ----
        if (pr.bool[PR_ENVOUTPUT]) {
          if (envFloatF != null) { // i.e. unity gain
            for (ch = 0; ch < envOutChanNum; ch++) {
              convBuf1 = inEnvBuf[ch];
              for (i = 0; i < chunkLength; i++) { // measure max amp
                f1 = Math.abs(convBuf1[i]);
                if (f1 > envMaxAmp) {
                  envMaxAmp = f1;
                }
              }
              envFloatF[ch].writeFloats(convBuf1, 0, chunkLength);
            }
          } else { // i.e. abs gain
            for (ch = 0; ch < envOutChanNum; ch++) {
              convBuf1 = inEnvBuf[ch];
              for (i = 0; i < chunkLength; i++) { // measure max amp + adjust gain
                f1 = Math.abs(convBuf1[i]);
                convBuf1[i] *= envGain;
                if (f1 > envMaxAmp) {
                  envMaxAmp = f1;
                }
              }
            }
            envOutF.writeFrames(inEnvBuf, 0, chunkLength);
          }
          framesWritten2 += chunkLength;
          progOff += chunkLength;
          // .... progress ....
          setProgression((float) progOff / (float) progLen);
        }
        // .... check running ....
        if (!threadRunning) break topLevel;

        // ---- calc shape envelope ----
        switch (pr.intg[PR_ENVSOURCE]) {
          case SRC_INPUT: // shape env = input env
            for (ch = 0; ch < inChanNum; ch++) {
              System.arraycopy(inEnvBuf[ch], 0, shapeEnvBuf[ch], 0, chunkLength);
            }
            break;
          case SRC_SOUNDFILE: // calc shape env from envInBuf
            for (ch = 0; ch < envInChanNum; ch++) {
              envInEnergy[ch] =
                  calcEnv(envInBuf[ch], shapeEnvBuf[ch], average, chunkLength, envInEnergy[ch]);
            }
            break;
          case SRC_ENVFILE: // nothing to do, we have already loaded the env
            break; //    in the correct buffer
          case SRC_ENV:
            throw new IOException("Graphic env not yet supported");
        }

        // ---- calc output ----
        // first generate output envelope
        switch (pr.intg[PR_MODE]) {
          case MODE_SUPERPOSE:
            if (!pr.bool[PR_INVERT]) { // multiply by shape
              for (ch = 0; ch < outChanNum; ch++) {
                convBuf1 = outBuf[ch];
                for (i = 0; i < chunkLength; i++) {
                  f1 =
                      shapeEnvBuf[shapeChan[ch][0]][i] * shapeChanWeight[ch][0]
                          + shapeEnvBuf[shapeChan[ch][1]][i] * shapeChanWeight[ch][1];
                  convBuf1[i] = Math.min(maxChange, f1);
                }
              }

            } else { // divide by shape
              for (ch = 0; ch < outChanNum; ch++) {
                convBuf1 = outBuf[ch];
                for (i = 0; i < chunkLength; i++) {
                  f1 =
                      shapeEnvBuf[shapeChan[ch][0]][i] * shapeChanWeight[ch][0]
                          + shapeEnvBuf[shapeChan[ch][1]][i] * shapeChanWeight[ch][1];
                  if (f1 > 0.0f) {
                    convBuf1[i] = Math.min(maxChange, 1.0f / f1);
                  } else {
                    convBuf1[i] = maxChange;
                  }
                }
              }
            }
            break;

          case MODE_REPLACE:
            if (!pr.bool[PR_INVERT]) { // shape / input
              for (ch = 0; ch < outChanNum; ch++) {
                convBuf1 = outBuf[ch];
                for (i = 0; i < chunkLength; i++) {
                  f1 =
                      shapeEnvBuf[shapeChan[ch][0]][i] * shapeChanWeight[ch][0]
                          + shapeEnvBuf[shapeChan[ch][1]][i] * shapeChanWeight[ch][1];
                  f2 =
                      inEnvBuf[inChan[ch][0]][i] * inChanWeight[ch][0]
                          + inEnvBuf[inChan[ch][1]][i] * inChanWeight[ch][1];
                  if (f2 > 0.0f) {
                    convBuf1[i] = Math.min(maxChange, f1 / f2);
                  } else {
                    convBuf1[i] = 0.0f; // input ist eh ueberall null, somit unveraenderlich
                  }
                }
              }

            } else { // 1 / (shape * input)
              for (ch = 0; ch < outChanNum; ch++) {
                convBuf1 = outBuf[ch];
                for (i = 0; i < chunkLength; i++) {
                  f1 =
                      shapeEnvBuf[shapeChan[ch][0]][i] * shapeChanWeight[ch][0]
                          + shapeEnvBuf[shapeChan[ch][1]][i] * shapeChanWeight[ch][1];
                  f1 *=
                      inEnvBuf[inChan[ch][0]][i] * inChanWeight[ch][0]
                          + inEnvBuf[inChan[ch][1]][i] * inChanWeight[ch][1];
                  if (f1 > 0.0f) {
                    convBuf1[i] = Math.min(maxChange, 1.0f / f1);
                  } else {
                    convBuf1[i] = maxChange;
                  }
                }
              }
            }
            break;
        }
        // then multiply input bites
        if (inChanNum == outChanNum) { // no weighting - use faster routine
          for (ch = 0; ch < outChanNum; ch++) {
            convBuf1 = outBuf[ch];
            convBuf2 = inBuf[ch];
            for (i = 0, j = avrOff; i < chunkLength; i++, j++) {
              convBuf1[i] *= convBuf2[j];
            }
          }
        } else {
          for (ch = 0; ch < outChanNum; ch++) {
            convBuf1 = outBuf[ch];
            for (i = 0, j = avrOff; i < chunkLength; i++, j++) {
              f1 =
                  inBuf[inChan[ch][0]][j] * inChanWeight[ch][0]
                      + inBuf[inChan[ch][1]][j] * inChanWeight[ch][1];
              convBuf1[i] *= f1;
            }
          }
        }

        // ---- write output sound file ----
        if (outFloatF != null) { // i.e. unity gain
          for (ch = 0; ch < outChanNum; ch++) {
            convBuf1 = outBuf[ch];
            for (i = 0; i < chunkLength; i++) { // measure max amp
              f1 = Math.abs(convBuf1[i]);
              if (f1 > maxAmp) {
                maxAmp = f1;
              }
            }
            outFloatF[ch].writeFloats(convBuf1, 0, chunkLength);
          }
        } else { // i.e. abs gain
          for (ch = 0; ch < outChanNum; ch++) {
            convBuf1 = outBuf[ch];
            for (i = 0; i < chunkLength; i++) { // measure max amp + adjust gain
              f1 = Math.abs(convBuf1[i]);
              convBuf1[i] *= gain;
              if (f1 > maxAmp) {
                maxAmp = f1;
              }
            }
          }
          outF.writeFrames(outBuf, 0, chunkLength);
        }
        framesWritten += chunkLength;
        progOff += chunkLength;
        // .... progress ....
        setProgression((float) progOff / (float) progLen);

        // ---- shift buffers ----
        for (ch = 0;
            ch < inChanNum;
            ch++) { // zero padding is performed after AudioFile.readFrames()!
          System.arraycopy(inBuf[ch], chunkLength, inBuf[ch], 0, average);
        }
        if (extraAudioFile) {
          for (ch = 0;
              ch < envInChanNum;
              ch++) { // zero padding is performed after AudioFile.readFrames()!
            System.arraycopy(envInBuf[ch], chunkLength, envInBuf[ch], 0, average);
          }
        }
      } // until framesWritten == outLength
      // .... check running ....
      if (!threadRunning) break topLevel;

      // ---- normalize output ----

      // sound file
      if (pr.intg[PR_GAINTYPE] == GAIN_UNITY) {
        peakGain = new Param((double) maxAmp, Param.ABS_AMP);
        gain =
            (float)
                (Param.transform(
                        pr.para[PR_GAIN],
                        Param.ABS_AMP,
                        new Param(1.0 / peakGain.val, peakGain.unit),
                        null))
                    .val;
        f1 = 1.0f;
        if ((envOutF != null) && (pr.intg[PR_ENVGAINTYPE] == GAIN_UNITY)) { // leave prog space
          f1 = (1.0f + getProgression()) / 2;
        }
        normalizeAudioFile(outFloatF, outF, outBuf, gain, f1);
        for (ch = 0; ch < outChanNum; ch++) {
          outFloatF[ch].cleanUp();
          outFloatF[ch] = null;
          outTempFile[ch].delete();
          outTempFile[ch] = null;
        }
      }
      // .... check running ....
      if (!threadRunning) break topLevel;

      // envelope file
      if ((envOutF != null) && (pr.intg[PR_ENVGAINTYPE] == GAIN_UNITY)) {
        peakGain = new Param((double) envMaxAmp, Param.ABS_AMP);
        envGain =
            (float)
                (Param.transform(
                        pr.para[PR_ENVGAIN],
                        Param.ABS_AMP,
                        new Param(1.0 / peakGain.val, peakGain.unit),
                        null))
                    .val;

        normalizeAudioFile(envFloatF, envOutF, inEnvBuf, envGain, 1.0f);
        for (ch = 0; ch < envOutChanNum; ch++) {
          envFloatF[ch].cleanUp();
          envFloatF[ch] = null;
          envTempFile[ch].delete();
          envTempFile[ch] = null;
        }
      }
      // .... check running ....
      if (!threadRunning) break topLevel;

      // ---- Finish ----

      outF.close();
      outF = null;
      outStream = null;
      if (envOutF != null) {
        envOutF.close();
        envOutF = null;
        envOutStream = null;
      }
      if (envInF != null) {
        envInF.close();
        envInF = null;
        envInStream = null;
      }
      inF.close();
      inF = null;
      inStream = null;
      outBuf = null;
      inBuf = null;
      inEnvBuf = null;
      envInBuf = null;
      shapeEnvBuf = null;

      // inform about clipping/ low level
      maxAmp *= gain;
      handleClipping(maxAmp);
      envMaxAmp *= envGain;
      //			handleClipping( envMaxAmp );	// ;( routine nicht flexibel genug!

    } catch (IOException e1) {
      setError(e1);
    } catch (OutOfMemoryError e2) {
      inStream = null;
      outStream = null;
      envInStream = null;
      envOutStream = null;
      inBuf = null;
      outBuf = null;
      inEnvBuf = null;
      envInBuf = null;
      shapeEnvBuf = null;
      convBuf1 = null;
      convBuf2 = null;
      System.gc();

      setError(new Exception(ERR_MEMORY));
      ;
    }

    // ---- cleanup (topLevel) ----
    if (inF != null) {
      inF.cleanUp();
      inF = null;
    }
    if (outF != null) {
      outF.cleanUp();
      outF = null;
    }
    if (envInF != null) {
      envInF.cleanUp();
      envInF = null;
    }
    if (envOutF != null) {
      envOutF.cleanUp();
      envOutF = null;
    }
    if (outFloatF != null) {
      for (ch = 0; ch < outFloatF.length; ch++) {
        if (outFloatF[ch] != null) outFloatF[ch].cleanUp();
        if (outTempFile[ch] != null) outTempFile[ch].delete();
      }
    }
    if (envFloatF != null) {
      for (ch = 0; ch < envFloatF.length; ch++) {
        if (envFloatF[ch] != null) envFloatF[ch].cleanUp();
        if (envTempFile[ch] != null) envTempFile[ch].delete();
      }
    }
  } // process()
예제 #3
0
  protected void buildGUI() {
    // einmalig PropertyArray initialisieren
    if (static_pr == null) {
      static_pr = new PropertyArray();
      static_pr.text = prText;
      static_pr.textName = prTextName;
      static_pr.intg = prIntg;
      static_pr.intgName = prIntgName;
      static_pr.bool = prBool;
      static_pr.boolName = prBoolName;
      static_pr.para = prPara;
      static_pr.para[PR_WARP] = new Param(-10.0, Param.FACTOR);
      static_pr.para[PR_WARPMODDEPTH] = new Param(20.0, Param.OFFSET_AMP);
      static_pr.para[PR_INFREQ] = new Param(1000.0, Param.ABS_HZ);
      static_pr.para[PR_OUTFREQ] = new Param(1000.0, Param.ABS_HZ);
      static_pr.paraName = prParaName;
      static_pr.envl = prEnvl;
      static_pr.envl[PR_WARPENV] = Envelope.createBasicEnvelope(Envelope.BASIC_TIME);
      static_pr.envlName = prEnvlName;
      //			static_pr.superPr	= DocumentFrame.static_pr;

      fillDefaultAudioDescr(static_pr.intg, PR_OUTPUTTYPE, PR_OUTPUTRES);
      fillDefaultGain(static_pr.para, PR_GAIN);
      static_presets = new Presets(getClass(), static_pr.toProperties(true));
    }
    presets = static_presets;
    pr = (PropertyArray) static_pr.clone();

    // -------- GUI bauen --------

    GridBagConstraints con;

    PathField ggInputFile, ggOutputFile;
    PathField[] ggParent1;
    ParamField ggWarp, ggWarpModDepth, ggInFreq, ggOutFreq;
    JCheckBox ggWarpMod;
    EnvIcon ggWarpEnv;
    Component[] ggGain;
    JComboBox ggFrameSize, ggOverlap;

    gui = new GUISupport();
    con = gui.getGridBagConstraints();
    con.insets = new Insets(1, 2, 1, 2);

    ParamListener paramL =
        new ParamListener() {
          public void paramChanged(ParamEvent e) {
            int ID = gui.getItemID(e);

            switch (ID) {
              case GG_WARP:
              case GG_INFREQ:
                pr.para[ID - GG_OFF_PARAMFIELD] = ((ParamField) e.getSource()).getParam();
                recalcOutFreq();
                break;

              case GG_OUTFREQ:
                pr.para[ID - GG_OFF_PARAMFIELD] = ((ParamField) e.getSource()).getParam();
                recalcWarpAmount();
                break;
            }
          }
        };

    ItemListener il =
        new ItemListener() {
          public void itemStateChanged(ItemEvent e) {
            int ID = gui.getItemID(e);

            switch (ID) {
              case GG_WARPMOD:
                pr.bool[ID - GG_OFF_CHECKBOX] = ((JCheckBox) e.getSource()).isSelected();
                reflectPropertyChanges();
                break;
            }
          }
        };

    PathListener pathL =
        new PathListener() {
          public void pathChanged(PathEvent e) {
            int ID = gui.getItemID(e);

            switch (ID) {
              case GG_INPUTFILE:
                setInput(((PathField) e.getSource()).getPath().getPath());
                break;
            }
          }
        };

    // -------- I/O-Gadgets --------
    con.fill = GridBagConstraints.BOTH;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addLabel(
        new GroupLabel("Waveform I/O", GroupLabel.ORIENT_HORIZONTAL, GroupLabel.BRACE_NONE));

    ggInputFile =
        new PathField(PathField.TYPE_INPUTFILE + PathField.TYPE_FORMATFIELD, "Select input file");
    ggInputFile.handleTypes(GenericFile.TYPES_SOUND);
    con.gridwidth = 1;
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Input file", SwingConstants.RIGHT));
    con.gridwidth = GridBagConstraints.REMAINDER;
    con.weightx = 0.9;
    gui.addPathField(ggInputFile, GG_INPUTFILE, pathL);

    ggOutputFile =
        new PathField(
            PathField.TYPE_OUTPUTFILE + PathField.TYPE_FORMATFIELD + PathField.TYPE_RESFIELD,
            "Select output file");
    ggOutputFile.handleTypes(GenericFile.TYPES_SOUND);
    con.gridwidth = 1;
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Output file", SwingConstants.RIGHT));
    con.gridwidth = GridBagConstraints.REMAINDER;
    con.weightx = 0.9;
    gui.addPathField(ggOutputFile, GG_OUTPUTFILE, pathL);
    gui.registerGadget(ggOutputFile.getTypeGadget(), GG_OUTPUTTYPE);
    gui.registerGadget(ggOutputFile.getResGadget(), GG_OUTPUTRES);

    ggParent1 = new PathField[1];
    ggParent1[0] = ggInputFile;
    ggOutputFile.deriveFrom(ggParent1, "$D0$F0Wrp$E");

    ggGain = createGadgets(GGTYPE_GAIN);
    con.weightx = 0.1;
    con.gridwidth = 1;
    gui.addLabel(new JLabel("Gain", SwingConstants.RIGHT));
    con.weightx = 0.4;
    gui.addParamField((ParamField) ggGain[0], GG_GAIN, paramL);
    con.weightx = 0.5;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addChoice((JComboBox) ggGain[1], GG_GAINTYPE, il);

    // -------- Settings-Gadgets --------
    gui.addLabel(
        new GroupLabel("Warp settings", GroupLabel.ORIENT_HORIZONTAL, GroupLabel.BRACE_NONE));

    ggWarp = new ParamField(Constants.spaces[Constants.modSpace]); // XXX
    con.weightx = 0.1;
    con.gridwidth = 1;
    gui.addLabel(new JLabel("Warp amount", SwingConstants.RIGHT));
    con.weightx = 0.4;
    gui.addParamField(ggWarp, GG_WARP, paramL);

    ggWarpModDepth = new ParamField(Constants.spaces[Constants.offsetAmpSpace]); // XXX
    ggWarpModDepth.setReference(ggWarp);
    ggWarpMod = new JCheckBox();
    con.weightx = 0.1;
    gui.addCheckbox(ggWarpMod, GG_WARPMOD, il);
    con.weightx = 0.4;
    gui.addParamField(ggWarpModDepth, GG_WARPMODDEPTH, paramL);

    ggWarpEnv = new EnvIcon(getComponent());
    con.weightx = 0.1;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addGadget(ggWarpEnv, GG_WARPENV);

    ggInFreq = new ParamField(Constants.spaces[Constants.absHzSpace]);
    con.weightx = 0.1;
    con.gridwidth = 1;
    gui.addLabel(new JLabel("Input freq.", SwingConstants.RIGHT));
    con.weightx = 0.4;
    gui.addParamField(ggInFreq, GG_INFREQ, paramL);
    ggOutFreq = new ParamField(Constants.spaces[Constants.absHzSpace]);
    con.weightx = 0.1;
    gui.addLabel(new JLabel("\u2192 Output freq.", SwingConstants.RIGHT));
    con.weightx = 0.4;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addParamField(ggOutFreq, GG_OUTFREQ, paramL);

    ggFrameSize = new JComboBox();
    for (int i = 32; i <= 32768; i <<= 1) {
      ggFrameSize.addItem(String.valueOf(i));
    }
    con.weightx = 0.1;
    con.gridwidth = 1;
    gui.addLabel(new JLabel("Frame size [smp]", SwingConstants.RIGHT));
    con.weightx = 0.4;
    gui.addChoice(ggFrameSize, GG_FRAMESIZE, il);

    ggOverlap = new JComboBox();
    for (int i = 1; i <= 16; i++) {
      ggOverlap.addItem(i + "x");
    }
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Overlap", SwingConstants.RIGHT));
    con.weightx = 0.4;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addChoice(ggOverlap, GG_OVERLAP, il);

    initGUI(this, FLAGS_PRESETS | FLAGS_PROGBAR, gui);
  }
예제 #4
0
  protected void buildGUI() {
    // einmalig PropertyArray initialisieren
    if (static_pr == null) {
      static_pr = new PropertyArray();
      static_pr.text = prText;
      static_pr.textName = prTextName;
      static_pr.intg = prIntg;
      static_pr.intgName = prIntgName;
      static_pr.bool = prBool;
      static_pr.boolName = prBoolName;
      static_pr.para = prPara;
      static_pr.para[PR_MAXCHANGE] = new Param(96.0, Param.DECIBEL_AMP);
      static_pr.para[PR_AVERAGE] = new Param(1000.0, Param.ABS_MS);
      static_pr.paraName = prParaName;
      static_pr.envl = prEnvl;
      static_pr.envl[PR_ENV] = Envelope.createBasicEnvelope(Envelope.BASIC_UNSIGNED_TIME);
      static_pr.envl[PR_RIGHTCHANENV] = Envelope.createBasicEnvelope(Envelope.BASIC_UNSIGNED_TIME);
      static_pr.envlName = prEnvlName;
      //			static_pr.superPr	= DocumentFrame.static_pr;

      fillDefaultAudioDescr(static_pr.intg, PR_OUTPUTTYPE, PR_OUTPUTRES);
      fillDefaultAudioDescr(static_pr.intg, PR_ENVOUTTYPE, PR_ENVOUTRES);
      fillDefaultGain(static_pr.para, PR_GAIN);
      fillDefaultGain(static_pr.para, PR_ENVGAIN);
      static_presets = new Presets(getClass(), static_pr.toProperties(true));
    }
    presets = static_presets;
    pr = (PropertyArray) static_pr.clone();

    // -------- GUI bauen --------

    GridBagConstraints con;
    //		GridBagLayout		lay;

    PathField ggInputFile, ggOutputFile, ggEnvInFile, ggEnvOutFile;
    PathField[] ggInputs;
    JComboBox ggEnvSource, ggMode;
    ParamField ggMaxChange, ggAverage;
    JCheckBox ggEnvOutput, ggInvert, ggRightChan;
    EnvIcon ggEnv, ggRightChanEnv;
    Component[] ggGain, ggEnvGain;
    ParamSpace[] spcAverage;
    ParamSpace spcMaxChange;

    gui = new GUISupport();
    con = gui.getGridBagConstraints();
    //		lay				= gui.getGridBagLayout();
    con.insets = new Insets(1, 2, 1, 2);

    ItemListener il =
        new ItemListener() {
          public void itemStateChanged(ItemEvent e) {
            int ID = gui.getItemID(e);

            switch (ID) {
              case GG_ENVSOURCE:
                pr.intg[ID - GG_OFF_CHOICE] = ((JComboBox) e.getSource()).getSelectedIndex();
                reflectPropertyChanges();
                break;
              case GG_ENVOUTPUT:
              case GG_RIGHTCHAN:
                pr.bool[ID - GG_OFF_CHECKBOX] = ((JCheckBox) e.getSource()).isSelected();
                reflectPropertyChanges();
                break;
            }
          }
        };

    // -------- Input-Gadgets --------
    con.fill = GridBagConstraints.BOTH;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addLabel(
        new GroupLabel("Waveform I/O", GroupLabel.ORIENT_HORIZONTAL, GroupLabel.BRACE_NONE));

    ggInputFile =
        new PathField(PathField.TYPE_INPUTFILE + PathField.TYPE_FORMATFIELD, "Select input file");
    ggInputFile.handleTypes(GenericFile.TYPES_SOUND);
    con.gridwidth = 1;
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Input file", SwingConstants.RIGHT));
    con.gridwidth = GridBagConstraints.REMAINDER;
    con.weightx = 0.9;
    gui.addPathField(ggInputFile, GG_INPUTFILE, null);

    ggEnvInFile =
        new PathField(
            PathField.TYPE_INPUTFILE + PathField.TYPE_FORMATFIELD, "Select input envelope file");
    ggEnvInFile.handleTypes(GenericFile.TYPES_SOUND);
    con.gridwidth = 1;
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Env input", SwingConstants.RIGHT));
    con.gridwidth = GridBagConstraints.REMAINDER;
    con.weightx = 0.9;
    gui.addPathField(ggEnvInFile, GG_ENVINFILE, null);

    ggOutputFile =
        new PathField(
            PathField.TYPE_OUTPUTFILE + PathField.TYPE_FORMATFIELD + PathField.TYPE_RESFIELD,
            "Select output file");
    ggOutputFile.handleTypes(GenericFile.TYPES_SOUND);
    ggInputs = new PathField[1];
    ggInputs[0] = ggInputFile;
    ggOutputFile.deriveFrom(ggInputs, "$D0$F0Amp$E");
    con.gridwidth = 1;
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Output file", SwingConstants.RIGHT));
    con.gridwidth = GridBagConstraints.REMAINDER;
    con.weightx = 0.9;
    gui.addPathField(ggOutputFile, GG_OUTPUTFILE, null);
    gui.registerGadget(ggOutputFile.getTypeGadget(), GG_OUTPUTTYPE);
    gui.registerGadget(ggOutputFile.getResGadget(), GG_OUTPUTRES);

    ggGain = createGadgets(GGTYPE_GAIN);
    con.weightx = 0.1;
    con.gridwidth = 1;
    gui.addLabel(new JLabel("Gain", SwingConstants.RIGHT));
    con.weightx = 0.4;
    gui.addParamField((ParamField) ggGain[0], GG_GAIN, null);
    con.weightx = 0.5;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addChoice((JComboBox) ggGain[1], GG_GAINTYPE, il);

    // -------- Env-Output-Gadgets --------
    gui.addLabel(
        new GroupLabel(
            "Separate envelope output", GroupLabel.ORIENT_HORIZONTAL, GroupLabel.BRACE_NONE));

    ggEnvOutFile =
        new PathField(
            PathField.TYPE_OUTPUTFILE + PathField.TYPE_FORMATFIELD + PathField.TYPE_RESFIELD,
            "Select output envelope file");
    ggEnvOutFile.handleTypes(GenericFile.TYPES_SOUND);
    ggEnvOutFile.deriveFrom(ggInputs, "$D0$F0Env$E");
    con.gridwidth = 1;
    con.weightx = 0.1;
    ggEnvOutput = new JCheckBox("Env output");
    gui.addCheckbox(ggEnvOutput, GG_ENVOUTPUT, il);
    con.gridwidth = GridBagConstraints.REMAINDER;
    con.weightx = 0.9;
    gui.addPathField(ggEnvOutFile, GG_ENVOUTFILE, null);
    gui.registerGadget(ggEnvOutFile.getTypeGadget(), GG_ENVOUTTYPE);
    gui.registerGadget(ggEnvOutFile.getResGadget(), GG_ENVOUTRES);

    // cannot call createGadgets twice (BUG!) XXX
    ggEnvGain = new Component[2]; // createGadgets( GGTYPE_GAIN );
    ggEnvGain[0] = new ParamField(Constants.spaces[Constants.decibelAmpSpace]);
    JComboBox ch = new JComboBox();
    ch.addItem("normalized");
    ch.addItem("immediate");
    ggEnvGain[1] = ch;

    con.weightx = 0.1;
    con.gridwidth = 1;
    gui.addLabel(new JLabel("Gain", SwingConstants.RIGHT));
    con.weightx = 0.4;
    gui.addParamField((ParamField) ggEnvGain[0], GG_ENVGAIN, null);
    con.weightx = 0.5;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addChoice((JComboBox) ggEnvGain[1], GG_ENVGAINTYPE, il);

    // -------- Settings --------
    gui.addLabel(
        new GroupLabel("Shaper Settings", GroupLabel.ORIENT_HORIZONTAL, GroupLabel.BRACE_NONE));

    ggEnvSource = new JComboBox();
    ggEnvSource.addItem("Input file");
    ggEnvSource.addItem("Sound file");
    ggEnvSource.addItem("Envelope file");
    ggEnvSource.addItem("Envelope");
    con.gridwidth = 1;
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Source", SwingConstants.RIGHT));
    con.weightx = 0.4;
    gui.addChoice(ggEnvSource, GG_ENVSOURCE, il);

    ggInvert = new JCheckBox();
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Inversion", SwingConstants.RIGHT));
    con.gridwidth = GridBagConstraints.REMAINDER;
    con.weightx = 0.4;
    gui.addCheckbox(ggInvert, GG_INVERT, il);

    ggMode = new JComboBox();
    ggMode.addItem("Superposition");
    ggMode.addItem("Replacement");
    con.gridwidth = 1;
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Apply mode", SwingConstants.RIGHT));
    con.weightx = 0.4;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addChoice(ggMode, GG_MODE, il);

    ggEnv = new EnvIcon(getComponent());
    con.gridwidth = 1;
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Envelope", SwingConstants.RIGHT));
    con.weightx = 0.4;
    gui.addGadget(ggEnv, GG_ENV);

    spcMaxChange = new ParamSpace(Constants.spaces[Constants.decibelAmpSpace]);
    //		spcMaxChange.min= spcMaxChange.inc;
    spcMaxChange =
        new ParamSpace(spcMaxChange.inc, spcMaxChange.max, spcMaxChange.inc, spcMaxChange.unit);
    ggMaxChange = new ParamField(spcMaxChange);
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Max boost", SwingConstants.RIGHT));
    con.weightx = 0.4;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addParamField(ggMaxChange, GG_MAXCHANGE, null);

    ggRightChan = new JCheckBox("Right chan.");
    ggRightChanEnv = new EnvIcon(getComponent());
    con.weightx = 0.1;
    con.gridwidth = 1;
    gui.addCheckbox(ggRightChan, GG_RIGHTCHAN, il);
    con.weightx = 0.4;
    gui.addGadget(ggRightChanEnv, GG_RIGHTCHANENV);

    spcAverage = new ParamSpace[3];
    spcAverage[0] = Constants.spaces[Constants.absMsSpace];
    spcAverage[1] = Constants.spaces[Constants.absBeatsSpace];
    spcAverage[2] = Constants.spaces[Constants.ratioTimeSpace];
    ggAverage = new ParamField(spcAverage);
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Smoothing", SwingConstants.RIGHT));
    con.weightx = 0.4;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addParamField(ggAverage, GG_AVERAGE, null);

    initGUI(this, FLAGS_PRESETS | FLAGS_PROGBAR, gui);
  }
예제 #5
0
  /** Translation durchfuehren */
  public void process() {
    int i, j, k;
    int ch, len;
    float f1;
    double d1, d2, d3, d4, d5;
    long progOff, progLen, lo;

    // io
    AudioFile reInF = null;
    AudioFile imInF = null;
    AudioFile reOutF = null;
    AudioFile imOutF = null;
    AudioFileDescr reInStream = null;
    AudioFileDescr imInStream = null;
    AudioFileDescr reOutStream = null;
    AudioFileDescr imOutStream = null;
    FloatFile reFloatF[] = null;
    FloatFile imFloatF[] = null;
    File reTempFile[] = null;
    File imTempFile[] = null;
    int outChanNum;

    float[][] reInBuf; // [ch][i]
    float[][] imInBuf; // [ch][i]
    float[][] reOutBuf = null; // [ch][i]
    float[][] imOutBuf = null; // [ch][i]
    float[] convBuf1, convBuf2;
    boolean complex;

    PathField ggOutput;

    // Synthesize
    Param ampRef = new Param(1.0, Param.ABS_AMP); // transform-Referenz
    float gain; // gain abs amp
    float dryGain, wetGain;
    float inGain;
    float maxAmp = 0.0f;
    Param peakGain;

    int inLength, inOff;
    int pre;
    int post;
    int length;
    int framesRead, framesWritten, outLength;
    boolean polarIn, polarOut;

    // phase unwrapping
    double[] phi;
    int[] wrap;
    double[] carry;

    Param lenRef;

    topLevel:
    try {

      complex = pr.bool[PR_HASIMINPUT] || pr.bool[PR_HASIMOUTPUT];
      polarIn = pr.intg[PR_OPERATOR] == OP_POLAR2RECT;
      polarOut = pr.intg[PR_OPERATOR] == OP_RECT2POLAR;
      if ((polarIn || polarOut) && !complex) throw new IOException(ERR_NOTCOMPLEX);

      // ---- open input ----

      reInF = AudioFile.openAsRead(new File(pr.text[PR_REINPUTFILE]));
      reInStream = reInF.getDescr();
      inLength = (int) reInStream.length;
      reInBuf = new float[reInStream.channels][8192];
      imInBuf = new float[reInStream.channels][8192];

      if (pr.bool[PR_HASIMINPUT]) {
        imInF = AudioFile.openAsRead(new File(pr.text[PR_IMINPUTFILE]));
        imInStream = imInF.getDescr();
        if (imInStream.channels != reInStream.channels) throw new IOException(ERR_COMPLEX);
        inLength = (int) Math.min(inLength, imInStream.length);
      }

      lenRef = new Param(AudioFileDescr.samplesToMillis(reInStream, inLength), Param.ABS_MS);
      d1 =
          AudioFileDescr.millisToSamples(
              reInStream, (Param.transform(pr.para[PR_OFFSET], Param.ABS_MS, lenRef, null).value));
      j = (int) (d1 >= 0.0 ? (d1 + 0.5) : (d1 - 0.5)); // correct rounding for negative values!
      length =
          (int)
              (AudioFileDescr.millisToSamples(
                      reInStream,
                      (Param.transform(pr.para[PR_LENGTH], Param.ABS_MS, lenRef, null)).value)
                  + 0.5);

      // System.err.println( "offset = "+j );

      if (j >= 0) {
        inOff = Math.min(j, inLength);
        if (!pr.bool[PR_REVERSE]) {
          reInF.seekFrame(inOff);
          if (pr.bool[PR_HASIMINPUT]) {
            imInF.seekFrame(inOff);
          }
        }
        inLength -= inOff;
        pre = 0;
      } else {
        inOff = 0;
        pre = Math.min(-j, length);
      }
      inLength = Math.min(inLength, length - pre);
      post = length - pre - inLength;

      if (pr.bool[PR_REVERSE]) {
        i = pre;
        pre = post;
        post = i;
        inOff += inLength;
      }

      // .... check running ....
      if (!threadRunning) break topLevel;

      // for( op = 0; op < 2; op++ ) {
      // 	System.out.println( op +": pre "+pre[op]+" / len "+inLength[op]+" / post "+post[op] );
      // }
      // System.out.println( "tot "+length[0]);

      outLength = length;
      outChanNum = reInStream.channels;

      // ---- open output ----

      ggOutput = (PathField) gui.getItemObj(GG_REOUTPUTFILE);
      if (ggOutput == null) throw new IOException(ERR_MISSINGPROP);
      reOutStream = new AudioFileDescr(reInStream);
      ggOutput.fillStream(reOutStream);
      reOutStream.channels = outChanNum;
      // well, more sophisticated code would
      // move and truncate the markers...
      if ((pre == 0) /* && (post == 0) */) {
        reInF.readMarkers();
        reOutStream.setProperty(
            AudioFileDescr.KEY_MARKERS, reInStream.getProperty(AudioFileDescr.KEY_MARKERS));
      }
      reOutF = AudioFile.openAsWrite(reOutStream);
      reOutBuf = new float[outChanNum][8192];
      imOutBuf = new float[outChanNum][8192];

      if (pr.bool[PR_HASIMOUTPUT]) {
        imOutStream = new AudioFileDescr(reInStream);
        ggOutput.fillStream(imOutStream);
        imOutStream.channels = outChanNum;
        imOutStream.file = new File(pr.text[PR_IMOUTPUTFILE]);
        imOutF = AudioFile.openAsWrite(imOutStream);
      }
      // .... check running ....
      if (!threadRunning) break topLevel;

      // ---- Further inits ----

      phi = new double[outChanNum];
      wrap = new int[outChanNum];
      carry = new double[outChanNum];
      for (ch = 0; ch < outChanNum; ch++) {
        phi[ch] = 0.0;
        wrap[ch] = 0;
        carry[ch] = Double.NEGATIVE_INFINITY;
      }

      progOff = 0; // read, transform, write
      progLen = (long) outLength * 3;

      wetGain = (float) (Param.transform(pr.para[PR_WETMIX], Param.ABS_AMP, ampRef, null)).value;
      dryGain = (float) (Param.transform(pr.para[PR_DRYMIX], Param.ABS_AMP, ampRef, null)).value;
      if (pr.bool[PR_DRYINVERT]) {
        dryGain = -dryGain;
      }
      inGain = (float) (Param.transform(pr.para[PR_INPUTGAIN], Param.ABS_AMP, ampRef, null)).value;
      if (pr.bool[PR_INVERT]) {
        inGain = -inGain;
      }

      // normalization requires temp files
      if (pr.intg[PR_GAINTYPE] == GAIN_UNITY) {
        reTempFile = new File[outChanNum];
        reFloatF = new FloatFile[outChanNum];
        for (ch = 0;
            ch < outChanNum;
            ch++) { // first zero them because an exception might be thrown
          reTempFile[ch] = null;
          reFloatF[ch] = null;
        }
        for (ch = 0; ch < outChanNum; ch++) {
          reTempFile[ch] = IOUtil.createTempFile();
          reFloatF[ch] = new FloatFile(reTempFile[ch], GenericFile.MODE_OUTPUT);
        }
        if (pr.bool[PR_HASIMOUTPUT]) {
          imTempFile = new File[outChanNum];
          imFloatF = new FloatFile[outChanNum];
          for (ch = 0;
              ch < outChanNum;
              ch++) { // first zero them because an exception might be thrown
            imTempFile[ch] = null;
            imFloatF[ch] = null;
          }
          for (ch = 0; ch < outChanNum; ch++) {
            imTempFile[ch] = IOUtil.createTempFile();
            imFloatF[ch] = new FloatFile(imTempFile[ch], GenericFile.MODE_OUTPUT);
          }
        }
        progLen += outLength;
      } else {
        gain = (float) (Param.transform(pr.para[PR_GAIN], Param.ABS_AMP, ampRef, null)).value;
        wetGain *= gain;
        dryGain *= gain;
      }
      // .... check running ....
      if (!threadRunning) break topLevel;

      // ----==================== the real stuff ====================----

      framesRead = 0;
      framesWritten = 0;

      while (threadRunning && (framesWritten < outLength)) {
        // ---- choose chunk len ----
        len = Math.min(8192, outLength - framesWritten);
        if (pre > 0) {
          len = Math.min(len, pre);
        } else if (inLength > 0) {
          len = Math.min(len, inLength);
        } else {
          len = Math.min(len, post);
        }

        // ---- read input chunks ----
        if (pre > 0) {
          Util.clear(reInBuf);
          if (complex) {
            Util.clear(imInBuf);
          }
          pre -= len;
        } else if (inLength > 0) {
          if (pr.bool[PR_REVERSE]) { // ---- read reversed ----
            reInF.seekFrame(inOff - framesRead - len);
            reInF.readFrames(reInBuf, 0, len);
            for (ch = 0; ch < reInStream.channels; ch++) {
              convBuf1 = reInBuf[ch];
              for (i = 0, j = len - 1; i < j; i++, j--) {
                f1 = convBuf1[j];
                convBuf1[j] = convBuf1[i];
                convBuf1[i] = f1;
              }
            }
            if (pr.bool[PR_HASIMINPUT]) {
              imInF.seekFrame(inOff - framesRead - len);
              imInF.readFrames(imInBuf, 0, len);
              for (ch = 0; ch < imInStream.channels; ch++) {
                convBuf1 = imInBuf[ch];
                for (i = 0, j = len - 1; i < j; i++, j--) {
                  f1 = convBuf1[j];
                  convBuf1[j] = convBuf1[i];
                  convBuf1[i] = f1;
                }
              }
            } else if (complex) {
              Util.clear(imInBuf);
            }
          } else { // ---- read normal ----
            reInF.readFrames(reInBuf, 0, len);
            if (pr.bool[PR_HASIMINPUT]) {
              imInF.readFrames(imInBuf, 0, len);
            } else if (complex) {
              Util.clear(imInBuf);
            }
          }
          inLength -= len;
          framesRead += len;
        } else {
          Util.clear(reInBuf);
          if (complex) {
            Util.clear(imInBuf);
          }
          post -= len;
        }
        progOff += len;
        // .... progress ....
        setProgression((float) progOff / (float) progLen);
        // .... check running ....
        if (!threadRunning) break topLevel;

        // ---- save dry signal ----
        for (ch = 0; ch < outChanNum; ch++) {
          convBuf1 = reInBuf[ch];
          convBuf2 = reOutBuf[ch];
          for (i = 0; i < len; i++) {
            convBuf2[i] = convBuf1[i] * dryGain;
          }
          if (complex) {
            convBuf1 = imInBuf[ch];
            convBuf2 = imOutBuf[ch];
            for (i = 0; i < len; i++) {
              convBuf2[i] = convBuf1[i] * dryGain;
            }
          }
        }

        // ---- rectify + apply input gain ----
        for (ch = 0; ch < reInStream.channels; ch++) {
          convBuf1 = reInBuf[ch];
          convBuf2 = imInBuf[ch];
          // ---- rectify ----
          if (pr.bool[PR_RECTIFY]) {
            if (complex) {
              if (polarIn) {
                for (i = 0; i < len; i++) {
                  convBuf2[i] = 0.0f;
                }
              } else {
                for (i = 0; i < len; i++) {
                  d1 = convBuf1[i];
                  d2 = convBuf2[i];
                  convBuf1[i] = (float) Math.sqrt(d1 * d1 + d2 * d2);
                  convBuf2[i] = 0.0f;
                }
              }
            } else {
              for (i = 0; i < len; i++) {
                convBuf1[i] = Math.abs(convBuf1[i]);
              }
            }
          }
          // ---- apply input gain ----
          Util.mult(convBuf1, 0, len, inGain);
          if (complex & !polarIn) {
            Util.mult(convBuf2, 0, len, inGain);
          }
        }

        // ---- heart of the dragon ----
        for (ch = 0; ch < outChanNum; ch++) {
          convBuf1 = reInBuf[ch];
          convBuf2 = imInBuf[ch];

          switch (pr.intg[PR_OPERATOR]) {
            case OP_NONE: // ================ None ================
              for (i = 0; i < len; i++) {
                reOutBuf[ch][i] += wetGain * convBuf1[i];
              }
              if (complex) {
                for (i = 0; i < len; i++) {
                  imOutBuf[ch][i] += wetGain * convBuf2[i];
                }
              }
              break;

            case OP_SIN: // ================ Cosinus ================
              if (complex) {
                for (i = 0; i < len; i++) {
                  reOutBuf[ch][i] += wetGain * (float) Math.sin(convBuf1[i] * Math.PI);
                  imOutBuf[ch][i] += wetGain * (float) Math.sin(convBuf2[i] * Math.PI);
                }
              } else {
                for (i = 0; i < len; i++) {
                  reOutBuf[ch][i] += wetGain * (float) Math.sin(convBuf1[i] * Math.PI);
                }
              }
              break;

            case OP_SQR: // ================ Square ================
              if (complex) {
                for (i = 0; i < len; i++) {
                  reOutBuf[ch][i] +=
                      wetGain * (convBuf1[i] * convBuf1[i] - convBuf2[i] * convBuf2[i]);
                  imOutBuf[ch][i] -= wetGain * (convBuf1[i] * convBuf2[i] * 2);
                }
              } else {
                for (i = 0; i < len; i++) {
                  reOutBuf[ch][i] += wetGain * (convBuf1[i] * convBuf1[i]);
                }
              }
              break;

            case OP_SQRT: // ================ Square root ================
              if (complex) {
                d3 = phi[ch];
                k = wrap[ch];
                d4 = k * Constants.PI2;
                for (i = 0; i < len; i++) {
                  d1 =
                      wetGain
                          * Math.pow(convBuf1[i] * convBuf1[i] + convBuf2[i] * convBuf2[i], 0.25);
                  d2 = Math.atan2(convBuf2[i], convBuf1[i]);
                  if (d2 - d3 > Math.PI) {
                    k--;
                    d4 = k * Constants.PI2;
                  } else if (d3 - d2 > Math.PI) {
                    k++;
                    d4 = k * Constants.PI2;
                  }
                  d2 += d4;
                  d3 = d2;
                  d2 /= 2;
                  reOutBuf[ch][i] += (float) (d1 * Math.cos(d2));
                  imOutBuf[ch][i] += (float) (d1 * Math.sin(d2));
                }
                phi[ch] = d3;
                wrap[ch] = k;

              } else {
                for (i = 0; i < len; i++) {
                  f1 = convBuf1[i];
                  if (f1 > 0) {
                    reOutBuf[ch][i] += wetGain * (float) Math.sqrt(f1);
                  } // else undefiniert
                }
              }
              break;

            case OP_RECT2POLARW: // ================ Rect->Polar (wrapped) ================
              for (i = 0; i < len; i++) {
                d1 = wetGain * Math.sqrt(convBuf1[i] * convBuf1[i] + convBuf2[i] * convBuf2[i]);
                d2 = Math.atan2(convBuf2[i], convBuf1[i]);
                reOutBuf[ch][i] += (float) d1;
                imOutBuf[ch][i] += (float) d2;
              }
              break;

            case OP_RECT2POLAR: // ================ Rect->Polar ================
              d3 = phi[ch];
              k = wrap[ch];
              d4 = k * Constants.PI2;
              for (i = 0; i < len; i++) {
                d1 = wetGain * Math.sqrt(convBuf1[i] * convBuf1[i] + convBuf2[i] * convBuf2[i]);
                d2 = Math.atan2(convBuf2[i], convBuf1[i]);
                if (d2 - d3 > Math.PI) {
                  k--;
                  d4 = k * Constants.PI2;
                } else if (d3 - d2 > Math.PI) {
                  k++;
                  d4 = k * Constants.PI2;
                }
                d2 += d4;
                reOutBuf[ch][i] += (float) d1;
                imOutBuf[ch][i] += (float) d2;
                d3 = d2;
              }
              phi[ch] = d3;
              wrap[ch] = k;
              break;

            case OP_POLAR2RECT: // ================ Polar->Rect ================
              for (i = 0; i < len; i++) {
                f1 = wetGain * convBuf1[i];
                reOutBuf[ch][i] += f1 * (float) Math.cos(convBuf2[i]);
                imOutBuf[ch][i] += f1 * (float) Math.sin(convBuf2[i]);
              }
              break;

            case OP_LOG: // ================ Log ================
              if (complex) {
                d3 = phi[ch];
                k = wrap[ch];
                d4 = k * Constants.PI2;
                d5 = carry[ch];
                for (i = 0; i < len; i++) {
                  d1 = Math.sqrt(convBuf1[i] * convBuf1[i] + convBuf2[i] * convBuf2[i]);
                  d2 = Math.atan2(convBuf2[i], convBuf1[i]);
                  if (d2 - d3 > Math.PI) {
                    k--;
                    d4 = k * Constants.PI2;
                  } else if (d3 - d2 > Math.PI) {
                    k++;
                    d4 = k * Constants.PI2;
                  }
                  if (d1 > 0.0) {
                    d5 = Math.log(d1);
                  }
                  d2 += d4;
                  reOutBuf[ch][i] += (float) d5;
                  imOutBuf[ch][i] += (float) d2;
                  d3 = d2;
                }
                phi[ch] = d3;
                wrap[ch] = k;
                carry[ch] = d5;

              } else {
                for (i = 0; i < len; i++) {
                  f1 = convBuf1[i];
                  if (f1 > 0) {
                    reOutBuf[ch][i] += wetGain * (float) Math.log(f1);
                  } // else undefiniert
                }
              }
              break;

            case OP_EXP: // ================ Exp ================
              if (complex) {
                for (i = 0; i < len; i++) {
                  d1 = wetGain * Math.exp(convBuf1[i]);
                  reOutBuf[ch][i] += (float) (d1 * Math.cos(convBuf2[i]));
                  imOutBuf[ch][i] += (float) (d1 * Math.sin(convBuf2[i]));
                }
              } else {
                for (i = 0; i < len; i++) {
                  reOutBuf[ch][i] += wetGain * (float) Math.exp(convBuf1[i]);
                }
              }
              break;

            case OP_NOT: // ================ NOT ================
              for (i = 0; i < len; i++) {
                lo = ~((long) (convBuf1[i] * 2147483647.0));
                reOutBuf[ch][i] += wetGain * (float) ((lo & 0xFFFFFFFFL) / 2147483647.0);
              }
              if (complex) {
                for (i = 0; i < len; i++) {
                  lo = ~((long) (convBuf2[i] * 2147483647.0));
                  imOutBuf[ch][i] += wetGain * (float) ((lo & 0xFFFFFFFFL) / 2147483647.0);
                }
              }
              break;
          }
        } // for outChan
        progOff += len;
        // .... progress ....
        setProgression((float) progOff / (float) progLen);
        // .... check running ....
        if (!threadRunning) break topLevel;

        // ---- write output chunk ----
        if (reFloatF != null) {
          for (ch = 0; ch < outChanNum; ch++) {
            reFloatF[ch].writeFloats(reOutBuf[ch], 0, len);
            if (pr.bool[PR_HASIMOUTPUT]) {
              imFloatF[ch].writeFloats(imOutBuf[ch], 0, len);
            }
          }
        } else {
          reOutF.writeFrames(reOutBuf, 0, len);
          if (pr.bool[PR_HASIMOUTPUT]) {
            imOutF.writeFrames(imOutBuf, 0, len);
          }
        }
        // check max amp
        for (ch = 0; ch < outChanNum; ch++) {
          convBuf1 = reOutBuf[ch];
          for (i = 0; i < len; i++) {
            f1 = Math.abs(convBuf1[i]);
            if (f1 > maxAmp) {
              maxAmp = f1;
            }
          }
          if (pr.bool[PR_HASIMOUTPUT]) {
            convBuf1 = imOutBuf[ch];
            for (i = 0; i < len; i++) {
              f1 = Math.abs(convBuf1[i]);
              if (f1 > maxAmp) {
                maxAmp = f1;
              }
            }
          }
        }

        progOff += len;
        framesWritten += len;
        // .... progress ....
        setProgression((float) progOff / (float) progLen);
      } // while not framesWritten

      // ----==================== normalize output ====================----

      if (pr.intg[PR_GAINTYPE] == GAIN_UNITY) {
        peakGain = new Param(maxAmp, Param.ABS_AMP);
        gain =
            (float)
                (Param.transform(
                        pr.para[PR_GAIN],
                        Param.ABS_AMP,
                        new Param(1.0 / peakGain.value, peakGain.unit),
                        null))
                    .value;
        f1 = pr.bool[PR_HASIMOUTPUT] ? ((1.0f + getProgression()) / 2) : 1.0f;
        normalizeAudioFile(reFloatF, reOutF, reOutBuf, gain, f1);
        if (pr.bool[PR_HASIMOUTPUT]) {
          normalizeAudioFile(imFloatF, imOutF, imOutBuf, gain, 1.0f);
        }
        maxAmp *= gain;

        for (ch = 0; ch < outChanNum; ch++) {
          reFloatF[ch].cleanUp();
          reFloatF[ch] = null;
          reTempFile[ch].delete();
          reTempFile[ch] = null;
          if (pr.bool[PR_HASIMOUTPUT]) {
            imFloatF[ch].cleanUp();
            imFloatF[ch] = null;
            imTempFile[ch].delete();
            imTempFile[ch] = null;
          }
        }
      }
      // .... check running ....
      if (!threadRunning) break topLevel;

      // ---- Finish ----

      reOutF.close();
      reOutF = null;
      reOutStream = null;
      if (imOutF != null) {
        imOutF.close();
        imOutF = null;
        imOutStream = null;
      }
      reInF.close();
      reInF = null;
      reInStream = null;
      if (pr.bool[PR_HASIMINPUT]) {
        imInF.close();
        imInF = null;
        imInStream = null;
      }
      reOutBuf = null;
      imOutBuf = null;
      reInBuf = null;
      imInBuf = null;

      // inform about clipping/ low level
      handleClipping(maxAmp);
    } catch (IOException e1) {
      setError(e1);
    } catch (OutOfMemoryError e2) {
      reOutBuf = null;
      imOutBuf = null;
      reInBuf = null;
      imInBuf = null;
      convBuf1 = null;
      convBuf2 = null;
      System.gc();

      setError(new Exception(ERR_MEMORY));
    }

    // ---- cleanup (topLevel) ----
    convBuf1 = null;
    convBuf2 = null;

    if (reInF != null) {
      reInF.cleanUp();
      reInF = null;
    }
    if (imInF != null) {
      imInF.cleanUp();
      imInF = null;
    }
    if (reOutF != null) {
      reOutF.cleanUp();
      reOutF = null;
    }
    if (imOutF != null) {
      imOutF.cleanUp();
      imOutF = null;
    }
    if (reFloatF != null) {
      for (ch = 0; ch < reFloatF.length; ch++) {
        if (reFloatF[ch] != null) {
          reFloatF[ch].cleanUp();
          reFloatF[ch] = null;
        }
        if (reTempFile[ch] != null) {
          reTempFile[ch].delete();
          reTempFile[ch] = null;
        }
      }
    }
    if (imFloatF != null) {
      for (ch = 0; ch < imFloatF.length; ch++) {
        if (imFloatF[ch] != null) {
          imFloatF[ch].cleanUp();
          imFloatF[ch] = null;
        }
        if (imTempFile[ch] != null) {
          imTempFile[ch].delete();
          imTempFile[ch] = null;
        }
      }
    }
  } // process()
예제 #6
0
  protected void buildGUI() {
    // einmalig PropertyArray initialisieren
    if (static_pr == null) {
      static_pr = new PropertyArray();
      static_pr.text = prText;
      static_pr.textName = prTextName;
      static_pr.intg = prIntg;
      static_pr.intgName = prIntgName;
      static_pr.para = prPara;
      static_pr.para[PR_INPUTGAIN] = new Param(0.0, Param.DECIBEL_AMP);
      static_pr.para[PR_OFFSET] = new Param(0.0, Param.ABS_MS);
      static_pr.para[PR_LENGTH] = new Param(100.0, Param.FACTOR_TIME);
      static_pr.para[PR_DRYMIX] = new Param(0.0, Param.FACTOR_AMP);
      static_pr.para[PR_WETMIX] = new Param(100.0, Param.FACTOR_AMP);
      static_pr.paraName = prParaName;
      static_pr.bool = prBool;
      static_pr.boolName = prBoolName;
      //			static_pr.superPr	= DocumentFrame.static_pr;

      fillDefaultAudioDescr(static_pr.intg, PR_OUTPUTTYPE, PR_OUTPUTRES);
      fillDefaultGain(static_pr.para, PR_GAIN);
      static_presets = new Presets(getClass(), static_pr.toProperties(true));
    }
    presets = static_presets;
    pr = (PropertyArray) static_pr.clone();

    // -------- build GUI --------

    GridBagConstraints con;

    PathField ggImInputFile, ggReInputFile, ggReOutputFile, ggImOutputFile;
    ParamField ggInputGain, ggOffset, ggLength, ggDryMix, ggWetMix;
    JComboBox ggOperator;
    JCheckBox ggHasImInput, ggHasImOutput, ggRectify, ggInvert, ggDryInvert, ggReverse;
    PathField[] ggParent1, ggParent2;
    Component[] ggGain;
    ParamSpace[] spcOffset, spcLength;
    int anchor;

    gui = new GUISupport();
    con = gui.getGridBagConstraints();
    con.insets = new Insets(1, 2, 1, 2);

    ItemListener il =
        new ItemListener() {
          public void itemStateChanged(ItemEvent e) {
            int ID = gui.getItemID(e);

            switch (ID) {
              case GG_HASIMINPUT:
              case GG_HASIMOUTPUT:
                pr.bool[ID - GG_OFF_CHECKBOX] = ((JCheckBox) e.getSource()).isSelected();
                reflectPropertyChanges();
                break;
            }
          }
        };

    PathListener pathL =
        new PathListener() {
          public void pathChanged(PathEvent e) {
            int ID = gui.getItemID(e);

            switch (ID) {
              case PR_REINPUTFILE:
                setInput(((PathField) e.getSource()).getPath().getPath());
                break;
            }
          }
        };

    // -------- Input-Gadgets --------
    spcOffset = new ParamSpace[3];
    spcOffset[0] =
        new ParamSpace(-36000000.0, 36000000.0, 0.1, Param.ABS_MS); // allow negative offset
    spcOffset[1] = new ParamSpace(-240000.0, 240000.0, 0.001, Param.ABS_BEATS);
    spcOffset[2] = new ParamSpace(-100.0, 100.0, 0.01, Param.FACTOR_TIME);
    //		spcOffset[0]	= Constants.spaces[ Constants.absMsSpace ];
    //		spcOffset[1]	= Constants.spaces[ Constants.absBeatsSpace ];
    //		spcOffset[2]	= Constants.spaces[ Constants.offsetTimeSpace ];
    spcLength = new ParamSpace[4];
    spcLength[0] = Constants.spaces[Constants.absMsSpace];
    spcLength[1] = Constants.spaces[Constants.absBeatsSpace];
    spcLength[2] = Constants.spaces[Constants.offsetTimeSpace];
    spcLength[3] = Constants.spaces[Constants.factorTimeSpace];

    con.fill = GridBagConstraints.BOTH;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addLabel(new GroupLabel("Input file", GroupLabel.ORIENT_HORIZONTAL, GroupLabel.BRACE_NONE));
    con.fill = GridBagConstraints.HORIZONTAL;

    ggReInputFile =
        new PathField(
            PathField.TYPE_INPUTFILE + PathField.TYPE_FORMATFIELD, "Select real part of input");
    ggReInputFile.handleTypes(GenericFile.TYPES_SOUND);
    con.gridwidth = 1;
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Input [Real]", SwingConstants.RIGHT));
    con.gridwidth = 2;
    con.weightx = 3.0;
    gui.addPathField(ggReInputFile, GG_REINPUTFILE, pathL);

    ggOffset = new ParamField(spcOffset);
    con.weightx = 0.1;
    con.gridwidth = 1;
    gui.addLabel(new JLabel("Offset", SwingConstants.RIGHT));
    con.weightx = 0.4;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addParamField(ggOffset, GG_OFFSET, null);

    ggImInputFile =
        new PathField(
            PathField.TYPE_INPUTFILE + PathField.TYPE_FORMATFIELD,
            "Select imaginary part of input");
    ggImInputFile.handleTypes(GenericFile.TYPES_SOUND);
    ggHasImInput = new JCheckBox("Input [Imaginary]");
    con.gridwidth = 1;
    con.weightx = 0.1;
    anchor = con.anchor;
    con.anchor = GridBagConstraints.EAST;
    gui.addCheckbox(ggHasImInput, GG_HASIMINPUT, il);
    con.anchor = anchor;
    con.weightx = 3.0;
    con.gridwidth = 2;
    gui.addPathField(ggImInputFile, GG_IMINPUTFILE, pathL);

    ggLength = new ParamField(spcLength);
    con.weightx = 0.1;
    con.gridwidth = 1;
    gui.addLabel(new JLabel("Length", SwingConstants.RIGHT));
    con.weightx = 0.4;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addParamField(ggLength, GG_LENGTH, null);

    ggParent1 = new PathField[1];
    ggParent1[0] = ggReInputFile;
    ggParent2 = new PathField[1];
    ggParent2[0] = ggReInputFile;
    ggImInputFile.deriveFrom(ggParent2, "$D0$F0i$X0");

    ggInputGain = new ParamField(Constants.spaces[Constants.decibelAmpSpace]);
    con.gridwidth = 1;
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Drive", SwingConstants.RIGHT));
    con.weightx = 0.4;
    gui.addParamField(ggInputGain, GG_INPUTGAIN, null);

    con.weightx = 0.1;
    con.gridwidth = 1;
    gui.addLabel(new JLabel(""));
    ggRectify = new JCheckBox("Rectify");
    con.gridwidth = 1;
    con.weightx = 0.4;
    gui.addCheckbox(ggRectify, GG_RECTIFY, il);
    ggInvert = new JCheckBox("Invert");
    gui.addCheckbox(ggInvert, GG_INVERT, il);
    ggReverse = new JCheckBox("Reverse");
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addCheckbox(ggReverse, GG_REVERSE, il);

    // -------- Output-Gadgets --------
    gui.addLabel(new GroupLabel("Output", GroupLabel.ORIENT_HORIZONTAL, GroupLabel.BRACE_NONE));

    ggReOutputFile =
        new PathField(
            PathField.TYPE_OUTPUTFILE + PathField.TYPE_FORMATFIELD + PathField.TYPE_RESFIELD,
            "Select output for real part");
    ggReOutputFile.handleTypes(GenericFile.TYPES_SOUND);
    con.gridwidth = 1;
    con.weightx = 0.1;
    gui.addLabel(new JLabel("File [Real]", SwingConstants.RIGHT));
    con.gridwidth = GridBagConstraints.REMAINDER;
    con.weightx = 0.9;
    gui.addPathField(ggReOutputFile, GG_REOUTPUTFILE, pathL);
    gui.registerGadget(ggReOutputFile.getTypeGadget(), GG_OUTPUTTYPE);
    gui.registerGadget(ggReOutputFile.getResGadget(), GG_OUTPUTRES);

    ggImOutputFile = new PathField(PathField.TYPE_OUTPUTFILE, "Select output for imaginary part");
    //		ggImOutputFile.handleTypes( GenericFile.TYPES_SOUND );
    ggHasImOutput = new JCheckBox("File [Imaginary]");
    con.gridwidth = 1;
    con.weightx = 0.1;
    anchor = con.anchor;
    con.anchor = GridBagConstraints.EAST;
    gui.addCheckbox(ggHasImOutput, GG_HASIMOUTPUT, il);
    con.anchor = anchor;
    con.gridwidth = GridBagConstraints.REMAINDER;
    con.weightx = 0.9;
    gui.addPathField(ggImOutputFile, GG_IMOUTPUTFILE, pathL);

    ggParent2 = new PathField[1];
    ggParent2[0] = ggReOutputFile;
    ggReOutputFile.deriveFrom(ggParent1, "$D0$F0Op$E");
    ggImOutputFile.deriveFrom(ggParent2, "$D0$F0i$X0");

    ggGain = createGadgets(GGTYPE_GAIN);
    con.weightx = 0.1;
    con.gridwidth = 1;
    gui.addLabel(new JLabel("Gain", SwingConstants.RIGHT));
    con.weightx = 0.4;
    gui.addParamField((ParamField) ggGain[0], GG_GAIN, null);
    con.weightx = 0.5;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addChoice((JComboBox) ggGain[1], GG_GAINTYPE, il);

    // -------- Settings --------
    gui.addLabel(new GroupLabel("Operation", GroupLabel.ORIENT_HORIZONTAL, GroupLabel.BRACE_NONE));

    ggOperator = new JComboBox();
    for (int i = 0; i < OPNAMES.length; i++) {
      ggOperator.addItem(OPNAMES[i]);
    }
    con.gridwidth = 1;
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Operator", SwingConstants.RIGHT));
    con.weightx = 0.4;
    gui.addChoice(ggOperator, GG_OPERATOR, il);

    //		con.weightx		= 0.1;
    //		gui.addLabel( new JLabel( "" ));
    ggDryMix = new ParamField(Constants.spaces[Constants.ratioAmpSpace]);
    gui.addLabel(new JLabel("Dry mix", SwingConstants.RIGHT));
    con.weightx = 0.4;
    con.gridwidth = 2;
    gui.addParamField(ggDryMix, GG_DRYMIX, null);

    ggDryInvert = new JCheckBox("Invert");
    con.weightx = 0.1;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addCheckbox(ggDryInvert, GG_DRYINVERT, il);

    //		con.gridwidth	= 3;
    con.gridwidth = 2;
    gui.addLabel(new JLabel(""));
    ggWetMix = new ParamField(Constants.spaces[Constants.ratioAmpSpace]);
    con.weightx = 0.1;
    con.gridwidth = 1;
    gui.addLabel(new JLabel("Wet mix", SwingConstants.RIGHT));
    con.weightx = 0.4;
    con.gridwidth = 2;
    gui.addParamField(ggWetMix, GG_WETMIX, null);
    con.weightx = 0.1;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addLabel(new JLabel(""));

    initGUI(this, FLAGS_PRESETS | FLAGS_PROGBAR, gui);
  }
예제 #7
0
  protected void process() {
    long progOff;
    final long progLen;

    AudioFile inF = null;
    final AudioFileDescr inDescr;
    final int inChanNum;
    final long inLength;

    //		final Param				ampRef			= new Param( 1.0, Param.ABS_AMP );			// transform-Referenz

    final PathField ggOutput;

    int chunkLen;

    final ConstQ constQ;
    final float boost = 1f; // 1000f;

    final double minFreq = pr.para[PR_MINFREQ].value;
    final double maxFreq = pr.para[PR_MAXFREQ].value;
    final double timeRes = pr.para[PR_TIMERES].value;
    final int bandsPerOct = (int) pr.para[PR_BANDSPEROCT].value;
    final int maxFFTSize = 256 << pr.intg[PR_MAXFFTSIZE];
    final boolean color = false;

    final int bitsPerSmp;
    ImageFile outF = null;
    final ImageStream imgStream;
    final byte[] row;
    final int overlapSize;

    final int width, height;
    final int inBufSize;
    final float[][] inBuf;
    final int fftSize;
    final int stepSize;
    final int numKernels;
    final float[] kernel;
    //		final float[]			hsb	= new float[ 3 ];
    final double signalCeil =
        pr.para[PR_SIGNALCEIL]
            .value; // (Param.transform( pr.para[ PR_SIGNALCEIL ], Param.ABS_AMP, ampRef, null
    // )).value;
    final double noiseFloor =
        pr.para[PR_NOISEFLOOR]
            .value; // (Param.transform( pr.para[ PR_NOISEFLOOR ], Param.ABS_AMP, ampRef, null
    // )).value;
    final double dynamic = signalCeil - noiseFloor;
    int rgb;
    int winSize, inOff;
    long framesRead;
    //		float					brightness;

    topLevel:
    try {

      // ---- open input, output; init ----
      // ptrn input
      inF = AudioFile.openAsRead(new File(pr.text[PR_INPUTFILE]));
      inDescr = inF.getDescr();
      inChanNum = inDescr.channels;
      inLength = inDescr.length;
      // this helps to prevent errors from empty files!
      if ((inLength < 1) || (inChanNum < 1)) throw new EOFException(ERR_EMPTY);
      if (inChanNum != 1) throw new EOFException(ERR_MONO);
      // .... check running ....
      if (!threadRunning) break topLevel;

      //			if( inChanNum > 1 ) {
      //				System.out.println( "WARNING: Multichannel input. Using mono mix for mosaic
      // correlation!" );
      //			}

      // ---- further inits ----

      constQ = new ConstQ();
      constQ.setSampleRate(inDescr.rate);
      constQ.setMinFreq((float) minFreq);
      constQ.setMaxFreq((float) maxFreq);
      constQ.setBandsPerOct(bandsPerOct);
      constQ.setMaxFFTSize(maxFFTSize);
      constQ.setMaxTimeRes((float) timeRes);
      constQ.createKernels();
      fftSize = constQ.getFFTSize();
      numKernels = constQ.getNumKernels();

      winSize = fftSize; // << 1;
      stepSize = (int) (AudioFileDescr.millisToSamples(inDescr, timeRes) + 0.5);
      overlapSize = fftSize - stepSize;
      height = (int) ((inLength + stepSize - 1) / stepSize);
      width = numKernels;

      // System.out.println( "w " + width + "; h " + height + "; winSize " + winSize + "; inLength "
      // + inLength );

      ggOutput = (PathField) gui.getItemObj(GG_OUTPUTFILE);
      if (ggOutput == null) throw new IOException(ERR_MISSINGPROP);
      outF = new ImageFile(pr.text[PR_OUTPUTFILE], GenericFile.MODE_OUTPUT | ggOutput.getType());
      imgStream = new ImageStream();
      imgStream.bitsPerSmp = 8; // ??? fillStream might not work correctly?
      ggOutput.fillStream(imgStream);
      imgStream.width = width;
      imgStream.height = height;
      imgStream.smpPerPixel = /* color ? 3 :*/ 1;
      bitsPerSmp = imgStream.bitsPerSmp;
      outF.initWriter(imgStream);
      row = outF.allocRow();

      inBufSize = Math.max(8192, fftSize);
      inBuf = new float[inChanNum][inBufSize];
      kernel = new float[numKernels];

      progLen = height;
      progOff = 0;

      // ----==================== processing loop ====================----

      framesRead = 0;
      inOff = 0;

      // final java.util.Random rnd = new java.util.Random();

      for (int y = 0; y < height; y++) {
        if (inOff < 0) {
          inF.seekFrame(Math.min(inF.getFrameNum(), inF.getFramePosition() - inOff));
          inOff = 0;
        }
        // read
        chunkLen = (int) Math.min(inLength - framesRead, winSize - inOff);

        // System.out.println( "readFrames " + inOff + " -> " + chunkLen );

        inF.readFrames(inBuf, inOff, chunkLen);
        if ((inOff + chunkLen) < winSize) {
          Util.clear(inBuf, inOff + chunkLen, winSize - (inOff + chunkLen));
        }

        // transform
        constQ.transform(inBuf[0], 0, winSize, kernel, 0);
        for (int x = 0; x < width; x++) {
          kernel[x] =
              (float)
                  ((Math.min(
                              signalCeil,
                              (Math.max(noiseFloor, MathUtil.linearToDB(kernel[x] * boost))))
                          - noiseFloor)
                      / dynamic);
          //					kernel[ x ] = rnd.nextFloat();
        }

        if (color) {
          throw new IllegalStateException("Color not yet implemented");
          //					if( bitsPerSmp == 8 ) {
          //						for( int x = 0; x < width; x++ ) {
          //
          //						}
          //					} else {
          //						for( int x = 0; x < width; x++ ) {
          //
          //						}
          //					}
        } else {
          if (bitsPerSmp == 8) {
            for (int x = 0; x < width; x++) {
              row[x] = (byte) (kernel[x] * 0xFF + 0.5f);
            }
          } else {
            for (int x = 0, cnt = 0; x < width; x++) {
              rgb = (int) (kernel[x] * 0xFFFF + 0.5f);
              row[cnt++] = (byte) (rgb >> 8);
              row[cnt++] = (byte) rgb;
            }
          }
        }

        outF.writeRow(row);

        // handle overlap
        // System.out.println( "inBuf : " + inBuf[0].length + "; stepSize = " + stepSize + ";
        // overlap = " + overlapSize );
        if (overlapSize > 0) Util.copy(inBuf, stepSize, inBuf, 0, overlapSize);
        inOff = overlapSize;

        framesRead += chunkLen;

        progOff++;
        setProgression((float) progOff / (float) progLen);
        // .... check running ....
        if (!threadRunning) break topLevel;
      } // for x

      inF.close();
      inF = null;
      outF.close();
      outF = null;
    } catch (IOException e1) {
      setError(e1);
    } catch (OutOfMemoryError e2) {
      setError(new Exception(ERR_MEMORY));
    }

    // ---- cleanup (topLevel) ----
    if (outF != null) outF.cleanUp();
    if (inF != null) inF.cleanUp();
  } // process()
예제 #8
0
  protected void buildGUI() {
    // einmalig PropertyArray initialisieren
    if (static_pr == null) {
      static_pr = new PropertyArray();
      static_pr.text = prText;
      static_pr.textName = prTextName;
      static_pr.intg = prIntg;
      static_pr.intgName = prIntgName;
      //			static_pr.bool		= prBool;
      //			static_pr.boolName	= prBoolName;
      static_pr.para = prPara;
      static_pr.para[PR_MINFREQ] = new Param(32.0, Param.ABS_HZ);
      static_pr.para[PR_MAXFREQ] = new Param(18000.0, Param.ABS_HZ);
      static_pr.para[PR_BANDSPEROCT] = new Param(12.0, Param.NONE);
      static_pr.para[PR_TIMERES] = new Param(20.0, Param.ABS_MS);
      static_pr.para[PR_SIGNALCEIL] = new Param(0.0, Param.DECIBEL_AMP);
      static_pr.para[PR_NOISEFLOOR] = new Param(-96.0, Param.DECIBEL_AMP);
      static_pr.paraName = prParaName;
      //			static_pr.superPr	= DocumentFrame.static_pr;
    }
    // default preset
    if (static_presets == null) {
      static_presets = new Presets(getClass(), static_pr.toProperties(true));
    }
    presets = static_presets;
    pr = (PropertyArray) static_pr.clone();

    // -------- build GUI --------

    final GridBagConstraints con;
    final PathField ggInputFile, ggOutputFile;
    final PathField[] ggInputs;
    final ParamField ggMinFreq, ggMaxFreq, ggBandsPerOct, ggTimeRes;
    final ParamField ggSignalCeil, ggNoiseFloor;
    final JComboBox ggMaxFFTSize;

    gui = new GUISupport();
    con = gui.getGridBagConstraints();
    con.insets = new Insets(1, 2, 1, 2);

    //		final ItemListener il = new ItemListener() {
    //			public void itemStateChanged( ItemEvent e )
    //			{
    //				int	ID = gui.getItemID( e );
    //
    //				switch( ID ) {
    //				case GG_READMARKERS:
    //					pr.bool[ ID - GG_OFF_CHECKBOX ] = ((JCheckBox) e.getSource()).isSelected();
    //					reflectPropertyChanges();
    //					break;
    //				}
    //			}
    //		};

    // -------- Input-Gadgets --------
    con.fill = GridBagConstraints.BOTH;
    con.gridwidth = GridBagConstraints.REMAINDER;

    gui.addLabel(
        new GroupLabel("Waveform I/O", GroupLabel.ORIENT_HORIZONTAL, GroupLabel.BRACE_NONE));

    ggInputFile =
        new PathField(
            PathField.TYPE_INPUTFILE + PathField.TYPE_FORMATFIELD, "Select input sound file");
    ggInputFile.handleTypes(GenericFile.TYPES_SOUND);
    con.gridwidth = 1;
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Audio input", SwingConstants.RIGHT));
    con.gridwidth = GridBagConstraints.REMAINDER;
    con.weightx = 0.9;
    gui.addPathField(ggInputFile, GG_INPUTFILE, null);

    ggOutputFile =
        new PathField(
            PathField.TYPE_OUTPUTFILE + PathField.TYPE_FORMATFIELD + PathField.TYPE_RESFIELD,
            "Select output image file");
    ggOutputFile.handleTypes(GenericFile.TYPES_IMAGE);
    ggInputs = new PathField[1];
    ggInputs[0] = ggInputFile;
    ggOutputFile.deriveFrom(ggInputs, "$D0$F0Sono$E");
    con.gridwidth = 1;
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Image output", SwingConstants.RIGHT));
    con.gridwidth = GridBagConstraints.REMAINDER;
    con.weightx = 0.9;
    gui.addPathField(ggOutputFile, GG_OUTPUTFILE, null);

    // -------- Plot Settings --------
    gui.addLabel(new GroupLabel("Settings", GroupLabel.ORIENT_HORIZONTAL, GroupLabel.BRACE_NONE));

    ggMinFreq = new ParamField(Constants.spaces[Constants.absHzSpace]);
    con.weightx = 0.1;
    con.gridwidth = 1;
    gui.addLabel(new JLabel("Lowest Frequency:", SwingConstants.RIGHT));
    con.weightx = 0.4;
    gui.addParamField(ggMinFreq, GG_MINFREQ, null);

    ggBandsPerOct = new ParamField(new ParamSpace(1, /* 96 */ 32768, 1, Param.NONE));
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Bands Per Octave:", SwingConstants.RIGHT));
    con.weightx = 0.4;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addParamField(ggBandsPerOct, GG_BANDSPEROCT, null);

    ggMaxFreq = new ParamField(Constants.spaces[Constants.absHzSpace]);
    con.weightx = 0.1;
    con.gridwidth = 1;
    gui.addLabel(new JLabel("Highest Frequency:", SwingConstants.RIGHT));
    con.weightx = 0.4;
    gui.addParamField(ggMaxFreq, GG_MAXFREQ, null);

    ggTimeRes = new ParamField(Constants.spaces[Constants.absMsSpace]);
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Max. Time Resolution:", SwingConstants.RIGHT));
    con.weightx = 0.4;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addParamField(ggTimeRes, GG_TIMERES, null);

    ggSignalCeil = new ParamField(Constants.spaces[Constants.decibelAmpSpace]);
    con.weightx = 0.1;
    con.gridwidth = 1;
    gui.addLabel(new JLabel("Signal Ceiling:", SwingConstants.RIGHT));
    con.weightx = 0.4;
    gui.addParamField(ggSignalCeil, GG_SIGNALCEIL, null);

    ggMaxFFTSize = new JComboBox();
    for (int i = 256; i <= 32768; i <<= 1) {
      ggMaxFFTSize.addItem(String.valueOf(i));
    }
    con.weightx = 0.1;
    gui.addLabel(new JLabel("Max. FFT Size:", SwingConstants.RIGHT));
    con.weightx = 0.4;
    con.gridwidth = GridBagConstraints.REMAINDER;
    gui.addChoice(ggMaxFFTSize, GG_MAXFFTSIZE, null);

    ggNoiseFloor = new ParamField(Constants.spaces[Constants.decibelAmpSpace]);
    con.weightx = 0.1;
    con.gridwidth = 1;
    gui.addLabel(new JLabel("Noise Floor:", SwingConstants.RIGHT));
    con.weightx = 0.4;
    //		con.gridwidth	= GridBagConstraints.REMAINDER;
    gui.addParamField(ggNoiseFloor, GG_NOISEFLOOR, null);

    initGUI(this, FLAGS_PRESETS | FLAGS_PROGBAR, gui);
  }