toxiclibs 0.9.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
- }