1 /* 2 * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package com.sun.media.sound; 26 27 import java.util.ArrayList; 28 import java.util.HashMap; 29 import java.util.List; 30 import java.util.Map; 31 32 import javax.sound.midi.Patch; 33 34 /** 35 * Soundfont instrument. 36 * 37 * @author Karl Helgason 38 */ 39 public final class SF2Instrument extends ModelInstrument { 40 41 String name = ""; 42 int preset = 0; 43 int bank = 0; 44 long library = 0; 45 long genre = 0; 46 long morphology = 0; 47 SF2GlobalRegion globalregion = null; 48 List<SF2InstrumentRegion> regions 49 = new ArrayList<SF2InstrumentRegion>(); 50 51 public SF2Instrument() { 52 super(null, null, null, null); 53 } 54 55 public SF2Instrument(SF2Soundbank soundbank) { 56 super(soundbank, null, null, null); 57 } 58 59 public String getName() { 60 return name; 61 } 62 63 public void setName(String name) { 64 this.name = name; 65 } 66 67 public Patch getPatch() { 68 if (bank == 128) 69 return new ModelPatch(0, preset, true); 70 else 71 return new ModelPatch(bank << 7, preset, false); 72 } 73 74 public void setPatch(Patch patch) { 75 if (patch instanceof ModelPatch && ((ModelPatch) patch).isPercussion()) { 76 bank = 128; 77 preset = patch.getProgram(); 78 } else { 79 bank = patch.getBank() >> 7; 80 preset = patch.getProgram(); 81 } 82 } 83 84 public Object getData() { 85 return null; 86 } 87 88 public long getGenre() { 89 return genre; 90 } 91 92 public void setGenre(long genre) { 93 this.genre = genre; 94 } 95 96 public long getLibrary() { 97 return library; 98 } 99 100 public void setLibrary(long library) { 101 this.library = library; 102 } 103 104 public long getMorphology() { 105 return morphology; 106 } 107 108 public void setMorphology(long morphology) { 109 this.morphology = morphology; 110 } 111 112 public List<SF2InstrumentRegion> getRegions() { 113 return regions; 114 } 115 116 public SF2GlobalRegion getGlobalRegion() { 117 return globalregion; 118 } 119 120 public void setGlobalZone(SF2GlobalRegion zone) { 121 globalregion = zone; 122 } 123 124 public String toString() { 125 if (bank == 128) 126 return "Drumkit: " + name + " preset #" + preset; 127 else 128 return "Instrument: " + name + " bank #" + bank 129 + " preset #" + preset; 130 } 131 132 public ModelPerformer[] getPerformers() { 133 int performercount = 0; 134 for (SF2InstrumentRegion presetzone : regions) 135 performercount += presetzone.getLayer().getRegions().size(); 136 ModelPerformer[] performers = new ModelPerformer[performercount]; 137 int pi = 0; 138 139 SF2GlobalRegion presetglobal = globalregion; 140 for (SF2InstrumentRegion presetzone : regions) { 141 Map<Integer, Short> pgenerators = new HashMap<Integer, Short>(); 142 pgenerators.putAll(presetzone.getGenerators()); 143 if (presetglobal != null) 144 pgenerators.putAll(presetglobal.getGenerators()); 145 146 SF2Layer layer = presetzone.getLayer(); 147 SF2GlobalRegion layerglobal = layer.getGlobalRegion(); 148 for (SF2LayerRegion layerzone : layer.getRegions()) { 149 ModelPerformer performer = new ModelPerformer(); 150 if (layerzone.getSample() != null) 151 performer.setName(layerzone.getSample().getName()); 152 else 153 performer.setName(layer.getName()); 154 155 performers[pi++] = performer; 156 157 int keyfrom = 0; 158 int keyto = 127; 159 int velfrom = 0; 160 int velto = 127; 161 162 if (layerzone.contains(SF2Region.GENERATOR_EXCLUSIVECLASS)) { 163 performer.setExclusiveClass(layerzone.getInteger( 164 SF2Region.GENERATOR_EXCLUSIVECLASS)); 165 } 166 if (layerzone.contains(SF2Region.GENERATOR_KEYRANGE)) { 167 byte[] bytes = layerzone.getBytes( 168 SF2Region.GENERATOR_KEYRANGE); 169 if (bytes[0] >= 0) 170 if (bytes[0] > keyfrom) 171 keyfrom = bytes[0]; 172 if (bytes[1] >= 0) 173 if (bytes[1] < keyto) 174 keyto = bytes[1]; 175 } 176 if (layerzone.contains(SF2Region.GENERATOR_VELRANGE)) { 177 byte[] bytes = layerzone.getBytes( 178 SF2Region.GENERATOR_VELRANGE); 179 if (bytes[0] >= 0) 180 if (bytes[0] > velfrom) 181 velfrom = bytes[0]; 182 if (bytes[1] >= 0) 183 if (bytes[1] < velto) 184 velto = bytes[1]; 185 } 186 if (presetzone.contains(SF2Region.GENERATOR_KEYRANGE)) { 187 byte[] bytes = presetzone.getBytes( 188 SF2Region.GENERATOR_KEYRANGE); 189 if (bytes[0] > keyfrom) 190 keyfrom = bytes[0]; 191 if (bytes[1] < keyto) 192 keyto = bytes[1]; 193 } 194 if (presetzone.contains(SF2Region.GENERATOR_VELRANGE)) { 195 byte[] bytes = presetzone.getBytes( 196 SF2Region.GENERATOR_VELRANGE); 197 if (bytes[0] > velfrom) 198 velfrom = bytes[0]; 199 if (bytes[1] < velto) 200 velto = bytes[1]; 201 } 202 performer.setKeyFrom(keyfrom); 203 performer.setKeyTo(keyto); 204 performer.setVelFrom(velfrom); 205 performer.setVelTo(velto); 206 207 int startAddrsOffset = layerzone.getShort( 208 SF2Region.GENERATOR_STARTADDRSOFFSET); 209 int endAddrsOffset = layerzone.getShort( 210 SF2Region.GENERATOR_ENDADDRSOFFSET); 211 int startloopAddrsOffset = layerzone.getShort( 212 SF2Region.GENERATOR_STARTLOOPADDRSOFFSET); 213 int endloopAddrsOffset = layerzone.getShort( 214 SF2Region.GENERATOR_ENDLOOPADDRSOFFSET); 215 216 startAddrsOffset += layerzone.getShort( 217 SF2Region.GENERATOR_STARTADDRSCOARSEOFFSET) * 32768; 218 endAddrsOffset += layerzone.getShort( 219 SF2Region.GENERATOR_ENDADDRSCOARSEOFFSET) * 32768; 220 startloopAddrsOffset += layerzone.getShort( 221 SF2Region.GENERATOR_STARTLOOPADDRSCOARSEOFFSET) * 32768; 222 endloopAddrsOffset += layerzone.getShort( 223 SF2Region.GENERATOR_ENDLOOPADDRSCOARSEOFFSET) * 32768; 224 startloopAddrsOffset -= startAddrsOffset; 225 endloopAddrsOffset -= startAddrsOffset; 226 227 SF2Sample sample = layerzone.getSample(); 228 int rootkey = sample.originalPitch; 229 if (layerzone.getShort(SF2Region.GENERATOR_OVERRIDINGROOTKEY) != -1) { 230 rootkey = layerzone.getShort( 231 SF2Region.GENERATOR_OVERRIDINGROOTKEY); 232 } 233 float pitchcorrection = (-rootkey * 100) + sample.pitchCorrection; 234 ModelByteBuffer buff = sample.getDataBuffer(); 235 ModelByteBuffer buff24 = sample.getData24Buffer(); 236 237 if (startAddrsOffset != 0 || endAddrsOffset != 0) { 238 buff = buff.subbuffer(startAddrsOffset * 2, 239 buff.capacity() + endAddrsOffset * 2); 240 if (buff24 != null) { 241 buff24 = buff24.subbuffer(startAddrsOffset, 242 buff24.capacity() + endAddrsOffset); 243 } 244 245 /* 246 if (startAddrsOffset < 0) 247 startAddrsOffset = 0; 248 if (endAddrsOffset > (buff.capacity()/2-startAddrsOffset)) 249 startAddrsOffset = (int)buff.capacity()/2-startAddrsOffset; 250 byte[] data = buff.array(); 251 int off = (int)buff.arrayOffset() + startAddrsOffset*2; 252 int len = (int)buff.capacity() + endAddrsOffset*2; 253 if (off+len > data.length) 254 len = data.length - off; 255 buff = new ModelByteBuffer(data, off, len); 256 if(buff24 != null) { 257 data = buff.array(); 258 off = (int)buff.arrayOffset() + startAddrsOffset; 259 len = (int)buff.capacity() + endAddrsOffset; 260 buff24 = new ModelByteBuffer(data, off, len); 261 } 262 */ 263 } 264 265 ModelByteBufferWavetable osc = new ModelByteBufferWavetable( 266 buff, sample.getFormat(), pitchcorrection); 267 if (buff24 != null) 268 osc.set8BitExtensionBuffer(buff24); 269 270 Map<Integer, Short> generators = new HashMap<Integer, Short>(); 271 if (layerglobal != null) 272 generators.putAll(layerglobal.getGenerators()); 273 generators.putAll(layerzone.getGenerators()); 274 for (Map.Entry<Integer, Short> gen : pgenerators.entrySet()) { 275 short val; 276 if (!generators.containsKey(gen.getKey())) 277 val = layerzone.getShort(gen.getKey()); 278 else 279 val = generators.get(gen.getKey()); 280 val += gen.getValue(); 281 generators.put(gen.getKey(), val); 282 } 283 284 // SampleMode: 285 // 0 indicates a sound reproduced with no loop 286 // 1 indicates a sound which loops continuously 287 // 2 is unused but should be interpreted as indicating no loop 288 // 3 indicates a sound which loops for the duration of key 289 // depression then proceeds to play the remainder of the sample. 290 int sampleMode = getGeneratorValue(generators, 291 SF2Region.GENERATOR_SAMPLEMODES); 292 if ((sampleMode == 1) || (sampleMode == 3)) { 293 if (sample.startLoop >= 0 && sample.endLoop > 0) { 294 osc.setLoopStart((int)(sample.startLoop 295 + startloopAddrsOffset)); 296 osc.setLoopLength((int)(sample.endLoop - sample.startLoop 297 + endloopAddrsOffset - startloopAddrsOffset)); 298 if (sampleMode == 1) 299 osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD); 300 if (sampleMode == 3) 301 osc.setLoopType(ModelWavetable.LOOP_TYPE_RELEASE); 302 } 303 } 304 performer.getOscillators().add(osc); 305 306 307 short volDelay = getGeneratorValue(generators, 308 SF2Region.GENERATOR_DELAYVOLENV); 309 short volAttack = getGeneratorValue(generators, 310 SF2Region.GENERATOR_ATTACKVOLENV); 311 short volHold = getGeneratorValue(generators, 312 SF2Region.GENERATOR_HOLDVOLENV); 313 short volDecay = getGeneratorValue(generators, 314 SF2Region.GENERATOR_DECAYVOLENV); 315 short volSustain = getGeneratorValue(generators, 316 SF2Region.GENERATOR_SUSTAINVOLENV); 317 short volRelease = getGeneratorValue(generators, 318 SF2Region.GENERATOR_RELEASEVOLENV); 319 320 if (volHold != -12000) { 321 short volKeyNumToHold = getGeneratorValue(generators, 322 SF2Region.GENERATOR_KEYNUMTOVOLENVHOLD); 323 volHold += 60 * volKeyNumToHold; 324 float fvalue = -volKeyNumToHold * 128; 325 ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER; 326 ModelIdentifier dest = ModelDestination.DESTINATION_EG1_HOLD; 327 performer.getConnectionBlocks().add( 328 new ModelConnectionBlock(new ModelSource(src), fvalue, 329 new ModelDestination(dest))); 330 } 331 if (volDecay != -12000) { 332 short volKeyNumToDecay = getGeneratorValue(generators, 333 SF2Region.GENERATOR_KEYNUMTOVOLENVDECAY); 334 volDecay += 60 * volKeyNumToDecay; 335 float fvalue = -volKeyNumToDecay * 128; 336 ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER; 337 ModelIdentifier dest = ModelDestination.DESTINATION_EG1_DECAY; 338 performer.getConnectionBlocks().add( 339 new ModelConnectionBlock(new ModelSource(src), fvalue, 340 new ModelDestination(dest))); 341 } 342 343 addTimecentValue(performer, 344 ModelDestination.DESTINATION_EG1_DELAY, volDelay); 345 addTimecentValue(performer, 346 ModelDestination.DESTINATION_EG1_ATTACK, volAttack); 347 addTimecentValue(performer, 348 ModelDestination.DESTINATION_EG1_HOLD, volHold); 349 addTimecentValue(performer, 350 ModelDestination.DESTINATION_EG1_DECAY, volDecay); 351 //float fvolsustain = (960-volSustain)*(1000.0f/960.0f); 352 353 volSustain = (short)(1000 - volSustain); 354 if (volSustain < 0) 355 volSustain = 0; 356 if (volSustain > 1000) 357 volSustain = 1000; 358 359 addValue(performer, 360 ModelDestination.DESTINATION_EG1_SUSTAIN, volSustain); 361 addTimecentValue(performer, 362 ModelDestination.DESTINATION_EG1_RELEASE, volRelease); 363 364 if (getGeneratorValue(generators, 365 SF2Region.GENERATOR_MODENVTOFILTERFC) != 0 366 || getGeneratorValue(generators, 367 SF2Region.GENERATOR_MODENVTOPITCH) != 0) { 368 short modDelay = getGeneratorValue(generators, 369 SF2Region.GENERATOR_DELAYMODENV); 370 short modAttack = getGeneratorValue(generators, 371 SF2Region.GENERATOR_ATTACKMODENV); 372 short modHold = getGeneratorValue(generators, 373 SF2Region.GENERATOR_HOLDMODENV); 374 short modDecay = getGeneratorValue(generators, 375 SF2Region.GENERATOR_DECAYMODENV); 376 short modSustain = getGeneratorValue(generators, 377 SF2Region.GENERATOR_SUSTAINMODENV); 378 short modRelease = getGeneratorValue(generators, 379 SF2Region.GENERATOR_RELEASEMODENV); 380 381 382 if (modHold != -12000) { 383 short modKeyNumToHold = getGeneratorValue(generators, 384 SF2Region.GENERATOR_KEYNUMTOMODENVHOLD); 385 modHold += 60 * modKeyNumToHold; 386 float fvalue = -modKeyNumToHold * 128; 387 ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER; 388 ModelIdentifier dest = ModelDestination.DESTINATION_EG2_HOLD; 389 performer.getConnectionBlocks().add( 390 new ModelConnectionBlock(new ModelSource(src), 391 fvalue, new ModelDestination(dest))); 392 } 393 if (modDecay != -12000) { 394 short modKeyNumToDecay = getGeneratorValue(generators, 395 SF2Region.GENERATOR_KEYNUMTOMODENVDECAY); 396 modDecay += 60 * modKeyNumToDecay; 397 float fvalue = -modKeyNumToDecay * 128; 398 ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER; 399 ModelIdentifier dest = ModelDestination.DESTINATION_EG2_DECAY; 400 performer.getConnectionBlocks().add( 401 new ModelConnectionBlock(new ModelSource(src), 402 fvalue, new ModelDestination(dest))); 403 } 404 405 addTimecentValue(performer, 406 ModelDestination.DESTINATION_EG2_DELAY, modDelay); 407 addTimecentValue(performer, 408 ModelDestination.DESTINATION_EG2_ATTACK, modAttack); 409 addTimecentValue(performer, 410 ModelDestination.DESTINATION_EG2_HOLD, modHold); 411 addTimecentValue(performer, 412 ModelDestination.DESTINATION_EG2_DECAY, modDecay); 413 if (modSustain < 0) 414 modSustain = 0; 415 if (modSustain > 1000) 416 modSustain = 1000; 417 addValue(performer, ModelDestination.DESTINATION_EG2_SUSTAIN, 418 1000 - modSustain); 419 addTimecentValue(performer, 420 ModelDestination.DESTINATION_EG2_RELEASE, modRelease); 421 422 if (getGeneratorValue(generators, 423 SF2Region.GENERATOR_MODENVTOFILTERFC) != 0) { 424 double fvalue = getGeneratorValue(generators, 425 SF2Region.GENERATOR_MODENVTOFILTERFC); 426 ModelIdentifier src = ModelSource.SOURCE_EG2; 427 ModelIdentifier dest 428 = ModelDestination.DESTINATION_FILTER_FREQ; 429 performer.getConnectionBlocks().add( 430 new ModelConnectionBlock(new ModelSource(src), 431 fvalue, new ModelDestination(dest))); 432 } 433 434 if (getGeneratorValue(generators, 435 SF2Region.GENERATOR_MODENVTOPITCH) != 0) { 436 double fvalue = getGeneratorValue(generators, 437 SF2Region.GENERATOR_MODENVTOPITCH); 438 ModelIdentifier src = ModelSource.SOURCE_EG2; 439 ModelIdentifier dest = ModelDestination.DESTINATION_PITCH; 440 performer.getConnectionBlocks().add( 441 new ModelConnectionBlock(new ModelSource(src), 442 fvalue, new ModelDestination(dest))); 443 } 444 445 } 446 447 if (getGeneratorValue(generators, 448 SF2Region.GENERATOR_MODLFOTOFILTERFC) != 0 449 || getGeneratorValue(generators, 450 SF2Region.GENERATOR_MODLFOTOPITCH) != 0 451 || getGeneratorValue(generators, 452 SF2Region.GENERATOR_MODLFOTOVOLUME) != 0) { 453 short lfo_freq = getGeneratorValue(generators, 454 SF2Region.GENERATOR_FREQMODLFO); 455 short lfo_delay = getGeneratorValue(generators, 456 SF2Region.GENERATOR_DELAYMODLFO); 457 addTimecentValue(performer, 458 ModelDestination.DESTINATION_LFO1_DELAY, lfo_delay); 459 addValue(performer, 460 ModelDestination.DESTINATION_LFO1_FREQ, lfo_freq); 461 } 462 463 short vib_freq = getGeneratorValue(generators, 464 SF2Region.GENERATOR_FREQVIBLFO); 465 short vib_delay = getGeneratorValue(generators, 466 SF2Region.GENERATOR_DELAYVIBLFO); 467 addTimecentValue(performer, 468 ModelDestination.DESTINATION_LFO2_DELAY, vib_delay); 469 addValue(performer, 470 ModelDestination.DESTINATION_LFO2_FREQ, vib_freq); 471 472 473 if (getGeneratorValue(generators, 474 SF2Region.GENERATOR_VIBLFOTOPITCH) != 0) { 475 double fvalue = getGeneratorValue(generators, 476 SF2Region.GENERATOR_VIBLFOTOPITCH); 477 ModelIdentifier src = ModelSource.SOURCE_LFO2; 478 ModelIdentifier dest = ModelDestination.DESTINATION_PITCH; 479 performer.getConnectionBlocks().add( 480 new ModelConnectionBlock( 481 new ModelSource(src, 482 ModelStandardTransform.DIRECTION_MIN2MAX, 483 ModelStandardTransform.POLARITY_BIPOLAR), 484 fvalue, new ModelDestination(dest))); 485 } 486 487 if (getGeneratorValue(generators, 488 SF2Region.GENERATOR_MODLFOTOFILTERFC) != 0) { 489 double fvalue = getGeneratorValue(generators, 490 SF2Region.GENERATOR_MODLFOTOFILTERFC); 491 ModelIdentifier src = ModelSource.SOURCE_LFO1; 492 ModelIdentifier dest = ModelDestination.DESTINATION_FILTER_FREQ; 493 performer.getConnectionBlocks().add( 494 new ModelConnectionBlock( 495 new ModelSource(src, 496 ModelStandardTransform.DIRECTION_MIN2MAX, 497 ModelStandardTransform.POLARITY_BIPOLAR), 498 fvalue, new ModelDestination(dest))); 499 } 500 501 if (getGeneratorValue(generators, 502 SF2Region.GENERATOR_MODLFOTOPITCH) != 0) { 503 double fvalue = getGeneratorValue(generators, 504 SF2Region.GENERATOR_MODLFOTOPITCH); 505 ModelIdentifier src = ModelSource.SOURCE_LFO1; 506 ModelIdentifier dest = ModelDestination.DESTINATION_PITCH; 507 performer.getConnectionBlocks().add( 508 new ModelConnectionBlock( 509 new ModelSource(src, 510 ModelStandardTransform.DIRECTION_MIN2MAX, 511 ModelStandardTransform.POLARITY_BIPOLAR), 512 fvalue, new ModelDestination(dest))); 513 } 514 515 if (getGeneratorValue(generators, 516 SF2Region.GENERATOR_MODLFOTOVOLUME) != 0) { 517 double fvalue = getGeneratorValue(generators, 518 SF2Region.GENERATOR_MODLFOTOVOLUME); 519 ModelIdentifier src = ModelSource.SOURCE_LFO1; 520 ModelIdentifier dest = ModelDestination.DESTINATION_GAIN; 521 performer.getConnectionBlocks().add( 522 new ModelConnectionBlock( 523 new ModelSource(src, 524 ModelStandardTransform.DIRECTION_MIN2MAX, 525 ModelStandardTransform.POLARITY_BIPOLAR), 526 fvalue, new ModelDestination(dest))); 527 } 528 529 if (layerzone.getShort(SF2Region.GENERATOR_KEYNUM) != -1) { 530 double val = layerzone.getShort(SF2Region.GENERATOR_KEYNUM)/128.0; 531 addValue(performer, ModelDestination.DESTINATION_KEYNUMBER, val); 532 } 533 534 if (layerzone.getShort(SF2Region.GENERATOR_VELOCITY) != -1) { 535 double val = layerzone.getShort(SF2Region.GENERATOR_VELOCITY) 536 / 128.0; 537 addValue(performer, ModelDestination.DESTINATION_VELOCITY, val); 538 } 539 540 if (getGeneratorValue(generators, 541 SF2Region.GENERATOR_INITIALFILTERFC) < 13500) { 542 short filter_freq = getGeneratorValue(generators, 543 SF2Region.GENERATOR_INITIALFILTERFC); 544 short filter_q = getGeneratorValue(generators, 545 SF2Region.GENERATOR_INITIALFILTERQ); 546 addValue(performer, 547 ModelDestination.DESTINATION_FILTER_FREQ, filter_freq); 548 addValue(performer, 549 ModelDestination.DESTINATION_FILTER_Q, filter_q); 550 } 551 552 int tune = 100 * getGeneratorValue(generators, 553 SF2Region.GENERATOR_COARSETUNE); 554 tune += getGeneratorValue(generators, 555 SF2Region.GENERATOR_FINETUNE); 556 if (tune != 0) { 557 addValue(performer, 558 ModelDestination.DESTINATION_PITCH, (short) tune); 559 } 560 if (getGeneratorValue(generators, SF2Region.GENERATOR_PAN) != 0) { 561 short val = getGeneratorValue(generators, 562 SF2Region.GENERATOR_PAN); 563 addValue(performer, ModelDestination.DESTINATION_PAN, val); 564 } 565 if (getGeneratorValue(generators, SF2Region.GENERATOR_INITIALATTENUATION) != 0) { 566 short val = getGeneratorValue(generators, 567 SF2Region.GENERATOR_INITIALATTENUATION); 568 addValue(performer, 569 ModelDestination.DESTINATION_GAIN, -0.376287f * val); 570 } 571 if (getGeneratorValue(generators, 572 SF2Region.GENERATOR_CHORUSEFFECTSSEND) != 0) { 573 short val = getGeneratorValue(generators, 574 SF2Region.GENERATOR_CHORUSEFFECTSSEND); 575 addValue(performer, ModelDestination.DESTINATION_CHORUS, val); 576 } 577 if (getGeneratorValue(generators, 578 SF2Region.GENERATOR_REVERBEFFECTSSEND) != 0) { 579 short val = getGeneratorValue(generators, 580 SF2Region.GENERATOR_REVERBEFFECTSSEND); 581 addValue(performer, ModelDestination.DESTINATION_REVERB, val); 582 } 583 if (getGeneratorValue(generators, 584 SF2Region.GENERATOR_SCALETUNING) != 100) { 585 short fvalue = getGeneratorValue(generators, 586 SF2Region.GENERATOR_SCALETUNING); 587 if (fvalue == 0) { 588 ModelIdentifier dest = ModelDestination.DESTINATION_PITCH; 589 performer.getConnectionBlocks().add( 590 new ModelConnectionBlock(null, rootkey * 100, 591 new ModelDestination(dest))); 592 } else { 593 ModelIdentifier dest = ModelDestination.DESTINATION_PITCH; 594 performer.getConnectionBlocks().add( 595 new ModelConnectionBlock(null, rootkey * (100 - fvalue), 596 new ModelDestination(dest))); 597 } 598 599 ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER; 600 ModelIdentifier dest = ModelDestination.DESTINATION_PITCH; 601 performer.getConnectionBlocks().add( 602 new ModelConnectionBlock(new ModelSource(src), 603 128 * fvalue, new ModelDestination(dest))); 604 605 } 606 607 performer.getConnectionBlocks().add( 608 new ModelConnectionBlock( 609 new ModelSource(ModelSource.SOURCE_NOTEON_VELOCITY, 610 new ModelTransform() { 611 public double transform(double value) { 612 if (value < 0.5) 613 return 1 - value * 2; 614 else 615 return 0; 616 } 617 }), 618 -2400, 619 new ModelDestination( 620 ModelDestination.DESTINATION_FILTER_FREQ))); 621 622 623 performer.getConnectionBlocks().add( 624 new ModelConnectionBlock( 625 new ModelSource(ModelSource.SOURCE_LFO2, 626 ModelStandardTransform.DIRECTION_MIN2MAX, 627 ModelStandardTransform.POLARITY_BIPOLAR, 628 ModelStandardTransform.TRANSFORM_LINEAR), 629 new ModelSource(new ModelIdentifier("midi_cc", "1", 0), 630 ModelStandardTransform.DIRECTION_MIN2MAX, 631 ModelStandardTransform.POLARITY_UNIPOLAR, 632 ModelStandardTransform.TRANSFORM_LINEAR), 633 50, new ModelDestination( 634 ModelDestination.DESTINATION_PITCH))); 635 636 if (layer.getGlobalRegion() != null) { 637 for (SF2Modulator modulator 638 : layer.getGlobalRegion().getModulators()) { 639 convertModulator(performer, modulator); 640 } 641 } 642 for (SF2Modulator modulator : layerzone.getModulators()) 643 convertModulator(performer, modulator); 644 645 if (presetglobal != null) { 646 for (SF2Modulator modulator : presetglobal.getModulators()) 647 convertModulator(performer, modulator); 648 } 649 for (SF2Modulator modulator : presetzone.getModulators()) 650 convertModulator(performer, modulator); 651 652 } 653 } 654 return performers; 655 } 656 657 private void convertModulator(ModelPerformer performer, 658 SF2Modulator modulator) { 659 ModelSource src1 = convertSource(modulator.getSourceOperator()); 660 ModelSource src2 = convertSource(modulator.getAmountSourceOperator()); 661 if (src1 == null && modulator.getSourceOperator() != 0) 662 return; 663 if (src2 == null && modulator.getAmountSourceOperator() != 0) 664 return; 665 double amount = modulator.getAmount(); 666 double[] amountcorrection = new double[1]; 667 ModelSource[] extrasrc = new ModelSource[1]; 668 amountcorrection[0] = 1; 669 ModelDestination dst = convertDestination( 670 modulator.getDestinationOperator(), amountcorrection, extrasrc); 671 amount *= amountcorrection[0]; 672 if (dst == null) 673 return; 674 if (modulator.getTransportOperator() == SF2Modulator.TRANSFORM_ABSOLUTE) { 675 ((ModelStandardTransform)dst.getTransform()).setTransform( 676 ModelStandardTransform.TRANSFORM_ABSOLUTE); 677 } 678 ModelConnectionBlock conn = new ModelConnectionBlock(src1, src2, amount, dst); 679 if (extrasrc[0] != null) 680 conn.addSource(extrasrc[0]); 681 performer.getConnectionBlocks().add(conn); 682 683 } 684 685 private static ModelSource convertSource(int src) { 686 if (src == 0) 687 return null; 688 ModelIdentifier id = null; 689 int idsrc = src & 0x7F; 690 if ((src & SF2Modulator.SOURCE_MIDI_CONTROL) != 0) { 691 id = new ModelIdentifier("midi_cc", Integer.toString(idsrc)); 692 } else { 693 if (idsrc == SF2Modulator.SOURCE_NOTE_ON_VELOCITY) 694 id = ModelSource.SOURCE_NOTEON_VELOCITY; 695 if (idsrc == SF2Modulator.SOURCE_NOTE_ON_KEYNUMBER) 696 id = ModelSource.SOURCE_NOTEON_KEYNUMBER; 697 if (idsrc == SF2Modulator.SOURCE_POLY_PRESSURE) 698 id = ModelSource.SOURCE_MIDI_POLY_PRESSURE; 699 if (idsrc == SF2Modulator.SOURCE_CHANNEL_PRESSURE) 700 id = ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE; 701 if (idsrc == SF2Modulator.SOURCE_PITCH_WHEEL) 702 id = ModelSource.SOURCE_MIDI_PITCH; 703 if (idsrc == SF2Modulator.SOURCE_PITCH_SENSITIVITY) 704 id = new ModelIdentifier("midi_rpn", "0"); 705 } 706 if (id == null) 707 return null; 708 709 ModelSource msrc = new ModelSource(id); 710 ModelStandardTransform transform 711 = (ModelStandardTransform) msrc.getTransform(); 712 713 if ((SF2Modulator.SOURCE_DIRECTION_MAX_MIN & src) != 0) 714 transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN); 715 else 716 transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX); 717 718 if ((SF2Modulator.SOURCE_POLARITY_BIPOLAR & src) != 0) 719 transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR); 720 else 721 transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR); 722 723 if ((SF2Modulator.SOURCE_TYPE_CONCAVE & src) != 0) 724 transform.setTransform(ModelStandardTransform.TRANSFORM_CONCAVE); 725 if ((SF2Modulator.SOURCE_TYPE_CONVEX & src) != 0) 726 transform.setTransform(ModelStandardTransform.TRANSFORM_CONVEX); 727 if ((SF2Modulator.SOURCE_TYPE_SWITCH & src) != 0) 728 transform.setTransform(ModelStandardTransform.TRANSFORM_SWITCH); 729 730 return msrc; 731 } 732 733 static ModelDestination convertDestination(int dst, 734 double[] amountcorrection, ModelSource[] extrasrc) { 735 ModelIdentifier id = null; 736 switch (dst) { 737 case SF2Region.GENERATOR_INITIALFILTERFC: 738 id = ModelDestination.DESTINATION_FILTER_FREQ; 739 break; 740 case SF2Region.GENERATOR_INITIALFILTERQ: 741 id = ModelDestination.DESTINATION_FILTER_Q; 742 break; 743 case SF2Region.GENERATOR_CHORUSEFFECTSSEND: 744 id = ModelDestination.DESTINATION_CHORUS; 745 break; 746 case SF2Region.GENERATOR_REVERBEFFECTSSEND: 747 id = ModelDestination.DESTINATION_REVERB; 748 break; 749 case SF2Region.GENERATOR_PAN: 750 id = ModelDestination.DESTINATION_PAN; 751 break; 752 case SF2Region.GENERATOR_DELAYMODLFO: 753 id = ModelDestination.DESTINATION_LFO1_DELAY; 754 break; 755 case SF2Region.GENERATOR_FREQMODLFO: 756 id = ModelDestination.DESTINATION_LFO1_FREQ; 757 break; 758 case SF2Region.GENERATOR_DELAYVIBLFO: 759 id = ModelDestination.DESTINATION_LFO2_DELAY; 760 break; 761 case SF2Region.GENERATOR_FREQVIBLFO: 762 id = ModelDestination.DESTINATION_LFO2_FREQ; 763 break; 764 765 case SF2Region.GENERATOR_DELAYMODENV: 766 id = ModelDestination.DESTINATION_EG2_DELAY; 767 break; 768 case SF2Region.GENERATOR_ATTACKMODENV: 769 id = ModelDestination.DESTINATION_EG2_ATTACK; 770 break; 771 case SF2Region.GENERATOR_HOLDMODENV: 772 id = ModelDestination.DESTINATION_EG2_HOLD; 773 break; 774 case SF2Region.GENERATOR_DECAYMODENV: 775 id = ModelDestination.DESTINATION_EG2_DECAY; 776 break; 777 case SF2Region.GENERATOR_SUSTAINMODENV: 778 id = ModelDestination.DESTINATION_EG2_SUSTAIN; 779 amountcorrection[0] = -1; 780 break; 781 case SF2Region.GENERATOR_RELEASEMODENV: 782 id = ModelDestination.DESTINATION_EG2_RELEASE; 783 break; 784 case SF2Region.GENERATOR_DELAYVOLENV: 785 id = ModelDestination.DESTINATION_EG1_DELAY; 786 break; 787 case SF2Region.GENERATOR_ATTACKVOLENV: 788 id = ModelDestination.DESTINATION_EG1_ATTACK; 789 break; 790 case SF2Region.GENERATOR_HOLDVOLENV: 791 id = ModelDestination.DESTINATION_EG1_HOLD; 792 break; 793 case SF2Region.GENERATOR_DECAYVOLENV: 794 id = ModelDestination.DESTINATION_EG1_DECAY; 795 break; 796 case SF2Region.GENERATOR_SUSTAINVOLENV: 797 id = ModelDestination.DESTINATION_EG1_SUSTAIN; 798 amountcorrection[0] = -1; 799 break; 800 case SF2Region.GENERATOR_RELEASEVOLENV: 801 id = ModelDestination.DESTINATION_EG1_RELEASE; 802 break; 803 case SF2Region.GENERATOR_KEYNUM: 804 id = ModelDestination.DESTINATION_KEYNUMBER; 805 break; 806 case SF2Region.GENERATOR_VELOCITY: 807 id = ModelDestination.DESTINATION_VELOCITY; 808 break; 809 810 case SF2Region.GENERATOR_COARSETUNE: 811 amountcorrection[0] = 100; 812 id = ModelDestination.DESTINATION_PITCH; 813 break; 814 815 case SF2Region.GENERATOR_FINETUNE: 816 id = ModelDestination.DESTINATION_PITCH; 817 break; 818 819 case SF2Region.GENERATOR_INITIALATTENUATION: 820 id = ModelDestination.DESTINATION_GAIN; 821 amountcorrection[0] = -0.376287f; 822 break; 823 824 case SF2Region.GENERATOR_VIBLFOTOPITCH: 825 id = ModelDestination.DESTINATION_PITCH; 826 extrasrc[0] = new ModelSource( 827 ModelSource.SOURCE_LFO2, 828 ModelStandardTransform.DIRECTION_MIN2MAX, 829 ModelStandardTransform.POLARITY_BIPOLAR); 830 break; 831 832 case SF2Region.GENERATOR_MODLFOTOPITCH: 833 id = ModelDestination.DESTINATION_PITCH; 834 extrasrc[0] = new ModelSource( 835 ModelSource.SOURCE_LFO1, 836 ModelStandardTransform.DIRECTION_MIN2MAX, 837 ModelStandardTransform.POLARITY_BIPOLAR); 838 break; 839 840 case SF2Region.GENERATOR_MODLFOTOFILTERFC: 841 id = ModelDestination.DESTINATION_FILTER_FREQ; 842 extrasrc[0] = new ModelSource( 843 ModelSource.SOURCE_LFO1, 844 ModelStandardTransform.DIRECTION_MIN2MAX, 845 ModelStandardTransform.POLARITY_BIPOLAR); 846 break; 847 848 case SF2Region.GENERATOR_MODLFOTOVOLUME: 849 id = ModelDestination.DESTINATION_GAIN; 850 amountcorrection[0] = -0.376287f; 851 extrasrc[0] = new ModelSource( 852 ModelSource.SOURCE_LFO1, 853 ModelStandardTransform.DIRECTION_MIN2MAX, 854 ModelStandardTransform.POLARITY_BIPOLAR); 855 break; 856 857 case SF2Region.GENERATOR_MODENVTOPITCH: 858 id = ModelDestination.DESTINATION_PITCH; 859 extrasrc[0] = new ModelSource( 860 ModelSource.SOURCE_EG2, 861 ModelStandardTransform.DIRECTION_MIN2MAX, 862 ModelStandardTransform.POLARITY_BIPOLAR); 863 break; 864 865 case SF2Region.GENERATOR_MODENVTOFILTERFC: 866 id = ModelDestination.DESTINATION_FILTER_FREQ; 867 extrasrc[0] = new ModelSource( 868 ModelSource.SOURCE_EG2, 869 ModelStandardTransform.DIRECTION_MIN2MAX, 870 ModelStandardTransform.POLARITY_BIPOLAR); 871 break; 872 873 default: 874 break; 875 } 876 if (id != null) 877 return new ModelDestination(id); 878 return null; 879 } 880 881 private void addTimecentValue(ModelPerformer performer, 882 ModelIdentifier dest, short value) { 883 double fvalue; 884 if (value == -12000) 885 fvalue = Double.NEGATIVE_INFINITY; 886 else 887 fvalue = value; 888 performer.getConnectionBlocks().add( 889 new ModelConnectionBlock(fvalue, new ModelDestination(dest))); 890 } 891 892 private void addValue(ModelPerformer performer, 893 ModelIdentifier dest, short value) { 894 double fvalue = value; 895 performer.getConnectionBlocks().add( 896 new ModelConnectionBlock(fvalue, new ModelDestination(dest))); 897 } 898 899 private void addValue(ModelPerformer performer, 900 ModelIdentifier dest, double value) { 901 double fvalue = value; 902 performer.getConnectionBlocks().add( 903 new ModelConnectionBlock(fvalue, new ModelDestination(dest))); 904 } 905 906 private short getGeneratorValue(Map<Integer, Short> generators, int gen) { 907 if (generators.containsKey(gen)) 908 return generators.get(gen); 909 return SF2Region.getDefaultValue(gen); 910 } 911 }