/* * Reverse.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.render; import java.io.IOException; import java.util.ArrayList; import java.util.List; import de.sciss.io.Span; import de.sciss.timebased.MarkerStake; import de.sciss.timebased.Stake; public class Reverse extends AbstractRenderPlugIn { private Span prTotalSpan; private RenderConsumer prConsumer; public int getMarkerPolicy() { return POLICY_MODIFY; } public int getUnselectedAudioPolicy() { return POLICY_MODIFY; } public boolean producerBegin( RenderSource source ) throws IOException { // random read access not necessary any more since the consumer // automatically handles random write access! // source.context.setOption( RenderContext.KEY_PREFBLOCKSIZE, new Integer( BLOCKSIZE )); // source.context.setOption( RenderContext.KEY_RANDOMACCESS, this ); prTotalSpan = source.context.getTimeSpan(); // request last block // prNextSpan = new Span( Math.max( prTotalSpan.start, prTotalSpan.stop - BLOCKSIZE ), prTotalSpan.stop ); prConsumer = source.context.getConsumer(); // flip markers at once if (source.validMarkers) { final int numMarkers = source.markers.getNumStakes(); final List<Stake> collNew = new ArrayList<Stake>(numMarkers); MarkerStake m; for (int i = 0; i < numMarkers; i++) { m = (MarkerStake) source.markers.get(i, true); collNew.add(m.replaceStart(prTotalSpan.stop - m.pos + prTotalSpan.start)); } source.markers.clear(this); source.markers.addAll(this, collNew); } return prConsumer.consumerBegin( source ); } public boolean producerRender(RenderSource source) throws IOException { float temp; float[] chBuf; // reverse each block for (int ch = 0; ch < source.numAudioChannels; ch++) { if (!source.audioTrackMap[ch]) continue; chBuf = source.audioBlockBuf[ch]; for (int i = source.audioBlockBufOff, j = i + source.audioBlockBufLen - 1; i < j; i++, j--) { temp = chBuf[i]; chBuf[i] = chBuf[j]; chBuf[j] = temp; } } // pseudo code: // blockStart --> totalStop - (blockStart - totalStart) - blockLen // blockStart --> totalStop + totalStart - blockStop // shift = totalStop + totalStart - blockStop - blockStart source.blockSpan = source.blockSpan.shift(prTotalSpan.stop + prTotalSpan.start - source.blockSpan.stop - source.blockSpan.start); return prConsumer.consumerRender(source); } public String getName() { return getResourceString( "plugInReverse" ); } // ---------- RandomAccessRequester interface ---------- // public Span getNextSpan() // { // return prNextSpan; // } }