mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-27 16:31:31 +00:00
Made an attempt to add the necessary extension to Track
, with a concrete implementation in PCMTrack
, to support time-based seeking, the intended mechanism for not magically spinning the disk back to the index hole upon every head step.
This commit is contained in:
parent
d832e5e10d
commit
30f8b6baa4
@ -37,9 +37,16 @@ class Track {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the next event that will be detected during rotation of this disk.
|
@returns the next event that will be detected during rotation of this disk.
|
||||||
*/
|
*/
|
||||||
virtual Event get_next_event() = 0;
|
virtual Event get_next_event() = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Jumps to the event latest offset that is less than or equal to the input time.
|
||||||
|
|
||||||
|
@returns the time jumped to.
|
||||||
|
*/
|
||||||
|
virtual Time seek_to(Time time_since_index_hole) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -61,6 +61,45 @@ PCMTrack::Event PCMTrack::get_next_event()
|
|||||||
return _next_event;
|
return _next_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Time PCMTrack::seek_to(Time time_since_index_hole)
|
||||||
|
{
|
||||||
|
_segment_pointer = 0;
|
||||||
|
|
||||||
|
// pick a common clock rate for counting time on this track and multiply up the time being sought appropriately
|
||||||
|
Time time_so_far;
|
||||||
|
time_so_far.clock_rate = NumberTheory::least_common_multiple(_track_clock_rate, time_since_index_hole.clock_rate);
|
||||||
|
time_since_index_hole.length *= time_so_far.clock_rate / time_since_index_hole.clock_rate;
|
||||||
|
time_since_index_hole.clock_rate = time_so_far.clock_rate;
|
||||||
|
|
||||||
|
while(_segment_pointer < _segments.size())
|
||||||
|
{
|
||||||
|
// determine how long this segment is in terms of the master clock
|
||||||
|
unsigned int clock_multiplier = time_so_far.clock_rate / _segments[_segment_pointer].length_of_a_bit.clock_rate;
|
||||||
|
unsigned int resolution_in_this_segment = _segments[_segment_pointer].length_of_a_bit.length * clock_multiplier;
|
||||||
|
unsigned int time_in_this_segment = resolution_in_this_segment * _segments[_segment_pointer].number_of_bits;
|
||||||
|
|
||||||
|
// if this segment goes on longer than the time being sought, end here
|
||||||
|
unsigned int time_remaining = time_since_index_hole.length - time_so_far.length;
|
||||||
|
if(time_in_this_segment >= time_remaining)
|
||||||
|
{
|
||||||
|
// get the amount of time actually to move into this segment
|
||||||
|
unsigned int time_found = time_remaining - (time_remaining % resolution_in_this_segment);
|
||||||
|
|
||||||
|
// resolve that into the stateful bit count
|
||||||
|
_bit_pointer = time_remaining / resolution_in_this_segment;
|
||||||
|
|
||||||
|
// update and return the time sought to
|
||||||
|
time_so_far.length += time_found;
|
||||||
|
return time_so_far;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise, accumulate time and keep moving
|
||||||
|
time_so_far.length += time_in_this_segment;
|
||||||
|
_segment_pointer++;
|
||||||
|
}
|
||||||
|
return time_since_index_hole;
|
||||||
|
}
|
||||||
|
|
||||||
void PCMTrack::fix_length()
|
void PCMTrack::fix_length()
|
||||||
{
|
{
|
||||||
// find the least common multiple of all segment clock rates
|
// find the least common multiple of all segment clock rates
|
||||||
|
@ -47,6 +47,7 @@ class PCMTrack: public Track {
|
|||||||
|
|
||||||
// as per @c Track
|
// as per @c Track
|
||||||
Event get_next_event();
|
Event get_next_event();
|
||||||
|
Time seek_to(Time time_since_index_hole);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// storage for the segments that describe this track
|
// storage for the segments that describe this track
|
||||||
|
@ -19,6 +19,7 @@ namespace Storage {
|
|||||||
*/
|
*/
|
||||||
struct Time {
|
struct Time {
|
||||||
unsigned int length, clock_rate;
|
unsigned int length, clock_rate;
|
||||||
|
Time() : length(0), clock_rate(1) {}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Reduces this @c Time to its simplest form — eliminates all common factors from @c length
|
Reduces this @c Time to its simplest form — eliminates all common factors from @c length
|
||||||
@ -32,14 +33,28 @@ struct Time {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the floating point conversion of this @c Time. This will often be less precise.
|
@returns the floating point conversion of this @c Time. This will often be less precise.
|
||||||
*/
|
*/
|
||||||
inline float get_float()
|
inline float get_float()
|
||||||
{
|
{
|
||||||
return (float)length / (float)clock_rate;
|
return (float)length / (float)clock_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool operator<(Time &other)
|
||||||
|
{
|
||||||
|
return other.clock_rate * length < clock_rate * other.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Time operator+(Time &other)
|
||||||
|
{
|
||||||
|
Time result;
|
||||||
|
result.clock_rate = NumberTheory::least_common_multiple(clock_rate, other.clock_rate);
|
||||||
|
result.length = length * (clock_rate / result.clock_rate) + other.length * (other.clock_rate / result.clock_rate);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Storage_h */
|
#endif /* Storage_h */
|
||||||
|
Loading…
Reference in New Issue
Block a user