/* * TransientExtrDlg.java * (FScape) * * Copyright (c) 2001-2016 Hanns Holger Rutz. All rights reserved. * * This software is published under the GNU General Public License v3+ * * * For further information, please contact Hanns Holger Rutz at * contact@sciss.de */ package de.sciss.fscape.gui; import de.sciss.fscape.io.FloatFile; import de.sciss.fscape.io.GenericFile; import de.sciss.fscape.prop.Presets; import de.sciss.fscape.prop.PropertyArray; import de.sciss.fscape.session.ModulePanel; import de.sciss.fscape.util.Constants; import de.sciss.fscape.util.Param; import de.sciss.fscape.util.ParamSpace; import de.sciss.fscape.util.Util; import de.sciss.io.AudioFile; import de.sciss.io.AudioFileDescr; import de.sciss.io.IOUtil; import javax.swing.*; import java.awt.*; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.EOFException; import java.io.File; import java.io.IOException; /** * Trying out to extract only the transient noise * from a sound using wavelet decomposition, never worked. */ public class TransientExtrDlg extends ModulePanel { // -------- private variables -------- // Properties (defaults) private static final int PR_INPUTFILE = 0; // pr.text private static final int PR_OUTPUTFILE = 1; private static final int PR_MODFILE = 2; private static final int PR_OUTPUTTYPE = 0; // pr.intg private static final int PR_OUTPUTRES = 1; private static final int PR_GAINTYPE = 2; private static final int PR_LPMODE = 3; private static final int PR_GAIN = 0; // pr.para private static final int PR_LPORDER1 = 1; private static final int PR_LPORDER2 = 2; private static final int PR_CMORDER = 3; private static final int PR_LPADAPT1 = 4; private static final int PR_LPADAPT2 = 5; private static final int PR_CMADAPT = 6; private static final int PR_CROSSSYNTH = 0; // pr.bool private static final int PR_CONSTANTMODULUS = 1; private static final String PRN_INPUTFILE = "InputFile"; private static final String PRN_OUTPUTFILE = "OutputFile"; private static final String PRN_MODFILE = "ModFile"; private static final String PRN_OUTPUTTYPE = "OutputType"; private static final String PRN_OUTPUTRES = "OutputReso"; private static final String PRN_LPMODE = "LPMode"; private static final String PRN_LPORDER1 = "LPOrder1"; private static final String PRN_LPORDER2 = "LPOrder2"; private static final String PRN_CMORDER = "CMOrder"; private static final String PRN_LPADAPT1 = "LPAdapt1"; private static final String PRN_LPADAPT2 = "LPAdapt2"; private static final String PRN_CMADAPT = "CMAdapt"; private static final String PRN_CROSSSYNTH = "CrossSynth"; private static final String PRN_CONSTANTMODULUS = "ConstMod"; private static final int LPMODE_BYPASS = 0; // PR_LPMODE private static final int LPMODE_FILTER = 1; private static final int LPMODE_RESIDUAL = 2; private static final String[] LPMODE_NAMES = { "Bypass", "Filter", "Residual" }; private static final String prText[] = { "", "", "" }; private static final String prTextName[] = { PRN_INPUTFILE, PRN_OUTPUTFILE, PRN_MODFILE }; private static final int prIntg[] = { 0, 0, GAIN_UNITY, LPMODE_RESIDUAL }; private static final String prIntgName[] = { PRN_OUTPUTTYPE, PRN_OUTPUTRES, PRN_GAINTYPE, PRN_LPMODE }; private static final boolean prBool[] = { true, false }; private static final String prBoolName[] = { PRN_CROSSSYNTH, PRN_CONSTANTMODULUS }; private static final Param prPara[] = { null, null, null, null, null, null, null }; private static final String prParaName[] = { PRN_GAIN, PRN_LPORDER1, PRN_LPORDER2, PRN_CMORDER, PRN_LPADAPT1, PRN_LPADAPT2, PRN_CMADAPT }; private static final int GG_INPUTFILE = GG_OFF_PATHFIELD + PR_INPUTFILE; private static final int GG_OUTPUTFILE = GG_OFF_PATHFIELD + PR_OUTPUTFILE; private static final int GG_MODFILE = GG_OFF_PATHFIELD + PR_MODFILE; private static final int GG_OUTPUTTYPE = GG_OFF_CHOICE + PR_OUTPUTTYPE; private static final int GG_OUTPUTRES = GG_OFF_CHOICE + PR_OUTPUTRES; private static final int GG_LPMODE = GG_OFF_CHOICE + PR_LPMODE; private static final int GG_LPORDER1 = GG_OFF_PARAMFIELD + PR_LPORDER1; private static final int GG_LPORDER2 = GG_OFF_PARAMFIELD + PR_LPORDER2; private static final int GG_CMORDER = GG_OFF_PARAMFIELD + PR_CMORDER; private static final int GG_LPADAPT1 = GG_OFF_PARAMFIELD + PR_LPADAPT1; private static final int GG_LPADAPT2 = GG_OFF_PARAMFIELD + PR_LPADAPT2; private static final int GG_CMADAPT = GG_OFF_PARAMFIELD + PR_CMADAPT; private static final int GG_GAINTYPE = GG_OFF_CHOICE + PR_GAINTYPE; private static final int GG_GAIN = GG_OFF_PARAMFIELD + PR_GAIN; private static final int GG_CROSSSYNTH = GG_OFF_CHECKBOX + PR_CROSSSYNTH; private static final int GG_CONSTANTMODULUS = GG_OFF_CHECKBOX + PR_CONSTANTMODULUS; private static PropertyArray static_pr = null; private static Presets static_presets = null; // -------- public methods -------- /** * !! setVisible() bleibt dem Aufrufer ueberlassen */ public TransientExtrDlg() { super( "Adaptive LP Filter" ); init2(); } 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_LPORDER1 ] = new Param( 18.0, Param.NONE ); static_pr.para[ PR_LPORDER2 ] = new Param( 12.0, Param.NONE ); static_pr.para[ PR_CMORDER ] = new Param( 24.0, Param.NONE ); static_pr.para[ PR_LPADAPT1 ] = new Param( 2.0, Param.FACTOR_AMP ); static_pr.para[ PR_LPADAPT2 ] = new Param( 0.5, Param.FACTOR_AMP ); static_pr.para[ PR_CMADAPT ] = new Param( 0.1, Param.FACTOR_AMP ); static_pr.paraName = prParaName; // 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 ggInputFile, ggOutputFile, ggModFile; JComboBox ggLPMode; JCheckBox ggCrossSynth, ggConstMod; ParamField ggLPOrder1, ggLPOrder2, ggCMOrder, ggLPAdapt1, ggLPAdapt2, ggCMAdapt; PathField[] ggInputs; Component[] ggGain; 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_LPMODE: pr.intg[ ID - GG_OFF_CHOICE ] = ((JComboBox) e.getSource()).getSelectedIndex(); reflectPropertyChanges(); break; case GG_CROSSSYNTH: case GG_CONSTANTMODULUS: 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 (excitation) input file" ); ggInputFile.handleTypes( GenericFile.TYPES_SOUND ); con.gridwidth = 1; con.weightx = 0.1; gui.addLabel( new JLabel( "(Excitation) input", SwingConstants.RIGHT )); con.gridwidth = GridBagConstraints.REMAINDER; con.weightx = 0.9; gui.addPathField( ggInputFile, GG_INPUTFILE, null ); ggModFile = new PathField( PathField.TYPE_INPUTFILE + PathField.TYPE_FORMATFIELD, "Select (filter) input file" ); ggModFile.handleTypes( GenericFile.TYPES_SOUND ); con.gridwidth = 1; con.weightx = 0.1; gui.addLabel( new JLabel( "Filter input", SwingConstants.RIGHT )); con.gridwidth = GridBagConstraints.REMAINDER; con.weightx = 0.9; gui.addPathField( ggModFile, GG_MODFILE, 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; // ggInputs[ 1 ] = ggModFile; ggOutputFile.deriveFrom( ggInputs, "$D0$F0LP$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 ); // -------- Settings -------- gui.addLabel( new GroupLabel( "Filter Settings", GroupLabel.ORIENT_HORIZONTAL, GroupLabel.BRACE_NONE )); ggLPMode = new JComboBox(); for( int i = 0; i < LPMODE_NAMES.length; i++ ) { ggLPMode.addItem( LPMODE_NAMES[ i ]); } con.weightx = 0.1; con.gridwidth = 1; gui.addLabel( new JLabel( "Source LP output", SwingConstants.RIGHT )); con.weightx = 0.4; gui.addChoice( ggLPMode, GG_LPMODE, il ); ggLPOrder1 = new ParamField( new ParamSpace( 1.0, 4096.0, 1.0, Param.NONE )); con.weightx = 0.1; gui.addLabel( new JLabel( "Source LP order", SwingConstants.RIGHT )); con.weightx = 0.4; gui.addParamField( ggLPOrder1, GG_LPORDER1, null ); ggLPAdapt1 = new ParamField( Constants.spaces[ Constants.ratioAmpSpace ]); con.weightx = 0.1; gui.addLabel( new JLabel( "Adaptiveness", SwingConstants.RIGHT )); con.weightx = 0.4; con.gridwidth = GridBagConstraints.REMAINDER; gui.addParamField( ggLPAdapt1, GG_LPADAPT1, null ); ggCrossSynth = new JCheckBox(); con.weightx = 0.1; con.gridwidth = 1; gui.addLabel( new JLabel( "Cross synthesis", SwingConstants.RIGHT )); con.weightx = 0.4; gui.addCheckbox( ggCrossSynth, GG_CROSSSYNTH, il ); ggLPOrder2 = new ParamField( new ParamSpace( 1.0, 4096.0, 1.0, Param.NONE )); con.weightx = 0.1; gui.addLabel( new JLabel( "Target LP order", SwingConstants.RIGHT )); con.weightx = 0.4; gui.addParamField( ggLPOrder2, GG_LPORDER2, null ); ggLPAdapt2 = new ParamField( Constants.spaces[ Constants.ratioAmpSpace ]); con.weightx = 0.1; gui.addLabel( new JLabel( "Adaptiveness", SwingConstants.RIGHT )); con.weightx = 0.4; con.gridwidth = GridBagConstraints.REMAINDER; gui.addParamField( ggLPAdapt2, GG_LPADAPT2, null ); ggConstMod = new JCheckBox(); con.weightx = 0.1; con.gridwidth = 1; gui.addLabel( new JLabel( "Constant Modulus Flt.", SwingConstants.RIGHT )); con.weightx = 0.4; gui.addCheckbox( ggConstMod, GG_CONSTANTMODULUS, il ); ggCMOrder = new ParamField( new ParamSpace( 1.0, 4096.0, 1.0, Param.NONE )); con.weightx = 0.1; gui.addLabel( new JLabel( "CM order", SwingConstants.RIGHT )); con.weightx = 0.4; gui.addParamField( ggCMOrder, GG_CMORDER, null ); ggCMAdapt = new ParamField( Constants.spaces[ Constants.ratioAmpSpace ]); con.weightx = 0.1; gui.addLabel( new JLabel( "Adaptiveness", SwingConstants.RIGHT )); con.weightx = 0.4; con.gridwidth = GridBagConstraints.REMAINDER; gui.addParamField( ggCMAdapt, GG_CMADAPT, null ); initGUI( this, FLAGS_PRESETS | FLAGS_PROGBAR, gui ); } public void fillGUI() { super.fillGUI(); super.fillGUI(gui); } public void fillPropertyArray() { super.fillPropertyArray(); super.fillPropertyArray(gui); } // -------- Processor Interface -------- protected void process() { int i, j, k, m, n, ch, chunkLength; long progOff, progLen; float f1; double d1, d2; // io AudioFile inF = null; AudioFile modF = null; AudioFile outF = null; AudioFileDescr inStream = null; AudioFileDescr modStream = null; AudioFileDescr outStream = null; FloatFile[] floatF = null; File[] tempFile = null; float[][] inBuf; float[][] outBuf; float[][] cmBuf = null; float[][] modBuf = null; float[][] lpBuf1 = null; float[][] lpBuf2 = null; float[] convBuf1, convBuf2, convBuf3, convBuf4; float[][] lpCoeffs1 = null; float[][] lpCoeffs2 = null; float[][] cmCoeffs = null; // Synthesize float gain = 1.0f; // gain abs amp Param ampRef = new Param( 1.0, Param.ABS_AMP ); // transform-Referenz boolean crossSynth = pr.bool[ PR_CROSSSYNTH ]; boolean constMod = pr.bool[ PR_CONSTANTMODULUS ]; boolean lpFilter = pr.intg[ PR_LPMODE ] != LPMODE_BYPASS; // Smp Init int inLength, inChanNum, modLength, modChanNum, outChanNum, outLength; int framesRead, framesRead2, framesWritten; int lpOrder1, lpOrder2, cmOrder, maxOrder; double lpAdapt1, lpAdapt2, cmAdapt, cmDispersion; float maxAmp = 0.0f; PathField ggOutput; topLevel: try { // System.out.println( "lp" + lpFilter+"; cross "+crossSynth+"; cm "+constMod ); // ---- 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 * inChanNum < 1 ) throw new EOFException( ERR_EMPTY ); // .... check running .... if( !threadRunning ) break topLevel; progOff = 0; progLen = 0; if( crossSynth ) { // input modF = AudioFile.openAsRead( new File( pr.text[ PR_MODFILE ])); modStream = modF.getDescr(); modChanNum = modStream.channels; modLength = (int) modStream.length; // this helps to prevent errors from empty files! if( modLength * modChanNum < 1 ) throw new EOFException( ERR_EMPTY ); // .... check running .... if( !threadRunning ) break topLevel; outLength = Math.min( inLength, modLength ); outChanNum = Math.max( inChanNum, modChanNum ); progLen += outLength; } else { modLength = inLength; modChanNum = inChanNum; outLength = inLength; outChanNum = inChanNum; } progLen += (long) outLength * 2; // 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; lpOrder1 = (int) (pr.para[ PR_LPORDER1 ].value + 0.5); lpOrder2 = (int) (pr.para[ PR_LPORDER2 ].value + 0.5); cmOrder = (int) (pr.para[ PR_CMORDER ].value + 0.5); lpAdapt1 = pr.para[ PR_LPADAPT1 ].value / 100; lpAdapt2 = pr.para[ PR_LPADAPT2 ].value / 100; cmAdapt = pr.para[ PR_CMADAPT ].value / 100; cmDispersion = 1.0; // user-adjustable? XXX maxOrder = Math.max( constMod ? cmOrder : 0, Math.max( crossSynth ? lpOrder2 : 0, lpFilter ? lpOrder1 : 0 )); inBuf = new float[ inChanNum ][ 8192 + maxOrder ]; Util.clear( inBuf ); outBuf = inBuf; // standard coeff init // the buffers are assigned to minimize arraycopying operations // (outBuf automatically points to the right array holding the ready samples for the output file) if( lpFilter ) { lpCoeffs1 = new float[ inChanNum ][ lpOrder1 ]; Util.clear( lpCoeffs1 ); for( ch = 0; ch < inChanNum; ch++ ) { lpCoeffs1[ ch ][ lpOrder1 >> 1 ] = 1.0f; } lpBuf1 = new float[ inChanNum ][ 8192 + maxOrder ]; Util.clear( lpBuf1 ); outBuf = lpBuf1; } else { lpBuf1 = inBuf; } if( crossSynth) { lpCoeffs2 = new float[ modChanNum ][ lpOrder2 ]; Util.clear( lpCoeffs2 ); for( ch = 0; ch < modChanNum; ch++ ) { lpCoeffs2[ ch ][ lpOrder2 >> 1 ] = 1.0f; } modBuf = new float[ modChanNum ][ 8192 + maxOrder ]; Util.clear( modBuf ); lpBuf2 = new float[ outChanNum ][ 8192 + maxOrder ]; Util.clear( lpBuf2 ); outBuf = lpBuf2; } if( constMod ) { cmCoeffs = new float[ outChanNum ][ cmOrder ]; Util.clear( cmCoeffs ); for( ch = 0; ch < outChanNum; ch++ ) { cmCoeffs[ ch ][ cmOrder >> 1 ] = 1.0f; } cmBuf = outBuf; outBuf = new float[ outChanNum ][ 8192 + maxOrder ]; Util.clear( outBuf ); } // 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 += outLength; } else { gain = (float) (Param.transform( pr.para[ PR_GAIN ], Param.ABS_AMP, ampRef, null )).value; } // .... check running .... if( !threadRunning ) break topLevel; // ----==================== the ultraworld ====================---- // based on formulae published in the article // "Blind Adapted, Pre-Whitened Constant Modulus Algorithm" by James P. LeBlanc and Inbar Fijalkow framesWritten = 0; framesRead = 0; // re inF framesRead2 = 0; // re modF // System.out.println( "outBuf == inBuf ? "+(outBuf == inBuf)); while( threadRunning && (framesWritten < outLength) ) { chunkLength = Math.min( 8192, Math.min( inLength - framesRead, modLength - framesRead2 )); // ==================== read input chunk ==================== inF.readFrames( inBuf, maxOrder, chunkLength ); framesRead += chunkLength; progOff += chunkLength; if( crossSynth ) { modF.readFrames( modBuf, maxOrder, chunkLength ); framesRead2 += chunkLength; progOff += chunkLength; } // .... progress .... setProgression( (float) progOff / (float) progLen ); // .... check running .... if( !threadRunning ) break topLevel; // ---- Source LP filter ---------------------------------------------------------------------- switch( pr.intg[ PR_LPMODE ]) { case LPMODE_FILTER: // d(n) = D'*X(n); D = [d0 d1 ... dN]'; X(n) = [x(n-1) x(n-2) ... x(n-N)]' // y(n) = d(n) (Mode=Filter) oder y(n) = x(n) - d(n) (Mode=Residual) // D(n+1) = D(n) - (?) *d(n)*X(n) for( ch = 0; ch < inChanNum; ch++ ) { convBuf1 = lpCoeffs1[ ch ]; convBuf2 = inBuf[ ch ]; convBuf3 = lpBuf1[ ch ]; for( i = 0, j = maxOrder; i < chunkLength; i++, j++ ) { d1 = 0.0; d2 = 0.0; for( k = 0, m = j; k < lpOrder1; ) { // calc d(n) f1 = convBuf2[ --m ]; d1 += convBuf1[ k++ ] * f1; d2 += f1*f1; } convBuf3[ j ] = (float) d1; // y(n) d1 = convBuf2[ j ] - d1; // error f1 = (float) (d1 * lpAdapt1); for( k = 0, m = j; k < lpOrder1; ) { // update D convBuf1[ k++ ] -= f1 * convBuf2[ --m ]; } } } // energy correction // adjustEnergy( lpCoeffs1 ); // buffer rotation for( ch = 0; ch < inChanNum; ch++ ) { System.arraycopy( inBuf[ ch ], chunkLength, inBuf[ ch ], 0, maxOrder ); } break; case LPMODE_RESIDUAL: // d(n) = D'*X(n); D = [d0 d1 ... dN]'; X(n) = [x(n-1) x(n-2) ... x(n-N)]' // y(n) = d(n) (Mode=Filter) oder y(n) = x(n) - d(n) (Mode=Residual) for( ch = 0; ch < inChanNum; ch++ ) { convBuf1 = lpCoeffs1[ ch ]; convBuf2 = inBuf[ ch ]; convBuf3 = lpBuf1[ ch ]; for( i = 0, j = maxOrder; i < chunkLength; i++, j++ ) { d1 = 0.0; for( k = 0, m = j; k < lpOrder1; ) { // calc d(n) d1 += convBuf1[ k++ ] * convBuf2[ --m ]; } d1 = convBuf2[ j ] - d1; // error convBuf3[ j ] = (float) d1; // y(n) f1 = (float) (d1 * lpAdapt1); for( k = 0, m = j; k < lpOrder1; ) { // update D convBuf1[ k++ ] -= f1 * convBuf2[ --m ]; } } } // buffer rotation for( ch = 0; ch < inChanNum; ch++ ) { System.arraycopy( inBuf[ ch ], chunkLength, inBuf[ ch ], 0, maxOrder ); } break; default: // LPMODE_BYPASS break; } // preliminary output now available in lpBuf1 (evtl. auch in outBuf) // ---- Target LP filter ---------------------------------------------------------------------- if( crossSynth ) { // d(n) = D'*Xmod(n); D = [d0 d1 ... dN]'; X(n) = [x(n-1) x(n-2) ... x(n-N)]' // y(n) = D'*Xin(n) if( inChanNum <= modChanNum ) { for( ch = 0; ch < modChanNum; ch++ ) { convBuf1 = lpCoeffs2[ ch ]; convBuf2 = modBuf[ ch ]; convBuf3 = lpBuf1[ ch % inChanNum ]; convBuf4 = lpBuf2[ ch ]; for( i = 0, j = maxOrder; i < chunkLength; i++, j++ ) { d1 = 0.0; d2 = 0.0; for( k = 0, m = j; k < lpOrder2; ) { // calc d(n) d1 += convBuf1[ k ] * convBuf2[ --m ]; d2 += convBuf1[ k++ ] * convBuf3[ m ]; // ...and y(n) } convBuf4[ j ] = (float) d2; // y(n) d1 = convBuf2[ j ] - d1; // error f1 = (float) (d1 * lpAdapt2); for( k = 0, m = j; k < lpOrder2; ) { // update D convBuf1[ k++ ] -= f1 * convBuf2[ --m ]; } } } } else { for( ch = 0; ch < modChanNum; ch++ ) { convBuf1 = lpCoeffs2[ ch ]; convBuf2 = modBuf[ ch ]; for( i = 0, j = maxOrder; i < chunkLength; i++, j++ ) { d1 = 0.0; for( k = 0, m = j; k < lpOrder2; ) { // calc d(n) d1 += convBuf1[ k ] * convBuf2[ --m ]; } for( n = ch; n < inChanNum; n += modChanNum ) { convBuf3 = lpBuf1[ n ]; convBuf4 = lpBuf2[ n ]; d2 = 0.0; for( k = 0, m = j; k < lpOrder2; ) { // calc d(n) d2 += convBuf1[ k++ ] * convBuf3[ m ]; // ...and y(n) } convBuf4[ j ] = (float) d2; // y(n) } d1 = convBuf2[ j ] - d1; // error f1 = (float) (d1 * lpAdapt2); for( k = 0, m = j; k < lpOrder2; ) { // update D convBuf1[ k++ ] -= f1 * convBuf2[ --m ]; } } } } // buffer rotation for( ch = 0; ch < modChanNum; ch++ ) { System.arraycopy( modBuf[ ch ], chunkLength, modBuf[ ch ], 0, maxOrder ); } for( ch = 0; ch < inChanNum; ch++ ) { System.arraycopy( lpBuf1[ ch ], chunkLength, lpBuf1[ ch ], 0, maxOrder ); } } // preliminary output now available in lpBuf2 (evtl. auch in outBuf) // ---- CM filter ---------------------------------------------------------------------- if( constMod ) { // y(n) = D'*X(n); D = [d0 d1 ... dN]'; X(n) = [x(n) x(n-1) ... x(n-N+1)]' // D(n+1) = D(n) - (?) *(y(n)*y(n) - mu)*y(n)*X(n) for( ch = 0; ch < outChanNum; ch++ ) { convBuf1 = cmCoeffs[ ch ]; convBuf2 = cmBuf[ ch ]; convBuf3 = outBuf[ ch ]; for( i = 0, j = maxOrder; i < chunkLength; i++, j++ ) { d1 = 0.0; for( k = 0, m = j; k < cmOrder; ) { // calc d(n) d1 += convBuf1[ k++ ] * convBuf2[ m-- ]; } convBuf3[ j ] = (float) d1; // y(n) f1 = (float) (cmAdapt * (d1*d1 - cmDispersion) * d1); for( k = 0, m = j; k < cmOrder; ) { // update D convBuf1[ k++ ] -= f1 * convBuf2[ m-- ]; } } } // buffer rotation for( ch = 0; ch < outChanNum; ch++ ) { System.arraycopy( cmBuf[ ch ], chunkLength, cmBuf[ ch ], 0, maxOrder ); } } // output now available outBuf // ---- Measure gain ---------------------------------------------------------------------- for( ch = 0; ch < outChanNum; ch++ ) { convBuf1 = outBuf[ ch ]; for( i = 0; i < chunkLength; i++ ) { f1 = Math.abs( convBuf1[ i ]); if( f1 > maxAmp ) { maxAmp = f1; } } } // ---- write output or temp ---- if( floatF != null ) { for( ch = 0; ch < outChanNum; ch++ ) { floatF[ ch ].writeFloats( outBuf[ ch ], maxOrder, chunkLength ); } } else { // adjust gain for( ch = 0; ch < outChanNum; ch++ ) { Util.mult( outBuf[ ch ], maxOrder, chunkLength, gain ); } outF.writeFrames( outBuf, maxOrder, chunkLength ); } framesWritten += chunkLength; // .... progress .... progOff += chunkLength; setProgression( (float) progOff / (float) progLen ); } // while not framesWritten // .... check running .... if( !threadRunning ) break topLevel; // ---- clean up, normalize ---- inF.close(); inF = null; inStream = null; if( modF != null ) { modF.close(); modF = null; modStream=null; } if( pr.intg[ PR_GAINTYPE ] == GAIN_UNITY ) { gain = (float) (Param.transform( pr.para[ PR_GAIN ], Param.ABS_AMP, new Param( 1.0 / maxAmp, Param.ABS_AMP ), null )).value; normalizeAudioFile( floatF, outF, outBuf, gain, 1.0f ); for( ch = 0; ch < inChanNum; ch++ ) { floatF[ ch ].cleanUp(); floatF[ ch ] = null; tempFile[ ch ].delete(); tempFile[ ch ] = null; } } outF.close(); outF = null; // ---- Finish ---- // inform about clipping/ low level maxAmp *= gain; handleClipping( maxAmp ); } catch( IOException e1 ) { setError( e1 ); } catch( OutOfMemoryError e2 ) { inStream = null; outStream = null; modStream = null; inBuf = null; outBuf = null; modBuf = null; lpBuf1 = null; lpBuf2 = null; cmBuf = null; convBuf1 = null; convBuf2 = null; convBuf3 = null; convBuf4 = null; System.gc(); setError( new Exception( ERR_MEMORY )); } // ---- cleanup (topLevel) ---- if( inF != null ) { inF.cleanUp(); } if( outF != null ) { outF.cleanUp(); } if( floatF != null ) { for( ch = 0; ch < floatF.length; ch++ ) { if( floatF[ ch ] != null ) floatF[ ch ].cleanUp(); if( tempFile[ ch ] != null ) tempFile[ ch ].delete(); } } } // process() // -------- private methods -------- protected void adjustEnergy( float[][] coeffs ) { int chanNum = coeffs.length; int numCoeffs = coeffs[0].length; float[] convBuf1; int ch, i; float f1; for( ch = 0; ch < chanNum; ch++ ) { convBuf1 = coeffs[ ch ]; for( i = 0; i < numCoeffs; i++ ) { f1 = Math.abs( convBuf1[ i ]); if( f1 > 1.0f ) { convBuf1[ i ] /= f1; } } } // for( i = 0, d1 = 0.0; i < numCoeffs; i++ ) { // d1 += convBuf1[ i ]*convBuf1[ i ]; // } // if( d1 > 0.0 ) { // Util.mult( convBuf1, 0, numCoeffs, (float) (1.0 / Math.sqrt( d1 ))); // } // } } protected void reflectPropertyChanges() { super.reflectPropertyChanges(); Component c; c = gui.getItemObj( GG_MODFILE ); if( c != null ) { c.setEnabled( pr.bool[ PR_CROSSSYNTH ]); } c = gui.getItemObj( GG_LPORDER1 ); if( c != null ) { c.setEnabled( pr.intg[ PR_LPMODE ] != LPMODE_BYPASS ); } c = gui.getItemObj( GG_LPADAPT1 ); if( c != null ) { c.setEnabled( pr.intg[ PR_LPMODE ] != LPMODE_BYPASS ); } c = gui.getItemObj( GG_LPORDER2 ); if( c != null ) { c.setEnabled( pr.bool[ PR_CROSSSYNTH ]); } c = gui.getItemObj( GG_LPADAPT2 ); if( c != null ) { c.setEnabled( pr.bool[ PR_CROSSSYNTH ]); } c = gui.getItemObj( GG_CMORDER ); if( c != null ) { c.setEnabled( pr.bool[ PR_CONSTANTMODULUS ]); } c = gui.getItemObj( GG_CMADAPT ); if( c != null ) { c.setEnabled( pr.bool[ PR_CONSTANTMODULUS ]); } } }