829N/A/*
6321N/A * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
829N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
829N/A *
829N/A * This code is free software; you can redistribute it and/or modify it
829N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
829N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
829N/A *
829N/A * This code is distributed in the hope that it will be useful, but WITHOUT
829N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
829N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
829N/A * version 2 for more details (a copy is included in the LICENSE file that
829N/A * accompanied this code).
829N/A *
829N/A * You should have received a copy of the GNU General Public License version
829N/A * 2 along with this work; if not, write to the Free Software Foundation,
829N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
829N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
829N/A */
829N/Apackage com.sun.media.sound;
829N/A
829N/Aimport java.util.ArrayList;
829N/Aimport java.util.HashMap;
829N/Aimport java.util.List;
829N/Aimport java.util.Map;
829N/A
829N/Aimport javax.sound.midi.Patch;
829N/A
829N/A/**
829N/A * Soundfont instrument.
829N/A *
829N/A * @author Karl Helgason
829N/A */
6321N/Apublic final class SF2Instrument extends ModelInstrument {
829N/A
6321N/A String name = "";
6321N/A int preset = 0;
6321N/A int bank = 0;
6321N/A long library = 0;
6321N/A long genre = 0;
6321N/A long morphology = 0;
6321N/A SF2GlobalRegion globalregion = null;
6321N/A List<SF2InstrumentRegion> regions
829N/A = new ArrayList<SF2InstrumentRegion>();
829N/A
829N/A public SF2Instrument() {
829N/A super(null, null, null, null);
829N/A }
829N/A
829N/A public SF2Instrument(SF2Soundbank soundbank) {
829N/A super(soundbank, null, null, null);
829N/A }
829N/A
829N/A public String getName() {
829N/A return name;
829N/A }
829N/A
829N/A public void setName(String name) {
829N/A this.name = name;
829N/A }
829N/A
829N/A public Patch getPatch() {
829N/A if (bank == 128)
829N/A return new ModelPatch(0, preset, true);
829N/A else
829N/A return new ModelPatch(bank << 7, preset, false);
829N/A }
829N/A
829N/A public void setPatch(Patch patch) {
829N/A if (patch instanceof ModelPatch && ((ModelPatch) patch).isPercussion()) {
829N/A bank = 128;
829N/A preset = patch.getProgram();
829N/A } else {
829N/A bank = patch.getBank() >> 7;
829N/A preset = patch.getProgram();
829N/A }
829N/A }
829N/A
829N/A public Object getData() {
829N/A return null;
829N/A }
829N/A
829N/A public long getGenre() {
829N/A return genre;
829N/A }
829N/A
829N/A public void setGenre(long genre) {
829N/A this.genre = genre;
829N/A }
829N/A
829N/A public long getLibrary() {
829N/A return library;
829N/A }
829N/A
829N/A public void setLibrary(long library) {
829N/A this.library = library;
829N/A }
829N/A
829N/A public long getMorphology() {
829N/A return morphology;
829N/A }
829N/A
829N/A public void setMorphology(long morphology) {
829N/A this.morphology = morphology;
829N/A }
829N/A
829N/A public List<SF2InstrumentRegion> getRegions() {
829N/A return regions;
829N/A }
829N/A
829N/A public SF2GlobalRegion getGlobalRegion() {
829N/A return globalregion;
829N/A }
829N/A
829N/A public void setGlobalZone(SF2GlobalRegion zone) {
829N/A globalregion = zone;
829N/A }
829N/A
829N/A public String toString() {
829N/A if (bank == 128)
829N/A return "Drumkit: " + name + " preset #" + preset;
829N/A else
829N/A return "Instrument: " + name + " bank #" + bank
829N/A + " preset #" + preset;
829N/A }
829N/A
829N/A public ModelPerformer[] getPerformers() {
829N/A int performercount = 0;
829N/A for (SF2InstrumentRegion presetzone : regions)
829N/A performercount += presetzone.getLayer().getRegions().size();
829N/A ModelPerformer[] performers = new ModelPerformer[performercount];
829N/A int pi = 0;
829N/A
829N/A SF2GlobalRegion presetglobal = globalregion;
829N/A for (SF2InstrumentRegion presetzone : regions) {
829N/A Map<Integer, Short> pgenerators = new HashMap<Integer, Short>();
829N/A pgenerators.putAll(presetzone.getGenerators());
829N/A if (presetglobal != null)
829N/A pgenerators.putAll(presetglobal.getGenerators());
829N/A
829N/A SF2Layer layer = presetzone.getLayer();
829N/A SF2GlobalRegion layerglobal = layer.getGlobalRegion();
829N/A for (SF2LayerRegion layerzone : layer.getRegions()) {
829N/A ModelPerformer performer = new ModelPerformer();
829N/A if (layerzone.getSample() != null)
829N/A performer.setName(layerzone.getSample().getName());
829N/A else
829N/A performer.setName(layer.getName());
829N/A
829N/A performers[pi++] = performer;
829N/A
829N/A int keyfrom = 0;
829N/A int keyto = 127;
829N/A int velfrom = 0;
829N/A int velto = 127;
829N/A
829N/A if (layerzone.contains(SF2Region.GENERATOR_EXCLUSIVECLASS)) {
829N/A performer.setExclusiveClass(layerzone.getInteger(
829N/A SF2Region.GENERATOR_EXCLUSIVECLASS));
829N/A }
829N/A if (layerzone.contains(SF2Region.GENERATOR_KEYRANGE)) {
829N/A byte[] bytes = layerzone.getBytes(
829N/A SF2Region.GENERATOR_KEYRANGE);
829N/A if (bytes[0] >= 0)
829N/A if (bytes[0] > keyfrom)
829N/A keyfrom = bytes[0];
829N/A if (bytes[1] >= 0)
829N/A if (bytes[1] < keyto)
829N/A keyto = bytes[1];
829N/A }
829N/A if (layerzone.contains(SF2Region.GENERATOR_VELRANGE)) {
829N/A byte[] bytes = layerzone.getBytes(
829N/A SF2Region.GENERATOR_VELRANGE);
829N/A if (bytes[0] >= 0)
829N/A if (bytes[0] > velfrom)
829N/A velfrom = bytes[0];
829N/A if (bytes[1] >= 0)
829N/A if (bytes[1] < velto)
829N/A velto = bytes[1];
829N/A }
829N/A if (presetzone.contains(SF2Region.GENERATOR_KEYRANGE)) {
829N/A byte[] bytes = presetzone.getBytes(
829N/A SF2Region.GENERATOR_KEYRANGE);
829N/A if (bytes[0] > keyfrom)
829N/A keyfrom = bytes[0];
829N/A if (bytes[1] < keyto)
829N/A keyto = bytes[1];
829N/A }
829N/A if (presetzone.contains(SF2Region.GENERATOR_VELRANGE)) {
829N/A byte[] bytes = presetzone.getBytes(
829N/A SF2Region.GENERATOR_VELRANGE);
829N/A if (bytes[0] > velfrom)
829N/A velfrom = bytes[0];
829N/A if (bytes[1] < velto)
829N/A velto = bytes[1];
829N/A }
829N/A performer.setKeyFrom(keyfrom);
829N/A performer.setKeyTo(keyto);
829N/A performer.setVelFrom(velfrom);
829N/A performer.setVelTo(velto);
829N/A
829N/A int startAddrsOffset = layerzone.getShort(
829N/A SF2Region.GENERATOR_STARTADDRSOFFSET);
829N/A int endAddrsOffset = layerzone.getShort(
829N/A SF2Region.GENERATOR_ENDADDRSOFFSET);
829N/A int startloopAddrsOffset = layerzone.getShort(
829N/A SF2Region.GENERATOR_STARTLOOPADDRSOFFSET);
829N/A int endloopAddrsOffset = layerzone.getShort(
829N/A SF2Region.GENERATOR_ENDLOOPADDRSOFFSET);
829N/A
829N/A startAddrsOffset += layerzone.getShort(
829N/A SF2Region.GENERATOR_STARTADDRSCOARSEOFFSET) * 32768;
829N/A endAddrsOffset += layerzone.getShort(
829N/A SF2Region.GENERATOR_ENDADDRSCOARSEOFFSET) * 32768;
829N/A startloopAddrsOffset += layerzone.getShort(
829N/A SF2Region.GENERATOR_STARTLOOPADDRSCOARSEOFFSET) * 32768;
829N/A endloopAddrsOffset += layerzone.getShort(
829N/A SF2Region.GENERATOR_ENDLOOPADDRSCOARSEOFFSET) * 32768;
829N/A startloopAddrsOffset -= startAddrsOffset;
829N/A endloopAddrsOffset -= startAddrsOffset;
829N/A
829N/A SF2Sample sample = layerzone.getSample();
829N/A int rootkey = sample.originalPitch;
829N/A if (layerzone.getShort(SF2Region.GENERATOR_OVERRIDINGROOTKEY) != -1) {
829N/A rootkey = layerzone.getShort(
829N/A SF2Region.GENERATOR_OVERRIDINGROOTKEY);
829N/A }
829N/A float pitchcorrection = (-rootkey * 100) + sample.pitchCorrection;
829N/A ModelByteBuffer buff = sample.getDataBuffer();
829N/A ModelByteBuffer buff24 = sample.getData24Buffer();
829N/A
829N/A if (startAddrsOffset != 0 || endAddrsOffset != 0) {
829N/A buff = buff.subbuffer(startAddrsOffset * 2,
829N/A buff.capacity() + endAddrsOffset * 2);
829N/A if (buff24 != null) {
829N/A buff24 = buff24.subbuffer(startAddrsOffset,
829N/A buff24.capacity() + endAddrsOffset);
829N/A }
829N/A
829N/A /*
829N/A if (startAddrsOffset < 0)
829N/A startAddrsOffset = 0;
829N/A if (endAddrsOffset > (buff.capacity()/2-startAddrsOffset))
829N/A startAddrsOffset = (int)buff.capacity()/2-startAddrsOffset;
829N/A byte[] data = buff.array();
829N/A int off = (int)buff.arrayOffset() + startAddrsOffset*2;
829N/A int len = (int)buff.capacity() + endAddrsOffset*2;
829N/A if (off+len > data.length)
829N/A len = data.length - off;
829N/A buff = new ModelByteBuffer(data, off, len);
829N/A if(buff24 != null) {
829N/A data = buff.array();
829N/A off = (int)buff.arrayOffset() + startAddrsOffset;
829N/A len = (int)buff.capacity() + endAddrsOffset;
829N/A buff24 = new ModelByteBuffer(data, off, len);
829N/A }
829N/A */
829N/A }
829N/A
829N/A ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
829N/A buff, sample.getFormat(), pitchcorrection);
829N/A if (buff24 != null)
829N/A osc.set8BitExtensionBuffer(buff24);
829N/A
829N/A Map<Integer, Short> generators = new HashMap<Integer, Short>();
829N/A if (layerglobal != null)
829N/A generators.putAll(layerglobal.getGenerators());
829N/A generators.putAll(layerzone.getGenerators());
829N/A for (Map.Entry<Integer, Short> gen : pgenerators.entrySet()) {
829N/A short val;
829N/A if (!generators.containsKey(gen.getKey()))
829N/A val = layerzone.getShort(gen.getKey());
829N/A else
829N/A val = generators.get(gen.getKey());
829N/A val += gen.getValue();
829N/A generators.put(gen.getKey(), val);
829N/A }
829N/A
829N/A // SampleMode:
829N/A // 0 indicates a sound reproduced with no loop
829N/A // 1 indicates a sound which loops continuously
829N/A // 2 is unused but should be interpreted as indicating no loop
829N/A // 3 indicates a sound which loops for the duration of key
829N/A // depression then proceeds to play the remainder of the sample.
829N/A int sampleMode = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_SAMPLEMODES);
829N/A if ((sampleMode == 1) || (sampleMode == 3)) {
829N/A if (sample.startLoop >= 0 && sample.endLoop > 0) {
829N/A osc.setLoopStart((int)(sample.startLoop
829N/A + startloopAddrsOffset));
829N/A osc.setLoopLength((int)(sample.endLoop - sample.startLoop
829N/A + endloopAddrsOffset - startloopAddrsOffset));
829N/A if (sampleMode == 1)
829N/A osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);
829N/A if (sampleMode == 3)
829N/A osc.setLoopType(ModelWavetable.LOOP_TYPE_RELEASE);
829N/A }
829N/A }
829N/A performer.getOscillators().add(osc);
829N/A
829N/A
829N/A short volDelay = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_DELAYVOLENV);
829N/A short volAttack = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_ATTACKVOLENV);
829N/A short volHold = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_HOLDVOLENV);
829N/A short volDecay = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_DECAYVOLENV);
829N/A short volSustain = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_SUSTAINVOLENV);
829N/A short volRelease = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_RELEASEVOLENV);
829N/A
829N/A if (volHold != -12000) {
829N/A short volKeyNumToHold = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_KEYNUMTOVOLENVHOLD);
829N/A volHold += 60 * volKeyNumToHold;
829N/A float fvalue = -volKeyNumToHold * 128;
829N/A ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
829N/A ModelIdentifier dest = ModelDestination.DESTINATION_EG1_HOLD;
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(new ModelSource(src), fvalue,
829N/A new ModelDestination(dest)));
829N/A }
829N/A if (volDecay != -12000) {
829N/A short volKeyNumToDecay = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_KEYNUMTOVOLENVDECAY);
829N/A volDecay += 60 * volKeyNumToDecay;
829N/A float fvalue = -volKeyNumToDecay * 128;
829N/A ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
829N/A ModelIdentifier dest = ModelDestination.DESTINATION_EG1_DECAY;
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(new ModelSource(src), fvalue,
829N/A new ModelDestination(dest)));
829N/A }
829N/A
829N/A addTimecentValue(performer,
829N/A ModelDestination.DESTINATION_EG1_DELAY, volDelay);
829N/A addTimecentValue(performer,
829N/A ModelDestination.DESTINATION_EG1_ATTACK, volAttack);
829N/A addTimecentValue(performer,
829N/A ModelDestination.DESTINATION_EG1_HOLD, volHold);
829N/A addTimecentValue(performer,
829N/A ModelDestination.DESTINATION_EG1_DECAY, volDecay);
829N/A //float fvolsustain = (960-volSustain)*(1000.0f/960.0f);
829N/A
829N/A volSustain = (short)(1000 - volSustain);
829N/A if (volSustain < 0)
829N/A volSustain = 0;
829N/A if (volSustain > 1000)
829N/A volSustain = 1000;
829N/A
829N/A addValue(performer,
829N/A ModelDestination.DESTINATION_EG1_SUSTAIN, volSustain);
829N/A addTimecentValue(performer,
829N/A ModelDestination.DESTINATION_EG1_RELEASE, volRelease);
829N/A
829N/A if (getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_MODENVTOFILTERFC) != 0
829N/A || getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_MODENVTOPITCH) != 0) {
829N/A short modDelay = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_DELAYMODENV);
829N/A short modAttack = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_ATTACKMODENV);
829N/A short modHold = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_HOLDMODENV);
829N/A short modDecay = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_DECAYMODENV);
829N/A short modSustain = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_SUSTAINMODENV);
829N/A short modRelease = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_RELEASEMODENV);
829N/A
829N/A
829N/A if (modHold != -12000) {
829N/A short modKeyNumToHold = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_KEYNUMTOMODENVHOLD);
829N/A modHold += 60 * modKeyNumToHold;
829N/A float fvalue = -modKeyNumToHold * 128;
829N/A ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
829N/A ModelIdentifier dest = ModelDestination.DESTINATION_EG2_HOLD;
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(new ModelSource(src),
829N/A fvalue, new ModelDestination(dest)));
829N/A }
829N/A if (modDecay != -12000) {
829N/A short modKeyNumToDecay = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_KEYNUMTOMODENVDECAY);
829N/A modDecay += 60 * modKeyNumToDecay;
829N/A float fvalue = -modKeyNumToDecay * 128;
829N/A ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
829N/A ModelIdentifier dest = ModelDestination.DESTINATION_EG2_DECAY;
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(new ModelSource(src),
829N/A fvalue, new ModelDestination(dest)));
829N/A }
829N/A
829N/A addTimecentValue(performer,
829N/A ModelDestination.DESTINATION_EG2_DELAY, modDelay);
829N/A addTimecentValue(performer,
829N/A ModelDestination.DESTINATION_EG2_ATTACK, modAttack);
829N/A addTimecentValue(performer,
829N/A ModelDestination.DESTINATION_EG2_HOLD, modHold);
829N/A addTimecentValue(performer,
829N/A ModelDestination.DESTINATION_EG2_DECAY, modDecay);
829N/A if (modSustain < 0)
829N/A modSustain = 0;
829N/A if (modSustain > 1000)
829N/A modSustain = 1000;
829N/A addValue(performer, ModelDestination.DESTINATION_EG2_SUSTAIN,
829N/A 1000 - modSustain);
829N/A addTimecentValue(performer,
829N/A ModelDestination.DESTINATION_EG2_RELEASE, modRelease);
829N/A
829N/A if (getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_MODENVTOFILTERFC) != 0) {
829N/A double fvalue = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_MODENVTOFILTERFC);
829N/A ModelIdentifier src = ModelSource.SOURCE_EG2;
829N/A ModelIdentifier dest
829N/A = ModelDestination.DESTINATION_FILTER_FREQ;
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(new ModelSource(src),
829N/A fvalue, new ModelDestination(dest)));
829N/A }
829N/A
829N/A if (getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_MODENVTOPITCH) != 0) {
829N/A double fvalue = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_MODENVTOPITCH);
829N/A ModelIdentifier src = ModelSource.SOURCE_EG2;
829N/A ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(new ModelSource(src),
829N/A fvalue, new ModelDestination(dest)));
829N/A }
829N/A
829N/A }
829N/A
829N/A if (getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_MODLFOTOFILTERFC) != 0
829N/A || getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_MODLFOTOPITCH) != 0
829N/A || getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_MODLFOTOVOLUME) != 0) {
829N/A short lfo_freq = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_FREQMODLFO);
829N/A short lfo_delay = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_DELAYMODLFO);
829N/A addTimecentValue(performer,
829N/A ModelDestination.DESTINATION_LFO1_DELAY, lfo_delay);
829N/A addValue(performer,
829N/A ModelDestination.DESTINATION_LFO1_FREQ, lfo_freq);
829N/A }
829N/A
829N/A short vib_freq = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_FREQVIBLFO);
829N/A short vib_delay = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_DELAYVIBLFO);
829N/A addTimecentValue(performer,
829N/A ModelDestination.DESTINATION_LFO2_DELAY, vib_delay);
829N/A addValue(performer,
829N/A ModelDestination.DESTINATION_LFO2_FREQ, vib_freq);
829N/A
829N/A
829N/A if (getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_VIBLFOTOPITCH) != 0) {
829N/A double fvalue = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_VIBLFOTOPITCH);
829N/A ModelIdentifier src = ModelSource.SOURCE_LFO2;
829N/A ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(
829N/A new ModelSource(src,
829N/A ModelStandardTransform.DIRECTION_MIN2MAX,
829N/A ModelStandardTransform.POLARITY_BIPOLAR),
829N/A fvalue, new ModelDestination(dest)));
829N/A }
829N/A
829N/A if (getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_MODLFOTOFILTERFC) != 0) {
829N/A double fvalue = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_MODLFOTOFILTERFC);
829N/A ModelIdentifier src = ModelSource.SOURCE_LFO1;
829N/A ModelIdentifier dest = ModelDestination.DESTINATION_FILTER_FREQ;
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(
829N/A new ModelSource(src,
829N/A ModelStandardTransform.DIRECTION_MIN2MAX,
829N/A ModelStandardTransform.POLARITY_BIPOLAR),
829N/A fvalue, new ModelDestination(dest)));
829N/A }
829N/A
829N/A if (getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_MODLFOTOPITCH) != 0) {
829N/A double fvalue = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_MODLFOTOPITCH);
829N/A ModelIdentifier src = ModelSource.SOURCE_LFO1;
829N/A ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(
829N/A new ModelSource(src,
829N/A ModelStandardTransform.DIRECTION_MIN2MAX,
829N/A ModelStandardTransform.POLARITY_BIPOLAR),
829N/A fvalue, new ModelDestination(dest)));
829N/A }
829N/A
829N/A if (getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_MODLFOTOVOLUME) != 0) {
829N/A double fvalue = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_MODLFOTOVOLUME);
829N/A ModelIdentifier src = ModelSource.SOURCE_LFO1;
829N/A ModelIdentifier dest = ModelDestination.DESTINATION_GAIN;
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(
829N/A new ModelSource(src,
829N/A ModelStandardTransform.DIRECTION_MIN2MAX,
829N/A ModelStandardTransform.POLARITY_BIPOLAR),
829N/A fvalue, new ModelDestination(dest)));
829N/A }
829N/A
829N/A if (layerzone.getShort(SF2Region.GENERATOR_KEYNUM) != -1) {
829N/A double val = layerzone.getShort(SF2Region.GENERATOR_KEYNUM)/128.0;
829N/A addValue(performer, ModelDestination.DESTINATION_KEYNUMBER, val);
829N/A }
829N/A
829N/A if (layerzone.getShort(SF2Region.GENERATOR_VELOCITY) != -1) {
829N/A double val = layerzone.getShort(SF2Region.GENERATOR_VELOCITY)
829N/A / 128.0;
829N/A addValue(performer, ModelDestination.DESTINATION_VELOCITY, val);
829N/A }
829N/A
829N/A if (getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_INITIALFILTERFC) < 13500) {
829N/A short filter_freq = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_INITIALFILTERFC);
829N/A short filter_q = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_INITIALFILTERQ);
829N/A addValue(performer,
829N/A ModelDestination.DESTINATION_FILTER_FREQ, filter_freq);
829N/A addValue(performer,
829N/A ModelDestination.DESTINATION_FILTER_Q, filter_q);
829N/A }
829N/A
829N/A int tune = 100 * getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_COARSETUNE);
829N/A tune += getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_FINETUNE);
829N/A if (tune != 0) {
829N/A addValue(performer,
829N/A ModelDestination.DESTINATION_PITCH, (short) tune);
829N/A }
829N/A if (getGeneratorValue(generators, SF2Region.GENERATOR_PAN) != 0) {
829N/A short val = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_PAN);
829N/A addValue(performer, ModelDestination.DESTINATION_PAN, val);
829N/A }
829N/A if (getGeneratorValue(generators, SF2Region.GENERATOR_INITIALATTENUATION) != 0) {
829N/A short val = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_INITIALATTENUATION);
829N/A addValue(performer,
829N/A ModelDestination.DESTINATION_GAIN, -0.376287f * val);
829N/A }
829N/A if (getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_CHORUSEFFECTSSEND) != 0) {
829N/A short val = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_CHORUSEFFECTSSEND);
829N/A addValue(performer, ModelDestination.DESTINATION_CHORUS, val);
829N/A }
829N/A if (getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_REVERBEFFECTSSEND) != 0) {
829N/A short val = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_REVERBEFFECTSSEND);
829N/A addValue(performer, ModelDestination.DESTINATION_REVERB, val);
829N/A }
829N/A if (getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_SCALETUNING) != 100) {
829N/A short fvalue = getGeneratorValue(generators,
829N/A SF2Region.GENERATOR_SCALETUNING);
829N/A if (fvalue == 0) {
829N/A ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(null, rootkey * 100,
829N/A new ModelDestination(dest)));
829N/A } else {
829N/A ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(null, rootkey * (100 - fvalue),
829N/A new ModelDestination(dest)));
829N/A }
829N/A
829N/A ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
829N/A ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(new ModelSource(src),
829N/A 128 * fvalue, new ModelDestination(dest)));
829N/A
829N/A }
829N/A
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(
829N/A new ModelSource(ModelSource.SOURCE_NOTEON_VELOCITY,
829N/A new ModelTransform() {
829N/A public double transform(double value) {
829N/A if (value < 0.5)
829N/A return 1 - value * 2;
829N/A else
829N/A return 0;
829N/A }
829N/A }),
829N/A -2400,
829N/A new ModelDestination(
829N/A ModelDestination.DESTINATION_FILTER_FREQ)));
829N/A
829N/A
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(
829N/A new ModelSource(ModelSource.SOURCE_LFO2,
829N/A ModelStandardTransform.DIRECTION_MIN2MAX,
829N/A ModelStandardTransform.POLARITY_BIPOLAR,
829N/A ModelStandardTransform.TRANSFORM_LINEAR),
829N/A new ModelSource(new ModelIdentifier("midi_cc", "1", 0),
829N/A ModelStandardTransform.DIRECTION_MIN2MAX,
829N/A ModelStandardTransform.POLARITY_UNIPOLAR,
829N/A ModelStandardTransform.TRANSFORM_LINEAR),
829N/A 50, new ModelDestination(
829N/A ModelDestination.DESTINATION_PITCH)));
829N/A
829N/A if (layer.getGlobalRegion() != null) {
829N/A for (SF2Modulator modulator
829N/A : layer.getGlobalRegion().getModulators()) {
829N/A convertModulator(performer, modulator);
829N/A }
829N/A }
829N/A for (SF2Modulator modulator : layerzone.getModulators())
829N/A convertModulator(performer, modulator);
829N/A
829N/A if (presetglobal != null) {
829N/A for (SF2Modulator modulator : presetglobal.getModulators())
829N/A convertModulator(performer, modulator);
829N/A }
829N/A for (SF2Modulator modulator : presetzone.getModulators())
829N/A convertModulator(performer, modulator);
829N/A
829N/A }
829N/A }
829N/A return performers;
829N/A }
829N/A
829N/A private void convertModulator(ModelPerformer performer,
829N/A SF2Modulator modulator) {
829N/A ModelSource src1 = convertSource(modulator.getSourceOperator());
829N/A ModelSource src2 = convertSource(modulator.getAmountSourceOperator());
829N/A if (src1 == null && modulator.getSourceOperator() != 0)
829N/A return;
829N/A if (src2 == null && modulator.getAmountSourceOperator() != 0)
829N/A return;
829N/A double amount = modulator.getAmount();
829N/A double[] amountcorrection = new double[1];
829N/A ModelSource[] extrasrc = new ModelSource[1];
829N/A amountcorrection[0] = 1;
829N/A ModelDestination dst = convertDestination(
829N/A modulator.getDestinationOperator(), amountcorrection, extrasrc);
829N/A amount *= amountcorrection[0];
829N/A if (dst == null)
829N/A return;
829N/A if (modulator.getTransportOperator() == SF2Modulator.TRANSFORM_ABSOLUTE) {
829N/A ((ModelStandardTransform)dst.getTransform()).setTransform(
829N/A ModelStandardTransform.TRANSFORM_ABSOLUTE);
829N/A }
829N/A ModelConnectionBlock conn = new ModelConnectionBlock(src1, src2, amount, dst);
829N/A if (extrasrc[0] != null)
829N/A conn.addSource(extrasrc[0]);
829N/A performer.getConnectionBlocks().add(conn);
829N/A
829N/A }
829N/A
829N/A private static ModelSource convertSource(int src) {
829N/A if (src == 0)
829N/A return null;
829N/A ModelIdentifier id = null;
829N/A int idsrc = src & 0x7F;
829N/A if ((src & SF2Modulator.SOURCE_MIDI_CONTROL) != 0) {
829N/A id = new ModelIdentifier("midi_cc", Integer.toString(idsrc));
829N/A } else {
829N/A if (idsrc == SF2Modulator.SOURCE_NOTE_ON_VELOCITY)
829N/A id = ModelSource.SOURCE_NOTEON_VELOCITY;
829N/A if (idsrc == SF2Modulator.SOURCE_NOTE_ON_KEYNUMBER)
829N/A id = ModelSource.SOURCE_NOTEON_KEYNUMBER;
829N/A if (idsrc == SF2Modulator.SOURCE_POLY_PRESSURE)
829N/A id = ModelSource.SOURCE_MIDI_POLY_PRESSURE;
829N/A if (idsrc == SF2Modulator.SOURCE_CHANNEL_PRESSURE)
829N/A id = ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;
829N/A if (idsrc == SF2Modulator.SOURCE_PITCH_WHEEL)
829N/A id = ModelSource.SOURCE_MIDI_PITCH;
829N/A if (idsrc == SF2Modulator.SOURCE_PITCH_SENSITIVITY)
829N/A id = new ModelIdentifier("midi_rpn", "0");
829N/A }
829N/A if (id == null)
829N/A return null;
829N/A
829N/A ModelSource msrc = new ModelSource(id);
829N/A ModelStandardTransform transform
829N/A = (ModelStandardTransform) msrc.getTransform();
829N/A
829N/A if ((SF2Modulator.SOURCE_DIRECTION_MAX_MIN & src) != 0)
829N/A transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
829N/A else
829N/A transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
829N/A
829N/A if ((SF2Modulator.SOURCE_POLARITY_BIPOLAR & src) != 0)
829N/A transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
829N/A else
829N/A transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
829N/A
829N/A if ((SF2Modulator.SOURCE_TYPE_CONCAVE & src) != 0)
829N/A transform.setTransform(ModelStandardTransform.TRANSFORM_CONCAVE);
829N/A if ((SF2Modulator.SOURCE_TYPE_CONVEX & src) != 0)
829N/A transform.setTransform(ModelStandardTransform.TRANSFORM_CONVEX);
829N/A if ((SF2Modulator.SOURCE_TYPE_SWITCH & src) != 0)
829N/A transform.setTransform(ModelStandardTransform.TRANSFORM_SWITCH);
829N/A
829N/A return msrc;
829N/A }
829N/A
6321N/A static ModelDestination convertDestination(int dst,
829N/A double[] amountcorrection, ModelSource[] extrasrc) {
829N/A ModelIdentifier id = null;
829N/A switch (dst) {
829N/A case SF2Region.GENERATOR_INITIALFILTERFC:
829N/A id = ModelDestination.DESTINATION_FILTER_FREQ;
829N/A break;
829N/A case SF2Region.GENERATOR_INITIALFILTERQ:
829N/A id = ModelDestination.DESTINATION_FILTER_Q;
829N/A break;
829N/A case SF2Region.GENERATOR_CHORUSEFFECTSSEND:
829N/A id = ModelDestination.DESTINATION_CHORUS;
829N/A break;
829N/A case SF2Region.GENERATOR_REVERBEFFECTSSEND:
829N/A id = ModelDestination.DESTINATION_REVERB;
829N/A break;
829N/A case SF2Region.GENERATOR_PAN:
829N/A id = ModelDestination.DESTINATION_PAN;
829N/A break;
829N/A case SF2Region.GENERATOR_DELAYMODLFO:
829N/A id = ModelDestination.DESTINATION_LFO1_DELAY;
829N/A break;
829N/A case SF2Region.GENERATOR_FREQMODLFO:
829N/A id = ModelDestination.DESTINATION_LFO1_FREQ;
829N/A break;
829N/A case SF2Region.GENERATOR_DELAYVIBLFO:
829N/A id = ModelDestination.DESTINATION_LFO2_DELAY;
829N/A break;
829N/A case SF2Region.GENERATOR_FREQVIBLFO:
829N/A id = ModelDestination.DESTINATION_LFO2_FREQ;
829N/A break;
829N/A
829N/A case SF2Region.GENERATOR_DELAYMODENV:
829N/A id = ModelDestination.DESTINATION_EG2_DELAY;
829N/A break;
829N/A case SF2Region.GENERATOR_ATTACKMODENV:
829N/A id = ModelDestination.DESTINATION_EG2_ATTACK;
829N/A break;
829N/A case SF2Region.GENERATOR_HOLDMODENV:
829N/A id = ModelDestination.DESTINATION_EG2_HOLD;
829N/A break;
829N/A case SF2Region.GENERATOR_DECAYMODENV:
829N/A id = ModelDestination.DESTINATION_EG2_DECAY;
829N/A break;
829N/A case SF2Region.GENERATOR_SUSTAINMODENV:
829N/A id = ModelDestination.DESTINATION_EG2_SUSTAIN;
829N/A amountcorrection[0] = -1;
829N/A break;
829N/A case SF2Region.GENERATOR_RELEASEMODENV:
829N/A id = ModelDestination.DESTINATION_EG2_RELEASE;
829N/A break;
829N/A case SF2Region.GENERATOR_DELAYVOLENV:
829N/A id = ModelDestination.DESTINATION_EG1_DELAY;
829N/A break;
829N/A case SF2Region.GENERATOR_ATTACKVOLENV:
829N/A id = ModelDestination.DESTINATION_EG1_ATTACK;
829N/A break;
829N/A case SF2Region.GENERATOR_HOLDVOLENV:
829N/A id = ModelDestination.DESTINATION_EG1_HOLD;
829N/A break;
829N/A case SF2Region.GENERATOR_DECAYVOLENV:
829N/A id = ModelDestination.DESTINATION_EG1_DECAY;
829N/A break;
829N/A case SF2Region.GENERATOR_SUSTAINVOLENV:
829N/A id = ModelDestination.DESTINATION_EG1_SUSTAIN;
829N/A amountcorrection[0] = -1;
829N/A break;
829N/A case SF2Region.GENERATOR_RELEASEVOLENV:
829N/A id = ModelDestination.DESTINATION_EG1_RELEASE;
829N/A break;
829N/A case SF2Region.GENERATOR_KEYNUM:
829N/A id = ModelDestination.DESTINATION_KEYNUMBER;
829N/A break;
829N/A case SF2Region.GENERATOR_VELOCITY:
829N/A id = ModelDestination.DESTINATION_VELOCITY;
829N/A break;
829N/A
829N/A case SF2Region.GENERATOR_COARSETUNE:
829N/A amountcorrection[0] = 100;
829N/A id = ModelDestination.DESTINATION_PITCH;
829N/A break;
829N/A
829N/A case SF2Region.GENERATOR_FINETUNE:
829N/A id = ModelDestination.DESTINATION_PITCH;
829N/A break;
829N/A
829N/A case SF2Region.GENERATOR_INITIALATTENUATION:
829N/A id = ModelDestination.DESTINATION_GAIN;
829N/A amountcorrection[0] = -0.376287f;
829N/A break;
829N/A
829N/A case SF2Region.GENERATOR_VIBLFOTOPITCH:
829N/A id = ModelDestination.DESTINATION_PITCH;
829N/A extrasrc[0] = new ModelSource(
829N/A ModelSource.SOURCE_LFO2,
829N/A ModelStandardTransform.DIRECTION_MIN2MAX,
829N/A ModelStandardTransform.POLARITY_BIPOLAR);
829N/A break;
829N/A
829N/A case SF2Region.GENERATOR_MODLFOTOPITCH:
829N/A id = ModelDestination.DESTINATION_PITCH;
829N/A extrasrc[0] = new ModelSource(
829N/A ModelSource.SOURCE_LFO1,
829N/A ModelStandardTransform.DIRECTION_MIN2MAX,
829N/A ModelStandardTransform.POLARITY_BIPOLAR);
829N/A break;
829N/A
829N/A case SF2Region.GENERATOR_MODLFOTOFILTERFC:
829N/A id = ModelDestination.DESTINATION_FILTER_FREQ;
829N/A extrasrc[0] = new ModelSource(
829N/A ModelSource.SOURCE_LFO1,
829N/A ModelStandardTransform.DIRECTION_MIN2MAX,
829N/A ModelStandardTransform.POLARITY_BIPOLAR);
829N/A break;
829N/A
829N/A case SF2Region.GENERATOR_MODLFOTOVOLUME:
829N/A id = ModelDestination.DESTINATION_GAIN;
829N/A amountcorrection[0] = -0.376287f;
829N/A extrasrc[0] = new ModelSource(
829N/A ModelSource.SOURCE_LFO1,
829N/A ModelStandardTransform.DIRECTION_MIN2MAX,
829N/A ModelStandardTransform.POLARITY_BIPOLAR);
829N/A break;
829N/A
829N/A case SF2Region.GENERATOR_MODENVTOPITCH:
829N/A id = ModelDestination.DESTINATION_PITCH;
829N/A extrasrc[0] = new ModelSource(
829N/A ModelSource.SOURCE_EG2,
829N/A ModelStandardTransform.DIRECTION_MIN2MAX,
829N/A ModelStandardTransform.POLARITY_BIPOLAR);
829N/A break;
829N/A
829N/A case SF2Region.GENERATOR_MODENVTOFILTERFC:
829N/A id = ModelDestination.DESTINATION_FILTER_FREQ;
829N/A extrasrc[0] = new ModelSource(
829N/A ModelSource.SOURCE_EG2,
829N/A ModelStandardTransform.DIRECTION_MIN2MAX,
829N/A ModelStandardTransform.POLARITY_BIPOLAR);
829N/A break;
829N/A
829N/A default:
829N/A break;
829N/A }
829N/A if (id != null)
829N/A return new ModelDestination(id);
829N/A return null;
829N/A }
829N/A
829N/A private void addTimecentValue(ModelPerformer performer,
829N/A ModelIdentifier dest, short value) {
829N/A double fvalue;
829N/A if (value == -12000)
829N/A fvalue = Double.NEGATIVE_INFINITY;
829N/A else
829N/A fvalue = value;
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(fvalue, new ModelDestination(dest)));
829N/A }
829N/A
829N/A private void addValue(ModelPerformer performer,
829N/A ModelIdentifier dest, short value) {
829N/A double fvalue = value;
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(fvalue, new ModelDestination(dest)));
829N/A }
829N/A
829N/A private void addValue(ModelPerformer performer,
829N/A ModelIdentifier dest, double value) {
829N/A double fvalue = value;
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(fvalue, new ModelDestination(dest)));
829N/A }
829N/A
829N/A private short getGeneratorValue(Map<Integer, Short> generators, int gen) {
829N/A if (generators.containsKey(gen))
829N/A return generators.get(gen);
829N/A return SF2Region.getDefaultValue(gen);
829N/A }
829N/A}