From 3297f6d545bd0d7d7f723d9d948d2474a305c42e Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 17 Dec 2016 22:44:33 -0500 Subject: [PATCH] Made an attempt to implement `seek_to` on `PCMSegmentEventSource`, taking account of off-by-half counting. --- Storage/Disk/PCMSegment.cpp | 37 +++++++++++++++++++++++++ Storage/Disk/PCMSegment.hpp | 3 +++ Storage/Storage.hpp | 54 ++++++++++++++++++++++++++++++------- 3 files changed, 84 insertions(+), 10 deletions(-) diff --git a/Storage/Disk/PCMSegment.cpp b/Storage/Disk/PCMSegment.cpp index befbda624..83f4dc203 100644 --- a/Storage/Disk/PCMSegment.cpp +++ b/Storage/Disk/PCMSegment.cpp @@ -47,3 +47,40 @@ Storage::Disk::Track::Event PCMSegmentEventSource::get_next_event() next_event_.type = Track::Event::IndexHole; return next_event_; } + +Storage::Time PCMSegmentEventSource::get_length() +{ + return segment_.length_of_a_bit * segment_.number_of_bits; +} + +Storage::Time PCMSegmentEventSource::seek_to(const Time &time_from_start) +{ + // test for requested time being beyond the end + Time length = get_length(); + if(time_from_start >= length) + { + next_event_.type = Track::Event::IndexHole; + bit_pointer_ = segment_.number_of_bits; + return length; + } + + // if not beyond the end then make an initial assumption that the next thing encountered will be a flux transition + next_event_.type = Track::Event::FluxTransition; + + // test for requested time being before the first bit + Time half_bit_length = segment_.length_of_a_bit; + half_bit_length.length >>= 1; + if(time_from_start < half_bit_length) + { + bit_pointer_ = 0; + Storage::Time zero; + return zero; + } + + // adjust for time to get to bit zero and determine number of bits in + Time relative_time = time_from_start - half_bit_length; + bit_pointer_ = (relative_time / segment_.length_of_a_bit).get_unsigned_int(); + + // map up to the correct amount of time + return half_bit_length + segment_.length_of_a_bit * (unsigned int)bit_pointer_; +} diff --git a/Storage/Disk/PCMSegment.hpp b/Storage/Disk/PCMSegment.hpp index 874a2f0ee..b1ce99994 100644 --- a/Storage/Disk/PCMSegment.hpp +++ b/Storage/Disk/PCMSegment.hpp @@ -36,6 +36,9 @@ class PCMSegmentEventSource { Track::Event get_next_event(); void reset(); + Time seek_to(const Time &time_from_start); + Time get_length(); + private: PCMSegment segment_; size_t bit_pointer_; diff --git a/Storage/Storage.hpp b/Storage/Storage.hpp index c5aa45f8d..4e1ef640f 100644 --- a/Storage/Storage.hpp +++ b/Storage/Storage.hpp @@ -36,17 +36,37 @@ struct Time { /*! @returns the floating point conversion of this @c Time. This will often be less precise. */ - inline float get_float() + inline float get_float() const { return (float)length / (float)clock_rate; } - inline bool operator < (Time other) + inline unsigned int get_unsigned_int() const + { + return length / clock_rate; + } + + inline bool operator < (const Time &other) const { return other.clock_rate * length < clock_rate * other.length; } - inline Time operator + (Time other) + inline bool operator <= (const Time &other) const + { + return other.clock_rate * length <= clock_rate * other.length; + } + + inline bool operator > (const Time &other) const + { + return other.clock_rate * length > clock_rate * other.length; + } + + inline bool operator >= (const Time &other) const + { + return other.clock_rate * length >= clock_rate * other.length; + } + + inline Time operator + (const Time &other) const { Time result; result.clock_rate = NumberTheory::least_common_multiple(clock_rate, other.clock_rate); @@ -54,7 +74,7 @@ struct Time { return result; } - inline Time &operator += (Time other) + inline Time &operator += (const Time &other) { unsigned int combined_clock_rate = NumberTheory::least_common_multiple(clock_rate, other.clock_rate); length = length * (combined_clock_rate / clock_rate) + other.length * (combined_clock_rate / other.clock_rate); @@ -62,7 +82,7 @@ struct Time { return *this; } - inline Time operator - (Time other) + inline Time operator - (const Time &other) const { Time result; result.clock_rate = NumberTheory::least_common_multiple(clock_rate, other.clock_rate); @@ -70,7 +90,7 @@ struct Time { return result; } - inline Time operator -= (Time other) + inline Time operator -= (const Time &other) { unsigned int combined_clock_rate = NumberTheory::least_common_multiple(clock_rate, other.clock_rate); length = length * (combined_clock_rate / clock_rate) - other.length * (combined_clock_rate / other.clock_rate); @@ -78,7 +98,7 @@ struct Time { return *this; } - inline Time operator * (Time other) + inline Time operator * (const Time &other) const { Time result; result.clock_rate = clock_rate * other.clock_rate; @@ -86,14 +106,28 @@ struct Time { return result; } - inline Time &operator *= (Time other) + inline Time &operator *= (const Time &other) { length *= other.length; clock_rate *= other.clock_rate; return *this; } - inline Time operator / (Time other) + inline Time operator * (unsigned int multiplier) const + { + Time result; + result.clock_rate = clock_rate * multiplier; + result.length = length; + return result; + } + + inline Time &operator *= (unsigned int multiplier) + { + length *= multiplier; + return *this; + } + + inline Time operator / (const Time &other) const { Time result; result.clock_rate = clock_rate * other.length; @@ -101,7 +135,7 @@ struct Time { return result; } - inline Time &operator /= (Time other) + inline Time &operator /= (const Time &other) { length *= other.clock_rate; clock_rate *= other.length;