/*
* AmpEnvOp.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.op;
import de.sciss.fscape.gui.GroupLabel;
import de.sciss.fscape.gui.OpIcon;
import de.sciss.fscape.gui.PropertyGUI;
import de.sciss.fscape.prop.OpPrefs;
import de.sciss.fscape.prop.Prefs;
import de.sciss.fscape.prop.Presets;
import de.sciss.fscape.prop.PropertyArray;
import de.sciss.fscape.spect.SpectFrame;
import de.sciss.fscape.spect.SpectStream;
import de.sciss.fscape.spect.SpectStreamSlot;
import de.sciss.fscape.util.Envelope;
import de.sciss.fscape.util.Modulator;
import de.sciss.fscape.util.Param;
import de.sciss.fscape.util.Slots;
import de.sciss.fscape.util.Util;
import java.io.EOFException;
import java.io.IOException;
public class AmpEnvOp
extends Operator {
// -------- private fields --------
protected static final String defaultName = "Amp Env";
protected static Presets static_presets = null;
protected static Prefs static_prefs = null;
protected static PropertyArray static_pr = null;
// Slots
protected static final int SLOT_INPUT = 0;
protected static final int SLOT_OUTPUT = 1;
private static final int PR_ENV = 0; // pr.envl
private static final String PRN_ENV = "Env";
private static final Envelope prEnvl[] = { null };
private static final String prEnvlName[] = { PRN_ENV };
// -------- public methods --------
public AmpEnvOp()
{
super();
// initialize only in the first instance
// preferences laden
if( static_prefs == null ) {
static_prefs = new OpPrefs( getClass(), getDefaultPrefs() );
}
// propertyarray defaults
if( static_pr == null ) {
static_pr = new PropertyArray();
// static_pr.bool = prBool;
// static_pr.boolName = prBoolName;
// static_pr.intg = prIntg;
// static_pr.intgName = prIntgName;
// static_pr.para = prPara;
// static_pr.para[ PR_LOMODDEPTH ] = new Param( 12.0, Param.OFFSET_SEMITONES );
// static_pr.paraName = prParaName;
static_pr.envl = prEnvl;
static_pr.envl[ PR_ENV ] = Envelope.createBasicEnvelope( Envelope.BASIC_TIME );
static_pr.envlName = prEnvlName;
static_pr.superPr = Operator.op_static_pr;
}
// default preset
if( static_presets == null ) {
static_presets = new Presets( getClass(), static_pr.toProperties( true ));
}
// register superclass entries
opName = "AmpEnvOp";
prefs = static_prefs;
presets = static_presets;
pr = (PropertyArray) static_pr.clone();
// slots
slots.addElement( new SpectStreamSlot( this, Slots.SLOTS_READER ));
slots.addElement( new SpectStreamSlot( this, Slots.SLOTS_WRITER ));
// icon
icon = new OpIcon( this, OpIcon.ID_FLIPFREQ, defaultName );
}
// -------- Runnable methods --------
public void run()
{
runInit();
final SpectStreamSlot runInSlot;
final SpectStreamSlot runOutSlot;
SpectStream runInStream = null;
final SpectStream runOutStream;
SpectFrame runInFr = null;
SpectFrame runOutFr = null;
float gain;
float[] convBuf1;
topLevel:
try {
// ------------------------------ Input-Slot ------------------------------
runInSlot = slots.elementAt(SLOT_INPUT);
if (runInSlot.getLinked() == null) {
runStop(); // -> threadDead = true
}
for (boolean initDone = false; !initDone && !threadDead; ) {
try {
runInStream = runInSlot.getDescr(); // throws InterruptedException
initDone = true;
} catch (InterruptedException ignored) {
}
runCheckPause();
}
if (threadDead) break topLevel;
// ------------------------------ Output-Slot ------------------------------
runOutSlot = slots.elementAt(SLOT_OUTPUT);
runOutStream = new SpectStream(runInStream);
runOutSlot.initWriter(runOutStream);
// ------------------------------ init ------------------------------
// create modulators
final Modulator envMod = new Modulator(new Param(0.0, Param.ABS_AMP), new Param(1.0, Param.ABS_AMP),
pr.envl[PR_ENV], runInStream);
runSlotsReady();
// ------------------------------ main process ------------------------------
mainLoop:
while (!threadDead) {
gain = (float) envMod.calc().value;
for (boolean readDone = false; (!readDone) && !threadDead; ) {
try {
runInFr = runInSlot.readFrame(); // throws InterruptedException
readDone = true;
runOutFr = runOutStream.allocFrame();
} catch (InterruptedException ignored) {
} catch (EOFException e) {
break mainLoop;
}
runCheckPause();
}
if (threadDead) break mainLoop;
Util.copy(runInFr.data, 0, runOutFr.data, 0, runInStream.bands << 1);
for (int ch = 0; ch < runInStream.chanNum; ch++) { // alle Kanaele
convBuf1 = runOutFr.data[ch];
for (int i = 0, j = 0; j < runInStream.bands; i += 2, j++) {
convBuf1[i] *= gain;
}
}
runInSlot.freeFrame(runInFr);
for (boolean writeDone = false; (!writeDone) && !threadDead; ) {
try { // Unterbrechung
runOutSlot.writeFrame(runOutFr); // throws InterruptedException
writeDone = true;
runFrameDone(runOutSlot, runOutFr);
runOutStream.freeFrame(runOutFr);
} catch (InterruptedException ignored) {} // mainLoop wird eh gleich verlassen
runCheckPause();
}
}
runInStream.closeReader();
runOutStream.closeWriter();
} catch (IOException e) {
runQuit(e);
return;
} catch (SlotAlreadyConnectedException e) {
runQuit(e);
return;
}
runQuit(null);
}
// -------- GUI methods --------
public PropertyGUI createGUI( int type )
{
PropertyGUI gui;
if( type != GUI_PREFS ) return null;
gui = new PropertyGUI(
"gl"+GroupLabel.NAME_GENERAL+"\n" +
"en,pr"+PRN_ENV );
return gui;
}
}