/* * InterleavedAudioStake.java * Eisenkraut * * Copyright (c) 2004-2016 Hanns Holger Rutz. All rights reserved. * * This software is published under the GNU General Public License v3+ * * * For further information, please contact Hanns Holger Rutz at * contact@sciss.de */ package de.sciss.eisenkraut.io; import de.sciss.io.CacheManager; import de.sciss.io.InterleavedStreamFile; import de.sciss.io.Span; import de.sciss.jcollider.Buffer; import de.sciss.net.OSCBundle; import de.sciss.timebased.Stake; import java.io.IOException; public class InterleavedAudioStake extends AudioStake { private final InterleavedStreamFile f; private final Span fileSpan; private final Span maxFileSpan; private final String fileName; public InterleavedAudioStake(Span span, InterleavedStreamFile f, Span fileSpan) { this(span, f, fileSpan, fileSpan, getFileName(f)); } private InterleavedAudioStake(Span span, InterleavedStreamFile f, Span fileSpan, Span maxFileSpan, String fileName) { super(span); this.f = f; this.fileSpan = fileSpan; this.maxFileSpan = maxFileSpan; this.fileName = fileName; } public void close() throws IOException { f.close(); } public void cleanUp() { try { close(); } catch( IOException e1 ) { /* ignore */ } } private static String getFileName(InterleavedStreamFile f) { return f.getFile().getAbsolutePath(); // return fileNameNormalizer.normalize(s, new StringBuffer()).toString(); } public Stake duplicate() { return new InterleavedAudioStake( span, f, fileSpan, maxFileSpan, fileName ); } public Stake replaceStart(long newStart) { final Span newFileSpan = fileSpan.replaceStart(fileSpan.start + newStart - span.start); final Span newSpan = span.replaceStart(newStart); if ((newSpan.getLength() < 0) || (newFileSpan.getLength() < 0) || !maxFileSpan.contains(newFileSpan)) { throw new IllegalArgumentException(String.valueOf(newStart)); } return new InterleavedAudioStake(newSpan, f, newFileSpan, maxFileSpan, fileName); } public Stake replaceStop(long newStop) { final Span newFileSpan = fileSpan.replaceStop(fileSpan.stop + newStop - span.stop); final Span newSpan = span.replaceStop(newStop); if ((newSpan.getLength() < 0) || (newFileSpan.getLength() < 0) || !maxFileSpan.contains(newFileSpan)) { throw new IllegalArgumentException(String.valueOf(newStop)); } return new InterleavedAudioStake(newSpan, f, newFileSpan, maxFileSpan, fileName); } public Stake shiftVirtual(long delta) { return new InterleavedAudioStake(span.shift(delta), f, fileSpan, maxFileSpan, fileName); } public int readFrames(float[][] data, int dataOffset, Span readSpan) throws IOException { final int len = (int) readSpan.getLength(); if (len == 0) return 0; final long fOffset = fileSpan.start + readSpan.start - span.start; if ((fOffset < fileSpan.start) || ((fOffset + len) > fileSpan.stop)) { throw new IllegalArgumentException(fOffset + " ... " + (fOffset + len) + " not within " + fileSpan.toString()); } synchronized (f) { if (f.getFramePosition() != fOffset) { f.seekFrame(fOffset); } f.readFrames(data, dataOffset, len); } return len; } public int writeFrames(float[][] data, int dataOffset, Span writeSpan) throws IOException { final int len = (int) writeSpan.getLength(); if (len == 0) return 0; final long fOffset = fileSpan.start + writeSpan.start - span.start; if ((fOffset < fileSpan.start) || ((fOffset + len) > fileSpan.stop)) { throw new IllegalArgumentException(fOffset + " ... " + (fOffset + len) + " not within " + fileSpan.toString()); } synchronized (f) { if (f.getFramePosition() != fOffset) { f.seekFrame(fOffset); } f.writeFrames(data, dataOffset, len); } return len; } public long copyFrames(InterleavedStreamFile target, Span readSpan) throws IOException { final long len = readSpan.getLength(); if (len == 0) return 0; final long fOffset = fileSpan.start + readSpan.start - span.start; if ((fOffset < fileSpan.start) || ((fOffset + len) > fileSpan.stop)) { throw new IllegalArgumentException(fOffset + " ... " + (fOffset + len) + " not within " + fileSpan.toString()); } synchronized (f) { if (f.getFramePosition() != fOffset) { f.seekFrame(fOffset); } f.copyFrames(target, len); } return len; } public void addBufferReadMessages(OSCBundle bndl, Span readSpan, Buffer[] bufs, int bufOff) { final int len = (int) readSpan.getLength(); if (len == 0) return; final long fOffset = fileSpan.start + readSpan.start - span.start; if ((fOffset < fileSpan.start) || ((fOffset + len) > fileSpan.stop)) { throw new IllegalArgumentException(fOffset + " ... " + (fOffset + len) + " not within " + fileSpan.toString()); } if ((bufs.length != 1) || (bufs[0].getNumChannels() != f.getChannelNum())) { throw new IllegalArgumentException("Wrong # of buffers / channels (required: 1 / " + f.getChannelNum()); } bndl.addPacket(bufs[0].readMsg(fileName, fOffset, len, bufOff)); } public int getChannelNum() { return f.getChannelNum(); } public void flush() throws IOException { synchronized (f) { f.flush(); } } public void addToCache(CacheManager cm) { cm.addFile(f.getFile()); } public void debugDump() { debugDumpBasics(); System.err.println(" ; f = " + f.getFile().getName() + " (file span " + fileSpan.toString() + " )"); } }