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.Arrays; 30 import java.util.HashMap; 31 import java.util.Iterator; 32 import java.util.List; 33 import java.util.Map; 34 35 import javax.sound.midi.MidiChannel; 36 import javax.sound.midi.Patch; 37 38 /** 39 * Software Synthesizer MIDI channel class. 40 * 41 * @author Karl Helgason 42 */ 43 public final class SoftChannel implements MidiChannel, ModelDirectedPlayer { 44 45 private static final boolean[] dontResetControls = new boolean[128]; 46 static { 47 for (int i = 0; i < dontResetControls.length; i++) 48 dontResetControls[i] = false; 49 50 dontResetControls[0] = true; // Bank Select (MSB) 51 dontResetControls[32] = true; // Bank Select (LSB) 52 dontResetControls[7] = true; // Channel Volume (MSB) 53 dontResetControls[8] = true; // Balance (MSB) 54 dontResetControls[10] = true; // Pan (MSB) 55 dontResetControls[11] = true; // Expression (MSB) 56 dontResetControls[91] = true; // Effects 1 Depth (default: Reverb Send) 57 dontResetControls[92] = true; // Effects 2 Depth (default: Tremolo Depth) 58 dontResetControls[93] = true; // Effects 3 Depth (default: Chorus Send) 59 dontResetControls[94] = true; // Effects 4 Depth (default: Celeste [Detune] Depth) 60 dontResetControls[95] = true; // Effects 5 Depth (default: Phaser Depth) 61 dontResetControls[70] = true; // Sound Controller 1 (default: Sound Variation) 62 dontResetControls[71] = true; // Sound Controller 2 (default: Timbre / Harmonic Quality) 63 dontResetControls[72] = true; // Sound Controller 3 (default: Release Time) 64 dontResetControls[73] = true; // Sound Controller 4 (default: Attack Time) 65 dontResetControls[74] = true; // Sound Controller 5 (default: Brightness) 66 dontResetControls[75] = true; // Sound Controller 6 (GM2 default: Decay Time) 67 dontResetControls[76] = true; // Sound Controller 7 (GM2 default: Vibrato Rate) 68 dontResetControls[77] = true; // Sound Controller 8 (GM2 default: Vibrato Depth) 69 dontResetControls[78] = true; // Sound Controller 9 (GM2 default: Vibrato Delay) 70 dontResetControls[79] = true; // Sound Controller 10 (GM2 default: Undefined) 71 dontResetControls[120] = true; // All Sound Off 72 dontResetControls[121] = true; // Reset All Controllers 73 dontResetControls[122] = true; // Local Control On/Off 74 dontResetControls[123] = true; // All Notes Off 75 dontResetControls[124] = true; // Omni Mode Off 76 dontResetControls[125] = true; // Omni Mode On 77 dontResetControls[126] = true; // Poly Mode Off 78 dontResetControls[127] = true; // Poly Mode On 79 80 dontResetControls[6] = true; // Data Entry (MSB) 81 dontResetControls[38] = true; // Data Entry (LSB) 82 dontResetControls[96] = true; // Data Increment 83 dontResetControls[97] = true; // Data Decrement 84 dontResetControls[98] = true; // Non-Registered Parameter Number (LSB) 85 dontResetControls[99] = true; // Non-Registered Parameter Number(MSB) 86 dontResetControls[100] = true; // RPN = Null 87 dontResetControls[101] = true; // RPN = Null 88 89 } 90 91 private static final int RPN_NULL_VALUE = (127 << 7) + 127; 92 private int rpn_control = RPN_NULL_VALUE; 93 private int nrpn_control = RPN_NULL_VALUE; 94 double portamento_time = 1; // keyschanges per control buffer time 95 int[] portamento_lastnote = new int[128]; 96 int portamento_lastnote_ix = 0; 97 private boolean portamento = false; 98 private boolean mono = false; 99 private boolean mute = false; 100 private boolean solo = false; 101 private boolean solomute = false; 102 private final Object control_mutex; 103 private final int channel; 104 private final SoftVoice[] voices; 105 private int bank; 106 private int program; 107 private final SoftSynthesizer synthesizer; 108 private final SoftMainMixer mainmixer; 109 private final int[] polypressure = new int[128]; 110 private int channelpressure = 0; 111 private final int[] controller = new int[128]; 112 private int pitchbend; 113 private final double[] co_midi_pitch = new double[1]; 114 private final double[] co_midi_channel_pressure = new double[1]; 115 SoftTuning tuning = new SoftTuning(); 116 int tuning_bank = 0; 117 int tuning_program = 0; 118 SoftInstrument current_instrument = null; 119 ModelChannelMixer current_mixer = null; 120 ModelDirector current_director = null; 121 122 // Controller Destination Settings 123 int cds_control_number = -1; 124 ModelConnectionBlock[] cds_control_connections = null; 125 ModelConnectionBlock[] cds_channelpressure_connections = null; 126 ModelConnectionBlock[] cds_polypressure_connections = null; 127 boolean sustain = false; 128 boolean[][] keybasedcontroller_active = null; 129 double[][] keybasedcontroller_value = null; 130 131 private class MidiControlObject implements SoftControl { 132 double[] pitch = co_midi_pitch; 133 double[] channel_pressure = co_midi_channel_pressure; 134 double[] poly_pressure = new double[1]; 135 136 @Override get(int instance, String name)137 public double[] get(int instance, String name) { 138 if (name == null) 139 return null; 140 if (name.equals("pitch")) 141 return pitch; 142 if (name.equals("channel_pressure")) 143 return channel_pressure; 144 if (name.equals("poly_pressure")) 145 return poly_pressure; 146 return null; 147 } 148 } 149 150 private final SoftControl[] co_midi = new SoftControl[128]; 151 { 152 for (int i = 0; i < co_midi.length; i++) { 153 co_midi[i] = new MidiControlObject(); 154 } 155 } 156 157 private final double[][] co_midi_cc_cc = new double[128][1]; 158 private final SoftControl co_midi_cc = new SoftControl() { 159 double[][] cc = co_midi_cc_cc; 160 @Override 161 public double[] get(int instance, String name) { 162 if (name == null) 163 return null; 164 return cc[Integer.parseInt(name)]; 165 } 166 }; 167 Map<Integer, int[]> co_midi_rpn_rpn_i = new HashMap<>(); 168 Map<Integer, double[]> co_midi_rpn_rpn = new HashMap<>(); 169 private final SoftControl co_midi_rpn = new SoftControl() { 170 Map<Integer, double[]> rpn = co_midi_rpn_rpn; 171 @Override 172 public double[] get(int instance, String name) { 173 if (name == null) 174 return null; 175 int iname = Integer.parseInt(name); 176 double[] v = rpn.get(iname); 177 if (v == null) { 178 v = new double[1]; 179 rpn.put(iname, v); 180 } 181 return v; 182 } 183 }; 184 Map<Integer, int[]> co_midi_nrpn_nrpn_i = new HashMap<>(); 185 Map<Integer, double[]> co_midi_nrpn_nrpn = new HashMap<>(); 186 private final SoftControl co_midi_nrpn = new SoftControl() { 187 Map<Integer, double[]> nrpn = co_midi_nrpn_nrpn; 188 @Override 189 public double[] get(int instance, String name) { 190 if (name == null) 191 return null; 192 int iname = Integer.parseInt(name); 193 double[] v = nrpn.get(iname); 194 if (v == null) { 195 v = new double[1]; 196 nrpn.put(iname, v); 197 } 198 return v; 199 } 200 }; 201 restrict7Bit(int value)202 private static int restrict7Bit(int value) 203 { 204 if(value < 0) return 0; 205 if(value > 127) return 127; 206 return value; 207 } 208 restrict14Bit(int value)209 private static int restrict14Bit(int value) 210 { 211 if(value < 0) return 0; 212 if(value > 16256) return 16256; 213 return value; 214 } 215 SoftChannel(SoftSynthesizer synth, int channel)216 public SoftChannel(SoftSynthesizer synth, int channel) { 217 this.channel = channel; 218 this.voices = synth.getVoices(); 219 this.synthesizer = synth; 220 this.mainmixer = synth.getMainMixer(); 221 control_mutex = synth.control_mutex; 222 resetAllControllers(true); 223 } 224 findFreeVoice(int x)225 private int findFreeVoice(int x) { 226 if(x == -1) 227 { 228 // x = -1 means that there where no available voice 229 // last time we called findFreeVoice 230 // and it hasn't changed because no audio has been 231 // rendered in the meantime. 232 // Therefore we have to return -1. 233 return -1; 234 } 235 for (int i = x; i < voices.length; i++) 236 if (!voices[i].active) 237 return i; 238 239 // No free voice was found, we must steal one 240 241 int vmode = synthesizer.getVoiceAllocationMode(); 242 if (vmode == 1) { 243 // DLS Static Voice Allocation 244 245 // * priority ( 10, 1-9, 11-16) 246 // Search for channel to steal from 247 int steal_channel = channel; 248 for (int j = 0; j < voices.length; j++) { 249 if (voices[j].stealer_channel == null) { 250 if (steal_channel == 9) { 251 steal_channel = voices[j].channel; 252 } else { 253 if (voices[j].channel != 9) { 254 if (voices[j].channel > steal_channel) 255 steal_channel = voices[j].channel; 256 } 257 } 258 } 259 } 260 261 int voiceNo = -1; 262 263 SoftVoice v = null; 264 // Search for oldest voice in off state on steal_channel 265 for (int j = 0; j < voices.length; j++) { 266 if (voices[j].channel == steal_channel) { 267 if (voices[j].stealer_channel == null && !voices[j].on) { 268 if (v == null) { 269 v = voices[j]; 270 voiceNo = j; 271 } 272 if (voices[j].voiceID < v.voiceID) { 273 v = voices[j]; 274 voiceNo = j; 275 } 276 } 277 } 278 } 279 // Search for oldest voice in on state on steal_channel 280 if (voiceNo == -1) { 281 for (int j = 0; j < voices.length; j++) { 282 if (voices[j].channel == steal_channel) { 283 if (voices[j].stealer_channel == null) { 284 if (v == null) { 285 v = voices[j]; 286 voiceNo = j; 287 } 288 if (voices[j].voiceID < v.voiceID) { 289 v = voices[j]; 290 voiceNo = j; 291 } 292 } 293 } 294 } 295 } 296 297 return voiceNo; 298 299 } else { 300 // Default Voice Allocation 301 // * Find voice that is on 302 // and Find voice which has lowest voiceID ( oldest voice) 303 // * Or find voice that is off 304 // and Find voice which has lowest voiceID ( oldest voice) 305 306 int voiceNo = -1; 307 308 SoftVoice v = null; 309 // Search for oldest voice in off state 310 for (int j = 0; j < voices.length; j++) { 311 if (voices[j].stealer_channel == null && !voices[j].on) { 312 if (v == null) { 313 v = voices[j]; 314 voiceNo = j; 315 } 316 if (voices[j].voiceID < v.voiceID) { 317 v = voices[j]; 318 voiceNo = j; 319 } 320 } 321 } 322 // Search for oldest voice in on state 323 if (voiceNo == -1) { 324 325 for (int j = 0; j < voices.length; j++) { 326 if (voices[j].stealer_channel == null) { 327 if (v == null) { 328 v = voices[j]; 329 voiceNo = j; 330 } 331 if (voices[j].voiceID < v.voiceID) { 332 v = voices[j]; 333 voiceNo = j; 334 } 335 } 336 } 337 } 338 339 return voiceNo; 340 } 341 342 } 343 initVoice(SoftVoice voice, SoftPerformer p, int voiceID, int noteNumber, int velocity, int delay, ModelConnectionBlock[] connectionBlocks, ModelChannelMixer channelmixer, boolean releaseTriggered)344 void initVoice(SoftVoice voice, SoftPerformer p, int voiceID, 345 int noteNumber, int velocity, int delay, ModelConnectionBlock[] connectionBlocks, 346 ModelChannelMixer channelmixer, boolean releaseTriggered) { 347 if (voice.active) { 348 // Voice is active , we must steal the voice 349 voice.stealer_channel = this; 350 voice.stealer_performer = p; 351 voice.stealer_voiceID = voiceID; 352 voice.stealer_noteNumber = noteNumber; 353 voice.stealer_velocity = velocity; 354 voice.stealer_extendedConnectionBlocks = connectionBlocks; 355 voice.stealer_channelmixer = channelmixer; 356 voice.stealer_releaseTriggered = releaseTriggered; 357 for (int i = 0; i < voices.length; i++) 358 if (voices[i].active && voices[i].voiceID == voice.voiceID) 359 voices[i].soundOff(); 360 return; 361 } 362 363 voice.extendedConnectionBlocks = connectionBlocks; 364 voice.channelmixer = channelmixer; 365 voice.releaseTriggered = releaseTriggered; 366 voice.voiceID = voiceID; 367 voice.tuning = tuning; 368 voice.exclusiveClass = p.exclusiveClass; 369 voice.softchannel = this; 370 voice.channel = channel; 371 voice.bank = bank; 372 voice.program = program; 373 voice.instrument = current_instrument; 374 voice.performer = p; 375 voice.objects.clear(); 376 voice.objects.put("midi", co_midi[noteNumber]); 377 voice.objects.put("midi_cc", co_midi_cc); 378 voice.objects.put("midi_rpn", co_midi_rpn); 379 voice.objects.put("midi_nrpn", co_midi_nrpn); 380 voice.noteOn(noteNumber, velocity, delay); 381 voice.setMute(mute); 382 voice.setSoloMute(solomute); 383 if (releaseTriggered) 384 return; 385 if (controller[84] != 0) { 386 voice.co_noteon_keynumber[0] 387 = (tuning.getTuning(controller[84]) / 100.0) 388 * (1f / 128f); 389 voice.portamento = true; 390 controlChange(84, 0); 391 } else if (portamento) { 392 if (mono) { 393 if (portamento_lastnote[0] != -1) { 394 voice.co_noteon_keynumber[0] 395 = (tuning.getTuning(portamento_lastnote[0]) / 100.0) 396 * (1f / 128f); 397 voice.portamento = true; 398 controlChange(84, 0); 399 } 400 portamento_lastnote[0] = noteNumber; 401 } else { 402 if (portamento_lastnote_ix != 0) { 403 portamento_lastnote_ix--; 404 voice.co_noteon_keynumber[0] 405 = (tuning.getTuning( 406 portamento_lastnote[portamento_lastnote_ix]) 407 / 100.0) 408 * (1f / 128f); 409 voice.portamento = true; 410 } 411 } 412 } 413 } 414 415 @Override noteOn(int noteNumber, int velocity)416 public void noteOn(int noteNumber, int velocity) { 417 noteOn(noteNumber, velocity, 0); 418 } 419 420 /* A special noteOn with delay parameter, which is used to 421 * start note within control buffers. 422 */ noteOn(int noteNumber, int velocity, int delay)423 void noteOn(int noteNumber, int velocity, int delay) { 424 noteNumber = restrict7Bit(noteNumber); 425 velocity = restrict7Bit(velocity); 426 noteOn_internal(noteNumber, velocity, delay); 427 if (current_mixer != null) 428 current_mixer.noteOn(noteNumber, velocity); 429 } 430 noteOn_internal(int noteNumber, int velocity, int delay)431 private void noteOn_internal(int noteNumber, int velocity, int delay) { 432 433 if (velocity == 0) { 434 noteOff_internal(noteNumber, 64); 435 return; 436 } 437 438 synchronized (control_mutex) { 439 if (sustain) { 440 sustain = false; 441 for (int i = 0; i < voices.length; i++) { 442 if ((voices[i].sustain || voices[i].on) 443 && voices[i].channel == channel && voices[i].active 444 && voices[i].note == noteNumber) { 445 voices[i].sustain = false; 446 voices[i].on = true; 447 voices[i].noteOff(0); 448 } 449 } 450 sustain = true; 451 } 452 453 mainmixer.activity(); 454 455 if (mono) { 456 if (portamento) { 457 boolean n_found = false; 458 for (int i = 0; i < voices.length; i++) { 459 if (voices[i].on && voices[i].channel == channel 460 && voices[i].active 461 && voices[i].releaseTriggered == false) { 462 voices[i].portamento = true; 463 voices[i].setNote(noteNumber); 464 n_found = true; 465 } 466 } 467 if (n_found) { 468 portamento_lastnote[0] = noteNumber; 469 return; 470 } 471 } 472 473 if (controller[84] != 0) { 474 boolean n_found = false; 475 for (int i = 0; i < voices.length; i++) { 476 if (voices[i].on && voices[i].channel == channel 477 && voices[i].active 478 && voices[i].note == controller[84] 479 && voices[i].releaseTriggered == false) { 480 voices[i].portamento = true; 481 voices[i].setNote(noteNumber); 482 n_found = true; 483 } 484 } 485 controlChange(84, 0); 486 if (n_found) 487 return; 488 } 489 } 490 491 if (mono) 492 allNotesOff(); 493 494 if (current_instrument == null) { 495 current_instrument 496 = synthesizer.findInstrument(program, bank, channel); 497 if (current_instrument == null) 498 return; 499 if (current_mixer != null) 500 mainmixer.stopMixer(current_mixer); 501 current_mixer = current_instrument.getSourceInstrument() 502 .getChannelMixer(this, synthesizer.getFormat()); 503 if (current_mixer != null) 504 mainmixer.registerMixer(current_mixer); 505 current_director = current_instrument.getDirector(this, this); 506 applyInstrumentCustomization(); 507 } 508 prevVoiceID = synthesizer.voiceIDCounter++; 509 firstVoice = true; 510 voiceNo = 0; 511 512 int tunedKey = (int)(Math.round(tuning.getTuning(noteNumber)/100.0)); 513 play_noteNumber = noteNumber; 514 play_velocity = velocity; 515 play_delay = delay; 516 play_releasetriggered = false; 517 lastVelocity[noteNumber] = velocity; 518 current_director.noteOn(tunedKey, velocity); 519 520 /* 521 SoftPerformer[] performers = current_instrument.getPerformers(); 522 for (int i = 0; i < performers.length; i++) { 523 SoftPerformer p = performers[i]; 524 if (p.keyFrom <= tunedKey && p.keyTo >= tunedKey) { 525 if (p.velFrom <= velocity && p.velTo >= velocity) { 526 if (firstVoice) { 527 firstVoice = false; 528 if (p.exclusiveClass != 0) { 529 int x = p.exclusiveClass; 530 for (int j = 0; j < voices.length; j++) { 531 if (voices[j].active 532 && voices[j].channel == channel 533 && voices[j].exclusiveClass == x) { 534 if (!(p.selfNonExclusive 535 && voices[j].note == noteNumber)) 536 voices[j].shutdown(); 537 } 538 } 539 } 540 } 541 voiceNo = findFreeVoice(voiceNo); 542 if (voiceNo == -1) 543 return; 544 initVoice(voices[voiceNo], p, prevVoiceID, noteNumber, 545 velocity); 546 } 547 } 548 } 549 */ 550 } 551 } 552 553 @Override noteOff(int noteNumber, int velocity)554 public void noteOff(int noteNumber, int velocity) { 555 noteNumber = restrict7Bit(noteNumber); 556 velocity = restrict7Bit(velocity); 557 noteOff_internal(noteNumber, velocity); 558 559 if (current_mixer != null) 560 current_mixer.noteOff(noteNumber, velocity); 561 } 562 noteOff_internal(int noteNumber, int velocity)563 private void noteOff_internal(int noteNumber, int velocity) { 564 synchronized (control_mutex) { 565 566 if (!mono) { 567 if (portamento) { 568 if (portamento_lastnote_ix != 127) { 569 portamento_lastnote[portamento_lastnote_ix] = noteNumber; 570 portamento_lastnote_ix++; 571 } 572 } 573 } 574 575 mainmixer.activity(); 576 for (int i = 0; i < voices.length; i++) { 577 if (voices[i].on && voices[i].channel == channel 578 && voices[i].note == noteNumber 579 && voices[i].releaseTriggered == false) { 580 voices[i].noteOff(velocity); 581 } 582 // We must also check stolen voices 583 if (voices[i].stealer_channel == this && voices[i].stealer_noteNumber == noteNumber) { 584 SoftVoice v = voices[i]; 585 v.stealer_releaseTriggered = false; 586 v.stealer_channel = null; 587 v.stealer_performer = null; 588 v.stealer_voiceID = -1; 589 v.stealer_noteNumber = 0; 590 v.stealer_velocity = 0; 591 v.stealer_extendedConnectionBlocks = null; 592 v.stealer_channelmixer = null; 593 } 594 } 595 596 // Try play back note-off triggered voices, 597 598 if (current_instrument == null) { 599 current_instrument 600 = synthesizer.findInstrument(program, bank, channel); 601 if (current_instrument == null) 602 return; 603 if (current_mixer != null) 604 mainmixer.stopMixer(current_mixer); 605 current_mixer = current_instrument.getSourceInstrument() 606 .getChannelMixer(this, synthesizer.getFormat()); 607 if (current_mixer != null) 608 mainmixer.registerMixer(current_mixer); 609 current_director = current_instrument.getDirector(this, this); 610 applyInstrumentCustomization(); 611 612 } 613 prevVoiceID = synthesizer.voiceIDCounter++; 614 firstVoice = true; 615 voiceNo = 0; 616 617 int tunedKey = (int)(Math.round(tuning.getTuning(noteNumber)/100.0)); 618 play_noteNumber = noteNumber; 619 play_velocity = lastVelocity[noteNumber]; 620 play_releasetriggered = true; 621 play_delay = 0; 622 current_director.noteOff(tunedKey, velocity); 623 624 } 625 } 626 private final int[] lastVelocity = new int[128]; 627 private int prevVoiceID; 628 private boolean firstVoice = true; 629 private int voiceNo = 0; 630 private int play_noteNumber = 0; 631 private int play_velocity = 0; 632 private int play_delay = 0; 633 private boolean play_releasetriggered = false; 634 635 @Override play(int performerIndex, ModelConnectionBlock[] connectionBlocks)636 public void play(int performerIndex, ModelConnectionBlock[] connectionBlocks) { 637 638 int noteNumber = play_noteNumber; 639 int velocity = play_velocity; 640 int delay = play_delay; 641 boolean releasetriggered = play_releasetriggered; 642 643 SoftPerformer p = current_instrument.getPerformer(performerIndex); 644 645 if (firstVoice) { 646 firstVoice = false; 647 if (p.exclusiveClass != 0) { 648 int x = p.exclusiveClass; 649 for (int j = 0; j < voices.length; j++) { 650 if (voices[j].active && voices[j].channel == channel 651 && voices[j].exclusiveClass == x) { 652 if (!(p.selfNonExclusive && voices[j].note == noteNumber)) 653 voices[j].shutdown(); 654 } 655 } 656 } 657 } 658 659 voiceNo = findFreeVoice(voiceNo); 660 661 if (voiceNo == -1) 662 return; 663 664 initVoice(voices[voiceNo], p, prevVoiceID, noteNumber, velocity, delay, 665 connectionBlocks, current_mixer, releasetriggered); 666 } 667 668 @Override noteOff(int noteNumber)669 public void noteOff(int noteNumber) { 670 if(noteNumber < 0 || noteNumber > 127) return; 671 noteOff_internal(noteNumber, 64); 672 } 673 674 @Override setPolyPressure(int noteNumber, int pressure)675 public void setPolyPressure(int noteNumber, int pressure) { 676 noteNumber = restrict7Bit(noteNumber); 677 pressure = restrict7Bit(pressure); 678 679 if (current_mixer != null) 680 current_mixer.setPolyPressure(noteNumber, pressure); 681 682 synchronized (control_mutex) { 683 mainmixer.activity(); 684 co_midi[noteNumber].get(0, "poly_pressure")[0] = pressure*(1.0/128.0); 685 polypressure[noteNumber] = pressure; 686 for (int i = 0; i < voices.length; i++) { 687 if (voices[i].active && voices[i].note == noteNumber) 688 voices[i].setPolyPressure(pressure); 689 } 690 } 691 } 692 693 @Override getPolyPressure(int noteNumber)694 public int getPolyPressure(int noteNumber) { 695 synchronized (control_mutex) { 696 return polypressure[noteNumber]; 697 } 698 } 699 700 @Override setChannelPressure(int pressure)701 public void setChannelPressure(int pressure) { 702 pressure = restrict7Bit(pressure); 703 if (current_mixer != null) 704 current_mixer.setChannelPressure(pressure); 705 synchronized (control_mutex) { 706 mainmixer.activity(); 707 co_midi_channel_pressure[0] = pressure * (1.0 / 128.0); 708 channelpressure = pressure; 709 for (int i = 0; i < voices.length; i++) { 710 if (voices[i].active) 711 voices[i].setChannelPressure(pressure); 712 } 713 } 714 } 715 716 @Override getChannelPressure()717 public int getChannelPressure() { 718 synchronized (control_mutex) { 719 return channelpressure; 720 } 721 } 722 applyInstrumentCustomization()723 void applyInstrumentCustomization() { 724 if (cds_control_connections == null 725 && cds_channelpressure_connections == null 726 && cds_polypressure_connections == null) { 727 return; 728 } 729 730 ModelInstrument src_instrument = current_instrument.getSourceInstrument(); 731 ModelPerformer[] performers = src_instrument.getPerformers(); 732 ModelPerformer[] new_performers = new ModelPerformer[performers.length]; 733 for (int i = 0; i < new_performers.length; i++) { 734 ModelPerformer performer = performers[i]; 735 ModelPerformer new_performer = new ModelPerformer(); 736 new_performer.setName(performer.getName()); 737 new_performer.setExclusiveClass(performer.getExclusiveClass()); 738 new_performer.setKeyFrom(performer.getKeyFrom()); 739 new_performer.setKeyTo(performer.getKeyTo()); 740 new_performer.setVelFrom(performer.getVelFrom()); 741 new_performer.setVelTo(performer.getVelTo()); 742 new_performer.getOscillators().addAll(performer.getOscillators()); 743 new_performer.getConnectionBlocks().addAll( 744 performer.getConnectionBlocks()); 745 new_performers[i] = new_performer; 746 747 List<ModelConnectionBlock> connblocks = 748 new_performer.getConnectionBlocks(); 749 750 if (cds_control_connections != null) { 751 String cc = Integer.toString(cds_control_number); 752 Iterator<ModelConnectionBlock> iter = connblocks.iterator(); 753 while (iter.hasNext()) { 754 ModelConnectionBlock conn = iter.next(); 755 ModelSource[] sources = conn.getSources(); 756 boolean removeok = false; 757 if (sources != null) { 758 for (int j = 0; j < sources.length; j++) { 759 ModelSource src = sources[j]; 760 if ("midi_cc".equals(src.getIdentifier().getObject()) 761 && cc.equals(src.getIdentifier().getVariable())) { 762 removeok = true; 763 } 764 } 765 } 766 if (removeok) 767 iter.remove(); 768 } 769 for (int j = 0; j < cds_control_connections.length; j++) 770 connblocks.add(cds_control_connections[j]); 771 } 772 773 if (cds_polypressure_connections != null) { 774 Iterator<ModelConnectionBlock> iter = connblocks.iterator(); 775 while (iter.hasNext()) { 776 ModelConnectionBlock conn = iter.next(); 777 ModelSource[] sources = conn.getSources(); 778 boolean removeok = false; 779 if (sources != null) { 780 for (int j = 0; j < sources.length; j++) { 781 ModelSource src = sources[j]; 782 if ("midi".equals(src.getIdentifier().getObject()) 783 && "poly_pressure".equals( 784 src.getIdentifier().getVariable())) { 785 removeok = true; 786 } 787 } 788 } 789 if (removeok) 790 iter.remove(); 791 } 792 for (int j = 0; j < cds_polypressure_connections.length; j++) 793 connblocks.add(cds_polypressure_connections[j]); 794 } 795 796 797 if (cds_channelpressure_connections != null) { 798 Iterator<ModelConnectionBlock> iter = connblocks.iterator(); 799 while (iter.hasNext()) { 800 ModelConnectionBlock conn = iter.next(); 801 ModelSource[] sources = conn.getSources(); 802 boolean removeok = false; 803 if (sources != null) { 804 for (int j = 0; j < sources.length; j++) { 805 ModelIdentifier srcid = sources[j].getIdentifier(); 806 if ("midi".equals(srcid.getObject()) && 807 "channel_pressure".equals(srcid.getVariable())) { 808 removeok = true; 809 } 810 } 811 } 812 if (removeok) 813 iter.remove(); 814 } 815 for (int j = 0; j < cds_channelpressure_connections.length; j++) 816 connblocks.add(cds_channelpressure_connections[j]); 817 } 818 819 } 820 821 current_instrument = new SoftInstrument(src_instrument, new_performers); 822 823 } 824 createModelConnections(ModelIdentifier sid, int[] destination, int[] range)825 private ModelConnectionBlock[] createModelConnections(ModelIdentifier sid, 826 int[] destination, int[] range) { 827 828 /* 829 controlled parameter (pp)|range (rr)| Description |Default 830 -------------------------|----------|-------------------------|------- 831 00 Pitch Control | 28H..58H | -24..+24 semitones | 40H 832 01 Filter Cutoff Control | 00H..7FH | -9600..+9450 cents | 40H 833 02 Amplitude Control | 00H..7FH | 0..(127/64)*100 percent | 40H 834 03 LFO Pitch Depth | 00H..7FH | 0..600 cents | 0 835 04 LFO Filter Depth | 00H..7FH | 0..2400 cents | 0 836 05 LFO Amplitude Depth | 00H..7FH | 0..100 percent | 0 837 */ 838 839 List<ModelConnectionBlock> conns = new ArrayList<>(); 840 841 for (int i = 0; i < destination.length; i++) { 842 int d = destination[i]; 843 int r = range[i]; 844 if (d == 0) { 845 double scale = (r - 64) * 100; 846 ModelConnectionBlock conn = new ModelConnectionBlock( 847 new ModelSource(sid, 848 ModelStandardTransform.DIRECTION_MIN2MAX, 849 ModelStandardTransform.POLARITY_UNIPOLAR, 850 ModelStandardTransform.TRANSFORM_LINEAR), 851 scale, 852 new ModelDestination( 853 new ModelIdentifier("osc", "pitch"))); 854 conns.add(conn); 855 856 } 857 if (d == 1) { 858 double scale = (r / 64.0 - 1.0) * 9600.0; 859 ModelConnectionBlock conn; 860 if (scale > 0) { 861 conn = new ModelConnectionBlock( 862 new ModelSource(sid, 863 ModelStandardTransform.DIRECTION_MAX2MIN, 864 ModelStandardTransform.POLARITY_UNIPOLAR, 865 ModelStandardTransform.TRANSFORM_LINEAR), 866 -scale, 867 new ModelDestination( 868 ModelDestination.DESTINATION_FILTER_FREQ)); 869 } else { 870 conn = new ModelConnectionBlock( 871 new ModelSource(sid, 872 ModelStandardTransform.DIRECTION_MIN2MAX, 873 ModelStandardTransform.POLARITY_UNIPOLAR, 874 ModelStandardTransform.TRANSFORM_LINEAR), 875 scale, 876 new ModelDestination( 877 ModelDestination.DESTINATION_FILTER_FREQ)); 878 } 879 conns.add(conn); 880 } 881 if (d == 2) { 882 final double scale = (r / 64.0); 883 ModelTransform mt = new ModelTransform() { 884 double s = scale; 885 @Override 886 public double transform(double value) { 887 if (s < 1) 888 value = s + (value * (1.0 - s)); 889 else if (s > 1) 890 value = 1 + (value * (s - 1.0)); 891 else 892 return 0; 893 return -((5.0 / 12.0) / Math.log(10)) * Math.log(value); 894 } 895 }; 896 897 ModelConnectionBlock conn = new ModelConnectionBlock( 898 new ModelSource(sid, mt), -960, 899 new ModelDestination(ModelDestination.DESTINATION_GAIN)); 900 conns.add(conn); 901 902 } 903 if (d == 3) { 904 double scale = (r / 64.0 - 1.0) * 9600.0; 905 ModelConnectionBlock conn = new ModelConnectionBlock( 906 new ModelSource(ModelSource.SOURCE_LFO1, 907 ModelStandardTransform.DIRECTION_MIN2MAX, 908 ModelStandardTransform.POLARITY_BIPOLAR, 909 ModelStandardTransform.TRANSFORM_LINEAR), 910 new ModelSource(sid, 911 ModelStandardTransform.DIRECTION_MIN2MAX, 912 ModelStandardTransform.POLARITY_UNIPOLAR, 913 ModelStandardTransform.TRANSFORM_LINEAR), 914 scale, 915 new ModelDestination( 916 ModelDestination.DESTINATION_PITCH)); 917 conns.add(conn); 918 } 919 if (d == 4) { 920 double scale = (r / 128.0) * 2400.0; 921 ModelConnectionBlock conn = new ModelConnectionBlock( 922 new ModelSource(ModelSource.SOURCE_LFO1, 923 ModelStandardTransform.DIRECTION_MIN2MAX, 924 ModelStandardTransform.POLARITY_BIPOLAR, 925 ModelStandardTransform.TRANSFORM_LINEAR), 926 new ModelSource(sid, 927 ModelStandardTransform.DIRECTION_MIN2MAX, 928 ModelStandardTransform.POLARITY_UNIPOLAR, 929 ModelStandardTransform.TRANSFORM_LINEAR), 930 scale, 931 new ModelDestination( 932 ModelDestination.DESTINATION_FILTER_FREQ)); 933 conns.add(conn); 934 } 935 if (d == 5) { 936 final double scale = (r / 127.0); 937 938 ModelTransform mt = new ModelTransform() { 939 double s = scale; 940 @Override 941 public double transform(double value) { 942 return -((5.0 / 12.0) / Math.log(10)) 943 * Math.log(1 - value * s); 944 } 945 }; 946 947 ModelConnectionBlock conn = new ModelConnectionBlock( 948 new ModelSource(ModelSource.SOURCE_LFO1, 949 ModelStandardTransform.DIRECTION_MIN2MAX, 950 ModelStandardTransform.POLARITY_UNIPOLAR, 951 ModelStandardTransform.TRANSFORM_LINEAR), 952 new ModelSource(sid, mt), 953 -960, 954 new ModelDestination( 955 ModelDestination.DESTINATION_GAIN)); 956 conns.add(conn); 957 } 958 } 959 960 return conns.toArray(new ModelConnectionBlock[conns.size()]); 961 } 962 mapPolyPressureToDestination(int[] destination, int[] range)963 public void mapPolyPressureToDestination(int[] destination, int[] range) { 964 current_instrument = null; 965 if (destination.length == 0) { 966 cds_polypressure_connections = null; 967 return; 968 } 969 cds_polypressure_connections 970 = createModelConnections( 971 new ModelIdentifier("midi", "poly_pressure"), 972 destination, range); 973 } 974 mapChannelPressureToDestination(int[] destination, int[] range)975 public void mapChannelPressureToDestination(int[] destination, int[] range) { 976 current_instrument = null; 977 if (destination.length == 0) { 978 cds_channelpressure_connections = null; 979 return; 980 } 981 cds_channelpressure_connections 982 = createModelConnections( 983 new ModelIdentifier("midi", "channel_pressure"), 984 destination, range); 985 } 986 mapControlToDestination(int control, int[] destination, int[] range)987 public void mapControlToDestination(int control, int[] destination, int[] range) { 988 989 if (!((control >= 0x01 && control <= 0x1F) 990 || (control >= 0x40 && control <= 0x5F))) { 991 cds_control_connections = null; 992 return; 993 } 994 995 current_instrument = null; 996 cds_control_number = control; 997 if (destination.length == 0) { 998 cds_control_connections = null; 999 return; 1000 } 1001 cds_control_connections 1002 = createModelConnections( 1003 new ModelIdentifier("midi_cc", Integer.toString(control)), 1004 destination, range); 1005 } 1006 controlChangePerNote(int noteNumber, int controller, int value)1007 public void controlChangePerNote(int noteNumber, int controller, int value) { 1008 1009 /* 1010 CC# | nn | Name | vv | default | description 1011 -----|------|-------------------------|----------------|------------|------------------------------- 1012 7 |07H |Note Volume |00H-40H-7FH |40H |0-100-(127/64)*100(%)(Relative) 1013 10 |0AH |*Pan |00H-7FH absolute|Preset Value|Left-Center-Right (absolute) 1014 33-63|21-3FH|LSB for |01H-1FH | | 1015 71 |47H |Timbre/Harmonic Intensity|00H-40H-7FH |40H (???) | 1016 72 |48H |Release Time |00H-40H-7FH |40H (???) | 1017 73 |49H |Attack Time |00H-40H-7FH |40H (???) | 1018 74 |4AH |Brightness |00H-40H-7FH |40H (???) | 1019 75 |4BH |Decay Time |00H-40H-7FH |40H (???) | 1020 76 |4CH |Vibrato Rate |00H-40H-7FH |40H (???) | 1021 77 |4DH |Vibrato Depth |00H-40H-7FH |40H (???) | 1022 78 |4EH |Vibrato Delay |00H-40H-7FH |40H (???) | 1023 91 |5BH |*Reverb Send |00H-7FH absolute|Preset Value|Left-Center-Right (absolute) 1024 93 |5DH |*Chorus Send |00H-7FH absolute|Preset Value|Left-Center-Right (absolute) 1025 120 |78H |**Fine Tuning |00H-40H-7FH |40H (???) | 1026 121 |79H |**Coarse Tuning |00H-40H-7FH |40H (???) | 1027 */ 1028 1029 if (keybasedcontroller_active == null) { 1030 keybasedcontroller_active = new boolean[128][]; 1031 keybasedcontroller_value = new double[128][]; 1032 } 1033 if (keybasedcontroller_active[noteNumber] == null) { 1034 keybasedcontroller_active[noteNumber] = new boolean[128]; 1035 Arrays.fill(keybasedcontroller_active[noteNumber], false); 1036 keybasedcontroller_value[noteNumber] = new double[128]; 1037 Arrays.fill(keybasedcontroller_value[noteNumber], 0); 1038 } 1039 1040 if (value == -1) { 1041 keybasedcontroller_active[noteNumber][controller] = false; 1042 } else { 1043 keybasedcontroller_active[noteNumber][controller] = true; 1044 keybasedcontroller_value[noteNumber][controller] = value / 128.0; 1045 } 1046 1047 if (controller < 120) { 1048 for (int i = 0; i < voices.length; i++) 1049 if (voices[i].active) 1050 voices[i].controlChange(controller, -1); 1051 } else if (controller == 120) { 1052 for (int i = 0; i < voices.length; i++) 1053 if (voices[i].active) 1054 voices[i].rpnChange(1, -1); 1055 } else if (controller == 121) { 1056 for (int i = 0; i < voices.length; i++) 1057 if (voices[i].active) 1058 voices[i].rpnChange(2, -1); 1059 } 1060 1061 } 1062 getControlPerNote(int noteNumber, int controller)1063 public int getControlPerNote(int noteNumber, int controller) { 1064 if (keybasedcontroller_active == null) 1065 return -1; 1066 if (keybasedcontroller_active[noteNumber] == null) 1067 return -1; 1068 if (!keybasedcontroller_active[noteNumber][controller]) 1069 return -1; 1070 return (int)(keybasedcontroller_value[noteNumber][controller] * 128); 1071 } 1072 1073 @Override controlChange(int controller, int value)1074 public void controlChange(int controller, int value) { 1075 controller = restrict7Bit(controller); 1076 value = restrict7Bit(value); 1077 if (current_mixer != null) 1078 current_mixer.controlChange(controller, value); 1079 1080 synchronized (control_mutex) { 1081 switch (controller) { 1082 /* 1083 Map<String, int[]>co_midi_rpn_rpn_i = new HashMap<String, int[]>(); 1084 Map<String, double[]>co_midi_rpn_rpn = new HashMap<String, double[]>(); 1085 Map<String, int[]>co_midi_nrpn_nrpn_i = new HashMap<String, int[]>(); 1086 Map<String, double[]>co_midi_nrpn_nrpn = new HashMap<String, double[]>(); 1087 */ 1088 1089 case 5: 1090 // This produce asin-like curve 1091 // as described in General Midi Level 2 Specification, page 6 1092 double x = -Math.asin((value / 128.0) * 2 - 1) / Math.PI + 0.5; 1093 x = Math.pow(100000.0, x) / 100.0; // x is now cent/msec 1094 // Convert x from cent/msec to key/controlbuffertime 1095 x = x / 100.0; // x is now keys/msec 1096 x = x * 1000.0; // x is now keys/sec 1097 x = x / synthesizer.getControlRate(); // x is now keys/controlbuffertime 1098 portamento_time = x; 1099 break; 1100 case 6: 1101 case 38: 1102 case 96: 1103 case 97: 1104 int val = 0; 1105 if (nrpn_control != RPN_NULL_VALUE) { 1106 int[] val_i = co_midi_nrpn_nrpn_i.get(nrpn_control); 1107 if (val_i != null) 1108 val = val_i[0]; 1109 } 1110 if (rpn_control != RPN_NULL_VALUE) { 1111 int[] val_i = co_midi_rpn_rpn_i.get(rpn_control); 1112 if (val_i != null) 1113 val = val_i[0]; 1114 } 1115 1116 if (controller == 6) 1117 val = (val & 127) + (value << 7); 1118 else if (controller == 38) 1119 val = (val & (127 << 7)) + value; 1120 else if (controller == 96 || controller == 97) { 1121 int step = 1; 1122 if (rpn_control == 2 || rpn_control == 3 || rpn_control == 4) 1123 step = 128; 1124 if (controller == 96) 1125 val += step; 1126 if (controller == 97) 1127 val -= step; 1128 } 1129 1130 if (nrpn_control != RPN_NULL_VALUE) 1131 nrpnChange(nrpn_control, val); 1132 if (rpn_control != RPN_NULL_VALUE) 1133 rpnChange(rpn_control, val); 1134 1135 break; 1136 case 64: // Hold1 (Damper) (cc#64) 1137 boolean on = value >= 64; 1138 if (sustain != on) { 1139 sustain = on; 1140 if (!on) { 1141 for (int i = 0; i < voices.length; i++) { 1142 if (voices[i].active && voices[i].sustain && 1143 voices[i].channel == channel) { 1144 voices[i].sustain = false; 1145 if (!voices[i].on) { 1146 voices[i].on = true; 1147 voices[i].noteOff(0); 1148 } 1149 } 1150 } 1151 } else { 1152 for (int i = 0; i < voices.length; i++) 1153 if (voices[i].active && voices[i].channel == channel) 1154 voices[i].redamp(); 1155 } 1156 } 1157 break; 1158 case 65: 1159 //allNotesOff(); 1160 portamento = value >= 64; 1161 portamento_lastnote[0] = -1; 1162 /* 1163 for (int i = 0; i < portamento_lastnote.length; i++) 1164 portamento_lastnote[i] = -1; 1165 */ 1166 portamento_lastnote_ix = 0; 1167 break; 1168 case 66: // Sostenuto (cc#66) 1169 on = value >= 64; 1170 if (on) { 1171 for (int i = 0; i < voices.length; i++) { 1172 if (voices[i].active && voices[i].on && 1173 voices[i].channel == channel) { 1174 voices[i].sostenuto = true; 1175 } 1176 } 1177 } 1178 if (!on) { 1179 for (int i = 0; i < voices.length; i++) { 1180 if (voices[i].active && voices[i].sostenuto && 1181 voices[i].channel == channel) { 1182 voices[i].sostenuto = false; 1183 if (!voices[i].on) { 1184 voices[i].on = true; 1185 voices[i].noteOff(0); 1186 } 1187 } 1188 } 1189 } 1190 break; 1191 case 98: 1192 nrpn_control = (nrpn_control & (127 << 7)) + value; 1193 rpn_control = RPN_NULL_VALUE; 1194 break; 1195 case 99: 1196 nrpn_control = (nrpn_control & 127) + (value << 7); 1197 rpn_control = RPN_NULL_VALUE; 1198 break; 1199 case 100: 1200 rpn_control = (rpn_control & (127 << 7)) + value; 1201 nrpn_control = RPN_NULL_VALUE; 1202 break; 1203 case 101: 1204 rpn_control = (rpn_control & 127) + (value << 7); 1205 nrpn_control = RPN_NULL_VALUE; 1206 break; 1207 case 120: 1208 allSoundOff(); 1209 break; 1210 case 121: 1211 resetAllControllers(value == 127); 1212 break; 1213 case 122: 1214 localControl(value >= 64); 1215 break; 1216 case 123: 1217 allNotesOff(); 1218 break; 1219 case 124: 1220 setOmni(false); 1221 break; 1222 case 125: 1223 setOmni(true); 1224 break; 1225 case 126: 1226 if (value == 1) 1227 setMono(true); 1228 break; 1229 case 127: 1230 setMono(false); 1231 break; 1232 1233 default: 1234 break; 1235 } 1236 1237 co_midi_cc_cc[controller][0] = value * (1.0 / 128.0); 1238 1239 if (controller == 0x00) { 1240 bank = /*(bank & 127) +*/ (value << 7); 1241 return; 1242 } 1243 1244 if (controller == 0x20) { 1245 bank = (bank & (127 << 7)) + value; 1246 return; 1247 } 1248 1249 this.controller[controller] = value; 1250 if(controller < 0x20) 1251 this.controller[controller + 0x20] = 0; 1252 1253 for (int i = 0; i < voices.length; i++) 1254 if (voices[i].active) 1255 voices[i].controlChange(controller, value); 1256 1257 } 1258 } 1259 1260 @Override getController(int controller)1261 public int getController(int controller) { 1262 synchronized (control_mutex) { 1263 // Should only return lower 7 bits, 1264 // even when controller is "boosted" higher. 1265 return this.controller[controller] & 127; 1266 } 1267 } 1268 tuningChange(int program)1269 public void tuningChange(int program) { 1270 tuningChange(0, program); 1271 } 1272 tuningChange(int bank, int program)1273 public void tuningChange(int bank, int program) { 1274 synchronized (control_mutex) { 1275 tuning = synthesizer.getTuning(new Patch(bank, program)); 1276 } 1277 } 1278 1279 @Override programChange(int program)1280 public void programChange(int program) { 1281 programChange(bank, program); 1282 } 1283 1284 @Override programChange(int bank, int program)1285 public void programChange(int bank, int program) { 1286 bank = restrict14Bit(bank); 1287 program = restrict7Bit(program); 1288 synchronized (control_mutex) { 1289 mainmixer.activity(); 1290 if(this.bank != bank || this.program != program) 1291 { 1292 this.bank = bank; 1293 this.program = program; 1294 current_instrument = null; 1295 } 1296 } 1297 } 1298 1299 @Override getProgram()1300 public int getProgram() { 1301 synchronized (control_mutex) { 1302 return program; 1303 } 1304 } 1305 1306 @Override setPitchBend(int bend)1307 public void setPitchBend(int bend) { 1308 bend = restrict14Bit(bend); 1309 if (current_mixer != null) 1310 current_mixer.setPitchBend(bend); 1311 synchronized (control_mutex) { 1312 mainmixer.activity(); 1313 co_midi_pitch[0] = bend * (1.0 / 16384.0); 1314 pitchbend = bend; 1315 for (int i = 0; i < voices.length; i++) 1316 if (voices[i].active) 1317 voices[i].setPitchBend(bend); 1318 } 1319 } 1320 1321 @Override getPitchBend()1322 public int getPitchBend() { 1323 synchronized (control_mutex) { 1324 return pitchbend; 1325 } 1326 } 1327 nrpnChange(int controller, int value)1328 public void nrpnChange(int controller, int value) { 1329 1330 /* 1331 System.out.println("(" + channel + ").nrpnChange(" 1332 + Integer.toHexString(controller >> 7) 1333 + " " + Integer.toHexString(controller & 127) 1334 + ", " + Integer.toHexString(value >> 7) 1335 + " " + Integer.toHexString(value & 127) + ")"); 1336 */ 1337 1338 if (synthesizer.getGeneralMidiMode() == 0) { 1339 if (controller == (0x01 << 7) + (0x08)) // Vibrato Rate 1340 controlChange(76, value >> 7); 1341 if (controller == (0x01 << 7) + (0x09)) // Vibrato Depth 1342 controlChange(77, value >> 7); 1343 if (controller == (0x01 << 7) + (0x0A)) // Vibrato Delay 1344 controlChange(78, value >> 7); 1345 if (controller == (0x01 << 7) + (0x20)) // Brightness 1346 controlChange(74, value >> 7); 1347 if (controller == (0x01 << 7) + (0x21)) // Filter Resonance 1348 controlChange(71, value >> 7); 1349 if (controller == (0x01 << 7) + (0x63)) // Attack Time 1350 controlChange(73, value >> 7); 1351 if (controller == (0x01 << 7) + (0x64)) // Decay Time 1352 controlChange(75, value >> 7); 1353 if (controller == (0x01 << 7) + (0x66)) // Release Time 1354 controlChange(72, value >> 7); 1355 1356 if (controller >> 7 == 0x18) // Pitch coarse 1357 controlChangePerNote(controller % 128, 120, value >> 7); 1358 if (controller >> 7 == 0x1A) // Volume 1359 controlChangePerNote(controller % 128, 7, value >> 7); 1360 if (controller >> 7 == 0x1C) // Panpot 1361 controlChangePerNote(controller % 128, 10, value >> 7); 1362 if (controller >> 7 == 0x1D) // Reverb 1363 controlChangePerNote(controller % 128, 91, value >> 7); 1364 if (controller >> 7 == 0x1E) // Chorus 1365 controlChangePerNote(controller % 128, 93, value >> 7); 1366 } 1367 1368 int[] val_i = co_midi_nrpn_nrpn_i.get(controller); 1369 double[] val_d = co_midi_nrpn_nrpn.get(controller); 1370 if (val_i == null) { 1371 val_i = new int[1]; 1372 co_midi_nrpn_nrpn_i.put(controller, val_i); 1373 } 1374 if (val_d == null) { 1375 val_d = new double[1]; 1376 co_midi_nrpn_nrpn.put(controller, val_d); 1377 } 1378 val_i[0] = value; 1379 val_d[0] = val_i[0] * (1.0 / 16384.0); 1380 1381 for (int i = 0; i < voices.length; i++) 1382 if (voices[i].active) 1383 voices[i].nrpnChange(controller, val_i[0]); 1384 1385 } 1386 rpnChange(int controller, int value)1387 public void rpnChange(int controller, int value) { 1388 1389 /* 1390 System.out.println("(" + channel + ").rpnChange(" 1391 + Integer.toHexString(controller >> 7) 1392 + " " + Integer.toHexString(controller & 127) 1393 + ", " + Integer.toHexString(value >> 7) 1394 + " " + Integer.toHexString(value & 127) + ")"); 1395 */ 1396 1397 if (controller == 3) { 1398 tuning_program = (value >> 7) & 127; 1399 tuningChange(tuning_bank, tuning_program); 1400 } 1401 if (controller == 4) { 1402 tuning_bank = (value >> 7) & 127; 1403 } 1404 1405 int[] val_i = co_midi_rpn_rpn_i.get(controller); 1406 double[] val_d = co_midi_rpn_rpn.get(controller); 1407 if (val_i == null) { 1408 val_i = new int[1]; 1409 co_midi_rpn_rpn_i.put(controller, val_i); 1410 } 1411 if (val_d == null) { 1412 val_d = new double[1]; 1413 co_midi_rpn_rpn.put(controller, val_d); 1414 } 1415 val_i[0] = value; 1416 val_d[0] = val_i[0] * (1.0 / 16384.0); 1417 1418 for (int i = 0; i < voices.length; i++) 1419 if (voices[i].active) 1420 voices[i].rpnChange(controller, val_i[0]); 1421 } 1422 1423 @Override resetAllControllers()1424 public void resetAllControllers() { 1425 resetAllControllers(false); 1426 } 1427 resetAllControllers(boolean allControls)1428 public void resetAllControllers(boolean allControls) { 1429 synchronized (control_mutex) { 1430 mainmixer.activity(); 1431 1432 for (int i = 0; i < 128; i++) { 1433 setPolyPressure(i, 0); 1434 } 1435 setChannelPressure(0); 1436 setPitchBend(8192); 1437 for (int i = 0; i < 128; i++) { 1438 if (!dontResetControls[i]) 1439 controlChange(i, 0); 1440 } 1441 1442 controlChange(71, 64); // Filter Resonance 1443 controlChange(72, 64); // Release Time 1444 controlChange(73, 64); // Attack Time 1445 controlChange(74, 64); // Brightness 1446 controlChange(75, 64); // Decay Time 1447 controlChange(76, 64); // Vibrato Rate 1448 controlChange(77, 64); // Vibrato Depth 1449 controlChange(78, 64); // Vibrato Delay 1450 1451 controlChange(8, 64); // Balance 1452 controlChange(11, 127); // Expression 1453 controlChange(98, 127); // NRPN Null 1454 controlChange(99, 127); // NRPN Null 1455 controlChange(100, 127); // RPN = Null 1456 controlChange(101, 127); // RPN = Null 1457 1458 // see DLS 2.1 (Power-on Default Values) 1459 if (allControls) { 1460 1461 keybasedcontroller_active = null; 1462 keybasedcontroller_value = null; 1463 1464 controlChange(7, 100); // Volume 1465 controlChange(10, 64); // Pan 1466 controlChange(91, 40); // Reverb 1467 1468 for (int controller : co_midi_rpn_rpn.keySet()) { 1469 // don't reset tuning settings 1470 if (controller != 3 && controller != 4) 1471 rpnChange(controller, 0); 1472 } 1473 for (int controller : co_midi_nrpn_nrpn.keySet()) 1474 nrpnChange(controller, 0); 1475 rpnChange(0, 2 << 7); // Pitch Bend sensitivity 1476 rpnChange(1, 64 << 7); // Channel fine tunning 1477 rpnChange(2, 64 << 7); // Channel Coarse Tuning 1478 rpnChange(5, 64); // Modulation Depth, +/- 50 cent 1479 1480 tuning_bank = 0; 1481 tuning_program = 0; 1482 tuning = new SoftTuning(); 1483 1484 } 1485 1486 } 1487 } 1488 1489 @Override allNotesOff()1490 public void allNotesOff() { 1491 if (current_mixer != null) 1492 current_mixer.allNotesOff(); 1493 synchronized (control_mutex) { 1494 for (int i = 0; i < voices.length; i++) 1495 if (voices[i].on && voices[i].channel == channel 1496 && voices[i].releaseTriggered == false) { 1497 voices[i].noteOff(0); 1498 } 1499 } 1500 } 1501 1502 @Override allSoundOff()1503 public void allSoundOff() { 1504 if (current_mixer != null) 1505 current_mixer.allSoundOff(); 1506 synchronized (control_mutex) { 1507 for (int i = 0; i < voices.length; i++) 1508 if (voices[i].on && voices[i].channel == channel) 1509 voices[i].soundOff(); 1510 } 1511 } 1512 1513 @Override localControl(boolean on)1514 public boolean localControl(boolean on) { 1515 return false; 1516 } 1517 1518 @Override setMono(boolean on)1519 public void setMono(boolean on) { 1520 if (current_mixer != null) 1521 current_mixer.setMono(on); 1522 synchronized (control_mutex) { 1523 allNotesOff(); 1524 mono = on; 1525 } 1526 } 1527 1528 @Override getMono()1529 public boolean getMono() { 1530 synchronized (control_mutex) { 1531 return mono; 1532 } 1533 } 1534 1535 @Override setOmni(boolean on)1536 public void setOmni(boolean on) { 1537 if (current_mixer != null) 1538 current_mixer.setOmni(on); 1539 allNotesOff(); 1540 // Omni is not supported by GM2 1541 } 1542 1543 @Override getOmni()1544 public boolean getOmni() { 1545 return false; 1546 } 1547 1548 @Override setMute(boolean mute)1549 public void setMute(boolean mute) { 1550 if (current_mixer != null) 1551 current_mixer.setMute(mute); 1552 synchronized (control_mutex) { 1553 this.mute = mute; 1554 for (int i = 0; i < voices.length; i++) 1555 if (voices[i].active && voices[i].channel == channel) 1556 voices[i].setMute(mute); 1557 } 1558 } 1559 1560 @Override getMute()1561 public boolean getMute() { 1562 synchronized (control_mutex) { 1563 return mute; 1564 } 1565 } 1566 1567 @Override setSolo(boolean soloState)1568 public void setSolo(boolean soloState) { 1569 if (current_mixer != null) 1570 current_mixer.setSolo(soloState); 1571 1572 synchronized (control_mutex) { 1573 this.solo = soloState; 1574 1575 boolean soloinuse = false; 1576 for (SoftChannel c : synthesizer.channels) { 1577 if (c.solo) { 1578 soloinuse = true; 1579 break; 1580 } 1581 } 1582 1583 if (!soloinuse) { 1584 for (SoftChannel c : synthesizer.channels) 1585 c.setSoloMute(false); 1586 return; 1587 } 1588 1589 for (SoftChannel c : synthesizer.channels) 1590 c.setSoloMute(!c.solo); 1591 1592 } 1593 1594 } 1595 setSoloMute(boolean mute)1596 private void setSoloMute(boolean mute) { 1597 synchronized (control_mutex) { 1598 if (solomute == mute) 1599 return; 1600 this.solomute = mute; 1601 for (int i = 0; i < voices.length; i++) 1602 if (voices[i].active && voices[i].channel == channel) 1603 voices[i].setSoloMute(solomute); 1604 } 1605 } 1606 1607 @Override getSolo()1608 public boolean getSolo() { 1609 synchronized (control_mutex) { 1610 return solo; 1611 } 1612 } 1613 } 1614