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()
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()
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); }
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); }
/** 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()
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); }
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()
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); }