918 lines · 32.2 KB · Java
RawDownload
/* * Copyright (c) 2007, 2010, 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.io.IOException;import java.util.Arrays;import java.util.HashMap;import java.util.Map; import javax.sound.midi.VoiceStatus; /** * Software synthesizer voice class. * * @author Karl Helgason */public class SoftVoice extends VoiceStatus {     public int exclusiveClass = 0;    public boolean releaseTriggered = false;    private int noteOn_noteNumber = 0;    private int noteOn_velocity = 0;    private int noteOff_velocity = 0;    private int delay = 0;    protected ModelChannelMixer channelmixer = null;    protected double tunedKey = 0;    protected SoftTuning tuning = null;    protected SoftChannel stealer_channel = null;    protected ModelConnectionBlock[] stealer_extendedConnectionBlocks = null;    protected SoftPerformer stealer_performer = null;    protected ModelChannelMixer stealer_channelmixer = null;    protected int stealer_voiceID = -1;    protected int stealer_noteNumber = 0;    protected int stealer_velocity = 0;    protected boolean stealer_releaseTriggered = false;    protected int voiceID = -1;    protected boolean sustain = false;    protected boolean sostenuto = false;    protected boolean portamento = false;    private SoftFilter filter_left;    private SoftFilter filter_right;    private SoftProcess eg = new SoftEnvelopeGenerator();    private SoftProcess lfo = new SoftLowFrequencyOscillator();    protected Map<String, SoftControl> objects =            new HashMap<String, SoftControl>();    protected SoftSynthesizer synthesizer;    protected SoftInstrument instrument;    protected SoftPerformer performer;    protected SoftChannel softchannel = null;    protected boolean on = false;    private boolean audiostarted = false;    private boolean started = false;    private boolean stopping = false;    private float osc_attenuation = 0.0f;    private ModelOscillatorStream osc_stream;    private int osc_stream_nrofchannels;    private float[][] osc_buff = new float[2][];    private boolean osc_stream_off_transmitted = false;    private boolean out_mixer_end = false;    private float out_mixer_left = 0;    private float out_mixer_right = 0;    private float out_mixer_effect1 = 0;    private float out_mixer_effect2 = 0;    private float last_out_mixer_left = 0;    private float last_out_mixer_right = 0;    private float last_out_mixer_effect1 = 0;    private float last_out_mixer_effect2 = 0;    protected ModelConnectionBlock[] extendedConnectionBlocks = null;    private ModelConnectionBlock[] connections;    // Last value added to destination    private double[] connections_last = new double[50];    // Pointer to source value    private double[][][] connections_src = new double[50][3][];    // Key-based override (if any)    private int[][] connections_src_kc = new int[50][3];    // Pointer to destination value    private double[][] connections_dst = new double[50][];    private boolean soundoff = false;    private float lastMuteValue = 0;    private float lastSoloMuteValue = 0;    protected double[] co_noteon_keynumber = new double[1];    protected double[] co_noteon_velocity = new double[1];    protected double[] co_noteon_on = new double[1];    private SoftControl co_noteon = new SoftControl() {        double[] keynumber = co_noteon_keynumber;        double[] velocity = co_noteon_velocity;        double[] on = co_noteon_on;        public double[] get(int instance, String name) {            if (name == null)                return null;            if (name.equals("keynumber"))                return keynumber;            if (name.equals("velocity"))                return velocity;            if (name.equals("on"))                return on;            return null;        }    };    private double[] co_mixer_active = new double[1];    private double[] co_mixer_gain = new double[1];    private double[] co_mixer_pan = new double[1];    private double[] co_mixer_balance = new double[1];    private double[] co_mixer_reverb = new double[1];    private double[] co_mixer_chorus = new double[1];    private SoftControl co_mixer = new SoftControl() {        double[] active = co_mixer_active;        double[] gain = co_mixer_gain;        double[] pan = co_mixer_pan;        double[] balance = co_mixer_balance;        double[] reverb = co_mixer_reverb;        double[] chorus = co_mixer_chorus;        public double[] get(int instance, String name) {            if (name == null)                return null;            if (name.equals("active"))                return active;            if (name.equals("gain"))                return gain;            if (name.equals("pan"))                return pan;            if (name.equals("balance"))                return balance;            if (name.equals("reverb"))                return reverb;            if (name.equals("chorus"))                return chorus;            return null;        }    };    private double[] co_osc_pitch = new double[1];    private SoftControl co_osc = new SoftControl() {        double[] pitch = co_osc_pitch;        public double[] get(int instance, String name) {            if (name == null)                return null;            if (name.equals("pitch"))                return pitch;            return null;        }    };    private double[] co_filter_freq = new double[1];    private double[] co_filter_type = new double[1];    private double[] co_filter_q = new double[1];    private SoftControl co_filter = new SoftControl() {        double[] freq = co_filter_freq;        double[] ftype = co_filter_type;        double[] q = co_filter_q;        public double[] get(int instance, String name) {            if (name == null)                return null;            if (name.equals("freq"))                return freq;            if (name.equals("type"))                return ftype;            if (name.equals("q"))                return q;            return null;        }    };    protected SoftResamplerStreamer resampler;    private int nrofchannels;     public SoftVoice(SoftSynthesizer synth) {        synthesizer = synth;        filter_left = new SoftFilter(synth.getFormat().getSampleRate());        filter_right = new SoftFilter(synth.getFormat().getSampleRate());        nrofchannels = synth.getFormat().getChannels();    }     private int getValueKC(ModelIdentifier id) {        if (id.getObject().equals("midi_cc")) {            int ic = Integer.parseInt(id.getVariable());            if (ic != 0 && ic != 32) {                if (ic < 120)                    return ic;            }        } else if (id.getObject().equals("midi_rpn")) {            if (id.getVariable().equals("1"))                return 120; // Fine tuning            if (id.getVariable().equals("2"))                return 121; // Coarse tuning        }        return -1;    }     private double[] getValue(ModelIdentifier id) {        SoftControl o = objects.get(id.getObject());        if (o == null)            return null;        return o.get(id.getInstance(), id.getVariable());    }     private double transformValue(double value, ModelSource src) {        if (src.getTransform() != null)            return src.getTransform().transform(value);        else            return value;    }     private double transformValue(double value, ModelDestination dst) {        if (dst.getTransform() != null)            return dst.getTransform().transform(value);        else            return value;    }     private double processKeyBasedController(double value, int keycontrol) {        if (keycontrol == -1)            return value;        if (softchannel.keybasedcontroller_active != null)            if (softchannel.keybasedcontroller_active[note] != null)                if (softchannel.keybasedcontroller_active[note][keycontrol]) {                    double key_controlvalue =                            softchannel.keybasedcontroller_value[note][keycontrol];                    if (keycontrol == 10 || keycontrol == 91 || keycontrol == 93)                        return key_controlvalue;                    value += key_controlvalue * 2.0 - 1.0;                    if (value > 1)                        value = 1;                    else if (value < 0)                        value = 0;                }        return value;    }     private void processConnection(int ix) {        ModelConnectionBlock conn = connections[ix];        double[][] src = connections_src[ix];        double[] dst = connections_dst[ix];        if (dst == null || Double.isInfinite(dst[0]))            return;         double value = conn.getScale();        if (softchannel.keybasedcontroller_active == null) {            ModelSource[] srcs = conn.getSources();            for (int i = 0; i < srcs.length; i++) {                value *= transformValue(src[i][0], srcs[i]);                if (value == 0)                    break;            }        } else {            ModelSource[] srcs = conn.getSources();            int[] src_kc = connections_src_kc[ix];            for (int i = 0; i < srcs.length; i++) {                value *= transformValue(processKeyBasedController(src[i][0],                        src_kc[i]), srcs[i]);                if (value == 0)                    break;            }        }         value = transformValue(value, conn.getDestination());        dst[0] = dst[0] - connections_last[ix] + value;        connections_last[ix] = value;        // co_mixer_gain[0] = 0;    }     protected void updateTuning(SoftTuning newtuning) {        tuning = newtuning;        tunedKey = tuning.getTuning(note) / 100.0;        if (!portamento) {            co_noteon_keynumber[0] = tunedKey * (1.0 / 128.0);            if(performer == null)                return;            int[] c = performer.midi_connections[4];            if (c == null)                return;            for (int i = 0; i < c.length; i++)                processConnection(c[i]);        }    }     protected void setNote(int noteNumber) {        note = noteNumber;        tunedKey = tuning.getTuning(noteNumber) / 100.0;    }     protected void noteOn(int noteNumber, int velocity, int delay) {         sustain = false;        sostenuto = false;        portamento = false;         soundoff = false;        on = true;        active = true;        started = true;        // volume = velocity;         noteOn_noteNumber = noteNumber;        noteOn_velocity = velocity;        this.delay = delay;         lastMuteValue = 0;        lastSoloMuteValue = 0;         setNote(noteNumber);         if (performer.forcedKeynumber)            co_noteon_keynumber[0] = 0;        else            co_noteon_keynumber[0] = tunedKey * (1f / 128f);        if (performer.forcedVelocity)            co_noteon_velocity[0] = 0;        else            co_noteon_velocity[0] = velocity * (1f / 128f);        co_mixer_active[0] = 0;        co_mixer_gain[0] = 0;        co_mixer_pan[0] = 0;        co_mixer_balance[0] = 0;        co_mixer_reverb[0] = 0;        co_mixer_chorus[0] = 0;        co_osc_pitch[0] = 0;        co_filter_freq[0] = 0;        co_filter_q[0] = 0;        co_filter_type[0] = 0;        co_noteon_on[0] = 1;         eg.reset();        lfo.reset();        filter_left.reset();        filter_right.reset();         objects.put("master", synthesizer.getMainMixer().co_master);        objects.put("eg", eg);        objects.put("lfo", lfo);        objects.put("noteon", co_noteon);        objects.put("osc", co_osc);        objects.put("mixer", co_mixer);        objects.put("filter", co_filter);         connections = performer.connections;         if (connections_last == null                || connections_last.length < connections.length) {            connections_last = new double[connections.length];        }        if (connections_src == null                || connections_src.length < connections.length) {            connections_src = new double[connections.length][][];            connections_src_kc = new int[connections.length][];        }        if (connections_dst == null                || connections_dst.length < connections.length) {            connections_dst = new double[connections.length][];        }        for (int i = 0; i < connections.length; i++) {            ModelConnectionBlock conn = connections[i];            connections_last[i] = 0;            if (conn.getSources() != null) {                ModelSource[] srcs = conn.getSources();                if (connections_src[i] == null                        || connections_src[i].length < srcs.length) {                    connections_src[i] = new double[srcs.length][];                    connections_src_kc[i] = new int[srcs.length];                }                double[][] src = connections_src[i];                int[] src_kc = connections_src_kc[i];                connections_src[i] = src;                for (int j = 0; j < srcs.length; j++) {                    src_kc[j] = getValueKC(srcs[j].getIdentifier());                    src[j] = getValue(srcs[j].getIdentifier());                }            }             if (conn.getDestination() != null)                connections_dst[i] = getValue(conn.getDestination()                        .getIdentifier());            else                connections_dst[i] = null;        }         for (int i = 0; i < connections.length; i++)            processConnection(i);         if (extendedConnectionBlocks != null) {            for (ModelConnectionBlock connection: extendedConnectionBlocks) {                double value = 0;                 if (softchannel.keybasedcontroller_active == null) {                    for (ModelSource src: connection.getSources()) {                        double x = getValue(src.getIdentifier())[0];                        ModelTransform t = src.getTransform();                        if (t == null)                            value += x;                        else                            value += t.transform(x);                    }                } else {                    for (ModelSource src: connection.getSources()) {                        double x = getValue(src.getIdentifier())[0];                        x = processKeyBasedController(x,                                getValueKC(src.getIdentifier()));                        ModelTransform t = src.getTransform();                        if (t == null)                            value += x;                        else                            value += t.transform(x);                    }                }                 ModelDestination dest = connection.getDestination();                ModelTransform t = dest.getTransform();                if (t != null)                    value = t.transform(value);                getValue(dest.getIdentifier())[0] += value;            }        }         eg.init(synthesizer);        lfo.init(synthesizer);     }     protected void setPolyPressure(int pressure) {        if(performer == null)            return;        int[] c = performer.midi_connections[2];        if (c == null)            return;        for (int i = 0; i < c.length; i++)            processConnection(c[i]);    }     protected void setChannelPressure(int pressure) {        if(performer == null)            return;        int[] c = performer.midi_connections[1];        if (c == null)            return;        for (int i = 0; i < c.length; i++)            processConnection(c[i]);    }     protected void controlChange(int controller, int value) {        if(performer == null)            return;        int[] c = performer.midi_ctrl_connections[controller];        if (c == null)            return;        for (int i = 0; i < c.length; i++)            processConnection(c[i]);    }     protected void nrpnChange(int controller, int value) {        if(performer == null)            return;        int[] c = performer.midi_nrpn_connections.get(controller);        if (c == null)            return;        for (int i = 0; i < c.length; i++)            processConnection(c[i]);    }     protected void rpnChange(int controller, int value) {        if(performer == null)            return;        int[] c = performer.midi_rpn_connections.get(controller);        if (c == null)            return;        for (int i = 0; i < c.length; i++)            processConnection(c[i]);    }     protected void setPitchBend(int bend) {        if(performer == null)            return;        int[] c = performer.midi_connections[0];        if (c == null)            return;        for (int i = 0; i < c.length; i++)            processConnection(c[i]);    }     protected void setMute(boolean mute) {        co_mixer_gain[0] -= lastMuteValue;        lastMuteValue = mute ? -960 : 0;

Lines 1–500 of 918.