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