private void ResetStream(bool hardReset) { if (position > byteMappings.Omega.To) { throw new Exception("position beyond length"); } length = byteMappings.Omega.To; byteMappings.SetWarpedPosition(position); ByteTimeWarp mL = byteMappings.Lower; ByteTimeWarp mH = byteMappings.Upper; if (cropStream == null || cropStream.Begin != mL.From || cropStream.End != mH.From || resamplingStream.Length != byteMappings.Omega.To) { // mapping has changed, stream subsection must be renewed if (hardReset) { // Each internal stream for each warped/resampled section works on the same underlying source stream, so // we add the SourceClosePreventionStream to avoid the source being closed when an internally used stream // of a section is disposed or closed (as in the call below). The source stream continues to get closed // when this stream is closed. cropStream = new CropStream(new SourceClosePreventionStream(sourceStream), mL.From, mH.From); // Get rid of stream for previous section if (resamplingStream != null) { resamplingStream.Close(); } // Create stream for current section resamplingStream = new ResamplingStream(cropStream, ResamplingQuality.VariableRate, ByteTimeWarp.CalculateSampleRateRatio(mL, mH)); resamplingStream.Position = position - mL.To; } else { // Reset the streams to the new conditions without creating new instances as the hard reset does // NOTE always hard resetting works too, but this mode has been added to keep the sample resampler throughout playback // Reset crop stream to source bounds, else the successive setting of begin and end can fail if // the new begin position is after the old end position and the validation in the crop stream fails cropStream.Begin = 0; cropStream.End = sourceStream.Length; // Reset the crop stream to the new bounds cropStream.Begin = mL.From; cropStream.End = mH.From; cropStream.Position = 0; // Reset the resampling stream resamplingStream.SampleRateRatio = ByteTimeWarp.CalculateSampleRateRatio(mL, mH); resamplingStream.Position = position - mL.To; } } }
private void ResetStream(bool hardReset) { if (position > byteMappings.Omega.To) { throw new Exception("position beyond length"); } length = byteMappings.Omega.To; byteMappings.SetWarpedPosition(position); ByteTimeWarp mL = byteMappings.Lower; ByteTimeWarp mH = byteMappings.Upper; if (cropStream == null || cropStream.Begin != mL.From || cropStream.End != mH.From || resamplingStream.Length != byteMappings.Omega.To) { // mapping has changed, stream subsection must be renewed if (hardReset) { cropStream = new CropStream(sourceStream, mL.From, mH.From); if (resamplingStream != null) { resamplingStream.Close(); } resamplingStream = new ResamplingStream(cropStream, ResamplingQuality.VariableRate, ByteTimeWarp.CalculateSampleRateRatio(mL, mH)); resamplingStream.Position = position - mL.To; } else { // Reset the streams to the new conditions without creating new instances as the hard reset does // NOTE always hard resetting works too, but this mode has been added to keep the sample resampler throughout playback // Reset crop stream to source bounds, else the successive setting of begin and end can fail if // the new begin position is after the old end position and the validation in the crop stream fails cropStream.Begin = 0; cropStream.End = sourceStream.Length; // Reset the crop stream to the new bounds cropStream.Begin = mL.From; cropStream.End = mH.From; cropStream.Position = 0; // Reset the resampling stream resamplingStream.SampleRateRatio = ByteTimeWarp.CalculateSampleRateRatio(mL, mH); resamplingStream.Position = position - mL.To; } } }
public void ValidateMappings() { // validate that no mapping is overlapping with another one for (int x = 0; x < Count - 1; x++) { for (int y = x + 1; y < Count; y++) { if (this[x].To > this[y].To) { throw new Exception(this[x] + " is overlapping " + this[y]); } else if (!ResamplingStream.CheckSampleRateRatio(TimeWarp.CalculateSampleRateRatio(this[x], this[y]))) { throw new Exception("invalid sample ratio: " + TimeWarp.CalculateSampleRateRatio(this[x], this[y])); } } } }