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