LWJGL Forum

Programming => Bug Reports / RFE => Topic started by: Evan407 on January 14, 2017, 18:03:18

Title: [CLOSED] Buffer crashes
Post by: Evan407 on January 14, 2017, 18:03:18
  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.
Title: Re: [BUG] Buffer crashes
Post by: 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);
Title: Re: [BUG] Buffer crashes
Post by: Evan407 on January 17, 2017, 22:26:24
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.