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