Save This Page
Home » openjdk-7 » com.sun.media » sound » [javadoc | source]
    1   /*
    2    * Copyright (c) 2007, 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 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       protected 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       protected boolean readfully = true;
   76       private 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       protected 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       protected 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       protected 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 SoftAudioBuffer[] buffers = SoftMainMixer.this.buffers;
  863               private int nrofchannels
  864                       = SoftMainMixer.this.synth.getFormat().getChannels();
  865               private int buffersize = buffers[0].getSize();
  866               private byte[] bbuffer = new byte[buffersize
  867                       * (SoftMainMixer.this.synth.getFormat()
  868                           .getSampleSizeInBits() / 8)
  869                       * nrofchannels];
  870               private int bbuffer_pos = 0;
  871               private 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   }

Save This Page
Home » openjdk-7 » com.sun.media » sound » [javadoc | source]