776 lines
34 KiB
Java
776 lines
34 KiB
Java
/*
|
|
* 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;
|
|
}
|
|
}
|