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.io.IOException;
  29 import java.io.InputStream;
  30 import java.util.HashSet;
  31 import java.util.Iterator;
  32 import java.util.Map.Entry;
  33 import java.util.Set;
  34 import java.util.TreeMap;
  35 
  36 import javax.sound.midi.MidiMessage;
  37 import javax.sound.midi.Patch;
  38 import javax.sound.midi.ShortMessage;
  39 import javax.sound.sampled.AudioInputStream;
  40 import javax.sound.sampled.AudioSystem;
  41 
  42 /**
  43  * Software synthesizer main audio mixer.
  44  *
  45  * @author Karl Helgason
  46  */
  47 public 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 }