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 }