/*
 * 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.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) {
        tunedKey = tuning.getTuning(note) / 100.0;
        if (!portamento) {
            co_noteon_keynumber[0] = tunedKey * (1.0 / 128.0);
            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) {
        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) {
        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) {
        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) {
        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) {
        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) {
        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;
        co_mixer_gain[0] += lastMuteValue;
    }

    protected void setSoloMute(boolean mute) {
        co_mixer_gain[0] -= lastSoloMuteValue;
        lastSoloMuteValue = mute ? -960 : 0;
        co_mixer_gain[0] += lastSoloMuteValue;
    }

    protected void shutdown() {
        if (co_noteon_on[0] < -0.5)
            return;
        on = false;

        co_noteon_on[0] = -1;

        int[] c = performer.midi_connections[3];
        if (c == null)
            return;
        for (int i = 0; i < c.length; i++)
            processConnection(c[i]);
    }

    protected void soundOff() {
        on = false;
        soundoff = true;
    }

    protected void noteOff(int velocity) {
        if (!on)
            return;
        on = false;

        noteOff_velocity = velocity;

        if (softchannel.sustain) {
            sustain = true;
            return;
        }
        if (sostenuto)
            return;

        co_noteon_on[0] = 0;

        int[] c = performer.midi_connections[3];
        if (c == null)
            return;
        for (int i = 0; i < c.length; i++)
            processConnection(c[i]);
    }

    protected void redamp() {
        if (co_noteon_on[0] > 0.5)
            return;
        if (co_noteon_on[0] < -0.5)
            return; // don't redamp notes in shutdown stage

        sustain = true;
        co_noteon_on[0] = 1;

        int[] c = performer.midi_connections[3];
        if (c == null)
            return;
        for (int i = 0; i < c.length; i++)
            processConnection(c[i]);
    }

    protected void processControlLogic() {
        if (stopping) {
            active = false;
            stopping = false;
            audiostarted = false;
            if (osc_stream != null)
                try {
                    osc_stream.close();
                } catch (IOException e) {
                    //e.printStackTrace();
                }

            if (stealer_channel != null) {
                stealer_channel.initVoice(this, stealer_performer,
                        stealer_voiceID, stealer_noteNumber, stealer_velocity, 0,
                        stealer_extendedConnectionBlocks, stealer_channelmixer,
                        stealer_releaseTriggered);
                stealer_releaseTriggered = false;
                stealer_channel = null;
                stealer_performer = null;
                stealer_voiceID = -1;
                stealer_noteNumber = 0;
                stealer_velocity = 0;
                stealer_extendedConnectionBlocks = null;
                stealer_channelmixer = null;
            }
        }
        if (started) {
            audiostarted = true;

            ModelOscillator osc = performer.oscillators[0];

            osc_stream_off_transmitted = false;
            if (osc instanceof ModelWavetable) {
                try {
                    resampler.open((ModelWavetable)osc,
                            synthesizer.getFormat().getSampleRate());
                    osc_stream = resampler;
                } catch (IOException e) {
                    //e.printStackTrace();
                }
            } else {
                osc_stream = osc.open(synthesizer.getFormat().getSampleRate());
            }
            osc_attenuation = osc.getAttenuation();
            osc_stream_nrofchannels = osc.getChannels();
            if (osc_buff == null || osc_buff.length < osc_stream_nrofchannels)
                osc_buff = new float[osc_stream_nrofchannels][];

            if (osc_stream != null)
                osc_stream.noteOn(softchannel, this, noteOn_noteNumber,
                        noteOn_velocity);


        }
        if (audiostarted) {
            if (portamento) {
                double note_delta = tunedKey - (co_noteon_keynumber[0] * 128);
                double note_delta_a = Math.abs(note_delta);
                if (note_delta_a < 0.0000000001) {
                    co_noteon_keynumber[0] = tunedKey * (1.0 / 128.0);
                    portamento = false;
                } else {
                    if (note_delta_a > softchannel.portamento_time)
                        note_delta = Math.signum(note_delta)
                                * softchannel.portamento_time;
                    co_noteon_keynumber[0] += note_delta * (1.0 / 128.0);
                }

                int[] c = performer.midi_connections[4];
                if (c == null)
                    return;
                for (int i = 0; i < c.length; i++)
                    processConnection(c[i]);
            }

            eg.processControlLogic();
            lfo.processControlLogic();

            for (int i = 0; i < performer.ctrl_connections.length; i++)
                processConnection(performer.ctrl_connections[i]);

            osc_stream.setPitch((float)co_osc_pitch[0]);

            int filter_type = (int)co_filter_type[0];
            double filter_freq;

            if (co_filter_freq[0] == 13500.0)
                filter_freq = 19912.126958213175;
            else
                filter_freq = 440.0 * Math.exp(
                        ((co_filter_freq[0]) - 6900.0) *
                        (Math.log(2.0) / 1200.0));
            /*
            filter_freq = 440.0 * Math.pow(2.0,
            ((co_filter_freq[0]) - 6900.0) / 1200.0);*/
            /*
             * double velocity = co_noteon_velocity[0]; if(velocity < 0.5)
             * filter_freq *= ((velocity * 2)*0.75 + 0.25);
             */

            double q = co_filter_q[0] / 10.0;
            filter_left.setFilterType(filter_type);
            filter_left.setFrequency(filter_freq);
            filter_left.setResonance(q);
            filter_right.setFilterType(filter_type);
            filter_right.setFrequency(filter_freq);
            filter_right.setResonance(q);
            /*
            float gain = (float) Math.pow(10,
            (-osc_attenuation + co_mixer_gain[0]) / 200.0);
             */
            float gain = (float)Math.exp(
                    (-osc_attenuation + co_mixer_gain[0])*(Math.log(10) / 200.0));

            if (co_mixer_gain[0] <= -960)
                gain = 0;

            if (soundoff) {
                stopping = true;
                gain = 0;
                /*
                 * if(co_mixer_gain[0] > -960)
                 *   co_mixer_gain[0] -= 960;
                 */
            }

            volume = (int)(Math.sqrt(gain) * 128);

            // gain *= 0.2;

            double pan = co_mixer_pan[0] * (1.0 / 1000.0);
            // System.out.println("pan = " + pan);
            if (pan < 0)
                pan = 0;
            else if (pan > 1)
                pan = 1;

            if (pan == 0.5) {
                out_mixer_left = gain * 0.7071067811865476f;
                out_mixer_right = out_mixer_left;
            } else {
                out_mixer_left = gain * (float)Math.cos(pan * Math.PI * 0.5);
                out_mixer_right = gain * (float)Math.sin(pan * Math.PI * 0.5);
            }

            double balance = co_mixer_balance[0] * (1.0 / 1000.0);
            if (balance != 0.5) {
                if (balance > 0.5)
                    out_mixer_left *= (1 - balance) * 2;
                else
                    out_mixer_right *= balance * 2;
            }

            if (synthesizer.reverb_on) {
                out_mixer_effect1 = (float)(co_mixer_reverb[0] * (1.0 / 1000.0));
                out_mixer_effect1 *= gain;
            } else
                out_mixer_effect1 = 0;
            if (synthesizer.chorus_on) {
                out_mixer_effect2 = (float)(co_mixer_chorus[0] * (1.0 / 1000.0));
                out_mixer_effect2 *= gain;
            } else
                out_mixer_effect2 = 0;
            out_mixer_end = co_mixer_active[0] < 0.5;

            if (!on)
                if (!osc_stream_off_transmitted) {
                    osc_stream_off_transmitted = true;
                    if (osc_stream != null)
                        osc_stream.noteOff(noteOff_velocity);
                }

        }
        if (started) {
            last_out_mixer_left = out_mixer_left;
            last_out_mixer_right = out_mixer_right;
            last_out_mixer_effect1 = out_mixer_effect1;
            last_out_mixer_effect2 = out_mixer_effect2;
            started = false;
        }

    }

    protected void mixAudioStream(SoftAudioBuffer in, SoftAudioBuffer out,
            SoftAudioBuffer dout,
            float amp_from, float amp_to) {
        int bufferlen = in.getSize();
        if (amp_from < 0.000000001 && amp_to < 0.000000001)
            return;
        if(dout != null && delay != 0)
        {
            if (amp_from == amp_to) {
                float[] fout = out.array();
                float[] fin = in.array();
                int j = 0;
                for (int i = delay; i < bufferlen; i++)
                    fout[i] += fin[j++] * amp_to;
                fout = dout.array();
                for (int i = 0; i < delay; i++)
                    fout[i] += fin[j++] * amp_to;
            } else {
                float amp = amp_from;
                float amp_delta = (amp_to - amp_from) / bufferlen;
                float[] fout = out.array();
                float[] fin = in.array();
                int j = 0;
                for (int i = delay; i < bufferlen; i++) {
                    amp += amp_delta;
                    fout[i] += fin[j++] * amp;
                }
                fout = dout.array();
                for (int i = 0; i < delay; i++) {
                    amp += amp_delta;
                    fout[i] += fin[j++] * amp;
                }
            }
        }
        else
        {
            if (amp_from == amp_to) {
                float[] fout = out.array();
                float[] fin = in.array();
                for (int i = 0; i < bufferlen; i++)
                    fout[i] += fin[i] * amp_to;
            } else {
                float amp = amp_from;
                float amp_delta = (amp_to - amp_from) / bufferlen;
                float[] fout = out.array();
                float[] fin = in.array();
                for (int i = 0; i < bufferlen; i++) {
                    amp += amp_delta;
                    fout[i] += fin[i] * amp;
                }
            }
        }

    }

    protected void processAudioLogic(SoftAudioBuffer[] buffer) {
        if (!audiostarted)
            return;

        int bufferlen = buffer[0].getSize();

        try {
            osc_buff[0] = buffer[SoftMainMixer.CHANNEL_LEFT_DRY].array();
            if (nrofchannels != 1)
                osc_buff[1] = buffer[SoftMainMixer.CHANNEL_RIGHT_DRY].array();
            int ret = osc_stream.read(osc_buff, 0, bufferlen);
            if (ret == -1) {
                stopping = true;
                return;
            }
            if (ret != bufferlen) {
                Arrays.fill(osc_buff[0], ret, bufferlen, 0f);
                if (nrofchannels != 1)
                    Arrays.fill(osc_buff[1], ret, bufferlen, 0f);
            }

        } catch (IOException e) {
            //e.printStackTrace();
        }

        SoftAudioBuffer left = buffer[SoftMainMixer.CHANNEL_LEFT];
        SoftAudioBuffer right = buffer[SoftMainMixer.CHANNEL_RIGHT];
        SoftAudioBuffer mono = buffer[SoftMainMixer.CHANNEL_MONO];
        SoftAudioBuffer eff1 = buffer[SoftMainMixer.CHANNEL_EFFECT1];
        SoftAudioBuffer eff2 = buffer[SoftMainMixer.CHANNEL_EFFECT2];

        SoftAudioBuffer dleft = buffer[SoftMainMixer.CHANNEL_DELAY_LEFT];
        SoftAudioBuffer dright = buffer[SoftMainMixer.CHANNEL_DELAY_RIGHT];
        SoftAudioBuffer dmono = buffer[SoftMainMixer.CHANNEL_DELAY_MONO];
        SoftAudioBuffer deff1 = buffer[SoftMainMixer.CHANNEL_DELAY_EFFECT1];
        SoftAudioBuffer deff2 = buffer[SoftMainMixer.CHANNEL_DELAY_EFFECT2];

        SoftAudioBuffer leftdry = buffer[SoftMainMixer.CHANNEL_LEFT_DRY];
        SoftAudioBuffer rightdry = buffer[SoftMainMixer.CHANNEL_RIGHT_DRY];

        if (osc_stream_nrofchannels == 1)
            rightdry = null;

        if (!Double.isInfinite(co_filter_freq[0])) {
            filter_left.processAudio(leftdry);
            if (rightdry != null)
                filter_right.processAudio(rightdry);
        }

        if (nrofchannels == 1) {
            out_mixer_left = (out_mixer_left + out_mixer_right) / 2;
            mixAudioStream(leftdry, left, dleft, last_out_mixer_left, out_mixer_left);
            if (rightdry != null)
                mixAudioStream(rightdry, left, dleft, last_out_mixer_left,
                        out_mixer_left);
        } else {
            if(rightdry == null &&
                    last_out_mixer_left == last_out_mixer_right &&
                    out_mixer_left == out_mixer_right)
            {
                mixAudioStream(leftdry, mono, dmono, last_out_mixer_left, out_mixer_left);
            }
            else
            {
                mixAudioStream(leftdry, left, dleft, last_out_mixer_left, out_mixer_left);
                if (rightdry != null)
                    mixAudioStream(rightdry, right, dright, last_out_mixer_right,
                        out_mixer_right);
                else
                    mixAudioStream(leftdry, right, dright, last_out_mixer_right,
                        out_mixer_right);
            }
        }

        if (rightdry == null) {
            mixAudioStream(leftdry, eff1, deff1, last_out_mixer_effect1,
                    out_mixer_effect1);
            mixAudioStream(leftdry, eff2, deff2, last_out_mixer_effect2,
                    out_mixer_effect2);
        } else {
            mixAudioStream(leftdry, eff1, deff1, last_out_mixer_effect1 * 0.5f,
                    out_mixer_effect1 * 0.5f);
            mixAudioStream(leftdry, eff2, deff2, last_out_mixer_effect2 * 0.5f,
                    out_mixer_effect2 * 0.5f);
            mixAudioStream(rightdry, eff1, deff1, last_out_mixer_effect1 * 0.5f,
                    out_mixer_effect1 * 0.5f);
            mixAudioStream(rightdry, eff2, deff2, last_out_mixer_effect2 * 0.5f,
                    out_mixer_effect2 * 0.5f);
        }

        last_out_mixer_left = out_mixer_left;
        last_out_mixer_right = out_mixer_right;
        last_out_mixer_effect1 = out_mixer_effect1;
        last_out_mixer_effect2 = out_mixer_effect2;

        if (out_mixer_end) {
            stopping = true;
        }

    }
}
