/*
* CollageDlg.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.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 javax.swing.*;
import java.awt.*;
/**
* Processing module for mixing sounds together.
*/
public class CollageDlg
extends ModulePanel {
// -------- private variables --------
// Properties (defaults)
private static final int PR_OUTPUTFILE = 0; // pr.text
// private static final int PR_BOARD = 1;
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_OUTPUTCHAN = 0; // pr.para
private static final int PR_GAIN = 1;
private static final String PRN_OUTPUTFILE = "OutputFile";
private static final String PRN_BOARD = "Board";
private static final String PRN_OUTPUTTYPE = "OutputType";
private static final String PRN_OUTPUTRES = "OutputRes";
private static final String PRN_OUTPUTCHAN = "OutputChan";
private static final String prText[] = { "", "" };
private static final String prTextName[] = { PRN_OUTPUTFILE, PRN_BOARD };
private static final int prIntg[] = { 0, 0, GAIN_UNITY };
private static final String prIntgName[] = { PRN_OUTPUTTYPE, PRN_OUTPUTRES, PRN_GAINTYPE };
private static final Param prPara[] = { null, null };
private static final String prParaName[] = { PRN_OUTPUTCHAN, PRN_GAIN };
private static final int GG_OUTPUTFILE = GG_OFF_PATHFIELD + PR_OUTPUTFILE;
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_GAINTYPE = GG_OFF_CHOICE + PR_GAINTYPE;
private static final int GG_OUTPUTCHAN = GG_OFF_PARAMFIELD + PR_OUTPUTCHAN;
private static final int GG_GAIN = GG_OFF_PARAMFIELD + PR_GAIN;
private static final int GG_BOARD = GG_OFF_OTHER + 0;
private static final int GG_INPUTFILE = GG_OFF_OTHER + 1;
private static final int GG_INGAIN = GG_OFF_OTHER + 2;
private static final int GG_INVERT = GG_OFF_OTHER + 4;
private static final int GG_SUMCHAN = GG_OFF_OTHER + 5;
private static final int GG_PAN = GG_OFF_OTHER + 6;
private static final int GG_FADEIN = GG_OFF_OTHER + 7;
private static final int GG_FADEINTYPE = GG_OFF_OTHER + 8;
private static final int GG_FADEINLEN = GG_OFF_OTHER + 9;
private static final int GG_FADEOUT = GG_OFF_OTHER + 10;
private static final int GG_FADEOUTTYPE = GG_OFF_OTHER + 11;
private static final int GG_FADEOUTLEN = GG_OFF_OTHER + 12;
private static final int GG_STARTTIME = GG_OFF_OTHER + 13;
private static final int GG_INFILEOFFSET = GG_OFF_OTHER + 14;
private static final int GG_LENGTH = GG_OFF_OTHER + 15;
private static final int GG_ENDTIME = GG_OFF_OTHER + 16;
// private static final int GG_ACTIONADD = GG_OFF_OTHER + 17;
// private static final int GG_ACTIONDEL = GG_OFF_OTHER + 18;
// private static final int GG_ACTIONDUP = GG_OFF_OTHER + 19;
private static PropertyArray static_pr = null;
private static Presets static_presets = null;
// -------- public methods --------
public CollageDlg() {
super("Collage");
init2();
}
protected void buildGUI() {
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_OUTPUTCHAN ] = new Param( 2.0, Param.NONE );
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 ggOutputFile, ggInputFile;
JComboBox ggFadeType;
ParamField ggOutChan, ggInGain, ggPan, ggFadeLen, ggStartTime, ggOffset, ggLength, ggEndTime;
JCheckBox ggInvert, ggMono, ggFade;
CollageList ggBoard;
Component[] ggGain;
ParamSpace[] spcOffset, spcLength;
gui = new GUISupport();
con = gui.getGridBagConstraints();
con.insets = new Insets( 1, 2, 1, 2 );
// -------- I/O-Gadgets --------
con.fill = GridBagConstraints.BOTH;
con.gridwidth = GridBagConstraints.REMAINDER;
gui.addLabel( new GroupLabel( "Waveform Output", GroupLabel.ORIENT_HORIZONTAL,
GroupLabel.BRACE_NONE ));
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.05;
gui.addLabel( new JLabel( "File name", SwingConstants.RIGHT ));
con.gridheight = 2;
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 );
// gui.registerGadget( ggOutputFile.getRateGadget(), GG_OUTPUTRATE );
ggGain = createGadgets( GGTYPE_GAIN );
con.weightx = 0.05;
con.gridwidth = 1;
gui.addLabel( new JLabel( "Gain", SwingConstants.RIGHT ));
con.weightx = 0.2;
gui.addParamField( (ParamField) ggGain[ 0 ], GG_GAIN, null );
con.weightx = 0.2;
gui.addChoice( (JComboBox) ggGain[ 1 ], GG_GAINTYPE, null );
ggOutChan = new ParamField( new ParamSpace( 1.0, 10000.0, 1.0, Param.NONE ));
con.weightx = 0.05;
gui.addLabel( new JLabel( "# of channels", SwingConstants.RIGHT ));
con.weightx = 0.4;
con.gridwidth = GridBagConstraints.REMAINDER;
gui.addParamField( ggOutChan, GG_OUTPUTCHAN, null );
// -------- Collage Board --------
con.fill = GridBagConstraints.BOTH;
gui.addLabel( new GroupLabel( "Collage Board", GroupLabel.ORIENT_HORIZONTAL,
GroupLabel.BRACE_NONE ));
ggBoard = new CollageList();
con.weightx = 0.9;
con.weighty = 0.9;
con.gridwidth = GridBagConstraints.REMAINDER;
// con.gridwidth = 4;
con.gridheight = 4;
// gui.addGadget( ggCircuit, GG_CIRCUIT );
gui.addGadget( ggBoard, GG_BOARD );
// ggBoard.addActionListener( this );
spcOffset = new ParamSpace[ 3 ];
spcOffset[0] = Constants.spaces[ Constants.offsetMsSpace ];
spcOffset[1] = Constants.spaces[ Constants.offsetBeatsSpace ];
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.weightx = 0.05;
con.weighty = 0.0;
con.gridheight = 1;
con.gridwidth = GridBagConstraints.REMAINDER;
con.fill = GridBagConstraints.HORIZONTAL;
// ggAction = new JButton( "Add" );
// gui.addButton( ggAction, GG_ACTIONADD, this );
// ggAction = new JButton( "Delete" );
// gui.addButton( ggAction, GG_ACTIONDEL, this );
// ggAction = new JButton( "Duplicate" );
// gui.addButton( ggAction, GG_ACTIONDUP, this );
// gui.addLabel( new JLabel() );
ggInputFile = new PathField( PathField.TYPE_INPUTFILE + PathField.TYPE_FORMATFIELD,
"Select input sound" );
ggInputFile.handleTypes( GenericFile.TYPES_SOUND );
con.gridwidth = 1;
con.weightx = 0.05;
gui.addLabel( new JLabel( "Input file", SwingConstants.RIGHT ));
con.gridwidth = GridBagConstraints.REMAINDER;
con.weightx = 0.9;
gui.addPathField( ggInputFile, GG_INPUTFILE, null );
ggInGain = new ParamField( Constants.spaces[ Constants.decibelAmpSpace ]);
con.gridwidth = 1;
con.weightx = 0.05;
gui.addLabel( new JLabel( "Gain", SwingConstants.RIGHT ));
con.weightx = 0.4;
gui.addParamField( ggInGain, GG_INGAIN, null );
ggInvert = new JCheckBox( "Invert" );
con.weightx = 0.05;
gui.addCheckbox( ggInvert, GG_INVERT, null );
ggOffset = new ParamField( spcOffset );
con.weightx = 0.05;
gui.addLabel( new JLabel( "Cut offset", SwingConstants.RIGHT ));
con.weightx = 0.3;
con.gridwidth = GridBagConstraints.REMAINDER;
gui.addParamField( ggOffset, GG_INFILEOFFSET, null );
ggPan = new ParamField( Constants.spaces[ Constants.decibelAmpSpace ]);
con.gridwidth = 1;
con.weightx = 0.05;
gui.addLabel( new JLabel( "Pan", SwingConstants.RIGHT ));
con.weightx = 0.4;
gui.addParamField( ggPan, GG_PAN, null );
ggMono = new JCheckBox( "Make mono" );
con.weightx = 0.05;
gui.addCheckbox( ggMono, GG_SUMCHAN, null );
ggLength = new ParamField( spcLength );
con.weightx = 0.05;
gui.addLabel( new JLabel( "Cut length", SwingConstants.RIGHT ));
con.weightx = 0.4;
con.gridwidth = GridBagConstraints.REMAINDER;
gui.addParamField( ggLength, GG_LENGTH, null );
ggFade = new JCheckBox( "Fade in" );
con.weightx = 0.05;
con.gridwidth = 1;
gui.addCheckbox( ggFade, GG_FADEIN, null );
ggFadeLen = new ParamField( spcLength );
con.weightx = 0.4;
gui.addParamField( ggFadeLen, GG_FADEINLEN, null );
ggFadeType = new JComboBox();
ggFadeType.addItem( "Linear" );
ggFadeType.addItem( "Slow rise" );
ggFadeType.addItem( "Fast rise" );
ggFadeType.addItem( "Easy in+out" );
con.weightx = 0.2;
gui.addChoice( ggFadeType, GG_FADEINTYPE, null );
ggStartTime = new ParamField( spcOffset );
con.weightx = 0.05;
gui.addLabel( new JLabel( "Start time", SwingConstants.RIGHT ));
con.weightx = 0.4;
con.gridwidth = GridBagConstraints.REMAINDER;
gui.addParamField( ggStartTime, GG_STARTTIME, null );
ggFade = new JCheckBox( "Fade out" );
con.weightx = 0.05;
con.gridwidth = 1;
gui.addCheckbox( ggFade, GG_FADEOUT, null );
ggFadeLen = new ParamField( spcLength );
con.weightx = 0.4;
gui.addParamField( ggFadeLen, GG_FADEOUTLEN, null );
ggFadeType = new JComboBox();
ggFadeType.addItem( "Linear" );
ggFadeType.addItem( "Slow fall" );
ggFadeType.addItem( "Fast fall" );
ggFadeType.addItem( "Easy in+out" );
con.weightx = 0.2;
gui.addChoice( ggFadeType, GG_FADEOUTTYPE, null );
ggEndTime = new ParamField( spcOffset );
con.weightx = 0.05;
gui.addLabel( new JLabel( "End time", SwingConstants.RIGHT ));
con.weightx = 0.4;
con.gridwidth = GridBagConstraints.REMAINDER;
gui.addParamField( ggEndTime, GG_ENDTIME, null );
initGUI( this, FLAGS_PRESETS | FLAGS_PROGBAR, gui );
}
/**
* Transfer values from prop-array to GUI
*/
public void fillGUI()
{
super.fillGUI();
super.fillGUI( gui );
// CircuitPanel cp = (CircuitPanel) gui.getItemObj( GG_CIRCUIT );
// if( cp != null ) {
// cp.setCircuit( pr.text[ PR_CIRCUIT ]);
// }
}
/**
* Transfer values from GUI to prop-array
*/
public void fillPropertyArray()
{
super.fillPropertyArray();
super.fillPropertyArray( gui );
// CircuitPanel cp = (CircuitPanel) gui.getItemObj( GG_CIRCUIT );
// if( cp != null ) {
// pr.text[ PR_CIRCUIT ] = cp.getCircuit();
// }
}
// -------- Processor Interface --------
protected void process()
{
/* int i, j, k, ch;
long progOff, progLen;
float maxAmp = 0.0f;
AudioFile outF = null;
PathField ggOutput;
AudioFileDescr outStream;
int outChanNum = 1; // fix
int outLength;
int fftLength;
int off;
int framesWritten;
float outBuf[], outBufWrap[][];
float impBuf[][];
CircuitPanel cp;
Point impLength;
float floaty;
Param ampRef = new Param( 1.0, Param.ABS_AMP ); // transform-Referenz
Param peakGain; // (abs amp)
float gain = 1.0f; // gain abs amp
topLevel: try {
// ---- open files ----
ggOutput = (PathField) gui.getItemObj( GG_OUTPUTFILE );
if( ggOutput == null ) throw new IOException( ERR_MISSINGPROP );
outF = new AudioFile( pr.text[ PR_OUTPUTFILE ], AudioFile.MODE_OUTPUT | ggOutput.getType() );
outStream = new AudioFileDescr();
ggOutput.fillStream( outStream );
outStream.chanNum = outChanNum;
// .... check running ....
if( !threadRunning ) break topLevel;
// ---- preparations ----
cp = (CircuitPanel) gui.getItemObj( GG_CIRCUIT );
if( cp == null ) throw new IOException( ERR_MISSINGPROP );
impLength = calcLength( cp, outStream );
outLength = impLength.x + impLength.y;
outStream.samples= outLength;
if( (outLength*outChanNum) <= 0 ) throw new IOException( ERR_EMPTY );
for( fftLength = 2; fftLength < outLength; fftLength <<= 1 ) ;
// add "support"
outStream.markers.addElement( new Marker( impLength.x, MARK_SUPPORT ));
outF.initWriter( outStream );
// System.out.println( "impLength === "+impLength.x+" ... "+impLength.y+" fft "+fftLength );
progOff = 0;
progLen = outLength + (outLength & ~1);
// ---- da Collage ----
outBuf = new float[ fftLength + 2 ];
outBufWrap = new float[ outChanNum ][];
for( ch = 0; ch < outChanNum; ch++ ) {
outBufWrap[ ch ] = outBuf;
}
impBuf = new float[ 3 ][];
impBuf[ 0 ] = outBuf;
impBuf[ 1 ] = new float[ 1 ];
impBuf[ 1 ][ 0 ]= 0.0f; // time domain
impBuf[ 2 ] = new float[ impLength.x ]; // rotate buffer
calcIR( cp, outStream, impBuf, impLength );
progOff += (outLength >> 1);
// .... progress ....
setProgression( (float) progOff / (float) progLen );
if( !threadRunning ) break topLevel;
if( impBuf[ 1 ][ 0 ] == 1.0f ) {
Fourier.realTransform( outBuf, fftLength, Fourier.INVERSE );
Util.rotate( outBuf, fftLength, impBuf[ 2 ], impLength.x ); // undo rotation
}
progOff += (outLength >> 1);
// .... progress ....
setProgression( (float) progOff / (float) progLen );
if( !threadRunning ) break topLevel;
// ---- normalize output ----
if( pr.bool[ PR_NORMGAIN ]) {
for( i = 0; i < outLength; i++ ) {
floaty = Math.abs( outBuf[ i ]);
if( floaty > maxAmp ) {
maxAmp = floaty;
}
}
gain = 1.0f / maxAmp;
maxAmp = 1.0f;
for( i = 0; i < outLength; i++ ) {
outBuf[ i ] *= gain;
}
}
// ---- write output ----
for( framesWritten = 0; threadRunning && (framesWritten < outLength); ) {
j = Math.min( 8192, outLength - framesWritten );
outF.writeFrames( outBufWrap, framesWritten, j );
framesWritten += j;
progOff += j;
// .... progress ....
setProgression( (float) progOff / (float) progLen );
}
// .... check running ....
if( !threadRunning ) break topLevel;
// ---- Finish ----
outF.close();
outF = null;
outStream = null;
// .... check running ....
if( !threadRunning ) break topLevel;
// System.out.println( "progOff "+progOff+"; progLen "+progLen );
} // topLevel
catch( IOException e1 ) {
setError( e1 );
}
catch( OutOfMemoryError e2 ) {
impBuf = null;
outBuf = null;
outBufWrap = null;
outStream = null;
System.gc();
setError( new Exception( ERR_MEMORY ));;
}
// ---- cleanup (topLevel) ----
if( outF != null ) {
outF.cleanUp();
}
*/ }
}