Use Tree Navigation
public class

SoftPerformer

extends Object
/*
 * Copyright (c) 2007, 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 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;
   
}
}