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;
3957N/Aimport java.util.Arrays;
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 * This class is used to store information to describe instrument.
829N/A * It contains list of regions and modulators.
829N/A * It is stored inside a "ins " List Chunk inside DLS files.
829N/A * In the DLS documentation a modulator is called articulator.
829N/A *
829N/A * @author Karl Helgason
829N/A */
6321N/Apublic final class DLSInstrument extends ModelInstrument {
829N/A
6321N/A int preset = 0;
6321N/A int bank = 0;
6321N/A boolean druminstrument = false;
6321N/A byte[] guid = null;
6321N/A DLSInfo info = new DLSInfo();
6321N/A List<DLSRegion> regions = new ArrayList<DLSRegion>();
6321N/A List<DLSModulator> modulators = new ArrayList<DLSModulator>();
829N/A
829N/A public DLSInstrument() {
829N/A super(null, null, null, null);
829N/A }
829N/A
829N/A public DLSInstrument(DLSSoundbank soundbank) {
829N/A super(soundbank, null, null, null);
829N/A }
829N/A
829N/A public DLSInfo getInfo() {
829N/A return info;
829N/A }
829N/A
829N/A public String getName() {
829N/A return info.name;
829N/A }
829N/A
829N/A public void setName(String name) {
829N/A info.name = name;
829N/A }
829N/A
829N/A public ModelPatch getPatch() {
829N/A return new ModelPatch(bank, preset, druminstrument);
829N/A }
829N/A
829N/A public void setPatch(Patch patch) {
829N/A if (patch instanceof ModelPatch && ((ModelPatch)patch).isPercussion()) {
829N/A druminstrument = true;
829N/A bank = patch.getBank();
829N/A preset = patch.getProgram();
829N/A } else {
829N/A druminstrument = false;
829N/A bank = patch.getBank();
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 List<DLSRegion> getRegions() {
829N/A return regions;
829N/A }
829N/A
829N/A public List<DLSModulator> getModulators() {
829N/A return modulators;
829N/A }
829N/A
829N/A public String toString() {
829N/A if (druminstrument)
829N/A return "Drumkit: " + info.name
829N/A + " bank #" + bank + " preset #" + preset;
829N/A else
829N/A return "Instrument: " + info.name
829N/A + " bank #" + bank + " preset #" + preset;
829N/A }
829N/A
829N/A private ModelIdentifier convertToModelDest(int dest) {
829N/A if (dest == DLSModulator.CONN_DST_NONE)
829N/A return null;
829N/A if (dest == DLSModulator.CONN_DST_GAIN)
829N/A return ModelDestination.DESTINATION_GAIN;
829N/A if (dest == DLSModulator.CONN_DST_PITCH)
829N/A return ModelDestination.DESTINATION_PITCH;
829N/A if (dest == DLSModulator.CONN_DST_PAN)
829N/A return ModelDestination.DESTINATION_PAN;
829N/A
829N/A if (dest == DLSModulator.CONN_DST_LFO_FREQUENCY)
829N/A return ModelDestination.DESTINATION_LFO1_FREQ;
829N/A if (dest == DLSModulator.CONN_DST_LFO_STARTDELAY)
829N/A return ModelDestination.DESTINATION_LFO1_DELAY;
829N/A
829N/A if (dest == DLSModulator.CONN_DST_EG1_ATTACKTIME)
829N/A return ModelDestination.DESTINATION_EG1_ATTACK;
829N/A if (dest == DLSModulator.CONN_DST_EG1_DECAYTIME)
829N/A return ModelDestination.DESTINATION_EG1_DECAY;
829N/A if (dest == DLSModulator.CONN_DST_EG1_RELEASETIME)
829N/A return ModelDestination.DESTINATION_EG1_RELEASE;
829N/A if (dest == DLSModulator.CONN_DST_EG1_SUSTAINLEVEL)
829N/A return ModelDestination.DESTINATION_EG1_SUSTAIN;
829N/A
829N/A if (dest == DLSModulator.CONN_DST_EG2_ATTACKTIME)
829N/A return ModelDestination.DESTINATION_EG2_ATTACK;
829N/A if (dest == DLSModulator.CONN_DST_EG2_DECAYTIME)
829N/A return ModelDestination.DESTINATION_EG2_DECAY;
829N/A if (dest == DLSModulator.CONN_DST_EG2_RELEASETIME)
829N/A return ModelDestination.DESTINATION_EG2_RELEASE;
829N/A if (dest == DLSModulator.CONN_DST_EG2_SUSTAINLEVEL)
829N/A return ModelDestination.DESTINATION_EG2_SUSTAIN;
829N/A
829N/A // DLS2 Destinations
829N/A if (dest == DLSModulator.CONN_DST_KEYNUMBER)
829N/A return ModelDestination.DESTINATION_KEYNUMBER;
829N/A
829N/A if (dest == DLSModulator.CONN_DST_CHORUS)
829N/A return ModelDestination.DESTINATION_CHORUS;
829N/A if (dest == DLSModulator.CONN_DST_REVERB)
829N/A return ModelDestination.DESTINATION_REVERB;
829N/A
829N/A if (dest == DLSModulator.CONN_DST_VIB_FREQUENCY)
829N/A return ModelDestination.DESTINATION_LFO2_FREQ;
829N/A if (dest == DLSModulator.CONN_DST_VIB_STARTDELAY)
829N/A return ModelDestination.DESTINATION_LFO2_DELAY;
829N/A
829N/A if (dest == DLSModulator.CONN_DST_EG1_DELAYTIME)
829N/A return ModelDestination.DESTINATION_EG1_DELAY;
829N/A if (dest == DLSModulator.CONN_DST_EG1_HOLDTIME)
829N/A return ModelDestination.DESTINATION_EG1_HOLD;
829N/A if (dest == DLSModulator.CONN_DST_EG1_SHUTDOWNTIME)
829N/A return ModelDestination.DESTINATION_EG1_SHUTDOWN;
829N/A
829N/A if (dest == DLSModulator.CONN_DST_EG2_DELAYTIME)
829N/A return ModelDestination.DESTINATION_EG2_DELAY;
829N/A if (dest == DLSModulator.CONN_DST_EG2_HOLDTIME)
829N/A return ModelDestination.DESTINATION_EG2_HOLD;
829N/A
829N/A if (dest == DLSModulator.CONN_DST_FILTER_CUTOFF)
829N/A return ModelDestination.DESTINATION_FILTER_FREQ;
829N/A if (dest == DLSModulator.CONN_DST_FILTER_Q)
829N/A return ModelDestination.DESTINATION_FILTER_Q;
829N/A
829N/A return null;
829N/A }
829N/A
829N/A private ModelIdentifier convertToModelSrc(int src) {
829N/A if (src == DLSModulator.CONN_SRC_NONE)
829N/A return null;
829N/A
829N/A if (src == DLSModulator.CONN_SRC_LFO)
829N/A return ModelSource.SOURCE_LFO1;
829N/A if (src == DLSModulator.CONN_SRC_KEYONVELOCITY)
829N/A return ModelSource.SOURCE_NOTEON_VELOCITY;
829N/A if (src == DLSModulator.CONN_SRC_KEYNUMBER)
829N/A return ModelSource.SOURCE_NOTEON_KEYNUMBER;
829N/A if (src == DLSModulator.CONN_SRC_EG1)
829N/A return ModelSource.SOURCE_EG1;
829N/A if (src == DLSModulator.CONN_SRC_EG2)
829N/A return ModelSource.SOURCE_EG2;
829N/A if (src == DLSModulator.CONN_SRC_PITCHWHEEL)
829N/A return ModelSource.SOURCE_MIDI_PITCH;
829N/A if (src == DLSModulator.CONN_SRC_CC1)
829N/A return new ModelIdentifier("midi_cc", "1", 0);
829N/A if (src == DLSModulator.CONN_SRC_CC7)
829N/A return new ModelIdentifier("midi_cc", "7", 0);
829N/A if (src == DLSModulator.CONN_SRC_CC10)
829N/A return new ModelIdentifier("midi_cc", "10", 0);
829N/A if (src == DLSModulator.CONN_SRC_CC11)
829N/A return new ModelIdentifier("midi_cc", "11", 0);
829N/A if (src == DLSModulator.CONN_SRC_RPN0)
829N/A return new ModelIdentifier("midi_rpn", "0", 0);
829N/A if (src == DLSModulator.CONN_SRC_RPN1)
829N/A return new ModelIdentifier("midi_rpn", "1", 0);
829N/A
829N/A if (src == DLSModulator.CONN_SRC_POLYPRESSURE)
829N/A return ModelSource.SOURCE_MIDI_POLY_PRESSURE;
829N/A if (src == DLSModulator.CONN_SRC_CHANNELPRESSURE)
829N/A return ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;
829N/A if (src == DLSModulator.CONN_SRC_VIBRATO)
829N/A return ModelSource.SOURCE_LFO2;
829N/A if (src == DLSModulator.CONN_SRC_MONOPRESSURE)
829N/A return ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;
829N/A
829N/A if (src == DLSModulator.CONN_SRC_CC91)
829N/A return new ModelIdentifier("midi_cc", "91", 0);
829N/A if (src == DLSModulator.CONN_SRC_CC93)
829N/A return new ModelIdentifier("midi_cc", "93", 0);
829N/A
829N/A return null;
829N/A }
829N/A
829N/A private ModelConnectionBlock convertToModel(DLSModulator mod) {
829N/A ModelIdentifier source = convertToModelSrc(mod.getSource());
829N/A ModelIdentifier control = convertToModelSrc(mod.getControl());
829N/A ModelIdentifier destination_id =
829N/A convertToModelDest(mod.getDestination());
829N/A
829N/A int scale = mod.getScale();
829N/A double f_scale;
829N/A if (scale == Integer.MIN_VALUE)
829N/A f_scale = Double.NEGATIVE_INFINITY;
829N/A else
829N/A f_scale = scale / 65536.0;
829N/A
829N/A if (destination_id != null) {
829N/A ModelSource src = null;
829N/A ModelSource ctrl = null;
829N/A ModelConnectionBlock block = new ModelConnectionBlock();
829N/A if (control != null) {
829N/A ModelSource s = new ModelSource();
829N/A if (control == ModelSource.SOURCE_MIDI_PITCH) {
829N/A ((ModelStandardTransform)s.getTransform()).setPolarity(
829N/A ModelStandardTransform.POLARITY_BIPOLAR);
829N/A } else if (control == ModelSource.SOURCE_LFO1
829N/A || control == ModelSource.SOURCE_LFO2) {
829N/A ((ModelStandardTransform)s.getTransform()).setPolarity(
829N/A ModelStandardTransform.POLARITY_BIPOLAR);
829N/A }
829N/A s.setIdentifier(control);
829N/A block.addSource(s);
829N/A ctrl = s;
829N/A }
829N/A if (source != null) {
829N/A ModelSource s = new ModelSource();
829N/A if (source == ModelSource.SOURCE_MIDI_PITCH) {
829N/A ((ModelStandardTransform)s.getTransform()).setPolarity(
829N/A ModelStandardTransform.POLARITY_BIPOLAR);
829N/A } else if (source == ModelSource.SOURCE_LFO1
829N/A || source == ModelSource.SOURCE_LFO2) {
829N/A ((ModelStandardTransform)s.getTransform()).setPolarity(
829N/A ModelStandardTransform.POLARITY_BIPOLAR);
829N/A }
829N/A s.setIdentifier(source);
829N/A block.addSource(s);
829N/A src = s;
829N/A }
829N/A ModelDestination destination = new ModelDestination();
829N/A destination.setIdentifier(destination_id);
829N/A block.setDestination(destination);
829N/A
829N/A if (mod.getVersion() == 1) {
829N/A //if (mod.getTransform() == DLSModulator.CONN_TRN_CONCAVE) {
829N/A // ((ModelStandardTransform)destination.getTransform())
829N/A // .setTransform(
829N/A // ModelStandardTransform.TRANSFORM_CONCAVE);
829N/A //}
829N/A if (mod.getTransform() == DLSModulator.CONN_TRN_CONCAVE) {
829N/A if (src != null) {
829N/A ((ModelStandardTransform)src.getTransform())
829N/A .setTransform(
829N/A ModelStandardTransform.TRANSFORM_CONCAVE);
829N/A ((ModelStandardTransform)src.getTransform())
829N/A .setDirection(
829N/A ModelStandardTransform.DIRECTION_MAX2MIN);
829N/A }
829N/A if (ctrl != null) {
829N/A ((ModelStandardTransform)ctrl.getTransform())
829N/A .setTransform(
829N/A ModelStandardTransform.TRANSFORM_CONCAVE);
829N/A ((ModelStandardTransform)ctrl.getTransform())
829N/A .setDirection(
829N/A ModelStandardTransform.DIRECTION_MAX2MIN);
829N/A }
829N/A }
829N/A
829N/A } else if (mod.getVersion() == 2) {
829N/A int transform = mod.getTransform();
829N/A int src_transform_invert = (transform >> 15) & 1;
829N/A int src_transform_bipolar = (transform >> 14) & 1;
829N/A int src_transform = (transform >> 10) & 8;
829N/A int ctr_transform_invert = (transform >> 9) & 1;
829N/A int ctr_transform_bipolar = (transform >> 8) & 1;
829N/A int ctr_transform = (transform >> 4) & 8;
829N/A
829N/A
829N/A if (src != null) {
829N/A int trans = ModelStandardTransform.TRANSFORM_LINEAR;
829N/A if (src_transform == DLSModulator.CONN_TRN_SWITCH)
829N/A trans = ModelStandardTransform.TRANSFORM_SWITCH;
829N/A if (src_transform == DLSModulator.CONN_TRN_CONCAVE)
829N/A trans = ModelStandardTransform.TRANSFORM_CONCAVE;
829N/A if (src_transform == DLSModulator.CONN_TRN_CONVEX)
829N/A trans = ModelStandardTransform.TRANSFORM_CONVEX;
829N/A ((ModelStandardTransform)src.getTransform())
829N/A .setTransform(trans);
829N/A ((ModelStandardTransform)src.getTransform())
829N/A .setPolarity(src_transform_bipolar == 1);
829N/A ((ModelStandardTransform)src.getTransform())
829N/A .setDirection(src_transform_invert == 1);
829N/A
829N/A }
829N/A
829N/A if (ctrl != null) {
829N/A int trans = ModelStandardTransform.TRANSFORM_LINEAR;
829N/A if (ctr_transform == DLSModulator.CONN_TRN_SWITCH)
829N/A trans = ModelStandardTransform.TRANSFORM_SWITCH;
829N/A if (ctr_transform == DLSModulator.CONN_TRN_CONCAVE)
829N/A trans = ModelStandardTransform.TRANSFORM_CONCAVE;
829N/A if (ctr_transform == DLSModulator.CONN_TRN_CONVEX)
829N/A trans = ModelStandardTransform.TRANSFORM_CONVEX;
829N/A ((ModelStandardTransform)ctrl.getTransform())
829N/A .setTransform(trans);
829N/A ((ModelStandardTransform)ctrl.getTransform())
829N/A .setPolarity(ctr_transform_bipolar == 1);
829N/A ((ModelStandardTransform)ctrl.getTransform())
829N/A .setDirection(ctr_transform_invert == 1);
829N/A }
829N/A
829N/A /* No output transforms are defined the DLS Level 2
829N/A int out_transform = transform % 8;
829N/A int trans = ModelStandardTransform.TRANSFORM_LINEAR;
829N/A if (out_transform == DLSModulator.CONN_TRN_SWITCH)
829N/A trans = ModelStandardTransform.TRANSFORM_SWITCH;
829N/A if (out_transform == DLSModulator.CONN_TRN_CONCAVE)
829N/A trans = ModelStandardTransform.TRANSFORM_CONCAVE;
829N/A if (out_transform == DLSModulator.CONN_TRN_CONVEX)
829N/A trans = ModelStandardTransform.TRANSFORM_CONVEX;
829N/A if (ctrl != null) {
829N/A ((ModelStandardTransform)destination.getTransform())
829N/A .setTransform(trans);
829N/A }
829N/A */
829N/A
829N/A }
829N/A
829N/A block.setScale(f_scale);
829N/A
829N/A return block;
829N/A }
829N/A
829N/A return null;
829N/A }
829N/A
829N/A public ModelPerformer[] getPerformers() {
829N/A List<ModelPerformer> performers = new ArrayList<ModelPerformer>();
829N/A
829N/A Map<String, DLSModulator> modmap = new HashMap<String, DLSModulator>();
829N/A for (DLSModulator mod: getModulators()) {
829N/A modmap.put(mod.getSource() + "x" + mod.getControl() + "=" +
829N/A mod.getDestination(), mod);
829N/A }
829N/A
829N/A Map<String, DLSModulator> insmodmap =
829N/A new HashMap<String, DLSModulator>();
829N/A
829N/A for (DLSRegion zone: regions) {
829N/A ModelPerformer performer = new ModelPerformer();
829N/A performer.setName(zone.getSample().getName());
829N/A performer.setSelfNonExclusive((zone.getFusoptions() &
829N/A DLSRegion.OPTION_SELFNONEXCLUSIVE) != 0);
829N/A performer.setExclusiveClass(zone.getExclusiveClass());
829N/A performer.setKeyFrom(zone.getKeyfrom());
829N/A performer.setKeyTo(zone.getKeyto());
829N/A performer.setVelFrom(zone.getVelfrom());
829N/A performer.setVelTo(zone.getVelto());
829N/A
829N/A insmodmap.clear();
829N/A insmodmap.putAll(modmap);
829N/A for (DLSModulator mod: zone.getModulators()) {
829N/A insmodmap.put(mod.getSource() + "x" + mod.getControl() + "=" +
829N/A mod.getDestination(), mod);
829N/A }
829N/A
829N/A List<ModelConnectionBlock> blocks = performer.getConnectionBlocks();
829N/A for (DLSModulator mod: insmodmap.values()) {
829N/A ModelConnectionBlock p = convertToModel(mod);
829N/A if (p != null)
829N/A blocks.add(p);
829N/A }
829N/A
829N/A
829N/A DLSSample sample = zone.getSample();
829N/A DLSSampleOptions sampleopt = zone.getSampleoptions();
829N/A if (sampleopt == null)
829N/A sampleopt = sample.getSampleoptions();
829N/A
829N/A ModelByteBuffer buff = sample.getDataBuffer();
829N/A
829N/A float pitchcorrection = (-sampleopt.unitynote * 100) +
829N/A sampleopt.finetune;
829N/A
829N/A ModelByteBufferWavetable osc = new ModelByteBufferWavetable(buff,
829N/A sample.getFormat(), pitchcorrection);
829N/A osc.setAttenuation(osc.getAttenuation() / 65536f);
829N/A if (sampleopt.getLoops().size() != 0) {
829N/A DLSSampleLoop loop = sampleopt.getLoops().get(0);
829N/A osc.setLoopStart((int)loop.getStart());
829N/A osc.setLoopLength((int)loop.getLength());
829N/A if (loop.getType() == DLSSampleLoop.LOOP_TYPE_FORWARD)
829N/A osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);
829N/A if (loop.getType() == DLSSampleLoop.LOOP_TYPE_RELEASE)
829N/A osc.setLoopType(ModelWavetable.LOOP_TYPE_RELEASE);
829N/A else
829N/A osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);
829N/A }
829N/A
829N/A performer.getConnectionBlocks().add(
829N/A new ModelConnectionBlock(SoftFilter.FILTERTYPE_LP12,
829N/A new ModelDestination(
829N/A new ModelIdentifier("filter", "type", 1))));
829N/A
829N/A performer.getOscillators().add(osc);
829N/A
829N/A performers.add(performer);
829N/A
829N/A }
829N/A
829N/A return performers.toArray(new ModelPerformer[performers.size()]);
829N/A }
829N/A
829N/A public byte[] getGuid() {
3957N/A return guid == null ? null : Arrays.copyOf(guid, guid.length);
829N/A }
829N/A
829N/A public void setGuid(byte[] guid) {
3957N/A this.guid = guid == null ? null : Arrays.copyOf(guid, guid.length);
829N/A }
829N/A}