/* * 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.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map; import javax.sound.midi.MidiChannel;import javax.sound.midi.Patch; /** * Software Synthesizer MIDI channel class. * * @author Karl Helgason */public class SoftChannel implements MidiChannel, ModelDirectedPlayer { private static boolean[] dontResetControls = new boolean[128]; static { for (int i = 0; i < dontResetControls.length; i++) dontResetControls[i] = false; dontResetControls[0] = true; // Bank Select (MSB) dontResetControls[32] = true; // Bank Select (LSB) dontResetControls[7] = true; // Channel Volume (MSB) dontResetControls[8] = true; // Balance (MSB) dontResetControls[10] = true; // Pan (MSB) dontResetControls[11] = true; // Expression (MSB) dontResetControls[91] = true; // Effects 1 Depth (default: Reverb Send) dontResetControls[92] = true; // Effects 2 Depth (default: Tremolo Depth) dontResetControls[93] = true; // Effects 3 Depth (default: Chorus Send) dontResetControls[94] = true; // Effects 4 Depth (default: Celeste [Detune] Depth) dontResetControls[95] = true; // Effects 5 Depth (default: Phaser Depth) dontResetControls[70] = true; // Sound Controller 1 (default: Sound Variation) dontResetControls[71] = true; // Sound Controller 2 (default: Timbre / Harmonic Quality) dontResetControls[72] = true; // Sound Controller 3 (default: Release Time) dontResetControls[73] = true; // Sound Controller 4 (default: Attack Time) dontResetControls[74] = true; // Sound Controller 5 (default: Brightness) dontResetControls[75] = true; // Sound Controller 6 (GM2 default: Decay Time) dontResetControls[76] = true; // Sound Controller 7 (GM2 default: Vibrato Rate) dontResetControls[77] = true; // Sound Controller 8 (GM2 default: Vibrato Depth) dontResetControls[78] = true; // Sound Controller 9 (GM2 default: Vibrato Delay) dontResetControls[79] = true; // Sound Controller 10 (GM2 default: Undefined) dontResetControls[120] = true; // All Sound Off dontResetControls[121] = true; // Reset All Controllers dontResetControls[122] = true; // Local Control On/Off dontResetControls[123] = true; // All Notes Off dontResetControls[124] = true; // Omni Mode Off dontResetControls[125] = true; // Omni Mode On dontResetControls[126] = true; // Poly Mode Off dontResetControls[127] = true; // Poly Mode On dontResetControls[6] = true; // Data Entry (MSB) dontResetControls[38] = true; // Data Entry (LSB) dontResetControls[96] = true; // Data Increment dontResetControls[97] = true; // Data Decrement dontResetControls[98] = true; // Non-Registered Parameter Number (LSB) dontResetControls[99] = true; // Non-Registered Parameter Number(MSB) dontResetControls[100] = true; // RPN = Null dontResetControls[101] = true; // RPN = Null } private static final int RPN_NULL_VALUE = (127 << 7) + 127; private int rpn_control = RPN_NULL_VALUE; private int nrpn_control = RPN_NULL_VALUE; protected double portamento_time = 1; // keyschanges per control buffer time protected int[] portamento_lastnote = new int[128]; protected int portamento_lastnote_ix = 0; private boolean portamento = false; private boolean mono = false; private boolean mute = false; private boolean solo = false; private boolean solomute = false; private Object control_mutex; private int channel; private SoftVoice[] voices; private int bank; private int program; private SoftSynthesizer synthesizer; private SoftMainMixer mainmixer; private int[] polypressure = new int[128]; private int channelpressure = 0; private int[] controller = new int[128]; private int pitchbend; private double[] co_midi_pitch = new double[1]; private double[] co_midi_channel_pressure = new double[1]; protected SoftTuning tuning = new SoftTuning(); protected int tuning_bank = 0; protected int tuning_program = 0; protected SoftInstrument current_instrument = null; protected ModelChannelMixer current_mixer = null; protected ModelDirector current_director = null; // Controller Destination Settings protected int cds_control_number = -1; protected ModelConnectionBlock[] cds_control_connections = null; protected ModelConnectionBlock[] cds_channelpressure_connections = null; protected ModelConnectionBlock[] cds_polypressure_connections = null; protected boolean sustain = false; protected boolean[][] keybasedcontroller_active = null; protected double[][] keybasedcontroller_value = null; private class MidiControlObject implements SoftControl { double[] pitch = co_midi_pitch; double[] channel_pressure = co_midi_channel_pressure; double[] poly_pressure = new double[1]; public double[] get(int instance, String name) { if (name == null) return null; if (name.equals("pitch")) return pitch; if (name.equals("channel_pressure")) return channel_pressure; if (name.equals("poly_pressure")) return poly_pressure; return null; } } private SoftControl[] co_midi = new SoftControl[128]; { for (int i = 0; i < co_midi.length; i++) { co_midi[i] = new MidiControlObject(); } } private double[][] co_midi_cc_cc = new double[128][1]; private SoftControl co_midi_cc = new SoftControl() { double[][] cc = co_midi_cc_cc; public double[] get(int instance, String name) { if (name == null) return null; return cc[Integer.parseInt(name)]; } }; Map<Integer, int[]> co_midi_rpn_rpn_i = new HashMap<Integer, int[]>(); Map<Integer, double[]> co_midi_rpn_rpn = new HashMap<Integer, double[]>(); private SoftControl co_midi_rpn = new SoftControl() { Map<Integer, double[]> rpn = co_midi_rpn_rpn; public double[] get(int instance, String name) { if (name == null) return null; int iname = Integer.parseInt(name); double[] v = rpn.get(iname); if (v == null) { v = new double[1]; rpn.put(iname, v); } return v; } }; Map<Integer, int[]> co_midi_nrpn_nrpn_i = new HashMap<Integer, int[]>(); Map<Integer, double[]> co_midi_nrpn_nrpn = new HashMap<Integer, double[]>(); private SoftControl co_midi_nrpn = new SoftControl() { Map<Integer, double[]> nrpn = co_midi_nrpn_nrpn; public double[] get(int instance, String name) { if (name == null) return null; int iname = Integer.parseInt(name); double[] v = nrpn.get(iname); if (v == null) { v = new double[1]; nrpn.put(iname, v); } return v; } }; private static int restrict7Bit(int value) { if(value < 0) return 0; if(value > 127) return 127; return value; } private static int restrict14Bit(int value) { if(value < 0) return 0; if(value > 16256) return 16256; return value; } public SoftChannel(SoftSynthesizer synth, int channel) { this.channel = channel; this.voices = synth.getVoices(); this.synthesizer = synth; this.mainmixer = synth.getMainMixer(); control_mutex = synth.control_mutex; resetAllControllers(true); } private int findFreeVoice(int x) { if(x == -1) { // x = -1 means that there where no available voice // last time we called findFreeVoice // and it hasn't changed because no audio has been // rendered in the meantime. // Therefore we have to return -1. return -1; } for (int i = x; i < voices.length; i++) if (!voices[i].active) return i; // No free voice was found, we must steal one int vmode = synthesizer.getVoiceAllocationMode(); if (vmode == 1) { // DLS Static Voice Allocation // * priority ( 10, 1-9, 11-16) // Search for channel to steal from int steal_channel = channel; for (int j = 0; j < voices.length; j++) { if (voices[j].stealer_channel == null) { if (steal_channel == 9) { steal_channel = voices[j].channel; } else { if (voices[j].channel != 9) { if (voices[j].channel > steal_channel) steal_channel = voices[j].channel; } } } } int voiceNo = -1; SoftVoice v = null; // Search for oldest voice in off state on steal_channel for (int j = 0; j < voices.length; j++) { if (voices[j].channel == steal_channel) { if (voices[j].stealer_channel == null && !voices[j].on) { if (v == null) { v = voices[j]; voiceNo = j; } if (voices[j].voiceID < v.voiceID) { v = voices[j]; voiceNo = j; } } } } // Search for oldest voice in on state on steal_channel if (voiceNo == -1) { for (int j = 0; j < voices.length; j++) { if (voices[j].channel == steal_channel) { if (voices[j].stealer_channel == null) { if (v == null) { v = voices[j]; voiceNo = j; } if (voices[j].voiceID < v.voiceID) { v = voices[j]; voiceNo = j; } } } } } return voiceNo; } else { // Default Voice Allocation // * Find voice that is on // and Find voice which has lowest voiceID ( oldest voice) // * Or find voice that is off // and Find voice which has lowest voiceID ( oldest voice) int voiceNo = -1; SoftVoice v = null; // Search for oldest voice in off state for (int j = 0; j < voices.length; j++) { if (voices[j].stealer_channel == null && !voices[j].on) { if (v == null) { v = voices[j]; voiceNo = j; } if (voices[j].voiceID < v.voiceID) { v = voices[j]; voiceNo = j; } } } // Search for oldest voice in on state if (voiceNo == -1) { for (int j = 0; j < voices.length; j++) { if (voices[j].stealer_channel == null) { if (v == null) { v = voices[j]; voiceNo = j; } if (voices[j].voiceID < v.voiceID) { v = voices[j]; voiceNo = j; } } } } return voiceNo; } } protected void initVoice(SoftVoice voice, SoftPerformer p, int voiceID, int noteNumber, int velocity, int delay, ModelConnectionBlock[] connectionBlocks, ModelChannelMixer channelmixer, boolean releaseTriggered) { if (voice.active) { // Voice is active , we must steal the voice voice.stealer_channel = this; voice.stealer_performer = p; voice.stealer_voiceID = voiceID; voice.stealer_noteNumber = noteNumber; voice.stealer_velocity = velocity; voice.stealer_extendedConnectionBlocks = connectionBlocks; voice.stealer_channelmixer = channelmixer; voice.stealer_releaseTriggered = releaseTriggered; for (int i = 0; i < voices.length; i++) if (voices[i].active && voices[i].voiceID == voice.voiceID) voices[i].soundOff(); return; } voice.extendedConnectionBlocks = connectionBlocks; voice.channelmixer = channelmixer; voice.releaseTriggered = releaseTriggered; voice.voiceID = voiceID; voice.tuning = tuning; voice.exclusiveClass = p.exclusiveClass; voice.softchannel = this; voice.channel = channel; voice.bank = bank; voice.program = program; voice.instrument = current_instrument; voice.performer = p; voice.objects.clear(); voice.objects.put("midi", co_midi[noteNumber]); voice.objects.put("midi_cc", co_midi_cc); voice.objects.put("midi_rpn", co_midi_rpn); voice.objects.put("midi_nrpn", co_midi_nrpn); voice.noteOn(noteNumber, velocity, delay); voice.setMute(mute); voice.setSoloMute(solomute); if (releaseTriggered) return; if (controller[84] != 0) { voice.co_noteon_keynumber[0] = (tuning.getTuning(controller[84]) / 100.0) * (1f / 128f); voice.portamento = true; controlChange(84, 0); } else if (portamento) { if (mono) { if (portamento_lastnote[0] != -1) { voice.co_noteon_keynumber[0] = (tuning.getTuning(portamento_lastnote[0]) / 100.0) * (1f / 128f); voice.portamento = true; controlChange(84, 0); } portamento_lastnote[0] = noteNumber; } else { if (portamento_lastnote_ix != 0) { portamento_lastnote_ix--; voice.co_noteon_keynumber[0] = (tuning.getTuning( portamento_lastnote[portamento_lastnote_ix]) / 100.0) * (1f / 128f); voice.portamento = true; } } } } public void noteOn(int noteNumber, int velocity) { noteOn(noteNumber, velocity, 0); } /* A special noteOn with delay parameter, which is used to * start note within control buffers. */ protected void noteOn(int noteNumber, int velocity, int delay) { noteNumber = restrict7Bit(noteNumber); velocity = restrict7Bit(velocity); noteOn_internal(noteNumber, velocity, delay); if (current_mixer != null) current_mixer.noteOn(noteNumber, velocity); } private void noteOn_internal(int noteNumber, int velocity, int delay) { if (velocity == 0) { noteOff_internal(noteNumber, 64); return; } synchronized (control_mutex) { if (sustain) { sustain = false; for (int i = 0; i < voices.length; i++) { if ((voices[i].sustain || voices[i].on) && voices[i].channel == channel && voices[i].active && voices[i].note == noteNumber) { voices[i].sustain = false; voices[i].on = true; voices[i].noteOff(0); } } sustain = true; } mainmixer.activity(); if (mono) { if (portamento) { boolean n_found = false; for (int i = 0; i < voices.length; i++) { if (voices[i].on && voices[i].channel == channel && voices[i].active && voices[i].releaseTriggered == false) { voices[i].portamento = true; voices[i].setNote(noteNumber); n_found = true; } } if (n_found) { portamento_lastnote[0] = noteNumber; return; } } if (controller[84] != 0) { boolean n_found = false; for (int i = 0; i < voices.length; i++) { if (voices[i].on && voices[i].channel == channel && voices[i].active && voices[i].note == controller[84] && voices[i].releaseTriggered == false) { voices[i].portamento = true; voices[i].setNote(noteNumber); n_found = true; } } controlChange(84, 0); if (n_found) return; } } if (mono) allNotesOff(); if (current_instrument == null) { current_instrument = synthesizer.findInstrument(program, bank, channel); if (current_instrument == null) return; if (current_mixer != null) mainmixer.stopMixer(current_mixer); current_mixer = current_instrument.getSourceInstrument() .getChannelMixer(this, synthesizer.getFormat()); if (current_mixer != null) mainmixer.registerMixer(current_mixer); current_director = current_instrument.getDirector(this, this); applyInstrumentCustomization();Lines 1–500 of 1579. Load more
/* * 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.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.sound.midi.MidiChannel; import javax.sound.midi.Patch; /** * Software Synthesizer MIDI channel class. * * @author Karl Helgason */ public class SoftChannel implements MidiChannel, ModelDirectedPlayer { private static boolean[] dontResetControls = new boolean[128]; static { for (int i = 0; i < dontResetControls.length; i++) dontResetControls[i] = false; dontResetControls[0] = true; // Bank Select (MSB) dontResetControls[32] = true; // Bank Select (LSB) dontResetControls[7] = true; // Channel Volume (MSB) dontResetControls[8] = true; // Balance (MSB) dontResetControls[10] = true; // Pan (MSB) dontResetControls[11] = true; // Expression (MSB) dontResetControls[91] = true; // Effects 1 Depth (default: Reverb Send) dontResetControls[92] = true; // Effects 2 Depth (default: Tremolo Depth) dontResetControls[93] = true; // Effects 3 Depth (default: Chorus Send) dontResetControls[94] = true; // Effects 4 Depth (default: Celeste [Detune] Depth) dontResetControls[95] = true; // Effects 5 Depth (default: Phaser Depth) dontResetControls[70] = true; // Sound Controller 1 (default: Sound Variation) dontResetControls[71] = true; // Sound Controller 2 (default: Timbre / Harmonic Quality) dontResetControls[72] = true; // Sound Controller 3 (default: Release Time) dontResetControls[73] = true; // Sound Controller 4 (default: Attack Time) dontResetControls[74] = true; // Sound Controller 5 (default: Brightness) dontResetControls[75] = true; // Sound Controller 6 (GM2 default: Decay Time) dontResetControls[76] = true; // Sound Controller 7 (GM2 default: Vibrato Rate) dontResetControls[77] = true; // Sound Controller 8 (GM2 default: Vibrato Depth) dontResetControls[78] = true; // Sound Controller 9 (GM2 default: Vibrato Delay) dontResetControls[79] = true; // Sound Controller 10 (GM2 default: Undefined) dontResetControls[120] = true; // All Sound Off dontResetControls[121] = true; // Reset All Controllers dontResetControls[122] = true; // Local Control On/Off dontResetControls[123] = true; // All Notes Off dontResetControls[124] = true; // Omni Mode Off dontResetControls[125] = true; // Omni Mode On dontResetControls[126] = true; // Poly Mode Off dontResetControls[127] = true; // Poly Mode On dontResetControls[6] = true; // Data Entry (MSB) dontResetControls[38] = true; // Data Entry (LSB) dontResetControls[96] = true; // Data Increment dontResetControls[97] = true; // Data Decrement dontResetControls[98] = true; // Non-Registered Parameter Number (LSB) dontResetControls[99] = true; // Non-Registered Parameter Number(MSB) dontResetControls[100] = true; // RPN = Null dontResetControls[101] = true; // RPN = Null } private static final int RPN_NULL_VALUE = (127 << 7) + 127; private int rpn_control = RPN_NULL_VALUE; private int nrpn_control = RPN_NULL_VALUE; protected double portamento_time = 1; // keyschanges per control buffer time protected int[] portamento_lastnote = new int[128]; protected int portamento_lastnote_ix = 0; private boolean portamento = false; private boolean mono = false; private boolean mute = false; private boolean solo = false; private boolean solomute = false; private Object control_mutex; private int channel; private SoftVoice[] voices; private int bank; private int program; private SoftSynthesizer synthesizer; private SoftMainMixer mainmixer; private int[] polypressure = new int[128]; private int channelpressure = 0; private int[] controller = new int[128]; private int pitchbend; private double[] co_midi_pitch = new double[1]; private double[] co_midi_channel_pressure = new double[1]; protected SoftTuning tuning = new SoftTuning(); protected int tuning_bank = 0; protected int tuning_program = 0; protected SoftInstrument current_instrument = null; protected ModelChannelMixer current_mixer = null; protected ModelDirector current_director = null; // Controller Destination Settings protected int cds_control_number = -1; protected ModelConnectionBlock[] cds_control_connections = null; protected ModelConnectionBlock[] cds_channelpressure_connections = null; protected ModelConnectionBlock[] cds_polypressure_connections = null; protected boolean sustain = false; protected boolean[][] keybasedcontroller_active = null; protected double[][] keybasedcontroller_value = null; private class MidiControlObject implements SoftControl { double[] pitch = co_midi_pitch; double[] channel_pressure = co_midi_channel_pressure; double[] poly_pressure = new double[1]; public double[] get(int instance, String name) { if (name == null) return null; if (name.equals("pitch")) return pitch; if (name.equals("channel_pressure")) return channel_pressure; if (name.equals("poly_pressure")) return poly_pressure; return null; } } private SoftControl[] co_midi = new SoftControl[128]; { for (int i = 0; i < co_midi.length; i++) { co_midi[i] = new MidiControlObject(); } } private double[][] co_midi_cc_cc = new double[128][1]; private SoftControl co_midi_cc = new SoftControl() { double[][] cc = co_midi_cc_cc; public double[] get(int instance, String name) { if (name == null) return null; return cc[Integer.parseInt(name)]; } }; Map<Integer, int[]> co_midi_rpn_rpn_i = new HashMap<Integer, int[]>(); Map<Integer, double[]> co_midi_rpn_rpn = new HashMap<Integer, double[]>(); private SoftControl co_midi_rpn = new SoftControl() { Map<Integer, double[]> rpn = co_midi_rpn_rpn; public double[] get(int instance, String name) { if (name == null) return null; int iname = Integer.parseInt(name); double[] v = rpn.get(iname); if (v == null) { v = new double[1]; rpn.put(iname, v); } return v; } }; Map<Integer, int[]> co_midi_nrpn_nrpn_i = new HashMap<Integer, int[]>(); Map<Integer, double[]> co_midi_nrpn_nrpn = new HashMap<Integer, double[]>(); private SoftControl co_midi_nrpn = new SoftControl() { Map<Integer, double[]> nrpn = co_midi_nrpn_nrpn; public double[] get(int instance, String name) { if (name == null) return null; int iname = Integer.parseInt(name); double[] v = nrpn.get(iname); if (v == null) { v = new double[1]; nrpn.put(iname, v); } return v; } }; private static int restrict7Bit(int value) { if(value < 0) return 0; if(value > 127) return 127; return value; } private static int restrict14Bit(int value) { if(value < 0) return 0; if(value > 16256) return 16256; return value; } public SoftChannel(SoftSynthesizer synth, int channel) { this.channel = channel; this.voices = synth.getVoices(); this.synthesizer = synth; this.mainmixer = synth.getMainMixer(); control_mutex = synth.control_mutex; resetAllControllers(true); } private int findFreeVoice(int x) { if(x == -1) { // x = -1 means that there where no available voice // last time we called findFreeVoice // and it hasn't changed because no audio has been // rendered in the meantime. // Therefore we have to return -1. return -1; } for (int i = x; i < voices.length; i++) if (!voices[i].active) return i; // No free voice was found, we must steal one int vmode = synthesizer.getVoiceAllocationMode(); if (vmode == 1) { // DLS Static Voice Allocation // * priority ( 10, 1-9, 11-16) // Search for channel to steal from int steal_channel = channel; for (int j = 0; j < voices.length; j++) { if (voices[j].stealer_channel == null) { if (steal_channel == 9) { steal_channel = voices[j].channel; } else { if (voices[j].channel != 9) { if (voices[j].channel > steal_channel) steal_channel = voices[j].channel; } } } } int voiceNo = -1; SoftVoice v = null; // Search for oldest voice in off state on steal_channel for (int j = 0; j < voices.length; j++) { if (voices[j].channel == steal_channel) { if (voices[j].stealer_channel == null && !voices[j].on) { if (v == null) { v = voices[j]; voiceNo = j; } if (voices[j].voiceID < v.voiceID) { v = voices[j]; voiceNo = j; } } } } // Search for oldest voice in on state on steal_channel if (voiceNo == -1) { for (int j = 0; j < voices.length; j++) { if (voices[j].channel == steal_channel) { if (voices[j].stealer_channel == null) { if (v == null) { v = voices[j]; voiceNo = j; } if (voices[j].voiceID < v.voiceID) { v = voices[j]; voiceNo = j; } } } } } return voiceNo; } else { // Default Voice Allocation // * Find voice that is on // and Find voice which has lowest voiceID ( oldest voice) // * Or find voice that is off // and Find voice which has lowest voiceID ( oldest voice) int voiceNo = -1; SoftVoice v = null; // Search for oldest voice in off state for (int j = 0; j < voices.length; j++) { if (voices[j].stealer_channel == null && !voices[j].on) { if (v == null) { v = voices[j]; voiceNo = j; } if (voices[j].voiceID < v.voiceID) { v = voices[j]; voiceNo = j; } } } // Search for oldest voice in on state if (voiceNo == -1) { for (int j = 0; j < voices.length; j++) { if (voices[j].stealer_channel == null) { if (v == null) { v = voices[j]; voiceNo = j; } if (voices[j].voiceID < v.voiceID) { v = voices[j]; voiceNo = j; } } } } return voiceNo; } } protected void initVoice(SoftVoice voice, SoftPerformer p, int voiceID, int noteNumber, int velocity, int delay, ModelConnectionBlock[] connectionBlocks, ModelChannelMixer channelmixer, boolean releaseTriggered) { if (voice.active) { // Voice is active , we must steal the voice voice.stealer_channel = this; voice.stealer_performer = p; voice.stealer_voiceID = voiceID; voice.stealer_noteNumber = noteNumber; voice.stealer_velocity = velocity; voice.stealer_extendedConnectionBlocks = connectionBlocks; voice.stealer_channelmixer = channelmixer; voice.stealer_releaseTriggered = releaseTriggered; for (int i = 0; i < voices.length; i++) if (voices[i].active && voices[i].voiceID == voice.voiceID) voices[i].soundOff(); return; } voice.extendedConnectionBlocks = connectionBlocks; voice.channelmixer = channelmixer; voice.releaseTriggered = releaseTriggered; voice.voiceID = voiceID; voice.tuning = tuning; voice.exclusiveClass = p.exclusiveClass; voice.softchannel = this; voice.channel = channel; voice.bank = bank; voice.program = program; voice.instrument = current_instrument; voice.performer = p; voice.objects.clear(); voice.objects.put("midi", co_midi[noteNumber]); voice.objects.put("midi_cc", co_midi_cc); voice.objects.put("midi_rpn", co_midi_rpn); voice.objects.put("midi_nrpn", co_midi_nrpn); voice.noteOn(noteNumber, velocity, delay); voice.setMute(mute); voice.setSoloMute(solomute); if (releaseTriggered) return; if (controller[84] != 0) { voice.co_noteon_keynumber[0] = (tuning.getTuning(controller[84]) / 100.0) * (1f / 128f); voice.portamento = true; controlChange(84, 0); } else if (portamento) { if (mono) { if (portamento_lastnote[0] != -1) { voice.co_noteon_keynumber[0] = (tuning.getTuning(portamento_lastnote[0]) / 100.0) * (1f / 128f); voice.portamento = true; controlChange(84, 0); } portamento_lastnote[0] = noteNumber; } else { if (portamento_lastnote_ix != 0) { portamento_lastnote_ix--; voice.co_noteon_keynumber[0] = (tuning.getTuning( portamento_lastnote[portamento_lastnote_ix]) / 100.0) * (1f / 128f); voice.portamento = true; } } } } public void noteOn(int noteNumber, int velocity) { noteOn(noteNumber, velocity, 0); } /* A special noteOn with delay parameter, which is used to * start note within control buffers. */ protected void noteOn(int noteNumber, int velocity, int delay) { noteNumber = restrict7Bit(noteNumber); velocity = restrict7Bit(velocity); noteOn_internal(noteNumber, velocity, delay); if (current_mixer != null) current_mixer.noteOn(noteNumber, velocity); } private void noteOn_internal(int noteNumber, int velocity, int delay) { if (velocity == 0) { noteOff_internal(noteNumber, 64); return; } synchronized (control_mutex) { if (sustain) { sustain = false; for (int i = 0; i < voices.length; i++) { if ((voices[i].sustain || voices[i].on) && voices[i].channel == channel && voices[i].active && voices[i].note == noteNumber) { voices[i].sustain = false; voices[i].on = true; voices[i].noteOff(0); } } sustain = true; } mainmixer.activity(); if (mono) { if (portamento) { boolean n_found = false; for (int i = 0; i < voices.length; i++) { if (voices[i].on && voices[i].channel == channel && voices[i].active && voices[i].releaseTriggered == false) { voices[i].portamento = true; voices[i].setNote(noteNumber); n_found = true; } } if (n_found) { portamento_lastnote[0] = noteNumber; return; } } if (controller[84] != 0) { boolean n_found = false; for (int i = 0; i < voices.length; i++) { if (voices[i].on && voices[i].channel == channel && voices[i].active && voices[i].note == controller[84] && voices[i].releaseTriggered == false) { voices[i].portamento = true; voices[i].setNote(noteNumber); n_found = true; } } controlChange(84, 0); if (n_found) return; } } if (mono) allNotesOff(); if (current_instrument == null) { current_instrument = synthesizer.findInstrument(program, bank, channel); if (current_instrument == null) return; if (current_mixer != null) mainmixer.stopMixer(current_mixer); current_mixer = current_instrument.getSourceInstrument() .getChannelMixer(this, synthesizer.getFormat()); if (current_mixer != null) mainmixer.registerMixer(current_mixer); current_director = current_instrument.getDirector(this, this); applyInstrumentCustomization();