toxiclibs 0.9.1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,159 +0,0 @@
1
- /*
2
- * __ .__ .__ ._____.
3
- * _/ |_ _______ __|__| ____ | | |__\_ |__ ______
4
- * \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/
5
- * | | ( <_> > <| \ \___| |_| || \_\ \\___ \
6
- * |__| \____/__/\_ \__|\___ >____/__||___ /____ >
7
- * \/ \/ \/ \/
8
- *
9
- * Copyright (c) 2006-2011 Karsten Schmidt
10
- *
11
- * This library is free software; you can redistribute it and/or
12
- * modify it under the terms of the GNU Lesser General Public
13
- * License as published by the Free Software Foundation; either
14
- * version 2.1 of the License, or (at your option) any later version.
15
- *
16
- * http://creativecommons.org/licenses/LGPL/2.1/
17
- *
18
- * This library is distributed in the hope that it will be useful,
19
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21
- * Lesser General Public License for more details.
22
- *
23
- * You should have received a copy of the GNU Lesser General Public
24
- * License along with this library; if not, write to the Free Software
25
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26
- */
27
- package toxi.audio;
28
-
29
- import java.io.FilterInputStream;
30
- import java.io.IOException;
31
- import java.io.InputStream;
32
-
33
- /**
34
- * <p>
35
- * Convert A-Law or u-Law byte stream into mono PCM byte stream
36
- * </p>
37
- *
38
- * <code>
39
- * static AudioFormat alawformat= new AudioFormat(AudioFormat.Encoding.ALAW,8000,8,1,1,8000,false);
40
- * static AudioFormat ulawformat= new AudioFormat(AudioFormat.Encoding.ULAW,8000,8,1,1,8000,false);
41
- * </code>
42
- * <p>
43
- * PCM 8000.0 Hz, 16 bit, mono, SIGNED, little-endian
44
- * </p>
45
- * <code>static AudioFormat pcmformat = new AudioFormat(8000,16,1,true,false);</code>
46
- *
47
- * <p>
48
- * From: Mathematical Tools in Signal Processing with C++ and Java Simulations
49
- * by Willi-Hans Steeb International School for Scientific Computing
50
- * </p>
51
- */
52
- public class DecompressInputStream extends FilterInputStream {
53
-
54
- private static final int[] ALAWTABLE = { 0x80ea, 0x80eb, 0x80e8, 0x80e9, 0x80ee,
55
- 0x80ef, 0x80ec, 0x80ed, 0x80e2, 0x80e3, 0x80e0, 0x80e1, 0x80e6,
56
- 0x80e7, 0x80e4, 0x80e5, 0x40f5, 0xc0f5, 0x40f4, 0xc0f4, 0x40f7,
57
- 0xc0f7, 0x40f6, 0xc0f6, 0x40f1, 0xc0f1, 0x40f0, 0xc0f0, 0x40f3,
58
- 0xc0f3, 0x40f2, 0xc0f2, 0x00aa, 0x00ae, 0x00a2, 0x00a6, 0x00ba,
59
- 0x00be, 0x00b2, 0x00b6, 0x008a, 0x008e, 0x0082, 0x0086, 0x009a,
60
- 0x009e, 0x0092, 0x0096, 0x00d5, 0x00d7, 0x00d1, 0x00d3, 0x00dd,
61
- 0x00df, 0x00d9, 0x00db, 0x00c5, 0x00c7, 0x00c1, 0x00c3, 0x00cd,
62
- 0x00cf, 0x00c9, 0x00cb, 0xa8fe, 0xb8fe, 0x88fe, 0x98fe, 0xe8fe,
63
- 0xf8fe, 0xc8fe, 0xd8fe, 0x28fe, 0x38fe, 0x08fe, 0x18fe, 0x68fe,
64
- 0x78fe, 0x48fe, 0x58fe, 0xa8ff, 0xb8ff, 0x88ff, 0x98ff, 0xe8ff,
65
- 0xf8ff, 0xc8ff, 0xd8ff, 0x28ff, 0x38ff, 0x08ff, 0x18ff, 0x68ff,
66
- 0x78ff, 0x48ff, 0x58ff, 0xa0fa, 0xe0fa, 0x20fa, 0x60fa, 0xa0fb,
67
- 0xe0fb, 0x20fb, 0x60fb, 0xa0f8, 0xe0f8, 0x20f8, 0x60f8, 0xa0f9,
68
- 0xe0f9, 0x20f9, 0x60f9, 0x50fd, 0x70fd, 0x10fd, 0x30fd, 0xd0fd,
69
- 0xf0fd, 0x90fd, 0xb0fd, 0x50fc, 0x70fc, 0x10fc, 0x30fc, 0xd0fc,
70
- 0xf0fc, 0x90fc, 0xb0fc, 0x8015, 0x8014, 0x8017, 0x8016, 0x8011,
71
- 0x8010, 0x8013, 0x8012, 0x801d, 0x801c, 0x801f, 0x801e, 0x8019,
72
- 0x8018, 0x801b, 0x801a, 0xc00a, 0x400a, 0xc00b, 0x400b, 0xc008,
73
- 0x4008, 0xc009, 0x4009, 0xc00e, 0x400e, 0xc00f, 0x400f, 0xc00c,
74
- 0x400c, 0xc00d, 0x400d, 0x0056, 0x0052, 0x005e, 0x005a, 0x0046,
75
- 0x0042, 0x004e, 0x004a, 0x0076, 0x0072, 0x007e, 0x007a, 0x0066,
76
- 0x0062, 0x006e, 0x006a, 0x002b, 0x0029, 0x002f, 0x002d, 0x0023,
77
- 0x0021, 0x0027, 0x0025, 0x003b, 0x0039, 0x003f, 0x003d, 0x0033,
78
- 0x0031, 0x0037, 0x0035, 0x5801, 0x4801, 0x7801, 0x6801, 0x1801,
79
- 0x0801, 0x3801, 0x2801, 0xd801, 0xc801, 0xf801, 0xe801, 0x9801,
80
- 0x8801, 0xb801, 0xa801, 0x5800, 0x4800, 0x7800, 0x6800, 0x1800,
81
- 0x0800, 0x3800, 0x2800, 0xd800, 0xc800, 0xf800, 0xe800, 0x9800,
82
- 0x8800, 0xb800, 0xa800, 0x6005, 0x2005, 0xe005, 0xa005, 0x6004,
83
- 0x2004, 0xe004, 0xa004, 0x6007, 0x2007, 0xe007, 0xa007, 0x6006,
84
- 0x2006, 0xe006, 0xa006, 0xb002, 0x9002, 0xf002, 0xd002, 0x3002,
85
- 0x1002, 0x7002, 0x5002, 0xb003, 0x9003, 0xf003, 0xd003, 0x3003,
86
- 0x1003, 0x7003, 0x5003, };
87
-
88
- private static final int[] ULAWTABLE = { 0x8482, 0x8486, 0x848a, 0x848e, 0x8492,
89
- 0x8496, 0x849a, 0x849e, 0x84a2, 0x84a6, 0x84aa, 0x84ae, 0x84b2,
90
- 0x84b6, 0x84ba, 0x84be, 0x84c1, 0x84c3, 0x84c5, 0x84c7, 0x84c9,
91
- 0x84cb, 0x84cd, 0x84cf, 0x84d1, 0x84d3, 0x84d5, 0x84d7, 0x84d9,
92
- 0x84db, 0x84dd, 0x84df, 0x04e1, 0x04e2, 0x04e3, 0x04e4, 0x04e5,
93
- 0x04e6, 0x04e7, 0x04e8, 0x04e9, 0x04ea, 0x04eb, 0x04ec, 0x04ed,
94
- 0x04ee, 0x04ef, 0x04f0, 0xc4f0, 0x44f1, 0xc4f1, 0x44f2, 0xc4f2,
95
- 0x44f3, 0xc4f3, 0x44f4, 0xc4f4, 0x44f5, 0xc4f5, 0x44f6, 0xc4f6,
96
- 0x44f7, 0xc4f7, 0x44f8, 0xa4f8, 0xe4f8, 0x24f9, 0x64f9, 0xa4f9,
97
- 0xe4f9, 0x24fa, 0x64fa, 0xa4fa, 0xe4fa, 0x24fb, 0x64fb, 0xa4fb,
98
- 0xe4fb, 0x24fc, 0x64fc, 0x94fc, 0xb4fc, 0xd4fc, 0xf4fc, 0x14fd,
99
- 0x34fd, 0x54fd, 0x74fd, 0x94fd, 0xb4fd, 0xd4fd, 0xf4fd, 0x14fe,
100
- 0x34fe, 0x54fe, 0x74fe, 0x8cfe, 0x9cfe, 0xacfe, 0xbcfe, 0xccfe,
101
- 0xdcfe, 0xecfe, 0xfcfe, 0x0cff, 0x1cff, 0x2cff, 0x3cff, 0x4cff,
102
- 0x5cff, 0x6cff, 0x7cff, 0x88ff, 0x90ff, 0x98ff, 0xa0ff, 0xa8ff,
103
- 0xb0ff, 0xb8ff, 0xc0ff, 0xc8ff, 0xd0ff, 0xd8ff, 0xe0ff, 0xe8ff,
104
- 0xf0ff, 0xf8ff, 0x0000, 0x7c7d, 0x7c79, 0x7c75, 0x7c71, 0x7c6d,
105
- 0x7c69, 0x7c65, 0x7c61, 0x7c5d, 0x7c59, 0x7c55, 0x7c51, 0x7c4d,
106
- 0x7c49, 0x7c45, 0x7c41, 0x7c3e, 0x7c3c, 0x7c3a, 0x7c38, 0x7c36,
107
- 0x7c34, 0x7c32, 0x7c30, 0x7c2e, 0x7c2c, 0x7c2a, 0x7c28, 0x7c26,
108
- 0x7c24, 0x7c22, 0x7c20, 0xfc1e, 0xfc1d, 0xfc1c, 0xfc1b, 0xfc1a,
109
- 0xfc19, 0xfc18, 0xfc17, 0xfc16, 0xfc15, 0xfc14, 0xfc13, 0xfc12,
110
- 0xfc11, 0xfc10, 0xfc0f, 0x3c0f, 0xbc0e, 0x3c0e, 0xbc0d, 0x3c0d,
111
- 0xbc0c, 0x3c0c, 0xbc0b, 0x3c0b, 0xbc0a, 0x3c0a, 0xbc09, 0x3c09,
112
- 0xbc08, 0x3c08, 0xbc07, 0x5c07, 0x1c07, 0xdc06, 0x9c06, 0x5c06,
113
- 0x1c06, 0xdc05, 0x9c05, 0x5c05, 0x1c05, 0xdc04, 0x9c04, 0x5c04,
114
- 0x1c04, 0xdc03, 0x9c03, 0x6c03, 0x4c03, 0x2c03, 0x0c03, 0xec02,
115
- 0xcc02, 0xac02, 0x8c02, 0x6c02, 0x4c02, 0x2c02, 0x0c02, 0xec01,
116
- 0xcc01, 0xac01, 0x8c01, 0x7401, 0x6401, 0x5401, 0x4401, 0x3401,
117
- 0x2401, 0x1401, 0x0401, 0xf400, 0xe400, 0xd400, 0xc400, 0xb400,
118
- 0xa400, 0x9400, 0x8400, 0x7800, 0x7000, 0x6800, 0x6000, 0x5800,
119
- 0x5000, 0x4800, 0x4000, 0x3800, 0x3000, 0x2800, 0x2000, 0x1800,
120
- 0x1000, 0x0800, 0x0000, };
121
-
122
- private int[] table = null;
123
-
124
- public DecompressInputStream(InputStream in, boolean useALaw)
125
- throws IOException {
126
- super(in);
127
- table = (useALaw) ? ALAWTABLE : ULAWTABLE;
128
- }
129
-
130
- @Override
131
- public int read() throws IOException {
132
- throw new IOException(getClass().getName()
133
- + ".read() :\n\tDo not support simple read().");
134
- }
135
-
136
- @Override
137
- public int read(byte[] b) throws IOException {
138
- return read(b, 0, b.length);
139
- }
140
-
141
- @Override
142
- public int read(byte[] b, int off, int len) throws IOException {
143
- byte[] inb;
144
- int value;
145
-
146
- inb = new byte[len >> 1]; // get A-Law or u-Law bytes
147
- len = in.read(inb);
148
- if (len == -1) {
149
- return -1;
150
- }
151
-
152
- for (int i = 0; i < len; i++) {
153
- value = table[inb[i] & 0x00FF];
154
- b[off++] = (byte) ((value >> 8) & 0x00FF); // little-endian
155
- b[off++] = (byte) (value & 0x00FF);
156
- }
157
- return len << 1;
158
- }
159
- }
@@ -1,197 +0,0 @@
1
- /*
2
- * __ .__ .__ ._____.
3
- * _/ |_ _______ __|__| ____ | | |__\_ |__ ______
4
- * \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/
5
- * | | ( <_> > <| \ \___| |_| || \_\ \\___ \
6
- * |__| \____/__/\_ \__|\___ >____/__||___ /____ >
7
- * \/ \/ \/ \/
8
- *
9
- * Copyright (c) 2006-2011 Karsten Schmidt
10
- *
11
- * This library is free software; you can redistribute it and/or
12
- * modify it under the terms of the GNU Lesser General Public
13
- * License as published by the Free Software Foundation; either
14
- * version 2.1 of the License, or (at your option) any later version.
15
- *
16
- * http://creativecommons.org/licenses/LGPL/2.1/
17
- *
18
- * This library is distributed in the hope that it will be useful,
19
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21
- * Lesser General Public License for more details.
22
- *
23
- * You should have received a copy of the GNU Lesser General Public
24
- * License along with this library; if not, write to the Free Software
25
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26
- */
27
-
28
- package toxi.audio;
29
-
30
- import toxi.math.MathUtils;
31
- import toxi.math.SinCosLUT;
32
-
33
- /**
34
- * This class provides a simple IIR filter implementation with one of lowpass,
35
- * highpass or bandpass characteristics. The class can filter individual samples
36
- * or entire signal buffers. The filter function always has this form:
37
- *
38
- * <pre>
39
- * y = 1 / a0 * (b0 * x0 + b1 * x1 + b2 * x2 - a1 * q1 - a2 * q2)
40
- * </pre>
41
- *
42
- * http://en.wikipedia.org/wiki/Infinite_impulse_response
43
- */
44
- public class IIRFilter {
45
-
46
- public enum Type {
47
- LOWPASS, HIGHPASS, BANDPASS;
48
- }
49
-
50
- protected static final SinCosLUT SIN_TABLE = new SinCosLUT(0.05f);
51
-
52
- protected final Type type;
53
-
54
- protected float b0, b1, b2, a0, a1, a2, alpha;
55
- protected float out1, out2, in1, in2;
56
-
57
- protected final float sampleRate;
58
- protected final float sampleRateRadians;
59
-
60
- protected float decay = 0.999f;
61
-
62
- /**
63
- * @param type
64
- * @param sampleRate
65
- */
66
- public IIRFilter(Type type, float sampleRate) {
67
- this.type = type;
68
- this.sampleRate = sampleRate;
69
- sampleRateRadians = MathUtils.TWO_PI / sampleRate;
70
- }
71
-
72
- /**
73
- * Just calculates the amplitude of the filtered signal, but doesn't
74
- * actually apply the filter.
75
- *
76
- * @param in
77
- * @return amplitude
78
- */
79
- public float calculateAmplitude(float[] in) {
80
- float amp = 0;
81
- for (int i = 0; i < in.length; i++) {
82
- final float yn = a0
83
- * (b0 * in[i] + b1 * in1 + b2 * in2 - a1 * out1 - a2 * out2);
84
- in2 = in1;
85
- in1 = in[i];
86
- out2 = out1;
87
- out1 = yn;
88
- if (amp < MathUtils.abs(yn)) {
89
- amp = yn;
90
- } else {
91
- amp *= decay;
92
- }
93
- }
94
- return amp;
95
- }
96
-
97
- public IIRFilter clear() {
98
- in1 = in2 = 0;
99
- out1 = out2 = 0;
100
- return this;
101
- };
102
-
103
- /**
104
- * Applies filter to a single sample value.
105
- *
106
- * @param in
107
- * @return filtered sample
108
- */
109
- public float filter(float in) {
110
- final float yn = a0
111
- * (b0 * in + b1 * in1 + b2 * in2 - a1 * out1 - a2 * out2);
112
- in2 = in1;
113
- in1 = in;
114
- out2 = out1;
115
- out1 = yn;
116
- return yn;
117
- }
118
-
119
- /**
120
- * Destructively filters a the given signal buffer. The original samples are
121
- * overwritten.
122
- *
123
- * @param in
124
- * @return amplitude of filtered signal
125
- */
126
- public float filter(float[] in) {
127
- float amp = 0;
128
- for (int i = 0; i < in.length; i++) {
129
- final float yn = a0
130
- * (b0 * in[i] + b1 * in1 + b2 * in2 - a1 * out1 - a2 * out2);
131
- in2 = in1;
132
- in1 = in[i];
133
- out2 = out1;
134
- out1 = yn;
135
- in[i] = yn;
136
-
137
- if (amp < MathUtils.abs(in[i])) {
138
- amp = in[i];
139
- } else {
140
- amp *= decay;
141
- }
142
- }
143
- return amp;
144
- }
145
-
146
- /**
147
- * @return the decay
148
- */
149
- public float getDecay() {
150
- return decay;
151
- }
152
-
153
- /**
154
- * Initializes the filter to the given cutoff frequency and Q (resonance)
155
- * settings. This function needs to be called at least once before the
156
- * filter can be used.
157
- *
158
- * @param freq
159
- * @param q
160
- * @return itself
161
- */
162
- public IIRFilter init(final float freq, float q) {
163
- float theta = sampleRateRadians * freq;
164
- float si = SIN_TABLE.sin(theta);
165
- float co = SIN_TABLE.cos(theta);
166
- alpha = si / q;
167
- a0 = 1f / (1 + alpha);
168
- a1 = -2 * co;
169
- a2 = 1 - alpha;
170
- switch (type) {
171
- case LOWPASS:
172
- b0 = b2 = (1f - co) * 0.5f;
173
- b1 = 1f - co;
174
- break;
175
- case HIGHPASS:
176
- b0 = b2 = (1f + co) * 0.5f;
177
- b1 = -(1f + co);
178
- break;
179
- case BANDPASS:
180
- b0 = si * 0.5f;
181
- b1 = 0;
182
- b2 = -si * 0.5f;
183
- break;
184
- }
185
- return this;
186
- }
187
-
188
- /**
189
- * @param decay
190
- * the decay to set
191
- * @return itself
192
- */
193
- public IIRFilter setDecay(float decay) {
194
- this.decay = decay;
195
- return this;
196
- }
197
- }
@@ -1,388 +0,0 @@
1
- /*
2
- * Copyright (c) 2006-2011 Karsten Schmidt
3
- *
4
- * This library is free software; you can redistribute it and/or
5
- * modify it under the terms of the GNU Lesser General Public
6
- * License as published by the Free Software Foundation; either
7
- * version 2.1 of the License, or (at your option) any later version.
8
- *
9
- * http://creativecommons.org/licenses/LGPL/2.1/
10
- *
11
- * This library is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
- * Lesser General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU Lesser General Public
17
- * License along with this library; if not, write to the Free Software
18
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
- * Modified and updated by Martin Prout December 2015
20
- */
21
- package toxi.audio;
22
-
23
- import java.io.IOException;
24
- import java.io.InputStream;
25
- import java.nio.IntBuffer;
26
- import java.util.ArrayList;
27
- import java.util.logging.Logger;
28
-
29
- import javax.sound.sampled.UnsupportedAudioFileException;
30
-
31
- import com.jogamp.openal.AL;
32
- import com.jogamp.openal.ALC;
33
- import com.jogamp.openal.ALCcontext;
34
- import com.jogamp.openal.ALCdevice;
35
- import com.jogamp.openal.ALException;
36
- import com.jogamp.openal.ALFactory;
37
- import com.jogamp.openal.eax.EAX;
38
- import com.jogamp.openal.eax.EAXConstants;
39
- import com.jogamp.openal.eax.EAXFactory;
40
- import com.jogamp.openal.util.WAVData;
41
- import com.jogamp.openal.util.WAVLoader;
42
- import java.util.logging.Level;
43
-
44
- /**
45
- * <a href="https://joal.dev.java.net/">JOAL</a> convenience wrapper. Full
46
- * documentation forthcoming. Please see the attached Processing demo & source
47
- * distribution of this package for basic usage.
48
- */
49
- public class JOALUtil {
50
-
51
- public static String HARDWARE = "Generic Hardware";
52
- public static String SOFTWARE = "Generic Software";
53
-
54
- public static final Logger logger = Logger.getLogger(JOALUtil.class
55
- .getName());
56
-
57
- protected static JOALUtil instance;
58
-
59
- public static JOALUtil getInstance() {
60
- synchronized (JOALUtil.class) {
61
- if (instance == null) {
62
- instance = new JOALUtil();
63
- }
64
- }
65
- return instance;
66
- }
67
-
68
- protected ArrayList<AudioBuffer> buffers;
69
- protected ArrayList<AudioSource> sources;
70
-
71
- protected SoundListener listener;
72
- protected AL al;
73
- protected ALC alc;
74
- protected ALCcontext context;
75
- protected ALCdevice device;
76
-
77
- protected EAX eax;
78
- protected boolean isInited;
79
-
80
- protected boolean isEAX;
81
-
82
- protected JOALUtil() {
83
- }
84
-
85
- /**
86
- * Deletes & releases all sources and buffers created via this class.
87
- */
88
- public void deleteAll() {
89
- logger.info("deleting all sources & buffers...");
90
- while (sources.size() > 0) {
91
- deleteSource(sources.get(0), true);
92
- }
93
- sources.clear();
94
- buffers.clear();
95
- }
96
-
97
- public boolean deleteBuffer(AudioBuffer b) {
98
- if (b != null) {
99
- sources.stream().filter((s) -> (s.getBuffer() == b)).map((s) -> {
100
- s.stop();
101
- return s;
102
- }).forEach((s) -> {
103
- logger.log(Level.FINE, "forced stopping source: {0}", s);
104
- });
105
- boolean result = b.delete();
106
- if (buffers.remove(b)) {
107
- logger.log(Level.INFO, "deleted buffer: {0}", b);
108
- }
109
- return result;
110
- } else {
111
- logger.warning("attempted to delete null buffer");
112
- return true;
113
- }
114
- }
115
-
116
- public boolean deleteSource(AudioSource src) {
117
- return deleteSource(src, false);
118
- }
119
-
120
- public boolean deleteSource(AudioSource src, boolean killBuffer) {
121
- AudioBuffer buffer = src.getBuffer();
122
- boolean result = src.delete();
123
- if (sources.remove(src)) {
124
- logger.log(Level.INFO, "deleted source: {0}", src);
125
- } else {
126
- logger.log(Level.WARNING, "deleted unmanaged source: {0}", src);
127
- }
128
- if (killBuffer && buffer != null) {
129
- result = result && deleteBuffer(buffer);
130
- }
131
- return result;
132
- }
133
-
134
- /**
135
- * Creates the specified number of audio sample buffers and returns an array
136
- * of {@link AudioBuffer} wrappers.
137
- *
138
- * @param numBuffers
139
- * number of requested buffers
140
- * @return array
141
- */
142
- public AudioBuffer[] generateBuffers(int numBuffers) {
143
- if (!isInited) {
144
- init();
145
- }
146
- AudioBuffer[] result = new AudioBuffer[numBuffers];
147
- int[] arr = new int[numBuffers];
148
- al.alGenBuffers(numBuffers, arr, 0);
149
- for (int i = 0; i < numBuffers; i++) {
150
- result[i] = new AudioBuffer(al, arr[i]);
151
- buffers.add(result[i]);
152
- }
153
- return result;
154
- }
155
-
156
- /**
157
- * Convenience wrapper for {@link #generateSources(int)} to create a single
158
- * {@link AudioSource}.
159
- *
160
- * @return audio source instance
161
- */
162
- public AudioSource generateSource() {
163
- return generateSources(1)[0];
164
- }
165
-
166
- /**
167
- * Convenience wrapper bundling {@link #loadBuffer(String)} &
168
- * {@link #generateSource()} in a single method call. Generates a new
169
- * {@link AudioSource} and assigns the sample buffer created from the given
170
- * WAV file.
171
- *
172
- * @param file
173
- * absolute path to WAV file
174
- * @return configured audio source instance
175
- */
176
- public AudioSource generateSourceFromFile(String file) {
177
- if (!isInited) {
178
- init();
179
- }
180
- AudioSource source = null;
181
- AudioBuffer buffer = loadBuffer(file);
182
- if (buffer != null) {
183
- source = generateSource();
184
- source.setBuffer(buffer);
185
- }
186
- return source;
187
- }
188
-
189
- /**
190
- * Creates the specified number of hardware audio sources required to
191
- * actually play the sample data stored in {@link AudioBuffer}s.
192
- *
193
- * @param numSources
194
- * number of sources required
195
- * @return array
196
- */
197
- public AudioSource[] generateSources(int numSources) {
198
- if (!isInited) {
199
- init();
200
- }
201
- AudioSource[] result = new AudioSource[numSources];
202
- int[] arr = new int[numSources];
203
- al.alGenSources(numSources, arr, 0);
204
- for (int i = 0; i < numSources; i++) {
205
- result[i] = new AudioSource(al, arr[i]);
206
- sources.add(result[i]);
207
- }
208
- return result;
209
- }
210
-
211
- /**
212
- * Returns a direct reference to the OpenAL API.
213
- *
214
- * @return JOAL context
215
- */
216
- public AL getAL() {
217
- if (!isInited) {
218
- init();
219
- }
220
- return al;
221
- }
222
-
223
- /**
224
- * Retrieves a list of available OpenAL compatible audio devices. This
225
- * method can be called before a call to {@link #init()}.
226
- *
227
- * @return array of device names
228
- */
229
- public String[] getDeviceList() {
230
- if (alc == null) {
231
- alc = ALFactory.getALC();
232
- }
233
- return alc.alcGetDeviceSpecifiers();
234
- }
235
-
236
- /**
237
- * Returns the {@link SoundListener} instance for the associated OpenAL
238
- * context.
239
- *
240
- * @return listener object
241
- */
242
- public SoundListener getListener() {
243
- if (!isInited) {
244
- init();
245
- }
246
- if (listener == null) {
247
- listener = new SoundListener(this);
248
- }
249
- return listener;
250
- }
251
-
252
- /**
253
- * Initializes the OpenAL context. Safe to be called multiple times (only
254
- * first time is executed).
255
- *
256
- * @return true, if successful
257
- */
258
- public boolean init() {
259
- return init(null, false);
260
- }
261
-
262
- /**
263
- * Initializes the OpenAL context and if parameter is true, will attempt to
264
- * also setup an EAX environment. The method does nothing if it had been
265
- * called previously and not been {@link #shutdown()} meanwhile.
266
- *
267
- * @param deviceName
268
- * @param attemptEAX
269
- * @return true, if successful (does not care if EAX is supported & has
270
- * succeeded).
271
- */
272
- public boolean init(String deviceName, boolean attemptEAX) {
273
- if (context != null) {
274
- throw new ALException("OpenAL already initialized");
275
- }
276
- if (al == null) {
277
- al = ALFactory.getAL();
278
- }
279
- if (alc == null) {
280
- alc = ALFactory.getALC();
281
- }
282
- ALCdevice d = alc.alcOpenDevice(deviceName);
283
- if (d == null) {
284
- throw new ALException("Error opening default OpenAL device");
285
- }
286
- ALCcontext c = alc.alcCreateContext(d, null);
287
- if (c == null) {
288
- alc.alcCloseDevice(d);
289
- throw new ALException("Error creating OpenAL context");
290
- }
291
- alc.alcMakeContextCurrent(c);
292
- if (alc.alcGetError(d) != 0) {
293
- alc.alcDestroyContext(c);
294
- alc.alcCloseDevice(d);
295
- throw new ALException("Error making OpenAL context current");
296
- }
297
- // Fully initialized; finish setup
298
- device = d;
299
- context = c;
300
- isInited = (al.alGetError() == AL.AL_NO_ERROR);
301
- buffers = new ArrayList<>();
302
- sources = new ArrayList<>();
303
- listener = new SoundListener(this);
304
- isEAX = al.alIsExtensionPresent("EAX2.0");
305
- if (isEAX && attemptEAX) {
306
- initEAX();
307
- }
308
- return isInited;
309
- }
310
-
311
- protected void initEAX() {
312
- eax = EAXFactory.getEAX();
313
- IntBuffer b = IntBuffer.allocate(1);
314
- b.put(EAXConstants.EAX_ENVIRONMENT_HANGAR);
315
- eax.setListenerProperty(
316
- EAXConstants.DSPROPERTY_EAXLISTENER_ENVIRONMENT, b);
317
- }
318
-
319
- /**
320
- * Checks if EAX are supported by the underlying hardware.
321
- *
322
- * @return true, if supported.
323
- */
324
- public boolean isEAXSupported() {
325
- return isEAX;
326
- }
327
-
328
- /**
329
- * Loads a WAV file from the given {@link InputStream}.
330
- *
331
- * @param is
332
- * input stream
333
- * @return buffer wrapper instance
334
- * @throws UnsupportedAudioFileException
335
- * @throws IOException
336
- */
337
- public AudioBuffer loadBuffer(InputStream is)
338
- throws UnsupportedAudioFileException, IOException {
339
- AudioBuffer result;
340
- AudioBuffer[] tmp = generateBuffers(1);
341
- result = tmp[0];
342
- WAVData wd = WAVLoader.loadFromStream(is);
343
- result.configure(wd.data, wd.format, wd.freq);
344
- return result;
345
- }
346
-
347
- /**
348
- * Loads a WAV file (mono/stereo) from the specified file name
349
- *
350
- * @param fileName
351
- * audio file name
352
- * @return buffer wrapper instance
353
- */
354
- public AudioBuffer loadBuffer(String fileName) {
355
- AudioBuffer result = null;
356
- try {
357
- WAVData wd = WAVLoader.loadFromFile(fileName);
358
- AudioBuffer[] tmp = generateBuffers(1);
359
- result = tmp[0];
360
- result.configure(wd.data, wd.format, wd.freq);
361
- } catch (IOException e) {
362
- logger.severe(e.getMessage());
363
- }
364
- return result;
365
- }
366
-
367
- /**
368
- * Destroys all objects, sources, buffers, contexts created by this class.
369
- */
370
- public void shutdown() {
371
- if (isInited) {
372
- logger.info("shutting down JOAL");
373
- deleteAll();
374
- alc.alcMakeContextCurrent(null);
375
- alc.alcDestroyContext(context);
376
- alc.alcCloseDevice(device);
377
-
378
- context = null;
379
- device = null;
380
- alc = null;
381
- al = null;
382
- buffers = null;
383
- sources = null;
384
-
385
- isInited = false;
386
- }
387
- }
388
- }