@Override public AudioFrame provide() { synchronized (synchronizer) { if (provide(getBridgeFrame())) { return unwrapBridgeFrame(); } return null; } }
@Override public boolean provide(MutableAudioFrame targetFrame) { synchronized (synchronizer) { if (frameCount == 0) { if (terminateOnEmpty) { popPendingTerminator(targetFrame); synchronizer.notifyAll(); return true; } return false; } else { popFrame(targetFrame); synchronizer.notifyAll(); return true; } } }
@Override public void consume(AudioFrame frame) throws InterruptedException { // If an interrupt sent along with setting the stopping status was silently consumed elsewhere, this check should // still trigger. Guarantees that stopped tracks cannot get stuck in this method. Possible performance improvement: // offer with timeout, check stopping if timed out, then put? if (stopping != null && stopping.get()) { throw new InterruptedException(); } synchronized (synchronizer) { if (!locked) { receivedFrames = true; if (clearOnInsert) { clear(); clearOnInsert = false; } while (!attemptStore(frame)) { synchronizer.wait(); } synchronizer.notifyAll(); } } }
store(frame, 0, 0, frameLength); } else { int lastFrame = wrappedFrameIndex(firstFrame + frameCount - 1); int nextFrame = wrappedFrameIndex(lastFrame + 1); store(frame, nextFrame, bufferTail, frameLength); } else if (bufferHead >= frameLength) { store(frame, nextFrame, 0, frameLength); } else { return false; store(frame, nextFrame, bufferTail, frameLength); } else { return false;
/** * @param bufferDuration The length of the internal buffer in milliseconds * @param format The format of the frames held in this buffer * @param stopping Atomic boolean which has true value when the track is in a state of pending stop. */ public NonAllocatingAudioFrameBuffer(int bufferDuration, AudioDataFormat format, AtomicBoolean stopping) { super(format); int maximumFrameCount = bufferDuration / (int) format.frameDuration() + 1; frames = createFrames(maximumFrameCount, format); silentFrame = createSilentFrame(format); this.frameBuffer = new byte[format.expectedChunkSize() * maximumFrameCount]; worstCaseFrameCount = frameBuffer.length / format.maximumChunkSize(); this.stopping = stopping; }
@Override public AudioFrame provide(long timeout, TimeUnit unit) throws TimeoutException, InterruptedException { synchronized (synchronizer) { if (provide(getBridgeFrame(), timeout, unit)) { return unwrapBridgeFrame(); } return null; } }
@Override public boolean provide(MutableAudioFrame targetFrame, long timeout, TimeUnit unit) throws TimeoutException, InterruptedException { long currentTime = System.nanoTime(); long endTime = currentTime + unit.toMillis(timeout); synchronized (synchronizer) { while (frameCount == 0) { if (terminateOnEmpty) { popPendingTerminator(targetFrame); synchronizer.notifyAll(); return true; } synchronizer.wait(endTime - currentTime); currentTime = System.nanoTime(); if (currentTime >= endTime) { throw new TimeoutException(); } } popFrame(targetFrame); synchronizer.notifyAll(); return true; } }