Mac OS X crashes on AL.destroy

Started by NateS, November 18, 2008, 07:55:36

Previous topic - Next topic

NateS

Running the program below causes Max OS X 10.5.5 to explode during the AL.destroy() call, presumably because the microphone is still open. Would it be possible to handle the cleanup in AL.destroy?

import java.nio.ByteBuffer;
import java.nio.IntBuffer;

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 OpenALMicTest2 {
	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("Opening microphone: " + defaultDeviceID);
		ALCdevice device = ALC11.alcCaptureOpenDevice(defaultDeviceID, 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);
		int i = 0;
		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));
			if (++i > 20) break;
		}
		AL.destroy(); // Boom.
	}
}


Here is the thread that exploded:
0   ???                           	0x1c8fa494 0 + 479175828
1   com.apple.audio.CoreAudio     	0x9022dfdf HP_IOProc::Call(AudioTimeStamp const&, AudioTimeStamp const&, AudioBufferList const*, AudioTimeStamp const&, AudioBufferList*) + 319
2   com.apple.audio.CoreAudio     	0x9022dcd0 IOA_Device::CallIOProcs(AudioTimeStamp const&, AudioTimeStamp const&, AudioTimeStamp const&) + 274
3   com.apple.audio.CoreAudio     	0x9022dbac HP_IOThread::PerformIO(AudioTimeStamp const&) + 1246
4   com.apple.audio.CoreAudio     	0x9022bf87 HP_IOThread::WorkLoop() + 1239
5   com.apple.audio.CoreAudio     	0x9022baab HP_IOThread::ThreadEntry(HP_IOThread*) + 17
6   com.apple.audio.CoreAudio     	0x9021c300 CAPThread::Entry(CAPThread*) + 96
7   libSystem.B.dylib             	0x9264f6f5 _pthread_start + 321
8   libSystem.B.dylib             	0x9264f5b2 thread_start + 34


Attached is the full dump.

Matzon

to be honest I don't know if we can detect and do something about an open capture device ?
That said, our clean up code looks fairly sane:
ALC10.alcMakeContextCurrent(null);
ALC10.alcDestroyContext(context);
ALC10.alcCloseDevice(device);


We would have to know if the device is a capture device and call alcCaptureCloseDevice on it - but I don't think its possible.
I do feel that it is an apple bug tho...

NateS

Hmm. Would it hurt to call both alcCloseDevice and alcCaptureCloseDevice? Otherwise I can keep track in my game and close them all before calling destroy.