Path: blob/master/src/java.desktop/share/classes/com/sun/media/sound/DLSInstrument.java
41161 views
/*1* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.media.sound;2627import java.util.ArrayList;28import java.util.Arrays;29import java.util.HashMap;30import java.util.List;31import java.util.Map;3233import javax.sound.midi.Patch;3435/**36* This class is used to store information to describe instrument.37* It contains list of regions and modulators.38* It is stored inside a "ins " List Chunk inside DLS files.39* In the DLS documentation a modulator is called articulator.40*41* @author Karl Helgason42*/43public final class DLSInstrument extends ModelInstrument {4445int preset = 0;46int bank = 0;47boolean druminstrument = false;48byte[] guid = null;49DLSInfo info = new DLSInfo();50List<DLSRegion> regions = new ArrayList<>();51List<DLSModulator> modulators = new ArrayList<>();5253public DLSInstrument() {54super(null, null, null, null);55}5657public DLSInstrument(DLSSoundbank soundbank) {58super(soundbank, null, null, null);59}6061public DLSInfo getInfo() {62return info;63}6465@Override66public String getName() {67return info.name;68}6970public void setName(String name) {71info.name = name;72}7374@Override75public ModelPatch getPatch() {76return new ModelPatch(bank, preset, druminstrument);77}7879public void setPatch(Patch patch) {80if (patch instanceof ModelPatch && ((ModelPatch)patch).isPercussion()) {81druminstrument = true;82bank = patch.getBank();83preset = patch.getProgram();84} else {85druminstrument = false;86bank = patch.getBank();87preset = patch.getProgram();88}89}9091@Override92public Object getData() {93return null;94}9596public List<DLSRegion> getRegions() {97return regions;98}99100public List<DLSModulator> getModulators() {101return modulators;102}103104@Override105public String toString() {106if (druminstrument)107return "Drumkit: " + info.name108+ " bank #" + bank + " preset #" + preset;109else110return "Instrument: " + info.name111+ " bank #" + bank + " preset #" + preset;112}113114private ModelIdentifier convertToModelDest(int dest) {115if (dest == DLSModulator.CONN_DST_NONE)116return null;117if (dest == DLSModulator.CONN_DST_GAIN)118return ModelDestination.DESTINATION_GAIN;119if (dest == DLSModulator.CONN_DST_PITCH)120return ModelDestination.DESTINATION_PITCH;121if (dest == DLSModulator.CONN_DST_PAN)122return ModelDestination.DESTINATION_PAN;123124if (dest == DLSModulator.CONN_DST_LFO_FREQUENCY)125return ModelDestination.DESTINATION_LFO1_FREQ;126if (dest == DLSModulator.CONN_DST_LFO_STARTDELAY)127return ModelDestination.DESTINATION_LFO1_DELAY;128129if (dest == DLSModulator.CONN_DST_EG1_ATTACKTIME)130return ModelDestination.DESTINATION_EG1_ATTACK;131if (dest == DLSModulator.CONN_DST_EG1_DECAYTIME)132return ModelDestination.DESTINATION_EG1_DECAY;133if (dest == DLSModulator.CONN_DST_EG1_RELEASETIME)134return ModelDestination.DESTINATION_EG1_RELEASE;135if (dest == DLSModulator.CONN_DST_EG1_SUSTAINLEVEL)136return ModelDestination.DESTINATION_EG1_SUSTAIN;137138if (dest == DLSModulator.CONN_DST_EG2_ATTACKTIME)139return ModelDestination.DESTINATION_EG2_ATTACK;140if (dest == DLSModulator.CONN_DST_EG2_DECAYTIME)141return ModelDestination.DESTINATION_EG2_DECAY;142if (dest == DLSModulator.CONN_DST_EG2_RELEASETIME)143return ModelDestination.DESTINATION_EG2_RELEASE;144if (dest == DLSModulator.CONN_DST_EG2_SUSTAINLEVEL)145return ModelDestination.DESTINATION_EG2_SUSTAIN;146147// DLS2 Destinations148if (dest == DLSModulator.CONN_DST_KEYNUMBER)149return ModelDestination.DESTINATION_KEYNUMBER;150151if (dest == DLSModulator.CONN_DST_CHORUS)152return ModelDestination.DESTINATION_CHORUS;153if (dest == DLSModulator.CONN_DST_REVERB)154return ModelDestination.DESTINATION_REVERB;155156if (dest == DLSModulator.CONN_DST_VIB_FREQUENCY)157return ModelDestination.DESTINATION_LFO2_FREQ;158if (dest == DLSModulator.CONN_DST_VIB_STARTDELAY)159return ModelDestination.DESTINATION_LFO2_DELAY;160161if (dest == DLSModulator.CONN_DST_EG1_DELAYTIME)162return ModelDestination.DESTINATION_EG1_DELAY;163if (dest == DLSModulator.CONN_DST_EG1_HOLDTIME)164return ModelDestination.DESTINATION_EG1_HOLD;165if (dest == DLSModulator.CONN_DST_EG1_SHUTDOWNTIME)166return ModelDestination.DESTINATION_EG1_SHUTDOWN;167168if (dest == DLSModulator.CONN_DST_EG2_DELAYTIME)169return ModelDestination.DESTINATION_EG2_DELAY;170if (dest == DLSModulator.CONN_DST_EG2_HOLDTIME)171return ModelDestination.DESTINATION_EG2_HOLD;172173if (dest == DLSModulator.CONN_DST_FILTER_CUTOFF)174return ModelDestination.DESTINATION_FILTER_FREQ;175if (dest == DLSModulator.CONN_DST_FILTER_Q)176return ModelDestination.DESTINATION_FILTER_Q;177178return null;179}180181private ModelIdentifier convertToModelSrc(int src) {182if (src == DLSModulator.CONN_SRC_NONE)183return null;184185if (src == DLSModulator.CONN_SRC_LFO)186return ModelSource.SOURCE_LFO1;187if (src == DLSModulator.CONN_SRC_KEYONVELOCITY)188return ModelSource.SOURCE_NOTEON_VELOCITY;189if (src == DLSModulator.CONN_SRC_KEYNUMBER)190return ModelSource.SOURCE_NOTEON_KEYNUMBER;191if (src == DLSModulator.CONN_SRC_EG1)192return ModelSource.SOURCE_EG1;193if (src == DLSModulator.CONN_SRC_EG2)194return ModelSource.SOURCE_EG2;195if (src == DLSModulator.CONN_SRC_PITCHWHEEL)196return ModelSource.SOURCE_MIDI_PITCH;197if (src == DLSModulator.CONN_SRC_CC1)198return new ModelIdentifier("midi_cc", "1", 0);199if (src == DLSModulator.CONN_SRC_CC7)200return new ModelIdentifier("midi_cc", "7", 0);201if (src == DLSModulator.CONN_SRC_CC10)202return new ModelIdentifier("midi_cc", "10", 0);203if (src == DLSModulator.CONN_SRC_CC11)204return new ModelIdentifier("midi_cc", "11", 0);205if (src == DLSModulator.CONN_SRC_RPN0)206return new ModelIdentifier("midi_rpn", "0", 0);207if (src == DLSModulator.CONN_SRC_RPN1)208return new ModelIdentifier("midi_rpn", "1", 0);209210if (src == DLSModulator.CONN_SRC_POLYPRESSURE)211return ModelSource.SOURCE_MIDI_POLY_PRESSURE;212if (src == DLSModulator.CONN_SRC_CHANNELPRESSURE)213return ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;214if (src == DLSModulator.CONN_SRC_VIBRATO)215return ModelSource.SOURCE_LFO2;216if (src == DLSModulator.CONN_SRC_MONOPRESSURE)217return ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;218219if (src == DLSModulator.CONN_SRC_CC91)220return new ModelIdentifier("midi_cc", "91", 0);221if (src == DLSModulator.CONN_SRC_CC93)222return new ModelIdentifier("midi_cc", "93", 0);223224return null;225}226227private ModelConnectionBlock convertToModel(DLSModulator mod) {228ModelIdentifier source = convertToModelSrc(mod.getSource());229ModelIdentifier control = convertToModelSrc(mod.getControl());230ModelIdentifier destination_id =231convertToModelDest(mod.getDestination());232233int scale = mod.getScale();234double f_scale;235if (scale == Integer.MIN_VALUE)236f_scale = Double.NEGATIVE_INFINITY;237else238f_scale = scale / 65536.0;239240if (destination_id != null) {241ModelSource src = null;242ModelSource ctrl = null;243ModelConnectionBlock block = new ModelConnectionBlock();244if (control != null) {245ModelSource s = new ModelSource();246if (control == ModelSource.SOURCE_MIDI_PITCH) {247((ModelStandardTransform)s.getTransform()).setPolarity(248ModelStandardTransform.POLARITY_BIPOLAR);249} else if (control == ModelSource.SOURCE_LFO1250|| control == ModelSource.SOURCE_LFO2) {251((ModelStandardTransform)s.getTransform()).setPolarity(252ModelStandardTransform.POLARITY_BIPOLAR);253}254s.setIdentifier(control);255block.addSource(s);256ctrl = s;257}258if (source != null) {259ModelSource s = new ModelSource();260if (source == ModelSource.SOURCE_MIDI_PITCH) {261((ModelStandardTransform)s.getTransform()).setPolarity(262ModelStandardTransform.POLARITY_BIPOLAR);263} else if (source == ModelSource.SOURCE_LFO1264|| source == ModelSource.SOURCE_LFO2) {265((ModelStandardTransform)s.getTransform()).setPolarity(266ModelStandardTransform.POLARITY_BIPOLAR);267}268s.setIdentifier(source);269block.addSource(s);270src = s;271}272ModelDestination destination = new ModelDestination();273destination.setIdentifier(destination_id);274block.setDestination(destination);275276if (mod.getVersion() == 1) {277//if (mod.getTransform() == DLSModulator.CONN_TRN_CONCAVE) {278// ((ModelStandardTransform)destination.getTransform())279// .setTransform(280// ModelStandardTransform.TRANSFORM_CONCAVE);281//}282if (mod.getTransform() == DLSModulator.CONN_TRN_CONCAVE) {283if (src != null) {284((ModelStandardTransform)src.getTransform())285.setTransform(286ModelStandardTransform.TRANSFORM_CONCAVE);287((ModelStandardTransform)src.getTransform())288.setDirection(289ModelStandardTransform.DIRECTION_MAX2MIN);290}291if (ctrl != null) {292((ModelStandardTransform)ctrl.getTransform())293.setTransform(294ModelStandardTransform.TRANSFORM_CONCAVE);295((ModelStandardTransform)ctrl.getTransform())296.setDirection(297ModelStandardTransform.DIRECTION_MAX2MIN);298}299}300301} else if (mod.getVersion() == 2) {302int transform = mod.getTransform();303int src_transform_invert = (transform >> 15) & 1;304int src_transform_bipolar = (transform >> 14) & 1;305int src_transform = (transform >> 10) & 8;306int ctr_transform_invert = (transform >> 9) & 1;307int ctr_transform_bipolar = (transform >> 8) & 1;308int ctr_transform = (transform >> 4) & 8;309310311if (src != null) {312int trans = ModelStandardTransform.TRANSFORM_LINEAR;313if (src_transform == DLSModulator.CONN_TRN_SWITCH)314trans = ModelStandardTransform.TRANSFORM_SWITCH;315if (src_transform == DLSModulator.CONN_TRN_CONCAVE)316trans = ModelStandardTransform.TRANSFORM_CONCAVE;317if (src_transform == DLSModulator.CONN_TRN_CONVEX)318trans = ModelStandardTransform.TRANSFORM_CONVEX;319((ModelStandardTransform)src.getTransform())320.setTransform(trans);321((ModelStandardTransform)src.getTransform())322.setPolarity(src_transform_bipolar == 1);323((ModelStandardTransform)src.getTransform())324.setDirection(src_transform_invert == 1);325326}327328if (ctrl != null) {329int trans = ModelStandardTransform.TRANSFORM_LINEAR;330if (ctr_transform == DLSModulator.CONN_TRN_SWITCH)331trans = ModelStandardTransform.TRANSFORM_SWITCH;332if (ctr_transform == DLSModulator.CONN_TRN_CONCAVE)333trans = ModelStandardTransform.TRANSFORM_CONCAVE;334if (ctr_transform == DLSModulator.CONN_TRN_CONVEX)335trans = ModelStandardTransform.TRANSFORM_CONVEX;336((ModelStandardTransform)ctrl.getTransform())337.setTransform(trans);338((ModelStandardTransform)ctrl.getTransform())339.setPolarity(ctr_transform_bipolar == 1);340((ModelStandardTransform)ctrl.getTransform())341.setDirection(ctr_transform_invert == 1);342}343344/* No output transforms are defined the DLS Level 2345int out_transform = transform % 8;346int trans = ModelStandardTransform.TRANSFORM_LINEAR;347if (out_transform == DLSModulator.CONN_TRN_SWITCH)348trans = ModelStandardTransform.TRANSFORM_SWITCH;349if (out_transform == DLSModulator.CONN_TRN_CONCAVE)350trans = ModelStandardTransform.TRANSFORM_CONCAVE;351if (out_transform == DLSModulator.CONN_TRN_CONVEX)352trans = ModelStandardTransform.TRANSFORM_CONVEX;353if (ctrl != null) {354((ModelStandardTransform)destination.getTransform())355.setTransform(trans);356}357*/358359}360361block.setScale(f_scale);362363return block;364}365366return null;367}368369@Override370public ModelPerformer[] getPerformers() {371List<ModelPerformer> performers = new ArrayList<>();372373Map<String, DLSModulator> modmap = new HashMap<>();374for (DLSModulator mod: getModulators()) {375modmap.put(mod.getSource() + "x" + mod.getControl() + "=" +376mod.getDestination(), mod);377}378379Map<String, DLSModulator> insmodmap = new HashMap<>();380381for (DLSRegion zone: regions) {382ModelPerformer performer = new ModelPerformer();383performer.setName(zone.getSample().getName());384performer.setSelfNonExclusive((zone.getFusoptions() &385DLSRegion.OPTION_SELFNONEXCLUSIVE) != 0);386performer.setExclusiveClass(zone.getExclusiveClass());387performer.setKeyFrom(zone.getKeyfrom());388performer.setKeyTo(zone.getKeyto());389performer.setVelFrom(zone.getVelfrom());390performer.setVelTo(zone.getVelto());391392insmodmap.clear();393insmodmap.putAll(modmap);394for (DLSModulator mod: zone.getModulators()) {395insmodmap.put(mod.getSource() + "x" + mod.getControl() + "=" +396mod.getDestination(), mod);397}398399List<ModelConnectionBlock> blocks = performer.getConnectionBlocks();400for (DLSModulator mod: insmodmap.values()) {401ModelConnectionBlock p = convertToModel(mod);402if (p != null)403blocks.add(p);404}405406407DLSSample sample = zone.getSample();408DLSSampleOptions sampleopt = zone.getSampleoptions();409if (sampleopt == null)410sampleopt = sample.getSampleoptions();411412ModelByteBuffer buff = sample.getDataBuffer();413414float pitchcorrection = (-sampleopt.unitynote * 100) +415sampleopt.finetune;416417ModelByteBufferWavetable osc = new ModelByteBufferWavetable(buff,418sample.getFormat(), pitchcorrection);419osc.setAttenuation(osc.getAttenuation() / 65536f);420if (sampleopt.getLoops().size() != 0) {421DLSSampleLoop loop = sampleopt.getLoops().get(0);422osc.setLoopStart((int)loop.getStart());423osc.setLoopLength((int)loop.getLength());424if (loop.getType() == DLSSampleLoop.LOOP_TYPE_FORWARD)425osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);426if (loop.getType() == DLSSampleLoop.LOOP_TYPE_RELEASE)427osc.setLoopType(ModelWavetable.LOOP_TYPE_RELEASE);428else429osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);430}431432performer.getConnectionBlocks().add(433new ModelConnectionBlock(SoftFilter.FILTERTYPE_LP12,434new ModelDestination(435new ModelIdentifier("filter", "type", 1))));436437performer.getOscillators().add(osc);438439performers.add(performer);440441}442443return performers.toArray(new ModelPerformer[performers.size()]);444}445446public byte[] getGuid() {447return guid == null ? null : Arrays.copyOf(guid, guid.length);448}449450public void setGuid(byte[] guid) {451this.guid = guid == null ? null : Arrays.copyOf(guid, guid.length);452}453}454455456