different behavior on Windows/Mac

Started by NateS, November 18, 2008, 06:58:46

Previous topic - Next topic

NateS

In the Java program below I get different behavior on Windows and Mac. This happens with lwjgl2.0b1.

This line...
String[] deviceIDs = ALC10.alcGetString(AL.getDevice(), ALC11.ALC_CAPTURE_DEVICE_SPECIFIER).split("\0");

...results in:
Windows: [Generic Hardware]
Mac: [Logitech USB Microphone]

It appears on Windows it isn't returning me microphone devices, so when I go to open this device ID, it fails to open. It is correct on the Mac (my Mac has only the one microphone).

If I change the line to...
String[] deviceIDs = ALC10.alcGetString(null, ALC11.ALC_CAPTURE_DEVICE_SPECIFIER).split("\0");

...then I get:
Windows: [Logitech USB Microphone, NVIDIA(R) nForce(TM) Audio]
Mac: OpenALException: ALC Invalid Device

This appears to be the correct devices on Windows, but goes boom on the Mac.

Here is a working example:
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.Arrays;

import org.lwjgl.BufferUtils;
import org.lwjgl.openal.AL;
import org.lwjgl.openal.AL10;
import org.lwjgl.openal.ALC10;
import org.lwjgl.openal.ALC11;
import org.lwjgl.openal.ALCdevice;
import org.lwjgl.openal.OpenALException;

public class OpenALMicTest {
	public static void main (String[] args) throws Exception {
		AL.create();

		int major, minor;
		IntBuffer buffer = BufferUtils.createIntBuffer(2);
		ALC10.alcGetInteger(AL.getDevice(), ALC10.ALC_MAJOR_VERSION, buffer);
		major = buffer.get(0);
		buffer.rewind();
		ALC10.alcGetInteger(AL.getDevice(), ALC10.ALC_MINOR_VERSION, buffer);
		minor = buffer.get(0);
		System.out.println("OpenAL Version: " + major + "." + minor);

		if (!ALC10.alcIsExtensionPresent(AL.getDevice(), "ALC_EXT_CAPTURE"))
			throw new OpenALException("Unable to open microphones: ALC_EXT_CAPTURE extension not available.");

		String defaultDeviceID = ALC10.alcGetString(AL.getDevice(), ALC11.ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
		System.out.println("Default microphones: " + defaultDeviceID);

		String[] deviceIDs = ALC10.alcGetString(AL.getDevice(), ALC11.ALC_CAPTURE_DEVICE_SPECIFIER).split("\0");
		System.out.println("All microphones: " + Arrays.asList(deviceIDs));

		if (deviceIDs.length == 0) throw new RuntimeException("No microphones found.");

		String openDeviceID = deviceIDs[0];
		System.out.println("Opening microphone: " + openDeviceID);
		ALCdevice device = ALC11.alcCaptureOpenDevice(openDeviceID, 22050, AL10.AL_FORMAT_MONO16, 1024);
		if (device == null) throw new RuntimeException("Unable to open microphone with format: mono 16bit 22050hz");
		ALC11.alcCaptureStart(device);
		System.out.println("Capture started.");

		IntBuffer sampleCountBuffer = BufferUtils.createIntBuffer(1);
		ByteBuffer byteBuffer = BufferUtils.createByteBuffer(1024 * 2);
		while (true) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException ignored) {
			}
			ALC10.alcGetInteger(device, ALC11.ALC_CAPTURE_SAMPLES, sampleCountBuffer);
			if (sampleCountBuffer.get(0) < 1024) continue;
			byteBuffer.rewind();
			ALC11.alcCaptureSamples(device, byteBuffer, 1024);
			float sample = byteBuffer.getShort() / (float)Short.MAX_VALUE;
			sample = (int)(sample * 100) / 100f;
			System.out.println(Math.abs(sample));
		}
	}
}

Matzon

as per: http://connect.creativelabs.com/openal/Documentation/OpenAL%201.1%20Specification.htm
QuoteAn alcGetString query of ALC_DEVICE_SPECIFIER or ALC_CAPTURE_DEVICE_SPECIFIER with a NULL device passed in will return a list of available devices.  Each device name will be separated by a single NULL character and the list will be terminated with two NULL characters.

A request for ALC_DEFAULT_DEVICE_SPECIFIER on a system without an audio output device will result in NULL being returned.

A request for ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER on a system without an audio capture device will result in NULL being returned.

NateS

Thanks, it is good to know what the difference should be when passing null versus a device. However, it doesn't explain the behavior I'm seeing as described above.

Matzon

It doesn't explain why apple is NOT following spec, no - but its really out of our hands...

NateS

I see. Well this one is easy enough to work around.