775 lines · 34.5 KB · Java
RawDownload
/* * 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;

Lines 1–500 of 775.