/*
* UnitorOp.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.Constants;
import de.sciss.fscape.util.Param;
import de.sciss.fscape.util.Slots;
import java.io.IOException;
public class UnitorOp
extends Operator {
// -------- private variables --------
protected static final String defaultName = "Unitor"; // "real" name (z.B. Icons)
protected static Presets static_presets = null;
protected static Prefs static_prefs = null;
protected static PropertyArray static_pr = null;
protected static final int NUM_INPUT = 6; // Zahl der Slots
// Slots
protected static final int SLOT_INPUT = 0; // bis 5
protected static final int SLOT_OUTPUT = NUM_INPUT;
// Properties (defaults)
private static final int PR_OPERATION = 0; // Array-Indices: pr.intg
private static final int PR_DATAFORM = 1;
private static final int PR_ADJUSTGAIN = 0; // pr.bool
private static final int PR_DELAY = 1; // bis 6
private static final int PR_GAIN = 0; // pr.para
private static final int PR_DELAYTIME = 1; // bis 6
private static final int PR_OPERATION_COLLECT = 0;
private static final int PR_OPERATION_ADD = 1;
private static final int PR_OPERATION_SUBSTRACT = 2;
private static final int PR_OPERATION_MULTIPLY = 3;
private static final int PR_OPERATION_DIVIDE = 4;
private static final int PR_OPERATION_AND = 5;
private static final int PR_OPERATION_OR = 6;
private static final int PR_OPERATION_XOR = 7;
private static final int PR_OPERATION_EXP = 8;
private static final int PR_OPERATION_LOG = 9;
private static final int PR_OPERATION_MODULO = 10;
private static final int PR_OPERATION_ATAN = 11;
private static final int PR_DATAFORM_AMP = 0;
private static final int PR_DATAFORM_RECT = 1;
private static final int PR_DATAFORM_POLAR = 2;
private static final String PRN_OPERATION = "Operation"; // Property-Keynames
private static final String PRN_DATAFORM = "DataForm";
private static final String PRN_ADJUSTGAIN = "AdjustGain";
private static final String PRN_GAIN = "Gain";
private static final String PRN_DELAY = "Delay"; // 1...6
private static final String PRN_DELAYTIME = "DelayTime"; // 1...6
private static final int prIntg[] = { PR_OPERATION_ADD, PR_DATAFORM_RECT };
private static final String prIntgName[] = { PRN_OPERATION, PRN_DATAFORM };
// -------- public methods --------
// public PropertyGUI createGUI( int type );
public UnitorOp()
{
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.intg = prIntg;
static_pr.intgName = prIntgName;
static_pr.bool = new boolean[ 1 + NUM_INPUT ];
static_pr.boolName = new String[ 1 + NUM_INPUT ];
static_pr.para = new Param[ 1 + NUM_INPUT ];
static_pr.paraName = new String[ 1 + NUM_INPUT ];
static_pr.bool[ PR_ADJUSTGAIN ] = false;
static_pr.boolName[ PR_ADJUSTGAIN ] = PRN_ADJUSTGAIN;
static_pr.para[ PR_GAIN ] = new Param( 0.0, Param.DECIBEL_AMP );
static_pr.paraName[ PR_GAIN ] = PRN_GAIN;
for( int i = 0; i < NUM_INPUT; i++ ) {
static_pr.para[ PR_DELAYTIME + i ] = new Param( (double) i, Param.ABS_BEATS );
static_pr.paraName[ PR_DELAYTIME + i ] = PRN_DELAYTIME + (i+1);
static_pr.bool[ PR_DELAY + i ] = false;
static_pr.boolName[ PR_DELAY + i ] = PRN_DELAY + (i+1);
}
static_pr.superPr = Operator.op_static_pr;
}
// default preset
if( static_presets == null ) {
static_presets = new Presets( getClass(), static_pr.toProperties( true ));
}
// superclass-Felder uebertragen
opName = "UnitorOp";
prefs = static_prefs;
presets = static_presets;
pr = (PropertyArray) static_pr.clone();
// slots
for( int i = 0; i < NUM_INPUT; i++ ) {
slots.addElement( new SpectStreamSlot( this, Slots.SLOTS_READER,
Slots.SLOTS_DEFREADER +(i+1) )); // SLOT_INPUT
}
slots.addElement( new SpectStreamSlot( this, Slots.SLOTS_WRITER )); // SLOT_OUTPUT
// icon
icon = new OpIcon( this, OpIcon.ID_UNITOR, defaultName );
}
// -------- Runnable methods --------
/**
* TESTSTADIUM XXX
*/
public void run() {
runInit(); // superclass
int i, j, ch, numFinished;
float f1;
// Haupt-Variablen fuer den Prozess
SpectStreamSlot runInSlot[] = new SpectStreamSlot[ NUM_INPUT ];
SpectStreamSlot runOutSlot;
SpectStream runInStream[] = new SpectStream[ NUM_INPUT ];
SpectStream runOutStream;
SpectFrame runInFr[] = new SpectFrame[ NUM_INPUT ];
SpectFrame runOutFr;
// int runSlotNum[] = new int[ NUM_INPUT ];
int runChanStart[] = new int[ NUM_INPUT ];
// Berechnungs-Grundlagen
Param ampRef = new Param( 1.0, Param.ABS_AMP ); // transform-Referenz
double gain = 1.0;
// andere
int numIn = 0; // number of used slots
int oldReadDone;
int readable;
int chanNum = 0;
float srcData[]; // Frame-Daten eines Kanals
float destData[];
int srcCh;
int dataLen;
float srcAmp, srcPhase; // Polar <==> Rect
double srcReal, srcImg;
boolean wantsRect; // true if polar->rect transform required
boolean wantsInt; // true if float->int transform required
int intFrame[][] = null; // fuer AND/OR/XOR brauchen wir Integer!
topLevel:
try {
// ------------------------------ Input-Slots ------------------------------
for (i = 0; (i < NUM_INPUT) && !threadDead; i++) {
try {
runInFr[numIn] = null;
runInSlot[numIn] = slots.elementAt(SLOT_INPUT + i);
if (runInSlot[numIn].getLinked() != null) {
runInStream[numIn] = runInSlot[numIn].getDescr(); // throws InterruptedException
if (pr.intg[PR_OPERATION] == PR_OPERATION_COLLECT) {
runChanStart[numIn] = chanNum;
chanNum += runInStream[numIn].chanNum;
} else {
runChanStart[numIn] = 0;
chanNum = Math.max(chanNum, runInStream[numIn].chanNum);
}
numIn++;
}
} catch (InterruptedException e) {
i--; // retry this getDescr()
}
runCheckPause();
}
if (numIn == 0) runStop(); // threadDead = true
if (threadDead) break topLevel;
// ------------------------------ Output-Slot ------------------------------
runOutSlot = slots.elementAt(SLOT_OUTPUT);
runOutStream = new SpectStream(runInStream[0]);
runOutStream.setChannels(chanNum);
runOutSlot.initWriter(runOutStream);
// ------------------------------ Vorberechnungen ------------------------------
if (pr.bool[PR_ADJUSTGAIN]) {
gain = (float) Param.transform(pr.para[PR_GAIN], Param.ABS_AMP,
ampRef, runInStream[0]).value;
if (Math.abs(gain - 1.0f) < 0.01f) {
gain = 1.0f; // schneller kopieren
}
}
wantsRect = (pr.intg[ PR_DATAFORM ] == PR_DATAFORM_RECT);
wantsInt = (pr.intg[ PR_OPERATION ] == PR_OPERATION_AND) ||
(pr.intg[ PR_OPERATION ] == PR_OPERATION_OR) ||
// (pr.intg[ PR_OPERATION ] == PR_OPERATION_MODULO) ||
(pr.intg[ PR_OPERATION ] == PR_OPERATION_XOR);
if( wantsInt ) {
intFrame = new int[ runOutStream.chanNum ][ runOutStream.bands << 1 ];
}
// ------------------------------ Hauptschleife ------------------------------
runSlotsReady();
mainLoop:
while (!threadDead) {
// ---------- Frame einlesen ----------
for (int readDone = 0; (readDone < numIn) && !threadDead; ) {
oldReadDone = readDone;
for (i = 0, numFinished = 0; i < numIn; i++) {
try { // Unterbrechung
if (runInFr[i] == null) { // noch nicht gelesen
readable = runInStream[i].framesReadable();
if (readable > 0) {
runInFr[i] = runInSlot[i].readFrame();
readDone++;
} else if (readable < 0) { // Stream geschlossen, leeres Frame erzeugen
numFinished++;
if (numFinished == numIn) break mainLoop; // fertisch
runInFr[i] = runInStream[i].allocFrame();
for (ch = 0; ch < runInFr[i].data.length; ch++) {
srcData = runInFr[i].data[ch];
for (j = 0; j < srcData.length; j++) {
srcData[j] = 0.0f;
}
}
readDone++;
}
}
} catch (InterruptedException e) {
break mainLoop;
}
runCheckPause();
}
if (oldReadDone == readDone) { // konnte nix gelesen werden
try {
Thread.sleep(500); // ...deshalb kurze Pause
} catch (InterruptedException ignored) {} // mainLoop wird gleich automatisch verlassen
runCheckPause();
}
}
if (threadDead) break mainLoop; // Schluss machen
// ---------- Process: Ziel-Frame berechnen ----------
runOutFr = runOutStream.allocFrame();
if (pr.intg[PR_OPERATION] == PR_OPERATION_COLLECT) { // Kanaele zusammenfassen
for (i = 0; i < numIn; i++) {
for (ch = 0; ch < runInFr[i].data.length; ch++) {
srcData = runInFr[i].data[ch];
destData = runOutFr.data[runChanStart[i] + ch];
System.arraycopy(srcData, 0, destData, 0,
Math.min(destData.length, srcData.length));
// ggf. overhead nullen
for (j = srcData.length; j < destData.length; j++) {
destData[j] = 0.0f;
}
}
}
} else { // mathematische Operationen
// ---------- erster Schritt: unterstes Frame ins Ziel kopieren, ggf. Polar => Rect / Float => int
srcCh = runInFr[0].data.length;
if (!wantsRect) {
if (!wantsInt) {
for (ch = 0; ch < runOutFr.data.length; ch++) {
srcData = runInFr[0].data[ch % srcCh]; // ggf. Kanaele wiederholen
destData = runOutFr.data[ch];
System.arraycopy(srcData, 0, destData, 0,
Math.min(destData.length, srcData.length));
// ggf. overhead nullen
for (j = srcData.length; j < destData.length; j++) {
destData[j] = 0.0f;
}
}
} else { // !wantsRect && wantsInt
for (ch = 0; ch < runOutFr.data.length; ch++) {
srcData = runInFr[0].data[ch % srcCh]; // ggf. Kanaele wiederholen
dataLen = Math.min(intFrame[ch].length, srcData.length);
for (j = 0; j < dataLen; j += 2) {
intFrame[ch][j + SpectFrame.AMP] = (int) (srcData[j + SpectFrame.AMP] *
0x7FFFFFFF);
intFrame[ch][j + SpectFrame.PHASE] = (int) (((srcData[j + SpectFrame.PHASE] +
Math.PI) % Constants.PI2) *
0x145F306D);
}
// ggf. overhead nullen
for (j = srcData.length; j < intFrame[ch].length; j += 2) {
intFrame[ch][j + SpectFrame.AMP] = 0;
intFrame[ch][j + SpectFrame.PHASE] = 0x3FFFFFFF;
}
}
}
} else {
if (!wantsInt) { // && wantsRect
for (ch = 0; ch < runOutFr.data.length; ch++) {
srcData = runInFr[0].data[ch % srcCh]; // ggf. Kanaele wiederholen
destData = runOutFr.data[ch];
dataLen = Math.min(destData.length, srcData.length);
for (j = 0; j < dataLen; j += 2) {
srcAmp = srcData[j + SpectFrame.AMP];
srcPhase = srcData[j + SpectFrame.PHASE];
destData[j] = srcAmp * (float) Math.cos(srcPhase); // real
destData[j + 1] = srcAmp * (float) Math.sin(srcPhase); // img
}
// ggf. overhead nullen
for (j = srcData.length; j < destData.length; j++) {
destData[j] = 0.0f;
}
}
} else { // wantsRect && wantsInt
for (ch = 0; ch < runOutFr.data.length; ch++) {
srcData = runInFr[0].data[ch % srcCh]; // ggf. Kanaele wiederholen
dataLen = Math.min(intFrame[ch].length, srcData.length);
for (j = 0; j < dataLen; j += 2) {
srcAmp = srcData[j + SpectFrame.AMP] * 0x3FFFFFFF;
srcPhase = srcData[j + SpectFrame.PHASE];
intFrame[ch][j] = (int) (srcAmp * Math.cos(srcPhase));
intFrame[ch][j + 1] = (int) (srcAmp * Math.sin(srcPhase));
}
// ggf. overhead nullen
for (j = srcData.length; j < intFrame[ch].length; j++) {
intFrame[ch][j] = 0;
}
}
}
}
// ---------- zweiter Schritt: alle folgenden via spezifizierte Operation hinzufuegen
for (i = 1; i < numIn; i++) {
srcCh = runInFr[i].data.length;
for (ch = 0; ch < runOutFr.data.length; ch++) {
srcData = runInFr[i].data[ch % srcCh]; // ggf. Kanaele wiederholen
destData = runOutFr.data[ch];
dataLen = Math.min(destData.length, srcData.length);
switch (pr.intg[PR_OPERATION]) {
case PR_OPERATION_ADD: // -------- Addition --------
switch (pr.intg[PR_DATAFORM]) {
case PR_DATAFORM_AMP:
for (j = 0; j < dataLen; j += 2) {
destData[j + SpectFrame.AMP] += srcData[j + SpectFrame.AMP];
}
break;
case PR_DATAFORM_POLAR:
for (j = 0; j < dataLen; j += 2) {
destData[j] += srcData[j];
}
break;
case PR_DATAFORM_RECT:
for (j = 0; j < dataLen; j += 2) {
srcAmp = srcData[j + SpectFrame.AMP];
srcPhase = srcData[j + SpectFrame.PHASE];
destData[j] += srcAmp * Math.cos(srcPhase);
destData[j + 1]+= srcAmp * Math.sin(srcPhase);
}
break;
default:
break;
}
break;
case PR_OPERATION_SUBSTRACT: // -------- Subtraktion --------
switch (pr.intg[PR_DATAFORM]) {
case PR_DATAFORM_AMP:
for (j = 0; j < dataLen; j += 2) {
f1 = destData[j + SpectFrame.AMP] - srcData[j + SpectFrame.AMP];
destData[j + SpectFrame.AMP] = Math.max(0.0f, f1);
}
break;
case PR_DATAFORM_POLAR:
for (j = 0; j < dataLen; j++) {
destData[j] -= srcData[j];
}
break;
case PR_DATAFORM_RECT:
for (j = 0; j < dataLen; j += 2) {
srcAmp = srcData[j + SpectFrame.AMP];
srcPhase = srcData[j + SpectFrame.PHASE];
destData[j] -= srcAmp * Math.cos(srcPhase);
destData[j + 1]-= srcAmp * Math.sin(srcPhase);
}
break;
default:
break;
}
break;
case PR_OPERATION_MULTIPLY: // -------- Multiplikation --------
switch (pr.intg[PR_DATAFORM]) {
case PR_DATAFORM_AMP:
for (j = 0; j < dataLen; j += 2) {
destData[j + SpectFrame.AMP] *= srcData[j + SpectFrame.AMP];
}
break;
case PR_DATAFORM_POLAR:
for (j = 0; j < dataLen; j++) {
destData[j] *= srcData[j];
}
break;
case PR_DATAFORM_RECT:
for (j = 0; j < dataLen; j += 2) {
srcAmp = srcData[j + SpectFrame.AMP];
srcPhase = srcData[j + SpectFrame.PHASE];
destData[j] *= srcAmp * Math.cos(srcPhase);
destData[j + 1]*= srcAmp * Math.sin(srcPhase);
}
break;
default:
break;
}
break;
case PR_OPERATION_DIVIDE: // -------- Division --------
switch (pr.intg[PR_DATAFORM]) {
case PR_DATAFORM_AMP:
for (j = 0; j < dataLen; j += 2) {
destData[j + SpectFrame.AMP] = (float) (destData[j + SpectFrame.AMP] /
Math.max(srcData[j + SpectFrame.AMP], 1.0e-6)) % 1.0f;
}
break;
case PR_DATAFORM_POLAR:
for (j = 0; j < dataLen; j += 2) {
destData[j + SpectFrame.AMP] = (float) (destData[j + SpectFrame.AMP] /
Math.max(srcData[j + SpectFrame.AMP], 1.0e-6)) % 1.0f;
destData[j + SpectFrame.PHASE] = (float)
((destData[j + SpectFrame.PHASE] /
Math.max(srcData[j + SpectFrame.PHASE] + Math.PI, 1.0e-6)) %
Constants.PI2);
}
break;
case PR_DATAFORM_RECT:
for (j = 0; j < dataLen; j += 2) {
srcAmp = srcData[j + SpectFrame.AMP];
srcPhase = srcData[j + SpectFrame.PHASE];
destData[j] = (float) (destData[j] /
Math.max(srcAmp * (1.0 + Math.cos(srcPhase)), 1.0e-6)) % 1.0f;
destData[j + 1] = (float) (destData[j + 1] /
Math.max(srcAmp * (1.0 + Math.sin(srcPhase)), 1.0e-6)) % 1.0f;
}
break;
default:
break;
}
break;
case PR_OPERATION_AND: // -------- AND --------
switch (pr.intg[PR_DATAFORM]) {
case PR_DATAFORM_AMP:
for (j = 0; j < dataLen; j += 2) {
intFrame[ch][j + SpectFrame.AMP] &= (int)
(srcData[j + SpectFrame.AMP] * 0x7FFFFFFF);
}
break;
case PR_DATAFORM_POLAR:
for (j = 0; j < dataLen; j += 2) {
intFrame[ ch ][ j + SpectFrame.AMP ] &= (int)
(srcData[ j + SpectFrame.AMP ] * 0x7FFFFFFF);
intFrame[ ch ][ j + SpectFrame.PHASE ] &= (int)
(srcData[ j + SpectFrame.PHASE ] * 0x145F306D);
}
break;
case PR_DATAFORM_RECT:
for (j = 0; j < dataLen; j += 2) {
srcAmp = srcData[j + SpectFrame.AMP] * 0x3FFFFFFF;
srcPhase = srcData[j + SpectFrame.PHASE];
intFrame[ch][j] &= (int) (srcAmp * Math.cos(srcPhase));
intFrame[ch][j + 1] &= (int) (srcAmp * Math.sin(srcPhase));
}
break;
default:
break;
}
break;
case PR_OPERATION_OR: // -------- OR --------
switch (pr.intg[PR_DATAFORM]) {
case PR_DATAFORM_AMP:
for (j = 0; j < dataLen; j += 2) {
intFrame[ch][j + SpectFrame.AMP] |= (int)
(srcData[j + SpectFrame.AMP] * 0x7FFFFFFF);
}
break;
case PR_DATAFORM_POLAR:
for (j = 0; j < dataLen; j += 2) {
intFrame[ch][j + SpectFrame.AMP] |= (int)
(srcData[j + SpectFrame.AMP] * 0x7FFFFFFF);
intFrame[ch][j + SpectFrame.PHASE] |= (int)
(srcData[j + SpectFrame.PHASE] * 0x145F306D);
}
break;
case PR_DATAFORM_RECT:
for (j = 0; j < dataLen; j += 2) {
srcAmp = srcData[j + SpectFrame.AMP] * 0x3FFFFFFF;
srcPhase = srcData[j + SpectFrame.PHASE];
intFrame[ch][j] |= (int) (srcAmp * Math.cos(srcPhase));
intFrame[ch][j + 1] |= (int) (srcAmp * Math.sin(srcPhase));
}
break;
default:
break;
}
break;
case PR_OPERATION_XOR: // -------- XOR --------
switch (pr.intg[PR_DATAFORM]) {
case PR_DATAFORM_AMP:
for (j = 0; j < dataLen; j += 2) {
intFrame[ch][j + SpectFrame.AMP] ^= (int)
(srcData[j + SpectFrame.AMP] * 0x7FFFFFFF);
}
break;
case PR_DATAFORM_POLAR:
for (j = 0; j < dataLen; j += 2) {
intFrame[ch][j + SpectFrame.AMP] ^= (int)
(srcData[j + SpectFrame.AMP] * 0x7FFFFFFF);
intFrame[ch][j + SpectFrame.PHASE] ^= (int)
(srcData[j + SpectFrame.PHASE] * 0x145F306D);
}
break;
case PR_DATAFORM_RECT:
for (j = 0; j < dataLen; j += 2) {
srcAmp = srcData[j + SpectFrame.AMP] * 0x3FFFFFFF;
srcPhase = srcData[j + SpectFrame.PHASE];
intFrame[ch][j] ^= (int) (srcAmp * Math.cos(srcPhase));
intFrame[ch][j + 1] ^= (int) (srcAmp * Math.sin(srcPhase));
}
break;
default:
break;
}
break;
case PR_OPERATION_EXP:
break;
case PR_OPERATION_LOG:
break;
case PR_OPERATION_MODULO: // -------- Modulo --------
switch (pr.intg[PR_DATAFORM]) {
case PR_DATAFORM_AMP:
for (j = 0; j < dataLen; j += 2) {
destData[j + SpectFrame.AMP] %= Math.max(
srcData[j + SpectFrame.AMP], 1.0e-6);
}
break;
case PR_DATAFORM_POLAR:
for (j = 0; j < dataLen; j += 2) {
destData[j + SpectFrame.AMP] %= Math.max(
srcData[j + SpectFrame.AMP], 1.0e-6);
destData[j + SpectFrame.PHASE] %= Math.max(
srcData[j + SpectFrame.PHASE] + Math.PI, 1.0e-6);
}
break;
case PR_DATAFORM_RECT:
for (j = 0; j < dataLen; j += 2) {
srcAmp = srcData[j + SpectFrame.AMP];
srcPhase = srcData[j + SpectFrame.PHASE];
destData[j] %= Math.max(
srcAmp * (1.0 + Math.cos(srcPhase)) / 2, 1.0e-6);
destData[j + 1] %= Math.max(
srcAmp * (1.0 + Math.sin(srcPhase)) / 2, 1.0e-6);
}
break;
default:
break;
}
break;
case PR_OPERATION_ATAN:
switch (pr.intg[PR_DATAFORM]) {
case PR_DATAFORM_AMP:
for (j = 0; j < dataLen; j += 2) {
destData[j + SpectFrame.AMP] = 1.0f - (float) (Math.atan2(
destData[j + SpectFrame.AMP],
srcData[j + SpectFrame.AMP]) / Constants.PIH);
}
break;
case PR_DATAFORM_POLAR:
for (j = 0; j < dataLen; j += 2) {
destData[j + SpectFrame.AMP] = 1.0f - (float) (Math.atan2(
destData[j + SpectFrame.AMP],
srcData[j + SpectFrame.AMP]) / Constants.PIH);
destData[j + SpectFrame.PHASE] = (float) Math.atan2(
destData[j + SpectFrame.PHASE],
srcData[j + SpectFrame.PHASE]);
}
break;
case PR_DATAFORM_RECT:
for (j = 0; j < dataLen; j += 2) {
srcAmp = srcData[j + SpectFrame.AMP];
srcPhase = srcData[j + SpectFrame.PHASE];
destData[j] = (float) (Math.atan2(
destData[j], srcAmp * Math.cos(srcPhase)) / Math.PI);
destData[j + 1] = (float) (Math.atan2(
destData[j + 1], srcAmp * Math.sin(srcPhase)) / Math.PI);
}
break;
default:
break;
}
break;
default:
break;
}
}
}
// ---------- letzter Schritt: ggf. Int nach Float zurueckrechnen bzw. Rect => Polar
if (!wantsInt) {
if (wantsRect) {
for (ch = 0; ch < runOutFr.data.length; ch++) {
destData = runOutFr.data[ch];
for (j = 0; j < destData.length; j += 2) {
srcReal = destData[j];
srcImg = destData[j + 1];
destData[j + SpectFrame.AMP] = (float)
Math.sqrt(srcReal * srcReal + srcImg * srcImg);
destData[j + SpectFrame.PHASE] = (float)
Math.atan2(srcImg, srcReal);
}
}
}
} else {
if (!wantsRect) { // && wantsInt
for( ch = 0; ch < runOutFr.data.length; ch++ ) {
destData = runOutFr.data[ch];
for (j = 0; j < destData.length; j += 2) {
destData[j + SpectFrame.AMP] = (float) intFrame[ch][j + SpectFrame.AMP] /
0x7FFFFFFF;
destData[j + SpectFrame.PHASE] = (float)
((double) intFrame[ch][j + SpectFrame.PHASE] /
0x145F306D - Math.PI);
}
}
} else { // wantsInt && wantsRect
for (ch = 0; ch < runOutFr.data.length; ch++) {
destData = runOutFr.data[ch];
for (j = 0; j < destData.length; j += 2) {
srcReal = (double) intFrame[ch][j] / 0x3FFFFFFF;
srcImg = (double) intFrame[ch][j + 1] / 0x3FFFFFFF;
destData[j + SpectFrame.AMP] = (float)
Math.sqrt(srcReal * srcReal + srcImg * srcImg);
destData[j + SpectFrame.PHASE] = (float)
Math.atan2(srcImg, srcReal);
}
}
}
}
}
// ---------- Frame berechnung Ende
// Lautstaerke anpassen
if (gain != 1.0f) {
for (ch = 0; ch < runOutFr.data.length; ch++) {
destData = runOutFr.data[ch];
for (j = 0; j < destData.length; j += 2) {
destData[j + SpectFrame.AMP] *= gain;
}
}
}
for (i = 0; i < numIn; i++) {
runInSlot[i].freeFrame(runInFr[i]);
runInFr[i] = null;
}
// ---------- Frame schreiben ----------
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();
}
} // end of main loop
for (i = 0; i < numIn; i++) {
runInStream[i].closeReader();
}
runOutStream.closeWriter();
} // break topLevel
catch (IOException e) {
runQuit(e);
return;
} catch (SlotAlreadyConnectedException e) {
runQuit(e);
return;
}
// catch( OutOfMemoryException e ) {
// abort( e );
// return;
// }
runQuit(null);
}
// -------- GUI methods --------
public PropertyGUI createGUI(int type) {
PropertyGUI gui;
StringBuffer delay = new StringBuffer();
StringBuffer opAction = new StringBuffer("ac0|101|di");
if (type != GUI_PREFS) return null;
for (int i = 1; i <= NUM_INPUT; i++) {
delay.append("\ncbSlot " + i + ",actrue|" + i + "|en,acfalse|" + i + "|di,pr" +
pr.boolName[PR_DELAY + (i - 1)] + ";pf" + Constants.absMsSpace + "|" +
Constants.absBeatsSpace + "|" + Constants.ratioTimeSpace + ",id" + i + ",pr" +
pr.paraName[PR_DELAYTIME + (i - 1)]);
}
for (int i = 1; i <= PR_OPERATION_ATAN; i++) {
opAction.append(",ac" + i + "|101|en");
}
gui = new PropertyGUI(
"gl"+GroupLabel.NAME_GENERAL+"\n" +
"lbOperation;ch,pr"+PRN_OPERATION + ","+opAction+","+
"itCollect channels,"+
"itAdd up,"+
"itSubstract,"+
"itMultiply,"+
"itDivide,"+
"itBoolean AND,"+
"itBoolean OR,"+
"itBoolean XOR,"+
"itPower,"+
"itLogarithm,"+
"itModulo,"+
"itArcus tangens\n"+
"lbOperate on;ch,id101,pr"+PRN_DATAFORM+"," +
"itAmplitude,"+
"itZ-plane rect,"+
"itPolar (phase/amp)\n"+
"cbAdjust gain,actrue|100|en,acfalse|100|di,pr"+PRN_ADJUSTGAIN+";"+
"pf"+Constants.decibelAmpSpace+",id100,pr"+PRN_GAIN+"\n" +
"glInput slot delay" + delay );
return gui;
}
}