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
|