1 /*
2  * Copyright (c) 2002-2008 LWJGL Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of 'LWJGL' nor the names of
17  *   its contributors may be used to endorse or promote products derived
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 package org.lwjgl.openal;
33 
34 import java.nio.ByteBuffer;
35 import java.nio.IntBuffer;
36 
37 import org.lwjgl.BufferUtils;
38 import org.lwjgl.LWJGLException;
39 import org.lwjgl.LWJGLUtil;
40 import org.lwjgl.MemoryUtil;
41 
42 /**
43  * <p>
44  * The ALC11 class implements features in OpenAL 1.1, specifically
45  * ALC methods and properties.
46  * </p>
47  *
48  * @author Brian Matzon <brian@matzon.dk>
49  * @see ALC10
50  * @version $Revision: 2286 $
51  * $Id: ALC.java 2286 2006-03-23 19:32:21 +0000 (to, 23 mar 2006) matzon $
52  */
53 public final class ALC11 {
54 
55 	public static final int ALC_DEFAULT_ALL_DEVICES_SPECIFIER			= 0x1012;
56 	public static final int ALC_ALL_DEVICES_SPECIFIER					= 0x1013;
57 
58 	public static final int ALC_CAPTURE_DEVICE_SPECIFIER				= 0x310;
59 	public static final int ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER		= 0x311;
60 	public static final int ALC_CAPTURE_SAMPLES							= 0x312;
61 
62 	public static final int ALC_MONO_SOURCES							= 0x1010;
63 	public static final int ALC_STEREO_SOURCES							= 0x1011;
64 
65 	/**
66 	 * The alcCaptureOpenDevice function allows the application to connect to a capture
67 	 * device. To obtain a list of all available capture devices, use getCaptureDevices a list of all
68 	 * capture devices will be returned. Retrieving ALC_CAPTURE_DEVICE_SPECIFIER with a valid capture device specified will result
69 	 * in the name of that device being returned as a single string.
70 	 *
71 	 * If the function returns null, then no sound driver/device has been found, or the
72 	 * requested format could not be fulfilled.
73 	 * The "deviceName" argument is a string that requests a certain device or
74 	 * device configuration. If null is specified, the implementation will provide an
75 	 * implementation specific default. The "frequency" and "format" arguments specify the format that
76 	 * audio data will be presented to the application, and match the values that can be passed to
77 	 * alBufferData. The implementation is expected to convert and resample to this format on
78 	 * behalf of the application. The "buffersize" argument specifies the number of sample frames
79 	 * to buffer in the AL, for example, requesting a format of AL_FORMAT_STEREO16 and
80 	 * a buffer size of 1024 would require the AL to store up to 1024 * 4 bytes of audio data.
81 	 * Note that the implementation may use a larger buffer than requested if it needs to, but the
82 	 * implementation will set up a buffer of at least the requested size.
83 	 * Specifying a compressed or extension-supplied format may result in failure, even if the
84 	 * extension is supplied for rendering.
85 	 *
86 	 * <i>LWJGL SPECIFIC: the actual created device is managed internally in lwjgl</i>
87 	 *
88 	 * @param devicename Name of device to open for capture
89 	 * @param frequency Frequency of samples to capture
90 	 * @param format Format of samples to capture
91 	 * @param buffersize Size of buffer to capture to
92 	 * @return ALCdevice if it was possible to open a device
93 	 */
alcCaptureOpenDevice(String devicename, int frequency, int format, int buffersize)94 	public static ALCdevice alcCaptureOpenDevice(String devicename, int frequency, int format, int buffersize) {
95 		ByteBuffer buffer = MemoryUtil.encodeASCII(devicename);
96 		long device_address = nalcCaptureOpenDevice(MemoryUtil.getAddressSafe(buffer), frequency, format, buffersize);
97 		if(device_address != 0) {
98 			ALCdevice device = new ALCdevice(device_address);
99 			synchronized (ALC10.devices) {
100 				ALC10.devices.put(device_address, device);
101 			}
102 			return device;
103 		}
104 		return null;
105 	}
nalcCaptureOpenDevice(long devicename, int frequency, int format, int buffersize)106 	private static native long nalcCaptureOpenDevice(long devicename, int frequency, int format, int buffersize);
107 
108 	/**
109 	 * The alcCaptureCloseDevice function allows the application to disconnect from a capture
110 	 * device.
111 	 *
112 	 * The return code will be true or false, indicating success or failure. If
113 	 * the device is null or invalid, an ALC_INVALID_DEVICE error will be generated.
114 	 * Once closed, a capture device is invalid.
115 	 * @return true if device was successfully closed
116 	 */
alcCaptureCloseDevice(ALCdevice device)117 	public static boolean alcCaptureCloseDevice(ALCdevice device) {
118 		boolean result = nalcCaptureCloseDevice(ALC10.getDevice(device));
119 		synchronized (ALC10.devices) {
120 			device.setInvalid();
121 			ALC10.devices.remove(new Long(device.device));
122 		}
123 		return result;
124 	}
nalcCaptureCloseDevice(long device)125 	static native boolean nalcCaptureCloseDevice(long device);
126 
127 	/**
128 	 * Once a capture device has been opened via alcCaptureOpenDevice, it is made to start
129 	 * recording audio via the alcCaptureStart entry point:
130 	 *
131 	 * Once started, the device will record audio to an internal ring buffer, the size of which was
132 	 * specified when opening the device.
133 	 * The application may query the capture device to discover how much data is currently
134 	 * available via the alcGetInteger with the ALC_CAPTURE_SAMPLES token. This will
135 	 * report the number of sample frames currently available.
136 	 */
alcCaptureStart(ALCdevice device)137 	public static  void alcCaptureStart(ALCdevice device) {
138 		nalcCaptureStart(ALC10.getDevice(device));
139 	}
nalcCaptureStart(long device)140 	static native void nalcCaptureStart(long device);
141 
142 	/**
143 	 * If the application doesn't need to capture more audio for an amount of time, they can halt
144 	 * the device without closing it via the alcCaptureStop entry point.
145 	 * The implementation is encouraged to optimize for this case. The amount of audio
146 	 * samples available after restarting a stopped capture device is reset to zero. The
147 	 * application does not need to stop the capture device to read from it.
148 	 */
alcCaptureStop(ALCdevice device)149 	public static  void alcCaptureStop(ALCdevice device) {
150 		nalcCaptureStop(ALC10.getDevice(device));
151 	}
nalcCaptureStop(long device)152 	static native void nalcCaptureStop(long device);
153 
154 	/**
155 	 * When the application feels there are enough samples available to process, it can obtain
156 	 * them from the AL via the alcCaptureSamples entry point.
157 	 *
158 	 * The "buffer" argument specifies an application-allocated buffer that can contain at least
159 	 * "samples" sample frames. The implementation may defer conversion and resampling until
160 	 * this point. Requesting more sample frames than are currently available is an error.
161 	 *
162 	 * @param buffer Buffer to store samples in
163 	 * @param samples Number of samples to request
164 	 */
alcCaptureSamples(ALCdevice device, ByteBuffer buffer, int samples )165 	public static  void alcCaptureSamples(ALCdevice device, ByteBuffer buffer, int samples ) {
166 		nalcCaptureSamples(ALC10.getDevice(device), MemoryUtil.getAddress(buffer), samples);
167 	}
nalcCaptureSamples(long device, long buffer, int samples )168 	static native void nalcCaptureSamples(long device, long buffer, int samples );
169 
initNativeStubs()170 	static native void initNativeStubs() throws LWJGLException;
171 
172 	/**
173 	 * Initializes ALC11, including any extensions
174 	 * @return true if initialization was successfull
175 	 */
initialize()176 	static boolean initialize() {
177 		try {
178 			IntBuffer ib = BufferUtils.createIntBuffer(2);
179 			ALC10.alcGetInteger(AL.getDevice(), ALC10.ALC_MAJOR_VERSION, ib);
180 			ib.position(1);
181 			ALC10.alcGetInteger(AL.getDevice(), ALC10.ALC_MINOR_VERSION, ib);
182 
183 			int major = ib.get(0);
184 			int minor = ib.get(1);
185 
186 			// checking for version 1.x+
187 			if(major >= 1) {
188 
189 				// checking for version 1.1+
190 				if(major > 1 || minor >= 1) {
191 					ALC11.initNativeStubs();
192                                         AL11.initNativeStubs();
193 				}
194 			}
195 		} catch (LWJGLException le) {
196 			LWJGLUtil.log("failed to initialize ALC11: " + le);
197 			return false;
198 		}
199 		return true;
200 	}
201 }
202