/*
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.media.sound;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* This class decodes information from ModelPeformer for use in SoftVoice.
* It also adds default connections if they where missing in ModelPerformer.
*
* @author Karl Helgason
*/
public final class SoftPerformer {
static ModelConnectionBlock[] defaultconnections
= new ModelConnectionBlock[42];
static {
int o = 0;
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("noteon", "on", 0),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_UNIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
1, new ModelDestination(new ModelIdentifier("eg", "on", 0)));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("noteon", "on", 0),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_UNIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
1, new ModelDestination(new ModelIdentifier("eg", "on", 1)));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("eg", "active", 0),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_UNIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
1, new ModelDestination(new ModelIdentifier("mixer", "active", 0)));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("eg", 0),
ModelStandardTransform.DIRECTION_MAX2MIN,
ModelStandardTransform.POLARITY_UNIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
-960, new ModelDestination(new ModelIdentifier("mixer", "gain")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("noteon", "velocity"),
ModelStandardTransform.DIRECTION_MAX2MIN,
ModelStandardTransform.POLARITY_UNIPOLAR,
ModelStandardTransform.TRANSFORM_CONCAVE),
-960, new ModelDestination(new ModelIdentifier("mixer", "gain")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("midi", "pitch"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_BIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
new ModelSource(new ModelIdentifier("midi_rpn", "0"),
new ModelTransform() {
public double transform(double value) {
int v = (int) (value * 16384.0);
int msb = v >> 7;
int lsb = v & 127;
return msb * 100 + lsb;
}
}),
new ModelDestination(new ModelIdentifier("osc", "pitch")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("noteon", "keynumber"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_UNIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
12800, new ModelDestination(new ModelIdentifier("osc", "pitch")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("midi_cc", "7"),
ModelStandardTransform.DIRECTION_MAX2MIN,
ModelStandardTransform.POLARITY_UNIPOLAR,
ModelStandardTransform.TRANSFORM_CONCAVE),
-960, new ModelDestination(new ModelIdentifier("mixer", "gain")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("midi_cc", "8"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_UNIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
1000, new ModelDestination(new ModelIdentifier("mixer", "balance")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("midi_cc", "10"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_UNIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
1000, new ModelDestination(new ModelIdentifier("mixer", "pan")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("midi_cc", "11"),
ModelStandardTransform.DIRECTION_MAX2MIN,
ModelStandardTransform.POLARITY_UNIPOLAR,
ModelStandardTransform.TRANSFORM_CONCAVE),
-960, new ModelDestination(new ModelIdentifier("mixer", "gain")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("midi_cc", "91"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_UNIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
1000, new ModelDestination(new ModelIdentifier("mixer", "reverb")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("midi_cc", "93"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_UNIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
1000, new ModelDestination(new ModelIdentifier("mixer", "chorus")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("midi_cc", "71"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_BIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
200, new ModelDestination(new ModelIdentifier("filter", "q")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("midi_cc", "74"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_BIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
9600, new ModelDestination(new ModelIdentifier("filter", "freq")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("midi_cc", "72"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_BIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
6000, new ModelDestination(new ModelIdentifier("eg", "release2")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("midi_cc", "73"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_BIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
2000, new ModelDestination(new ModelIdentifier("eg", "attack2")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("midi_cc", "75"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_BIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
6000, new ModelDestination(new ModelIdentifier("eg", "decay2")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("midi_cc", "67"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_UNIPOLAR,
ModelStandardTransform.TRANSFORM_SWITCH),
-50, new ModelDestination(ModelDestination.DESTINATION_GAIN));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("midi_cc", "67"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_UNIPOLAR,
ModelStandardTransform.TRANSFORM_SWITCH),
-2400, new ModelDestination(ModelDestination.DESTINATION_FILTER_FREQ));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("midi_rpn", "1"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_BIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
100, new ModelDestination(new ModelIdentifier("osc", "pitch")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("midi_rpn", "2"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_BIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
12800, new ModelDestination(new ModelIdentifier("osc", "pitch")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("master", "fine_tuning"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_BIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
100, new ModelDestination(new ModelIdentifier("osc", "pitch")));
defaultconnections[o++] = new ModelConnectionBlock(
new ModelSource(
new ModelIdentifier("master", "coarse_tuning"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_BIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
12800, new ModelDestination(new ModelIdentifier("osc", "pitch")));
defaultconnections[o++] = new ModelConnectionBlock(13500,
new ModelDestination(new ModelIdentifier("filter", "freq", 0)));
defaultconnections[o++] = new ModelConnectionBlock(
Float.NEGATIVE_INFINITY, new ModelDestination(
new ModelIdentifier("eg", "delay", 0)));
defaultconnections[o++] = new ModelConnectionBlock(
Float.NEGATIVE_INFINITY, new ModelDestination(
new ModelIdentifier("eg", "attack", 0)));
defaultconnections[o++] = new ModelConnectionBlock(
Float.NEGATIVE_INFINITY, new ModelDestination(
new ModelIdentifier("eg", "hold", 0)));
defaultconnections[o++] = new ModelConnectionBlock(
Float.NEGATIVE_INFINITY, new ModelDestination(
new ModelIdentifier("eg", "decay", 0)));
defaultconnections[o++] = new ModelConnectionBlock(1000,
new ModelDestination(new ModelIdentifier("eg", "sustain", 0)));
defaultconnections[o++] = new ModelConnectionBlock(
Float.NEGATIVE_INFINITY, new ModelDestination(
new ModelIdentifier("eg", "release", 0)));
defaultconnections[o++] = new ModelConnectionBlock(1200.0
* Math.log(0.015) / Math.log(2), new ModelDestination(
new ModelIdentifier("eg", "shutdown", 0))); // 15 msec default
defaultconnections[o++] = new ModelConnectionBlock(
Float.NEGATIVE_INFINITY, new ModelDestination(
new ModelIdentifier("eg", "delay", 1)));
defaultconnections[o++] = new ModelConnectionBlock(
Float.NEGATIVE_INFINITY, new ModelDestination(
new ModelIdentifier("eg", "attack", 1)));
defaultconnections[o++] = new ModelConnectionBlock(
Float.NEGATIVE_INFINITY, new ModelDestination(
new ModelIdentifier("eg", "hold", 1)));
defaultconnections[o++] = new ModelConnectionBlock(
Float.NEGATIVE_INFINITY, new ModelDestination(
new ModelIdentifier("eg", "decay", 1)));
defaultconnections[o++] = new ModelConnectionBlock(1000,
new ModelDestination(new ModelIdentifier("eg", "sustain", 1)));
defaultconnections[o++] = new ModelConnectionBlock(
Float.NEGATIVE_INFINITY, new ModelDestination(
new ModelIdentifier("eg", "release", 1)));
defaultconnections[o++] = new ModelConnectionBlock(-8.51318,
new ModelDestination(new ModelIdentifier("lfo", "freq", 0)));
defaultconnections[o++] = new ModelConnectionBlock(
Float.NEGATIVE_INFINITY, new ModelDestination(
new ModelIdentifier("lfo", "delay", 0)));
defaultconnections[o++] = new ModelConnectionBlock(-8.51318,
new ModelDestination(new ModelIdentifier("lfo", "freq", 1)));
defaultconnections[o++] = new ModelConnectionBlock(
Float.NEGATIVE_INFINITY, new ModelDestination(
new ModelIdentifier("lfo", "delay", 1)));
}
public int keyFrom = 0;
public int keyTo = 127;
public int velFrom = 0;
public int velTo = 127;
public int exclusiveClass = 0;
public boolean selfNonExclusive = false;
public boolean forcedVelocity = false;
public boolean forcedKeynumber = false;
public ModelPerformer performer;
public ModelConnectionBlock[] connections;
public ModelOscillator[] oscillators;
public Map<Integer, int[]> midi_rpn_connections = new HashMap<Integer, int[]>();
public Map<Integer, int[]> midi_nrpn_connections = new HashMap<Integer, int[]>();
public int[][] midi_ctrl_connections;
public int[][] midi_connections;
public int[] ctrl_connections;
private List<Integer> ctrl_connections_list = new ArrayList<Integer>();
private static class KeySortComparator implements Comparator<ModelSource> {
public int compare(ModelSource o1, ModelSource o2) {
return o1.getIdentifier().toString().compareTo(
o2.getIdentifier().toString());
}
}
private static KeySortComparator keySortComparator = new KeySortComparator();
private String extractKeys(ModelConnectionBlock conn) {
StringBuffer sb = new StringBuffer();
if (conn.getSources() != null) {
sb.append("[");
ModelSource[] srcs = conn.getSources();
ModelSource[] srcs2 = new ModelSource[srcs.length];
for (int i = 0; i < srcs.length; i++)
srcs2[i] = srcs[i];
Arrays.sort(srcs2, keySortComparator);
for (int i = 0; i < srcs.length; i++) {
sb.append(srcs[i].getIdentifier());
sb.append(";");
}
sb.append("]");
}
sb.append(";");
if (conn.getDestination() != null) {
sb.append(conn.getDestination().getIdentifier());
}
sb.append(";");
return sb.toString();
}
private void processSource(ModelSource src, int ix) {
ModelIdentifier id = src.getIdentifier();
String o = id.getObject();
if (o.equals("midi_cc"))
processMidiControlSource(src, ix);
else if (o.equals("midi_rpn"))
processMidiRpnSource(src, ix);
else if (o.equals("midi_nrpn"))
processMidiNrpnSource(src, ix);
else if (o.equals("midi"))
processMidiSource(src, ix);
else if (o.equals("noteon"))
processNoteOnSource(src, ix);
else if (o.equals("osc"))
return;
else if (o.equals("mixer"))
return;
else
ctrl_connections_list.add(ix);
}
private void processMidiControlSource(ModelSource src, int ix) {
String v = src.getIdentifier().getVariable();
if (v == null)
return;
int c = Integer.parseInt(v);
if (midi_ctrl_connections[c] == null)
midi_ctrl_connections[c] = new int[]{ix};
else {
int[] olda = midi_ctrl_connections[c];
int[] newa = new int[olda.length + 1];
for (int i = 0; i < olda.length; i++)
newa[i] = olda[i];
newa[newa.length - 1] = ix;
midi_ctrl_connections[c] = newa;
}
}
private void processNoteOnSource(ModelSource src, int ix) {
String v = src.getIdentifier().getVariable();
int c = -1;
if (v.equals("on"))
c = 3;
if (v.equals("keynumber"))
c = 4;
if (c == -1)
return;
if (midi_connections[c] == null)
midi_connections[c] = new int[]{ix};
else {
int[] olda = midi_connections[c];
int[] newa = new int[olda.length + 1];
for (int i = 0; i < olda.length; i++)
newa[i] = olda[i];
newa[newa.length - 1] = ix;
midi_connections[c] = newa;
}
}
private void processMidiSource(ModelSource src, int ix) {
String v = src.getIdentifier().getVariable();
int c = -1;
if (v.equals("pitch"))
c = 0;
if (v.equals("channel_pressure"))
c = 1;
if (v.equals("poly_pressure"))
c = 2;
if (c == -1)
return;
if (midi_connections[c] == null)
midi_connections[c] = new int[]{ix};
else {
int[] olda = midi_connections[c];
int[] newa = new int[olda.length + 1];
for (int i = 0; i < olda.length; i++)
newa[i] = olda[i];
newa[newa.length - 1] = ix;
midi_connections[c] = newa;
}
}
private void processMidiRpnSource(ModelSource src, int ix) {
String v = src.getIdentifier().getVariable();
if (v == null)
return;
int c = Integer.parseInt(v);
if (midi_rpn_connections.get(c) == null)
midi_rpn_connections.put(c, new int[]{ix});
else {
int[] olda = midi_rpn_connections.get(c);
int[] newa = new int[olda.length + 1];
for (int i = 0; i < olda.length; i++)
newa[i] = olda[i];
newa[newa.length - 1] = ix;
midi_rpn_connections.put(c, newa);
}
}
private void processMidiNrpnSource(ModelSource src, int ix) {
String v = src.getIdentifier().getVariable();
if (v == null)
return;
int c = Integer.parseInt(v);
if (midi_nrpn_connections.get(c) == null)
midi_nrpn_connections.put(c, new int[]{ix});
else {
int[] olda = midi_nrpn_connections.get(c);
int[] newa = new int[olda.length + 1];
for (int i = 0; i < olda.length; i++)
newa[i] = olda[i];
newa[newa.length - 1] = ix;
midi_nrpn_connections.put(c, newa);
}
}
public SoftPerformer(ModelPerformer performer) {
this.performer = performer;
keyFrom = performer.getKeyFrom();
keyTo = performer.getKeyTo();
velFrom = performer.getVelFrom();
velTo = performer.getVelTo();
exclusiveClass = performer.getExclusiveClass();
selfNonExclusive = performer.isSelfNonExclusive();
Map<String, ModelConnectionBlock> connmap = new HashMap<String, ModelConnectionBlock>();
List<ModelConnectionBlock> performer_connections = new ArrayList<ModelConnectionBlock>();
performer_connections.addAll(performer.getConnectionBlocks());
if (performer.isDefaultConnectionsEnabled()) {
// Add modulation depth range (RPN 5) to the modulation wheel (cc#1)
boolean isModulationWheelConectionFound = false;
for (int j = 0; j < performer_connections.size(); j++) {
ModelConnectionBlock connection = performer_connections.get(j);
ModelSource[] sources = connection.getSources();
ModelDestination dest = connection.getDestination();
boolean isModulationWheelConection = false;
if (dest != null && sources != null && sources.length > 1) {
for (int i = 0; i < sources.length; i++) {
// check if connection block has the source "modulation
// wheel cc#1"
if (sources[i].getIdentifier().getObject().equals(
"midi_cc")) {
if (sources[i].getIdentifier().getVariable()
.equals("1")) {
isModulationWheelConection = true;
isModulationWheelConectionFound = true;
break;
}
}
}
}
if (isModulationWheelConection) {
ModelConnectionBlock newconnection = new ModelConnectionBlock();
newconnection.setSources(connection.getSources());
newconnection.setDestination(connection.getDestination());
newconnection.addSource(new ModelSource(
new ModelIdentifier("midi_rpn", "5")));
newconnection.setScale(connection.getScale() * 256.0);
performer_connections.set(j, newconnection);
}
}
if (!isModulationWheelConectionFound) {
ModelConnectionBlock conn = new ModelConnectionBlock(
new ModelSource(ModelSource.SOURCE_LFO1,
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_BIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
new ModelSource(new ModelIdentifier("midi_cc", "1", 0),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_UNIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
50,
new ModelDestination(ModelDestination.DESTINATION_PITCH));
conn.addSource(new ModelSource(new ModelIdentifier("midi_rpn",
"5")));
conn.setScale(conn.getScale() * 256.0);
performer_connections.add(conn);
}
// Let Aftertouch to behave just like modulation wheel (cc#1)
boolean channel_pressure_set = false;
boolean poly_pressure = false;
ModelConnectionBlock mod_cc_1_connection = null;
int mod_cc_1_connection_src_ix = 0;
for (ModelConnectionBlock connection : performer_connections) {
ModelSource[] sources = connection.getSources();
ModelDestination dest = connection.getDestination();
// if(dest != null && sources != null)
if (dest != null && sources != null) {
for (int i = 0; i < sources.length; i++) {
ModelIdentifier srcid = sources[i].getIdentifier();
// check if connection block has the source "modulation
// wheel cc#1"
if (srcid.getObject().equals("midi_cc")) {
if (srcid.getVariable().equals("1")) {
mod_cc_1_connection = connection;
mod_cc_1_connection_src_ix = i;
}
}
// check if channel or poly pressure are already
// connected
if (srcid.getObject().equals("midi")) {
if (srcid.getVariable().equals("channel_pressure"))
channel_pressure_set = true;
if (srcid.getVariable().equals("poly_pressure"))
poly_pressure = true;
}
}
}
}
if (mod_cc_1_connection != null) {
if (!channel_pressure_set) {
ModelConnectionBlock mc = new ModelConnectionBlock();
mc.setDestination(mod_cc_1_connection.getDestination());
mc.setScale(mod_cc_1_connection.getScale());
ModelSource[] src_list = mod_cc_1_connection.getSources();
ModelSource[] src_list_new = new ModelSource[src_list.length];
for (int i = 0; i < src_list_new.length; i++)
src_list_new[i] = src_list[i];
src_list_new[mod_cc_1_connection_src_ix] = new ModelSource(
new ModelIdentifier("midi", "channel_pressure"));
mc.setSources(src_list_new);
connmap.put(extractKeys(mc), mc);
}
if (!poly_pressure) {
ModelConnectionBlock mc = new ModelConnectionBlock();
mc.setDestination(mod_cc_1_connection.getDestination());
mc.setScale(mod_cc_1_connection.getScale());
ModelSource[] src_list = mod_cc_1_connection.getSources();
ModelSource[] src_list_new = new ModelSource[src_list.length];
for (int i = 0; i < src_list_new.length; i++)
src_list_new[i] = src_list[i];
src_list_new[mod_cc_1_connection_src_ix] = new ModelSource(
new ModelIdentifier("midi", "poly_pressure"));
mc.setSources(src_list_new);
connmap.put(extractKeys(mc), mc);
}
}
// Enable Vibration Sound Controllers : 76, 77, 78
ModelConnectionBlock found_vib_connection = null;
for (ModelConnectionBlock connection : performer_connections) {
ModelSource[] sources = connection.getSources();
if (sources.length != 0
&& sources[0].getIdentifier().getObject().equals("lfo")) {
if (connection.getDestination().getIdentifier().equals(
ModelDestination.DESTINATION_PITCH)) {
if (found_vib_connection == null)
found_vib_connection = connection;
else {
if (found_vib_connection.getSources().length > sources.length)
found_vib_connection = connection;
else if (found_vib_connection.getSources()[0]
.getIdentifier().getInstance() < 1) {
if (found_vib_connection.getSources()[0]
.getIdentifier().getInstance() >
sources[0].getIdentifier().getInstance()) {
found_vib_connection = connection;
}
}
}
}
}
}
int instance = 1;
if (found_vib_connection != null) {
instance = found_vib_connection.getSources()[0].getIdentifier()
.getInstance();
}
ModelConnectionBlock connection;
connection = new ModelConnectionBlock(
new ModelSource(new ModelIdentifier("midi_cc", "78"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_BIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
2000, new ModelDestination(
new ModelIdentifier("lfo", "delay2", instance)));
connmap.put(extractKeys(connection), connection);
final double scale = found_vib_connection == null ? 0
: found_vib_connection.getScale();
connection = new ModelConnectionBlock(
new ModelSource(new ModelIdentifier("lfo", instance)),
new ModelSource(new ModelIdentifier("midi_cc", "77"),
new ModelTransform() {
double s = scale;
public double transform(double value) {
value = value * 2 - 1;
value *= 600;
if (s == 0) {
return value;
} else if (s > 0) {
if (value < -s)
value = -s;
return value;
} else {
if (value < s)
value = -s;
return -value;
}
}
}), new ModelDestination(ModelDestination.DESTINATION_PITCH));
connmap.put(extractKeys(connection), connection);
connection = new ModelConnectionBlock(
new ModelSource(new ModelIdentifier("midi_cc", "76"),
ModelStandardTransform.DIRECTION_MIN2MAX,
ModelStandardTransform.POLARITY_BIPOLAR,
ModelStandardTransform.TRANSFORM_LINEAR),
2400, new ModelDestination(
new ModelIdentifier("lfo", "freq", instance)));
connmap.put(extractKeys(connection), connection);
}
// Add default connection blocks
if (performer.isDefaultConnectionsEnabled())
for (ModelConnectionBlock connection : defaultconnections)
connmap.put(extractKeys(connection), connection);
// Add connection blocks from modelperformer
for (ModelConnectionBlock connection : performer_connections)
connmap.put(extractKeys(connection), connection);
// seperate connection blocks : Init time, Midi Time, Midi/Control Time,
// Control Time
List<ModelConnectionBlock> connections = new ArrayList<ModelConnectionBlock>();
midi_ctrl_connections = new int[128][];
for (int i = 0; i < midi_ctrl_connections.length; i++) {
midi_ctrl_connections[i] = null;
}
midi_connections = new int[5][];
for (int i = 0; i < midi_connections.length; i++) {
midi_connections[i] = null;
}
int ix = 0;
boolean mustBeOnTop = false;
for (ModelConnectionBlock connection : connmap.values()) {
if (connection.getDestination() != null) {
ModelDestination dest = connection.getDestination();
ModelIdentifier id = dest.getIdentifier();
if (id.getObject().equals("noteon")) {
mustBeOnTop = true;
if (id.getVariable().equals("keynumber"))
forcedKeynumber = true;
if (id.getVariable().equals("velocity"))
forcedVelocity = true;
}
}
if (mustBeOnTop) {
connections.add(0, connection);
mustBeOnTop = false;
} else
connections.add(connection);
}
for (ModelConnectionBlock connection : connections) {
if (connection.getSources() != null) {
ModelSource[] srcs = connection.getSources();
for (int i = 0; i < srcs.length; i++) {
processSource(srcs[i], ix);
}
}
ix++;
}
this.connections = new ModelConnectionBlock[connections.size()];
connections.toArray(this.connections);
this.ctrl_connections = new int[ctrl_connections_list.size()];
for (int i = 0; i < this.ctrl_connections.length; i++)
this.ctrl_connections[i] = ctrl_connections_list.get(i);
oscillators = new ModelOscillator[performer.getOscillators().size()];
performer.getOscillators().toArray(oscillators);
for (ModelConnectionBlock conn : connections) {
if (conn.getDestination() != null) {
if (isUnnecessaryTransform(conn.getDestination().getTransform())) {
conn.getDestination().setTransform(null);
}
}
if (conn.getSources() != null) {
for (ModelSource src : conn.getSources()) {
if (isUnnecessaryTransform(src.getTransform())) {
src.setTransform(null);
}
}
}
}
}
private static boolean isUnnecessaryTransform(ModelTransform transform) {
if (transform == null)
return false;
if (!(transform instanceof ModelStandardTransform))
return false;
ModelStandardTransform stransform = (ModelStandardTransform)transform;
if (stransform.getDirection() != ModelStandardTransform.DIRECTION_MIN2MAX)
return false;
if (stransform.getPolarity() != ModelStandardTransform.POLARITY_UNIPOLAR)
return false;
if (stransform.getTransform() != ModelStandardTransform.TRANSFORM_LINEAR)
return false;
return false;
}
}