[CLOSED] Buffer crashes

Started by Evan407, January 14, 2017, 18:03:18

Previous topic - Next topic

Evan407

  static long micDevice;
  static ByteBuffer captureBuffer = BufferUtils.createByteBuffer(8192);
  static boolean capturing = false;
  static int numSamples;
  static void captureStart(){
	if(!capturing){
	  capturing = true;
	  micDevice = alcCaptureOpenDevice((ByteBuffer)null,44100,AL_FORMAT_MONO16,8192);
	  alcCaptureStart(micDevice);
	}
  }
  static void captureSamples(){//called repeatedly
	if(capturing){
	  numSamples = alcGetInteger(micDevice,ALC_CAPTURE_SAMPLES);
	  if(0 < numSamples){
		captureBuffer.limit(numSamples);//!! you have to do this 
		alcCaptureSamples(micDevice,captureBuffer);
for(;0 < numSamples--;)System.out.println(captureBuffer.get());////test
		captureBuffer.clear();
	  }
	}
  }
  static void captureEnd(){
	if(capturing){
	  capturing = false;
	  alcCaptureCloseDevice(micDevice);
	}
  }


Quote-1
-87
-1
-98
-1
-98
-1
-109
-1
-118
-1
114Assertion '!e->next' failed at pulsecore/queue.c:104, function pa_queue_pop(). Aborting.

-2
-53
-2
121
-1
47
0
-77
0
-106
0
-72
-1
-72
-2
-29
-3
90
-3
50
-3
56
-3
60
-3
103
-3
-82
-3
-42
-3
-60
-3
40
-3
63
-4Aborted (core dumped)

It seems to just kind of randomly die.

spasi

The problem is a combination of a bug in LWJGL and bugs in your code. First, here's the code that should work with the build you have:

static ShortBuffer captureBuffer = BufferUtils.createShortBuffer(8192); // 8192 * 2 bytes

static void captureStart() {
	if ( !capturing ) {
		capturing = true;
		micDevice = alcCaptureOpenDevice((ByteBuffer)null, 48000, AL_FORMAT_MONO16, 8192); // (1)
		alcCaptureStart(micDevice);
	}
}

static void captureSamples() {
	if ( capturing ) {
		numSamples = Math.min(alcGetInteger(micDevice, ALC_CAPTURE_SAMPLES), 8192); // (2)
		if ( 0 < numSamples ) {
			nalcCaptureSamples(micDevice, memAddress(captureBuffer), numSamples); // (3)
			for ( int i = 0; i < numSamples; i++ )
				System.out.println(captureBuffer.get(i));
		}
	}
}


and the explanation:

1) The "samples" parameter in alcCaptureOpenDevice and alcCaptureSamples is not the buffer size in bytes. It is the number of sample frames to buffer/capture. The number of bytes should be: sample_frames * channels * bytes_per_channel. For format = AL_FORMAT_MONO16 and samples = 8192, the capture buffer should have a capacity of at least 8192 * 1 * 2 = 16384.

2) The number of sample frames actually captured by the OpenAL implementation can be higher than the number specified in alcCaptureOpenDevice. You should not ask for more than ALC_CAPTURE_SAMPLES, but not more than the capture buffer capacity either.

3) Because of 1), LWJGL should not have used auto-sizing of the buffer parameter in alcCaptureSamples. The "samples" parameter should be explicitly specified by the user. You can see a workaround in the code above.

The next LWJGL snapshot (3.1.2 build 5) will fix 3) and also have overloads for Short/Int/Float buffers. You will be able to change the line marked with (3) in the code above to:

alcCaptureSamples(micDevice, captureBuffer, numSamples);

Evan407

Quote from: spasi on January 15, 2017, 20:54:24
The problem is a combination of a bug in LWJGL and bugs in your code. First, here's the code that should work with the build you have:

static ShortBuffer captureBuffer = BufferUtils.createShortBuffer(8192); // 8192 * 2 bytes

static void captureStart() {
	if ( !capturing ) {
		capturing = true;
		micDevice = alcCaptureOpenDevice((ByteBuffer)null, 48000, AL_FORMAT_MONO16, 8192); // (1)
		alcCaptureStart(micDevice);
	}
}

static void captureSamples() {
	if ( capturing ) {
		numSamples = Math.min(alcGetInteger(micDevice, ALC_CAPTURE_SAMPLES), 8192); // (2)
		if ( 0 < numSamples ) {
			nalcCaptureSamples(micDevice, memAddress(captureBuffer), numSamples); // (3)
			for ( int i = 0; i < numSamples; i++ )
				System.out.println(captureBuffer.get(i));
		}
	}
}


and the explanation:

1) The "samples" parameter in alcCaptureOpenDevice and alcCaptureSamples is not the buffer size in bytes. It is the number of sample frames to buffer/capture. The number of bytes should be: sample_frames * channels * bytes_per_channel. For format = AL_FORMAT_MONO16 and samples = 8192, the capture buffer should have a capacity of at least 8192 * 1 * 2 = 16384.

2) The number of sample frames actually captured by the OpenAL implementation can be higher than the number specified in alcCaptureOpenDevice. You should not ask for more than ALC_CAPTURE_SAMPLES, but not more than the capture buffer capacity either.

3) Because of 1), LWJGL should not have used auto-sizing of the buffer parameter in alcCaptureSamples. The "samples" parameter should be explicitly specified by the user. You can see a workaround in the code above.

The next LWJGL snapshot (3.1.2 build 5) will fix 3) and also have overloads for Short/Int/Float buffers. You will be able to change the line marked with (3) in the code above to:

alcCaptureSamples(micDevice, captureBuffer, numSamples);


Thank you for your reply. I did not notice that each sample was 2 bytes and not 1.