/** * @return The timecode of the last frame in the buffer, null if the buffer is empty or is marked to be cleared upon * receiving the next frame. */ @Override public Long getLastInputTimecode() { Long lastTimecode = null; synchronized (synchronizer) { if (!clearOnInsert) { for (AudioFrame frame : audioFrames) { lastTimecode = frame.getTimecode(); } } } return lastTimecode; }
private void processProvidedFrame(AudioFrame frame) { if (frame != null && !frame.isTerminator()) { lastFrameTimecode.set(frame.getTimecode()); if (pendingSeek.get() == NO_SEEK && !frameBuffer.hasClearOnInsert()) { markerTracker.checkPlaybackTimecode(frame.getTimecode()); } } }
private void processProvidedFrame(AudioFrame frame) { if (frame != null && !frame.isTerminator()) { if (!isPerformingSeek()) { markerTracker.checkPlaybackTimecode(frame.getTimecode()); } lastFrameTimecode.set(frame.getTimecode()); } }
@Override public void encode(DataOutput out, TrackFrameDataMessage message) throws IOException { out.writeLong(message.executorId); out.writeInt(message.frames.size()); for (AudioFrame frame : message.frames) { out.writeLong(frame.getTimecode()); out.writeInt(frame.getDataLength()); out.write(frame.getData()); out.writeInt(frame.getVolume()); } out.writeBoolean(message.finished); out.writeLong(message.seekedPosition); }
private AudioFrame filterFrame(AudioFrame frame) { if (frame != null && frame.getVolume() == 0) { return new ImmutableAudioFrame(frame.getTimecode(), format.silenceBytes(), 0, format); } return frame; }
private void store(AudioFrame frame, int index, int frameOffset, int frameLength) { ReferenceMutableAudioFrame targetFrame = frames[index]; targetFrame.setTimecode(frame.getTimecode()); targetFrame.setVolume(frame.getVolume()); targetFrame.setDataReference(frameBuffer, frameOffset, frameLength); frame.getData(frameBuffer, frameOffset); frameCount++; }
@Override public AudioFrame rebuild(AudioFrame frame) { if (frame.getVolume() == newVolume) { return frame; } decoder.decode(frame.getData(), sampleBuffer); int targetVolume = newVolume; if (++frameIndex < 50) { targetVolume = (int) ((newVolume - frame.getVolume()) * (frameIndex / 50.0) + frame.getVolume()); } // Volume 0 is stored in the frame with volume 100 buffer if (targetVolume != 0) { volumeProcessor.applyVolume(frame.getVolume(), targetVolume, sampleBuffer); } byte[] bytes = encoder.encode(sampleBuffer); // One frame per 20ms is consumed. To not spike the CPU usage, reencode only once per 5ms. By the time the buffer is // fully rebuilt, it is probably near to 3/4 its maximum size. try { Thread.sleep(5); } catch (InterruptedException e) { // Keep it interrupted, it will trip on the next interruptible operation Thread.currentThread().interrupt(); } return new ImmutableAudioFrame(frame.getTimecode(), bytes, targetVolume, format); }
private void handleTrackFrameData(TrackFrameDataMessage message) throws Exception { RemoteAudioTrackExecutor executor = playingTracks.get(message.executorId); if (executor != null) { if (message.seekedPosition >= 0) { executor.clearSeek(message.seekedPosition); } AudioFrameBuffer buffer = executor.getAudioBuffer(); executor.receivedData(); AudioDataFormat format = executor.getConfiguration().getOutputFormat(); for (AudioFrame frame : message.frames) { buffer.consume(new ImmutableAudioFrame(frame.getTimecode(), frame.getData(), frame.getVolume(), format)); } if (message.finished) { buffer.setTerminateOnEmpty(); trackEnded(executor, false); } } }
private boolean passToMutable(AudioFrame frame, MutableAudioFrame targetFrame) { if (targetFrame != null) { if (frame.isTerminator()) { targetFrame.setTerminator(true); } else { targetFrame.setTimecode(frame.getTimecode()); targetFrame.setVolume(frame.getVolume()); targetFrame.store(frame.getData(), 0, frame.getDataLength()); targetFrame.setTerminator(false); } return true; } return false; }