public void dispose() { if (audio.noDevice) return; if (bufferID == -1) return; audio.freeBuffer(bufferID); alDeleteBuffers(bufferID); bufferID = -1; audio.forget(this); }
public void dispose() { if (buffers == null) return; if (sourceID != -1) { audio.freeSource(sourceID); sourceID = -1; } audio.getAL().alDeleteBuffers(buffers.limit(), buffers); buffers = null; }
@Override public long loop(float volume) { if (audio.noDevice) return 0; int sourceID = audio.obtainSource(false); if (sourceID == -1) return -1; long soundId = audio.getSoundId(sourceID); alSourcei(sourceID, AL_BUFFER, bufferID); alSourcei(sourceID, AL_LOOPING, AL_TRUE); alSourcef(sourceID, AL_GAIN, volume); alSourcePlay(sourceID); return soundId; }
public void stop() { if (sourceID == -1) return; audio.freeSource(sourceID); sourceID = -1; renderedSeconds = 0; isPlaying = false; }
public long play(float volume) { if (audio.noDevice) return 0; int sourceID = audio.obtainSource(false); if (sourceID == -1) { // Attempt to recover by stopping the least recently played sound audio.retain(this, true); sourceID = audio.obtainSource(false); } else audio.retain(this, false); // In case it still didn't work if (sourceID == -1) return -1; long soundId = audio.getSoundId(sourceID); alSourcei(sourceID, AL_BUFFER, bufferID); alSourcei(sourceID, AL_LOOPING, AL_FALSE); alSourcef(sourceID, AL_GAIN, volume); alSourcePlay(sourceID); return soundId; }
public void writeSamples(byte[] data, int offset, int length) { if (length < 0) throw new IllegalArgumentException("length cannot be < 0."); if (sourceID == -1) { sourceID = audio.obtainSource(true); if (sourceID == -1) return; if (buffers == null) { buffers = Buffers.newDirectIntBuffer(bufferCount); audio.getAL().alGenBuffers(buffers.limit(), buffers); if (audio.getAL().alGetError() != ALConstants.AL_NO_ERROR) throw new GdxRuntimeException("Unabe to allocate audio buffers."); } audio.getAL().alSourcei(sourceID, ALConstants.AL_LOOPING, ALConstants.AL_FALSE); audio.getAL().alSourcef(sourceID, ALConstants.AL_GAIN, volume); // Fill initial buffers. int queuedBuffers = 0; for (int i = 0; i < bufferCount; i++) { int bufferID = buffers.get(i); int written = Math.min(bufferSize, length); tempBuffer.clear(); tempBuffer.put(data, offset, written).flip(); audio .getAL() .alBufferData(bufferID, format, tempBuffer, tempBuffer.remaining(), sampleRate); ib.put(0, bufferID).rewind(); audio.getAL().alSourceQueueBuffers(sourceID, ib.limit(), ib); length -= written; offset += written; queuedBuffers++; } // Queue rest of buffers, empty. tempBuffer.clear().flip(); for (int i = queuedBuffers; i < bufferCount; i++) { int bufferID = buffers.get(i); audio .getAL() .alBufferData(bufferID, format, tempBuffer, tempBuffer.remaining(), sampleRate); audio.getAL().alSourceQueueBuffers(sourceID, ib.limit(), ib); } audio.getAL().alSourcePlay(sourceID); isPlaying = true; } while (length > 0) { int written = fillBuffer(data, offset, length); length -= written; offset += written; } }
/** Blocks until some of the data could be buffered. */ private int fillBuffer(byte[] data, int offset, int length) { int written = Math.min(bufferSize, length); outer: while (true) { audio.getAL().alGetSourcei(sourceID, ALConstants.AL_BUFFERS_PROCESSED, ib); int buffers = ib.get(0); while (buffers-- > 0) { // FIXME ib.put(0, buffers).rewind(); audio.getAL().alSourceUnqueueBuffers(sourceID, ib.limit(), ib); int bufferID = ib.get(0); if (bufferID == ALConstants.AL_INVALID_VALUE) break; renderedSeconds += secondsPerBuffer; tempBuffer.clear(); tempBuffer.put(data, offset, written).flip(); audio .getAL() .alBufferData(bufferID, format, tempBuffer, tempBuffer.remaining(), sampleRate); ib.put(0, bufferID).rewind(); audio.getAL().alSourceQueueBuffers(sourceID, ib.limit(), ib); break outer; } // Wait for buffer to be free. try { Thread.sleep((long) (1000 * secondsPerBuffer / bufferCount)); } catch (InterruptedException ignored) { } } // A buffer underflow will cause the source to stop. if (!isPlaying || !isCurrentSourcePlaying()) { audio.getAL().alSourcePlay(sourceID); isPlaying = true; } return written; }
public void setVolume(float volume) { this.volume = volume; if (sourceID != -1) audio.getAL().alSourcef(sourceID, ALConstants.AL_GAIN, volume); }
@Override public void resume(long soundId) { if (audio.noDevice) return; audio.resumeSound(soundId); }
public float getPosition() { if (sourceID == -1) return 0; audio.getAL().alGetSourcef(sourceID, ALConstants.AL_SEC_OFFSET, fb); return renderedSeconds + fb.get(0); }
public void stop() { if (audio.noDevice) return; audio.stopSourcesWithBuffer(bufferID); }
@Override public void setPan(long soundId, float pan, float volume) { if (audio.noDevice) return; audio.setSoundPan(soundId, pan, volume); }
@Override public void stop(long soundId) { if (audio.noDevice) return; audio.stopSound(soundId); }
@Override public void setVolume(long soundId, float volume) { if (audio.noDevice) return; audio.setSoundGain(soundId, volume); }
@Override public void setLooping(long soundId, boolean looping) { if (audio.noDevice) return; audio.setSoundLooping(soundId, looping); }
@Override public void setPitch(long soundId, float pitch) { if (audio.noDevice) return; audio.setSoundPitch(soundId, pitch); }
private boolean isCurrentSourcePlaying() { audio.getAL().alGetSourcei(sourceID, ALConstants.AL_SOURCE_STATE, ib); return (ib.get(0) == ALConstants.AL_PLAYING); }
@Override public void resume() { if (audio.noDevice) return; audio.resumeSourcesWithBuffer(bufferID); }
@Override public void pause(long soundId) { if (audio.noDevice) return; audio.pauseSound(soundId); }
@Override public void pause() { if (audio.noDevice) return; audio.pauseSourcesWithBuffer(bufferID); }