< prev index next >

src/java.desktop/share/classes/com/sun/media/sound/SoftMainMixer.java

Print this page




   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */

  25 package com.sun.media.sound;
  26 
  27 import java.io.IOException;
  28 import java.io.InputStream;
  29 import java.util.HashSet;
  30 import java.util.Iterator;

  31 import java.util.Set;
  32 import java.util.TreeMap;
  33 import java.util.Map.Entry;
  34 
  35 import javax.sound.midi.MidiMessage;
  36 import javax.sound.midi.Patch;
  37 import javax.sound.midi.ShortMessage;
  38 import javax.sound.sampled.AudioInputStream;
  39 import javax.sound.sampled.AudioSystem;
  40 
  41 /**
  42  * Software synthesizer main audio mixer.
  43  *
  44  * @author Karl Helgason
  45  */
  46 public final class SoftMainMixer {
  47 
  48     // A private class thats contains a ModelChannelMixer and it's private buffers.
  49     // This becomes necessary when we want to have separate delay buffers for each channel mixer.
  50     private class SoftChannelMixerContainer
  51     {
  52         ModelChannelMixer mixer;
  53         SoftAudioBuffer[] buffers;


  57     public static final int CHANNEL_RIGHT = 1;
  58     public static final int CHANNEL_MONO = 2;
  59     public static final int CHANNEL_DELAY_LEFT = 3;
  60     public static final int CHANNEL_DELAY_RIGHT = 4;
  61     public static final int CHANNEL_DELAY_MONO = 5;
  62     public static final int CHANNEL_EFFECT1 = 6;
  63     public static final int CHANNEL_EFFECT2 = 7;
  64     public static final int CHANNEL_DELAY_EFFECT1 = 8;
  65     public static final int CHANNEL_DELAY_EFFECT2 = 9;
  66     public static final int CHANNEL_LEFT_DRY = 10;
  67     public static final int CHANNEL_RIGHT_DRY = 11;
  68     public static final int CHANNEL_SCRATCH1 = 12;
  69     public static final int CHANNEL_SCRATCH2 = 13;
  70     boolean active_sensing_on = false;
  71     private long msec_last_activity = -1;
  72     private boolean pusher_silent = false;
  73     private int pusher_silent_count = 0;
  74     private long sample_pos = 0;
  75     boolean readfully = true;
  76     private final Object control_mutex;
  77     private SoftSynthesizer synth;
  78     private float samplerate = 44100;
  79     private int nrofchannels = 2;
  80     private SoftVoice[] voicestatus = null;
  81     private SoftAudioBuffer[] buffers;
  82     private SoftReverb reverb;
  83     private SoftAudioProcessor chorus;
  84     private SoftAudioProcessor agc;
  85     private long msec_buffer_len = 0;
  86     private int buffer_len = 0;
  87     TreeMap<Long, Object> midimessages = new TreeMap<Long, Object>();
  88     private int delay_midievent = 0;
  89     private int max_delay_midievent = 0;
  90     double last_volume_left = 1.0;
  91     double last_volume_right = 1.0;
  92     private double[] co_master_balance = new double[1];
  93     private double[] co_master_volume = new double[1];
  94     private double[] co_master_coarse_tuning = new double[1];
  95     private double[] co_master_fine_tuning = new double[1];
  96     private AudioInputStream ais;
  97     private Set<SoftChannelMixerContainer> registeredMixers = null;
  98     private Set<ModelChannelMixer> stoppedMixers = null;
  99     private SoftChannelMixerContainer[] cur_registeredMixers = null;
 100     SoftControl co_master = new SoftControl() {
 101 
 102         double[] balance = co_master_balance;
 103         double[] volume = co_master_volume;
 104         double[] coarse_tuning = co_master_coarse_tuning;
 105         double[] fine_tuning = co_master_fine_tuning;
 106 

 107         public double[] get(int instance, String name) {
 108             if (name == null)
 109                 return null;
 110             if (name.equals("balance"))
 111                 return balance;
 112             if (name.equals("volume"))
 113                 return volume;
 114             if (name.equals("coarse_tuning"))
 115                 return coarse_tuning;
 116             if (name.equals("fine_tuning"))
 117                 return fine_tuning;
 118             return null;
 119         }
 120     };
 121 
 122     private void processSystemExclusiveMessage(byte[] data) {
 123         synchronized (synth.control_mutex) {
 124             activity();
 125 
 126             // Universal Non-Real-Time SysEx


 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;


 866             private final byte[] bbuffer = new byte[buffersize
 867                     * (SoftMainMixer.this.synth.getFormat()
 868                         .getSampleSizeInBits() / 8)
 869                     * nrofchannels];
 870             private int bbuffer_pos = 0;
 871             private final byte[] single = new byte[1];
 872 
 873             public void fillBuffer() {
 874                 /*
 875                 boolean pusher_silent2;
 876                 synchronized (control_mutex) {
 877                     pusher_silent2 = pusher_silent;
 878                 }
 879                 if(!pusher_silent2)*/
 880                 processAudioBuffers();
 881                 for (int i = 0; i < nrofchannels; i++)
 882                     buffers[i].get(bbuffer, i);
 883                 bbuffer_pos = 0;
 884             }
 885 

 886             public int read(byte[] b, int off, int len) {
 887                 int bbuffer_len = bbuffer.length;
 888                 int offlen = off + len;
 889                 int orgoff = off;
 890                 byte[] bbuffer = this.bbuffer;
 891                 while (off < offlen) {
 892                     if (available() == 0)
 893                         fillBuffer();
 894                     else {
 895                         int bbuffer_pos = this.bbuffer_pos;
 896                         while (off < offlen && bbuffer_pos < bbuffer_len)
 897                             b[off++] = bbuffer[bbuffer_pos++];
 898                         this.bbuffer_pos = bbuffer_pos;
 899                         if (!readfully)
 900                             return off - orgoff;
 901                     }
 902                 }
 903                 return len;
 904             }
 905 

 906             public int read() throws IOException {
 907                 int ret = read(single);
 908                 if (ret == -1)
 909                     return -1;
 910                 return single[0] & 0xFF;
 911             }
 912 

 913             public int available() {
 914                 return bbuffer.length - bbuffer_pos;
 915             }
 916 

 917             public void close() {
 918                 SoftMainMixer.this.synth.close();
 919             }
 920         };
 921 
 922         ais = new AudioInputStream(in, synth.getFormat(), AudioSystem.NOT_SPECIFIED);
 923 
 924     }
 925 
 926     public AudioInputStream getInputStream() {
 927         return ais;
 928     }
 929 
 930     public void reset() {
 931 
 932         SoftChannel[] channels = synth.channels;
 933         for (int i = 0; i < channels.length; i++) {
 934             channels[i].allSoundOff();
 935             channels[i].resetAllControllers(true);
 936 




   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;


  58     public static final int CHANNEL_RIGHT = 1;
  59     public static final int CHANNEL_MONO = 2;
  60     public static final int CHANNEL_DELAY_LEFT = 3;
  61     public static final int CHANNEL_DELAY_RIGHT = 4;
  62     public static final int CHANNEL_DELAY_MONO = 5;
  63     public static final int CHANNEL_EFFECT1 = 6;
  64     public static final int CHANNEL_EFFECT2 = 7;
  65     public static final int CHANNEL_DELAY_EFFECT1 = 8;
  66     public static final int CHANNEL_DELAY_EFFECT2 = 9;
  67     public static final int CHANNEL_LEFT_DRY = 10;
  68     public static final int CHANNEL_RIGHT_DRY = 11;
  69     public static final int CHANNEL_SCRATCH1 = 12;
  70     public static final int CHANNEL_SCRATCH2 = 13;
  71     boolean active_sensing_on = false;
  72     private long msec_last_activity = -1;
  73     private boolean pusher_silent = false;
  74     private int pusher_silent_count = 0;
  75     private long sample_pos = 0;
  76     boolean readfully = true;
  77     private final Object control_mutex;
  78     private final SoftSynthesizer synth;
  79     private float samplerate = 44100;
  80     private int nrofchannels = 2;
  81     private SoftVoice[] voicestatus = null;
  82     private final SoftAudioBuffer[] buffers;
  83     private final SoftReverb reverb;
  84     private final SoftAudioProcessor chorus;
  85     private final SoftAudioProcessor agc;
  86     private long msec_buffer_len = 0;
  87     private int buffer_len = 0;
  88     TreeMap<Long, Object> midimessages = new TreeMap<>();
  89     private int delay_midievent = 0;
  90     private int max_delay_midievent = 0;
  91     double last_volume_left = 1.0;
  92     double last_volume_right = 1.0;
  93     private final double[] co_master_balance = new double[1];
  94     private final double[] co_master_volume = new double[1];
  95     private final double[] co_master_coarse_tuning = new double[1];
  96     private final double[] co_master_fine_tuning = new double[1];
  97     private final AudioInputStream ais;
  98     private Set<SoftChannelMixerContainer> registeredMixers = null;
  99     private Set<ModelChannelMixer> stoppedMixers = null;
 100     private SoftChannelMixerContainer[] cur_registeredMixers = null;
 101     SoftControl co_master = new SoftControl() {
 102 
 103         double[] balance = co_master_balance;
 104         double[] volume = co_master_volume;
 105         double[] coarse_tuning = co_master_coarse_tuning;
 106         double[] fine_tuning = co_master_fine_tuning;
 107 
 108         @Override
 109         public double[] get(int instance, String name) {
 110             if (name == null)
 111                 return null;
 112             if (name.equals("balance"))
 113                 return balance;
 114             if (name.equals("volume"))
 115                 return volume;
 116             if (name.equals("coarse_tuning"))
 117                 return coarse_tuning;
 118             if (name.equals("fine_tuning"))
 119                 return fine_tuning;
 120             return null;
 121         }
 122     };
 123 
 124     private void processSystemExclusiveMessage(byte[] data) {
 125         synchronized (synth.control_mutex) {
 126             activity();
 127 
 128             // Universal Non-Real-Time SysEx


 762 
 763     // Must only we called within control_mutex synchronization
 764     public void activity()
 765     {
 766         long silent_samples = 0;
 767         if(pusher_silent)
 768         {
 769             pusher_silent = false;
 770             if(synth.weakstream != null)
 771             {
 772                 synth.weakstream.setInputStream(ais);
 773                 silent_samples = synth.weakstream.silent_samples;
 774             }
 775         }
 776         msec_last_activity = (long)((sample_pos + silent_samples)
 777                 * (1000000.0 / samplerate));
 778     }
 779 
 780     public void stopMixer(ModelChannelMixer mixer) {
 781         if (stoppedMixers == null)
 782             stoppedMixers = new HashSet<>();
 783         stoppedMixers.add(mixer);
 784     }
 785 
 786     public void registerMixer(ModelChannelMixer mixer) {
 787         if (registeredMixers == null)
 788             registeredMixers = new HashSet<>();
 789         SoftChannelMixerContainer mixercontainer = new SoftChannelMixerContainer();
 790         mixercontainer.buffers = new SoftAudioBuffer[6];
 791         for (int i = 0; i < mixercontainer.buffers.length; i++) {
 792             mixercontainer.buffers[i] =
 793                 new SoftAudioBuffer(buffer_len, synth.getFormat());
 794         }
 795         mixercontainer.mixer = mixer;
 796         registeredMixers.add(mixercontainer);
 797         cur_registeredMixers = null;
 798     }
 799 
 800     public SoftMainMixer(SoftSynthesizer synth) {
 801         this.synth = synth;
 802 
 803         sample_pos = 0;
 804 
 805         co_master_balance[0] = 0.5;
 806         co_master_volume[0] = 1;
 807         co_master_coarse_tuning[0] = 0.5;
 808         co_master_fine_tuning[0] = 0.5;


 868             private final byte[] bbuffer = new byte[buffersize
 869                     * (SoftMainMixer.this.synth.getFormat()
 870                         .getSampleSizeInBits() / 8)
 871                     * nrofchannels];
 872             private int bbuffer_pos = 0;
 873             private final byte[] single = new byte[1];
 874 
 875             public void fillBuffer() {
 876                 /*
 877                 boolean pusher_silent2;
 878                 synchronized (control_mutex) {
 879                     pusher_silent2 = pusher_silent;
 880                 }
 881                 if(!pusher_silent2)*/
 882                 processAudioBuffers();
 883                 for (int i = 0; i < nrofchannels; i++)
 884                     buffers[i].get(bbuffer, i);
 885                 bbuffer_pos = 0;
 886             }
 887 
 888             @Override
 889             public int read(byte[] b, int off, int len) {
 890                 int bbuffer_len = bbuffer.length;
 891                 int offlen = off + len;
 892                 int orgoff = off;
 893                 byte[] bbuffer = this.bbuffer;
 894                 while (off < offlen) {
 895                     if (available() == 0)
 896                         fillBuffer();
 897                     else {
 898                         int bbuffer_pos = this.bbuffer_pos;
 899                         while (off < offlen && bbuffer_pos < bbuffer_len)
 900                             b[off++] = bbuffer[bbuffer_pos++];
 901                         this.bbuffer_pos = bbuffer_pos;
 902                         if (!readfully)
 903                             return off - orgoff;
 904                     }
 905                 }
 906                 return len;
 907             }
 908 
 909             @Override
 910             public int read() throws IOException {
 911                 int ret = read(single);
 912                 if (ret == -1)
 913                     return -1;
 914                 return single[0] & 0xFF;
 915             }
 916 
 917             @Override
 918             public int available() {
 919                 return bbuffer.length - bbuffer_pos;
 920             }
 921 
 922             @Override
 923             public void close() {
 924                 SoftMainMixer.this.synth.close();
 925             }
 926         };
 927 
 928         ais = new AudioInputStream(in, synth.getFormat(), AudioSystem.NOT_SPECIFIED);
 929 
 930     }
 931 
 932     public AudioInputStream getInputStream() {
 933         return ais;
 934     }
 935 
 936     public void reset() {
 937 
 938         SoftChannel[] channels = synth.channels;
 939         for (int i = 0; i < channels.length; i++) {
 940             channels[i].allSoundOff();
 941             channels[i].resetAllControllers(true);
 942 


< prev index next >