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 26package com.sun.media.sound; 27 28import java.io.IOException; 29import java.io.InputStream; 30import java.util.HashSet; 31import java.util.Iterator; 32import java.util.Map.Entry; 33import java.util.Set; 34import java.util.TreeMap; 35 36import javax.sound.midi.MidiMessage; 37import javax.sound.midi.Patch; 38import javax.sound.midi.ShortMessage; 39import javax.sound.sampled.AudioInputStream; 40import javax.sound.sampled.AudioSystem; 41 42/** 43 * Software synthesizer main audio mixer. 44 * 45 * @author Karl Helgason 46 */ 47public final class SoftMainMixer { 48 49 // A private class thats contains a ModelChannelMixer and it's private buffers. 50 // This becomes necessary when we want to have separate delay buffers for each channel mixer. 51 private class SoftChannelMixerContainer 52 { 53 ModelChannelMixer mixer; 54 SoftAudioBuffer[] buffers; 55 } 56 57 public static final int CHANNEL_LEFT = 0; 58 public static final int CHANNEL_RIGHT = 1; 59 public static final int CHANNEL_MONO = 2; 60 public static final int CHANNEL_DELAY_LEFT = 3; 61 public static final int CHANNEL_DELAY_RIGHT = 4; 62 public static final int CHANNEL_DELAY_MONO = 5; 63 public static final int CHANNEL_EFFECT1 = 6; 64 public static final int CHANNEL_EFFECT2 = 7; 65 public static final int CHANNEL_DELAY_EFFECT1 = 8; 66 public static final int CHANNEL_DELAY_EFFECT2 = 9; 67 public static final int CHANNEL_LEFT_DRY = 10; 68 public static final int CHANNEL_RIGHT_DRY = 11; 69 public static final int CHANNEL_SCRATCH1 = 12; 70 public static final int CHANNEL_SCRATCH2 = 13; 71 boolean active_sensing_on = false; 72 private long msec_last_activity = -1; 73 private boolean pusher_silent = false; 74 private int pusher_silent_count = 0; 75 private long sample_pos = 0; 76 boolean readfully = true; 77 private final Object control_mutex; 78 private final SoftSynthesizer synth; 79 private float samplerate = 44100; 80 private int nrofchannels = 2; 81 private SoftVoice[] voicestatus = null; 82 private final SoftAudioBuffer[] buffers; 83 private final SoftReverb reverb; 84 private final SoftAudioProcessor chorus; 85 private final SoftAudioProcessor agc; 86 private long msec_buffer_len = 0; 87 private int buffer_len = 0; 88 TreeMap<Long, Object> midimessages = new TreeMap<>(); 89 private int delay_midievent = 0; 90 private int max_delay_midievent = 0; 91 double last_volume_left = 1.0; 92 double last_volume_right = 1.0; 93 private final double[] co_master_balance = new double[1]; 94 private final double[] co_master_volume = new double[1]; 95 private final double[] co_master_coarse_tuning = new double[1]; 96 private final double[] co_master_fine_tuning = new double[1]; 97 private final AudioInputStream ais; 98 private Set<SoftChannelMixerContainer> registeredMixers = null; 99 private Set<ModelChannelMixer> stoppedMixers = null; 100 private SoftChannelMixerContainer[] cur_registeredMixers = null; 101 SoftControl co_master = new SoftControl() { 102 103 double[] balance = co_master_balance; 104 double[] volume = co_master_volume; 105 double[] coarse_tuning = co_master_coarse_tuning; 106 double[] fine_tuning = co_master_fine_tuning; 107 108 @Override 109 public double[] get(int instance, String name) { 110 if (name == null) 111 return null; 112 if (name.equals("balance")) 113 return balance; 114 if (name.equals("volume")) 115 return volume; 116 if (name.equals("coarse_tuning")) 117 return coarse_tuning; 118 if (name.equals("fine_tuning")) 119 return fine_tuning; 120 return null; 121 } 122 }; 123 124 private void processSystemExclusiveMessage(byte[] data) { 125 synchronized (synth.control_mutex) { 126 activity(); 127 128 // Universal Non-Real-Time SysEx 129 if ((data[1] & 0xFF) == 0x7E) { 130 int deviceID = data[2] & 0xFF; 131 if (deviceID == 0x7F || deviceID == synth.getDeviceID()) { 132 int subid1 = data[3] & 0xFF; 133 int subid2; 134 switch (subid1) { 135 case 0x08: // MIDI Tuning Standard 136 subid2 = data[4] & 0xFF; 137 switch (subid2) { 138 case 0x01: // BULK TUNING DUMP 139 { 140 // http://www.midi.org/about-midi/tuning.shtml 141 SoftTuning tuning = synth.getTuning(new Patch(0, 142 data[5] & 0xFF)); 143 tuning.load(data); 144 break; 145 } 146 case 0x04: // KEY-BASED TUNING DUMP 147 case 0x05: // SCALE/OCTAVE TUNING DUMP, 1 byte format 148 case 0x06: // SCALE/OCTAVE TUNING DUMP, 2 byte format 149 case 0x07: // SINGLE NOTE TUNING CHANGE (NON REAL-TIME) 150 // (BANK) 151 { 152 // http://www.midi.org/about-midi/tuning_extens.shtml 153 SoftTuning tuning = synth.getTuning(new Patch( 154 data[5] & 0xFF, data[6] & 0xFF)); 155 tuning.load(data); 156 break; 157 } 158 case 0x08: // scale/octave tuning 1-byte form (Non 159 // Real-Time) 160 case 0x09: // scale/octave tuning 2-byte form (Non 161 // Real-Time) 162 { 163 // http://www.midi.org/about-midi/tuning-scale.shtml 164 SoftTuning tuning = new SoftTuning(data); 165 int channelmask = (data[5] & 0xFF) * 16384 166 + (data[6] & 0xFF) * 128 + (data[7] & 0xFF); 167 SoftChannel[] channels = synth.channels; 168 for (int i = 0; i < channels.length; i++) 169 if ((channelmask & (1 << i)) != 0) 170 channels[i].tuning = tuning; 171 break; 172 } 173 default: 174 break; 175 } 176 break; 177 case 0x09: // General Midi Message 178 subid2 = data[4] & 0xFF; 179 switch (subid2) { 180 case 0x01: // General Midi 1 On 181 synth.setGeneralMidiMode(1); 182 reset(); 183 break; 184 case 0x02: // General Midi Off 185 synth.setGeneralMidiMode(0); 186 reset(); 187 break; 188 case 0x03: // General MidI Level 2 On 189 synth.setGeneralMidiMode(2); 190 reset(); 191 break; 192 default: 193 break; 194 } 195 break; 196 case 0x0A: // DLS Message 197 subid2 = data[4] & 0xFF; 198 switch (subid2) { 199 case 0x01: // DLS On 200 if (synth.getGeneralMidiMode() == 0) 201 synth.setGeneralMidiMode(1); 202 synth.voice_allocation_mode = 1; 203 reset(); 204 break; 205 case 0x02: // DLS Off 206 synth.setGeneralMidiMode(0); 207 synth.voice_allocation_mode = 0; 208 reset(); 209 break; 210 case 0x03: // DLS Static Voice Allocation Off 211 synth.voice_allocation_mode = 0; 212 break; 213 case 0x04: // DLS Static Voice Allocation On 214 synth.voice_allocation_mode = 1; 215 break; 216 default: 217 break; 218 } 219 break; 220 221 default: 222 break; 223 } 224 } 225 } 226 227 // Universal Real-Time SysEx 228 if ((data[1] & 0xFF) == 0x7F) { 229 int deviceID = data[2] & 0xFF; 230 if (deviceID == 0x7F || deviceID == synth.getDeviceID()) { 231 int subid1 = data[3] & 0xFF; 232 int subid2; 233 switch (subid1) { 234 case 0x04: // Device Control 235 236 subid2 = data[4] & 0xFF; 237 switch (subid2) { 238 case 0x01: // Master Volume 239 case 0x02: // Master Balane 240 case 0x03: // Master fine tuning 241 case 0x04: // Master coarse tuning 242 int val = (data[5] & 0x7F) 243 + ((data[6] & 0x7F) * 128); 244 if (subid2 == 0x01) 245 setVolume(val); 246 else if (subid2 == 0x02) 247 setBalance(val); 248 else if (subid2 == 0x03) 249 setFineTuning(val); 250 else if (subid2 == 0x04) 251 setCoarseTuning(val); 252 break; 253 case 0x05: // Global Parameter Control 254 int ix = 5; 255 int slotPathLen = (data[ix++] & 0xFF); 256 int paramWidth = (data[ix++] & 0xFF); 257 int valueWidth = (data[ix++] & 0xFF); 258 int[] slotPath = new int[slotPathLen]; 259 for (int i = 0; i < slotPathLen; i++) { 260 int msb = (data[ix++] & 0xFF); 261 int lsb = (data[ix++] & 0xFF); 262 slotPath[i] = msb * 128 + lsb; 263 } 264 int paramCount = (data.length - 1 - ix) 265 / (paramWidth + valueWidth); 266 long[] params = new long[paramCount]; 267 long[] values = new long[paramCount]; 268 for (int i = 0; i < paramCount; i++) { 269 values[i] = 0; 270 for (int j = 0; j < paramWidth; j++) 271 params[i] = params[i] * 128 272 + (data[ix++] & 0xFF); 273 for (int j = 0; j < valueWidth; j++) 274 values[i] = values[i] * 128 275 + (data[ix++] & 0xFF); 276 277 } 278 globalParameterControlChange(slotPath, params, values); 279 break; 280 default: 281 break; 282 } 283 break; 284 285 case 0x08: // MIDI Tuning Standard 286 subid2 = data[4] & 0xFF; 287 switch (subid2) { 288 case 0x02: // SINGLE NOTE TUNING CHANGE (REAL-TIME) 289 { 290 // http://www.midi.org/about-midi/tuning.shtml 291 SoftTuning tuning = synth.getTuning(new Patch(0, 292 data[5] & 0xFF)); 293 tuning.load(data); 294 SoftVoice[] voices = synth.getVoices(); 295 for (int i = 0; i < voices.length; i++) 296 if (voices[i].active) 297 if (voices[i].tuning == tuning) 298 voices[i].updateTuning(tuning); 299 break; 300 } 301 case 0x07: // SINGLE NOTE TUNING CHANGE (REAL-TIME) 302 // (BANK) 303 { 304 // http://www.midi.org/about-midi/tuning_extens.shtml 305 SoftTuning tuning = synth.getTuning(new Patch( 306 data[5] & 0xFF, data[6] & 0xFF)); 307 tuning.load(data); 308 SoftVoice[] voices = synth.getVoices(); 309 for (int i = 0; i < voices.length; i++) 310 if (voices[i].active) 311 if (voices[i].tuning == tuning) 312 voices[i].updateTuning(tuning); 313 break; 314 } 315 case 0x08: // scale/octave tuning 1-byte form 316 //(Real-Time) 317 case 0x09: // scale/octave tuning 2-byte form 318 // (Real-Time) 319 { 320 // http://www.midi.org/about-midi/tuning-scale.shtml 321 SoftTuning tuning = new SoftTuning(data); 322 int channelmask = (data[5] & 0xFF) * 16384 323 + (data[6] & 0xFF) * 128 + (data[7] & 0xFF); 324 SoftChannel[] channels = synth.channels; 325 for (int i = 0; i < channels.length; i++) 326 if ((channelmask & (1 << i)) != 0) 327 channels[i].tuning = tuning; 328 SoftVoice[] voices = synth.getVoices(); 329 for (int i = 0; i < voices.length; i++) 330 if (voices[i].active) 331 if ((channelmask & (1 << (voices[i].channel))) != 0) 332 voices[i].updateTuning(tuning); 333 break; 334 } 335 default: 336 break; 337 } 338 break; 339 case 0x09: // Control Destination Settings 340 subid2 = data[4] & 0xFF; 341 switch (subid2) { 342 case 0x01: // Channel Pressure 343 { 344 int[] destinations = new int[(data.length - 7) / 2]; 345 int[] ranges = new int[(data.length - 7) / 2]; 346 int ix = 0; 347 for (int j = 6; j < data.length - 1; j += 2) { 348 destinations[ix] = data[j] & 0xFF; 349 ranges[ix] = data[j + 1] & 0xFF; 350 ix++; 351 } 352 int channel = data[5] & 0xFF; 353 SoftChannel softchannel = synth.channels[channel]; 354 softchannel.mapChannelPressureToDestination( 355 destinations, ranges); 356 break; 357 } 358 case 0x02: // Poly Pressure 359 { 360 int[] destinations = new int[(data.length - 7) / 2]; 361 int[] ranges = new int[(data.length - 7) / 2]; 362 int ix = 0; 363 for (int j = 6; j < data.length - 1; j += 2) { 364 destinations[ix] = data[j] & 0xFF; 365 ranges[ix] = data[j + 1] & 0xFF; 366 ix++; 367 } 368 int channel = data[5] & 0xFF; 369 SoftChannel softchannel = synth.channels[channel]; 370 softchannel.mapPolyPressureToDestination( 371 destinations, ranges); 372 break; 373 } 374 case 0x03: // Control Change 375 { 376 int[] destinations = new int[(data.length - 7) / 2]; 377 int[] ranges = new int[(data.length - 7) / 2]; 378 int ix = 0; 379 for (int j = 7; j < data.length - 1; j += 2) { 380 destinations[ix] = data[j] & 0xFF; 381 ranges[ix] = data[j + 1] & 0xFF; 382 ix++; 383 } 384 int channel = data[5] & 0xFF; 385 SoftChannel softchannel = synth.channels[channel]; 386 int control = data[6] & 0xFF; 387 softchannel.mapControlToDestination(control, 388 destinations, ranges); 389 break; 390 } 391 default: 392 break; 393 } 394 break; 395 396 case 0x0A: // Key Based Instrument Control 397 { 398 subid2 = data[4] & 0xFF; 399 switch (subid2) { 400 case 0x01: // Basic Message 401 int channel = data[5] & 0xFF; 402 int keynumber = data[6] & 0xFF; 403 SoftChannel softchannel = synth.channels[channel]; 404 for (int j = 7; j < data.length - 1; j += 2) { 405 int controlnumber = data[j] & 0xFF; 406 int controlvalue = data[j + 1] & 0xFF; 407 softchannel.controlChangePerNote(keynumber, 408 controlnumber, controlvalue); 409 } 410 break; 411 default: 412 break; 413 } 414 break; 415 } 416 default: 417 break; 418 } 419 } 420 } 421 422 } 423 } 424 425 private void processMessages(long timeStamp) { 426 Iterator<Entry<Long, Object>> iter = midimessages.entrySet().iterator(); 427 while (iter.hasNext()) { 428 Entry<Long, Object> entry = iter.next(); 429 if (entry.getKey() >= (timeStamp + msec_buffer_len)) 430 return; 431 long msec_delay = entry.getKey() - timeStamp; 432 delay_midievent = (int)(msec_delay * (samplerate / 1000000.0) + 0.5); 433 if(delay_midievent > max_delay_midievent) 434 delay_midievent = max_delay_midievent; 435 if(delay_midievent < 0) 436 delay_midievent = 0; 437 processMessage(entry.getValue()); 438 iter.remove(); 439 } 440 delay_midievent = 0; 441 } 442 443 void processAudioBuffers() { 444 445 if(synth.weakstream != null && synth.weakstream.silent_samples != 0) 446 { 447 sample_pos += synth.weakstream.silent_samples; 448 synth.weakstream.silent_samples = 0; 449 } 450 451 for (int i = 0; i < buffers.length; i++) { 452 if(i != CHANNEL_DELAY_LEFT && 453 i != CHANNEL_DELAY_RIGHT && 454 i != CHANNEL_DELAY_MONO && 455 i != CHANNEL_DELAY_EFFECT1 && 456 i != CHANNEL_DELAY_EFFECT2) 457 buffers[i].clear(); 458 } 459 460 if(!buffers[CHANNEL_DELAY_LEFT].isSilent()) 461 { 462 buffers[CHANNEL_LEFT].swap(buffers[CHANNEL_DELAY_LEFT]); 463 } 464 if(!buffers[CHANNEL_DELAY_RIGHT].isSilent()) 465 { 466 buffers[CHANNEL_RIGHT].swap(buffers[CHANNEL_DELAY_RIGHT]); 467 } 468 if(!buffers[CHANNEL_DELAY_MONO].isSilent()) 469 { 470 buffers[CHANNEL_MONO].swap(buffers[CHANNEL_DELAY_MONO]); 471 } 472 if(!buffers[CHANNEL_DELAY_EFFECT1].isSilent()) 473 { 474 buffers[CHANNEL_EFFECT1].swap(buffers[CHANNEL_DELAY_EFFECT1]); 475 } 476 if(!buffers[CHANNEL_DELAY_EFFECT2].isSilent()) 477 { 478 buffers[CHANNEL_EFFECT2].swap(buffers[CHANNEL_DELAY_EFFECT2]); 479 } 480 481 double volume_left; 482 double volume_right; 483 484 SoftChannelMixerContainer[] act_registeredMixers; 485 486 // perform control logic 487 synchronized (control_mutex) { 488 489 long msec_pos = (long)(sample_pos * (1000000.0 / samplerate)); 490 491 processMessages(msec_pos); 492 493 if (active_sensing_on) { 494 // Active Sensing 495 // if no message occurs for max 1000 ms 496 // then do AllSoundOff on all channels 497 if ((msec_pos - msec_last_activity) > 1000000) { 498 active_sensing_on = false; 499 for (SoftChannel c : synth.channels) 500 c.allSoundOff(); 501 } 502 503 } 504 505 for (int i = 0; i < voicestatus.length; i++) 506 if (voicestatus[i].active) 507 voicestatus[i].processControlLogic(); 508 sample_pos += buffer_len; 509 510 double volume = co_master_volume[0]; 511 volume_left = volume; 512 volume_right = volume; 513 514 double balance = co_master_balance[0]; 515 if (balance > 0.5) 516 volume_left *= (1 - balance) * 2; 517 else 518 volume_right *= balance * 2; 519 520 chorus.processControlLogic(); 521 reverb.processControlLogic(); 522 agc.processControlLogic(); 523 524 if (cur_registeredMixers == null) { 525 if (registeredMixers != null) { 526 cur_registeredMixers = 527 new SoftChannelMixerContainer[registeredMixers.size()]; 528 registeredMixers.toArray(cur_registeredMixers); 529 } 530 } 531 532 act_registeredMixers = cur_registeredMixers; 533 if (act_registeredMixers != null) 534 if (act_registeredMixers.length == 0) 535 act_registeredMixers = null; 536 537 } 538 539 if (act_registeredMixers != null) { 540 541 // Make backup of left,right,mono channels 542 SoftAudioBuffer leftbak = buffers[CHANNEL_LEFT]; 543 SoftAudioBuffer rightbak = buffers[CHANNEL_RIGHT]; 544 SoftAudioBuffer monobak = buffers[CHANNEL_MONO]; 545 SoftAudioBuffer delayleftbak = buffers[CHANNEL_DELAY_LEFT]; 546 SoftAudioBuffer delayrightbak = buffers[CHANNEL_DELAY_RIGHT]; 547 SoftAudioBuffer delaymonobak = buffers[CHANNEL_DELAY_MONO]; 548 549 int bufferlen = buffers[CHANNEL_LEFT].getSize(); 550 551 float[][] cbuffer = new float[nrofchannels][]; 552 float[][] obuffer = new float[nrofchannels][]; 553 obuffer[0] = leftbak.array(); 554 if (nrofchannels != 1) 555 obuffer[1] = rightbak.array(); 556 557 for (SoftChannelMixerContainer cmixer : act_registeredMixers) { 558 559 // Reroute default left,right output 560 // to channelmixer left,right input/output 561 buffers[CHANNEL_LEFT] = cmixer.buffers[CHANNEL_LEFT]; 562 buffers[CHANNEL_RIGHT] = cmixer.buffers[CHANNEL_RIGHT]; 563 buffers[CHANNEL_MONO] = cmixer.buffers[CHANNEL_MONO]; 564 buffers[CHANNEL_DELAY_LEFT] = cmixer.buffers[CHANNEL_DELAY_LEFT]; 565 buffers[CHANNEL_DELAY_RIGHT] = cmixer.buffers[CHANNEL_DELAY_RIGHT]; 566 buffers[CHANNEL_DELAY_MONO] = cmixer.buffers[CHANNEL_DELAY_MONO]; 567 568 buffers[CHANNEL_LEFT].clear(); 569 buffers[CHANNEL_RIGHT].clear(); 570 buffers[CHANNEL_MONO].clear(); 571 572 if(!buffers[CHANNEL_DELAY_LEFT].isSilent()) 573 { 574 buffers[CHANNEL_LEFT].swap(buffers[CHANNEL_DELAY_LEFT]); 575 } 576 if(!buffers[CHANNEL_DELAY_RIGHT].isSilent()) 577 { 578 buffers[CHANNEL_RIGHT].swap(buffers[CHANNEL_DELAY_RIGHT]); 579 } 580 if(!buffers[CHANNEL_DELAY_MONO].isSilent()) 581 { 582 buffers[CHANNEL_MONO].swap(buffers[CHANNEL_DELAY_MONO]); 583 } 584 585 cbuffer[0] = buffers[CHANNEL_LEFT].array(); 586 if (nrofchannels != 1) 587 cbuffer[1] = buffers[CHANNEL_RIGHT].array(); 588 589 boolean hasactivevoices = false; 590 for (int i = 0; i < voicestatus.length; i++) 591 if (voicestatus[i].active) 592 if (voicestatus[i].channelmixer == cmixer.mixer) { 593 voicestatus[i].processAudioLogic(buffers); 594 hasactivevoices = true; 595 } 596 597 if(!buffers[CHANNEL_MONO].isSilent()) 598 { 599 float[] mono = buffers[CHANNEL_MONO].array(); 600 float[] left = buffers[CHANNEL_LEFT].array(); 601 if (nrofchannels != 1) { 602 float[] right = buffers[CHANNEL_RIGHT].array(); 603 for (int i = 0; i < bufferlen; i++) { 604 float v = mono[i]; 605 left[i] += v; 606 right[i] += v; 607 } 608 } 609 else 610 { 611 for (int i = 0; i < bufferlen; i++) { 612 left[i] += mono[i]; 613 } 614 } 615 } 616 617 if (!cmixer.mixer.process(cbuffer, 0, bufferlen)) { 618 synchronized (control_mutex) { 619 registeredMixers.remove(cmixer); 620 cur_registeredMixers = null; 621 } 622 } 623 624 for (int i = 0; i < cbuffer.length; i++) { 625 float[] cbuff = cbuffer[i]; 626 float[] obuff = obuffer[i]; 627 for (int j = 0; j < bufferlen; j++) 628 obuff[j] += cbuff[j]; 629 } 630 631 if (!hasactivevoices) { 632 synchronized (control_mutex) { 633 if (stoppedMixers != null) { 634 if (stoppedMixers.contains(cmixer)) { 635 stoppedMixers.remove(cmixer); 636 cmixer.mixer.stop(); 637 } 638 } 639 } 640 } 641 642 } 643 644 buffers[CHANNEL_LEFT] = leftbak; 645 buffers[CHANNEL_RIGHT] = rightbak; 646 buffers[CHANNEL_MONO] = monobak; 647 buffers[CHANNEL_DELAY_LEFT] = delayleftbak; 648 buffers[CHANNEL_DELAY_RIGHT] = delayrightbak; 649 buffers[CHANNEL_DELAY_MONO] = delaymonobak; 650 651 } 652 653 for (int i = 0; i < voicestatus.length; i++) 654 if (voicestatus[i].active) 655 if (voicestatus[i].channelmixer == null) 656 voicestatus[i].processAudioLogic(buffers); 657 658 if(!buffers[CHANNEL_MONO].isSilent()) 659 { 660 float[] mono = buffers[CHANNEL_MONO].array(); 661 float[] left = buffers[CHANNEL_LEFT].array(); 662 int bufferlen = buffers[CHANNEL_LEFT].getSize(); 663 if (nrofchannels != 1) { 664 float[] right = buffers[CHANNEL_RIGHT].array(); 665 for (int i = 0; i < bufferlen; i++) { 666 float v = mono[i]; 667 left[i] += v; 668 right[i] += v; 669 } 670 } 671 else 672 { 673 for (int i = 0; i < bufferlen; i++) { 674 left[i] += mono[i]; 675 } 676 } 677 } 678 679 // Run effects 680 if (synth.chorus_on) 681 chorus.processAudio(); 682 683 if (synth.reverb_on) 684 reverb.processAudio(); 685 686 if (nrofchannels == 1) 687 volume_left = (volume_left + volume_right) / 2; 688 689 // Set Volume / Balance 690 if (last_volume_left != volume_left || last_volume_right != volume_right) { 691 float[] left = buffers[CHANNEL_LEFT].array(); 692 float[] right = buffers[CHANNEL_RIGHT].array(); 693 int bufferlen = buffers[CHANNEL_LEFT].getSize(); 694 695 float amp; 696 float amp_delta; 697 amp = (float)(last_volume_left * last_volume_left); 698 amp_delta = (float)((volume_left * volume_left - amp) / bufferlen); 699 for (int i = 0; i < bufferlen; i++) { 700 amp += amp_delta; 701 left[i] *= amp; 702 } 703 if (nrofchannels != 1) { 704 amp = (float)(last_volume_right * last_volume_right); 705 amp_delta = (float)((volume_right*volume_right - amp) / bufferlen); 706 for (int i = 0; i < bufferlen; i++) { 707 amp += amp_delta; 708 right[i] *= volume_right; 709 } 710 } 711 last_volume_left = volume_left; 712 last_volume_right = volume_right; 713 714 } else { 715 if (volume_left != 1.0 || volume_right != 1.0) { 716 float[] left = buffers[CHANNEL_LEFT].array(); 717 float[] right = buffers[CHANNEL_RIGHT].array(); 718 int bufferlen = buffers[CHANNEL_LEFT].getSize(); 719 float amp; 720 amp = (float) (volume_left * volume_left); 721 for (int i = 0; i < bufferlen; i++) 722 left[i] *= amp; 723 if (nrofchannels != 1) { 724 amp = (float)(volume_right * volume_right); 725 for (int i = 0; i < bufferlen; i++) 726 right[i] *= amp; 727 } 728 729 } 730 } 731 732 if(buffers[CHANNEL_LEFT].isSilent() 733 && buffers[CHANNEL_RIGHT].isSilent()) 734 { 735 736 int midimessages_size; 737 synchronized (control_mutex) { 738 midimessages_size = midimessages.size(); 739 } 740 741 if(midimessages_size == 0) 742 { 743 pusher_silent_count++; 744 if(pusher_silent_count > 5) 745 { 746 pusher_silent_count = 0; 747 synchronized (control_mutex) { 748 pusher_silent = true; 749 if(synth.weakstream != null) 750 synth.weakstream.setInputStream(null); 751 } 752 } 753 } 754 } 755 else 756 pusher_silent_count = 0; 757 758 if (synth.agc_on) 759 agc.processAudio(); 760 761 } 762 763 // Must only we called within control_mutex synchronization 764 public void activity() 765 { 766 long silent_samples = 0; 767 if(pusher_silent) 768 { 769 pusher_silent = false; 770 if(synth.weakstream != null) 771 { 772 synth.weakstream.setInputStream(ais); 773 silent_samples = synth.weakstream.silent_samples; 774 } 775 } 776 msec_last_activity = (long)((sample_pos + silent_samples) 777 * (1000000.0 / samplerate)); 778 } 779 780 public void stopMixer(ModelChannelMixer mixer) { 781 if (stoppedMixers == null) 782 stoppedMixers = new HashSet<>(); 783 stoppedMixers.add(mixer); 784 } 785 786 public void registerMixer(ModelChannelMixer mixer) { 787 if (registeredMixers == null) 788 registeredMixers = new HashSet<>(); 789 SoftChannelMixerContainer mixercontainer = new SoftChannelMixerContainer(); 790 mixercontainer.buffers = new SoftAudioBuffer[6]; 791 for (int i = 0; i < mixercontainer.buffers.length; i++) { 792 mixercontainer.buffers[i] = 793 new SoftAudioBuffer(buffer_len, synth.getFormat()); 794 } 795 mixercontainer.mixer = mixer; 796 registeredMixers.add(mixercontainer); 797 cur_registeredMixers = null; 798 } 799 800 public SoftMainMixer(SoftSynthesizer synth) { 801 this.synth = synth; 802 803 sample_pos = 0; 804 805 co_master_balance[0] = 0.5; 806 co_master_volume[0] = 1; 807 co_master_coarse_tuning[0] = 0.5; 808 co_master_fine_tuning[0] = 0.5; 809 810 msec_buffer_len = (long) (1000000.0 / synth.getControlRate()); 811 samplerate = synth.getFormat().getSampleRate(); 812 nrofchannels = synth.getFormat().getChannels(); 813 814 int buffersize = (int) (synth.getFormat().getSampleRate() 815 / synth.getControlRate()); 816 817 buffer_len = buffersize; 818 819 max_delay_midievent = buffersize; 820 821 control_mutex = synth.control_mutex; 822 buffers = new SoftAudioBuffer[14]; 823 for (int i = 0; i < buffers.length; i++) { 824 buffers[i] = new SoftAudioBuffer(buffersize, synth.getFormat()); 825 } 826 voicestatus = synth.getVoices(); 827 828 reverb = new SoftReverb(); 829 chorus = new SoftChorus(); 830 agc = new SoftLimiter(); 831 832 float samplerate = synth.getFormat().getSampleRate(); 833 float controlrate = synth.getControlRate(); 834 reverb.init(samplerate, controlrate); 835 chorus.init(samplerate, controlrate); 836 agc.init(samplerate, controlrate); 837 838 reverb.setLightMode(synth.reverb_light); 839 840 reverb.setMixMode(true); 841 chorus.setMixMode(true); 842 agc.setMixMode(false); 843 844 chorus.setInput(0, buffers[CHANNEL_EFFECT2]); 845 chorus.setOutput(0, buffers[CHANNEL_LEFT]); 846 if (nrofchannels != 1) 847 chorus.setOutput(1, buffers[CHANNEL_RIGHT]); 848 chorus.setOutput(2, buffers[CHANNEL_EFFECT1]); 849 850 reverb.setInput(0, buffers[CHANNEL_EFFECT1]); 851 reverb.setOutput(0, buffers[CHANNEL_LEFT]); 852 if (nrofchannels != 1) 853 reverb.setOutput(1, buffers[CHANNEL_RIGHT]); 854 855 agc.setInput(0, buffers[CHANNEL_LEFT]); 856 if (nrofchannels != 1) 857 agc.setInput(1, buffers[CHANNEL_RIGHT]); 858 agc.setOutput(0, buffers[CHANNEL_LEFT]); 859 if (nrofchannels != 1) 860 agc.setOutput(1, buffers[CHANNEL_RIGHT]); 861 862 InputStream in = new InputStream() { 863 864 private final SoftAudioBuffer[] buffers = SoftMainMixer.this.buffers; 865 private final int nrofchannels 866 = SoftMainMixer.this.synth.getFormat().getChannels(); 867 private final int buffersize = buffers[0].getSize(); 868 private final byte[] bbuffer = new byte[buffersize 869 * (SoftMainMixer.this.synth.getFormat() 870 .getSampleSizeInBits() / 8) 871 * nrofchannels]; 872 private int bbuffer_pos = 0; 873 private final byte[] single = new byte[1]; 874 875 public void fillBuffer() { 876 /* 877 boolean pusher_silent2; 878 synchronized (control_mutex) { 879 pusher_silent2 = pusher_silent; 880 } 881 if(!pusher_silent2)*/ 882 processAudioBuffers(); 883 for (int i = 0; i < nrofchannels; i++) 884 buffers[i].get(bbuffer, i); 885 bbuffer_pos = 0; 886 } 887 888 @Override 889 public int read(byte[] b, int off, int len) { 890 int bbuffer_len = bbuffer.length; 891 int offlen = off + len; 892 int orgoff = off; 893 byte[] bbuffer = this.bbuffer; 894 while (off < offlen) { 895 if (available() == 0) 896 fillBuffer(); 897 else { 898 int bbuffer_pos = this.bbuffer_pos; 899 while (off < offlen && bbuffer_pos < bbuffer_len) 900 b[off++] = bbuffer[bbuffer_pos++]; 901 this.bbuffer_pos = bbuffer_pos; 902 if (!readfully) 903 return off - orgoff; 904 } 905 } 906 return len; 907 } 908 909 @Override 910 public int read() throws IOException { 911 int ret = read(single); 912 if (ret == -1) 913 return -1; 914 return single[0] & 0xFF; 915 } 916 917 @Override 918 public int available() { 919 return bbuffer.length - bbuffer_pos; 920 } 921 922 @Override 923 public void close() { 924 SoftMainMixer.this.synth.close(); 925 } 926 }; 927 928 ais = new AudioInputStream(in, synth.getFormat(), AudioSystem.NOT_SPECIFIED); 929 930 } 931 932 public AudioInputStream getInputStream() { 933 return ais; 934 } 935 936 public void reset() { 937 938 SoftChannel[] channels = synth.channels; 939 for (int i = 0; i < channels.length; i++) { 940 channels[i].allSoundOff(); 941 channels[i].resetAllControllers(true); 942 943 if (synth.getGeneralMidiMode() == 2) { 944 if (i == 9) 945 channels[i].programChange(0, 0x78 * 128); 946 else 947 channels[i].programChange(0, 0x79 * 128); 948 } else 949 channels[i].programChange(0, 0); 950 } 951 setVolume(0x7F * 128 + 0x7F); 952 setBalance(0x40 * 128 + 0x00); 953 setCoarseTuning(0x40 * 128 + 0x00); 954 setFineTuning(0x40 * 128 + 0x00); 955 // Reset Reverb 956 globalParameterControlChange( 957 new int[]{0x01 * 128 + 0x01}, new long[]{0}, new long[]{4}); 958 // Reset Chorus 959 globalParameterControlChange( 960 new int[]{0x01 * 128 + 0x02}, new long[]{0}, new long[]{2}); 961 } 962 963 public void setVolume(int value) { 964 synchronized (control_mutex) { 965 co_master_volume[0] = value / 16384.0; 966 } 967 } 968 969 public void setBalance(int value) { 970 synchronized (control_mutex) { 971 co_master_balance[0] = value / 16384.0; 972 } 973 } 974 975 public void setFineTuning(int value) { 976 synchronized (control_mutex) { 977 co_master_fine_tuning[0] = value / 16384.0; 978 } 979 } 980 981 public void setCoarseTuning(int value) { 982 synchronized (control_mutex) { 983 co_master_coarse_tuning[0] = value / 16384.0; 984 } 985 } 986 987 public int getVolume() { 988 synchronized (control_mutex) { 989 return (int) (co_master_volume[0] * 16384.0); 990 } 991 } 992 993 public int getBalance() { 994 synchronized (control_mutex) { 995 return (int) (co_master_balance[0] * 16384.0); 996 } 997 } 998 999 public int getFineTuning() { 1000 synchronized (control_mutex) { 1001 return (int) (co_master_fine_tuning[0] * 16384.0); 1002 } 1003 } 1004 1005 public int getCoarseTuning() { 1006 synchronized (control_mutex) { 1007 return (int) (co_master_coarse_tuning[0] * 16384.0); 1008 } 1009 } 1010 1011 public void globalParameterControlChange(int[] slothpath, long[] params, 1012 long[] paramsvalue) { 1013 if (slothpath.length == 0) 1014 return; 1015 1016 synchronized (control_mutex) { 1017 1018 // slothpath: 01xx are reserved only for GM2 1019 1020 if (slothpath[0] == 0x01 * 128 + 0x01) { 1021 for (int i = 0; i < paramsvalue.length; i++) { 1022 reverb.globalParameterControlChange(slothpath, params[i], 1023 paramsvalue[i]); 1024 } 1025 } 1026 if (slothpath[0] == 0x01 * 128 + 0x02) { 1027 for (int i = 0; i < paramsvalue.length; i++) { 1028 chorus.globalParameterControlChange(slothpath, params[i], 1029 paramsvalue[i]); 1030 } 1031 1032 } 1033 1034 } 1035 } 1036 1037 public void processMessage(Object object) { 1038 if (object instanceof byte[]) 1039 processMessage((byte[]) object); 1040 if (object instanceof MidiMessage) 1041 processMessage((MidiMessage)object); 1042 } 1043 1044 public void processMessage(MidiMessage message) { 1045 if (message instanceof ShortMessage) { 1046 ShortMessage sms = (ShortMessage)message; 1047 processMessage(sms.getChannel(), sms.getCommand(), 1048 sms.getData1(), sms.getData2()); 1049 return; 1050 } 1051 processMessage(message.getMessage()); 1052 } 1053 1054 public void processMessage(byte[] data) { 1055 int status = 0; 1056 if (data.length > 0) 1057 status = data[0] & 0xFF; 1058 1059 if (status == 0xF0) { 1060 processSystemExclusiveMessage(data); 1061 return; 1062 } 1063 1064 int cmd = (status & 0xF0); 1065 int ch = (status & 0x0F); 1066 1067 int data1; 1068 int data2; 1069 if (data.length > 1) 1070 data1 = data[1] & 0xFF; 1071 else 1072 data1 = 0; 1073 if (data.length > 2) 1074 data2 = data[2] & 0xFF; 1075 else 1076 data2 = 0; 1077 1078 processMessage(ch, cmd, data1, data2); 1079 1080 } 1081 1082 public void processMessage(int ch, int cmd, int data1, int data2) { 1083 synchronized (synth.control_mutex) { 1084 activity(); 1085 } 1086 1087 if (cmd == 0xF0) { 1088 int status = cmd | ch; 1089 switch (status) { 1090 case ShortMessage.ACTIVE_SENSING: 1091 synchronized (synth.control_mutex) { 1092 active_sensing_on = true; 1093 } 1094 break; 1095 default: 1096 break; 1097 } 1098 return; 1099 } 1100 1101 SoftChannel[] channels = synth.channels; 1102 if (ch >= channels.length) 1103 return; 1104 SoftChannel softchannel = channels[ch]; 1105 1106 switch (cmd) { 1107 case ShortMessage.NOTE_ON: 1108 if(delay_midievent != 0) 1109 softchannel.noteOn(data1, data2, delay_midievent); 1110 else 1111 softchannel.noteOn(data1, data2); 1112 break; 1113 case ShortMessage.NOTE_OFF: 1114 softchannel.noteOff(data1, data2); 1115 break; 1116 case ShortMessage.POLY_PRESSURE: 1117 softchannel.setPolyPressure(data1, data2); 1118 break; 1119 case ShortMessage.CONTROL_CHANGE: 1120 softchannel.controlChange(data1, data2); 1121 break; 1122 case ShortMessage.PROGRAM_CHANGE: 1123 softchannel.programChange(data1); 1124 break; 1125 case ShortMessage.CHANNEL_PRESSURE: 1126 softchannel.setChannelPressure(data1); 1127 break; 1128 case ShortMessage.PITCH_BEND: 1129 softchannel.setPitchBend(data1 + data2 * 128); 1130 break; 1131 default: 1132 break; 1133 } 1134 1135 } 1136 1137 public long getMicrosecondPosition() { 1138 if(pusher_silent) 1139 { 1140 if(synth.weakstream != null) 1141 { 1142 return (long)((sample_pos + synth.weakstream.silent_samples) 1143 * (1000000.0 / samplerate)); 1144 } 1145 } 1146 return (long)(sample_pos * (1000000.0 / samplerate)); 1147 } 1148 1149 public void close() { 1150 } 1151} 1152