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